Compare commits

..

No commits in common. "4248825af0c9a079b8c8326b3f96aba923b41e97" and "ee38e46c12773e6da1256c27e965507a79396043" have entirely different histories.

9 changed files with 17 additions and 64 deletions

View File

@ -25,7 +25,6 @@ def get_enabled_plugins():
class PluginStub: class PluginStub:
def __init__(self, name) -> None: def __init__(self, name) -> None:
self.name = name self.name = name
self.version = "?"
logger.error("Could not connect to database or database not initialized! No plugins enabled!") logger.error("Could not connect to database or database not initialized! No plugins enabled!")
logger.debug("Can not query enabled plugins", exc_info=True) logger.debug("Can not query enabled plugins", exc_info=True)

View File

@ -11,36 +11,7 @@ from ..database import db
lifetime = 1800 lifetime = 1800
def __get_user_agent_platform(ua: str): def validate_token(token, user_agent, permission):
if "Win" in ua:
return "Windows"
if "Mac" in ua:
return "Macintosh"
if "Linux" in ua:
return "Linux"
if "Android" in ua:
return "Android"
if "like Mac" in ua:
return "iOS"
return "unknown"
def __get_user_agent_browser(ua: str):
ua_str = ua.lower()
if "firefox" in ua_str or "fxios" in ua_str:
return "firefox"
if "safari" in ua_str:
return "safari"
if "opr/" in ua_str:
return "opera"
if "edg" in ua_str:
return "edge"
if "chrom" in ua_str or "crios" in ua_str:
return "chrome"
return "unknown"
def validate_token(token, request_headers, permission):
"""Verify session """Verify session
Verify a Session and Roles so if the User has permission or not. Verify a Session and Roles so if the User has permission or not.
@ -48,7 +19,7 @@ def validate_token(token, request_headers, permission):
Args: Args:
token: Token to verify. token: Token to verify.
request_headers: Headers to validate user agent of browser user_agent: User agent of browser to check
permission: Permission needed to access restricted routes permission: Permission needed to access restricted routes
Returns: Returns:
A Session for this given Token A Session for this given Token
@ -60,16 +31,8 @@ def validate_token(token, request_headers, permission):
session = Session.query.filter_by(token=token).one_or_none() session = Session.query.filter_by(token=token).one_or_none()
if session: if session:
logger.debug("token found, check if expired or invalid user agent differs") logger.debug("token found, check if expired or invalid user agent differs")
platform = request_headers.get("Sec-CH-UA-Platform", None) or __get_user_agent_platform(
request_headers.get("User-Agent", "")
)
browser = request_headers.get("Sec-CH-UA", None) or __get_user_agent_browser(
request_headers.get("User-Agent", "")
)
if session.expires >= datetime.now(timezone.utc) and ( if session.expires >= datetime.now(timezone.utc) and (
session.browser == browser and session.platform == platform session.browser == user_agent.browser and session.platform == user_agent.platform
): ):
if not permission or session.user_.has_permission(permission): if not permission or session.user_.has_permission(permission):
session.refresh() session.refresh()

View File

@ -1,5 +1,3 @@
from __future__ import annotations # TODO: Remove if python requirement is >= 3.12 (? PEP 563 is defered)
from sqlalchemy import event from sqlalchemy import event
from pathlib import Path from pathlib import Path

View File

@ -1,5 +1,3 @@
from __future__ import annotations # TODO: Remove if python requirement is >= 3.12 (? PEP 563 is defered)
from datetime import datetime from datetime import datetime
from typing import Any from typing import Any
@ -16,8 +14,8 @@ class Notification(db.Model, ModelSerializeMixin):
user_id_: int = db.Column("user", Serial, db.ForeignKey("user.id"), nullable=False) user_id_: int = db.Column("user", Serial, db.ForeignKey("user.id"), nullable=False)
plugin_id_: int = db.Column("plugin", Serial, db.ForeignKey("plugin.id"), nullable=False) plugin_id_: int = db.Column("plugin", Serial, db.ForeignKey("plugin.id"), nullable=False)
user_: User = db.relationship("User") user_: "User" = db.relationship("User")
plugin_: Plugin = db.relationship( plugin_: "Plugin" = db.relationship(
"Plugin", backref=db.backref("notifications_", cascade="all, delete, delete-orphan") "Plugin", backref=db.backref("notifications_", cascade="all, delete, delete-orphan")
) )

