コード例 #1
0
def logout():
    """
    - Revoke the tokens with Globus Auth.
    - Destroy the session state.
    - Redirect the user to the Globus Auth logout page.
    """
    client = load_portal_client()

    # Revoke the tokens with Globus Auth
    for token, token_type in (
        (token_info[ty], ty)
            # get all of the token info dicts
            for token_info in session['tokens'].values()
            # cross product with the set of token types
            for ty in ('access_token', 'refresh_token')
            # only where the relevant token is actually present
            if token_info[ty] is not None):
        client.oauth2_revoke_token(
            token, additional_params={'token_type_hint': token_type})

    # Destroy the session state
    session.clear()

    redirect_uri = url_for('home', _external=True)

    ga_logout_url = []
    ga_logout_url.append(app.config['GLOBUS_AUTH_LOGOUT_URI'])
    ga_logout_url.append('?client={}'.format(app.config['PORTAL_CLIENT_ID']))
    ga_logout_url.append('&redirect_uri={}'.format(redirect_uri))
    ga_logout_url.append('&redirect_name=Globus Sample Data Portal')

    # Redirect the user to the Globus Auth logout page
    return redirect(''.join(ga_logout_url))
コード例 #2
0
def browse(dataset_id=None, endpoint_id=None, endpoint_path=None):
    """
    - Get list of files for the selected dataset or endpoint ID/path
    - Return a list of files to a browse view

    The target template (browse.jinja2) expects an `endpoint_uri` (if
    available for the endpoint), `target` (either `"dataset"`
    or `"endpoint"`), and 'file_list' (list of dictionaries) containing
    the following information about each file in the result:

    {'name': 'file name', 'size': 'file size', 'id': 'file uri/path'}

    If you want to display additional information about each file, you
    must add those keys to the dictionary and modify the browse.jinja2
    template accordingly.
    """

    assert bool(dataset_id) != bool(endpoint_id and endpoint_path)

    if dataset_id:
        try:
            dataset = next(ds for ds in datasets if ds['id'] == dataset_id)
        except StopIteration:
            abort(404)

        endpoint_id = app.config['DATASET_ENDPOINT_ID']
        endpoint_path = app.config['DATASET_ENDPOINT_BASE'] + dataset['path']

    else:
        endpoint_path = '/' + endpoint_path

    transfer = TransferClient(authorizer=RefreshTokenAuthorizer(
        session['tokens']['transfer.api.globus.org']['refresh_token'],
        load_portal_client()))

    try:
        transfer.endpoint_autoactivate(endpoint_id)
        listing = transfer.operation_ls(endpoint_id, path=endpoint_path)
    except TransferAPIError as err:
        flash('Error [{}]: {}'.format(err.code, err.message))
        return redirect(url_for('transfer'))

    file_list = [e for e in listing if e['type'] == 'file']

    ep = transfer.get_endpoint(endpoint_id)

    https_server = ep['https_server']
    endpoint_uri = https_server + endpoint_path if https_server else None
    webapp_xfer = 'https://www.globus.org/app/transfer?' + \
        urlencode(dict(origin_id=endpoint_id, origin_path=endpoint_path))

    return render_template(
        'browse.jinja2',
        endpoint_uri=endpoint_uri,
        target="dataset" if dataset_id else "endpoint",
        description=(dataset['name'] if dataset_id else ep['display_name']),
        file_list=file_list,
        webapp_xfer=webapp_xfer)
コード例 #3
0
def authcallback():
    """Handles the interaction with Globus Auth."""
    # If we're coming back from Globus Auth in an error state, the error
    # will be in the "error" query string parameter.
    if 'error' in request.args:
        flash("You could not be logged into the portal: " +
              request.args.get('error_description', request.args['error']))
        return redirect(url_for('home'))

    # Set up our Globus Auth/OAuth2 state
    redirect_uri = url_for('authcallback', _external=True)

    client = load_portal_client()
    client.oauth2_start_flow(redirect_uri,
                             refresh_tokens=True,
                             requested_scopes=app.config['USER_SCOPES'])

    # If there's no "code" query string parameter, we're in this route
    # starting a Globus Auth login flow.
    if 'code' not in request.args:
        additional_authorize_params = ({
            'signup': 1
        } if request.args.get('signup') else {})

        auth_uri = client.oauth2_get_authorize_url(
            additional_params=additional_authorize_params)

        return redirect(auth_uri)
    else:
        # If we do have a "code" param, we're coming back from Globus Auth
        # and can start the process of exchanging an auth code for a token.
        code = request.args.get('code')
        tokens = client.oauth2_exchange_code_for_tokens(code)

        id_token = tokens.decode_id_token(client)
        session.update(
            tokens=tokens.by_resource_server,
            is_authenticated=True,
            name=id_token.get('name', ''),
            email=id_token.get('email', ''),
            institution=id_token.get('organization', ''),
            primary_username=id_token.get('preferred_username'),
            primary_identity=id_token.get('sub'),
        )

        profile = database.load_profile(session['primary_identity'])

        if profile:
            name, email, institution = profile

            session['name'] = name
            session['email'] = email
            session['institution'] = institution
        else:
            return redirect(url_for('profile', next=url_for('transfer')))

        return redirect(url_for('transfer'))
