Esempio n. 1
0
	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)
Esempio n. 2
0
	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)
Esempio n. 3
0
	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)
Esempio n. 4
0
	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)
Esempio n. 5
0
    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)
Esempio n. 6
0
    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)
Esempio n. 7
0
    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)
Esempio n. 8
0
    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)
Esempio n. 9
0
    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)