def create_user_token_from_globus_profile(profile, access_token):
    """
    Use this method on your Resource Provider (Like Atmosphere)
    to exchange a profile (that was retrieved via a tokeninfo endpoint)
    for a UserToken that can then be internally validated in an 'authorize' authBackend step..
    """

    logger.info(profile)
    expiry = profile['exp'] # This is an 'epoch-int'
    expiry = _extract_expiry_date(expiry)
    issuer = profile['iss']
    issued_at = profile['iat']
    raw_username = profile['username']  # username@login_auth.com
    raw_name = profile['name']
    email = profile['email']
    username = _extract_user_from_email(raw_username)
    first_name, last_name = _extract_first_last_name(raw_name)
    profile_dict = {
        'username':username,
        'firstName':first_name,
        'lastName':last_name,
        'email': email,
    }
    auth_token = create_user_and_token(profile_dict, access_token, expiry, issuer)
    return auth_token
def globus_validate_code(request):
    """
    This flow is used to create a new Token on behalf of a Service Client
    (Like Troposphere)
    Validates 'code' returned from the IdP
    If valid: Return new AuthToken to be passed to the Resource Provider.
        else: Return None
    """
    code = request.GET.get('code','')
    error = request.GET.get('error','')
    error_description = request.GET.get('error_description','')
    if error:
        error_msg = "%s: %s" % (error, error_description) if error_description else error
        raise Unauthorized(error_msg)
    if not code:
        logger.warn("User returned from Login prompt but there was NO `code` to validate!")
        return None
    if type(code) == list:
        code = code[0]
    flow = globus_initFlow()
    try:
        credentials = flow.step2_exchange(code)
        logger.info(credentials.__dict__)
    except OAuthError as err:
        logger.exception("Error exchanging code w/ globus")
        return None
    except Exception as err:
        logger.exception("Unknown Error occurred while exchanging code w/ globus")
        return None
    # Parsing
    try:
        user_access_token = parse_atmosphere_token(credentials.token_response)
        token_profile = credentials.id_token
        expiry_date = credentials.token_expiry
    except Exception as err:
        logger.exception("Parse of the credentials response failed. Ask a developer for help!")
        return None
    raw_username = token_profile['preferred_username']
    email = token_profile['email']
    username = _extract_user_from_email(raw_username)
    if not username:
        logger.info("No user provided in token_profile: Check output %s" % token_profile)
        return None
    full_name = token_profile['name']
    issuer = token_profile['iss']
    # Creation
    first_name, last_name = _extract_first_last_name(full_name)
    username = username.lower()
    user_profile = {
        'username':username,
        'firstName':first_name,
        'lastName':last_name,
        'email': email,
    }
    auth_token = create_user_and_token(user_profile, user_access_token, expiry_date, issuer)
    return auth_token