diff --git a/flaschengeist/controller/apiKeyController.py b/flaschengeist/controller/apiKeyController.py index 0a464bc..54058f5 100644 --- a/flaschengeist/controller/apiKeyController.py +++ b/flaschengeist/controller/apiKeyController.py @@ -1,5 +1,7 @@ import secrets +from werkzeug.exceptions import Unauthorized + from .. import logger from ..database import db from ..models import ApiKey @@ -21,7 +23,7 @@ def validate_api_key(api_key, permission): Forbidden: If permission is insufficient """ logger.debug("check api_key {{ {} }} is valid".format(api_key)) - api_key = ApiKey.query.filter_by(api_key=api_key).one_or_none() + api_key = ApiKey.query.filter_by(_token=api_key).one_or_none() if api_key: logger.debug("api_key found") if not permission or api_key.user_.has_permission(permission): @@ -44,9 +46,10 @@ def create(user, name, description=None) -> ApiKey: logger.debug("create api key token") token_str = secrets.token_hex(16) logger.debug("create api_key for user {{ {} }}".format(user)) - api_key = ApiKey(_user_id=user.id__, name=name, description=description, token=token_str) + api_key = ApiKey(_user_id=user.id_, name=name, description=description, _token=token_str) db.session.add(api_key) db.session.commit() + api_key.token = api_key._token return api_key diff --git a/flaschengeist/models/api_key.py b/flaschengeist/models/api_key.py index 9089ca6..dd158a4 100644 --- a/flaschengeist/models/api_key.py +++ b/flaschengeist/models/api_key.py @@ -1,7 +1,9 @@ -from __future__ import annotations # TODO: Remove if python requirement is >= 3.12 (? PEP 563 is defered) +from __future__ import \ + annotations # TODO: Remove if python requirement is >= 3.12 (? PEP 563 is defered) from datetime import datetime, timedelta, timezone from secrets import compare_digest +from typing import Union from .. import logger from ..database import db @@ -20,7 +22,7 @@ class ApiKey(db.Model, ModelSerializeMixin): __allow_unmapped__ = True __tablename__ = "api_key" expires: datetime = db.Column(UtcDateTime, nullable=True) - token: str = db.Column(db.String(32), unique=True) + _token: str = db.Column("token", db.String(32), unique=True) name: str = db.Column(db.String(32)) description: str = db.Column(db.String(255), nullable=True) lifetime: int = db.Column(db.Integer, nullable=True) @@ -29,6 +31,7 @@ class ApiKey(db.Model, ModelSerializeMixin): id: int = db.Column("id", Serial, primary_key=True) _user_id = db.Column("user_id", Serial, db.ForeignKey("user.id")) user_: User = db.relationship("User", back_populates="api_keys_") + token: Union[str, None] = None @property def userid(self): @@ -39,11 +42,11 @@ class ApiKey(db.Model, ModelSerializeMixin): Update the Timestamp to the current Time. """ - logger.debug("update timestamp from session with token {{ {} }}".format(self.token)) + logger.debug("update timestamp from session with token {{ {} }}".format(self._token)) self.expires = datetime.now(timezone.utc) + timedelta(seconds=self.lifetime) def __eq__(self, token): if isinstance(token, str): - return compare_digest(self.token, token) + return compare_digest(self._token, token) else: return super(Session, self).__eq__(token) diff --git a/flaschengeist/utils/decorators.py b/flaschengeist/utils/decorators.py index 32f0ab2..9c1f1da 100644 --- a/flaschengeist/utils/decorators.py +++ b/flaschengeist/utils/decorators.py @@ -3,21 +3,20 @@ from functools import wraps from werkzeug.exceptions import Unauthorized from flaschengeist import logger -from flaschengeist.controller import sessionController +from flaschengeist.controller import apiKeyController, sessionController def extract_api_key(permission=None): from flask import request try: - api_key = request.headers.get("X-API-KEY") - logger.debug(f"api_key {{ {api_key} }} | headers {{ {request.headers} }}") + apiKey = request.headers.get("X-API-KEY") except AttributeError: logger.debug("Missing X-API-KEY header") raise Unauthorized - session = sessionController.validate_api_key(api_key, request.headers, permission) - return session + apiKey = apiKeyController.validate_api_key(apiKey, permission) + return apiKey def extract_session(permission=None):