コード例 #4
0
def submit_transfer():
    """
    - Take the data returned by the Browse Endpoint helper page
      and make a Globus transfer request.
    - Send the user to the transfer status page with the task id
      from the transfer.
    """
    browse_endpoint_form = request.form

    selected = session['form']['datasets']
    filtered_datasets = [ds for ds in datasets if ds['id'] in selected]

    transfer_tokens = session['tokens']['transfer.api.globus.org']

    authorizer = RefreshTokenAuthorizer(
        transfer_tokens['refresh_token'],
        load_portal_client(),
        access_token=transfer_tokens['access_token'],
        expires_at=transfer_tokens['expires_at_seconds'])

    transfer = TransferClient(authorizer=authorizer)

    source_endpoint_id = app.config['DATASET_ENDPOINT_ID']
    source_endpoint_base = app.config['DATASET_ENDPOINT_BASE']
    destination_endpoint_id = browse_endpoint_form['endpoint_id']
    destination_folder = browse_endpoint_form.get('folder[0]')

    transfer_data = TransferData(transfer_client=transfer,
                                 source_endpoint=source_endpoint_id,
                                 destination_endpoint=destination_endpoint_id,
                                 label=browse_endpoint_form.get('label'))

    for ds in filtered_datasets:
        source_path = source_endpoint_base + ds['path']
        dest_path = browse_endpoint_form['path']

        if destination_folder:
            dest_path += destination_folder + '/'

        dest_path += ds['name'] + '/'

        transfer_data.add_item(source_path=source_path,
                               destination_path=dest_path,
                               recursive=True)

    transfer.endpoint_autoactivate(source_endpoint_id)
    transfer.endpoint_autoactivate(destination_endpoint_id)
    task_id = transfer.submit_transfer(transfer_data)['task_id']

    flash('Transfer request submitted successfully. Task ID: ' + task_id)

    return (redirect(url_for('transfer_status', task_id=task_id)))
コード例 #5
0
def transfer_status(task_id):
    """
    Call Globus to get status/details of transfer with
    task_id.

    The target template (tranfer_status.jinja2) expects a Transfer API
    'task' object.

    'task_id' is passed to the route in the URL as 'task_id'.
    """
    transfer = TransferClient(authorizer=RefreshTokenAuthorizer(
        session['tokens']['transfer.api.globus.org']['refresh_token'],
        load_portal_client()))
    task = transfer.get_task(task_id)

    return render_template('transfer_status.jinja2', task=task)
