Exemplo n.º 1
0
def create_shared_endpoint(globus_dict,
                           host_endpoint,
                           host_path,
                           display_name='Globus endpoint',
                           description='description'):
    globus_transfer_token = globus_dict['transfer_token']
    scopes = "urn:globus:auth:scopes:transfer.api.globus.org:all"
    authorizer = globus_sdk.AccessTokenAuthorizer(globus_transfer_token)
    tc = TransferClient(authorizer=authorizer)
    # high level interface; provides iterators for list responses
    shared_ep_data = {
        "DATA_TYPE": "shared_endpoint",
        "host_endpoint": host_endpoint,
        "host_path": host_path,
        "display_name": display_name,
        # optionally specify additional endpoint fields
        "description": description
    }
    #r = tc.operation_mkdir(host_id, path=share_path) #TODO create the directory directly from here instead of at local level?

    tc.endpoint_autoactivate(host_endpoint,
                             if_expires_in=3600)  #necessary for real use?
    create_result = tc.create_shared_endpoint(
        shared_ep_data)  #not the app's end point, so should fail
    endpoint_id = create_result['id']
    globus_dict['endpoint_id'] = endpoint_id
    globus_dict['transfer_client'] = tc
    return globus_dict
Exemplo n.º 2
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)
Exemplo n.º 3
0
    def __init__(self):
        """
            Initializes the HuBMAP downloader with client ID and hubmap endpoint.

            Here the user is asked to authenticate himself.
        """

        self.CLIENT_ID = '40628e5b-29ae-43c7-adc5-38c75ff907b9'
        self.hubmap_endpoint_id = "af603d86-eab9-4eec-bb1d-9d26556741bb"

        client = globus_sdk.NativeAppAuthClient(self.CLIENT_ID)
        client.oauth2_start_flow()

        authorize_url = client.oauth2_get_authorize_url()
        print('Please go to this URL and login: {0}'.format(authorize_url))

        # this is to work on Python2 and Python3 -- you can just use raw_input() or
        # input() for your specific version
        get_input = getattr(__builtins__, 'raw_input', input)
        auth_code = get_input(
            'Please enter the code you get after login here: ').strip()
        token_response = client.oauth2_exchange_code_for_tokens(auth_code)

        globus_auth_data = token_response.by_resource_server['auth.globus.org']
        globus_transfer_data = token_response.by_resource_server[
            'transfer.api.globus.org']

        # most specifically, you want these tokens as strings
        self.AUTH_TOKEN = globus_auth_data['access_token']
        self.TRANSFER_TOKEN = globus_transfer_data['access_token']

        self.authorizer = globus_sdk.AccessTokenAuthorizer(self.TRANSFER_TOKEN)
        self.tc = globus_sdk.TransferClient(authorizer=self.authorizer)

        self.transfers = []
Exemplo n.º 4
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"])
Exemplo n.º 5
0
def get_confidential_app_authorizer(client_id, client_secret):
    tokens = do_client_credentials_app_authentication(
        client_id=client_id, client_secret=client_secret)
    transfer_tokens = tokens['transfer.api.globus.org']
    transfer_access_token = transfer_tokens['access_token']

    return globus_sdk.AccessTokenAuthorizer(transfer_access_token)
Exemplo n.º 6
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)
Exemplo n.º 7
0
def get_transfer_client(ctoken_obj):
    """
    Get a transfer client from a ConciergeToken (request.auth obj)
    """
    transfer_token = ctoken_obj.get_token(settings.TRANSFER_SCOPE)
    transfer_authorizer = globus_sdk.AccessTokenAuthorizer(transfer_token)
    return globus_sdk.TransferClient(authorizer=transfer_authorizer)
Exemplo n.º 8
0
def get_globus_data(auth_token, transfer_token, gconfig):

    admin_endpoint_map = {}
    endpoint_map_list_of_tasks = {}

    # GlobusAuthorizer
    authorizer = globus_sdk.AccessTokenAuthorizer(transfer_token)
    tc = globus_sdk.TransferClient(authorizer=authorizer)

    # High level interface; provides iterators for list responses.
    # Get endpoints administered by user with given tokens
    for ep in tc.endpoint_search(filter_scope="administered-by-me"):
        print("[{}] {}".format(ep["id"], ep["display_name"]))
        admin_endpoint_map[ep["id"]] = ep["display_name"]
        if ep["display_name"] is None:
            if ep["canonical_name"] is not None:
                admin_endpoint_map[ep["id"]] = ep["canonical_name"]
            else:
                admin_endpoint_map[ep["id"]] = str(ep["id"])

        # Filter DTNs that are not in the list of interested DTNs
        if ep["id"] not in gconfig["interested_dtn_id_list"]:
            continue

        task_list = []
        iter_paginated_res = (tc.endpoint_manager_task_list(
            num_results=None, filter_endpoint=ep["id"]))
        for p in iter_paginated_res:
            task_list.append(p.data)
        endpoint_map_list_of_tasks[ep["id"]] = task_list

        # Print total number of tasks per endpoint
        print "Number of tasks", len(task_list)

    return admin_endpoint_map, endpoint_map_list_of_tasks
