def setUp(self):
        self.user1 = User("Max Mustermann")
        self.user2 = User("12345")

        self.service1 = LoginService("MusterService", ["fileStorage"])
        self.service2 = LoginService("BetonService", ["fileStorage"])

        self.token1 = Token(self.user1, self.service1, "ABC")
        self.token2 = Token(self.user1, self.service2, "DEF")

        self.oauthservice1 = OAuth2Service(
            "MusterService",
            ["fileStorage"],
            FileTransferMode.active,
            FileTransferArchive.none,
            "http://localhost/oauth/authorize",
            "http://localhost/oauth/token",
            "MNO",
            "UVW",
        )
        self.oauthservice2 = OAuth2Service(
            "BetonService",
            ["fileStorage"],
            FileTransferMode.active,
            FileTransferArchive.none,
            "http://owncloud/oauth/authorize",
            "http://owncloud/oauth/token",
            "UVP",
            "OMN",
        )

        self.oauthtoken1 = OAuth2Token(self.user1, self.oauthservice1, "ABC",
                                       "XYZ")
        self.oauthtoken2 = OAuth2Token(self.user1, self.oauthservice2, "DEF",
                                       "UVW")
Example #2
0
    def setUp(self):
        self.service1 = LoginService("MusterService", ["fileStorage"])
        self.service2 = LoginService("BetonService", ["fileStorage"])
        self.oauthservice1 = OAuth2Service.from_service(
            self.service1,
            "http://localhost:5000/oauth/authorize",
            "http://localhost:5000/oauth/refresh",
            "ABC",
            "XYZ",
        )

        self.oauthservice2 = OAuth2Service.from_service(
            self.service2,
            "http://localhost:5000/oauth/authorize",
            "http://localhost:5000/oauth/refresh",
            "DEF",
            "MNO",
        )

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

        self.token1 = Token(self.user1, self.service1, "ABC")
        self.token2 = Token(self.user1, self.service2, "DEF")

        self.oauthtoken1 = OAuth2Token(self.user1, self.oauthservice1, "ABC",
                                       "XYZ")
        self.oauthtoken2 = OAuth2Token(self.user1, self.oauthservice2, "DEF",
                                       "UVW")
Example #3
0
    def setUp(self):
        self.tokenService = TokenService(testing="http://localhost:3000")

        self.url1 = "https://10.14.29.60/owncloud/index.php/apps/oauth2/authorize?response_type=code&client_id={}&redirect_uri={}".format(
            1, "http://localhost:8080")
        self.url2 = "http://zenodo.org/oauth/authorize?response_type=code&client_id={}&redirect_uri={}".format(
            2, "http://localhost:8080")

        self.servicename1 = "owncloud-local"
        self.servicename2 = "sandbox.zenodo.org"

        self.user1 = User("user")
        self.user2 = User("user_refresh")

        self.service1 = OAuth2Service(
            servicename=self.servicename1,
            implements=["fileStorage"],
            authorize_url=self.url1,
            refresh_url=
            "https://10.14.29.60/owncloud/index.php/apps/oauth2/api/v1/token",
            client_id="ABC",
            client_secret="XYZ",
        )

        self.service2 = OAuth2Service(
            servicename=self.servicename2,
            implements=["metadata"],
            authorize_url=self.url2,
            refresh_url="https://sandbox.zenodo.org/oauth/token",
            client_id="DEF",
            client_secret="UVW",
        )

        self.token1 = Token(self.user1, self.service1, "ABC")
        self.token2 = OAuth2Token(self.user1, self.service2, "ABC", "XYZ")
Example #4
0
def post():
    data = request.json

    rootUser = User(data.get("userId"))
    service = Util.tokenService.getService(data.get("servicename").lower(), clean=True)
    token = LoginToken(User(data.get("username")), service, data.get("password"))

    return Util.tokenService.addTokenToUser(token, rootUser)
    def testEqual(self):
        user1 = User("Max Mustermann")
        user2 = User("12345")
        user3 = User("Max Mustermann")

        self.assertNotEqual(user1, user2)
        self.assertEqual(user1, user3)
        self.assertEqual(user3, user1)
        self.assertEqual(user1, user1)
