コード例 #1
0
def key(key):
    # get the key from URL
    if not re.match("[0-9a-fA-F]+", key):
        raise Exception("Key id {0} is not a valid key".format(key))

    # check for the key file in the credmon directory
    cred_dir = get_cred_dir()
    key_path = os.path.join(cred_dir, key)
    if not os.path.exists(key_path):
        raise Exception("Key file {0} doesn't exist".format(key_path))

    # read in the key file, which is a list of classads
    providers = {}
    session['logged_in'] = False
    print('Creating new session from {0}'.format(key_path))
    with open(key_path, 'r') as key_file:

        # store the path to the key file since it will be accessed later in the session
        session['key_path'] = key_path

        # initialize data for each token provider
        for provider_ad in classad.parseAds(key_file):
            provider = get_provider_str(provider_ad['Provider'],
                                        provider_ad.get('Handle', ''))
            providers[provider] = {}
            providers[provider]['logged_in'] = False
            if 'Scopes' in provider_ad:
                providers[provider]['requested_scopes'] = [
                    s.rstrip().lstrip()
                    for s in provider_ad['Scopes'].split(',')
                ]
            if 'Audience' in provider_ad:
                providers[provider]['requested_resource'] = provider_ad[
                    'Audience']

        # the local username is global to the session, just grab it from the last classad
        session['local_username'] = provider_ad['LocalUser']

    session['providers'] = providers
    print('New session started for user {0}'.format(session['local_username']))
    return render_template('index.html')
コード例 #2
0
 def __init__(self, cred_dir = None):
     self.cred_dir = get_cred_dir(cred_dir)
     self.log = self.get_logger()
コード例 #3
0
def oauth_return(provider):
    """
    Returning from OAuth provider
    """

    # get the provider name from the outgoing_provider set in oauth_login()
    provider = session.pop('outgoing_provider', get_provider_str(provider, ''))
    if not (provider in session['providers']):
        raise Exception(
            "Provider {0} not in list of providers".format(provider))

    provider_ad = get_provider_ad(provider, session['key_path'])

    # gather information from the key file classad
    client_id = provider_ad['ClientId']
    redirect_uri = provider_ad['ReturnUrl']
    state = session['providers'][provider]['state']
    oauth = OAuth2Session(client_id, state=state, redirect_uri=redirect_uri)

    # convert http url to https if needed
    if request.url.startswith("http://"):
        updated_url = request.url.replace('http://', 'https://', 1)
    else:
        updated_url = request.url

    # fetch token
    client_secret = provider_ad['ClientSecret']
    token_url = provider_ad['TokenUrl']
    token = oauth.fetch_token(token_url,
                              authorization_response=updated_url,
                              client_secret=client_secret,
                              method='POST')
    print('Got {0} token for user {1}'.format(provider,
                                              session['local_username']))

    # get user info if available
    # todo: make this more generic
    try:
        get_user_info = oauth.get(provider_ad['UserUrl'])
        user_info = get_user_info.json()
        if 'login' in user_info:  # box
            session['providers'][provider]['username'] = user_info['login']
        elif 'sub' in user_info:  # scitokens/jwt
            session['providers'][provider]['username'] = user_info['sub']
        else:
            session['providers'][provider]['username'] = '******'
    except ValueError:
        session['providers'][provider]['username'] = '******'

    # split off the refresh token from the access token if it exists
    try:
        refresh_token_string = token.pop('refresh_token')
    except KeyError:  # no refresh token
        use_refresh_token = False
        refresh_token_string = ''
    else:
        use_refresh_token = True

    refresh_token = {'refresh_token': refresh_token_string}

    # create a metadata file for refreshing the token
    metadata = {
        'client_id': client_id,
        'client_secret': client_secret,
        'token_url': token_url,
        'use_refresh_token': use_refresh_token
    }

    # atomically write the tokens to the cred dir
    cred_dir = get_cred_dir()
    user_cred_dir = os.path.join(cred_dir, session['local_username'])
    if not os.path.isdir(user_cred_dir):
        os.makedirs(user_cred_dir)
    refresh_token_path = os.path.join(user_cred_dir,
                                      provider.replace(' ', '_') + '.top')
    access_token_path = os.path.join(user_cred_dir,
                                     provider.replace(' ', '_') + '.use')
    metadata_path = os.path.join(user_cred_dir,
                                 provider.replace(' ', '_') + '.meta')

    # write tokens to tmp files
    (tmp_fd, tmp_access_token_path) = tempfile.mkstemp(dir=user_cred_dir)
    with os.fdopen(tmp_fd, 'w') as f:
        json.dump(token, f)

    (tmp_fd, tmp_refresh_token_path) = tempfile.mkstemp(dir=user_cred_dir)
    with os.fdopen(tmp_fd, 'w') as f:
        json.dump(refresh_token, f)

    (tmp_fd, tmp_metadata_path) = tempfile.mkstemp(dir=user_cred_dir)
    with os.fdopen(tmp_fd, 'w') as f:
        json.dump(metadata, f)

    # (over)write token files
    try:
        atomic_rename(tmp_access_token_path, access_token_path)
        atomic_rename(tmp_refresh_token_path, refresh_token_path)
        atomic_rename(tmp_metadata_path, metadata_path)
    except OSError as e:
        sys.stderr.write(e)

    # mark provider as logged in
    session['providers'][provider]['logged_in'] = True

    # check if other providers are logged in
    session['logged_in'] = True
    for provider in session['providers']:
        if session['providers'][provider]['logged_in'] == False:
            session['logged_in'] = False

    return redirect("/")
