示例#1
0
    def delete_user(
        cls, *, delete_user_usecase: DeleteUserUseCase,
        fetch_user_usecase: FetchUserUseCase,
        fetch_access_token_usecase: FetchAccessTokenUseCase
    ) -> Callable[..., JsonEntity.of(_type=_A)]:
        async def wrapper(request: Request) -> JSONResponse:
            """
            parameters:
                - in: header
                  name: username
                  schema:
                    type: string
                  description: The username of the user who has an access-token
                  require: true
                - in: header
                  name: access-token
                  schema:
                    type: string
                  description: The access-token of the user currently doing this request
                  require: true
                - in: query
                  name: id
                  schema:
                    type: string
                  description: The id of the user
                - in: query
                  name: name
                  schema:
                    type: string
                  description: The name of the user
                - in: query
                  name: email
                  schema:
                    type: string
                  description: The email of the user
            responses:
                200:
                    description: User deleted
                400:
                    description: Error deleting the user
                    content:
                        application/json:
                            schema: Failure
                    examples:
                    - {"error": "Delete selector should be within this list ['id', 'name', 'email']"}
                401:
                    description: unauthorized
                    content:
                        application/json:
                            schema: Failure
                    examples:
                        - {"error": "You should provide username and access-token into the headers."}
            """
            return await delete_user_framework(
                delete_user_usecase=delete_user_usecase,
                fetch_user_usecase=fetch_user_usecase,
                fetch_access_token_usecase=fetch_access_token_usecase,
                request=request)

        return wrapper
示例#2
0
    def post_user(cls, *,
                  add_user_usecase: AddUserUseCase,
                  json_schema: Dict[str, Any],
                  json_schema_validator: JsonValidatorInterface) -> Callable[..., JsonEntity.of(_type=_A)]:
        @abstractmethod
        def wrapper(*args, **kwargs) -> JsonEntity.of(_type=_A): pass

        return wrapper
示例#3
0
    def update_user(cls, *,
                    update_user_usecase: UpdateUserUseCase,
                    fetch_user_usecase: FetchUserUseCase,
                    fetch_access_token_usecase: FetchAccessTokenUseCase,
                    json_schema: Dict[str, Any],
                    json_schema_validator: JsonValidatorInterface) -> Callable[..., JsonEntity.of(_type=_A)]:
        @abstractmethod
        def wrapper(*args, **kwargs) -> JsonEntity.of(_type=_A): pass

        return wrapper
示例#4
0
    def health_check(
            cls, *, services: List[Service]
    ) -> Callable[..., JsonEntity.of(_type=_A)]:
        async def wrapper(_request: Request) -> JSONResponse:
            """
            responses:
                200:
                    description: health check of all services
                    examples:
                        - {"InMemoryDatabase": "HEALTHY"}
                        - {"InMemoryDatabase": "UNHEALTHY"}
            """
            return JSONResponse(health_check_common(services=services))

        return wrapper
示例#5
0
    def get_access_token(
        cls, *, add_access_token_usecase: AddAccessTokenUseCase,
        json_schema: Dict[str,
                          Any], json_schema_validator: JsonValidatorInterface
    ) -> Callable[..., JsonEntity.of(_type=_A)]:
        @dataclass(frozen=True)
        class UserLoginJson:
            username: str
            password: str

        marshmallow_dataclass.class_schema(UserLoginJson)

        async def wrapper(request: Request) -> JSONResponse:
            """
            requestBody:
                description: Data to login a user and generate an access token for this particular user
                required: true
                content:
                  application/json:
                    schema: UserLoginJson
            responses:
                200:
                    description: AccessToken created
                    content:
                        application/json:
                            schema: AccessToken
                    examples:
                        - {"token": "token"}
                400:
                    description: error generating an access token
                    content:
                        application/json:
                            schema: Failure
                    examples:
                    - {"error": "Invalid password for this user"}
            """
            json_data: Dict[Any, Any] = await request.json()
            return await get_access_token_framework(
                add_access_token_usecase=add_access_token_usecase,
                json_schema=json_schema,
                json_schema_validator=json_schema_validator,
                json_data=json_data)

        return wrapper
