Esempio n. 1
0
def get_uuid(
    principal: Principal, db: Session, tenant_uuid: Optional[UUID], create: bool = True
) -> UUID4:
    if principal is None:
        if tenant_uuid is None:
            raise HTTPException(
                status_code=400,
                detail=dumps(
                    {
                        "detail": [
                            {
                                "loc": ["body", "tenant_uuid"],
                                "msg": "field required",
                                "type": "value_error.missing",
                            }
                        ]
                    }
                ),
                headers={"Content-Type": "text/json;charset=\"UTF8\""},
            )
    elif tenant_uuid is not None and tenant_uuid != UUID4(principal.tenant_uuid):
        raise HTTPException(
            status_code=403, detail="Token not valid for tenant_uuid %s" % tenant_uuid
        )
    else:
        tenant_uuid = UUID4(principal.tenant_uuid)
    if create and get_tenant_by_uuid(db, str(tenant_uuid)) is None:
        tenant = schema.TenantCreate(name=str(tenant_uuid), uuid=tenant_uuid)
        create_tenant(db, principal, tenant)
    return tenant_uuid
Esempio n. 2
0
    async def __call__(
        self,
        credentials: Optional[str],
        user_db: BaseUserDatabase,
    ) -> Optional[BaseUserDB]:
        if credentials is None:
            return None

        try:
            data = jwt.decode(
                credentials,
                self.secret,
                audience=self.token_audience,
                algorithms=[JWT_ALGORITHM],
            )
            user_id = data.get("user_id")
            if user_id is None:
                return None
        except jwt.PyJWTError:
            return None

        try:
            user_uiid = UUID4(user_id)
            return await user_db.get(user_uiid)
        except ValueError:
            return None
Esempio n. 3
0
 async def __call__(self, credentials: Optional[str], user_db: BaseUserDatabase):
     if credentials is not None:
         try:
             token_uuid = UUID4(credentials)
             return await user_db.get(token_uuid)
         except ValueError:
             return None
     return None
Esempio n. 4
0
    async def reset_password(
        request: Request, token: str = Body(...), password: str = Body(...)
    ):
        try:
            data = jwt.decode(
                token,
                reset_password_token_secret,
                audience=RESET_PASSWORD_TOKEN_AUDIENCE,
                algorithms=[JWT_ALGORITHM],
            )
            user_id = data.get("user_id")
            if user_id is None:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail=ErrorCode.RESET_PASSWORD_BAD_TOKEN,
                )

            try:
                user_uiid = UUID4(user_id)
            except ValueError:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail=ErrorCode.RESET_PASSWORD_BAD_TOKEN,
                )

            user = await user_db.get(user_uiid)
            if user is None or not user.is_active:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail=ErrorCode.RESET_PASSWORD_BAD_TOKEN,
                )

            if validate_password:
                try:
                    await validate_password(password, user)
                except InvalidPasswordException as e:
                    raise HTTPException(
                        status_code=status.HTTP_400_BAD_REQUEST,
                        detail={
                            "code": ErrorCode.RESET_PASSWORD_INVALID_PASSWORD,
                            "reason": e.reason,
                        },
                    )

            user.hashed_password = get_password_hash(password)
            await user_db.update(user)
            if after_reset_password:
                await run_handler(after_reset_password, user, request)
        except jwt.PyJWTError:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=ErrorCode.RESET_PASSWORD_BAD_TOKEN,
            )
Esempio n. 5
0
        async def activate(request: Request, token: str = Body(...)):
            try:
                data = jwt.decode(
                    token,
                    activation_token_secret,
                    audience=ACTIVATE_USER_TOKEN_AUDIENCE,
                    algorithms=[JWT_ALGORITHM],
                )
            except jwt.exceptions.ExpiredSignatureError:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail=ErrorCode.ACTIVATE_USER_TOKEN_EXPIRED,
                )
            except jwt.PyJWTError:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail=ErrorCode.ACTIVATE_USER_BAD_TOKEN,
                )

            user_id = data.get("user_id")
            if user_id is None:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail=ErrorCode.ACTIVATE_USER_BAD_TOKEN,
                )

            try:
                user_uuid = UUID4(user_id)
            except ValueError:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail=ErrorCode.ACTIVATE_USER_BAD_TOKEN,
                )

            user = await user_db.get(user_uuid)
            if user is None:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail=ErrorCode.ACTIVATE_USER_BAD_TOKEN,
                )

            if user.is_active:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail=ErrorCode.ACTIVATE_USER_LINK_USED,
                )
            user.is_active = True

            await user_db.update(user)
            if after_register:
                await run_handler(after_register, user, request)
            return user
Esempio n. 6
0
 async def read_token(
         self, token: Optional[str],
         user_manager: BaseUserManager[UserCreate,
                                       UserDB]) -> Optional[UserDB]:
     if token is not None:
         try:
             token_uuid = UUID4(token)
             return await user_manager.get(token_uuid)
         except ValueError:
             return None
         except UserNotExists:
             return None
     return None
