async def get_user_info(user_id, create_default=False) -> Optional[UserInfo]: async with db.acquire(): u: UserOrm = await UserOrm.get(user_id) if u is None: if not create_default: return None else: return await add_user(UserInfo( userId=user_id, globalRole=GlobalRole.user, groups=[ # GroupInfo( # groupId='common', # description='Common group for all users', # mode=Mode.read) ] )) user = UserInfo(userId=user_id, globalRole=GlobalRole(u.global_role)) user_groups = await db.select( [ UserGroupOrm.group_id, UserGroupOrm.mode, GroupOrm.description ] ).select_from( UserGroupOrm.join(GroupOrm) ).where( UserGroupOrm.user_id == user_id ).gino.all() user.groups = [] for ug in user_groups: user.groups.append(GroupInfo(groupId=ug.group_id, description=ug.description, mode=ug.mode)) return user
async def generate_access_token( user_id: str) -> Tuple[Optional[str], datetime.datetime]: user_info = await get_user_info(user_id, create_default=False) if user_info is None: user_info = UserInfo(userId=user_id, globalRole=GlobalRole.user, groups=[]) exp = datetime.datetime.now(tz=pytz.UTC) + datetime.timedelta(minutes=10) data = { "sub": user_id, "exp": exp, "user_info": str(user_info.json(by_alias=True)) } token = jwt.encode(header={ "alg": "RS256", "typ": "JWT" }, payload=data, key=base64.b64decode(AUTH_PRIVATE_KEY)) return token.decode('utf-8'), exp
def decode_api_key(api_key: str) -> Optional[dict]: try: token = jwt.decode(api_key, key=Const.AUTH_PUBLIC_KEY) except DecodeError: return None user_info = UserInfo.parse_raw(token['user_info']) t = dict( sub=user_info.user_id, expires_at=datetime.datetime.fromtimestamp(token['exp']), user_info=user_info ) if t['expires_at'] < datetime.datetime.now() and not DEBUG: return None return t
async def admin_add_user(request: web.Request, body, token_info: dict, **kwargs) -> web.Response: """add new user :param body: User parameters :type body: dict | bytes """ user_info: UserInfo = token_info['user_info'] if user_info.global_role != GlobalRole.admin: return web.Response(status=401, reason='Only admin can use this endpoint') new_user_info = UserInfo.parse_obj(body) result = await add_user(new_user_info) return web.Response(status=200, body=result.json(by_alias=True))
async def generate_unittest_cred(): await db.set_bind( f'postgresql://{Const.DB_USER}:{Const.DB_PASSWORD}@{Const.DB_HOST}:{Const.DB_PORT}/{Const.DB_NAME}') await db.gino.create_all() unittest_user = await get_user_info('unittest') if unittest_user is None: await add_user(UserInfo( userId='unittest', globalRole=GlobalRole.user, groups=[GroupInfo( groupId='unittest', description='group for unit tests', mode=Mode.admin )] )) refresh_token = RefreshToken( token_id=uuid.uuid4(), user_id='unittest', creation_date=datetime.datetime.now(tz=pytz.UTC), expiration_date=datetime.datetime.now(tz=pytz.UTC) + datetime.timedelta(days=365), is_revoked=False ) await RefreshTokenOrm.delete.where(RefreshTokenOrm.user_id == 'unittest').gino.status() await RefreshTokenOrm.create(**refresh_token.dict()) print('Unittest refresh token: ', refresh_token.token_id)
async def mock_user_info(user_id: str) -> Optional[UserInfo]: if user_id == 'v.baydin': return UserInfo(userId=user_id, globalRole=GlobalRole.admin, groups=[]) else: return None