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")
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")
def test_compare_tokens(self): t1 = Token(self.user1, self.service1, "ABC") t2 = Token(self.user1, self.service1, "ABC") t3 = Token(self.user1, self.service2, "ABC") t4 = Token(self.user1, self.service1, "QWERT") t5 = Token(self.user2, self.service2, "ABC") ot1 = OAuth2Token(self.user1, self.oauthservice1, "ABC", "XYZ") ot2 = OAuth2Token(self.user1, self.oauthservice1, "ABC", "XYZ") ot3 = self.oauthtoken2 = OAuth2Token(self.user1, self.oauthservice2, "DEF", "UVW") ot4 = OAuth2Token(self.user1, self.oauthservice1, "QWE", "RTZ") self.assertEqual(t1, t2) self.assertNotEqual(t3, t2) self.assertEqual(t1, t4) self.assertNotEqual(t1, t5) self.assertFalse(t1 is t2) self.assertEqual(ot1, ot2) self.assertNotEqual(ot3, ot2) self.assertEqual(ot1, ot4) self.assertEqual(t1, ot1)
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")
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")
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_tokenstorage_tokens_under_user(self): oauthtoken1 = OAuth2Token(self.user1, self.oauthservice1, "ABC", "X_ABC") self.empty_storage.addTokenToUser(oauthtoken1, self.user1, Force=True) oauthtoken2 = OAuth2Token(self.user1, self.oauthservice2, "XYZ", "X_XYZ") self.empty_storage.addTokenToUser(oauthtoken2, self.user1, Force=True) token1 = Token(self.user1, self.service2, "ISADF") with self.assertRaises(ServiceNotExistsError): self.empty_storage.addTokenToUser(token1, self.user1, Force=True) self.empty_storage.addTokenToUser(self.token1, self.user1, Force=True)
def test_storage_refresh_save_mechanism(self): expires_in = 3600 expected = OAuth2Token(self.user1, self.oauthservice1, "ABC", "XYZ") expected._expiration_date = datetime.fromtimestamp(time() + expires_in) # example taken from https://github.com/owncloud/oauth2 json_expected = { "access_token": expected.access_token, "token_type": "Bearer", "expires_in": expires_in, "refresh_token": expected.refresh_token, "user_id": self.user1.username, "message_url": f"{pact_host_fqdn}/owncloud/index.php/apps/oauth2/authorization-successful", } pact.given( "Storage can refresh given oauth2token and saves it in storage" ).upon_receiving( "A valid refresh token response with a higher expiration date." ).with_request( "POST", "/owncloud/index.php/apps/oauth2/api/v1/token").will_respond_with( 200, body=json_expected) result = None with pact: self.empty_storage.addService(self.oauthservice1) self.empty_storage.addUser(self.user1) self.empty_storage.addTokenToUser(self.oauthtoken4, self.user1) self.empty_storage.refresh_service(self.oauthservice1) result = self.empty_storage.getTokens() # there should only be one element in list, so it is ours self.assertEqual(len(result), 1) self.assertEqual( result[0], expected, msg=f"\nresult: {result[0]}\nexpected: {expected}") self.assertGreaterEqual(result[0].expiration_date, expected.expiration_date)
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_token_empty_string(self): with self.assertRaises(ValueError): Token(None, None, "") with self.assertRaises(ValueError): Token(self.user1, None, "") with self.assertRaises(ValueError): Token(self.user1, None, "ABC") with self.assertRaises(ValueError): OAuth2Token(self.user1, None, "", "") # refresh_token is the only parameter, which can be empty self.assertIsInstance( OAuth2Token(self.user1, self.oauthservice1, "ABC"), OAuth2Token) self.assertIsInstance( OAuth2Token(self.user1, self.oauthservice2, "ABC"), Token) with self.assertRaises(ValueError): OAuth2Token(self.user1, self.oauthservice1, "") with self.assertRaises(ValueError): OAuth2Token(self.user1, self.oauthservice1, "", "") with self.assertRaises(ValueError): OAuth2Token(self.user1, None, "ABC", "") with self.assertRaises(ValueError): OAuth2Token(self.user1, None, "", "X_ABC") with self.assertRaises(ValueError): OAuth2Token(self.user1, self.oauthservice1, "", "X_ABC") with self.assertRaises(ValueError): OAuth2Token(self.user1, None, "ABC", "X_ABC")
def test_token_json(self): dump = json.dumps(self.token1) # self.assertEqual(dump, json.dumps(expected)) self.assertEqual(Token.from_json(dump), self.token1) expected = { "type": "OAuth2Token", "data": { "service": self.service1, "access_token": self.oauthtoken1.access_token, "refresh_token": self.oauthtoken1.refresh_token, "expiration_date": str(self.oauthtoken1.expiration_date), }, } dump = json.dumps(self.oauthtoken1) # self.assertEqual(dump, json.dumps(expected)) self.assertEqual(OAuth2Token.from_json(dump), self.oauthtoken1, msg=dump)
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
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)
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
def test_exchange_code(self): code = "XYZABC" service = OAuth2Service( servicename="localhost", implements=["metadata"], authorize_url=f"{self.tokenService.address}/authorize", refresh_url=f"{self.tokenService.address}/oauth2/token", client_id="ABC", client_secret="XYZ", ) with self.assertRaises(ValueError): self.tokenService.exchangeAuthCodeToAccessToken( code, BaseService(servicename="localhost", implements=["metadata"]), self.user1.username) body = { "access_token": "1vtnuo1NkIsbndAjVnhl7y0wJha59JyaAiFIVQDvcBY2uvKmj5EPBEhss0pauzdQ", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "7y0wJuvKmj5E1vjVnhlPBEhha59JyaAiFIVQDvcBY2ss0pauzdQtnuo1NkIsbndA", "user_id": self.user1.username, "message_url": "https://www.example.org/owncloud/index.php/apps/oauth2/authorization-successful", } # 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"/oauth2/token").will_respond_with(200, body=body) expected = OAuth2Token( self.user1, service, body["access_token"], body["refresh_token"], datetime.now() + timedelta(seconds=body["expires_in"]), ) # need pact for save the access and refresh token in Token Storage pact.given("No token was registered for user").upon_receiving( "A request to add an oauthtoken.").with_request( "POST", f"/user/{self.user1.username}/token").will_respond_with( 200, body={"success": True}) token = self.tokenService.exchangeAuthCodeToAccessToken( code, service, self.user1.username) self.assertEqual(token, expected) # test for service object # 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 service object." ).with_request("POST", f"/oauth2/token").will_respond_with(200, body=body) # need pact for save the access and refresh token in Token Storage pact.given("No token was registered for user").upon_receiving( "A request to add an oauthtoken with service object." ).with_request("POST", f"/user/{self.user1.username}/token").will_respond_with( 200, body={"success": True}) token = self.tokenService.exchangeAuthCodeToAccessToken( code, service, self.user1.username) self.assertEqual(token, expected) # test serviceNotFoundError pact.given("no oauthservice was registered.").upon_receiving( "A request to get a oauthservice.").with_request( "GET", f"/service/{service.servicename}").will_respond_with( 500, body={ "error": "ServiceNotExistsError", "http_code": 500 }) with self.assertRaises(ServiceNotFoundError): self.tokenService.exchangeAuthCodeToAccessToken( code, service.servicename, self.user1.username) self.tokenService._storage = {} # test CodeNotExchangeableError pact.given("An oauthservice was registered.").upon_receiving( "A request to get this oauthservice for exchange code." ).with_request("GET", f"/service/{service.servicename}").will_respond_with( 200, body=json.dumps(service)) # need pact for exchange for code pact.given("Client ID and secret was not registered.").upon_receiving( "A request to exchange the given auth code to get access token and refresh token." ).with_request("POST", f"/oauth2/token").will_respond_with( 500, body={"error": "Login not successful"}) with self.assertRaises(CodeNotExchangeable): self.tokenService.exchangeAuthCodeToAccessToken( code, service.servicename, self.user1.username)