[feat][apiKey] show token only on create, fix decorator
This commit is contained in:
parent
7dd3321246
commit
df02808fb7
|
@ -1,5 +1,7 @@
|
||||||
import secrets
|
import secrets
|
||||||
|
|
||||||
|
from werkzeug.exceptions import Unauthorized
|
||||||
|
|
||||||
from .. import logger
|
from .. import logger
|
||||||
from ..database import db
|
from ..database import db
|
||||||
from ..models import ApiKey
|
from ..models import ApiKey
|
||||||
|
@ -21,7 +23,7 @@ def validate_api_key(api_key, permission):
|
||||||
Forbidden: If permission is insufficient
|
Forbidden: If permission is insufficient
|
||||||
"""
|
"""
|
||||||
logger.debug("check api_key {{ {} }} is valid".format(api_key))
|
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:
|
if api_key:
|
||||||
logger.debug("api_key found")
|
logger.debug("api_key found")
|
||||||
if not permission or api_key.user_.has_permission(permission):
|
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")
|
logger.debug("create api key token")
|
||||||
token_str = secrets.token_hex(16)
|
token_str = secrets.token_hex(16)
|
||||||
logger.debug("create api_key for user {{ {} }}".format(user))
|
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.add(api_key)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
api_key.token = api_key._token
|
||||||
return api_key
|
return api_key
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 datetime import datetime, timedelta, timezone
|
||||||
from secrets import compare_digest
|
from secrets import compare_digest
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
from .. import logger
|
from .. import logger
|
||||||
from ..database import db
|
from ..database import db
|
||||||
|
@ -20,7 +22,7 @@ class ApiKey(db.Model, ModelSerializeMixin):
|
||||||
__allow_unmapped__ = True
|
__allow_unmapped__ = True
|
||||||
__tablename__ = "api_key"
|
__tablename__ = "api_key"
|
||||||
expires: datetime = db.Column(UtcDateTime, nullable=True)
|
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))
|
name: str = db.Column(db.String(32))
|
||||||
description: str = db.Column(db.String(255), nullable=True)
|
description: str = db.Column(db.String(255), nullable=True)
|
||||||
lifetime: int = db.Column(db.Integer, 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)
|
id: int = db.Column("id", Serial, primary_key=True)
|
||||||
_user_id = db.Column("user_id", Serial, db.ForeignKey("user.id"))
|
_user_id = db.Column("user_id", Serial, db.ForeignKey("user.id"))
|
||||||
user_: User = db.relationship("User", back_populates="api_keys_")
|
user_: User = db.relationship("User", back_populates="api_keys_")
|
||||||
|
token: Union[str, None] = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def userid(self):
|
def userid(self):
|
||||||
|
@ -39,11 +42,11 @@ class ApiKey(db.Model, ModelSerializeMixin):
|
||||||
|
|
||||||
Update the Timestamp to the current Time.
|
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)
|
self.expires = datetime.now(timezone.utc) + timedelta(seconds=self.lifetime)
|
||||||
|
|
||||||
def __eq__(self, token):
|
def __eq__(self, token):
|
||||||
if isinstance(token, str):
|
if isinstance(token, str):
|
||||||
return compare_digest(self.token, token)
|
return compare_digest(self._token, token)
|
||||||
else:
|
else:
|
||||||
return super(Session, self).__eq__(token)
|
return super(Session, self).__eq__(token)
|
||||||
|
|
|
@ -3,21 +3,20 @@ from functools import wraps
|
||||||
from werkzeug.exceptions import Unauthorized
|
from werkzeug.exceptions import Unauthorized
|
||||||
|
|
||||||
from flaschengeist import logger
|
from flaschengeist import logger
|
||||||
from flaschengeist.controller import sessionController
|
from flaschengeist.controller import apiKeyController, sessionController
|
||||||
|
|
||||||
|
|
||||||
def extract_api_key(permission=None):
|
def extract_api_key(permission=None):
|
||||||
from flask import request
|
from flask import request
|
||||||
|
|
||||||
try:
|
try:
|
||||||
api_key = request.headers.get("X-API-KEY")
|
apiKey = request.headers.get("X-API-KEY")
|
||||||
logger.debug(f"api_key {{ {api_key} }} | headers {{ {request.headers} }}")
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
logger.debug("Missing X-API-KEY header")
|
logger.debug("Missing X-API-KEY header")
|
||||||
raise Unauthorized
|
raise Unauthorized
|
||||||
|
|
||||||
session = sessionController.validate_api_key(api_key, request.headers, permission)
|
apiKey = apiKeyController.validate_api_key(apiKey, permission)
|
||||||
return session
|
return apiKey
|
||||||
|
|
||||||
|
|
||||||
def extract_session(permission=None):
|
def extract_session(permission=None):
|
||||||
|
|
Loading…
Reference in New Issue