示例#6
0
async def get_access_token(
        *, add_access_token_usecase: AddAccessTokenUseCase,
        json_schema: Dict[str,
                          Any], json_schema_validator: JsonValidatorInterface,
        json_data: Dict[Any,
                        Any]) -> Callable[..., JsonEntity.of(_type=_A)]:
    json_validation_status: Either[Failure,
                                   Success] = json_schema_validator.validate(
                                       schema=json_schema, data=json_data)
    if isinstance(json_validation_status, Success):
        add_access_token_status = add_access_token_usecase.execute(
            username=json_data["username"],
            password=json_data["password"],
        )
        if isinstance(add_access_token_status, AccessToken):
            return JSONResponse(add_access_token_status.as_dict(),
                                status_code=200)

        return JSONResponse(add_access_token_status.as_dict(), status_code=400)
    return JSONResponse(json_validation_status.as_dict(), status_code=400)
示例#7
0
async def post_user(
        *, add_user_usecase: AddUserUseCase, json_schema: Dict[str, Any],
        json_schema_validator: JsonValidatorInterface,
        json_data: Dict[Any,
                        Any]) -> Callable[..., JsonEntity.of(_type=_A)]:
    json_validation_status: Either[Failure,
                                   Success] = json_schema_validator.validate(
                                       schema=json_schema, data=json_data)
    if isinstance(json_validation_status, Success):
        add_user_status = add_user_usecase.execute(
            username=json_data["name"],
            age=json_data["age"],
            password=json_data["password"],
            email=json_data.get("email", None),
            role=UserRole.USER)
        if isinstance(add_user_status, ApplicationUser):
            user_json: UserJson = from_application_user_to_json_user(
                application_user=add_user_status)
            return JSONResponse(user_json.as_dict(), status_code=200)

        return JSONResponse(add_user_status.as_dict(), status_code=400)
    return JSONResponse(json_validation_status.as_dict(), status_code=400)
示例#8
0
    def post_user(
        cls, *, add_user_usecase: AddUserUseCase, json_schema: Dict[str, Any],
        json_schema_validator: JsonValidatorInterface
    ) -> Callable[..., JsonEntity.of(_type=_A)]:
        async def wrapper(request: Request) -> JSONResponse:
            """
            requestBody:
                description: Data to create a user
                required: true
                content:
                  application/json:
                    schema: DomainUser
            responses:
                200:
                    description: User created
                    content:
                        application/json:
                            schema: UserJson
                    examples:
                        - {"name": "test", "age": 26, "email": "*****@*****.**", "role": "USER"}
                400:
                    description: error creating a user
                    content:
                        application/json:
                            schema: Failure
                    examples:
                    - {"error": "Username string is already exist, please use a different name."}
            """
            json_data: Dict[Any, Any] = await request.json()
            return await post_user_framework(
                add_user_usecase=add_user_usecase,
                json_schema=json_schema,
                json_schema_validator=json_schema_validator,
                json_data=json_data)

        return wrapper
示例#9
0
    def get_user(cls, *,
                 fetch_user_usecase: FetchUserUseCase,
                 fetch_access_token_usecase: FetchAccessTokenUseCase) -> Callable[..., JsonEntity.of(_type=_A)]:
        @abstractmethod
        def wrapper(*args, **kwargs) -> JsonEntity.of(_type=_A): pass

        return wrapper
示例#10
0
    def get_access_token(cls, *,
                         add_access_token_usecase: AddAccessTokenUseCase,
                         json_schema: Dict[str, Any],
                         json_schema_validator: JsonValidatorInterface) -> Callable[..., JsonEntity.of(_type=_A)]:
        @abstractmethod
        def wrapper(*args, **kwargs) -> JsonEntity.of(_type=_A): pass

        return wrapper
示例#11
0
    def health_check(cls, *, services: List[Service]) -> Callable[..., JsonEntity.of(_type=_A)]:
        @abstractmethod
        def wrapper(*args, **kwargs) -> JsonEntity.of(_type=_A): pass

        return wrapper
