Beispiel #1
0
def dynamic_url():

    log.debug('attempting to GET a thing')
    restore_bucket_vars()

    if 'proxy' in app.current_request.uri_params:
        path, bucket, filename = process_varargs(app.current_request.uri_params['proxy'], b_map)
        log.debug('path, bucket, filename: {}'.format(( path, bucket, filename)))
        if not bucket:
            template_vars = {'contentstring': 'File not found', 'title': 'File not found'}
            headers = {}
            return make_html_response(template_vars, headers, 404, 'error.html')
    else:
        path, bucket, filename = (None, None, None)

    cookievars = get_cookie_vars(app.current_request.headers)
    user_profile = None
    if cookievars:
        log.debug('cookievars: {}'.format(cookievars))
        if os.getenv('JWT_COOKIENAME','asf-urs') in cookievars:
            # this means our cookie is a jwt and we don't need to go digging in the session db
            user_profile = cookievars[os.getenv('JWT_COOKIENAME','asf-urs')]
        else:
            log.warning('jwt cookie not found, falling back to old style')
            user_profile = get_session(cookievars['urs-user-id'], cookievars['urs-access-token'])

    # Check for public bucket
    if check_public_bucket(bucket, public_buckets, b_map):
        log.debug("Accessing public bucket {0}".format(path))
    elif not user_profile:
        return do_auth_and_return(app.current_request.context)

    # Check that the bucket is either NOT private, or user belongs to that group
    private_check = check_private_bucket(bucket, private_buckets, b_map)
    log.debug('private check: {}'.format(private_check))
    u_in_g, new_user_profile = user_in_group(private_check, cookievars, user_profile, False)
    if new_user_profile and new_user_profile != user_profile:
        log.debug("Profile was mutated from {0} => {1}".format(user_profile,new_user_profile))
        user_profile = new_user_profile
    log.debug('user_in_group: {}'.format(u_in_g))
    if private_check and not u_in_g:
        template_vars = {'contentstring': 'This data is not currently available.', 'title': 'Could not access data'}
        headers = {}
        return make_html_response(template_vars, headers, 403, 'error.html')

    if not filename:
        log.warning("Request was made to directory listing instead of object: {0}".format(path))

        template_vars = {'contentstring': 'Request does not appear to be valid.', 'title': 'Request Not Serviceable'}
        headers = {}
        return make_html_response(template_vars, headers, 404, 'error.html')

    return try_download_from_bucket(bucket, filename, user_profile)
Beispiel #2
0
def dynamic_url():
    t = [time.time()]
    custom_headers = {}
    log.debug('attempting to GET a thing')
    restore_bucket_vars()
    log.debug(f'b_map: {b_map}')
    t.append(time.time())

    if 'proxy' in app.current_request.uri_params:
        path, bucket, filename, custom_headers = process_request(
            app.current_request.uri_params['proxy'], b_map)
        log.debug('path, bucket, filename, custom_headers: {}'.format(
            (path, bucket, filename, custom_headers)))
        if not bucket:
            template_vars = {
                'contentstring': 'File not found',
                'title': 'File not found',
                'requestid': get_request_id(),
            }
            headers = {}
            return make_html_response(template_vars, headers, 404,
                                      'error.html')
    else:
        path, bucket, filename = (None, None, None)

    cookievars = get_cookie_vars(app.current_request.headers)
    user_profile = None
    if cookievars:
        log.debug('cookievars: {}'.format(cookievars))
        if JWT_COOKIE_NAME in cookievars:
            # this means our cookie is a jwt and we don't need to go digging in the session db
            user_profile = cookievars[JWT_COOKIE_NAME]
        else:
            log.warning('jwt cookie not found')
            # Not kicking user out just yet. We might be dealing with a public bucket
    t.append(time.time())  # 2
    # Check for public bucket
    pub_bucket = check_public_bucket(bucket, b_map, filename)
    t.append(time.time())  # 3
    if pub_bucket:
        log.debug("Accessing public bucket {0}".format(path))
    elif not user_profile:
        if 'Authorization' in app.current_request.headers and app.current_request.headers[
                'Authorization'].split()[0].lower() == 'bearer':
            # we will deal with "bearer" auth here. "Basic" auth will be handled by do_auth_and_return()
            log.debug('we got an Authorization header. {}'.format(
                app.current_request.headers['Authorization']))
            token = app.current_request.headers['Authorization'].split()[1]
            action, data = handle_auth_bearer_header(token)

            if action == 'return':
                # Not a successful event.
                return data

            user_profile = data
            user_id = user_profile['uid']
            log_context(user_id=user_id)
            log.debug(f'User {user_id} has user profile: {user_profile}')
            jwt_payload = user_profile_2_jwt_payload(user_id, token,
                                                     user_profile)
            log.debug(f"Encoding JWT_PAYLOAD: {jwt_payload}")
            custom_headers.update(
                make_set_cookie_headers_jwt(jwt_payload, '',
                                            os.getenv('COOKIE_DOMAIN', '')))

        else:
            return do_auth_and_return(app.current_request.context)

    t.append(time.time())  # 4
    # Check that the bucket is either NOT private, or user belongs to that group
    private_check = check_private_bucket(
        bucket, b_map, filename)  # NOTE: Is an optimization attempt worth it
    # if we're asking for a public file and we
    # omit this check?
    log.debug('private check: {}'.format(private_check))
    t.append(time.time())  # 5
    u_in_g, new_user_profile = user_in_group(private_check, cookievars,
                                             user_profile, False)
    t.append(time.time())  # 6

    new_jwt_cookie_headers = {}
    if new_user_profile:
        log.debug(
            f"We got new profile from user_in_group() {new_user_profile}")
        user_profile = new_user_profile
        jwt_cookie_payload = user_profile_2_jwt_payload(
            get_jwt_field(cookievars, 'urs-user-id'),
            get_jwt_field(cookievars, 'urs-access-token'), user_profile)
        new_jwt_cookie_headers.update(
            make_set_cookie_headers_jwt(jwt_cookie_payload, '',
                                        os.getenv('COOKIE_DOMAIN', '')))

    log.debug('user_in_group: {}'.format(u_in_g))

    if private_check and not u_in_g:
        template_vars = {
            'contentstring': 'This data is not currently available.',
            'title': 'Could not access data',
            'requestid': get_request_id(),
        }
        return make_html_response(template_vars, new_jwt_cookie_headers, 403,
                                  'error.html')

    if not filename:  # Maybe this belongs up above, right after setting the filename var?
        log.warning(
            "Request was made to directory listing instead of object: {0}".
            format(path))

        template_vars = {
            'contentstring': 'Request does not appear to be valid.',
            'title': 'Request Not Serviceable',
            'requestid': get_request_id(),
        }

        return make_html_response(template_vars, new_jwt_cookie_headers, 404,
                                  'error.html')

    custom_headers.update(new_jwt_cookie_headers)
    log.debug(
        f'custom headers before try download from bucket: {custom_headers}')
    t.append(time.time())  # 7

    log.debug('timing for dynamic_url()')
    log.debug('ET for restore_bucket_vars(): {}s'.format(t[1] - t[0]))
    log.debug('ET for check_public_bucket(): {}s'.format(t[3] - t[2]))
    log.debug('ET for possible auth header handling: {}s'.format(t[4] - t[3]))
    log.debug('ET for user_in_group(): {}s'.format(t[6] - t[5]))
    log.debug('ET for total: {}s'.format(t[7] - t[0]))

    return try_download_from_bucket(bucket, filename, user_profile,
                                    custom_headers)