def create(self, request: 'th_Request') -> responses.Response: validator = validation.Dict({ "user_id": validation.Integer(), "reason": validation.String(length_min=orm.UsersBans.REASON_LEN_MIN, length_max=orm.UsersBans.REASON_LEN_MAX) }, allow_undefined_keys=not self._strict_requests) try: # Validation try: validator.validate(request.body) except validation.Error as ve: return responses.Unprocessable(ve.errors) # Authorization auth_response = self._s_auth.authorize(Action.USERS_BANS_CREATE, request.user) if not isinstance(auth_response, responses.OKEmpty): return auth_response # Get the user's ID from request (Which gets it's user info from a token) if not isinstance(request.user, Registered): return responses.UnauthorizedNotLoggedIn() user: Registered = request.user # Query try: self._m_users_bans.create(request.body["user_id"], user.user_id, request.body["reason"]) return responses.Created() except IntegrityError: return responses.NotFoundByID("user_id") except SQLAlchemyError as sqlae: return responses.DatabaseException(sqlae)
def update(self, request: 'th_Request') -> responses.Response: validator = validation.Dict({ "user_id": validation.Integer(), "reason": validation.String(length_min=orm.UsersBans.REASON_LEN_MIN, length_max=orm.UsersBans.REASON_LEN_MAX) }, allow_undefined_keys=not self._strict_requests) try: # Validation try: validator.validate(request.body) except validation.Error as ve: return responses.Unprocessable(ve.errors) user_id = request.body["user_id"] # Query for authorization try: orm_user_ban = self._m_users_bans.get(user_id) except NoResultFound: return responses.NotFoundByID("user_id") # Authorization auth_response = self._s_auth.authorize(Action.USERS_BANS_UPDATE, request.user, orm_user_ban.banner_id) if not isinstance(auth_response, responses.OKEmpty): return auth_response # Query try: self._m_users_bans.update(user_id, request.body["reason"]) return responses.OKEmpty() except NoResultFound: return responses.NotFoundByID("user_id") except SQLAlchemyError as sqlae: return responses.DatabaseException(sqlae)
def create(self, request: 'th_Request') -> responses.Response: validator = validation.Dict({ "title": validation.String(length_min=orm.Rooms.TITLE_LEN_MIN, length_max=orm.Rooms.TITLE_LEN_MAX), "is_public": validation.Boolean() }) try: # Validation try: validator.validate(request.body) except validation.Error as ve: return responses.Unprocessable(ve.errors) # Authorization auth_response = self._s_auth.authorize(Action.ROOMS_CREATE, request.user) if not isinstance(auth_response, responses.OKEmpty): return auth_response # Get the user's ID from request (Which gets it's user info from a token) if not isinstance(request.user, Registered): return responses.UnauthorizedNotLoggedIn() user: Registered = request.user # Query try: self._m_rooms.create(user.user_id, request.body["is_public"], request.body["title"]) return responses.Created() except IntegrityError: return responses.NotFoundByID("user_id") except SQLAlchemyError as sqlae: return responses.DatabaseException(sqlae)
def update(self, request: 'th_Request') -> responses.Response: validator = validation.Dict({ "room_id": validation.Integer(), "title": validation.String(length_min=orm.Rooms.TITLE_LEN_MIN, length_max=orm.Rooms.TITLE_LEN_MAX), }) try: # Validation try: validator.validate(request.body) except validation.Error as ve: return responses.Unprocessable(ve.errors) room_id = request.body["room_id"] # Query for authorization try: orm_room = self._m_rooms.get(room_id) except NoResultFound: return responses.NotFoundByID("room_id") # Authorization auth_response = self._s_auth.authorize(Action.ROOMS_UPDATE_TITLE, request.user, orm_room.user_id) if not isinstance(auth_response, responses.OKEmpty): return auth_response try: self._m_rooms.update(room_id, request.body["title"]) return responses.OKEmpty() except NoResultFound: return responses.NotFoundByID("room_id") except SQLAlchemyError as sqlae: return responses.DatabaseException(sqlae)
def create(self, request: 'th_Request') -> responses.Response: validator = validation.Dict( { "name": validation.String(length_min=orm.Users.NAME_LEN_MIN, length_max=orm.Users.NAME_LEN_MAX), "login": validation.String(length_min=orm.Users.LOGIN_LEN_MIN, length_max=orm.Users.LOGIN_LEN_MAX), "password": validation.String(length_min=orm.Users.PASSWORD_LEN_MIN, length_max=orm.Users.PASSWORD_LEN_MAX) }, allow_undefined_keys=not self._strict_requests) try: # Authorization auth_response = self._s_auth.authorize(Action.USERS_CREATE, request.user) if not isinstance(auth_response, responses.OKEmpty): return auth_response # Validation try: validator.validate(request.body) except validation.Error as ve: return responses.Unprocessable(ve.errors) # Hash password try: passhash = self._password_hasher.hash(request.body["password"]) except HashingError as he: return responses.InternalException( he, {"password": ["Could not be hashed"]}) # Query try: self._m_users.create(Roles.USER.id_, request.body["login"], request.body["name"], passhash) return responses.Created() except IntegrityError: return responses.ConflictID("login") except SQLAlchemyError as sqlae: return responses.DatabaseException(sqlae)
def create(self, request: 'th_Request') -> responses.Response: validator = validation.Dict( { "room_id": validation.Integer(), "content": validation.String(length_min=orm.Posts.CONTENT_LEN_MIN, length_max=orm.Posts.CONTENT_LEN_MAX) }, allow_undefined_keys=not self._strict_requests) try: print(request.body) # Validation try: validator.validate(request.body) except validation.Error as ve: return responses.Unprocessable(ve.errors) room_id = request.body["room_id"] # Queries for authorization try: orm_room = self._m_rooms.get(room_id) except NoResultFound: return responses.NotFoundByID("room_id") orm_room_users = self._m_rooms_users.get_all_by_room(orm_room.id) # Get the user's ID from request (Which gets it's user info from a token) if not isinstance(request.user, Registered): return responses.UnauthorizedNotLoggedIn() user: Registered = request.user # Authorize if orm_room.is_public: auth_response = self._s_auth.authorize( Action.POSTS_CREATE_PUBLIC, request.user) else: allowed_ids = [orm_room.user_id] + [ orm_ru.user_id for orm_ru in orm_room_users ] auth_response = self._s_auth.authorize(Action.POSTS_CREATE, request.user, allowed_ids) if not isinstance(auth_response, responses.OKEmpty): return auth_response # Query try: self._m_posts.create(room_id, user.user_id, request.body["content"]) return responses.Created() except IntegrityError: return responses.NotFoundByID("user_id") except SQLAlchemyError as sqlae: return responses.DatabaseException(sqlae)
def update(self, request: 'th_Request') -> responses.Response: validator = validation.Dict( { "post_id": validation.Integer(), "content": validation.String(length_min=orm.Posts.CONTENT_LEN_MIN, length_max=orm.Posts.CONTENT_LEN_MAX) }, allow_undefined_keys=not self._strict_requests) try: # Validation try: validator.validate(request.body) except validation.Error as ve: return responses.Unprocessable(ve.errors) post_id = request.body["post_id"] # Query for authorization try: orm_post = self._m_posts.get(post_id) except NoResultFound: return responses.NotFoundByID("post_id") # Authorization auth_response = self._s_auth.authorize(Action.POSTS_UPDATE, request.user, orm_post.user_id) if not isinstance(auth_response, responses.OKEmpty): return auth_response # TODO # Also possible to revoke update access to the user on lost access to the room # What about banned room checks try: self._m_posts.update(post_id, request.body["content"]) return responses.OKEmpty() except NoResultFound: return responses.NotFoundByID("post_id") except SQLAlchemyError as sqlae: return responses.DatabaseException(sqlae)
def login(self, request: 'th_Request') -> responses.Response: validator = validation.Dict( { "login": validation.String(), "password": validation.String() }, allow_undefined_keys=not self._strict_requests) try: # Validation try: validator.validate(request.body) except validation.Error as ve: return responses.Unprocessable(ve.errors) # Authorization auth_response = self._s_auth.authorize(Action.LOGIN, request.user) if not isinstance(auth_response, responses.OKEmpty): return auth_response # Query # Find user by login try: user = self._m_users.get_by_login(request.body["login"]) except NoResultFound: return responses.NotFoundByID("login") # Check if user is banned try: self._m_users_bans.get(user.id) return responses.Forbidden() except NoResultFound: # Not banned, ok pass # Verify password try: self._password_hasher.verify(user.passhash, request.body["password"]) except VerifyMismatchError: return responses.Unauthorized( {"all": ["Invalid login or password"]}) except (VerificationError, InvalidHash) as argonerr: return responses.InternalException( argonerr, {"password": ["Hashing error"]}) # Check rehash if self._password_hasher.check_needs_rehash(user.passhash): try: passhash_new = self._password_hasher.hash( request.body["password"]) self._m_users.update(user.id, passhash=passhash_new) except (HashingError, SQLAlchemyError, NoResultFound, MultipleResultsFound) as err: # Not crucial logging.exception(err) # Generate and return token token = jwt.Token.generate(jwt.Claims(user.id), self._private_key, user.passhash) return responses.OK({"token": token.to_string()}) except SQLAlchemyError as sqlae: return responses.DatabaseException(sqlae)
def update(self, request: 'th_Request') -> responses.Response: validator = validation.Dict( { "user_id": validation.Integer(), "role": validation.Integer(allow_none=True), "login": validation.String(allow_none=True, length_min=orm.Users.LOGIN_LEN_MIN, length_max=orm.Users.LOGIN_LEN_MAX), "name": validation.String(allow_none=True, length_min=orm.Users.NAME_LEN_MIN, length_max=orm.Users.NAME_LEN_MAX), "password": validation.String(allow_none=True, length_min=orm.Users.PASSWORD_LEN_MIN, length_max=orm.Users.PASSWORD_LEN_MAX) }, allow_undefined_keys=not self._strict_requests) try: # Validation try: validator.validate(request.body) except validation.Error as ve: return responses.Unprocessable(ve.errors) user_id = request.body["user_id"] # Authorization (certain attributes) if "name" in request.body: # Authorize name change auth_response = self._s_auth.authorize( Action.USERS_UPDATE_NAME, request.user, user_id) if not isinstance(auth_response, responses.OKEmpty): return auth_response if "role" in request.body: # Authorize role change auth_response = self._s_auth.authorize( Action.USERS_UPDATE_ROLE, request.user, None) if not isinstance(auth_response, responses.OKEmpty): return auth_response if "login" in request.body or "password" in request.body: # Authorize credential change auth_response = self._s_auth.authorize( Action.USERS_UPDATE_CRED, request.user, user_id) if not isinstance(auth_response, responses.OKEmpty): return auth_response # Hash password try: passhash = None if "password" not in request.body else self._password_hasher.hash( request.body["password"]) except HashingError as he: return responses.InternalException( he, {"password": ["Could not be hashed"]}) # Query try: self._m_users.update(user_id, request.body.get("role"), request.body.get("login"), request.body.get("name"), passhash) return responses.OKEmpty() except IntegrityError: return responses.ConflictID("login") except NoResultFound: return responses.NotFoundByID("user_id") except SQLAlchemyError as sqlae: return responses.DatabaseException(sqlae)