示例#12
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
    )
示例#13
0
    def get_user(
        cls, *, fetch_user_usecase: FetchUserUseCase,
        fetch_access_token_usecase: FetchAccessTokenUseCase
    ) -> Callable[..., JsonEntity.of(_type=_A)]:
        async def wrapper(request: Request) -> JSONResponse:
            """
            parameters:
                - in: header
                  name: username
                  schema:
                    type: string
                  description: The username of the user who has an access-token
                  require: true
                - in: header
                  name: access-token
                  schema:
                    type: string
                  description: The access-token of the user currently doing this request
                  require: true
                - in: query
                  name: id
                  schema:
                    type: string
                  description: The id of the user
                - in: query
                  name: name
                  schema:
                    type: string
                  description: The name of the user
                - in: query
                  name: email
                  schema:
                    type: string
                  description: The email of the user
            responses:
             200:
               description: the user you fetched
               content:
                    application/json:
                        schema: UserJson
               examples:
                   - {"name": "test", "age": 26, "email": "*****@*****.**", "role": "USER"}
             400:
               description: error fetching the user
               content:
                    application/json:
                        schema: Failure
               examples:
                   - {"error": "You should provide params as one of these [id, name, email]"}
             401:
                description: unauthorized
                content:
                    application/json:
                        schema: Failure
                examples:
                    - {"error": "You should provide username and access-token into the headers."}
            """
            return await get_user_framework(
                fetch_user_usecase=fetch_user_usecase,
                fetch_access_token_usecase=fetch_access_token_usecase,
                request=request)

        return wrapper
示例#14
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)
示例#15
0
        def wrapper(*args, **kwargs) -> JsonEntity.of(_type=_A): pass

        return wrapper
示例#16
0
class Route(NamedTuple):
    url: str
    methods: List[str]
    handler: Callable[..., JsonEntity.of(_type=_A)]
    args: Maybe[Tuple[Any, ...]]
    kwargs: Maybe[Dict[str, Any]]
示例#17
0
    def update_user(
        cls, *, update_user_usecase: UpdateUserUseCase,
        fetch_user_usecase: FetchUserUseCase,
        fetch_access_token_usecase: FetchAccessTokenUseCase,
        json_schema: Dict[str,
                          Any], json_schema_validator: JsonValidatorInterface
    ) -> Callable[..., JsonEntity.of(_type=_A)]:
        @dataclass(frozen=True)
        class UpdateUserData:
            update_by_selector: str
            update_by_data: str
            updated_user: DomainUser

        marshmallow_dataclass.class_schema(UpdateUserData)

        async def wrapper(request: Request) -> JSONResponse:
            """
            parameters:
                - in: header
                  name: username
                  schema:
                    type: string
                  description: The username of the user who has an access-token
                  require: true
                - in: header
                  name: access-token
                  schema:
                    type: string
                  description: The access-token of the user currently doing this request
                  require: true
            requestBody:
                description: Data to update a user
                required: true
                content:
                  application/json:
                    schema: UpdateUserData
            responses:
                200:
                    description: User updated
                    content:
                        application/json:
                            schema: ApplicationUser
                    examples:
                        - {"name": "test", "age": 26, "email": "*****@*****.**", "password": "******", "role": "USER"}
                400:
                    description: Error updating the user
                    content:
                        application/json:
                            schema: Failure
                    examples:
                    - {"error": "Update selector should be within this list ['id', 'name', 'email']"}
                401:
                    description: unauthorized
                    content:
                        application/json:
                            schema: Failure
                    examples:
                        - {"error": "You should provide username and access-token into the headers."}
            """
            return await update_user_framework(
                update_user_usecase=update_user_usecase,
                fetch_user_usecase=fetch_user_usecase,
                fetch_access_token_usecase=fetch_access_token_usecase,
                json_schema=json_schema,
                json_schema_validator=json_schema_validator,
                request=request)

        return wrapper