コード例 #4
0
def oauth_return(provider):
    """
    Returning from OAuth provider
    """

    # get the provider name from the outgoing_provider set in oauth_login()
    provider = session.pop('outgoing_provider', get_provider_str(provider, ''))
    if not ('providers' in session):
        sys.stderr.write(
            '"providers" key was not found in session object: {0}\n'.format(
                session))
        raise KeyError(
            'Key "providers" was not found in session object. This session is invalid.'
        )
    if not (provider in session['providers']):
        sys.stderr.write(
            'key {0} was not found in session["providers"] dict: {1}\n'.format(
                provider, session))
        raise KeyError(
            "Provider {0} was not found in list of providers. This session is invalid."
            .format(provider))
    provider_ad = get_provider_ad(provider, session['key_path'])

    # gather information from the key file classad
    client_id = provider_ad['ClientId']
    redirect_uri = provider_ad['ReturnUrl']
    state = session['providers'][provider]['state']
    oauth = OAuth2Session(client_id, state=state, redirect_uri=redirect_uri)

    # convert http url to https if needed
    if request.url.startswith("http://"):
        updated_url = request.url.replace('http://', 'https://', 1)
    else:
        updated_url = request.url

    # fetch token
    client_secret = provider_ad['ClientSecret']
    token_url = provider_ad['TokenUrl']
    token = oauth.fetch_token(token_url,
                              authorization_response=updated_url,
                              client_secret=client_secret,
                              method='POST',
                              **fetch_token_kwargs)
    print('Got {0} token for user {1}'.format(provider,
                                              session['local_username']))

    # get user info if available
    try:
        (user_url,
         user_field_keys) = api_endpoints.user(provider_ad['TokenUrl'])
        if user_url is not None:
            get_user_info = oauth.get(user_url)
            user_info = get_user_info.json()
            for user_field in user_field_keys:
                username = user_info[user_field]
            username = str(username)
            session['providers'][provider]['username'] = username
        elif 'sub' in token:  # scitokens/jwt
            session['providers'][provider]['username'] = token['sub']
        elif 'name' in token:  # scitokens/jwt
            session['providers'][provider]['username'] = token['name']
        else:
            session['providers'][provider]['username'] = '******'
    except ValueError:
        session['providers'][provider]['username'] = '******'

    # split off the refresh token from the access token if it exists
    try:
        refresh_token_string = token.pop('refresh_token')
    except KeyError:  # no refresh token
        use_refresh_token = False
        refresh_token_string = ''
    else:
        use_refresh_token = True

    refresh_token = {'refresh_token': refresh_token_string}

    # create a metadata file for refreshing the token
    metadata = {
        'client_id': client_id,
        'client_secret': client_secret,
        'token_url': token_url,
        'use_refresh_token': use_refresh_token
    }

    # atomically write the tokens to the cred dir
    cred_dir = get_cred_dir()
    user_cred_dir = os.path.join(cred_dir, session['local_username'])
    if not os.path.isdir(user_cred_dir):
        os.makedirs(user_cred_dir)
    refresh_token_path = os.path.join(user_cred_dir,
                                      provider.replace(' ', '_') + '.top')
    access_token_path = os.path.join(user_cred_dir,
                                     provider.replace(' ', '_') + '.use')
    metadata_path = os.path.join(user_cred_dir,
                                 provider.replace(' ', '_') + '.meta')

    # write tokens to tmp files
    try:
        (tmp_fd, tmp_access_token_path) = tempfile.mkstemp(dir=user_cred_dir)
    except OSError as oe:
        print(
            "Failed to create temporary file in the user credential directory: {0}"
            .format(str(oe)))
        raise
    with os.fdopen(tmp_fd, 'w') as f:
        json.dump(token, f)

    (tmp_fd, tmp_refresh_token_path) = tempfile.mkstemp(dir=user_cred_dir)
    with os.fdopen(tmp_fd, 'w') as f:
        json.dump(refresh_token, f)

    (tmp_fd, tmp_metadata_path) = tempfile.mkstemp(dir=user_cred_dir)
    with os.fdopen(tmp_fd, 'w') as f:
        json.dump(metadata, f)

    # (over)write token files
    try:
        atomic_rename(tmp_access_token_path, access_token_path)
        atomic_rename(tmp_refresh_token_path, refresh_token_path)
        atomic_rename(tmp_metadata_path, metadata_path)
    except OSError as e:
        sys.stderr.write('{0}\n'.format(str(e)))

    # mark provider as logged in
    session['providers'][provider]['logged_in'] = True

    # check if other providers are logged in
    session['logged_in'] = True
    for provider in session['providers']:
        if session['providers'][provider]['logged_in'] == False:
            session['logged_in'] = False

    # cleanup key file if logged in
    if session['logged_in']:
        print('Attempting to remove session file {0}'.format(
            session['key_path']))
        try:
            os.unlink(session['key_path'])
        except OSError as e:
            sys.stderr.write('Could not remove session file {0}: {1}\n'.format(
                session['key_path'], str(e)))

    return redirect("/")