diff --git a/kqueen/blueprints/api/generic_views.py b/kqueen/blueprints/api/generic_views.py index b7b1f41f..5c8cdf17 100644 --- a/kqueen/blueprints/api/generic_views.py +++ b/kqueen/blueprints/api/generic_views.py @@ -8,6 +8,10 @@ from kqueen.models import Organization from .helpers import get_object +import logging + +logger = logging.getLogger('kqueen_api') + class GenericView(View): obj = None @@ -32,35 +36,16 @@ def check_authentication(self): _jwt_required(current_app.config['JWT_DEFAULT_REALM']) def check_authorization(self): - # get view class - try: - _class = self.get_class() - except NotImplementedError: - return False - # get user data if current_identity: user = current_identity.get_dict() - organization = current_identity.organization else: return False - # form policy key - policy = '{}:{}'.format(_class.__name__.lower(), self.action) - # get policies and update them with organization level overrides - policies = current_app.config.get('DEFAULT_POLICIES', {}) - if hasattr(organization, 'policy') and organization.policy: - policies.update(organization.policy) - - try: - policy_value = policies[policy] - except KeyError: - current_app.logger.error('Unknown policy {}'.format(policy)) + policy_value = self.get_policy_value() + if not policy_value: return False - # evaluate user permissions - # if there are multiple objects, filter out those which current user - # doesn't have access to if isinstance(self.obj, list): allowed = [] for obj in self.obj: @@ -74,6 +59,35 @@ def check_authorization(self): 'Your user account is lacking the necessary ' 'permissions to perform this operation') + def get_policy_key(self): + # get view class + try: + _class = self.get_class() + except NotImplementedError: + return '' + + return '{}:{}'.format(_class.__name__.lower(), self.action) + + def get_policy_value(self): + # get policy_key + policy_key = self.get_policy_key() + if not policy_key: + return '' + + policies = current_app.config.get('DEFAULT_POLICIES', {}) + + # update them with organization level overrides + organization = current_identity.organization + if hasattr(organization, 'policy') and organization.policy: + policies.update(organization.policy) + + try: + policy_value = policies[policy_key] + except KeyError: + current_app.logger.error('Unknown policy {}'.format(policy_key)) + policy_value = '' + return policy_value + def set_object(self, *args, **kwargs): self.obj = get_object(self.get_class(), kwargs['pk'], current_identity) @@ -111,6 +125,13 @@ def dispatch_request(self, *args, **kwargs): return jsonify({'id': self.obj.id, 'state': 'deleted'}) + def get_policy_key(self): + policy_key = super().get_policy_key() + + if policy_key == 'user:delete': + policy_key = '{}_{}'.format(policy_key, self.obj.role) + return policy_key + class UpdateView(GenericView): methods = ['PATCH'] diff --git a/kqueen/config/default_policy.json b/kqueen/config/default_policy.json index 91fe7a66..41356f87 100644 --- a/kqueen/config/default_policy.json +++ b/kqueen/config/default_policy.json @@ -15,7 +15,9 @@ "provisioner:list": "ALL", "provisioner:update": "ALL", "user:create": "IS_ADMIN", - "user:delete": "IS_ADMIN", + "user:delete_member": "IS_ADMIN", + "user:delete_admin": "IS_ADMIN", + "user:delete_superadmin": "IS_SUPERADMIN", "user:get": "ALL", "user:list": "ALL", "user:update": "ADMIN_OR_OWNER"