Esempio n. 7
0
    async def verify(self, token: str, request: Optional[Request] = None) -> models.UD:
        """
        Validate a verification request.

        Changes the is_verified flag of the user to True.

        Triggers the on_after_verify handler on success.

        :param token: The verification token generated by request_verify.
        :param request: Optional FastAPI request that
        triggered the operation, defaults to None.
        :raises InvalidVerifyToken: The token is invalid or expired.
        :raises UserAlreadyVerified: The user is already verified.
        :return: The verified user.
        """
        try:
            data = decode_jwt(
                token,
                self.verification_token_secret,
                [self.verification_token_audience],
            )
        except jwt.PyJWTError:
            raise InvalidVerifyToken()

        try:
            user_id = data["user_id"]
            email = data["email"]
        except KeyError:
            raise InvalidVerifyToken()

        try:
            user = await self.get_by_email(email)
        except UserNotExists:
            raise InvalidVerifyToken()

        try:
            user_uuid = UUID4(user_id)
        except ValueError:
            raise InvalidVerifyToken()

        if user_uuid != user.id:
            raise InvalidVerifyToken()

        if user.is_verified:
            raise UserAlreadyVerified()

        verified_user = await self._update(user, {"is_verified": True})

        await self.on_after_verify(verified_user, request)

        return verified_user
Esempio n. 8
0
 async def get(cls, request: web.Request):
     """Get file from storage by UUID."""
     try:
         uuid = UUID4(request.match_info["uuid"])
     except ValueError:
         raise web.HTTPBadRequest
     app: AioHttpApplication = cast(AioHttpApplication, request.app)
     conn: Connection
     query = retrieve_data_by_uuid()
     async with app.db.acquire() as conn:
         data = await conn.fetchrow(query, uuid)
         if not data:
             raise web.HTTPNotFound
         return web.Response(body=data["data"],
                             content_type=data["content_type"])
async def get_current_token_data(token: str = Depends(oauth2_scheme)):
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="Could not validate credentials",
        headers={"WWW-Authenticate": "Bearer"},
    )
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        uuid = payload.get("sub")
        if uuid is None:
            raise credentials_exception
        role = payload.get("role")
        token_data = TokenData(id=UUID4(uuid), role=role)
    except JWTError:
        raise credentials_exception

    return token_data
Esempio n. 10
0
    async def read_token(
        self, token: Optional[str], user_manager: BaseUserManager[models.UC, models.UD]
    ) -> Optional[models.UD]:
        if token is None:
            return None

        user_id = await self.redis.get(token)
        if user_id is None:
            return None

        try:
            user_uiid = UUID4(user_id)
            return await user_manager.get(user_uiid)
        except ValueError:
            return None
        except UserNotExists:
            return None
Esempio n. 11
0
    async def reset_password(
        self, token: str, password: str, request: Optional[Request] = None
    ) -> models.UD:
        """
        Reset the password of a user.

        Triggers the on_after_reset_password handler on success.

        :param token: The token generated by forgot_password.
        :param password: The new password to set.
        :param request: Optional FastAPI request that
        triggered the operation, defaults to None.
        :raises InvalidResetPasswordToken: The token is invalid or expired.
        :raises UserInactive: The user is inactive.
        :raises InvalidPasswordException: The password is invalid.
        :return: The user with updated password.
        """
        try:
            data = decode_jwt(
                token,
                self.reset_password_token_secret,
                [self.reset_password_token_audience],
            )
        except jwt.PyJWTError:
            raise InvalidResetPasswordToken()

        try:
            user_id = data["user_id"]
        except KeyError:
            raise InvalidResetPasswordToken()

        try:
            user_uuid = UUID4(user_id)
        except ValueError:
            raise InvalidResetPasswordToken()

        user = await self.get(user_uuid)

        if not user.is_active:
            raise UserInactive()

        updated_user = await self._update(user, {"password": password})

        await self.on_after_reset_password(user, request)

        return updated_user
Esempio n. 12
0
async def reset_password(_: Response, formdata: ResetPasswordVM):
    token = formdata.token
    password = formdata.password

    try:
        data = jwt.decode(token,
                          s.SECRET_KEY_EMAIL,
                          audience=RESET_PASSWORD_TOKEN_AUDIENCE,
                          algorithms=[JWT_ALGORITHM])
        user_id = data.get("user_id")
        if user_id is None:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=ErrorCode.RESET_PASSWORD_BAD_TOKEN,
            )

        try:
            user_uuid = UUID4(user_id)
        except ValueError:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=ErrorCode.RESET_PASSWORD_BAD_TOKEN,
            )

        user = await userdb.get(user_uuid)
        if user is None or not user.is_active:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=ErrorCode.RESET_PASSWORD_BAD_TOKEN,
            )

        user.hashed_password = get_password_hash(password)
        # Use UserDB in order to remove the extra attributes generated by UserDBComplete
        user = UserDB(**user.dict())
        await userdb.update(user)
        return True
    except jwt.PyJWTError:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=ErrorCode.RESET_PASSWORD_BAD_TOKEN,
        )
