Пример #1
0
 async def add_post(user_id: int, post: InPost) -> TaskResponse:
     user = await UsersDataAccessLayer.get_user(user_id, without_error=True)
     if not user:
         raise DALError(HTTPStatus.NOT_FOUND.value,
                        Message.USER_DOES_NOT_EXISTS.value)
     ids = post.marked_users_ids
     if ids is not None and (
             not await PostsDAL._are_marked_users_correct(ids)
             or user_id in ids):
         raise DALError(HTTPStatus.BAD_REQUEST.value,
                        Message.INCORRECTLY_MARKED_USERS.value)
     task_id = str(uuid4())
     job = RedisInstances.redis_queue().enqueue(process_image, user_id,
                                                post, task_id)
     async_redis = await RedisInstances.async_redis()
     async_redis.sadd(RedisKey.TASKS_IN_PROGRESS.value, task_id)
     job_result: Optional[WorkerResult] = job.result
     if job_result:
         if job_result.post_id:
             return TaskResponse(
                 task_id=task_id,
                 status=Message.POST_READY.value,
                 post_id=job_result.post_id,
             )
         return TaskResponse(
             task_id=task_id,
             status=Message.POST_TASK_FALLEN.value,
             error_text=job_result.error,
         )
     return TaskResponse(task_id=task_id,
                         status=Message.POST_ACCEPTED_FOR_PROCESSING.value)
Пример #2
0
def _authenticate_user(username: str, password: str) -> Awaitable[OutUser]:
    message = Message.INCORRECT_USERNAME_OR_PASSWORD.value
    with create_session() as session:
        user: Optional[User] = session.query(User).filter(
            User.username == username).first()
        user = deepcopy(user)
    if user is None:
        raise DALError(HTTPStatus.UNAUTHORIZED.value, message)
    if _is_password_correct(password, user.password_hash):
        return OutUser.from_orm(user)  # type: ignore
    raise DALError(HTTPStatus.UNAUTHORIZED.value, message)
Пример #3
0
def _get_user_id(token: str) -> int:
    try:
        payload: Dict[str, Any] = jwt.decode(token,
                                             SECRET_KEY,
                                             algorithms=[ALGORITHM])
        user_id = payload.get('sub')
        if not user_id or not isinstance(user_id, int):
            raise DALError(HTTPStatus.UNAUTHORIZED.value,
                           Message.NOT_EXPECTING_PAYLOAD.value)
        return user_id
    except PyJWTError:
        raise DALError(HTTPStatus.UNAUTHORIZED.value,
                       Message.COULD_NOT_VALIDATE_CREDENTIALS.value)
Пример #4
0
 def _get_post(post_id: int, session: Session) -> Awaitable[DBPost]:
     post: DBPost = session.query(DBPost).filter(
         DBPost.id == post_id).first()
     if not post:
         raise DALError(HTTPStatus.NOT_FOUND.value,
                        Message.POST_NOT_EXISTS.value)
     return post  # type: ignore
Пример #5
0
def get_all_user_images(user_id: int) -> List[ImageWithPath]:
    users_folder = _get_project_root() / _get_name_for_grouping_id(user_id)
    user_folder = users_folder / str(user_id)
    if not user_folder.exists():
        raise DALError(HTTPStatus.NOT_FOUND.value,
                       Message.USER_DOES_NOT_HAVE_IMAGES.value)
    return _get_all_images_from_folder(user_folder)
Пример #6
0
def get_image(image_path: Path) -> Base64:
    if not image_path.exists():
        raise DALError(HTTPStatus.NOT_FOUND.value,
                       Message.IMAGE_DOES_NOT_EXISTS_ON_STORAGE.value)
    with image_path.open('rb') as f:
        image_bytes = f.read()
        return encode_bytes_to_base64(image_bytes)
Пример #7
0
async def _get_user_from_db(user_id: int) -> UserWithTokens:
    user = await UsersDataAccessLayer.get_user(user_id,
                                               without_error=True,
                                               need_tokens=True)
    if not user:
        raise DALError(HTTPStatus.UNAUTHORIZED.value,
                       Message.USER_DOES_NOT_EXISTS.value)
    return user  # type: ignore
Пример #8
0
 async def get_posts(user_id: int) -> List[PostWithImage]:
     with create_session() as session:
         user = session.query(User).filter(User.id == user_id).first()
         if not user:
             raise DALError(HTTPStatus.NOT_FOUND.value,
                            Message.USER_DOES_NOT_EXISTS.value)
         posts = user.posts
         if not posts:
             raise DALError(HTTPStatus.NOT_FOUND.value,
                            Message.POSTS_DO_NOT_EXIST.value)
         try:
             images: List[
                 ImageWithPath] = await storage_client.get_all_user_images(
                     user_id)
         except StorageError as e:
             raise DALError(HTTPStatus.BAD_REQUEST.value, e)
         return join_posts_with_images(posts, images)
Пример #9
0
def test_add_user_returns_error_message_when_error_raised(
        client: TestClient, in_user, mocker):
    mocker.patch.object(UsersDataAccessLayer,
                        'add_user').side_effect = DALError(
                            HTTPStatus.BAD_REQUEST.value,
                            Message.USER_ALREADY_EXISTS.value)
    response: Response = client.post('/users/', json=dict(in_user))
    assert response.status_code == HTTPStatus.BAD_REQUEST
    assert response.json()['detail'] == Message.USER_ALREADY_EXISTS.value
