Skip to content

Commit

Permalink
📈 Adding stats per AA fixes #31
Browse files Browse the repository at this point in the history
  • Loading branch information
puria committed Jul 17, 2019
1 parent 034df04 commit 621d23f
Show file tree
Hide file tree
Showing 12 changed files with 63 additions and 47 deletions.
3 changes: 3 additions & 0 deletions app/config.ini
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ keypair = /app/app/ci_keypair.keys
contracts_path = /app/app/contracts/src


secret = 615872afdb35a291f56166d63399d0fa1f2a37415b24206fb051dbce294afc5c


# OAuth2
ALGORITHM = HS256
TOKEN_SUBJECT = access
Expand Down
24 changes: 24 additions & 0 deletions app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ def exists(cls, aaid, value):
def total(cls):
return DBSession.query(cls).count()

@classmethod
def total_by_aaid(cls, aaid):
return DBSession.query(cls).filter_by(aaid=aaid).count()


class Statistics(Base):
uid = Column(Integer, primary_key=True, index=True)
Expand Down Expand Up @@ -128,6 +132,26 @@ def aggregate(cls):

return result

@classmethod
def by_aa(cls, aa):
result = {}
values = (
DBSession.query(cls.name, cls.value, func.count(cls.value), cls.aaid)
.filter_by(aaid=aa.authorizable_attribute_id)
.group_by(cls.name, cls.value)
.all()
)
for v in values:
existent_list = result.get(v[0], [])
existent_list.append({v[1]: v[2]})
if v[2] >= aa.optional_k(v[0]):
result[v[0]] = existent_list
result["total"] = ValidatedCredentials.total_by_aaid(
aa.authorizable_attribute_id
)

return result


Base.metadata.create_all(bind=engine)

Expand Down
6 changes: 4 additions & 2 deletions app/routers/authorizable_attribute.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,11 @@ def authorizable_attribute(
):
info = [_.json() for _ in item.authorizable_attribute_info]
optional = [_.json() for _ in item.authorizable_attribute_info_optional]
keypair = ZenContract(

keypair_contract = ZenContract(
CONTRACTS.GENERATE_KEYPAIR, {"issuer_identifier": config.get("uid")}
).execute()
)
keypair = keypair_contract.execute()
contract = ZenContract(
CONTRACTS.PUBLIC_VERIFY, {"issuer_identifier": config.get("uid")}
)
Expand Down
25 changes: 1 addition & 24 deletions app/routers/security.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,17 @@
import json
from datetime import timedelta, datetime
from pathlib import Path

import jwt
from fastapi import Depends, HTTPException, APIRouter
from fastapi.security import OAuth2PasswordRequestForm

from app.config.config import BaseConfig
from app.schema import TokenOutput
from app.zencontract import ZenContract, CONTRACTS

router = APIRouter()
config = BaseConfig()
log = config.logger


def load_keypair():
keypair = Path(config.get("keypair"))
if not keypair.is_file():
log.info("CREATING KEYPAIR IN %s" % keypair.as_posix())
keypair.touch()
keypair.write_text(
ZenContract(
CONTRACTS.GENERATE_KEYPAIR, {"issuer_identifier": config.get("uid")}
).execute()
)

if config.getboolean("debug"): # pragma: no cover
log.debug("+" * 50)
log.debug("KEYPAIR IS: \n%s" % keypair.read_text())
log.debug("+" * 50)

return keypair.read_text()


def create_access_token(*, data: dict, expires_delta: timedelta = None):
to_encode = data.copy()
if expires_delta:
Expand All @@ -43,8 +21,7 @@ def create_access_token(*, data: dict, expires_delta: timedelta = None):
minutes=config.getint("ACCESS_TOKEN_EXPIRE_MINUTES")
)
to_encode.update({"exp": expire, "sub": config.get("TOKEN_SUBJECT")})
keypair = json.loads(load_keypair())
secret = keypair[config.get("uid")]["sign"]["x"]
secret = config.get("secret")
encoded_jwt = jwt.encode(to_encode, secret, algorithm=config.get("ALGORITHM"))
return encoded_jwt

