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""" """Access token model definition"""
import datetime import datetime
import json import json
import secrets
from collections import OrderedDict
from typing import Sequence
import peewee import peewee
from keyosk import datatypes from keyosk import datatypes
from keyosk.database._shared import KeyoskBaseModel from keyosk.database._shared import KeyoskBaseModel
from keyosk.database.account import Account from keyosk.database.account import Account
from keyosk.database.account_acl import AccountACLEntry
from keyosk.database.domain import Domain from keyosk.database.domain import Domain
@ -56,70 +52,3 @@ class Token(KeyoskBaseModel):
def claims(self, value: datatypes.TokenClaims): def claims(self, value: datatypes.TokenClaims):
"""Set the claims dictionary""" """Set the claims dictionary"""
self._claims = json.dumps(value) 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