First stab at token auth. The UI could use a little bit of polishing.
This commit is contained in:
parent
f1746417b1
commit
283f9b81ae
9 changed files with 360 additions and 91 deletions
78
auth/auth.py
78
auth/auth.py
|
@ -32,19 +32,34 @@ def process_basic_auth(auth):
|
|||
credentials = b64decode(normalized[1]).split(':')
|
||||
|
||||
if len(credentials) != 2:
|
||||
logger.debug('Invalid basic auth credential formet.')
|
||||
logger.debug('Invalid basic auth credential format.')
|
||||
|
||||
authenticated = model.verify_user(credentials[0], credentials[1])
|
||||
if credentials[0] == '$token':
|
||||
# Use as token auth
|
||||
try:
|
||||
token = model.load_token_data(credentials[1])
|
||||
logger.debug('Successfully validated token: %s' % credentials[1])
|
||||
ctx = _request_ctx_stack.top
|
||||
ctx.validated_token = token
|
||||
|
||||
if authenticated:
|
||||
logger.debug('Successfully validated user: %s' % authenticated.username)
|
||||
ctx = _request_ctx_stack.top
|
||||
ctx.authenticated_user = authenticated
|
||||
identity_changed.send(app, identity=Identity(token.code, 'token'))
|
||||
return
|
||||
|
||||
new_identity = QuayDeferredPermissionUser(authenticated.username,
|
||||
'username')
|
||||
identity_changed.send(app, identity=new_identity)
|
||||
return
|
||||
except model.DataModelException:
|
||||
logger.debug('Invalid token: %s' % credentials[1])
|
||||
|
||||
else:
|
||||
authenticated = model.verify_user(credentials[0], credentials[1])
|
||||
|
||||
if authenticated:
|
||||
logger.debug('Successfully validated user: %s' % authenticated.username)
|
||||
ctx = _request_ctx_stack.top
|
||||
ctx.authenticated_user = authenticated
|
||||
|
||||
new_identity = QuayDeferredPermissionUser(authenticated.username,
|
||||
'username')
|
||||
identity_changed.send(app, identity=new_identity)
|
||||
return
|
||||
|
||||
# We weren't able to authenticate via basic auth.
|
||||
logger.debug('Basic auth present but could not be validated.')
|
||||
|
@ -54,42 +69,37 @@ def process_basic_auth(auth):
|
|||
def process_token(auth):
|
||||
normalized = [part.strip() for part in auth.split(' ') if part]
|
||||
if normalized[0].lower() != 'token' or len(normalized) != 2:
|
||||
logger.debug('Invalid token format.')
|
||||
logger.debug('Not an auth token: %s' % auth)
|
||||
return
|
||||
|
||||
token_details = normalized[1].split(',')
|
||||
|
||||
if len(token_details) != 2:
|
||||
logger.debug('Invalid token format.')
|
||||
return
|
||||
if len(token_details) != 1:
|
||||
logger.warning('Invalid token format: %s' % auth)
|
||||
abort(401)
|
||||
|
||||
token_vals = {val[0]: val[1] for val in
|
||||
(detail.split('=') for detail in token_details)}
|
||||
if ('signature' not in token_vals or 'repository' not in token_vals):
|
||||
logger.debug('Invalid token components.')
|
||||
return
|
||||
if 'signature' not in token_vals:
|
||||
logger.warning('Token does not contain signature: %s' % auth)
|
||||
abort(401)
|
||||
|
||||
unquoted = token_vals['repository'][1:-1]
|
||||
namespace, repository = parse_namespace_repository(unquoted)
|
||||
logger.debug('Validing signature: %s' % token_vals['signature'])
|
||||
validated = model.verify_token(token_vals['signature'], namespace,
|
||||
repository)
|
||||
try:
|
||||
token_data = model.load_token_data(token_vals['signature'])
|
||||
|
||||
if validated:
|
||||
session['repository'] = repository
|
||||
session['namespace'] = namespace
|
||||
except model.InvalidTokenException:
|
||||
logger.warning('Token could not be validated: %s' %
|
||||
token_vals['signature'])
|
||||
abort(401)
|
||||
|
||||
logger.debug('Successfully validated token: %s' % validated.code)
|
||||
ctx = _request_ctx_stack.top
|
||||
ctx.validated_token = validated
|
||||
session['repository'] = token_data.repository.name
|
||||
session['namespace'] = token_data.repository.namespace
|
||||
|
||||
identity_changed.send(app, identity=Identity(validated.code, 'token'))
|
||||
logger.debug('Successfully validated token: %s' % token_data.code)
|
||||
ctx = _request_ctx_stack.top
|
||||
ctx.validated_token = token_data
|
||||
|
||||
return
|
||||
|
||||
# WE weren't able to authenticate the token
|
||||
logger.debug('Token present but could not be validated.')
|
||||
abort(401)
|
||||
identity_changed.send(app, identity=Identity(token_data.code, 'token'))
|
||||
|
||||
|
||||
def process_auth(f):
|
||||
|
|
Reference in a new issue