Ejemplo n.º 1
0
def test_invalid_fetch_user(setup):
    usecase, created_domain_user = setup
    usecase: FetchUserUseCase
    created_domain_user: DomainUser

    # by invalid selector
    assert usecase.execute(
        fetch_by_selector="invalid_selector",
        fetch_by_data="invalid_data(doesn't matter)"
    ) == Failure(
        error=
        "Fetch selector should be within this list ['id', 'name', 'email']")

    # by id
    assert usecase.execute(
        fetch_by_selector="id", fetch_by_data="1") == Failure(
            error='There is no user with id 1 to be fetched')

    # by name
    assert usecase.execute(
        fetch_by_selector="name", fetch_by_data="invalid") == Failure(
            error='There is no user with name invalid to be fetched')
    # by email
    assert usecase.execute(
        fetch_by_selector="email", fetch_by_data="invalid") == Failure(
            error='There is no user with email invalid to be fetched')
Ejemplo n.º 2
0
 def __wrapper(*args, **kwargs) -> Either[Failure, Any]:
     try:
         return func(*args, **kwargs)
     except ValidationError as ex:
         return Failure(error=str(ex).split("\n")[0].strip())
     except Exception as ex:
         return Failure(error=str(ex))
Ejemplo n.º 3
0
def test_invalid_update_user(setup):
    _add_usecase, delete_usecase, created_domain_user = setup
    _add_usecase: AddUserUseCase
    delete_usecase: DeleteUserUseCase
    created_domain_user: DomainUser

    # by invalid selector
    assert delete_usecase.execute(
        delete_by_selector="invalid_selector", delete_by_data="invalid_data"
    ) == Failure(
        error=
        "Delete selector should be within this list ['id', 'name', 'email']")

    # by id
    assert delete_usecase.execute(
        delete_by_selector="id", delete_by_data="invalid") == Failure(
            error='There is no user with id invalid to be deleted')

    # by name
    assert delete_usecase.execute(
        delete_by_selector="name", delete_by_data="invalid") == Failure(
            error='There is no user with name invalid to be deleted')

    # by email
    assert delete_usecase.execute(
        delete_by_selector="email", delete_by_data="invalid") == Failure(
            error='There is no user with email invalid to be deleted')
Ejemplo n.º 4
0
    def execute(self, *, username: str, age: int, password: str,
                email: Maybe[str],
                role: UserRole) -> Either[Failure, ApplicationUser]:
        domain_user_creation_status: Either[Failure, DomainUser] = create_user(
            name=username, age=age, password=password, email=email, role=role)
        if isinstance(domain_user_creation_status, Failure):
            return Failure(error=domain_user_creation_status.error)

        database_user_creation_status: Either[
            Failure, ApplicationUser] = self.__persistence.persist_user(
                user=domain_user_creation_status)
        if isinstance(database_user_creation_status, Failure):
            return Failure(error=database_user_creation_status.error)

        return database_user_creation_status
Ejemplo n.º 5
0
            def id(self, *, user_id: str) -> Either[Failure, ApplicationUser]:
                fetch_status: Maybe[ApplicationUser] = db["ids"].get(user_id)
                if isinstance(fetch_status, ApplicationUser):
                    return fetch_status

                return Failure(
                    error=f"There is no user with id {user_id} to be fetched")
Ejemplo n.º 6
0
    def fetch_access_token(self, *,
                           username: str) -> Either[Failure, AccessToken]:
        fetch_access_token_status = self.__db["tokens"].get(username, None)
        if fetch_access_token_status is not None:
            return fetch_access_token_status

        return Failure(error=f"There is no access token for user {username}")
Ejemplo n.º 7
0
            def id(self, *, user_id: str) -> Either[Failure, Success]:
                fetch_status: Maybe[ApplicationUser] = db["ids"].get(user_id)
                if isinstance(fetch_status, ApplicationUser):
                    self.__inner_delete_user(user=fetch_status)
                    return Success()

                return Failure(
                    error=f"There is no user with id {user_id} to be deleted")
Ejemplo n.º 8
0
            def email(self, *, user_email: str) -> Either[Failure, Success]:
                user_id: Maybe[str] = db["emails"].get(user_email)
                if user_id is not None:
                    self.__inner_delete_user(user=db["ids"][user_id])
                    return Success()

                return Failure(
                    error=
                    f"There is no user with email {user_email} to be deleted")
Ejemplo n.º 9
0
            def name(self, *, user_name: str) -> Either[Failure, Success]:
                user_id: Maybe[str] = db["names"].get(user_name)
                if user_id is not None:
                    self.__inner_delete_user(user=db["ids"][user_id])
                    return Success()

                return Failure(
                    error=
                    f"There is no user with name {user_name} to be deleted")