Expand Down
20 changes: 18 additions & 2 deletions app/routers/stats.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from fastapi import APIRouter
from fastapi import APIRouter, HTTPException
from starlette.status import HTTP_204_NO_CONTENT

from app.models import Statistics
from app.models import Statistics, AuthorizableAttribute

router = APIRouter()

Expand All @@ -12,3 +13,18 @@
)
def index():
return Statistics.aggregate()


@router.get(
"/{authorizable_attribute_id}",
summary="Get an aggregated view of optional info values, for an Authorizable Attribute",
tags=["Statistics"],
)
def get_authorizable_attribute_stats(authorizable_attribute_id):
aa = AuthorizableAttribute.by_aa_id(authorizable_attribute_id)
if not aa:
raise HTTPException(
status_code=HTTP_204_NO_CONTENT, detail="Authorizable Attribute Not Found"
)

return Statistics.by_aa(aa)
3 changes: 2 additions & 1 deletion app/test.ini
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
[DEFAULT]
debug = true
uid = Credential Issuer 01
uid = issuer_identifier
keypair = /home/travis/build/DECODEproject/dddc-credential-issuer/tests/ci_keypair.keys
contracts_path = /home/travis/build/DECODEproject/dddc-credential-issuer/app/contracts/src
secret = 615872afdb35a291f56166d63399d0fa1f2a37415b24206fb051dbce294afc5c

ALGORITHM = HS256
TOKEN_SUBJECT = access
Expand Down
14 changes: 8 additions & 6 deletions app/zencontract.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def get_contract(self):
contract = contracts_dir.joinpath(self.name).read_text()
for k, v in self.placeholder.items():
contract = contract.replace(f"'{k}'", f"'{v}'")
return contract
return str(contract)

def execute(self):
if config.getboolean("debug"): # pragma: no cover
Expand All @@ -50,11 +50,13 @@ def execute(self):
log.debug("DATA: %s" % self._data)
log.debug("KEYS: %s" % self._keys)
log.debug("CODE: \n%s" % self.zencode)

result, errors = zenroom.zencode_exec(
script=self.zencode, keys=self._keys, data=self._data
)
self._error = errors
try:
result, errors = zenroom.zencode_exec(
script=self.zencode, keys=self._keys, data=self._data
)
self._error = str(errors)
except Exception:
log.exception("Zenroom contract exception", exc_info=True)
return result

def keys(self, keys=None):
Expand Down
1 change: 0 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ env =
DDDC_CREDENTIAL_ISSUER_CONFIGFILE=/home/puria/src/dddc-credential-issuer/app/test.ini



[flake8]
ignore = E501
max-line-length = 99
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"bunch==1.0.1",
"fastapi==0.33.0",
"pytest_runner==4.4",
"zenroom==1.0.5",
"zenroom==1.0.6",
"pre-commit==1.17.0",
"python-multipart==0.0.5",
"pyjwt==1.7.1",
Expand Down
2 changes: 1 addition & 1 deletion tests/test_auth_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def test_authorizable_attribute(client):
attrib = AuthorizableAttribute.by_aa_id(aaid)
assert attrib is not None
assert attrib.authorizable_attribute_id == aaid
assert r.json()["credential_issuer_id"] == "Credential Issuer 01"
assert r.json()["credential_issuer_id"] == "issuer_identifier"
assert "super_long_key" in attrib.authorizable_attribute_info


Expand Down
2 changes: 1 addition & 1 deletion tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def test_config_base_logger():

def test_config_get():
config = BaseConfig()
assert config.get("uid") == "Credential Issuer 01"
assert config.get("uid") == "issuer_identifier"


def test_config_getint():
Expand Down
8 changes: 0 additions & 8 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

from app.config.config import BaseConfig
from app.main import api
from app.routers.security import load_keypair
from app.zencontract import ZenContract, CONTRACTS


Expand Down Expand Up @@ -52,13 +51,6 @@ def remove_secret():
secret.unlink()


def test_secret_key_creation(remove_secret):
c = BaseConfig()
assert not Path(c.get("keypair")).is_file()
load_keypair()
assert Path(c.get("keypair")).is_file()


def test_uid(client):
config = BaseConfig()
r = client.get("/uid")
Expand Down

0 comments on commit 621d23f

Please sign in to comment.