async def update_permission(perm: UpdatePermissionVM, user=Depends(current_user)): if not await user.has_perm('permission.update'): raise x.PermissionDenied() try: await Permission.update_permission(perm) except BaseORMException: raise x.ServiceError() except Exception: raise x.AppError()
async def remove_grouppermission(res: Response, gp: GroupPermissionVM, user=Depends(current_user)): if not await user.has_perm('permission.detach'): raise x.PermissionDenied() try: if group := await Group.get_or_none(name=gp.name).only('id'): if permlist := await Permission.filter(code__in=listify(gp.codes) ).only('id'): await group.permissions.remove(*permlist) res.status_code = 204
async def create_group(res: Response, group: CreateGroupVM, user=Depends(current_user)): if not await user.has_perm('group.create'): raise x.PermissionDenied() try: if groupinst := await Group.create_group(**group.dict()): res.status_code = 201 return groupinst.to_dict() except (BaseORMException, RedisError): raise x.ServiceError() except Exception: raise x.AppError()
async def remove_userpermission(res: Response, up: UserPermissionVM, user=Depends(current_user)): if not await user.has_perm('permission.detach'): raise x.PermissionDenied() try: if perms := await Permission.filter(code__in=listify(up.codes) ).values_list('id', flat=True): if userperms := await UserPermissions.filter( user_id=user.id, permission_id__in=perms): for item in userperms: await item.delete() await UserMod.get_and_cache(user.id) res.status_code = 204
async def delete_group(res: Response, user=Depends(current_user), group: str = Body(...)): if not await user.has_perm('group.delete'): raise x.PermissionDenied() if not group: raise x.FalsyDataError() try: if await Group.delete_group(group): res.status_code = 204 except (BaseORMException, RedisError): raise x.ServiceError() except Exception: raise x.AppError()
async def delete_permission(res: Response, code: str = Body(..., min_length=3, max_length=20), user=Depends(current_user)): if not await user.has_perm('permission.delete'): raise x.PermissionDenied() try: if perm := await Permission.get_or_none(code=code ).only('id', 'deleted_at'): # TODO: Update group cache # TODO: Find a place to rescan user permissions, maybe on /token? await perm.soft_delete() res.status_code = 204 except (BaseORMException, RedisError): raise x.ServiceError() except Exception: raise x.AppError()
async def create_permission(res: Response, perm: CreatePermissionVM, user=Depends(current_user)): if not await user.has_perm('permission.create'): raise x.PermissionDenied() if not perm.code: raise x.FalsyDataError() try: perm.name = perm.name or ' '.join(i.capitalize() for i in perm.code.split('.')) if perm := await Permission.create(**perm.dict()): res.status_code = 201 return perm.to_dict() except BaseORMException: raise x.ServiceError() except Exception: raise x.AppError()
async def detach_permission(res: Response, user=Depends(current_user), perms=Body(...)): if not await user.has_perm('permission.detach'): raise x.PermissionDenied() if not perms: raise x.FalsyDataError() try: usermod = await UserMod.get_or_none(email=user.email).only('id') if not usermod: raise x.NotFoundError('User') await usermod.remove_permission(*listify(perms)) res.status_code = 204 except BaseORMException: raise x.ServiceError() except Exception: raise x.AppError()
async def add_group(res: Response, user=Depends(current_user), group: str = Body(...)): if not await user.has_perm('group.attach'): raise x.PermissionDenied() if not group: raise x.FalsyDataError() try: usermod = await UserMod.get_or_none(email=user.email).only('id') if not usermod: raise x.NotFoundError('User') if await usermod.add_group(group): res.status_code = 204 except BaseORMException: raise x.ServiceError() except Exception: raise x.AppError()
async def assign_userpermission(res: Response, up: UserPermissionVM, user=Depends(current_user)): if not await user.has_perm('permission.attach'): raise x.PermissionDenied() try: if usermod := await UserMod.get_or_none(pk=user.id).only('id'): if codes := list(set(listify(up.codes)) - set(user.permissions)): if perms := await Permission.filter(code__in=codes).only('id'): ll = [] for perm in perms: ll.append( UserPermissions(user=usermod, permission=perm, author=usermod)) await UserPermissions.bulk_create(ll) await UserMod.get_and_cache(user.id) res.status_code = 204
async def new_access_token(response: Response, refresh_token: Optional[str] = Cookie(None)): """ Create a new access_token with the refresh_token cookie. If the refresh_token is still valid then a new access_token is generated. If it's expired then it is equivalent to being logged out. The refresh_token is renewed for every login to prevent accidental logouts. """ try: if refresh_token is None: raise Exception # TODO: Access the cache instead of querying it token = await TokenMod.get(token=refresh_token, is_blacklisted=False) \ .only('id', 'token', 'expires', 'author_id') user = await userdb.get(token.author_id) mins = expires(token.expires) if mins <= 0: raise Exception elif mins <= s.REFRESH_TOKEN_CUTOFF: # refresh the refresh_token anyway before it expires try: token = await update_refresh_token(user, token=token) except DoesNotExist: token = await create_refresh_token(user) # Generate a new cookie cookie = refresh_cookie(REFRESH_TOKEN_KEY, token) response.set_cookie(**cookie) return await jwtauth.get_login_response(user, response) except Exception: del response.headers['authorization'] response.delete_cookie(REFRESH_TOKEN_KEY) raise x.PermissionDenied()
async def update_group(res: Response, groupdata: UpdateGroupVM, user=Depends(current_user)): if not await user.has_perm('group.update'): raise x.PermissionDenied() try: group = await Group.get_or_none(pk=groupdata.id ).only('id', 'name', 'summary') if not group: raise x.NotFoundError('Group') await group.update_group(groupdata) res.status_code = 204 # Update the cache if exists oldkey = s.CACHE_GROUPNAME.format(group.name) newkey = s.CACHE_GROUPNAME.format(groupdata.name) if red.exists(oldkey): formatted_oldkey = red.formatkey(oldkey) formatted_newkey = red.formatkey(newkey) red.rename(formatted_oldkey, formatted_newkey) except (BaseORMException, RedisError): raise x.BADERROR_503() except Exception: raise x.AppError()