Propagate the grant user context to the signed grant to fix image sharing.

This commit is contained in:
Jake Moshenko 2015-02-23 15:07:02 -05:00
parent 246ff556b9
commit 450b112f2c
4 changed files with 19 additions and 6 deletions

View file

@ -15,7 +15,7 @@ from data import model
from data.model import oauth
from app import app, authentication
from permissions import QuayDeferredPermissionUser
from auth_context import (set_authenticated_user, set_validated_token,
from auth_context import (set_authenticated_user, set_validated_token, set_grant_user_context,
set_authenticated_user_deferred, set_validated_oauth_token)
from util.http import abort
@ -131,10 +131,11 @@ def _process_basic_auth(auth):
logger.debug('Basic auth present but could not be validated.')
def generate_signed_token(grants):
def generate_signed_token(grants, user_context):
ser = SecureCookieSessionInterface().get_signing_serializer(app)
data_to_sign = {
'grants': grants,
'user_context': user_context,
}
encrypted = ser.dumps(data_to_sign)
@ -164,6 +165,7 @@ def _process_signed_grant(auth):
logger.debug('Successfully validated signed grant with data: %s', token_data)
loaded_identity = Identity(None, 'signed_grant')
set_grant_user_context(token_data['user_context'])
loaded_identity.provides.update(token_data['grants'])
identity_changed.send(app, identity=loaded_identity)

View file

@ -30,6 +30,15 @@ def set_authenticated_user(user_or_robot):
ctx.authenticated_user = user_or_robot
def get_grant_user_context():
return getattr(_request_ctx_stack.top, 'grant_user_context', None)
def set_grant_user_context(username_or_robotname):
ctx = _request_ctx_stack.top
ctx.grant_user_context = username_or_robotname
def set_authenticated_user_deferred(user_or_robot_db_uuid):
logger.debug('Deferring loading of authenticated user object with uuid: %s', user_or_robot_db_uuid)
ctx = _request_ctx_stack.top

View file

@ -60,7 +60,8 @@ def generate_headers(scope=GrantType.READ_REPOSITORY):
if permission.can():
# Generate a signed grant which expires here
signature = generate_signed_token(grants)
user_context = get_authenticated_user() and get_authenticated_user().username
signature = generate_signed_token(grants, user_context)
response.headers['WWW-Authenticate'] = signature
response.headers['X-Docker-Token'] = signature
else:

View file

@ -9,7 +9,7 @@ from time import time
from app import storage as store, image_diff_queue, app
from auth.auth import process_auth, extract_namespace_repo_from_session
from auth.auth_context import get_authenticated_user
from auth.auth_context import get_authenticated_user, get_grant_user_context
from util import checksums, changes
from util.http import abort, exact_abort
from auth.permissions import (ReadRepositoryPermission,
@ -463,8 +463,9 @@ def put_image_json(namespace, repository, image_id):
repo_image = model.get_repo_image_extended(namespace, repository, image_id)
if not repo_image:
logger.debug('Image not found, creating image')
username = get_authenticated_user() and get_authenticated_user().username
username = (get_authenticated_user() and get_authenticated_user().username or
get_grant_user_context())
logger.debug('Image not found, creating image with initiating user context: %s', username)
repo_image = model.find_create_or_link_image(image_id, repo, username, {},
store.preferred_locations[0])