Example #6
0
    def test_serviceprojects_add(self):
        proj1 = {"projectId": 0, "metadata": {}}
        proj2 = {"projectId": 1, "metadata": {}}

        userId = "admin"
        servicename = "port-zenodo"

        expected_project = proj1

        pact.given("one searched token was registered.").upon_receiving(
            "a request to get a specific token for service from user."
        ).with_request(
            "GET", f"/user/{userId}/token/{servicename}").will_respond_with(
                200,
                body=json.dumps(
                    Token(
                        User(userId),
                        BaseService(servicename=servicename,
                                    implements=["metadata"]), "ABC")))

        pact.given("service with project support").upon_receiving(
            "try to create a project").with_request(
                "POST",
                f"/metadata/project").will_respond_with(200,
                                                        body=expected_project)

        with pact:
            code = self.client.post(
                "/port-service/user/{}/service/{}/projects".format(
                    userId, servicename)).status_code

        self.assertEqual(code, 200)

        pact.given("one searched token was registered.").upon_receiving(
            "a request to get a specific token for service from user."
        ).with_request(
            "GET", f"/user/{userId}/token/{servicename}").will_respond_with(
                200,
                body=json.dumps(
                    Token(
                        User(userId),
                        BaseService(servicename=servicename,
                                    implements=["metadata"]), "ABC")))

        pact.given("Given token to access port").upon_receiving(
            "invalid request").with_request(
                "POST", "/metadata/project").will_respond_with(500, body="")

        with pact:
            code = self.client.post(
                "/port-service/user/{}/service/{}/projects".format(
                    userId, servicename)).status_code

        self.assertEqual(code, 500)
Example #7
0
    def test_serviceprojects_delete(self):
        proj1 = {"projectId": 0, "metadata": {}}

        userId = "admin"
        servicename = "port-zenodo"

        pact.given("one searched token was registered.").upon_receiving(
            "a request to get a specific token for service from user."
        ).with_request(
            "GET", f"/user/{userId}/token/{servicename}").will_respond_with(
                200,
                body=json.dumps(
                    Token(
                        User(userId),
                        BaseService(servicename=servicename,
                                    implements=["metadata"]), "ABC")))

        pact.given("Given token to access port").upon_receiving(
            "try to delete {}".format(proj1["projectId"])).with_request(
                "DELETE", "/metadata/project/{}".format(
                    proj1["projectId"])).will_respond_with(404, body="")

        with pact:
            code = self.client.delete(
                "/port-service/user/{}/service/{}/projects/{}".format(
                    userId, servicename, proj1["projectId"])).status_code

        self.assertGreaterEqual(code, 404)

        pact.given("one searched token was registered.").upon_receiving(
            "a request to get a specific token for service from user."
        ).with_request(
            "GET", f"/user/{userId}/token/{servicename}").will_respond_with(
                200,
                body=json.dumps(
                    Token(
                        User(userId),
                        BaseService(servicename=servicename,
                                    implements=["metadata"]), "ABC")))

        pact.given("Given token to access port").upon_receiving(
            "a call to delete {}".format(proj1["projectId"])).with_request(
                "DELETE", "/metadata/project/{}".format(
                    proj1["projectId"])).will_respond_with(204, body="")

        with pact:
            code = self.client.delete(
                "/port-service/user/{}/service/{}/projects/{}".format(
                    userId, servicename, proj1["projectId"])).status_code

        self.assertEqual(code, 204)
