Пример #1
0
    class TestDownload(EndpointResource):

        labels = ["tests"]
        # Set an invalid baseuri to test the automatic fallback to /api
        baseuri = "/invalid"

        @decorators.use_kwargs({"stream": fields.Bool()}, location="query")
        @decorators.endpoint(
            path="/tests/download",
            summary="Test missing filename",
            description="Only enabled in testing mode",
            responses={200: "Tests executed"},
        )
        @decorators.endpoint(
            path="/tests/download/<fname>",
            summary="Execute tests with the downloader",
            description="Only enabled in testing mode",
            responses={
                200: "Tests executed",
                206: "Sent partial content",
                416: "Range Not Satisfiable",
            },
        )
        def get(self,
                fname: Optional[str] = None,
                stream: bool = False) -> Response:

            if stream:
                fpath = Uploader.absolute_upload_file(fname,
                                                      subfolder=UPLOAD_PATH)
                return Downloader.send_file_streamed(fpath)

            return Downloader.download(fname)
Пример #2
0
    class TestDownload(EndpointResource):

        labels = ["tests"]

        @decorators.use_kwargs({"stream": fields.Bool()}, location="query")
        @decorators.endpoint(
            # forgot the leading slash to test the automatic fix
            path="tests/download/<folder>/<fname>",
            summary="Execute tests with the downloader",
            description="Only enabled in testing mode",
            responses={
                200: "Tests executed",
                206: "Sent partial content",
                403: "Invalid file path",
                404: "The requested file does not exist",
                416: "Range Not Satisfiable",
            },
        )
        def get(self,
                folder: str,
                fname: str,
                stream: bool = False) -> Response:
            # The same as defined in test_upload
            subfolder = DATA_PATH.joinpath(folder)

            if stream:
                return Downloader.send_file_streamed(fname,
                                                     subfolder=subfolder)

            return Downloader.send_file_content(fname, subfolder=subfolder)
Пример #3
0
class DatasetOutput(Schema):
    uuid = fields.Str(required=True)
    name = fields.Str(required=True)
    description = fields.Str(required=False)
    status = fields.Str(required=False)
    technical = fields.Neo4jRelationshipToSingle(TechnicalMetadata)
    phenotype = fields.Neo4jRelationshipToSingle(Phenotype)
    files = fields.Neo4jRelationshipToCount()
    readonly = fields.Bool(dump_default=True)
Пример #4
0
class StudyOutput(Schema):
    uuid = fields.Str(required=True)
    name = fields.Str(required=True)
    description = fields.Str(required=True)
    # Number of related datasets
    datasets = fields.Neo4jRelationshipToCount()
    phenotypes = fields.Neo4jRelationshipToCount()
    technicals = fields.Neo4jRelationshipToCount()
    readonly = fields.Bool(dump_default=True)
    owning_group_name = fields.Str()
Пример #5
0
 class TestPreloadCallback(EndpointResource):
     @decorators.auth.require()
     @decorators.preload(callback=verify_uuid_value)
     @decorators.use_kwargs({"test": fields.Bool(required=True)},
                            location="query")
     @decorators.endpoint(
         path="/tests/preloadcallback/<uuid>",
         summary="Only authorized if uuid corresponds to an admin user",
         description="Only enabled in testing mode",
         responses={200: "Tests executed"},
     )
     # Note: target_user is injected by the preload decorator
     def get(self, uuid: str, test: bool, user: User,
             target_user: User) -> Response:
         return self.response({"email": target_user.email})
Пример #6
0
 class Force(PartialSchema):
     force = fields.Bool()
