Exemple #1
0
    def removeAllFiles(self):
        data = Util.parseToken(Util.loadToken(self.userId, self.port))

        logger.debug("remove files in service {}".format(self.servicename))

        found = False

        if self.fileStorage:
            # todo: implements me
            found = True

        if self.metadata:
            req = requests.delete(
                f"{self.portaddress}/metadata/project/{self.getProjectId()}/files",
                json=data,
                verify=(os.environ.get("VERIFY_SSL", "True") == "True"),
            )

            if req.status_code < 300:
                found = True

        if found:
            self.reload()

        return found
Exemple #2
0
    def check_api_key(*args, **kwargs):
        g.zenodo = None

        try:
            req = request.get_json(force=True, cache=True)
        except:
            req = request.form.to_dict()

        try:
            service, userId, apiKey = Util.parseUserId(req.get("userId"))
        except:
            apiKey = Util.loadToken(req.get("userId"), "port-openscienceframework").access_token

        logger.debug("req data: {}".format(req))

        if apiKey is None:
            logger.error("apiKey or userId not found.")
            abort(401)

        logger.debug("found apiKey")
        g.osf = OSF(
            token=apiKey,
            address=os.getenv(
                "OPENSCIENCEFRAMEWORK_API_ADDRESS", "https://api.test.osf.io/v2"
            ),
        )

        return api_method(*args, **kwargs)
Exemple #3
0
    def check_api_key(*args, **kwargs):
        g.zenodo = None

        try:
            req = request.get_json(force=True)
        except Exception as e:
            logger.error(e, exc_info=True)
            req = request.form.to_dict()
        logger.debug("got request data: {}".format(req))

        try:
            service, userId, apiKey = Util.parseUserId(req.get("userId"))
        except Exception as e:
            logger.error(e, exc_info=True)
            apiKey = Util.loadToken(
                req.get("userId"), "port-zenodo").access_token

        if apiKey is None:
            logger.error("apiKey or userId not found.")
            abort(401)

        logger.debug("found apiKey")
        g.zenodo = Zenodo(apiKey, address=current_app.zenodo_address)

        return api_method(*args, **kwargs)
Exemple #4
0
    def reload(self):
        if self.fileStorage:
            data = {"filepath": self.getFilepath(), "userId": self.userId}
            req = requests.get(f"{self.portaddress}/storage/folder",
                               json=data,
                               verify=(os.environ.get("VERIFY_SSL",
                                                      "True") == "True"))

            if req.status_code >= 300:
                # for convenience
                data.update(
                    Util.parseToken(Util.loadToken(self.userId, self.port)))
                req = requests.get(f"{self.portaddress}/storage/folder",
                                   json=data,
                                   verify=(os.environ.get(
                                       "VERIFY_SSL", "True") == "True"))

                if req.status_code >= 300:
                    return False

            json = req.json()

            logger.debug("reload fileStorage in Service got: {}".format(json))

            self.files = json.get("files")

        if self.metadata:
            # TODO: metadata ports can also response with files
            self.reloadInformations()
Exemple #5
0
    def updateMetadataForResearch(self, researchId: int, updateMetadata: dict):
        """
        This method changes the metadata in all available ports to the given metadata values in given dict for specified researchId.
        """
        # get all ports registered to researchId
        allMetadata = []

        # get all ports registered to researchId
        logger.debug("start update for research method")

        research = Research(testing=self.testing, researchId=researchId)
        ports = research.getPortsWithProjectId()
        logger.debug("research ports: {}".format(ports))

        # FIXME: parallize me
        for (port, projectId) in ports:
            if projectId is None:
                continue

            portname = port["port"]

            if not portname.startswith("port-"):
                portname = "port-{}".format(portname)

            logger.debug("work on port {}".format(port))

            data = Util.parseToken(Util.loadToken(research.userId, portname))
            data["metadata"] = updateMetadata

            metadata = self.updateMetadataForResearchFromPort(
                portname, projectId, data)
            d = {"port": portname, "metadata": metadata}
            allMetadata.append(d)

        return allMetadata