Example #8
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")
Example #9
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
    def test_logintoken(self):
        user1 = User("Max Mustermann")
        user2 = User("12345")

        service1 = LoginService("MusterService", ["fileStorage"])
        service2 = LoginService("BetonService", ["fileStorage"], userId=False)
        service3 = LoginService("FahrService", ["fileStorage"], password=False)
        service4 = LoginService("TaxiService", ["fileStorage"],
                                userId=False,
                                password=False)

        with self.assertRaises(ValueError):
            LoginToken(None, service1, "")

        with self.assertRaises(ValueError):
            LoginToken(user1, service1, "")

        with self.assertRaises(ValueError):
            LoginToken(None, service1, "DEF")

        with self.assertRaises(ValueError):
            LoginToken(None, service2, "")

        with self.assertRaises(ValueError):
            LoginToken(user1, service2, "")

        LoginToken(None, service2, "DEF")

        with self.assertRaises(ValueError):
            LoginToken(None, service3, "")

        LoginToken(user1, service3, "")
        LoginToken(user1, service3, None)
        LoginToken(user1, service3, "DEF")

        with self.assertRaises(ValueError):
            LoginToken(None, service3, "DEF")

        LoginToken(None, service4, None)
        LoginToken(None, service4, "")
        LoginToken(user1, service4, "")
        LoginToken(None, service4, "DEF")

        Token(user1, service1, "DEF")
        Token(user1, service3, "DEF")
Example #11
0
def get(user_id, servicename):
    servicename = servicename.lower()
    if not servicename.startswith("port-"):
        servicename = "port-{}".format(servicename)

    return jsonify(
        Util.tokenService.getTokenForServiceFromUser(
            BaseService(servicename=servicename, implements=["metadata"]),
            User(user_id)))
Example #12
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}
Example #13
0
 def setUp(self):
     self.user1 = User("MaxMustermann")
     self.service1 = OAuth2Service(
         servicename="TestService",
         implements=["metadata"],
         authorize_url="http://localhost/oauth/authorize",
         refresh_url="http://localhost/oauth/token",
         client_id="MNO",
         client_secret="UVW")
     self.token1 = OAuth2Token(self.user1, self.service1, "ABC", "X_ABC")
    def test_token_service_init(self):
        user1 = User("Max Mustermann")
        service1 = BaseService("MusterService", ["fileStorage"])
        service2 = LoginService("BetonService", ["fileStorage"],
                                userId=True,
                                password=False)

        LoginToken(user1, service2, "")

        with self.assertRaises(ValueError):
            Token(user1, service1, "")
Example #15
0
def delete(user_id, servicename, projects_id):
    servicename = servicename.lower()
    if not servicename.startswith("port-"):
        servicename = "port-{}".format(servicename)

    if Util.tokenService.removeProjectForUserInService(
            User(user_id),
            BaseService(servicename=servicename, implements=["metadata"]),
            projects_id):
        return None, 204
    abort(404)
Example #16
0
def index(user_id, servicename):
    servicename = servicename.lower()
    if not servicename.startswith("port-"):
        servicename = "port-{}".format(servicename)

    listOfServices = Util.tokenService.getAllServicesForUser(User(user_id))

    for svc in listOfServices:
        if svc.get("servicename", "") == servicename:
            return jsonify(svc.get("projects", []))
    abort(404)
Example #17
0
def delete(user_id, servicename):
    servicename = servicename.lower()
    if not servicename.startswith("port-"):
        servicename = "port-{}".format(servicename)

    return jsonify({
        "success":
        Util.tokenService.removeTokenForServiceFromUser(
            BaseService(servicename=servicename, implements=["metadata"]),
            User(user_id))
    })
Example #18
0
    def test_parseToken(self):
        user1 = User("MaxMustermann")
        service1 = LoginService("MusterService", ["fileStorage"])
        token1 = Token(user1, service1, "ABC")

        serviceport = "{}".format(token1.service.servicename)
        data = {
            "userId":
            "port-{}://{}:{}".format("musterservice", "MaxMustermann", "ABC")
        }

        self.assertEqual(Util.parseToken(token1), data)
Example #19
0
    def getUser(self, user_id: str):
        """
        Returns the user with user_id.

        Raise a `UserNotExistsError`, if user not found.
        """

        if user_id in self._storage:
            return self._storage[user_id]["data"]

        from .Exceptions.StorageException import UserNotExistsError

        raise UserNotExistsError(self, User(user_id))
Example #20
0
def post(user_id, servicename):
    servicename = servicename.lower()
    if not servicename.startswith("port-"):
        servicename = "port-{}".format(servicename)

    projectId, project = Util.tokenService.createProjectForUserInService(
        User(user_id),
        BaseService(servicename=servicename, implements=["metadata"]))

    resp = {"projectId": str(projectId)}

    logger.debug("sent: {}".format(resp))
    return jsonify(resp)