Ejemplo n.º 10
0
            def email(self, *,
                      user_email: str) -> Either[Failure, ApplicationUser]:
                user_id: str = db["emails"].get(user_email)
                if user_id is not None:
                    user: ApplicationUser = db["ids"][user_id]
                    return user

                return Failure(
                    error=
                    f"There is no user with email {user_email} to be fetched")
Ejemplo n.º 11
0
            def name(self, *,
                     user_name: str) -> Either[Failure, ApplicationUser]:
                user_id: str = db["names"].get(user_name)
                if user_id is not None:
                    user: ApplicationUser = db["ids"][user_id]
                    return user

                return Failure(
                    error=
                    f"There is no user with name {user_name} to be fetched")
Ejemplo n.º 12
0
def test_invalid_update_user(setup):
    usecase, created_domain_user = setup
    usecase: UpdateUserUseCase
    created_domain_user: DomainUser

    updated_domain_user: DomainUser = create_user(
        name="newname",
        age=created_domain_user.age + 10,
        password=created_domain_user.password,
        email=created_domain_user.email,
        role=created_domain_user.role)

    # by invalid selector
    assert usecase.execute(
        update_by_selector="invalid_selector",
        update_by_data="invalid_data",
        updated_user=updated_domain_user
    ) == Failure(
        error=
        "Update selector should be within this list ['id', 'name', 'email']")

    # by id
    assert usecase.execute(
        update_by_selector="id",
        update_by_data="invalid",
        updated_user=updated_domain_user) == Failure(
            error='There is no user with id invalid to be updated')

    # by name
    assert usecase.execute(
        update_by_selector="name",
        update_by_data="invalid",
        updated_user=updated_domain_user) == Failure(
            error='There is no user with name invalid to be updated')

    # by email
    assert usecase.execute(
        update_by_selector="email",
        update_by_data="invalid",
        updated_user=updated_domain_user) == Failure(
            error='There is no user with email invalid to be updated')
Ejemplo n.º 13
0
def test_invalid_add_user(setup):
    name = "test"
    age = 26
    password = "******"
    email = "*****@*****.**"
    role = UserRole.USER

    usecase: AddUserUseCase = setup
    # other variety of invalid data is covered on the user_tests itself
    assert usecase.execute(
        username=name, age=age, password=password, email=email,
        role=role) == Failure(error='password should be stronger.')
Ejemplo n.º 14
0
            def email(
                    self, *, user_email: str, updated_user: DomainUser
            ) -> Either[Failure, ApplicationUser]:
                user_id: Maybe[str] = db["emails"].get(user_email)
                if user_id is not None:
                    db["ids"][
                        user_id] = PersistenceInterface.from_domain_user_to_database_user(
                            user=updated_user, user_id=user_id)

                    return db["ids"][user_id]

                return Failure(
                    error=
                    f"There is no user with email {user_email} to be updated")
Ejemplo n.º 15
0
    def persist_user(self, *,
                     user: DomainUser) -> Either[Failure, ApplicationUser]:
        if self.__db["names"].get(user.name, None) is not None:
            return Failure(
                error=
                f"Username {user.name} is already exist, please use a different name."
            )
        persisted_user = PersistenceInterface.from_domain_user_to_database_user(
            user=user, user_id=str(self.__last_id))
        self.__db['ids'][str(self.__last_id)] = persisted_user
        self.__db['names'][user.name] = str(self.__last_id)
        self.__db['emails'][user.email] = str(self.__last_id)
        self.__last_id += 1

        return persisted_user
Ejemplo n.º 16
0
    def execute(self, *,
                fetch_by_selector: str,
                fetch_by_data: str) -> Either[Failure, ApplicationUser]:
        if fetch_by_selector not in _fetch_selectors:
            return Failure(error=f"Fetch selector should be within this list {_fetch_selectors}")

        selector_mapping = {
            "id": self.__persistence.fetch_user_by.id,
            "name": self.__persistence.fetch_user_by.name,
            "email": self.__persistence.fetch_user_by.email
        }

        fetch_user_status: Either[Failure, ApplicationUser] = selector_mapping[fetch_by_selector](
            **{f"user_{fetch_by_selector}": fetch_by_data}
        )
        return fetch_user_status