Exemple #6
0
def bootstrap(name="MicroService", testing=False, *args, **kwargs):
    list_openapi = Util.load_oai("central-service_token-storage.yml")

    app = App(name, *args, **kwargs)

    opts = {
        "use_in_memory_on_failure": (os.getenv("use_inmemory_as_fallover",
                                               "False") == "True")
    }
    if testing:
        app.app.config.update({"TESTING": True})
        opts = {"use_in_memory_on_failure": True}

    CommonUtil.monkeypatch(app=app.app)

    ServerUtil.storage = Storage(**opts)

    for oai in list_openapi:
        app.add_api(
            oai,
            resolver=MultipleResourceResolver(
                "api", collection_endpoint_name="index"),
            validate_responses=True,
        )

    return app
Exemple #7
0
def bootstrap(name="MicroService", testing=False, *args, **kwargs):
    list_openapi = Util.load_oai("central-service_research-manager.yml")

    app = App(name, *args, **kwargs)
    RDSUtil.monkeypatch("getDict", app=app.app)

    opts = {
        "use_in_memory_on_failure": (os.getenv("use_inmemory_as_fallover",
                                               "False") == "True")
    }
    if testing:
        app.app.config.update({"TESTING": True})
        opts = {"use_in_memory_on_failure": True}

    Singleton.ProjectService = ProjectService(**opts)

    for oai in list_openapi:
        app.add_api(
            oai,
            resolver=MultipleResourceResolver(
                "api", collection_endpoint_name="index"),
            validate_responses=True,
        )

    return app
Exemple #8
0
    def removeFile(self, file_id):
        found = False

        file = self.files[file_id]

        data = Util.parseToken(Util.loadToken(self.userId, self.port))

        if self.fileStorage:
            data["filepath"] = "{}/{}".format(self.getFilepath(), file)
            req = requests.delete(
                f"{self.portaddress}/storage/file",
                json=data,
                verify=(os.environ.get("VERIFY_SSL", "True") == "True"),
            )

            if req.status_code < 300:
                found = True

        if self.metadata:
            req = requests.delete(
                f"{self.portaddress}/metadata/project/{self.getProjectId()}/files/{file_id}",
                json=data,
                verify=(os.environ.get("VERIFY_SSL", "True") == "True"),
            )

            if req.status_code < 300:
                found = True

        if found:
            del self.files[file_id]
            return True

        return False
Exemple #9
0
def bootstrap(name="MicroService", *args, **kwargs):
    import os
    from connexion_plus import App, MultipleResourceResolver, Util

    from lib.TokenService import TokenService

    list_openapi = Util.load_oai("use-case_port.yml")

    if "testing" in kwargs:
        ServerUtil.tokenService = TokenService(kwargs["testing"])
        del kwargs["testing"]
    else:
        ServerUtil.tokenService = TokenService()

    app = App(name, *args, **kwargs)
    CommonUtil.monkeypatch(app=app.app)

    for oai in list_openapi:
        app.add_api(
            oai,
            resolver=MultipleResourceResolver(
                "api", collection_endpoint_name="index"),
            validate_responses=True,
        )

    return app
Exemple #10
0
    def triggerPassiveMode(self, folder, servicename):
        """Trigger passive upload for given folder

        Args:
            folder (str): Set the folder.
            servicename (str): Given port, where files should be taken from.

        Returns:
            bool: Return True, if the trigger was successfully, otherwise False.
        """
        data = {
            "folder": folder,
            "service": servicename,
            "username": self.userId
        }

        data.update(Util.parseToken(Util.loadToken(self.userId, self.port)))

        logger.debug("start passive mode with data {} in service {}".format(
            data, self.getJSON()))

        if self.metadata:
            response_to = requests.post(
                f"{self.portaddress}/metadata/project/{self.getProjectId()}/files",
                data=data,
                verify=(os.environ.get("VERIFY_SSL", "True") == "True"),
            )

            if response_to.status_code >= 300:
                logger.error(response_to.json())
                return False
            pass

        return True