Example #21
0
def get(user_id, servicename, projects_id):
    servicename = servicename.lower()
    if not servicename.startswith("port-"):
        servicename = "port-{}".format(servicename)

    projects_id = int(projects_id)
    listOfServices = Util.tokenService.getAllServicesForUser(User(user_id))

    for svc in listOfServices:
        projects = svc.get("projects", [])
        if svc.get("servicename",
                   "") == servicename and projects_id < len(projects):
            return jsonify(projects[projects_id])

    abort(404)
Example #22
0
    def setUp(self):
        global pact
        pact = Consumer('UseCaseMetadataProject').has_pact_with(
            Provider('PortMetadata'), port=3000)

        self.app = create_app()
        self.client = self.app.test_client()

        self.user1 = User("MaxMustermann")
        self.service1 = OAuth2Service(
            servicename="TestService",
            implements=["metadata"],
            authorize_url="http://localhost/oauth/authorize",
            refresh_url="http://localhost/oauth/token",
            client_id="MNO",
            client_secret="UVW")
        self.token1 = OAuth2Token(self.user1, self.service1, "ABC", "X_ABC")
    def test_service_check_raises(self):
        svc1 = OAuth2Service(
            "MusterService",
            ["fileStorage"],
            FileTransferMode.active,
            FileTransferArchive.none,
            "http://localhost:5001",
            "http://localhost:5001/oauth/refresh",
            "ABC",
            "XYZ",
        )

        from RDS import User, Token, OAuth2Token

        with self.assertRaises(ValueError):
            svc1.refresh(Token(User("Max Mustermann"), svc1, "ABC"))
            svc1.refresh("asd")
            svc1.refresh(123)