Ejemplo n.º 17
0
    def persist_access_token(self, *, username: str,
                             password: str) -> Either[Failure, AccessToken]:
        fetch_user_status = self._fetch_user_by().name(user_name=username)
        if isinstance(fetch_user_status, Failure):
            return fetch_user_status

        if fetch_user_status.password != password:
            return Failure(error=f"Invalid password for user {username}")

        # will make the generation better and generic later ;)
        access_token = AccessToken(
            token=encode({
                "username": username
            }, password, algorithm='HS256').decode("utf-8"))
        self.__db["tokens"][username] = access_token

        return access_token
Ejemplo n.º 18
0
            def id(self, *, user_id: str, updated_user: DomainUser
                   ) -> Either[Failure, ApplicationUser]:
                fetch_status: Maybe[ApplicationUser] = db["ids"].get(user_id)
                if isinstance(fetch_status, ApplicationUser):
                    db["ids"][
                        fetch_status.
                        id] = PersistenceInterface.from_domain_user_to_database_user(
                            user=updated_user, user_id=fetch_status.id)

                    access_token_status = db["tokens"].get(
                        fetch_status.name, None)
                    if access_token_status is not None:
                        del db["tokens"][fetch_status.name]
                        db["tokens"][updated_user.name] = access_token_status

                    return db["ids"][fetch_status.id]

                return Failure(
                    error=f"There is no user with id {user_id} to be updated")
Ejemplo n.º 19
0
    def execute(self, *, delete_by_selector: str,
                delete_by_data: str) -> Either[Failure, Success]:
        if delete_by_selector not in _delete_selectors:
            return Failure(
                error=
                f"Delete selector should be within this list {_delete_selectors}"
            )

        selector_mapping = {
            "id": self.__persistence.delete_user_by.id,
            "name": self.__persistence.delete_user_by.name,
            "email": self.__persistence.delete_user_by.email
        }

        delete_user_status: Either[
            Failure, Success] = selector_mapping[delete_by_selector](
                **{
                    f"user_{delete_by_selector}": delete_by_data
                })
        return delete_user_status
Ejemplo n.º 20
0
    def execute(self, *, update_by_selector: str, update_by_data: str,
                updated_user: DomainUser) -> Either[Failure, ApplicationUser]:
        if update_by_selector not in _update_selectors:
            return Failure(
                error=
                f"Update selector should be within this list {_update_selectors}"
            )

        selector_mapping = {
            "id": self.__persistence.update_user_by.id,
            "name": self.__persistence.update_user_by.name,
            "email": self.__persistence.update_user_by.email
        }

        update_user_status: Either[
            Failure, ApplicationUser] = selector_mapping[update_by_selector](
                **{
                    f"user_{update_by_selector}": update_by_data,
                    "updated_user": updated_user
                })
        return update_user_status
Ejemplo n.º 21
0
async def delete_user(
        *, delete_user_usecase: DeleteUserUseCase,
        fetch_user_usecase: FetchUserUseCase,
        fetch_access_token_usecase: FetchAccessTokenUseCase,
        request: Request) -> Callable[..., JsonEntity.of(_type=_A)]:
    username = request.headers.get("username", None)
    token = request.headers.get("access-token", None)
    if username is not None and token is not None:
        current_logged_user_fetch_status = fetch_user_usecase.execute(
            fetch_by_selector='name', fetch_by_data=username)
        access_token_status = fetch_access_token_usecase.execute(
            username=username)
        if isinstance(access_token_status, Failure):
            return JSONResponse(access_token_status.as_dict(), 401)

        if access_token_status.token != token:
            return JSONResponse(
                Failure(error=f"Invalid access token for the user {username}").
                as_dict(), 401)

        if isinstance(current_logged_user_fetch_status, ApplicationUser):
            params = request.query_params

            if len(params) > 0:
                selector_key = list(params.keys())[0]
                selector_value = params[selector_key]
                if current_logged_user_fetch_status.role.name == UserRole.ADMIN.name:
                    pass
                elif current_logged_user_fetch_status.role.name == UserRole.USER.name:
                    permission_error_json = JSONResponse(Failure(
                        error=
                        "Your current user permission is not satisfying this operation."
                    ).as_dict(),
                                                         status_code=401)

                    if selector_key == "id":
                        if current_logged_user_fetch_status.id != selector_value:
                            return permission_error_json
                    if selector_key == "name":
                        if current_logged_user_fetch_status.name != selector_value:
                            return permission_error_json
                    if selector_key == "email":
                        if current_logged_user_fetch_status.email != selector_value:
                            return permission_error_json

                delete_user_status = delete_user_usecase.execute(
                    delete_by_selector=selector_key,
                    delete_by_data=selector_value)

                return JSONResponse(delete_user_status.as_dict(),
                                    status_code=200)

            return JSONResponse(Failure(
                error=
                "You should provide params as one of these [id, name, email]").
                                as_dict(),
                                status_code=400)

        return JSONResponse(current_logged_user_fetch_status.as_dict(), 401)
    return JSONResponse(
        Failure(
            error=
            "You should provide username and access-token into the headers.").
        as_dict(), 401)