Exemple #11
0
    def addFile(self, filename, fileContent):
        """Adds given file with filename to this service.

        Args:
            filename (str): Set the filename of this file.
            fileContent (io.BytesIO): Set the content of this file.

        Returns:
            bool: Return True, if the file was uploaded successfully, otherwise False.
        """
        data = Util.parseToken(Util.loadToken(self.userId, self.port))
        files = {"file": (filename, fileContent.getvalue())}
        data["filename"] = filename

        logger.debug("add file {} with data {} in service {}".format(
            files, data, self.getJSON()))

        if self.metadata:
            response_to = requests.post(
                f"{self.portaddress}/metadata/project/{self.getProjectId()}/files",
                files=files,
                data=data,
                verify=(os.environ.get("VERIFY_SSL", "True") == "True"),
            )

            if response_to.status_code >= 300:
                logger.error(response_to.json())
                return False

        if self.fileStorage:
            # TODO: fileStorage can also add files
            return False

        return True
Exemple #12
0
def post(project_id):
    # trigger upload on datasafe
    req = request.get_json(force=True, silent=True, cache=True)

    if req is None:
        req = request.form.to_dict()

    logger.debug("got request body: {}", req)

    try:
        service, userId, password = Util.parseUserId(req["userId"])
        if service != "port-datasafe":
            logger.debug("got wrong service token")
            raise ValueError
    except ValueError:
        token = Util.loadToken(req["userId"], "port-datasafe")
        userId = token.user.username
        password = token.access_token

    owncloud_token = Util.loadToken(req["username"], "port-owncloud")

    data = Util.parseToken(owncloud_token)
    data.update({
        "filepath": "{}/ro-crate-metadata.json".format(req["folder"])
    })

    logger.debug("send data: {}".format(data))

    metadata = json.loads(
        BytesIO(
            requests.get(
                "http://circle1-{}/storage/file".format("port-owncloud"),
                json=data,
                verify=(os.environ.get("VERIFY_SSL", "True") == "True"),
            ).content
        )
        .read()
        .decode("UTF-8")
    )

    logger.debug("got metadata: {}".format(metadata))
    doc = ROParser(metadata)

    logger.debug("parsed metadata: {}".format(doc))

    datasafe = Datasafe(
        userId,
        owncloud_token.access_token,
        doc.getElement(doc.rootIdentifier, expand=True, clean=True),
        req["folder"],
        os.getenv("DATASAFE_PUBLICKEY"),
        os.getenv("DATASAFE_PRIVATEKEY")
    )

    logger.debug("Trigger file upload")
    success = datasafe.triggerUploadForProject()
    logger.debug(f"Finished trigger, result was: {success}")

    return jsonify({"success": success}), 200 if success else 500
Exemple #13
0
    def from_dict(cls, tokenDict: dict):
        """
        Returns a token object from a dict.
        """
        from RDS import Util

        return cls(
            Util.getUserObject(tokenDict["user"]),
            Util.getServiceObject(tokenDict["service"]),
            tokenDict["access_token"],
        )
Exemple #14
0
 def test_init_objects(self):
     self.assertEqual(Util.getServiceObject(json.dumps(self.oauthservice1)),
                      self.oauthservice1)
     svc1 = LoginService("MusterService", ["fileStorage"])
     self.assertEqual(Util.getServiceObject(json.dumps(svc1)), svc1)
     self.assertNotEqual(
         Util.getServiceObject(json.dumps(svc1)).__class__,
         self.oauthservice1.__class__)
     self.assertEqual(Util.getUserObject(json.dumps(self.user1)),
                      self.user1)
     self.assertEqual(Util.getTokenObject(json.dumps(self.token1)),
                      self.token1)
Exemple #15
0
    def getMetadataForResearch(
        self,
        userId: str = None,
        researchIndex: int = None,
        researchId: int = None,
        metadataFields=None,
    ):
        """
        This method returns the metadata from all available ports for specified researchId.
        """
        allMetadata = []

        logger.debug("start get metadata method for research")

        research = Research(
            testing=self.testing,
            userId=userId,
            researchIndex=researchIndex,
            researchId=researchId,
        )

        ports = research.getPortsWithProjectId()

        logger.debug(f"got ports {ports}")

        # FIXME: parallize me
        for port, projectId in ports:
            # beware, that projectId could also be a string or sth else
            if projectId is None:
                continue

            portname = port["port"]

            if not portname.startswith("port-"):
                portname = "port-{}".format(portname)

            token = Util.loadToken(research.userId, portname)

            data = Util.parseToken(token)
            data["metadata"] = metadataFields

            logger.debug(f"work on port {port} with apiKey {token}")
            port = port["port"]
            metadata = self.getMetadataForProjectFromPort(
                port,
                projectId,
                apiKeyMetadata=data,
            )
            d = {"port": port, "metadata": metadata}
            allMetadata.append(d)

        return allMetadata