Example #24
0
def index(user_id):
    listOfServices = Util.tokenService.getAllServicesForUser(User(user_id))
    data = {"length": len(listOfServices), "list": listOfServices}

    return jsonify(data)
    def test_owncloud(self):

        # prepare service
        storage = Storage()

        redirect = "https://10.14.29.60/owncloud/index.php/apps/rds/oauth"
        owncloud = OAuth2Service(
            servicename="owncloud-local",
            implements=["metadata"],
            authorize_url=
            "https://10.14.29.60/owncloud/index.php/apps/oauth2/authorize?response_type=code&client_id={}&redirect_uri={}"
            .format(os.getenv("OWNCLOUD_OAUTH_CLIENT_ID"), redirect),
            refresh_url=
            "https://10.14.29.60/owncloud/index.php/apps/oauth2/api/v1/token",
            client_id=os.getenv("OWNCLOUD_OAUTH_CLIENT_ID"),
            client_secret=os.getenv("OWNCLOUD_OAUTH_CLIENT_SECRET"),
        )

        storage.addService(owncloud)

        # prepare user, which wants to make the whole oauth workflow
        user1 = User("user")
        token1 = Token(user1, owncloud, "user")

        storage.addUser(user1)
        storage.addTokenToUser(token1, user1)

        def get_access_token(user, token):
            nonlocal owncloud, storage

            self.driver.get(owncloud.authorize_url)

            if self.driver.current_url.startswith(
                    "https://10.14.29.60/owncloud/index.php/login"):
                # it redirects to login form
                field_username = self.driver.find_element_by_xpath(
                    '//*[@id="user"]')
                field_password = self.driver.find_element_by_xpath(
                    '//*[@id="password"]')
                field_username.clear()
                field_username.send_keys(user.username)

                field_password.clear()
                field_password.send_keys(token.access_token)

                old_url = self.driver.current_url
                url = self.driver.current_url

                field_password.send_keys(Keys.RETURN)

                retry = 0
                while old_url == url and retry < 5:
                    sleep(1)
                    retry += 1
                    url = self.driver.current_url
                    logger.info("url: {}".format(url))

                if retry >= 5:
                    raise Exception("url not redirect!")

            btn = self.driver.find_element_by_xpath(
                "/html/body/div[1]/div/span/form/button")
            old_url = self.driver.current_url
            url = self.driver.current_url

            btn.click()

            retry = 0
            while old_url == url and retry < 5:
                sleep(1)
                retry += 1
                url = self.driver.current_url
                logger.info("url: {}".format(url))

            if retry >= 5:
                raise Exception("url not redirect!")

            self.driver.delete_all_cookies()  # remove all cookies

            from urllib.parse import urlparse, parse_qs

            query = urlparse(url).query
            logger.info("query: {}".format(query))

            parse = parse_qs(query)
            logger.info("parse: {}".format(parse))

            code = parse["code"]

            data = {
                "grant_type": "authorization_code",
                "code": code,
                "redirect_uri": redirect,
            }

            req = requests.post(
                owncloud.refresh_url,
                data=data,
                auth=(owncloud.client_id, owncloud.client_secret),
                verify=False,
            ).json()
            oauthtoken = OAuth2Token(
                user,
                token.service,
                req["access_token"],
                req["refresh_token"],
                datetime.now() + timedelta(seconds=req["expires_in"]),
            )
            return oauthtoken

        oauthtoken1 = get_access_token(user1, token1)
        storage.addTokenToUser(oauthtoken1, user1, Force=True)

        ######## test a refresh token #######
        # prepare user, which wants to get a refresh token

        oauthuser2 = User("user_refresh")

        # check if there is already a file, which has an oauth2token to reuse it.
        oauthtoken2 = None
        filepath = "https://zivgitlab.uni-muenster.de/{}/{}/-/jobs/artifacts/{}/raw/{}/user_refresh.token?job_token={}&job={}".format(
            os.getenv("CI_PROJECT_NAMESPACE"),
            os.getenv("CI_PROJECT_NAME"),
            os.getenv("CI_COMMIT_REF_NAME"),
            os.getenv("FOLDER"),
            os.getenv("CI_JOB_TOKEN"),
            os.getenv("CI_JOB_NAME"),
        )
        try:
            headers = {"JOB-TOKEN": os.getenv("CI_JOB_TOKEN")}
            req = requests.get(filepath, headers=headers)
            if req.status_code != 200:
                raise Exception(
                    "Artifact not found, filepath: {filepath}, headers: {headers}"
                )

            try:
                oauthtoken2 = initialize_object_from_json(req.text)
            except Exception as e:
                raise Exception(f"{str(e)} + \n req: {req.text}")
        except Exception as e:
            logger.error(e)
            logger.warning(
                "No refresh token from previous test run was found, so we collect a new one. \nFilepath: {}"
                .format(filepath))
            # initialize like user1 with password
            token2 = Token(oauthuser2, owncloud, "user_refresh")

            # generate an oauthtoken like before and overwrite oauthtoken1
            oauthtoken2 = get_access_token(oauthuser2, token2)

        storage.addUser(oauthuser2)
        storage.addTokenToUser(oauthtoken2, oauthuser2)

        # try to refresh it now
        storage.refresh_service(owncloud)
        tokens = storage.getTokens(oauthuser2)
        checkToken = tokens[0]
        self.assertEqual(checkToken, oauthtoken2)

        # safe the current oauthtoken for reuse to test refresh token after a bigger period.
        with open("user_refresh.token", "w") as f:
            f.write(json.dumps(checkToken))
    def test_zenodo(self):
        # prepare service
        storage = Storage()

        zenodo = OAuth2Service(
            servicename="sandbox.zenodo.org",
            authorize_url=
            "https://sandbox.zenodo.org/oauth/authorize?scope=deposit%3Awrite+deposit%3Aactions&state=CHANGEME&redirect_uri=http%3A%2F%2Flocalhost%3A8080&response_type=code&client_id={}"
            .format(os.getenv("ZENODO_OAUTH_CLIENT_ID")),
            refresh_url="https://sandbox.zenodo.org/oauth/token",
            client_id=os.getenv("ZENODO_OAUTH_CLIENT_ID"),
            client_secret=os.getenv("ZENODO_OAUTH_CLIENT_SECRET"),
        )

        # TODO: needs valid user in env var in gitlab
        zenodouser1 = User("USERNAME")
        zenodotoken1 = Token(zenodo.servicename, "PASSWORT")

        def get_access_token(user, token):
            nonlocal zenodo, storage

            self.driver.get(zenodo.authorize_url)

            if self.driver.current_url.startswith(
                    "https://sandbox.zenodo.org/login"):
                # it redirects to login form
                field_username = self.driver.find_element_by_xpath(
                    '//*[@id="email"]')
                field_password = self.driver.find_element_by_xpath(
                    '//*[@id="password"]')
                field_username.clear()
                field_username.send_keys(user.username)

                field_password.clear()
                field_password.send_keys(token.access_token)
                field_password.send_keys(Keys.RETURN)

            self.driver.get(zenodo.authorize_url)
            btn = self.driver.find_element_by_xpath(
                "/html/body/div[2]/div[2]/div/div/div/div/div[2]/div[2]/form/button[1]"
            )
            old_url = self.driver.current_url
            url = self.driver.current_url

            btn.click()

            retry = 0
            while old_url == url and retry < 5:
                sleep(1)
                retry += 1
                url = self.driver.current_url
                logger.info("url: {}".format(url))

            if retry >= 5:
                raise Exception("url not redirect!")

            self.driver.delete_all_cookies()  # remove all cookies

            from urllib.parse import urlparse, parse_qs

            query = urlparse(url).query
            logger.info("query: {}".format(query))

            parse = parse_qs(query)
            logger.info("parse: {}".format(parse))

            code = parse["code"]

            data = {
                "grant_type": "authorization_code",
                "code": code,
                "redirect_uri": redirect,
            }

            req = requests.post(
                zenodo.refresh_url,
                data=data,
                auth=(zenodo.client_id, zenodo.client_secret),
            ).json()
            oauthtoken = OAuth2Token(
                zenodo.servicename,
                req["access_token"],
                req["refresh_token"],
                datetime.now() + timedelta(seconds=req["expires_in"]),
            )
            return oauthtoken

        oauthtoken1 = get_access_token(zenodouser1, zenodotoken1)
        storage.addTokenToUser(oauthtoken1, zenodouser1, Force=True)