Exemplo n.º 9
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'
                })
Exemplo n.º 10
0
def move_to_protected_location(url, action_id, dcc_id):
    """Move user submitted datasets to a read-only location, where only the
    Action Provider has write access"""
    transfer_token = get_app_token(CONFIG["DEPENDENT_SCOPES"]["transfer"])
    auth = globus_sdk.AccessTokenAuthorizer(transfer_token)
    tc = globus_sdk.TransferClient(authorizer=auth)

    purl = urllib.parse.urlparse(url)
    # DCCs *should* always be of the pattern "cfde_registry_dcc:kidsfirst"
    _, dcc_name = dcc_id.rsplit(":", 1)
    # New dataset name should look like:
    # /CFDE/public/kidsfirst/1612387394-05167ed4-6666-11eb-9dcc-784f43874631.tgz
    dcc_dir = os.path.join(CONFIG["LONG_TERM_STORAGE"], dcc_name)

    _, old_ext = os.path.splitext(purl.path)
    new_filename = f"{datetime.datetime.now().isoformat()}-{action_id}{old_ext}"
    new_dataset_path = os.path.join(dcc_dir, new_filename)
    logger.debug(f'Renaming dataset "{purl.path}" to "{new_dataset_path}"')
    try:
        tc.operation_rename(CONFIG["GCS_ENDPOINT"], purl.path, new_dataset_path)
    except globus_sdk.exc.TransferAPIError as tapie:
        if tapie.code == "EndpointError":
            raise error.DeveloperError(f"Failed to rename '{purl.path}' to '{new_dataset_path}', "
                                       f"Check {dcc_dir} exists!") from tapie
        raise
    url = urllib.parse.urlunparse((purl.scheme, purl.netloc, new_dataset_path, "", "", ""))
    logger.debug(f"Successfully updated dataset URL to {url}")
    return url
Exemplo n.º 11
0
    def __init__(self, token_response):
        '''
        Assume the user has logged in to globus and the jhuidies#dmztest collection, initialized their client, 
        visited the authentication url, copied the authentication code, and converted it to tokens, as
        set up in the accompanying notebook.
        e.g.:
            CLIENT_ID = 'XXXXX'
            client = globus_sdk.NativeAppAuthClient(CLIENT_ID)
            client.oauth2_start_flow()
            authorize_url = client.oauth2_get_authorize_url()
            auth_code = 'XXXXX'
            token_response = client.oauth2_exchange_code_for_tokens(auth_code)
        
        Here, set up the transfer client and jhu endpoint.
        '''

        globus_auth_data = token_response.by_resource_server['auth.globus.org']
        globus_transfer_data = token_response.by_resource_server[
            'transfer.api.globus.org']

        AUTH_TOKEN = globus_auth_data['access_token']
        TRANSFER_TOKEN = globus_transfer_data['access_token']
        authorizer = globus_sdk.AccessTokenAuthorizer(TRANSFER_TOKEN)

        self.tc = globus_sdk.TransferClient(authorizer=authorizer)
        self.jhu_endpoint = 'jhuidies#dmztest'
        self.jhu_tc = self.tc.get_endpoint(self.jhu_endpoint)
Exemplo n.º 12
0
def getGlobusObj():
    if not session.get('is_authenticated'):
        return redirect(url_for('globus_login'))
    authorizer = globus_sdk.AccessTokenAuthorizer(
        session['tokens']['transfer.api.globus.org']['access_token'])
    transfer_client = globus_sdk.TransferClient(authorizer=authorizer)
    return transfer_client