Пример #10
0
def test_login_returns_expected_error(mocked_auth, client, auth_data):
    mocked_auth.generate_tokens.side_effect = DALError(
        HTTPStatus.UNAUTHORIZED.value,
        Message.INCORRECT_USERNAME_OR_PASSWORD.value)
    response = client.post('/auth/token', data=auth_data)
    assert response.status_code == HTTPStatus.UNAUTHORIZED
    json = response.json()
    assert len(json) == 1
    assert json['detail'] == Message.INCORRECT_USERNAME_OR_PASSWORD.value
Пример #11
0
def test_refresh_token_with_error_returns_expected_value(
        mocked_auth, client, refresh_token_payload):
    mocked_auth.refresh_tokens.side_effect = DALError(
        HTTPStatus.BAD_REQUEST.value, Message.INVALID_REFRESH_TOKEN.value)
    response = client.post('/auth/fresh_token', json=refresh_token_payload)
    assert response.status_code == HTTPStatus.BAD_REQUEST
    json = response.json()
    assert len(json) == 1
    assert json['detail'] == Message.INVALID_REFRESH_TOKEN.value
Пример #12
0
async def refresh_tokens(refresh_token: str) -> TokensResponse:
    '''
    Проверяет refresh_token и возвращает новую пару токенов
    '''
    user_id = _get_user_id(refresh_token)
    user = await _get_user_from_db(user_id)
    if not _is_valid_token(refresh_token, user.refresh_token.decode()):
        raise DALError(HTTPStatus.UNAUTHORIZED.value,
                       Message.INVALID_REFRESH_TOKEN.value)
    return await _create_tokens(user)
Пример #13
0
 async def like(post_id: int, user_id_who_likes: int) -> List[OutUser]:
     with create_session() as session:
         post = await PostDAL._get_post(post_id, session)
         likes = post.likes
         user = await PostDAL._get_user(user_id_who_likes, session)
         if PostDAL._is_user_has_like(likes, user):
             raise DALError(
                 HTTPStatus.BAD_REQUEST.value,
                 Message.USER_HAS_ALREADY_LIKE_THIS_POST.value,
             )
         likes.append(user)
         return [OutUser.from_orm(user) for user in likes]
Пример #14
0
async def check_authorization(token: str = Depends(oauth_scheme), ) -> OutUser:
    '''
    Обрабатывает jwt
    :raises HttpException со статусом 401 если произошла ошибка при обработке токена
    :return: user
    '''
    user_id = _get_user_id(token)
    user = await _get_user_from_db(user_id)
    if _is_valid_token(token, user.access_token.decode()):
        return OutUser.from_orm(user)
    raise DALError(HTTPStatus.UNAUTHORIZED.value,
                   Message.ACCESS_TOKEN_OUTDATED.value)
Пример #15
0
 async def remove_like(post_id: int,
                       user_id_who_wants_delete_like: int) -> None:
     with create_session() as session:
         post = await PostDAL._get_post(post_id, session)
         user = await PostDAL._get_user(user_id_who_wants_delete_like,
                                        session)
         likes = post.likes
         if not PostDAL._is_user_has_like(likes, user):
             raise DALError(
                 HTTPStatus.NOT_FOUND.value,
                 Message.USER_DID_NOT_LIKE_THIS_POST.value,
             )
         likes.remove(user)
Пример #16
0
 async def get_post(post_id: int) -> PostWithImage:
     with create_session() as session:
         post = await PostDAL._get_post(post_id, session)
         try:
             image: Base64 = (await
                              storage_client.get_image_from_storage_async(
                                  post.image_path)).image
         except StorageError:
             raise DALError(
                 HTTPStatus.NOT_FOUND.value,
                 Message.IMAGE_DOES_NOT_EXISTS_ON_STORAGE.value,
             )
         serialized_post: Post = serialize(post)  # type: ignore
     return PostWithImage(**serialized_post.dict(), image=image)
Пример #17
0
 async def get_task_status(task_id: str) -> TaskResponse:
     redis = await RedisInstances.async_redis()
     solved_task: Optional[bytes] = (await redis.hmget(
         RedisKey.SOLVED_TASKS.value, task_id))[0]
     if solved_task:
         return TaskResponse(
             task_id=task_id,
             status=Message.POST_READY.value,
             post_id=solved_task.decode(),
         )
     fallen_task: Optional[bytes] = (await redis.hmget(
         RedisKey.FALLEN_TASKS.value, task_id))[0]
     if fallen_task:
         return TaskResponse(
             task_id=task_id,
             status=Message.POST_TASK_FALLEN.value,
             error_text=fallen_task.decode(),
         )
     if await redis.sismember(RedisKey.TASKS_IN_PROGRESS.value, task_id):
         return TaskResponse(
             task_id=task_id,
             status=Message.POST_ACCEPTED_FOR_PROCESSING.value)
     raise DALError(HTTPStatus.NOT_FOUND.value,
                    Message.TASK_NOT_EXISTS.value)
Пример #18
0
 def _get_user(user_id: int, session: Session) -> Awaitable[User]:
     user = session.query(User).filter(User.id == user_id).first()
     if user:
         return user
     raise DALError(HTTPStatus.NOT_FOUND.value,
                    Message.USER_DOES_NOT_EXISTS.value)