Example #27
0
    def exchangeAuthCodeToAccessToken(self, code: str,
                                      service: Union[str, OAuth2Service],
                                      user: str) -> OAuth2Token:
        """Exchanges the given `code` by the given `service`

        Args:
            code (str): The oauth2 exchange code.
            service (Union[str, OAuth2Service]): The servicename, which the code is for.
            user (str): The username, which wants to exchange the code.

        Raises:
            ValueError: The servicename was not valid.
            ServiceNotFoundError: The servicename was not found.
            CodeNotExchangeable: Code was not exchangeable.

        Returns:
            OAuth2Token: The oauth2 token with access- and refresh-tokens.
        """

        if not isinstance(service, (str, OAuth2Service)):
            raise ValueError(
                f"Given service argument {service} is not a valid string or OAuth2Service."
            )

        if type(service) is str:
            service = self.getService(service, clean=True)

            if not isinstance(service, OAuth2Service):
                raise ServiceNotFoundError(
                    service,
                    msg=
                    f"No oauthservice for {service} found, so we cannot exchange code.",
                )

        body = {
            "grant_type":
            "authorization_code",
            "code":
            code,
            "client_id":
            service.client_id,
            "client_secret":
            service.client_secret,
            "redirect_uri":
            os.getenv("RDS_OAUTH_REDIRECT_URI",
                      "http://localhost:3000/redirect"),
        }

        logger.info(f"request body: {body}")

        response = requests.post(
            f"{service.refresh_url}",
            data=body,
            auth=(service.client_id, service.client_secret),
            verify=(os.environ.get("VERIFY_SSL", "True") == "True"),
        )

        logger.info(f"response body: {response.text}")

        if response.status_code != 200:
            raise CodeNotExchangeable(code, service, msg=response.text)

        response_with_access_token = response.json()

        # FIXME: need here some solution, where the response will be evaluated by the corresponding port
        try:
            # owncloud / oauth2 spec
            user_id = response_with_access_token["user_id"]
        except:
            # zenodo specific
            #user_id = response_with_access_token["user"]["id"]
            pass
        # TODO: add here more cloud storage provider for username

        # if no user was set, then this token will be used for superuser
        if user is None:
            user = user_id

        exp_date = response_with_access_token["expires_in"]
        if exp_date > 3600:
            exp_date = 3600

        access_token = response_with_access_token["access_token"]
        refresh_token = response_with_access_token["refresh_token"]
        exp_date = datetime.datetime.now() + datetime.timedelta(
            seconds=exp_date)

        oauthtoken = OAuth2Token(User(user), service, access_token,
                                 refresh_token, exp_date)

        # save the access_token in tokenStorage
        logger.info(f"request oauthtoken body: {oauthtoken}")
        headers = {"Content-type": "application/json"}

        # adjustment to new model in c3 token storage

        response = requests.post(
            f"{self.address}/user/{user}/token",
            data=json.dumps(oauthtoken),
            headers=headers,
            verify=(os.environ.get("VERIFY_SSL", "True") == "True"),
        )
        logger.info(f"response oauthtoken body: {response.text}")

        if response.status_code >= 300:
            raise CodeNotExchangeable(response.status_code,
                                      service,
                                      msg=response.text)

        return oauthtoken