コード例 #6
0
def authcallback():
    """Handles the interaction with Globus Auth."""
    # If we're coming back from Globus Auth in an error state, the error
    # will be in the "error" query string parameter.
    if 'error' in request.args:
        flash("You could not be logged into the portal: " +
              request.args.get('error_description', request.args['error']), 'warning')
        return redirect(url_for('home'))

    # Set up our Globus Auth/OAuth2 state
    redirect_uri = url_for('authcallback', _external=True)

    client = load_portal_client()
    client.oauth2_start_flow(redirect_uri, refresh_tokens=True)

    # If there's no "code" query string parameter, we're in this route
    # starting a Globus Auth login flow.
    if 'code' not in request.args:
        # print("SIGNUP: {} ".format(request.args))
        next_url = get_safe_redirect()
        additional_authorize_params = (
            {'signup': 1} if request.args.get('signup') else {'next': next_url})

        auth_uri = client.oauth2_get_authorize_url(
            additional_params=additional_authorize_params)
        print("ADDITIONAL AUTHORIZED PARAMS: {}".format(additional_authorize_params))
        print("NEXT URL: {}".format(next_url))

        return redirect(auth_uri)
    else:
        # If we do have a "code" param, we're coming back from Globus Auth
        # and can start the process of exchanging an auth code for a token.
        print("GOT OUT OF AUTH URI LOOP")
        next_url = get_safe_redirect()
        print("NEXT URL: {}".format(next_url))
        code = request.args.get('code')
        tokens = client.oauth2_exchange_code_for_tokens(code)

        id_token = tokens.decode_id_token(client)
        session.update(
            tokens=tokens.by_resource_server,
            is_authenticated=True,
            name=id_token.get('name', ''),
            email=id_token.get('email', ''),
            institution=id_token.get('organization', ''),
            primary_username=id_token.get('preferred_username'),
            primary_identity=id_token.get('sub'),
        )

        access_token = session['tokens']['auth.globus.org']['access_token']
        token_introspect = client.oauth2_token_introspect(
            token=access_token, include='identity_set')
        identity_set = token_introspect.data['identity_set']
        profile = None

        for identity in identity_set:
            query = {'token': ciconnect_api_token,
                     'globus_id': identity}
            try:
                r = requests.get(
                    ciconnect_api_endpoint + '/v1alpha1/find_user', params=query)
                # r = get_user_info(session)
                if r.status_code == requests.codes.ok:
                    user_info = r.json()
                    # user_access_token = user_info['metadata']['access_token']
                    unix_name = user_info['metadata']['unix_name']
                    profile = requests.get(
                        ciconnect_api_endpoint + '/v1alpha1/users/' + unix_name, params=query)
                    profile = profile.json()
                    session['primary_identity'] = identity
            except:
                print("NO PROFILE FOUND WITH IDENTITY: {}".format(identity))

        connect_keynames = {'atlas': {'name': 'atlas-connect',
                                      'display_name': 'Atlas Connect',
                                      'unix_name': 'root.atlas'},
                            'cms': {'name': 'cms-connect',
                                    'display_name': 'CMS Connect',
                                    'unix_name': 'root.cms'},
                            'duke': {'name': 'duke-connect',
                                     'display_name': 'Duke Connect',
                                     'unix_name': 'root.duke'},
                            'uchicago': {'name': 'uchicago-connect',
                                         'display_name': 'UChicago Connect',
                                         'unix_name': 'root.uchicago'},
                            'spt': {'name': 'spt-connect',
                                    'display_name': 'SPT Connect',
                                    'unix_name': 'root.spt'},
                            'psdconnect': {'name': 'psd-connect',
                                           'display_name': 'PSD Connect',
                                           'unix_name': 'root.uchicago'},
                            'snowmass21': {'name': 'snowmass21-connect',
                                    'display_name': 'Snowmass21 Connect',
                                    'unix_name': 'root.snowmass21'},
                            'localhost': {'name': 'snowmass21-connect',
                                    'display_name': 'Snowmass21 Connect',
                                    'unix_name': 'root.snowmass21'}}
        url_host = request.host
        try:
            referrer = urlparse(request.referrer)
            # print("REFERRER: {}".format(referrer))
            queries = parse_qs(referrer.query)
            # print("QUERIES: {}".format(queries))
            redirect_uri = queries['redirect_uri'][0]
            # print("REDIRECT URI: {}".format(redirect_uri))
            next_url = queries['next'][0]
            # print("AFTER QUERIES NEXT URL: {}".format(next_url))
        except:
            next_url = '/'
        if 'ci-connect' in url_host:
            session['url_host'] = {'name': 'ci-connect',
                                   'display_name': 'CI Connect',
                                   'unix_name': 'root'}

        for key, value in list(connect_keynames.items()):
            if key in url_host:
                session['url_host'] = value

        if profile:
            profile = profile['metadata']
            session['name'] = profile['name']
            session['email'] = profile['email']
            session['phone'] = profile['phone']
            session['institution'] = profile['institution']
            session['unix_name'] = profile['unix_name']
            session['url_root'] = request.url_root
            # session['url_host'] = (request.host).split(':')[0]
            session['admin'] = admin_check(profile['unix_name'])
        else:
            session['url_root'] = request.url_root
            return redirect(url_for('create_profile',
                                    next=url_for('profile')))

        # print("FINAL NEXT URL: {}".format(next_url))
        if next_url == '/':
            return redirect(url_for('profile'))
        else:
            return redirect(next_url)