Exemple #16
0
def index():
    json = request.json
    try:
        service, userId, apiKey = Util.parseUserId(json.get("userId"))
    except:
        apiKey = Util.loadToken(json.get("userId"),
                                "port-owncloud").access_token
    filepath = json.get("filepath")
    logger.debug(f"userid {userId}")

    files = OwncloudUser(userId, apiKey).getFolder(filepath)

    return jsonify({"files": files})
Exemple #17
0
        def setUp(self):

            Util.monkeypatch()
            self.empty_storage = Storage(**get_opts())

            self.user1 = User("Max Mustermann")
            self.user2 = User("Mimi Mimikri")

            self.service1 = LoginService(servicename="MusterService",
                                         implements=["metadata"])
            self.service2 = LoginService(servicename="FahrService",
                                         implements=["metadata"])
            self.oauthservice1 = OAuth2Service(
                servicename="BetonService",
                implements=["metadata"],
                authorize_url="http://localhost/oauth/authorize",
                refresh_url="http://localhost/oauth/token",
                client_id="MNO",
                client_secret="UVW",
            )
            self.oauthservice2 = OAuth2Service(
                servicename="FlugService",
                implements=["metadata"],
                authorize_url="http://localhost21/oauth/authorize",
                refresh_url="http://localhost21/oauth/token",
                client_id="XCA",
                client_secret="BCXY",
            )

            self.empty_storage.addService(self.service1)
            self.empty_storage.addService(self.oauthservice1)
            self.empty_storage.addService(self.oauthservice2)

            self.token1 = Token(self.user1, self.service1, "ABC")
            self.token_like_token1 = Token(self.user1, self.service1, "DEF")
            self.token2 = Token(self.user1, self.oauthservice1, "XYZ")
            self.token3 = Token(self.user2, self.service2, "XASD")
            self.token4 = Token(self.user2, self.service1, "IOAJSD")

            self.oauthtoken1 = OAuth2Token(self.user1, self.oauthservice1,
                                           "ABC", "X_ABC")
            self.oauthtoken_like_token1 = OAuth2Token(self.user1,
                                                      self.oauthservice1,
                                                      "ABC", "X_DEF")
            self.oauthtoken2 = OAuth2Token(self.user1, self.oauthservice1,
                                           "XYZ", "X_XYZ")

            self.oauthtoken3 = OAuth2Token(self.user1, self.oauthservice2,
                                           "XYZ", "X_XYZ")
Exemple #18
0
def bootstrap(name="MicroService", *args, **kwargs):
    list_openapi = Util.load_oai("use-case_metadata.yml")

    app = App(name, *args, **kwargs)
    RDSUtil.monkeypatch(app=app)

    for oai in list_openapi:
        app.add_api(
            oai,
            resolver=MultipleResourceResolver(
                "api", collection_endpoint_name="index"),
            validate_responses=True,
        )

    return app
Exemple #19
0
    def refreshService(self, service: Union[str, BaseService]) -> bool:
        try:
            servicename = service.servicename
        except:
            servicename = service

        response = requests.get(
            f"{self.address}/service/{servicename}",
            verify=(os.environ.get("VERIFY_SSL", "True") == "True"),
        )

        if response.status_code != 200:
            try:
                raise ServiceNotFoundError(service)
            except:
                raise ServiceNotFoundError(
                    BaseService(servicename=servicename,
                                implements=["metadata"]))

        svc = Util.getServiceObject(response.json())

        if not svc in self._services:
            self._services.append(svc)

        return svc
