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)
Example #2
0
    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"])
Example #3
0
    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'
                })
Example #4
0
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)
Example #5
0
    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
Example #6
0
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'))
Example #7
0
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)
Example #8
0
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)
Example #10
0
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
Example #11
0
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)
Example #12
0
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
Example #13
0
 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")
Example #16
0
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")
Example #19
0
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")
Example #21
0
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)
Example #22
0
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
Example #23
0
    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"))
Example #24
0
    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")
Example #25
0
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')
Example #26
0
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"
Example #27
0
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"
Example #28
0
    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)
Example #29
0
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")
Example #30
0
    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