Esempio n. 13
0
    async def read_token(
        self, token: Optional[str], user_manager: BaseUserManager[models.UC,
                                                                  models.UD]
    ) -> Optional[models.UD]:
        if token is None:
            return None

        try:
            data = decode_jwt(token, self.secret, self.token_audience)
            user_id = data.get("user_id")
            if user_id is None:
                return None
        except jwt.PyJWTError:
            return None

        try:
            user_uiid = UUID4(user_id)
            return await user_manager.get(user_uiid)
        except ValueError:
            return None
        except UserNotExists:
            return None
Esempio n. 14
0
    async def reset_password(token: str = Body(...),
                             password: str = Body(...)):
        try:
            data = jwt.decode(
                token,
                reset_password_token_secret,
                audience=RESET_PASSWORD_TOKEN_AUDIENCE,
                algorithms=[JWT_ALGORITHM],
            )
            user_id = data.get("user_id")
            if user_id is None:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail=ErrorCode.RESET_PASSWORD_BAD_TOKEN,
                )

            try:
                user_uiid = UUID4(user_id)
            except ValueError:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail=ErrorCode.RESET_PASSWORD_BAD_TOKEN,
                )

            user = await user_db.get(user_uiid)
            if user is None or not user.is_active:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail=ErrorCode.RESET_PASSWORD_BAD_TOKEN,
                )

            user.hashed_password = get_password_hash(password)
            await user_db.update(user)
        except jwt.PyJWTError:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=ErrorCode.RESET_PASSWORD_BAD_TOKEN,
            )
    async def test_valid_body_correct_token_produced(
            self, test_app_client: httpx.AsyncClient, after_register,
            activation_callback):
        json = {
            "email": "*****@*****.**",
            "password": "******",
        }
        response = await test_app_client.post("/register", json=json)
        assert response.status_code == status.HTTP_201_CREATED
        assert after_register.called is False
        assert activation_callback.called is True

        token = activation_callback.call_args[0][1]
        data = jwt.decode(
            token,
            activation_token_secret,
            audience=ACTIVATE_USER_TOKEN_AUDIENCE,
            algorithms=[JWT_ALGORITHM],
        )
        user_id = data.get("user_id")
        user_uuid = UUID4(user_id)
        created_user = activation_callback.call_args[0][0]
        assert user_uuid == created_user.id
Esempio n. 16
0
 async def test_not_existing_user(self, user_manager: UserManagerMock):
     with pytest.raises(UserNotExists):
         await user_manager.get(
             UUID4("d35d213e-f3d8-4f08-954a-7e0d1bea286f"))
Esempio n. 17
0
    async def verify(request: Request, token: str = Body(..., embed=True)):
        try:
            data = jwt.decode(
                token,
                verification_token_secret,
                audience=VERIFY_USER_TOKEN_AUDIENCE,
                algorithms=[JWT_ALGORITHM],
            )
        except jwt.exceptions.ExpiredSignatureError:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=ErrorCode.VERIFY_USER_TOKEN_EXPIRED,
            )
        except jwt.PyJWTError:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=ErrorCode.VERIFY_USER_BAD_TOKEN,
            )

        user_id = data.get("user_id")
        email = cast(EmailStr, data.get("email"))

        if user_id is None:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=ErrorCode.VERIFY_USER_BAD_TOKEN,
            )

        try:
            user_check = await get_user(email)
        except UserNotExists:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=ErrorCode.VERIFY_USER_BAD_TOKEN,
            )

        try:
            user_uuid = UUID4(user_id)
        except ValueError:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=ErrorCode.VERIFY_USER_BAD_TOKEN,
            )

        if user_check.id != user_uuid:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=ErrorCode.VERIFY_USER_BAD_TOKEN,
            )

        try:
            user = await verify_user(user_check)
        except UserAlreadyVerified:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=ErrorCode.VERIFY_USER_ALREADY_VERIFIED,
            )

        if after_verification:
            await run_handler(after_verification, user, request)

        return user
Esempio n. 18
0
from typing import Optional

from pydantic import UUID4

from aggreagates.reservations.domain.repository import ResourceRepository
from aggreagates.reservations.domain.resource import Resource, ResourceId

initial_resource = Resource(
    resource_id=ResourceId(id=UUID4("0c51b998-e97b-4e8d-9df1-116e2c9eb384")),
    reservations=[]
)


class InMemoryResourceRepository(ResourceRepository):
    def __init__(self):
        self.data = {
            initial_resource.resource_id: initial_resource
        }

    def get(self, resource_id: ResourceId) -> Optional[Resource]:
        return self.data.get(resource_id)

    def save(self, resource: Resource) -> None:
        self.data[resource.resource_id] = resource
Esempio n. 19
0
 def from_string(cls, id: str):
     return cls(id=UUID4(id))