Exemple #20
0
    def getTokenForServiceFromUser(self, service: BaseService,
                                   user: User) -> Token:
        """
        Returns the token from type Token (struct: servicename: str, access_token: str) for given service from given user.

        Raise ServiceNotExistsError, if no token for service was found.
        """
        response = requests.get(
            f"{self.address}/user/{user.username}/token/{service.servicename}",
            verify=(os.environ.get("VERIFY_SSL", "True") == "True"),
        )

        data = response.json()
        while type(data) is not dict:
            data = json.loads(data)

        if response.status_code != 200:
            if "error" in data:
                if data["error"] == "TokenNotExistsError":
                    raise TokenNotFoundError(Token(user, service, "NOT_USED"))
                if data["error"] == "UserNotExistsError":
                    raise UserNotFoundError(user)
                if data["error"] == "ServiceNotExistsError":
                    raise ServiceNotFoundError(service)
            raise Exception(data)

        token = Util.getTokenObject(data)

        if isinstance(token.service, OAuth2Service):
            token.service._client_secret = ""

        if isinstance(token, OAuth2Token):
            token._refresh_token = ""

        return token
Exemple #21
0
    def createProjectForUserInService(self, user: User,
                                      service: BaseService) -> int:
        """
        Create a project in service, which the token is for.
        Returns the id for the new created project. If something went wrong, raise an ProjectNotCreated
        """

        token = self.getTokenForServiceFromUser(service, user)
        data = Util.parseToken(token)

        port = get_port_string(service.servicename)
        if self.address.startswith("http://localhost"):
            port = self.address

        req = requests.post(
            "{}/metadata/project".format(port),
            json=data,
            verify=(os.environ.get("VERIFY_SSL", "True") == "True"),
        )

        if req.status_code < 300:
            project = req.json()
            return project.get("projectId"), project

        raise ProjectNotCreatedError(service)
Exemple #22
0
    def getAllServicesForUser(self, user: User) -> list:
        """
        Returns a `list` for all services which the user has registered a token for.
        """
        response = requests.get(
            f"{self.address}/user/{user.username}/token",
            verify=(os.environ.get("VERIFY_SSL", "True") == "True"),
        )
        data = response.json()

        # TODO: adjust to oai spec

        services = []
        try:
            for index, l in enumerate(data["list"]):
                token = Util.getTokenObject(l)
                services.append({
                    "id":
                    index,
                    "servicename":
                    token.servicename,
                    "access_token":
                    token.access_token,
                    "projects":
                    self.getProjectsForToken(token),
                    "implements":
                    token._service.implements,
                    "informations":
                    self.getInformations(token.service)
                })
        except Exception as e:
            logger.error(e)
            raise UserNotFoundError(user)

        return services
Exemple #23
0
    def __init__(self, rc=None, use_in_memory_on_failure=True):
        # format: {user: [<type project>]}
        try:
            from redis_pubsub_dict import RedisDict
            import redis_pubsub_dict
            import functools
            import json

            redis_pubsub_dict.dumps = lambda x: json.dumps(x)
            redis_pubsub_dict.loads = lambda x: Util.try_function_on_dict(
                [Project.fromJSON])(x)
            redis_pubsub_dict.RedisDict.to_json = lambda x: dict(x.items())
            redis_pubsub_dict.RedisDict.__eq__ = (
                lambda x, other: dict(x.items()) == other)
            redis_pubsub_dict.RedisDict.keys = keys

            # runs in RDS ecosystem

            if rc is None:
                logger.debug("No redis client was given. Create one.")
                startup_nodes = [{
                    "host": os.getenv("REDIS_HOST", "localhost"),
                    "port": os.getenv("REDIS_PORT", "6379"),
                }]

                try:
                    logger.debug("first try cluster")
                    from rediscluster import RedisCluster

                    rc = RedisCluster(
                        startup_nodes=startup_nodes,
                        decode_responses=True,
                    )
                except Exception as e:
                    logger.error(e)
                    logger.debug(
                        "Cluster has an error, try standardalone redis")
                    from redis import Redis

                    rc = Redis(
                        **(startup_nodes[0]),
                        db=0,
                        decode_responses=True,
                    )
                    rc.info()  # provoke an error message

            logger.debug("set redis backed dict")
            self.projects = RedisDict(rc, "researchmanager_projects")
        except Exception as e:
            logger.error(e)
            logger.info("no redis found.")

            if not use_in_memory_on_failure:
                logger.info("exit...")
                import sys

                sys.exit()

            logger.info("use in-memory")
            self.projects = {}