Ejemplo n.º 22
0
def test_invalid_user_creation():
    name: str = "name"
    age: int = 26
    email: str = "*****@*****.**"
    password: str = "StrongPassw0rd"

    # empty name
    assert create_user(
        name="",
        age=age,
        password=password,
        email=email,
        role=UserRole.USER
    ) == Failure(error="name can't be empty.\n"
                       "name should be at least 2 characters.\n"
                       "name should be alpha or alpha numeric.")

    # one char name
    assert create_user(
        name="a",
        age=age,
        password=password,
        email=email,
        role=UserRole.USER
    ) == Failure(error='name should be at least 2 characters.')

    # less than 16 age <just a number to have limit in the app :D>
    assert create_user(
        name=name,
        age=15,
        password=password,
        email=email,
        role=UserRole.USER
    ) == Failure(error='age should be between 16 and 150.')

    # more than 150 age <just a number to have limit in the app :D>
    assert create_user(
        name=name,
        age=151,
        password=password,
        email=email,
        role=UserRole.USER
    ) == Failure(error='age should be between 16 and 150.')

    # weak password
    assert create_user(
        name=name,
        age=26,
        password="******",
        email=email,
        role=UserRole.USER
    ) == Failure(error='password should be stronger.')

    # invalid email
    assert create_user(
        name=name,
        age=26,
        password=password,
        email="invalid_email",
        role=UserRole.USER
    ) == Failure(error='email should be a valid one.')
Ejemplo n.º 23
0
async def update_user(*,
                      update_user_usecase: UpdateUserUseCase,
                      fetch_user_usecase: FetchUserUseCase,
                      fetch_access_token_usecase: FetchAccessTokenUseCase,
                      json_schema: Dict[str, Any],
                      json_schema_validator: JsonValidatorInterface,
                      request: Request) -> Callable[..., JsonEntity.of(_type=_A)]:
    # simple validation for now, will be better later ;)
    username = request.headers.get("username", None)
    token = request.headers.get("access-token", None)
    if username is not None and token is not None:
        current_logged_user_fetch_status = fetch_user_usecase.execute(
            fetch_by_selector='name',
            fetch_by_data=username
        )
        access_token_status = fetch_access_token_usecase.execute(
            username=username
        )
        if isinstance(access_token_status, Failure):
            return JSONResponse(access_token_status.as_dict(), 401)

        if access_token_status.token != token:
            return JSONResponse(Failure(error=f"Invalid access token for the user {username}").as_dict(), 401)

        if isinstance(current_logged_user_fetch_status, ApplicationUser):
            json_data: Dict[Any, Any] = await request.json()
            json_validation_status: Either[Failure, Success] = json_schema_validator.validate(
                schema=json_schema,
                data=json_data
            )
            if isinstance(json_validation_status, Success):
                # will make this better later ;)
                json_data["updated_user"]["role"] = UserRole.USER
                create_domain_user_status = create_user(
                    **json_data["updated_user"]
                )
                if isinstance(create_domain_user_status, Failure):
                    return JSONResponse(create_domain_user_status.as_dict())
                if current_logged_user_fetch_status.role.name == UserRole.ADMIN.name:
                    pass
                elif current_logged_user_fetch_status.role.name == UserRole.USER.name:
                    if current_logged_user_fetch_status.name != username:
                        return JSONResponse(
                            Failure(
                                error="Your current user permission is not satisfying this operation."
                            ).as_dict(),
                            status_code=401
                        )

                update_user_status = update_user_usecase.execute(
                    update_by_selector=json_data["update_by_selector"],
                    update_by_data=json_data["update_by_data"],
                    updated_user=create_domain_user_status
                )
                if isinstance(update_user_status, ApplicationUser):
                    user_json = from_application_user_to_json_user(
                        application_user=update_user_status
                    )
                    return JSONResponse(user_json.as_dict(), status_code=200)

                return JSONResponse(update_user_status.as_dict(), status_code=400)
            return JSONResponse(json_validation_status.as_dict(), status_code=400)

        return JSONResponse(current_logged_user_fetch_status.as_dict(), 401)

    return JSONResponse(
        Failure(error="You should provide username and access-token into the headers.").as_dict(), 401
    )