diff --git a/auth/authenticate.py b/auth/authenticate.py index 242d2793..bc5509b3 100644 --- a/auth/authenticate.py +++ b/auth/authenticate.py @@ -2,11 +2,14 @@ from functools import wraps from typing import Optional, Tuple from graphql.type import GraphQLResolveInfo +from sqlalchemy.orm import joinedload, exc from starlette.authentication import AuthenticationBackend from starlette.requests import HTTPConnection from auth.credentials import AuthCredentials, AuthUser -from services.auth.users import UserStorage +from base.orm import local_session +from orm import User, Role + from settings import SESSION_TOKEN_HEADER from auth.tokenstorage import SessionToken from base.exceptions import InvalidToken, OperationNotAllowed, Unauthorized @@ -32,10 +35,26 @@ class JWTAuthenticate(AuthenticationBackend): payload = await SessionToken.verify(token) if payload is None: return AuthCredentials(scopes=[]), AuthUser(user_id=None) - user = await UserStorage.get_user(payload.user_id) + + with local_session() as session: + try: + user = ( + session.query(User).options( + joinedload(User.roles), + joinedload(Role.permissions), + joinedload(User.ratings) + ).filter( + User.id == id + ).one() + ) + except exc.NoResultFound: + user = None + if not user: return AuthCredentials(scopes=[]), AuthUser(user_id=None) - scopes = await user.get_permission() + + scopes = user.get_permission() + return ( AuthCredentials( user_id=payload.user_id, @@ -46,10 +65,10 @@ class JWTAuthenticate(AuthenticationBackend): ) else: InvalidToken("please try again") - except Exception as exc: + except Exception as e: print("[auth.authenticate] session token verify error") - print(exc) - return AuthCredentials(scopes=[], error_message=str(exc)), AuthUser(user_id=None) + print(e) + return AuthCredentials(scopes=[], error_message=str(e)), AuthUser(user_id=None) def login_required(func): diff --git a/orm/user.py b/orm/user.py index 75a2d748..11055d29 100644 --- a/orm/user.py +++ b/orm/user.py @@ -103,12 +103,12 @@ class User(Base): async def get_permission(self): scope = {} - for user_role in self.roles: - role: Role = await RoleStorage.get_role(user_role.id) # type: ignore + for role in self.roles: for p in role.permissions: if p.resource_id not in scope: scope[p.resource_id] = set() scope[p.resource_id].add(p.operation_id) + return scope diff --git a/services/auth/roles.py b/services/auth/roles.py deleted file mode 100644 index b5924dc5..00000000 --- a/services/auth/roles.py +++ /dev/null @@ -1,35 +0,0 @@ -import asyncio - -from sqlalchemy.orm import selectinload - -from orm.rbac import Role - - -class RoleStorage: - roles = {} - lock = asyncio.Lock() - - @staticmethod - def init(session): - self = RoleStorage - roles = session.query(Role).options(selectinload(Role.permissions)).all() - self.roles = dict([(role.id, role) for role in roles]) - print("[auth.roles] %d precached" % len(roles)) - - @staticmethod - async def get_role(id): - self = RoleStorage - async with self.lock: - return self.roles.get(id) - - @staticmethod - async def add_role(role): - self = RoleStorage - async with self.lock: - self.roles[id] = role - - @staticmethod - async def del_role(id): - self = RoleStorage - async with self.lock: - del self.roles[id] diff --git a/services/auth/users.py b/services/auth/users.py deleted file mode 100644 index 2ba636bc..00000000 --- a/services/auth/users.py +++ /dev/null @@ -1,72 +0,0 @@ -import asyncio -from sqlalchemy.orm import selectinload, exc -from orm.user import User -from base.orm import local_session - - -class UserStorage: - users = {} - lock = asyncio.Lock() - - @staticmethod - def init(session): - self = UserStorage - users = ( - session.query(User) - .options(selectinload(User.roles), selectinload(User.ratings)) - .all() - ) - self.users = dict([(user.id, user) for user in users]) - print("[auth.users] %d precached" % len(self.users)) - - @staticmethod - async def get_user(id): - with local_session() as session: - try: - user = ( - session.query(User).options( - selectinload(User.roles), - selectinload(User.ratings) - ).filter( - User.id == id - ).one() - ) - return user - except exc.NoResultFound: - return None - - @staticmethod - async def get_all_users(): - self = UserStorage - async with self.lock: - aaa = list(self.users.values()) - aaa.sort(key=lambda user: user.createdAt) - return aaa - - @staticmethod - async def get_top_users(): - self = UserStorage - async with self.lock: - aaa = list(self.users.values()) - aaa.sort(key=lambda user: user.rating) - return aaa - - @staticmethod - async def get_user_by_slug(slug): - self = UserStorage - async with self.lock: - for user in self.users.values(): - if user.slug == slug: - return user - - @staticmethod - async def add_user(user): - self = UserStorage - async with self.lock: - self.users[user.id] = user - - @staticmethod - async def del_user(id): - self = UserStorage - async with self.lock: - del self.users[id] diff --git a/services/main.py b/services/main.py index f87f8afe..10301b86 100644 --- a/services/main.py +++ b/services/main.py @@ -1,5 +1,3 @@ -from services.auth.roles import RoleStorage -from services.auth.users import UserStorage from services.search import SearchService from services.stat.viewed import ViewedStorage from base.orm import local_session @@ -7,9 +5,9 @@ from base.orm import local_session async def storages_init(): with local_session() as session: - print('[main] initialize storages') - RoleStorage.init(session) - UserStorage.init(session) + print('[main] initialize SearchService') await SearchService.init(session) - session.commit() + print('[main] SearchService initialized') + print('[main] initialize storages') await ViewedStorage.init() + print('[main] storages initialized')