View File

@ -1,5 +1,3 @@
from __future__ import annotations # TODO: Remove if python requirement is >= 3.12 (? PEP 563 is defered)
from typing import Any from typing import Any
from ..database import db from ..database import db

View File

@ -1,12 +1,11 @@
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 .. import logger
from ..database import db from ..database import db
from ..database.types import ModelSerializeMixin, UtcDateTime, Serial from ..database.types import ModelSerializeMixin, UtcDateTime, Serial
from flaschengeist import logger
class Session(db.Model, ModelSerializeMixin): class Session(db.Model, ModelSerializeMixin):
"""Model for a Session """Model for a Session
@ -21,13 +20,13 @@ class Session(db.Model, ModelSerializeMixin):
expires: datetime = db.Column(UtcDateTime) expires: datetime = db.Column(UtcDateTime)
token: str = db.Column(db.String(32), unique=True) token: str = db.Column(db.String(32), unique=True)
lifetime: int = db.Column(db.Integer) lifetime: int = db.Column(db.Integer)
browser: str = db.Column(db.String(127)) browser: str = db.Column(db.String(30))
platform: str = db.Column(db.String(64)) platform: str = db.Column(db.String(30))
userid: str = "" userid: str = ""
_id = db.Column("id", Serial, primary_key=True) _id = 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="sessions_") user_: "User" = db.relationship("User", back_populates="sessions_")
@property @property
def userid(self): def userid(self):

View File

@ -1,5 +1,3 @@
from __future__ import annotations # TODO: Remove if python requirement is >= 3.12 (? PEP 563 is defered)
from typing import Optional from typing import Optional
from datetime import date, datetime from datetime import date, datetime
from sqlalchemy.orm.collections import attribute_mapped_collection from sqlalchemy.orm.collections import attribute_mapped_collection
@ -64,10 +62,10 @@ class User(db.Model, ModelSerializeMixin):
# Protected stuff for backend use only # Protected stuff for backend use only
id_ = db.Column("id", Serial, primary_key=True) id_ = db.Column("id", Serial, primary_key=True)
roles_: list[Role] = db.relationship("Role", secondary=association_table, cascade="save-update, merge") roles_: list[Role] = db.relationship("Role", secondary=association_table, cascade="save-update, merge")
sessions_: list[Session] = db.relationship( sessions_: list["Session"] = db.relationship(
"Session", back_populates="user_", cascade="all, delete, delete-orphan" "Session", back_populates="user_", cascade="all, delete, delete-orphan"
) )
avatar_: Optional[Image] = db.relationship("Image", cascade="all, delete, delete-orphan", single_parent=True) avatar_: Optional["Image"] = db.relationship("Image", cascade="all, delete, delete-orphan", single_parent=True)
reset_requests_: list["_PasswordReset"] = db.relationship("_PasswordReset", cascade="all, delete, delete-orphan") reset_requests_: list["_PasswordReset"] = db.relationship("_PasswordReset", cascade="all, delete, delete-orphan")
# Private stuff for internal use # Private stuff for internal use

View File

@ -14,7 +14,7 @@ def extract_session(permission=None):
logger.debug("Missing Authorization header or ill-formed") logger.debug("Missing Authorization header or ill-formed")
raise Unauthorized raise Unauthorized
session = sessionController.validate_token(token, request.headers, permission) session = sessionController.validate_token(token, request.user_agent, permission)
return session return session

View File

@ -22,14 +22,14 @@ include_package_data = True
python_requires = >=3.10 python_requires = >=3.10
packages = find: packages = find:
install_requires = install_requires =
Flask>=2.2.2 Flask==2.0.3
Pillow>=9.2 Pillow>=9.0
flask_cors flask_cors
flask_migrate>=3.1.0 flask_migrate>=3.1.0
flask_sqlalchemy>=2.5.1 flask_sqlalchemy>=2.5.1
sqlalchemy>=1.4.40 sqlalchemy>=1.4.39
toml toml
werkzeug>=2.2.2 werkzeug==2.0.3
[options.extras_require] [options.extras_require]
argon = argon2-cffi argon = argon2-cffi