Example #28
0
    def setUp(self):
        self.app = create_app()
        self.client = self.app.test_client()

        self.empty_storage = Storage()

        self.success = {"success": True}

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

        self.service1 = LoginService(servicename="MusterService",
                                     implements=["metadata"])
        self.service2 = LoginService(servicename="BetonService",
                                     implements=["metadata"])
        self.service3 = LoginService(servicename="FahrService",
                                     implements=["metadata"])

        self.oauthservice1 = OAuth2Service.from_service(
            self.service1,
            f"{pact_host_fqdn}/owncloud/index.php/apps/oauth2/authorize",
            f"{pact_host_fqdn}/owncloud/index.php/apps/oauth2/api/v1/token",
            "ABC",
            "XYZ",
        )

        self.oauthservice2 = OAuth2Service.from_service(
            self.service2,
            f"{pact_host_fqdn}/oauth/authorize",
            f"{pact_host_fqdn}/oauth/token",
            "DEF",
            "UVW",
        )

        self.oauthservice3 = OAuth2Service.from_service(
            self.service3,
            f"{pact_host_fqdn}/api/authorize",
            f"{pact_host_fqdn}/api/token",
            "GHI",
            "MNO",
        )

        self.token1 = Token(self.user1, self.service1, "ABC")
        self.token_like_token1 = Token(self.user1, self.service1, "DEF")
        self.token2 = Token(self.user2, self.service2, "XYZ")
        self.token3 = Token(self.user1, self.service3, "GHI")

        self.oauthtoken1 = OAuth2Token(self.user1, self.oauthservice1, "ABC",
                                       "X_ABC")
        self.oauthtoken_like_token1 = OAuth2Token(self.user1,
                                                  self.oauthservice1, "X_DEF")
        self.oauthtoken2 = OAuth2Token(self.user2, self.oauthservice2, "XYZ",
                                       "X_XYZ")
        self.oauthtoken3 = OAuth2Token(self.user1, self.oauthservice3, "GHI",
                                       "X_GHI")

        self.services = [
            self.service1,
            self.service2,
            self.service3,
            self.oauthservice1,
            self.oauthservice2,
            self.oauthservice3,
        ]

        self.filled_storage_without_tokens = Storage()
        self.filled_storage_without_tokens.addUser(self.user1)
        self.filled_storage_without_tokens.addUser(self.user2)
        self.filled_storage_without_tokens.addUser(self.user3)

        self.filled_storage = Storage()

        self.filled_storage.addService(self.oauthservice1)
        self.filled_storage.addService(self.oauthservice2)
        self.filled_storage.addService(self.oauthservice3)

        # user1 is filled with mixed token and oauth2token
        self.filled_storage.addUser(self.user1)
        self.filled_storage.addTokenToUser(self.token1, self.user1)
        self.filled_storage.addTokenToUser(self.token3, self.user1)
        self.filled_storage.addTokenToUser(self.oauthtoken1,
                                           self.user1,
                                           Force=True)

        # user2 is only filled with token
        self.filled_storage.addUser(self.user2)
        self.filled_storage.addTokenToUser(self.token2, self.user2)