Exemplo n.º 13
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'))
Exemplo n.º 14
0
def transfer_catalog(transfer_manifest,
                     dest_endpoint,
                     dest_prefix,
                     transfer_token,
                     sync_level=settings.GLOBUS_DEFAULT_SYNC_LEVEL):
    task_ids = []
    transfer_authorizer = globus_sdk.AccessTokenAuthorizer(transfer_token)
    tc = globus_sdk.TransferClient(authorizer=transfer_authorizer)
    tc.endpoint_autoactivate(dest_endpoint)
    if not transfer_manifest:
        raise ValidationError('No valid data to transfer', code='no_data')
    for globus_source_endpoint, data_list in transfer_manifest.items():
        log.debug(
            'Starting transfer from {} to {}:{} containing {} files'.format(
                globus_source_endpoint, dest_endpoint, dest_prefix,
                len(data_list)))
        tc.endpoint_autoactivate(globus_source_endpoint)
        tdata = globus_sdk.TransferData(tc,
                                        globus_source_endpoint,
                                        dest_endpoint,
                                        label=settings.SERVICE_NAME,
                                        sync_level=sync_level)
        for item in data_list:
            tdata.add_item(item, '/'.join((dest_prefix, item)))
        task = tc.submit_transfer(tdata)
        task_ids.append(task['task_id'])
    return task_ids
Exemplo n.º 15
0
 def connect(self):
     lg = self.config['login']
     self.refresh_token_file = refresh_token_file = lg['refresh token file']
     have_refresh = os.path.exists(refresh_token_file)
     if have_refresh:
         with open(refresh_token_file) as f:
             token = f.readline().strip()
         self.authorizer = globus_sdk.RefreshTokenAuthorizer(
             refresh_token=token, auth_client=self.client)
         return  #have a refresh token, all we need
     else:
         aurl = self.client.oauth2_get_authorize_url()
         browser = lg.getboolean('browser')
         if browser:
             webbrowser.open(aurl)
             time.sleep(0.5)
         else:
             print("open url {}".format(aurl))
             print("login and paste result")
     auth_code = input("Paste globus response:  ")
     tokens = self.client.oauth2_exchange_code_for_tokens(auth_code)
     transfer_data = tokens.by_resource_server['transfer.api.globus.org']
     TRANSFER_TOKEN = transfer_data['access_token']
     if not have_refresh:
         refresh = transfer_data['refresh_token']
         with open(refresh_token_file, 'w') as f:
             print("{}".format(refresh), file=f)
     self.authorizer = globus_sdk.AccessTokenAuthorizer(TRANSFER_TOKEN)
Exemplo n.º 16
0
 def test_init(self):
     """
     Confirms value error when trying to init with an authorizer
     """
     with self.assertRaises(ValueError):
         globus_sdk.NativeAppAuthClient(
             client_id=get_client_data()["native_app_client1"]["id"],
             authorizer=globus_sdk.AccessTokenAuthorizer(""))
Exemplo n.º 17
0
def get_transfer_client(user):
    '''return a transfer client for the user''' 
    client = user.get_credentials('globus')
    if client is not None:
        access_token = client.extra_data['transfer.api.globus.org']['access_token']
        authorizer = globus_sdk.AccessTokenAuthorizer(access_token)
        client = globus_sdk.TransferClient(authorizer=authorizer)
    return client
Exemplo n.º 18
0
 def mkdirRemote(endpoint, path):
     try:
         authorizer = globus_sdk.AccessTokenAuthorizer(
             GlobusManager.TRANSFER_TOKEN)
         tc = globus_sdk.TransferClient(authorizer=authorizer)
         tc.operation_mkdir(endpoint, path=path)
     except Exception, e:
         print e
Exemplo n.º 19
0
    def transfer_client(self):
        if self.__transfer_client:
            return self.__transfer_client

        transfer_token = self.tokens[self.transfer_scope]['access_token']
        self.__transfer_client = globus_sdk.TransferClient(
            authorizer=globus_sdk.AccessTokenAuthorizer(transfer_token))
        return self.__transfer_client
Exemplo n.º 20
0
    def mint_new_transfer_client(self, response=None):
        response = response or self.token_response

        access_token = response.by_resource_server['transfer.api.globus.org'][
            'access_token']

        authorizer = globus_sdk.AccessTokenAuthorizer(access_token)
        return globus_sdk.TransferClient(authorizer=authorizer)
Exemplo n.º 21
0
 def https_authorizer(self):
     """Get the https authorizer for downloading/uploading data from the GCS instance.
     This can differ between the dev/staging/prod machines"""
     try:
         return self.__native_client.get_authorizers_by_scope()[self.gcs_https_scope]
     except (fair_research_login.LoadError, KeyError):
         at = self.tokens[self.gcs_https_scope]["access_token"]
         return globus_sdk.AccessTokenAuthorizer(at)
Exemplo n.º 22
0
def get_transfer_client(user):
    """return a transfer client for the user"""
    client = user.get_credentials("globus")
    if client is not None:
        access_token = client.extra_data["transfer.api.globus.org"]["access_token"]
        authorizer = globus_sdk.AccessTokenAuthorizer(access_token)
        client = globus_sdk.TransferClient(authorizer=authorizer)
    return client