コード例 #7
0
def browse(dataset_id=None, endpoint_id=None, endpoint_path=None):
    """
    - Get list of files for the selected dataset or endpoint ID/path
    - Return a list of files to a browse view

    The target template (browse.jinja2) expects an `endpoint_uri` (if
    available for the endpoint), `target` (either `"dataset"`
    or `"endpoint"`), and 'file_list' (list of dictionaries) containing
    the following information about each file in the result:

    {'name': 'file name', 'size': 'file size', 'id': 'file uri/path'}

    If you want to display additional information about each file, you
    must add those keys to the dictionary and modify the browse.jinja2
    template accordingly.
    """

    if request.method == 'GET':
        assert bool(dataset_id) != bool(endpoint_id and endpoint_path)

        if dataset_id:
            try:
                dataset = next(ds for ds in datasets if ds['id'] == dataset_id)
            except StopIteration:
                abort(404)

            endpoint_id = app.config['DATASET_ENDPOINT_ID']
            endpoint_path = app.config['DATASET_ENDPOINT_BASE'] + dataset['path']

        else:
            endpoint_path = '/' + endpoint_path

        transfer_tokens = session['tokens']['transfer.api.globus.org']

        authorizer = RefreshTokenAuthorizer(
            transfer_tokens['refresh_token'],
            load_portal_client(),
            access_token=transfer_tokens['access_token'],
            expires_at=transfer_tokens['expires_at_seconds'])

        transfer = TransferClient(authorizer=authorizer)

        try:
            transfer.endpoint_autoactivate(endpoint_id)
            listing = transfer.operation_ls(endpoint_id, path=endpoint_path)
        except TransferAPIError as err:
            flash('Error [{}]: {}'.format(err.code, err.message))
            return redirect(url_for('browse'))

        file_list = [e for e in listing if e['type'] == 'file']

        ep = transfer.get_endpoint(endpoint_id)

        https_server = ep['https_server']
        endpoint_uri = https_server + endpoint_path if https_server else None
        webapp_xfer = 'https://app.globus.org/file-manager?' + \
            urlencode(dict(origin_id=endpoint_id, origin_path=endpoint_path))


        #print("endpintURL == " + endpoint_uri)

        return render_template('browse.jinja2', endpoint_uri=endpoint_uri,
                           target="dataset" if dataset_id else "endpoint",
                           description=(dataset['name'] if dataset_id
                                        else ep['display_name']),
                           mypath=(dataset['path'] if dataset_id
                                        else None),
                           myid=(dataset['id'] if dataset_id
                                        else None),
                           file_list=file_list, webapp_xfer=webapp_xfer)

    if request.method == 'POST':
        if not request.form.get('file'):
            flash('Please select at least one file.')
            return redirect(url_for('browse'))

        params = {
            'method': 'POST',
            'action': url_for('submit_transfer', _external=True,
                              _scheme='https'),
            'filelimit': 0,
            'folderlimit': 1
        }

        browse_endpoint = 'https://app.globus.org/file-manager?{}' \
            .format(urlencode(params))

        session['form'] = {
            'dirselect': False,
            'datasets': request.form.getlist('file'),
            'path': request.form.getlist('path'),
            'id': request.form.getlist('id')
        }

        return redirect(browse_endpoint)
コード例 #8
0
ファイル: views.py プロジェクト: tatonetti-lab/nsides
def authcallback():
    """Handles the interaction with Agave Auth."""
    # If we're coming back from Agave Auth in an error state, the error
    # will be in the "error" query string parameter.
    if 'error' in request.args:
        flash("You could not be logged into the portal: " +
              request.args.get('error_description', request.args['error']))
        return redirect(url_for('home'))

    redirect_uri = url_for('authcallback', _external=True)
    client = load_portal_client(redirect_uri)
    auth_uri = client.step1_get_authorize_url()
    print 'auth uri', auth_uri

    # If there's no "code" query string parameter, we're in this route
    # starting a Agave Auth login flow.
    if 'code' not in request.args:
        auth_uri = client.step1_get_authorize_url()
        return redirect(auth_uri)
    else:
        # If we do have a "code" param, we're coming back from Agave Auth
        # and can start the process of exchanging an auth code for a token.
        code = request.args.get('code')
        print 'code', code
        tokens = client.step2_exchange(code)
        tokens.revoke_uri = app.config['REVOKE_URL']
        token_json = tokens.to_json()
        print 'token json', token_json

        # user_profile = get_profile(tokens.access_token)
        user_profile = get_result(app.config['PROFILE_URL_BASE'], 'me',
                                  tokens.access_token)
        if user_profile[0]:
            print 'username', user_profile[1]['username']
        else:
            flash("User profile was not retrieved. Error:" + user_profile[1])

        session.update(tokens=tokens.to_json(),
                       is_authenticated=True,
                       name=user_profile[1]['full_name'],
                       email=user_profile[1]['email'],
                       institution='',
                       primary_identity=user_profile[1]['username'])

        profile = database.load_profile(session['primary_identity'])
        if profile:
            name, email, institution = profile

            session['name'] = name
            session['email'] = email
            session['institution'] = institution

            # handle_permission(session['primary_identity'])
        else:
            # take the user profile and save it into the database
            database.save_profile(identity_id=session['primary_identity'],
                                  name=session['name'],
                                  email=session['email'],
                                  institution=session['institution'])
            # set up the permission for new user
            handle_permission(session['primary_identity'])

            return redirect(url_for('profile', next=url_for('submit_job')))

        return redirect(url_for('submit_job'))