Example #29
0
    def test_redirect(self):
        code = "XYZABC"
        user = User("user")
        service = OAuth2Service(
            servicename="port-local",
            implements=["metadata"],
            authorize_url=f"{Util.tokenService.address}/oauth/authorize",
            refresh_url=f"{Util.tokenService.address}/oauth/token",
            client_id="ABC",
            client_secret="XYZ",
        )

        body = {
            "access_token":
            "1vtnuo1NkIsbndAjVnhl7y0wJha59JyaAiFIVQDvcBY2uvKmj5EPBEhss0pauzdQ",
            "token_type":
            "Bearer",
            "expires_in":
            3600,
            "refresh_token":
            "7y0wJuvKmj5E1vjVnhlPBEhha59JyaAiFIVQDvcBY2ss0pauzdQtnuo1NkIsbndA",
            "user_id":
            user.username,
            "message_url":
            "https://www.example.org/owncloud/index.php/apps/oauth2/authorization-successful",
        }

        # test returned state jwt object
        pact.given("An oauthservice was registered.").upon_receiving(
            "A request to get this oauthservice.").with_request(
                "GET", f"/service/{service.servicename}").will_respond_with(
                    200, body=service.to_json())

        with pact:
            response = self.client.get(
                f"/port-service/service/{service.servicename}")
        self.assertEqual(response.status_code,
                         200,
                         msg=response.get_data(as_text=True))

        # ignore signature
        resp_state = jwt.decode(response.json["jwt"],
                                "secret",
                                algorithms="HS256",
                                options={"verify_signature": False})
        logger.info(resp_state)

        self.assertEqual(resp_state["servicename"], service.servicename)
        self.assertEqual(resp_state["authorize_url"], service.authorize_url)

        date = resp_state["date"]

        # following request should not be needed a new pact, because its cached and date shuld be the same.
        response = self.client.get(
            f"/port-service/service/{service.servicename}")
        self.assertEqual(response.status_code,
                         200,
                         msg=response.get_data(as_text=True))

        # ignore signature
        resp_state = jwt.decode(response.json["jwt"],
                                "secret",
                                algorithms="HS256",
                                options={"verify_signature": False})
        logger.info(resp_state)

        self.assertEqual(resp_state["servicename"], service.servicename)
        self.assertEqual(resp_state["authorize_url"], service.authorize_url)

        key = Util.tokenService.secret

        data = {
            "servicename": service.servicename,
            "authorize_url": service.authorize_url,
            "date": str(datetime.datetime.now()),
        }
        import base64
        import json

        stateReal = jwt.encode(data, key, algorithm="HS256")
        state = base64.b64encode(
            json.dumps({
                "jwt": stateReal,
                "user": user.username
            }).encode("utf-8"))

        pluginDict = {
            "servicename": service.servicename,
            "state": stateReal,
            "userId": user.username,
            "code": code,
        }
        jwtEncode = jwt.encode(pluginDict,
                               service.client_secret,
                               algorithm="HS256")

        # need pact for exchange for code
        pact.given("Client ID and secret was registered.").upon_receiving(
            "A request to exchange the given auth code to get access token and refresh token."
        ).with_request("POST", f"/oauth/token").will_respond_with(200,
                                                                  body=body)

        # currently not needed
        # expected = OAuth2Token(user, service, body["access_token"], body["refresh_token"], datetime.datetime.now(
        # ) + datetime.timedelta(seconds=body["expires_in"]))

        # need pact for save the access and refresh token in Token Storage
        pact.given(
            "No token was registered for not registered user").upon_receiving(
                "A request to add an oauthtoken.").with_request(
                    "POST", f"/user/{user.username}/token").will_respond_with(
                        201, body={"success": True})

        with pact:
            response = self.client.post("/port-service/exchange",
                                        json={"jwt": jwtEncode})

        self.assertEqual(response.status_code, 204, msg=response.get_data())