def setUp(self): """ Makes a refresh_token grant to get new tokens for teseting Sets up an AuthClient and a RefreshTokenAuthorizer with a mock on_refresh function for testing their interactions """ super(RefreshTokenAuthorizerIntegrationTests, self).setUp() client_id = get_client_data()["native_app_client1"]["id"] form_data = {'refresh_token': SDKTESTER1A_NATIVE1_TRANSFER_RT, 'grant_type': 'refresh_token', 'client_id': client_id} token_res = globus_sdk.AuthClient().oauth2_token(form_data) token_res = token_res.by_resource_server self.access_token = token_res[ 'transfer.api.globus.org']['access_token'] self.expires_at = token_res[ 'transfer.api.globus.org']['expires_at_seconds'] self.on_refresh = mock.Mock() self.nac = globus_sdk.NativeAppAuthClient( client_id=get_client_data()["native_app_client1"]["id"]) self.authorizer = globus_sdk.RefreshTokenAuthorizer( SDKTESTER1A_NATIVE1_TRANSFER_RT, self.nac, access_token=self.access_token, expires_at=self.expires_at, on_refresh=self.on_refresh) self.tc = globus_sdk.TransferClient(authorizer=self.authorizer)
def test_oauth2_client_credentials_tokens(self): """ Get client credentials tokens, validate results Confirm tokens allow use of userinfo for the client Returns access_token for testing """ with mock.patch.object(self.cac, 'oauth2_token', side_effect=self.cac.oauth2_token) as m: token_res = self.cac.oauth2_client_credentials_tokens( requested_scopes="openid profile") m.assert_called_once_with( {"grant_type": "client_credentials", "scope": "openid profile"}) # validate results self.assertIn("access_token", token_res) self.assertIn("expires_in", token_res) self.assertIn("scope", token_res) self.assertEqual(token_res["resource_server"], "auth.globus.org") self.assertEqual(token_res["token_type"], "Bearer") # confirm usage of userinfo for client access_token = token_res["access_token"] ac = globus_sdk.AuthClient( authorizer=globus_sdk.AccessTokenAuthorizer(access_token)) userinfo_res = ac.oauth2_userinfo() self.assertEqual( userinfo_res["sub"], get_client_data()["confidential_app_client1"]["id"])
def authenticate_credentials(self, key): auth_client = globus_sdk.AuthClient( authorizer=globus_sdk.AccessTokenAuthorizer(key)) try: info = auth_client.oauth2_userinfo() email = info.get('email') if not email: log.error('Unable to get email for user, was "email" ' 'included in scopes?') raise AuthenticationFailed('Unable to verify user email') user_info = auth_client.get_identities(usernames=[email]) try: user_uuid = user_info.data['identities'][0]['id'] except KeyError: raise AuthenticationFailed( 'Failed to verify email "{}"'.format(email)) user = GlobusUser.objects.filter(uuid=user_uuid).first() if not user: user_info = auth_client.get_identities(usernames=[email]) log.debug('ID Info: {}'.format(user_info)) user = GlobusUser(email=email, uuid=user_uuid) user.save() log.debug('Concierge service authenticated user: {}'.format(email)) return user, key except globus_sdk.exc.AuthAPIError: raise AuthenticationFailed( detail={ 'detail': 'Expired or invalid Globus Auth', 'code': 'InvalidOrExpired' })
def userinfo(): # Call get_login_status() to fill out the login status variables (for login/logout display) loginstatus = get_login_status() # If not logged in, welcome and invite to login if not session.get('is_authenticated'): loginstatus["loginlink"] = url_for('login', state='goto-userinfo') return render_template(app.config['APP_LOGIN_TEMPLATE'], pagetitle=app.config['APP_DISPLAY_NAME'], loginstat=loginstatus) # get the stored access token for the Auth API and use it # to authorize stuff AS THE AUTHENTICATED USER auth_token = str(session.get('auth_token')) ac = globus_sdk.AuthClient( authorizer=globus_sdk.AccessTokenAuthorizer(auth_token)) try: # use Auth API to get the standard OIDC userinfo fields (like any OIDC client) oidcinfo = ac.oauth2_userinfo() except GlobusAPIError: # if any of the above have issues, trash the session and start over session.clear() return redirect(url_for('index')) # display all this information on the web page return render_template('userinfo.html', pagetitle=app.config['APP_DISPLAY_NAME'], explanationurl=url_for('change_linked_ids'), oidcinfo=json.dumps(oidcinfo.data, indent=3), loginstat=loginstatus)
def get_globus_client(self, username=None): """ Get Globus SDK RESTful clients Args: username (str): User's GlobusID username Returns: auth_client (Globus SDK Client): Globus Auth RESTful client nexus_client (Globus Nexus Client): Globus Auth-based RESTful Globus Nexus client """ if username is None: username = self.config["globus"]["root_user"]["username"] log.debug("Getting Globus SDK Auth and Nexus client for user %s", username) # Setting up Globus SDK client client_id = self.config["globus"]["app"]["client_id"] client_secret = self.config["globus"]["app"]["client_secret"] confidential_client = globus_sdk.ConfidentialAppAuthClient( client_id, client_secret) # Getting Authorizers auth_token, nexus_token = self.get_tokens(username) auth_authorizer = globus_sdk.RefreshTokenAuthorizer( auth_token, confidential_client) nexus_authorizer = globus_sdk.RefreshTokenAuthorizer( nexus_token, confidential_client) auth_client = globus_sdk.AuthClient(authorizer=auth_authorizer) nexus_client = NexusClient(authorizer=nexus_authorizer) return auth_client, nexus_client
def globusDo(func, tc: globus_sdk.TransferClient, **kwargs): if tc is None: tc = getGlobusObj() try: sess: synapse_session.obj = get_session() if (sess.globus_id == '') or (len(sess.globus_id) < 5): auth2 = globus_sdk.AccessTokenAuthorizer( session['tokens']['auth.globus.org']['access_token']) client = globus_sdk.AuthClient(authorizer=auth2) info = client.oauth2_userinfo() session['globus_id'] = info['sub'] sess.set_globus_id(info['sub']) sess.settings.globus_usr = info['preferred_username'] sess.save_settings() # session[usr.settings.GLOBUS_ID] = info['sub'] # session[usr.settings.GLOBUS_USER] = info['preferred_username'] print(info.data) return func(tc, kwargs) # globus.available_endpoints(transfer_client) except (globus_sdk.exc.TransferAPIError, KeyError) as e: if 'Token is not active' in str(e): return redirect(url_for('globus_login')) return "There was an error getting available Globus end points: " + str( e) except globus_sdk.exc.AuthAPIError as authapie: if 'FORBIDDEN' in str(authapie): return redirect(url_for('logout'))
def identities(): # Call get_login_status() to fill out the login status variables (for login/logout display) loginstatus = get_login_status() # If not logged in, welcome and invite to login if not session.get('is_authenticated'): return render_template(app.config['APP_LOGIN_TEMPLATE'], pagetitle=app.config['APP_DISPLAY_NAME'], loginurl=url_for('login'), loginstat=loginstatus) # get the stored access token for the Auth API and use it to access the Auth API # on the user's behalf auth_token = str(session.get('auth_token')) ac = globus_sdk.AuthClient( authorizer=globus_sdk.AccessTokenAuthorizer(auth_token)) try: # use Auth API to get more info about the authenticated user myids = ac.get_identities(ids=str(session.get('userid')), include="identity_provider").data except GlobusAPIError: # if any of the above have issues, trash the session and start over session.clear() return redirect(url_for('index')) # display all this information on the web page return render_template('identities.html', pagetitle=app.config['APP_DISPLAY_NAME'], explanationurl=url_for('change_effective_id'), globusmyids=json.dumps(myids, indent=3), loginstat=loginstatus)
def test_oauth2_get_authorize_url_native(): """ Starts an auth flow with a NativeAppFlowManager, gets the authorize url validates expected results with both default and specified parameters. """ ac = globus_sdk.AuthClient(client_id=CLIENT_ID) # default parameters for starting auth flow flow_manager = globus_sdk.auth.GlobusNativeAppFlowManager(ac) ac.current_oauth2_flow_manager = flow_manager # get url_and validate results url_res = ac.oauth2_get_authorize_url() expected_vals = [ ac.base_url + "v2/oauth2/authorize?", "client_id=" + ac.client_id, "redirect_uri=" + urllib.parse.quote_plus(ac.base_url + "v2/web/auth-code"), "scope=" + urllib.parse.quote_plus(" ".join(DEFAULT_REQUESTED_SCOPES)), "state=" + "_default", "response_type=" + "code", "code_challenge=" + urllib.parse.quote_plus(flow_manager.challenge), "code_challenge_method=" + "S256", "access_type=" + "online", ] for val in expected_vals: assert val in url_res # starting flow with specified paramaters flow_manager = globus_sdk.auth.GlobusNativeAppFlowManager( ac, requested_scopes="scopes", redirect_uri="uri", state="state", verifier=("a" * 43), refresh_tokens=True, ) ac.current_oauth2_flow_manager = flow_manager # get url_and validate results url_res = ac.oauth2_get_authorize_url() verifier, remade_challenge = make_native_app_challenge("a" * 43) expected_vals = [ ac.base_url + "v2/oauth2/authorize?", "client_id=" + ac.client_id, "redirect_uri=" + "uri", "scope=" + "scopes", "state=" + "state", "response_type=" + "code", "code_challenge=" + urllib.parse.quote_plus(remade_challenge), "code_challenge_method=" + "S256", "access_type=" + "offline", ] for val in expected_vals: assert val in url_res
def setUp(self): """ Instantiates an AuthClient with an access_token authorizer """ super(AuthClientTests, self).setUp() # get access token client_id = get_client_data()["native_app_client1"]["id"] form_data = { 'refresh_token': SDKTESTER1A_NATIVE1_AUTH_RT, 'grant_type': 'refresh_token', 'client_id': client_id } token_res = globus_sdk.AuthClient().oauth2_token(form_data) self.access_token = token_res["access_token"] # make auth client self.ac = globus_sdk.AuthClient( authorizer=globus_sdk.AccessTokenAuthorizer(self.access_token), client_id=client_id)
def auth_client(): tmplog_handle, tmplog = tempfile.mkstemp() client = globus_sdk.AuthClient() client.logger.logger.addHandler(logging.FileHandler(tmplog)) yield client try: os.remove(tmplog) except OSError: pass
def index(): """ This could be any page you like, rendered by Flask. For this simple example, it will either redirect you to login, or print a simple message. """ if not session.get('is_authenticated'): return redirect(url_for('login')) logout_uri = url_for('logout', _external=True) # get the stored access token for the Auth API and use it # to authorize stuff AS THE AUTHENTICATED USER auth_token = str(session.get('tokens')['auth.globus.org']['access_token']) ac = globus_sdk.AuthClient( authorizer=globus_sdk.AccessTokenAuthorizer(auth_token)) # use Auth API to get more info about the authenticated user myids = ac.get_identities(ids=str(session.get('username')), include="identity_provider").data # use Auth API to get the standard OIDC userinfo fields (like any OIDC client) oidcinfo = ac.oauth2_userinfo() # get the stored OIDC id_token myoidc = session.get('id_token') # authenticate to Auth API AS AN APPLICATION and find out still more information cc = load_app_client() ir = cc.oauth2_token_introspect(auth_token, include='identities_set').data # display all this information on the web page page = '<html>\n<head><title>Display Your Auth Data</title></head>\n\n' page = page + '<body>\n<p>' + str( session.get('realname')) + ', you are logged in.</p>\n\n' page = page + '<p>Your local username is: ' + str( session.get('username')) + '</p>\n\n' page = page + '<p><a href="' + logout_uri + '">Logout now.</a></p>\n\n' page = page + '<p>OIDC UserInfo says your effective ID is ' + oidcinfo[ "sub"] page = page + ', your name is ' + oidcinfo["name"] page = page + ', and your email is ' + oidcinfo["email"] + '.</p>\n\n' page = page + '<pre>' + json.dumps(oidcinfo.data, indent=3) + '</pre>\n\n' page = page + '<p>Your OIDC identity is:</p>\n<pre>' + json.dumps( myoidc, indent=3) + '</pre>\n\n' page = page + '<p>Your Globus Auth identity is:</p>\n<pre>' + json.dumps( myids, indent=3) + '</pre>\n\n' page = page + '<p>Introspecting your Auth API access token tells me:</p>\n<pre>' + json.dumps( ir, indent=3) + '</pre>\n\n' # We probably shouldn't display the token, but for debugging purposes, here's how you'd do it... # page = page + '<p>The tokens I received are:</p>\n<pre>' + json.dumps(session.get('tokens'),indent=3) + '</pre>\n\n' page = page + '</body></html>' return (page)
def test_oauth2_get_authorize_url_confidential(): """ Starts an auth flow with a AuthorizationCodeFlowManager, gets the authorize url, validates expected results with both default and specified parameters. """ ac = globus_sdk.AuthClient(client_id=CLIENT_ID) # default parameters for starting auth flow flow_manager = globus_sdk.auth.GlobusAuthorizationCodeFlowManager( ac, "uri") ac.current_oauth2_flow_manager = flow_manager # get url_and validate results url_res = ac.oauth2_get_authorize_url() expected_vals = [ ac.base_url + "v2/oauth2/authorize?", "client_id=" + ac.client_id, "redirect_uri=" + "uri", "scope=" + quote_plus(" ".join(DEFAULT_REQUESTED_SCOPES)), "state=" + "_default", "response_type=" + "code", "access_type=" + "online", ] for val in expected_vals: assert val in url_res # starting flow with specified paramaters flow_manager = globus_sdk.auth.GlobusAuthorizationCodeFlowManager( ac, requested_scopes="scopes", redirect_uri="uri", state="state", refresh_tokens=True, ) ac.current_oauth2_flow_manager = flow_manager # get url_and validate results url_res = ac.oauth2_get_authorize_url() expected_vals = [ ac.base_url + "v2/oauth2/authorize?", "client_id=" + ac.client_id, "redirect_uri=" + "uri", "scope=" + "scopes", "state=" + "state", "response_type=" + "code", "access_type=" + "offline", ] for val in expected_vals: assert val in url_res
def get_cached_created_by(self): """Get the 'created_by' field by pulling the current users name from Globus Auth. The field is only fetched the first time after the client has been instantiated. After that, the value is cached and returned from memory. This speeds things up if calling register() multiple times from the same client. """ if getattr(self, '_cached_created_by', None): return self._cached_created_by authorizer = self.native_client.get_authorizers()['auth.globus.org'] ac = globus_sdk.AuthClient(authorizer=authorizer) user_info = ac.oauth2_userinfo() self._cached_created_by = user_info.data.get('name', '') return self._cached_created_by
def change_linked_ids(): # Call get_login_status() to fill out the login status variables (for login/logout display) loginstatus = get_login_status() # If not logged in, welcome and invite to login if not session.get('is_authenticated'): loginstatus["loginlink"] = url_for('login', state='goto-change_linked_ids') return render_template(app.config['APP_LOGIN_TEMPLATE'], pagetitle=app.config['APP_DISPLAY_NAME'], loginstat=loginstatus) # get the id_token from session context myoidc = session.get('id_token') primaryidp = myoidc['identity_provider_display_name'] # get the stored access token for the Auth API and use it # to authorize stuff AS THE AUTHENTICATED USER auth_token = str(session.get('auth_token')) ac = globus_sdk.AuthClient( authorizer=globus_sdk.AccessTokenAuthorizer(auth_token)) # get the identity_set from oauth2_userinfo() try: # use Auth API to get more info about the authenticated user myids = ac.get_identities(ids=str(session.get('userid')), include="identity_provider").data # use Auth API to get the standard OIDC userinfo fields (like any OIDC client) oidcinfo = ac.oauth2_userinfo() except GlobusAPIError: # if any of the above have issues, trash the session and start over session.clear() return redirect(url_for('index')) # there will always be at least one entry in the identity_set idsetproviders = '' first = True for id in oidcinfo.data['identity_set']: if first: first = False else: idsetproviders += ', ' idsetproviders += id['identity_provider_display_name'] return render_template('change-linked-ids.html', pagetitle=app.config['APP_DISPLAY_NAME'], returnurl=url_for('index'), primaryidp=primaryidp, idsetproviders=idsetproviders, loginstat=loginstatus)
def test_oauth2_exchange_code_for_tokens_native(self): """ Starts a NativeAppFlowManager, Confirms invalid code raises 401 Further testing cannot be done without user login credentials """ ac = globus_sdk.AuthClient( client_id=get_client_data()["native_app_client1"]["id"]) flow_manager = globus_sdk.auth.GlobusNativeAppFlowManager(ac) ac.current_oauth2_flow_manager = flow_manager with self.assertRaises(AuthAPIError) as apiErr: ac.oauth2_exchange_code_for_tokens("invalid_code") self.assertEqual(apiErr.exception.http_status, 401) self.assertEqual(apiErr.exception.code, "Error")
def sessioninfo(): # Call get_login_status() to fill out the login status variables (for login/logout display) loginstatus = get_login_status() # If not logged in, welcome and invite to login if not session.get('is_authenticated'): loginstatus["loginlink"] = url_for('login', state='goto-sessioninfo') return render_template(app.config['APP_LOGIN_TEMPLATE'], pagetitle=app.config['APP_DISPLAY_NAME'], loginstat=loginstatus) # get the stored access token for the Auth API and use it to authorize access # on the user's behalf auth_token = str(session.get('auth_token')) ac = globus_sdk.AuthClient( authorizer=globus_sdk.AccessTokenAuthorizer(auth_token)) try: # authenticate to Auth API AS AN APPLICATION and use it to introspect the token cc = load_app_client() # we ask for session_info (duh) and for identity_set_detail to get linked identities # the linked identities are for: (a) interpreting the authentication results, # and (b) offering to boost the session with additional authentications ir = cc.oauth2_token_introspect( auth_token, include='identity_set_detail,session_info').data except GlobusAPIError: # if any of the above have issues, trash the session and start over session.clear() return redirect(url_for('index')) # get linked identities - this is used below to look up the identity provider's name # AND is passed into the page template to allow the user to add an authentication to # the current session identities = ir['identity_set_detail'] # use the session data to find out how the user authenticated authevents = get_auth_events(ir, identities) # pull the session information out of the introspection results sinfo = ir['session_info'] # display all this information on the web page return render_template('session.html', pagetitle=app.config['APP_DISPLAY_NAME'], explanationurl=url_for('change_effective_id'), authevents=authevents, identities=identities, sessioninfo=json.dumps(sinfo, indent=3), loginstat=loginstatus)
def test_oauth2_token(self): """ Gets an access_token using oauth2/token directly, validates results. """ client_id = get_client_data()["native_app_client1"]["id"] form_data = { 'refresh_token': SDKTESTER1A_NATIVE1_AUTH_RT, 'grant_type': 'refresh_token', 'client_id': client_id } # valid client token_res = globus_sdk.AuthClient().oauth2_token(form_data) self.assertIn("access_token", token_res) self.assertIn("expires_in", token_res) self.assertIn("scope", token_res)
def test_get_identities_errors(self): """ Confirms bad and unauthorized requests to get_identities throw errors """ # bad request with self.assertRaises(AuthAPIError) as apiErr: self.ac.get_identities(usernames=["a", "b"], ids=["0", "1"]) self.assertEqual(apiErr.exception.http_status, 400) self.assertEqual(apiErr.exception.code, "INVALID_PARAMETERS") # no auth with self.assertRaises(AuthAPIError) as apiErr: globus_sdk.AuthClient().get_identities() self.assertEqual(apiErr.exception.http_status, 401) self.assertEqual(apiErr.exception.code, "UNAUTHORIZED")
def identities(): # Call get_login_status() to fill out the login status variables (for login/logout display) loginstatus = get_login_status() # If not logged in, welcome and invite to login if not session.get('is_authenticated'): loginstatus["loginlink"] = url_for('login', state='goto-identities') return render_template(app.config['APP_LOGIN_TEMPLATE'], pagetitle=app.config['APP_DISPLAY_NAME'], loginstat=loginstatus) # Check to see if a specific identity was requested if 'id' in request.args: id = request.args.get('id') else: id = str(loginstatus["identity"]) # get the stored access token for the Auth API and use it to access the Auth API # on the user's behalf auth_token = str(session.get('auth_token')) ac = globus_sdk.AuthClient( authorizer=globus_sdk.AccessTokenAuthorizer(auth_token)) try: # use Auth API to get more info about the authenticated user myids = ac.get_identities(usernames=id, query_params={ "include": "identity_provider" }).data except GlobusAPIError: # if any of the above have issues, trash the session and start over session.clear() return redirect(url_for('index')) # Now get the list of linked identities from the id_token in the session cache # This is passed into the page template to allow the user to lookup any of the # linked identities linkedids = session.get('id_token')['identity_set'] # display all this information on the web page return render_template('identities.html', pagetitle=app.config['APP_DISPLAY_NAME'], explanationurl=url_for('change_linked_ids'), id=id, globusmyids=json.dumps(myids, indent=3), linkedids=linkedids, loginstat=loginstatus)
def test_oauth2_userinfo(self): """ Gets userinfo, validates results Confirms unauthorized client cannot access userinfo """ userinfo_res = self.ac.oauth2_userinfo() self.assertEqual(userinfo_res["preferred_username"], get_user_data()["sdktester1a"]["username"]) self.assertEqual(userinfo_res["name"], get_user_data()["sdktester1a"]["name"]) self.assertEqual(userinfo_res["sub"], get_user_data()["sdktester1a"]["id"]) # unauthorized client with self.assertRaises(AuthAPIError) as apiErr: globus_sdk.AuthClient().oauth2_userinfo() self.assertEqual(apiErr.exception.http_status, 403) self.assertEqual(apiErr.exception.code, "FORBIDDEN")
def sessioninfo(): # Call get_login_status() to fill out the login status variables (for login/logout display) loginstatus = get_login_status() # If not logged in, welcome and invite to login if not session.get('is_authenticated'): return render_template(app.config['APP_LOGIN_TEMPLATE'], pagetitle=app.config['APP_DISPLAY_NAME'], loginurl=url_for('login'), loginstat=loginstatus) # get the stored access token for the Auth API and use it to authorize access # on the user's behalf auth_token = str(session.get('auth_token')) ac = globus_sdk.AuthClient( authorizer=globus_sdk.AccessTokenAuthorizer(auth_token)) try: # authenticate to Auth API AS AN APPLICATION and use it to introspect the token cc = load_app_client() ir = cc.oauth2_token_introspect( auth_token, include='identities_set,session_info').data # get the UserInfo data with the identity_set included. # this is used below to look up the identity provider's name. oidcinfo = ac.oauth2_userinfo() # use the session data to find out how the user authenticated authevents = get_auth_events(ir, oidcinfo) # pull the session information out of the introspection results sinfo = ir['session_info'] except GlobusAPIError: # if any of the above have issues, trash the session and start over session.clear() return redirect(url_for('index')) # display all this information on the web page return render_template('session.html', pagetitle=app.config['APP_DISPLAY_NAME'], explanationurl=url_for('change_effective_id'), authevents=authevents, sessioninfo=json.dumps(sinfo, indent=3), loginstat=loginstatus)
def create_clients(args): """ Create authorize and transfer clients Parameters ---------- globus_app_id : App UUID Returns ------- ac : Authorize client tc : Transfer client """ token_response = refresh_globus_token(args) # let's get stuff for the Globus Transfer service globus_transfer_data = token_response.by_resource_server[ 'transfer.api.globus.org'] # the refresh token and access token, often abbr. as RT and AT transfer_rt = globus_transfer_data['refresh_token'] transfer_at = globus_transfer_data['access_token'] expires_at_s = globus_transfer_data['expires_at_seconds'] globus_token_life = expires_at_s - time.time() log.warning("Globus access token will expire in %2.2f hours", (globus_token_life / 3600)) # see https://globus-sdk-python.readthedocs.io/en/stable/tutorial/#step-1-get-a-client # to create your project app_id. Once is set put it in globus.config app-id field globus_app_id = args.globus_app_uuid client = globus_sdk.NativeAppAuthClient(globus_app_id) client.oauth2_start_flow(refresh_tokens=True) # Now we've got the data we need, but what do we do? # That "GlobusAuthorizer" from before is about to come to the rescue authorizer = globus_sdk.RefreshTokenAuthorizer(transfer_rt, client, access_token=transfer_at, expires_at=expires_at_s) # and try using `tc` to make TransferClient calls. Everything should just # work -- for days and days, months and months, even years ac = globus_sdk.AuthClient(authorizer=authorizer) tc = globus_sdk.TransferClient(authorizer=authorizer) return ac, tc
def __init__(self): """ The ACLManager is used to add and remove acl endpoints for KBase Users on our Globus Share """ logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) config = configparser.ConfigParser() config.read("/etc/globus.cfg") cf = config['globus'] self.endpoint_id = cf['endpoint_id'] client = globus_sdk.NativeAppAuthClient(cf['client_id']) try: transfer_authorizer = globus_sdk.RefreshTokenAuthorizer(cf['transfer_token'], client) self.globus_transfer_client = globus_sdk.TransferClient(authorizer=transfer_authorizer) auth_authorizer = globus_sdk.RefreshTokenAuthorizer(cf['auth_token'], client) self.globus_auth_client = globus_sdk.AuthClient(authorizer=auth_authorizer) except globus_sdk.GlobusAPIError as error: logging.error(str(error.code) + error.raw_text) raise HTTPInternalServerError(text=str("Invalid Token Specified in globus.cfg file"))
def test_oauth2_revoke_token(self): """ Gets an access_token from test_oauth2_refresh_token, then revokes it Confirms that the base AuthClient logic for handling Null Authorizers passes the client id correctly, and the token can no longer be used """ # get and then revoke the token access_token = self.test_oauth2_refresh_token() rev_res = self.nac.oauth2_revoke_token(access_token) # validate results self.assertFalse(rev_res["active"]) # confirm token is no longer usable with self.assertRaises(AuthAPIError) as apiErr: ac = globus_sdk.AuthClient( authorizer=globus_sdk.AccessTokenAuthorizer(access_token), client_id=get_client_data()["native_app_client1"]["id"]) ac.oauth2_userinfo() self.assertEqual(apiErr.exception.http_status, 403) self.assertEqual(apiErr.exception.code, "FORBIDDEN")
def validate_globus_user(email, authorization_header): try: type, code = authorization_header.split() if str(type) != 'Bearer': raise AuthorizationException( 'Only Bearer tokens are supported ' 'for Globus Auth', user=email, type='InvalidToken') import globus_sdk # noqa ac = globus_sdk.AuthClient( authorizer=globus_sdk.AccessTokenAuthorizer(code)) try: idents = ac.get_identities(email).get('identities') if not idents: raise AuthorizationException('User needs to link their email ' '%s to their Globus identity: ' 'globus.org/app/account' % email, user=email, type='InvalidIdentity') except globus_sdk.exc.AuthAPIError: raise AuthorizationException( 'Expired or invalid Globus Auth ' 'code.', user=email, type='AuthorizationFailed') except (ValueError, AttributeError): raise AuthorizationException('Invalid Globus Authorization Header.', user=email, type='InvalidHeader') except ImportError: print('Please install Globus: "pip install globus_sdk"') raise AuthorizationException( 'Server is misconfigured to use ' 'Globus Auth, please notify ' 'the administrator. Sorry.', user=email, code=500, type='ServerError')
def putRedirectUri(client_id, secret, redirect_uri): """ Check if VC3 headnode IP address is in the Redirect_URI globus app list (and add it if not). """ clients_api_base_url = "/v2/api/clients" authorizer = globus_sdk.BasicAuthorizer(client_id, secret) auth_client = globus_sdk.AuthClient(client_id=client_id, authorizer=authorizer) res = auth_client.get("{}/{}".format(clients_api_base_url, client_id)) redirects = res["client"]["redirect_uris"] if redirect_uri not in redirects: redirects.append(redirect_uri) res = auth_client.put("{}/{}".format(clients_api_base_url, client_id), {'client': { 'redirect_uris': redirects }}) assert redirect_uri in res["client"][ "redirect_uris"], "Failed adding Redirect_URI"
def test_oauth2_exchange_code_for_tokens_native(): """ Starts a NativeAppFlowManager, Confirms invalid code raises 401 Further testing cannot be done without user login credentials """ register_api_route( "auth", "/v2/oauth2/token", method="POST", body=INVALID_GRANT_RESPONSE_BODY, status=401, ) ac = globus_sdk.AuthClient(client_id=CLIENT_ID) flow_manager = globus_sdk.auth.GlobusNativeAppFlowManager(ac) ac.current_oauth2_flow_manager = flow_manager with pytest.raises(globus_sdk.AuthAPIError) as excinfo: ac.oauth2_exchange_code_for_tokens("invalid_code") assert excinfo.value.http_status == 401 assert excinfo.value.code == "Error"
def setUp(self): """ Do a refresh_token grant token call to get token responses, test with those results that. """ super(RefreshTokenResponsePickleTests, self).setUp() client_id = get_client_data()["native_app_client1"]["id"] form_data = { 'refresh_token': SDKTESTER1A_NATIVE1_TRANSFER_RT, 'grant_type': 'refresh_token', 'client_id': client_id } self.ac = globus_sdk.AuthClient() # add a logger with an open file handle to ensure that the client # cannot be pickled -- this is the common way that pickleability is # broken # also, this looks odd -- logger.logger -- but it's correct, "logger" # is what we named our LoggerAdapter, and "logger" is the name of the # underlying logger object on a LoggerAdapter tmplog_handle, self.tmplog = tempfile.mkstemp() self.ac.logger.logger.addHandler(logging.FileHandler(self.tmplog)) self.token_response = self.ac.oauth2_token(form_data)
def auth_client(): storage_adapter = token_storage_adapter() as_dict = storage_adapter.read_as_dict() if as_dict is None or AUTH_RESOURCE_SERVER not in as_dict: raise click.UsageError( "Cannot load Auth credentials. Probably not logged in.") authdata = as_dict[AUTH_RESOURCE_SERVER] access_token = authdata["access_token"] refresh_token = authdata["refresh_token"] access_token_expires = authdata["expires_at_seconds"] authorizer = globus_sdk.RefreshTokenAuthorizer( refresh_token, internal_auth_client(), access_token, int(access_token_expires), on_refresh=storage_adapter.on_refresh, ) return globus_sdk.AuthClient(authorizer=authorizer, app_name="searchable-files")
def test_oauth2_refresh_token(self): """ Sends a refresh_token grant, validates results Confirms received access_token can be used to authorize userinfo Returns the access token for use in test_oauth2_revoke_token """ ref_res = self.nac.oauth2_refresh_token(SDKTESTER1A_NATIVE1_AUTH_RT) self.assertIn("access_token", ref_res) self.assertIn("expires_in", ref_res) self.assertIn("scope", ref_res) self.assertEqual(ref_res["resource_server"], "auth.globus.org") self.assertEqual(ref_res["token_type"], "Bearer") # confirm token can be used access_token = ref_res["access_token"] ac = globus_sdk.AuthClient( authorizer=globus_sdk.AccessTokenAuthorizer(access_token), client_id=get_client_data()["native_app_client1"]["id"]) userinfo_res = ac.oauth2_userinfo() self.assertEqual(userinfo_res["sub"], get_user_data()["sdktester1a"]["id"]) # return access_token return access_token