Exemplo n.º 23
0
def get_file(url, output_path, auth_config, token=None, dest_endpoint=None):

    try:
        src_endpoint = urlsplit(url).hostname
        src_path = urlsplit(url).path
        if platform.system() == "Windows":
            dest_path = ''.join(('/', output_path.replace('\\', '/').replace(':', '')))
        else:
            dest_path = os.path.abspath(output_path)

        if not token:
            token, dest_endpoint = authenticate(url, auth_config)
        if token is None:
            logger.warn("A valid Globus access token is required to create transfers. "
                        "Check keychain.json for valid parameters.")
            return False

        if dest_endpoint is None:
            logger.warn("A valid Globus destination endpoint must be specified. "
                        "Check keychain.json for valid parameters.")
            return False

        # initialize transfer client
        authorizer = globus_sdk.AccessTokenAuthorizer(token)
        client = globus_sdk.TransferClient(authorizer=authorizer)

        # Activate source endpoint
        logger.debug("Activating source endpoint: %s" % src_endpoint)
        data = client.endpoint_autoactivate(src_endpoint, if_expires_in=600)

        # Activate destination endpoint
        logger.debug("Activating destination endpoint: %s" % dest_endpoint)
        data = client.endpoint_autoactivate(dest_endpoint, if_expires_in=600)

        filename = src_path.rsplit('/', 1)[-1]
        label = "".join(("BDBag Fetch -- ", filename.replace('.', '_')))

        # get a unique ID for this transfer
        tdata = globus_sdk.TransferData(client,
                                        src_endpoint,
                                        dest_endpoint,
                                        label=label)

        tdata.add_item(src_path, dest_path, recursive=False)

        # start the transfer
        data = client.submit_transfer(tdata)
        task_id = data["task_id"]

        logger.info("Globus transfer started with ID %s" % task_id)
        logger.debug("Transferring file %s to %s" % (url, output_path))
        return True

    except Exception as e:
        logger.error('Globus transfer request exception: %s' % get_typed_exception(e))

    return False
Exemplo n.º 24
0
def tasks():

    client = NativeClient(client_id=CLIENT_ID, app_name=APP_NAME)
    client.login(requested_scopes=SCOPES)

    tokens = client.load_tokens(requested_scopes=SCOPES)
    auther = globus_sdk.AccessTokenAuthorizer(
        tokens['search.api.globus.org']['access_token'])
    sc = globus_sdk.SearchClient(authorizer=auther)
    print(sc.get_task_list(INDEX))
    print('Finished')
Exemplo n.º 25
0
    def _get_transfer_client(self) -> None:
        """Sets self.tc to Globus transfer client using
        self.transfer_token as authorization.

        Returns
        -------
        None
        """
        authorizer = globus_sdk.AccessTokenAuthorizer(self.transfer_token)

        self.tc = globus_sdk.TransferClient(authorizer=authorizer)
Exemplo n.º 26
0
def gen_groups_client(client_id, client_secret):
    auth_client = globus_sdk.ConfidentialAppAuthClient(client_id, client_secret)

    token_response = auth_client.oauth2_client_credentials_tokens(
      requested_scopes=GROUPS_SCOPE).by_resource_server['nexus.api.globus.org']

    authorizer = globus_sdk.AccessTokenAuthorizer(token_response['access_token'])

    groups_client = globus_sdk.base.BaseClient(
      'groups', base_url=GROUPS_API_URL, authorizer=authorizer)

    return groups_client
Exemplo n.º 27
0
    def copyData(self, ori, dest):
        #print "xxx", ori, dest
        authorizer = globus_sdk.AccessTokenAuthorizer(
            GlobusManager.TRANSFER_TOKEN)
        tc = globus_sdk.TransferClient(authorizer=authorizer)
        res = self.copyDirectory(ori, dest, tc)

        if res == "NOT_A_DIRECTORY":
            res = self.copyFile(ori, dest, tc)

        if res is not "OK":
            raise Exception(res)
def get_globus_client():
    # authorizer = globus_sdk.RefreshTokenAuthorizer(
    #     os.environ["REFRESH_TOKEN"],
    #     client)

    authorizer = globus_sdk.AccessTokenAuthorizer(TRANSFER_TOKEN)

    # and try using `tc` to make TransferClient calls. Everything should just
    # work -- for days and days, months and months, even years
    tc = globus_sdk.TransferClient(authorizer=authorizer)

    return tc
Exemplo n.º 29
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)
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)