Пример #7
0
def admin_user_input(request: FlaskRequest, is_post: bool) -> Type[Schema]:

    is_admin = HTTPTokenAuth.is_session_user_admin(request, auth)

    attributes: MarshmallowSchema = {}
    if is_post:
        # This is because Email is not typed on marshmallow
        attributes["email"] = fields.Email(  # type: ignore
            required=is_post,
            validate=validate.Length(max=100))

    attributes["name"] = fields.Str(
        required=is_post,
        validate=validate.Length(min=1),
        metadata={"label": "First Name"},
    )
    attributes["surname"] = fields.Str(
        required=is_post,
        validate=validate.Length(min=1),
        metadata={"label": "Last Name"},
    )

    attributes["password"] = fields.Str(
        required=is_post,
        validate=validate.Length(min=auth.MIN_PASSWORD_LENGTH),
        metadata={"password": True},
    )

    if Connector.check_availability("smtp"):
        attributes["email_notification"] = fields.Bool(
            metadata={"label": "Notify password by email"})

    attributes["is_active"] = fields.Bool(
        dump_default=True,
        required=False,
        metadata={"label": "Activate user"},
    )

    roles = {r.name: r.description for r in auth.get_roles()}
    if not is_admin and RoleEnum.ADMIN.value in roles:
        roles.pop(RoleEnum.ADMIN.value)

    attributes["roles"] = fields.List(
        fields.Str(validate=validate.OneOf(
            choices=[r for r in roles.keys()],
            labels=[r for r in roles.values()],
        )),
        dump_default=[auth.default_role],
        required=False,
        unique=True,
        metadata={
            "label": "Roles",
            "description": "",
            "extra_descriptions": auth.role_descriptions,
        },
    )

    group_keys = []
    group_labels = []

    for g in auth.get_groups():
        group_keys.append(g.uuid)
        group_labels.append(f"{g.shortname} - {g.fullname}")

    if len(group_keys) == 1:
        default_group = group_keys[0]
    else:
        default_group = None

    attributes["group"] = fields.Str(
        required=is_post,
        dump_default=default_group,
        validate=validate.OneOf(choices=group_keys, labels=group_labels),
        metadata={
            "label": "Group",
            "description": "The group to which the user belongs",
        },
    )

    attributes["expiration"] = fields.DateTime(
        required=False,
        allow_none=True,
        metadata={
            "label": "Account expiration",
            "description": "This user will be blocked after this date",
        },
    )

    if custom_fields := mem.customizer.get_custom_input_fields(
            request=request, scope=mem.customizer.ADMIN):
        attributes.update(custom_fields)
Пример #8
0
    def test_responses(self, faker: Faker) -> None:
        class MySchema(Schema):
            name = fields.Str()

        f = "myfield"
        assert (
            ResponseMaker.get_schema_type(f, fields.Str(metadata={"password": True}))
            == "password"
        )
        assert ResponseMaker.get_schema_type(f, fields.Bool()) == "boolean"
        assert ResponseMaker.get_schema_type(f, fields.Boolean()) == "boolean"
        assert ResponseMaker.get_schema_type(f, fields.Date()) == "date"
        assert ResponseMaker.get_schema_type(f, fields.DateTime()) == "datetime"
        assert ResponseMaker.get_schema_type(f, fields.AwareDateTime()) == "datetime"
        assert ResponseMaker.get_schema_type(f, fields.NaiveDateTime()) == "datetime"
        assert ResponseMaker.get_schema_type(f, fields.Decimal()) == "number"
        # This is because Email is not typed on marshmallow
        assert ResponseMaker.get_schema_type(f, fields.Email()) == "email"  # type: ignore
        assert ResponseMaker.get_schema_type(f, fields.Float()) == "number"
        assert ResponseMaker.get_schema_type(f, fields.Int()) == "int"
        assert ResponseMaker.get_schema_type(f, fields.Integer()) == "int"
        assert ResponseMaker.get_schema_type(f, fields.Number()) == "number"
        assert ResponseMaker.get_schema_type(f, fields.Str()) == "string"
        assert ResponseMaker.get_schema_type(f, fields.String()) == "string"
        assert ResponseMaker.get_schema_type(f, fields.Dict()) == "dictionary"
        assert ResponseMaker.get_schema_type(f, fields.List(fields.Str())) == "string[]"
        assert ResponseMaker.get_schema_type(f, fields.Nested(MySchema())) == "nested"
        # Unsupported types, fallback to string
        assert ResponseMaker.get_schema_type(f, fields.URL()) == "string"
        assert ResponseMaker.get_schema_type(f, fields.Url()) == "string"
        assert ResponseMaker.get_schema_type(f, fields.UUID()) == "string"
        # assert ResponseMaker.get_schema_type(f, fields.Constant("x")) == "string"
        assert ResponseMaker.get_schema_type(f, fields.Field()) == "string"
        # assert ResponseMaker.get_schema_type(f, fields.Function()) == "string"
        # assert ResponseMaker.get_schema_type(f, fields.Mapping()) == "string"
        # assert ResponseMaker.get_schema_type(f, fields.Method()) == "string"
        # assert ResponseMaker.get_schema_type(f, fields.Raw()) == "string"
        # assert ResponseMaker.get_schema_type(f, fields.TimeDelta()) == "string"

        assert not ResponseMaker.is_binary(None)
        assert not ResponseMaker.is_binary("")
        assert not ResponseMaker.is_binary("application/json")
        assert ResponseMaker.is_binary("application/octet-stream")
        assert ResponseMaker.is_binary("application/x-bzip")
        assert ResponseMaker.is_binary("application/x-bzip2")
        assert ResponseMaker.is_binary("application/pdf")
        assert ResponseMaker.is_binary("application/msword")
        assert ResponseMaker.is_binary("application/rtf")
        assert ResponseMaker.is_binary("application/x-tar")
        assert ResponseMaker.is_binary("application/gzip")
        assert ResponseMaker.is_binary("application/zip")
        assert ResponseMaker.is_binary("application/x-7z-compressed")
        assert not ResponseMaker.is_binary("text/plain")
        assert not ResponseMaker.is_binary("text/css")
        assert not ResponseMaker.is_binary("text/csv")
        assert not ResponseMaker.is_binary("text/html")
        assert not ResponseMaker.is_binary("text/javascript")
        assert not ResponseMaker.is_binary("text/xml")
        assert ResponseMaker.is_binary("image/gif")
        assert ResponseMaker.is_binary("image/jpeg")
        assert ResponseMaker.is_binary("image/png")
        assert ResponseMaker.is_binary("image/svg+xml")
        assert ResponseMaker.is_binary("image/tiff")
        assert ResponseMaker.is_binary("image/webp")
        assert ResponseMaker.is_binary("image/bmp")
        assert ResponseMaker.is_binary("image/aac")
        assert ResponseMaker.is_binary("audio/midi")
        assert ResponseMaker.is_binary("audio/mpeg")
        assert ResponseMaker.is_binary("audio/wav")
        assert ResponseMaker.is_binary("audio/anyother")
        assert ResponseMaker.is_binary("video/mpeg")
        assert ResponseMaker.is_binary("video/ogg")
        assert ResponseMaker.is_binary("video/webm")
        assert ResponseMaker.is_binary("video/anyother")
        assert ResponseMaker.is_binary("video/anyother")
        assert not ResponseMaker.is_binary(faker.pystr())

        response = EndpointResource.response("", code=200)
        assert response[1] == 200  # type: ignore
        response = EndpointResource.response(None, code=200)
        assert response[1] == 204  # type: ignore
        response = EndpointResource.response(None, code=200, head_method=True)
        assert response[1] == 200  # type: ignore
