Implement resource isolation for get one API endpoints.
@@ -26,6 +26,7 @@ from six.moves import http_client
from st2common import log as logging
from st2common.models.system.common import ResourceReference
from st2common.exceptions.db import StackStormDBObjectNotFoundError
+from st2common.exceptions.rbac import ResourceAccessDeniedError
from st2common.rbac import utils as rbac_utils
from st2common.exceptions.rbac import AccessDeniedError
from st2common.util import schema as util_schema
@@ -214,14 +215,22 @@ class ResourceController(object):
def resources_model_filter(self, model, instances, requester_user=None, offset=0, eop=0,
**from_model_kwargs):
"""
- Method which converts DB object to API object and performs any additional filtering.
+ Method which converts DB objects to API objects and performs any additional filtering.
"""
+
result = []
for instance in instances[offset:eop]:
item = model.from_model(instance, **from_model_kwargs)
result.append(item)
return result
+ def resource_model_filter(self, model, instance, requester_user=None, **from_model_kwargs):
+ """
+ Method which converts DB object to API object and performs any additional filtering.
+ """
+ item = model.from_model(instance, **from_model_kwargs)
+ return item
+
def _get_one_by_id(self, id, requester_user, permission_type, exclude_fields=None,
from_model_kwargs=None):
"""
@@ -407,6 +416,22 @@ class BaseResourceIsolationControllerMixin(object):
return result
def resource_model_filter(self, model, instance, requester_user=None, **from_model_kwargs):
+ # RBAC is disabled, bail out
+ if not cfg.CONF.rbac.enable:
+ result = super(BaseResourceIsolationControllerMixin, self).resource_model_filter(
+ model=model, instance=instance, requester_user=requester_user,
+ **from_model_kwargs)
+
+ return result
+
+ # RBAC permission isolation is disabled, bail out
+ if not cfg.CONF.rbac.permission_isolation:
+ result = super(BaseResourceIsolationControllerMixin, self).resource_model_filter(
+ model=model, instance=instance, requester_user=requester_user,
+ **from_model_kwargs)
+
+ return result
+
user_is_admin = rbac_utils.user_is_admin(user_db=requester_user)
user_is_system_user = (requester_user.name == cfg.CONF.system_user.user)
@@ -417,7 +442,7 @@ class BaseResourceIsolationControllerMixin(object):
return item
user = item.context.get('user', None)
- if user and user == requester_user.name:
+ if user and (user == requester_user.name):
return item
return None
@@ -446,10 +471,18 @@ class ContentPackResourceController(ResourceController):
permission_type=permission_type)
# Perform resource isolation check (if supported)
-
from_model_kwargs = from_model_kwargs or {}
from_model_kwargs.update(self.from_model_kwargs)
- result = self.model.from_model(instance, **from_model_kwargs)
+
+ result = self.resource_model_filter(model=self.model, instance=instance,
+ requester_user=requester_user,
+ **from_model_kwargs)
+
+ if not result:
+ LOG.debug('Not returning the result due to RBAC resource isolation filter')
+ raise ResourceAccessDeniedError(user_db=requester_user, resource_api_or_db=instance,
+ permission_type=permission_type)
+
if result and self.include_reference:
pack = getattr(result, 'pack', None)
name = getattr(result, 'name', None)