Exemple #24
0
def post(user_id):
    logger.debug(f"get token string: {request.json}.")

    from RDS import Token

    token = Util.getTokenObject(request.json)

    logger.debug(f"parsed token: {token}.")

    code = 200

    try:
        user = utility.storage.getUser(user_id)
    except UserNotExistsError as e:
        user = User(user_id)

    try:
        utility.storage.addTokenToUser(token, user)
    except UserHasTokenAlreadyError as e:
        abort(409, description=str(e))
    except UserNotExistsError as e:
        # only force adding, if user not exists, otherwise it also overwrites existing tokens.
        utility.storage.addTokenToUser(token, user, Force=True)
        code = 201

    return jsonify({"success": True}), code
Exemple #25
0
    def reloadInformations(self):
        """Updates all metadata informations from port.
        """

        json = requests.get("{}/service/{}".format(
            os.getenv("USE_CASE_SERVICE_PORT_SERVICE",
                      "{}/port-service".format(self.portaddress)),
            self.port)).json()

        logger.debug("reload metadata informations: got {}".format(json))

        svc = Util.getServiceObject(json["informations"])

        self.useZipForFolder = svc.fileTransferArchive == FileTransferArchive.zip
        self.fileTransferMode = svc.fileTransferMode
        self.fileTransferArchive = svc.fileTransferArchive

        if isinstance(svc, OAuth2Service):
            self.loginMode = 0
            self.credentials = svc.to_dict().get("credentials", {})
        else:
            self.loginMode = 1

        logger.debug("got svc: {}, loginmode: {}".format(
            svc.to_dict(), self.loginMode))
Exemple #26
0
    def getFile(self, file_id):
        from io import BytesIO

        file = self.files[file_id]

        if self.fileStorage:
            # this condition is for ports, which does not comply to the doc for urls
            path = "{}/{}".format(self.getFilepath(), file)
            if str(file).startswith(self.getFilepath()):
                path = file

            data = {
                "userId": self.userId,
                "filepath": path,
            }

            logger.debug("request data {}".format(data))

            response_to = requests.get(
                f"{self.portaddress}/storage/file",
                json=data,
                verify=(os.environ.get("VERIFY_SSL", "True") == "True"),
            )

            if response_to.status_code >= 300:
                data.update(
                    Util.parseToken(Util.loadToken(self.userId, self.port)))

                logger.debug("request data {}".format(data))

                response_to = requests.get(
                    f"{self.portaddress}/storage/file",
                    json=data,
                    verify=(os.environ.get("VERIFY_SSL", "True") == "True"),
                )

            cnt = response_to.content
            logger.debug("got content size: {}".format(len(cnt)))

            return BytesIO(cnt)

        if self.metadata:
            # TODO: metadata can respond with files too.
            pass

        return BytesIO(b"")
Exemple #27
0
def load_service_with_tokens(jsonStr):
    d = json.loads(jsonStr)
    user = User.from_json(json.dumps(d["data"]))
    tokens = []
    for t in d["tokens"]:
        tokens.append(
            Util.try_function_on_dict([OAuth2Token.from_json,
                                       Token.from_json])(json.dumps(t)))

    return {"data": user, "tokens": tokens}
Exemple #28
0
    def get(self, endpoint):
        """
        For convenience in this test suite.
        """
        data_result = []
        data = self.client.get(endpoint).json
        for d in data["list"]:
            data_result.append(Util.initialize_object_from_json(json.dumps(d)))

        return data_result
Exemple #29
0
    def test_initialize_object(self):
        self.assertEqual(
            Util.initialize_object_from_json(json.dumps(self.token1)),
            self.token1)
        self.assertEqual(
            Util.initialize_object_from_json(json.dumps(self.oauthtoken1)),
            self.oauthtoken1,
        )

        self.assertEqual(
            Util.initialize_object_from_json(json.dumps(self.service1)),
            self.service1)
        self.assertEqual(
            Util.initialize_object_from_json(json.dumps(self.oauthservice1)),
            self.oauthservice1,
        )

        self.assertEqual(
            Util.initialize_object_from_json(json.dumps(self.user1)),
            self.user1)
Exemple #30
0
def post():
    user = None
    try:
        user = Util.getUserObject(request.json)
    except:
        abort(400, description=f"Request not give a valid user object: {request.json}")

    utility.storage.addUser(user)

    data = {"success": True}
    return jsonify(data)