Пример #9
0
def getInputSchema(request, is_post):

    # as defined in Marshmallow.schema.from_dict
    attributes: Dict[str, Union[fields.Field, type]] = {}
    if is_post:
        attributes["email"] = fields.Email(required=is_post)

    attributes["name"] = fields.Str(required=is_post,
                                    validate=validate.Length(min=1))
    attributes["surname"] = fields.Str(required=is_post,
                                       validate=validate.Length(min=1))

    attributes["password"] = fields.Str(
        required=is_post,
        password=True,
        validate=validate.Length(min=auth.MIN_PASSWORD_LENGTH),
    )

    if Connector.check_availability("smtp"):
        attributes["email_notification"] = fields.Bool(
            label="Notify password by email")

    attributes["is_active"] = fields.Bool(label="Activate user",
                                          default=True,
                                          required=False)

    roles = {r.name: r.description for r in auth.get_roles()}

    attributes["roles"] = AdvancedList(
        fields.Str(validate=validate.OneOf(
            choices=[r for r in roles.keys()],
            labels=[r for r in roles.values()],
        )),
        required=False,
        label="Roles",
        description="",
        unique=True,
        multiple=True,
    )

    group_keys = []
    group_labels = []

    for g in auth.get_groups():
        group_keys.append(g.uuid)
        group_labels.append(f"{g.shortname} - {g.fullname}")

    if len(group_keys) == 1:
        default_group = group_keys[0]
    else:
        default_group = None

    attributes["group"] = fields.Str(
        label="Group",
        description="The group to which the user belongs",
        required=is_post,
        default=default_group,
        validate=validate.OneOf(choices=group_keys, labels=group_labels),
    )

    attributes["expiration"] = fields.DateTime(
        required=False,
        allow_none=True,
        label="Account expiration",
        description="This user will be blocked after this date",
    )

    if custom_fields := mem.customizer.get_custom_input_fields(
            request=request, scope=mem.customizer.ADMIN):
        attributes.update(custom_fields)