This repository has been archived on 2020-03-24. You can view files and clone it, but cannot push or open issues or pull requests.
quay/auth/validateresult.py

116 lines
3.8 KiB
Python
Raw Normal View History

from enum import Enum
from flask_principal import Identity, identity_changed
from app import app
from auth.auth_context import (set_authenticated_user, set_validated_token, set_grant_context,
set_validated_oauth_token, set_validated_app_specific_token)
from auth.scopes import scopes_from_scope_string
from auth.permissions import QuayDeferredPermissionUser
class AuthKind(Enum):
cookie = 'cookie'
basic = 'basic'
oauth = 'oauth'
signed_grant = 'signed_grant'
credentials = 'credentials'
class ValidateResult(object):
""" A result of validating auth in one form or another. """
def __init__(self, kind, missing=False, user=None, token=None, oauthtoken=None,
robot=None, appspecifictoken=None, signed_data=None, error_message=None):
self.kind = kind
self.missing = missing
self.user = user
self.robot = robot
self.token = token
self.oauthtoken = oauthtoken
self.appspecifictoken = appspecifictoken
self.signed_data = signed_data
self.error_message = error_message
def tuple(self):
return (self.kind, self.missing, self.user, self.token, self.oauthtoken, self.robot,
self.appspecifictoken, self.signed_data, self.error_message)
def __eq__(self, other):
return self.tuple() == other.tuple()
def apply_to_context(self):
""" Applies this auth result to the auth context and Flask-Principal. """
# Set the various pieces of the auth context.
if self.oauthtoken:
set_authenticated_user(self.authed_user)
set_validated_oauth_token(self.oauthtoken)
elif self.appspecifictoken:
set_authenticated_user(self.authed_user)
set_validated_app_specific_token(self.appspecifictoken)
elif self.authed_user:
set_authenticated_user(self.authed_user)
elif self.token:
set_validated_token(self.token)
elif self.signed_data:
if self.signed_data['user_context']:
set_grant_context({
'user': self.signed_data['user_context'],
'kind': 'user',
})
# Set the identity for Flask-Principal.
if self.identity:
identity_changed.send(app, identity=self.identity)
def with_kind(self, kind):
""" Returns a copy of this result, but with the kind replaced. """
return ValidateResult(kind, self.missing, self.user, self.token, self.oauthtoken, self.robot,
self.appspecifictoken, self.signed_data, self.error_message)
@property
def authed_user(self):
""" Returns the authenticated user, whether directly, or via an OAuth token. """
if not self.auth_valid:
return None
if self.oauthtoken:
return self.oauthtoken.authorized_user
if self.appspecifictoken:
return self.appspecifictoken.user
return self.user if self.user else self.robot
@property
def identity(self):
""" Returns the identity for the auth result. """
if not self.auth_valid:
return None
if self.oauthtoken:
scope_set = scopes_from_scope_string(self.oauthtoken.scope)
return QuayDeferredPermissionUser.for_user(self.oauthtoken.authorized_user, scope_set)
if self.authed_user:
return QuayDeferredPermissionUser.for_user(self.authed_user)
if self.token:
return Identity(self.token.code, 'token')
if self.signed_data:
identity = Identity(None, 'signed_grant')
identity.provides.update(self.signed_data['grants'])
return identity
return None
@property
def has_user(self):
""" Returns whether a user (not a robot) was authenticated successfully. """
return bool(self.user)
@property
def auth_valid(self):
""" Returns whether authentication successfully occurred. """
return (self.user or self.token or self.oauthtoken or self.appspecifictoken or self.robot or
self.signed_data)