2024-12-11 16:18:12 +00:00
|
|
|
import secrets
|
2024-12-14 17:54:01 +00:00
|
|
|
|
|
|
|
from sqlalchemy.orm.attributes import flag_modified
|
|
|
|
|
2024-12-11 16:18:12 +00:00
|
|
|
from database import db
|
|
|
|
from models import Session, User, Organization
|
|
|
|
from flask import jsonify
|
|
|
|
|
2024-12-14 17:54:01 +00:00
|
|
|
from utils import Perm
|
|
|
|
|
2024-12-11 16:18:12 +00:00
|
|
|
|
|
|
|
class SessionService:
|
|
|
|
@staticmethod
|
|
|
|
def create_session(user: User, org: Organization) -> Session:
|
|
|
|
session = Session(
|
|
|
|
user_id=user.id,
|
|
|
|
org_id=org.id,
|
2024-12-14 17:54:01 +00:00
|
|
|
token=secrets.token_hex(128),
|
|
|
|
roles=[]
|
2024-12-11 16:18:12 +00:00
|
|
|
)
|
|
|
|
db.add(session)
|
|
|
|
db.commit()
|
|
|
|
db.refresh(session)
|
|
|
|
return session
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_session(token: str) -> Session | None:
|
|
|
|
return db.query(Session).filter(Session.token == token).first()
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def delete_session(session: Session) -> None:
|
|
|
|
db.delete(session)
|
|
|
|
db.commit()
|
|
|
|
|
|
|
|
@staticmethod
|
2024-12-15 02:46:37 +00:00
|
|
|
def validate_session(token: str, required_perms: list[Perm] = None, doc_handle=None) -> tuple | Session:
|
2024-12-11 16:18:12 +00:00
|
|
|
from services import OrganizationService
|
|
|
|
|
|
|
|
if "Bearer" in token:
|
|
|
|
token = token.split(" ")[1]
|
|
|
|
|
|
|
|
session = SessionService.get_session(token)
|
|
|
|
if not session:
|
|
|
|
return jsonify({"error": "Not authenticated"}), 401
|
|
|
|
|
|
|
|
org = OrganizationService.get_organization(session.org_id)
|
|
|
|
if not org:
|
|
|
|
return jsonify({"error": "Organization not found"}), 404
|
|
|
|
|
|
|
|
status = OrganizationService.get_user_status(org, session.user_id)
|
|
|
|
if status != "active":
|
|
|
|
return jsonify({"error": "User is not active"}), 403
|
|
|
|
|
2024-12-15 02:20:26 +00:00
|
|
|
if required_perms:
|
|
|
|
for perm in required_perms:
|
2024-12-15 02:46:37 +00:00
|
|
|
if not SessionService.check_permission(session, perm, doc_handle):
|
2024-12-15 02:20:26 +00:00
|
|
|
return jsonify({"error": f"Permission denied, missing required permission: {perm}"}), 403
|
|
|
|
|
2024-12-11 16:18:12 +00:00
|
|
|
return session
|
2024-12-14 17:54:01 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def assume_role(session: Session, role: str) -> bool:
|
|
|
|
from services import OrganizationService
|
|
|
|
|
|
|
|
org = OrganizationService.get_organization(session.org_id)
|
|
|
|
if not org:
|
|
|
|
return False
|
|
|
|
|
|
|
|
user = User.query.get(session.user_id)
|
|
|
|
if not user:
|
|
|
|
return False
|
|
|
|
|
|
|
|
if role not in user.roles[org.id]:
|
|
|
|
return False
|
|
|
|
|
|
|
|
if role in session.roles:
|
|
|
|
return False
|
|
|
|
|
|
|
|
session.roles.append(role)
|
|
|
|
flag_modified(session, "roles")
|
|
|
|
db.commit()
|
|
|
|
db.refresh(session)
|
|
|
|
return True
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def drop_role(session: Session, role: str) -> bool:
|
|
|
|
from services import OrganizationService
|
|
|
|
|
|
|
|
org = OrganizationService.get_organization(session.org_id)
|
|
|
|
if not org:
|
|
|
|
return False
|
|
|
|
|
|
|
|
user = User.query.get(session.user_id)
|
|
|
|
if not user:
|
|
|
|
return False
|
|
|
|
|
|
|
|
if role not in user.roles[org.id]:
|
|
|
|
return False
|
|
|
|
|
|
|
|
if role not in session.roles:
|
|
|
|
return False
|
|
|
|
|
|
|
|
session.roles.remove(role)
|
|
|
|
flag_modified(session, "roles")
|
|
|
|
db.commit()
|
|
|
|
db.refresh(session)
|
|
|
|
return True
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def list_roles(session: Session) -> list:
|
|
|
|
return session.roles
|
|
|
|
|
|
|
|
@staticmethod
|
2024-12-15 02:46:37 +00:00
|
|
|
def check_permission(session: Session, perm: Perm, doc_handle=None) -> bool:
|
2024-12-14 17:54:01 +00:00
|
|
|
from services import OrganizationService, RoleService
|
|
|
|
|
|
|
|
org = OrganizationService.get_organization(session.org_id)
|
|
|
|
if not org:
|
|
|
|
return False
|
|
|
|
|
|
|
|
user = User.query.get(session.user_id)
|
|
|
|
if not user:
|
|
|
|
return False
|
|
|
|
|
|
|
|
for role in session.roles:
|
2024-12-15 02:46:37 +00:00
|
|
|
if RoleService.check_role_permission(org, role, perm, doc_handle):
|
2024-12-14 17:54:01 +00:00
|
|
|
return True
|
|
|
|
|
|
|
|
return False
|