1
0
mirror of https://github.com/enpaul/keyosk.git synced 2024-11-24 23:47:49 +00:00

Remove unnecessary infrastructure from token model

This commit is contained in:
Ethan Paul 2020-02-23 15:41:25 -05:00
parent 129e21a960
commit e4cf37c625

View File

@ -1,16 +1,12 @@
"""Access token model definition"""
import datetime
import json
import secrets
from collections import OrderedDict
from typing import Sequence
import peewee
from keyosk import datatypes
from keyosk.database._shared import KeyoskBaseModel
from keyosk.database.account import Account
from keyosk.database.account_acl import AccountACLEntry
from keyosk.database.domain import Domain
@ -56,70 +52,3 @@ class Token(KeyoskBaseModel):
def claims(self, value: datatypes.TokenClaims):
"""Set the claims dictionary"""
self._claims = json.dumps(value)
def make_public_claims(self):
"""Generate the public JWT claims from current state data"""
return {
"jti": self.uuid,
"sub": self.account.username,
"aud": self.domain.audience,
"iss": self.issuer,
"exp": int(self.expires.timestamp()), # pylint: disable=no-member
"iat": int(self.issued.timestamp()), # pylint: disable=no-member
}
@classmethod
def factory(
cls,
account: Account,
domain: Domain,
issuer: str,
lifespan: datetime.timedelta,
permissions: Sequence[AccountACLEntry],
generate_refresh: bool,
):
"""Create a new token using provided data
This function is intentionally not documented, as I expect it will not survive
first contact with a practical implementation
"""
new = cls(
account=account,
domain=domain,
issuer=issuer,
expires=(datetime.datetime.utcnow() + lifespan),
revoked=False,
refresh=secrets.token_urlsafe(42) if generate_refresh else None,
)
acls = {}
for permission in permissions:
# Note: Because we're relying on dictionary order here, we need to use
# ordered dict to support python3.6. Dictionaries remembering insertion
# order was officially implemented in 3.6, but not guaranteed until 3.7. So,
# technically, it would be fine to use a plain'ol'dictionary here, but to
# conform to best practices we use ordered dict for python3.6 support
# https://stackoverflow.com/questions/39980323/are-dictionaries-ordered-in-python-3-6
acls[permission.access_list.name] = OrderedDict(
{
item.name: False
for item in sorted(
domain.permissions, key=lambda item: item.bitindex
)
}
)
for permission in permissions:
acls[permission.access_list.name][permission.permission.name] = True
bitmasks = {
key: int("".join([str(int(item)) for item in value.values()]), 2)
for key, value in acls.items()
}
claims = new.make_public_claims()
claims.update({"ksk-pem": bitmasks})
new.claims = claims
return new