Merge "Add build_target arguement to enforcer"

This commit is contained in:
Zuul 2018-09-30 22:18:20 +00:00 committed by Gerrit Code Review
commit 9c91aa74da
7 changed files with 140 additions and 55 deletions

View File

@ -14,6 +14,7 @@
import flask import flask
import flask_restful import flask_restful
import functools
from six.moves import http_client from six.moves import http_client
from keystone.common import json_home from keystone.common import json_home
@ -342,7 +343,7 @@ class DomainUserListResource(flask_restful.Resource):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:list_grants', action='identity:list_grants',
target_attr=_build_enforcement_target()) build_target=_build_enforcement_target)
refs = PROVIDERS.assignment_api.list_grants( refs = PROVIDERS.assignment_api.list_grants(
domain_id=domain_id, user_id=user_id, domain_id=domain_id, user_id=user_id,
inherited_to_projects=False) inherited_to_projects=False)
@ -361,7 +362,7 @@ class DomainUserResource(ks_flask.ResourceBase):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:check_grant', action='identity:check_grant',
target_attr=_build_enforcement_target()) build_target=_build_enforcement_target)
PROVIDERS.assignment_api.get_grant( PROVIDERS.assignment_api.get_grant(
role_id, domain_id=domain_id, user_id=user_id, role_id, domain_id=domain_id, user_id=user_id,
inherited_to_projects=False) inherited_to_projects=False)
@ -374,7 +375,7 @@ class DomainUserResource(ks_flask.ResourceBase):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:create_grant', action='identity:create_grant',
target_attr=_build_enforcement_target()) build_target=_build_enforcement_target)
PROVIDERS.assignment_api.create_grant( PROVIDERS.assignment_api.create_grant(
role_id, domain_id=domain_id, user_id=user_id, role_id, domain_id=domain_id, user_id=user_id,
inherited_to_projects=False, initiator=self.audit_initiator) inherited_to_projects=False, initiator=self.audit_initiator)
@ -387,7 +388,8 @@ class DomainUserResource(ks_flask.ResourceBase):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:revoke_grant', action='identity:revoke_grant',
target_attr=_build_enforcement_target(allow_non_existing=True)) build_target=functools.partial(_build_enforcement_target,
allow_non_existing=True))
PROVIDERS.assignment_api.delete_grant( PROVIDERS.assignment_api.delete_grant(
role_id, domain_id=domain_id, user_id=user_id, role_id, domain_id=domain_id, user_id=user_id,
inherited_to_projects=False, initiator=self.audit_initiator) inherited_to_projects=False, initiator=self.audit_initiator)
@ -402,7 +404,7 @@ class DomainGroupListResource(flask_restful.Resource):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:list_grants', action='identity:list_grants',
target_attr=_build_enforcement_target()) build_target=_build_enforcement_target)
refs = PROVIDERS.assignment_api.list_grants( refs = PROVIDERS.assignment_api.list_grants(
domain_id=domain_id, group_id=group_id, domain_id=domain_id, group_id=group_id,
inherited_to_projects=False) inherited_to_projects=False)
@ -421,7 +423,7 @@ class DomainGroupResource(ks_flask.ResourceBase):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:check_grant', action='identity:check_grant',
target_attr=_build_enforcement_target()) build_target=_build_enforcement_target)
PROVIDERS.assignment_api.get_grant( PROVIDERS.assignment_api.get_grant(
role_id, domain_id=domain_id, group_id=group_id, role_id, domain_id=domain_id, group_id=group_id,
inherited_to_projects=False) inherited_to_projects=False)
@ -434,7 +436,7 @@ class DomainGroupResource(ks_flask.ResourceBase):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:create_grant', action='identity:create_grant',
target_attr=_build_enforcement_target()) build_target=_build_enforcement_target)
PROVIDERS.assignment_api.create_grant( PROVIDERS.assignment_api.create_grant(
role_id, domain_id=domain_id, group_id=group_id, role_id, domain_id=domain_id, group_id=group_id,
inherited_to_projects=False, initiator=self.audit_initiator) inherited_to_projects=False, initiator=self.audit_initiator)
@ -447,7 +449,8 @@ class DomainGroupResource(ks_flask.ResourceBase):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:revoke_grant', action='identity:revoke_grant',
target_attr=_build_enforcement_target(allow_non_existing=True)) build_target=functools.partial(_build_enforcement_target,
allow_non_existing=True))
PROVIDERS.assignment_api.delete_grant( PROVIDERS.assignment_api.delete_grant(
role_id, domain_id=domain_id, group_id=group_id, role_id, domain_id=domain_id, group_id=group_id,
inherited_to_projects=False, initiator=self.audit_initiator) inherited_to_projects=False, initiator=self.audit_initiator)

View File

@ -13,6 +13,7 @@
# This file handles all flask-restful resources for /v3/groups # This file handles all flask-restful resources for /v3/groups
import flask_restful import flask_restful
import functools
from six.moves import http_client from six.moves import http_client
from keystone.common import json_home from keystone.common import json_home
@ -147,7 +148,8 @@ class UserGroupCRUDResource(flask_restful.Resource):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:check_user_in_group', action='identity:check_user_in_group',
target_attr=self._build_enforcement_target_attr(user_id, group_id)) build_target=functools.partial(self._build_enforcement_target_attr,
user_id, group_id))
PROVIDERS.identity_api.check_user_in_group(user_id, group_id) PROVIDERS.identity_api.check_user_in_group(user_id, group_id)
return None, http_client.NO_CONTENT return None, http_client.NO_CONTENT
@ -158,7 +160,8 @@ class UserGroupCRUDResource(flask_restful.Resource):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:add_user_to_group', action='identity:add_user_to_group',
target_attr=self._build_enforcement_target_attr(user_id, group_id)) build_target=functools.partial(self._build_enforcement_target_attr,
user_id, group_id))
PROVIDERS.identity_api.add_user_to_group( PROVIDERS.identity_api.add_user_to_group(
user_id, group_id, initiator=ks_flask.build_audit_initiator()) user_id, group_id, initiator=ks_flask.build_audit_initiator())
return None, http_client.NO_CONTENT return None, http_client.NO_CONTENT
@ -170,7 +173,8 @@ class UserGroupCRUDResource(flask_restful.Resource):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:remove_user_from_group', action='identity:remove_user_from_group',
target_attr=self._build_enforcement_target_attr(user_id, group_id)) build_target=functools.partial(self._build_enforcement_target_attr,
user_id, group_id))
PROVIDERS.identity_api.remove_user_from_group( PROVIDERS.identity_api.remove_user_from_group(
user_id, group_id, initiator=ks_flask.build_audit_initiator()) user_id, group_id, initiator=ks_flask.build_audit_initiator())
return None, http_client.NO_CONTENT return None, http_client.NO_CONTENT

View File

@ -13,6 +13,7 @@
# This file handles all flask-restful resources for /v3/OS-INHERIT # This file handles all flask-restful resources for /v3/OS-INHERIT
import flask_restful import flask_restful
import functools
from oslo_log import log from oslo_log import log
from six.moves import http_client from six.moves import http_client
@ -110,8 +111,10 @@ class OSInheritDomainGroupRolesResource(flask_restful.Resource):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:check_grant', action='identity:check_grant',
target_attr=_build_enforcement_target_attr( build_target=functools.partial(_build_enforcement_target_attr,
domain_id=domain_id, group_id=group_id, role_id=role_id)) domain_id=domain_id,
group_id=group_id,
role_id=role_id))
PROVIDERS.assignment_api.get_grant( PROVIDERS.assignment_api.get_grant(
domain_id=domain_id, group_id=group_id, role_id=role_id, domain_id=domain_id, group_id=group_id, role_id=role_id,
inherited_to_projects=True) inherited_to_projects=True)
@ -125,8 +128,10 @@ class OSInheritDomainGroupRolesResource(flask_restful.Resource):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:create_grant', action='identity:create_grant',
target_attr=_build_enforcement_target_attr( build_target=functools.partial(_build_enforcement_target_attr,
domain_id=domain_id, group_id=group_id, role_id=role_id)) domain_id=domain_id,
group_id=group_id,
role_id=role_id))
PROVIDERS.assignment_api.create_grant( PROVIDERS.assignment_api.create_grant(
domain_id=domain_id, group_id=group_id, role_id=role_id, domain_id=domain_id, group_id=group_id, role_id=role_id,
inherited_to_projects=True) inherited_to_projects=True)
@ -140,8 +145,10 @@ class OSInheritDomainGroupRolesResource(flask_restful.Resource):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:revoke_grant', action='identity:revoke_grant',
target_attr=_build_enforcement_target_attr( build_target=functools.partial(_build_enforcement_target_attr,
domain_id=domain_id, group_id=group_id, role_id=role_id)) domain_id=domain_id,
group_id=group_id,
role_id=role_id))
PROVIDERS.assignment_api.delete_grant( PROVIDERS.assignment_api.delete_grant(
domain_id=domain_id, group_id=group_id, role_id=role_id, domain_id=domain_id, group_id=group_id, role_id=role_id,
inherited_to_projects=True) inherited_to_projects=True)
@ -157,8 +164,9 @@ class OSInheritDomainGroupRolesListResource(flask_restful.Resource):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:list_grants', action='identity:list_grants',
target_attr=_build_enforcement_target_attr( build_target=functools.partial(_build_enforcement_target_attr,
domain_id=domain_id, group_id=group_id)) domain_id=domain_id,
group_id=group_id))
refs = PROVIDERS.assignment_api.list_grants( refs = PROVIDERS.assignment_api.list_grants(
domain_id=domain_id, group_id=group_id, inherited_to_projects=True) domain_id=domain_id, group_id=group_id, inherited_to_projects=True)
return ks_flask.ResourceBase.wrap_collection( return ks_flask.ResourceBase.wrap_collection(
@ -174,8 +182,10 @@ class OSInheritDomainUserRolesResource(flask_restful.Resource):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:check_grant', action='identity:check_grant',
target_attr=_build_enforcement_target_attr( build_target=functools.partial(_build_enforcement_target_attr,
domain_id=domain_id, user_id=user_id, role_id=role_id)) domain_id=domain_id,
user_id=user_id,
role_id=role_id))
PROVIDERS.assignment_api.get_grant( PROVIDERS.assignment_api.get_grant(
domain_id=domain_id, user_id=user_id, role_id=role_id, domain_id=domain_id, user_id=user_id, role_id=role_id,
inherited_to_projects=True) inherited_to_projects=True)
@ -189,8 +199,10 @@ class OSInheritDomainUserRolesResource(flask_restful.Resource):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:create_grant', action='identity:create_grant',
target_attr=_build_enforcement_target_attr( build_target=functools.partial(_build_enforcement_target_attr,
domain_id=domain_id, user_id=user_id, role_id=role_id)) domain_id=domain_id,
user_id=user_id,
role_id=role_id))
PROVIDERS.assignment_api.create_grant( PROVIDERS.assignment_api.create_grant(
domain_id=domain_id, user_id=user_id, role_id=role_id, domain_id=domain_id, user_id=user_id, role_id=role_id,
inherited_to_projects=True) inherited_to_projects=True)
@ -204,8 +216,10 @@ class OSInheritDomainUserRolesResource(flask_restful.Resource):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:revoke_grant', action='identity:revoke_grant',
target_attr=_build_enforcement_target_attr( build_target=functools.partial(_build_enforcement_target_attr,
domain_id=domain_id, user_id=user_id, role_id=role_id)) domain_id=domain_id,
user_id=user_id,
role_id=role_id))
PROVIDERS.assignment_api.delete_grant( PROVIDERS.assignment_api.delete_grant(
domain_id=domain_id, user_id=user_id, role_id=role_id, domain_id=domain_id, user_id=user_id, role_id=role_id,
inherited_to_projects=True) inherited_to_projects=True)
@ -221,8 +235,9 @@ class OSInheritDomainUserRolesListResource(flask_restful.Resource):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:list_grants', action='identity:list_grants',
target_attr=_build_enforcement_target_attr( build_target=functools.partial(_build_enforcement_target_attr,
domain_id=domain_id, user_id=user_id)) domain_id=domain_id,
user_id=user_id))
refs = PROVIDERS.assignment_api.list_grants( refs = PROVIDERS.assignment_api.list_grants(
domain_id=domain_id, user_id=user_id, inherited_to_projects=True) domain_id=domain_id, user_id=user_id, inherited_to_projects=True)
return ks_flask.ResourceBase.wrap_collection( return ks_flask.ResourceBase.wrap_collection(
@ -238,8 +253,10 @@ class OSInheritProjectUserResource(flask_restful.Resource):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:check_grant', action='identity:check_grant',
target_attr=_build_enforcement_target_attr( build_target=functools.partial(_build_enforcement_target_attr,
project_id=project_id, user_id=user_id, role_id=role_id)) project_id=project_id,
user_id=user_id,
role_id=role_id))
PROVIDERS.assignment_api.get_grant( PROVIDERS.assignment_api.get_grant(
project_id=project_id, user_id=user_id, role_id=role_id, project_id=project_id, user_id=user_id, role_id=role_id,
inherited_to_projects=True) inherited_to_projects=True)
@ -253,8 +270,10 @@ class OSInheritProjectUserResource(flask_restful.Resource):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:create_grant', action='identity:create_grant',
target_attr=_build_enforcement_target_attr( build_target=functools.partial(_build_enforcement_target_attr,
project_id=project_id, user_id=user_id, role_id=role_id)) project_id=project_id,
user_id=user_id,
role_id=role_id))
PROVIDERS.assignment_api.create_grant( PROVIDERS.assignment_api.create_grant(
project_id=project_id, user_id=user_id, role_id=role_id, project_id=project_id, user_id=user_id, role_id=role_id,
inherited_to_projects=True) inherited_to_projects=True)
@ -268,8 +287,10 @@ class OSInheritProjectUserResource(flask_restful.Resource):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:revoke_grant', action='identity:revoke_grant',
target_attr=_build_enforcement_target_attr( build_target=functools.partial(_build_enforcement_target_attr,
project_id=project_id, user_id=user_id, role_id=role_id)) project_id=project_id,
user_id=user_id,
role_id=role_id))
PROVIDERS.assignment_api.delete_grant( PROVIDERS.assignment_api.delete_grant(
project_id=project_id, user_id=user_id, role_id=role_id, project_id=project_id, user_id=user_id, role_id=role_id,
inherited_to_projects=True) inherited_to_projects=True)
@ -285,8 +306,10 @@ class OSInheritProjectGroupResource(flask_restful.Resource):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:check_grant', action='identity:check_grant',
target_attr=_build_enforcement_target_attr( build_target=functools.partial(_build_enforcement_target_attr,
project_id=project_id, group_id=group_id, role_id=role_id)) project_id=project_id,
group_id=group_id,
role_id=role_id))
PROVIDERS.assignment_api.get_grant( PROVIDERS.assignment_api.get_grant(
project_id=project_id, group_id=group_id, role_id=role_id, project_id=project_id, group_id=group_id, role_id=role_id,
inherited_to_projects=True) inherited_to_projects=True)
@ -300,8 +323,10 @@ class OSInheritProjectGroupResource(flask_restful.Resource):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:create_grant', action='identity:create_grant',
target_attr=_build_enforcement_target_attr( build_target=functools.partial(_build_enforcement_target_attr,
project_id=project_id, group_id=group_id, role_id=role_id)) project_id=project_id,
group_id=group_id,
role_id=role_id))
PROVIDERS.assignment_api.create_grant( PROVIDERS.assignment_api.create_grant(
project_id=project_id, group_id=group_id, role_id=role_id, project_id=project_id, group_id=group_id, role_id=role_id,
inherited_to_projects=True) inherited_to_projects=True)
@ -315,8 +340,10 @@ class OSInheritProjectGroupResource(flask_restful.Resource):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:revoke_grant', action='identity:revoke_grant',
target_attr=_build_enforcement_target_attr( build_target=functools.partial(_build_enforcement_target_attr,
project_id=project_id, group_id=group_id, role_id=role_id)) project_id=project_id,
group_id=group_id,
role_id=role_id))
PROVIDERS.assignment_api.delete_grant( PROVIDERS.assignment_api.delete_grant(
project_id=project_id, group_id=group_id, role_id=role_id, project_id=project_id, group_id=group_id, role_id=role_id,
inherited_to_projects=True) inherited_to_projects=True)

View File

@ -191,7 +191,7 @@ class RoleImplicationListResource(flask_restful.Resource):
GET/HEAD /v3/roles/{prior_role_id}/implies GET/HEAD /v3/roles/{prior_role_id}/implies
""" """
ENFORCER.enforce_call(action='identity:list_implied_roles', ENFORCER.enforce_call(action='identity:list_implied_roles',
target_attr=_build_enforcement_target_ref()) build_target=_build_enforcement_target_ref)
ref = PROVIDERS.role_api.list_implied_roles(prior_role_id) ref = PROVIDERS.role_api.list_implied_roles(prior_role_id)
implied_ids = [r['implied_role_id'] for r in ref] implied_ids = [r['implied_role_id'] for r in ref]
response_json = shared.role_inference_response(prior_role_id) response_json = shared.role_inference_response(prior_role_id)
@ -216,7 +216,7 @@ class RoleImplicationResource(flask_restful.Resource):
# Alternatively we can keep check_implied_role and reference # Alternatively we can keep check_implied_role and reference
# ._get_implied_role instead. # ._get_implied_role instead.
ENFORCER.enforce_call(action='identity:check_implied_role', ENFORCER.enforce_call(action='identity:check_implied_role',
target_attr=_build_enforcement_target_ref()) build_target=_build_enforcement_target_ref)
self.get(prior_role_id, implied_role_id) self.get(prior_role_id, implied_role_id)
# NOTE(morgan): Our API here breaks HTTP Spec. This should be evaluated # NOTE(morgan): Our API here breaks HTTP Spec. This should be evaluated
# for a future fix. This should just return the above "get" however, # for a future fix. This should just return the above "get" however,
@ -231,7 +231,7 @@ class RoleImplicationResource(flask_restful.Resource):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:get_implied_role', action='identity:get_implied_role',
target_attr=_build_enforcement_target_ref()) build_target=_build_enforcement_target_ref)
return self._get_implied_role(prior_role_id, implied_role_id) return self._get_implied_role(prior_role_id, implied_role_id)
def _get_implied_role(self, prior_role_id, implied_role_id): def _get_implied_role(self, prior_role_id, implied_role_id):
@ -255,7 +255,7 @@ class RoleImplicationResource(flask_restful.Resource):
PUT /v3/roles/{prior_role_id}/implies/{implied_role_id} PUT /v3/roles/{prior_role_id}/implies/{implied_role_id}
""" """
ENFORCER.enforce_call(action='identity:create_implied_role', ENFORCER.enforce_call(action='identity:create_implied_role',
target_attr=_build_enforcement_target_ref()) build_target=_build_enforcement_target_ref)
PROVIDERS.role_api.create_implied_role(prior_role_id, implied_role_id) PROVIDERS.role_api.create_implied_role(prior_role_id, implied_role_id)
response_json = self._get_implied_role(prior_role_id, implied_role_id) response_json = self._get_implied_role(prior_role_id, implied_role_id)
return response_json, http_client.CREATED return response_json, http_client.CREATED
@ -266,7 +266,7 @@ class RoleImplicationResource(flask_restful.Resource):
DELETE /v3/roles/{prior_role_id}/implies/{implied_role_id} DELETE /v3/roles/{prior_role_id}/implies/{implied_role_id}
""" """
ENFORCER.enforce_call(action='identity:delete_implied_role', ENFORCER.enforce_call(action='identity:delete_implied_role',
target_attr=_build_enforcement_target_ref()) build_target=_build_enforcement_target_ref)
PROVIDERS.role_api.delete_implied_role(prior_role_id, implied_role_id) PROVIDERS.role_api.delete_implied_role(prior_role_id, implied_role_id)
return None, http_client.NO_CONTENT return None, http_client.NO_CONTENT

View File

@ -14,6 +14,7 @@
import flask import flask
import flask_restful import flask_restful
import functools
from six.moves import http_client from six.moves import http_client
from keystone.common import json_home from keystone.common import json_home
@ -57,7 +58,7 @@ class SystemUsersListResource(flask_restful.Resource):
GET/HEAD /system/users/{user_id}/roles GET/HEAD /system/users/{user_id}/roles
""" """
ENFORCER.enforce_call(action='identity:list_system_grants_for_user', ENFORCER.enforce_call(action='identity:list_system_grants_for_user',
target_attr=_build_enforcement_target()) build_target=_build_enforcement_target)
refs = PROVIDERS.assignment_api.list_system_grants_for_user(user_id) refs = PROVIDERS.assignment_api.list_system_grants_for_user(user_id)
return ks_flask.ResourceBase.wrap_collection( return ks_flask.ResourceBase.wrap_collection(
refs, collection_name='roles') refs, collection_name='roles')
@ -70,7 +71,7 @@ class SystemUsersResource(flask_restful.Resource):
GET/HEAD /system/users/{user_id}/roles/{role_id} GET/HEAD /system/users/{user_id}/roles/{role_id}
""" """
ENFORCER.enforce_call(action='identity:check_system_grant_for_user', ENFORCER.enforce_call(action='identity:check_system_grant_for_user',
target_attr=_build_enforcement_target()) build_target=_build_enforcement_target)
PROVIDERS.assignment_api.check_system_grant_for_user(user_id, role_id) PROVIDERS.assignment_api.check_system_grant_for_user(user_id, role_id)
return None, http_client.NO_CONTENT return None, http_client.NO_CONTENT
@ -80,7 +81,7 @@ class SystemUsersResource(flask_restful.Resource):
PUT /system/users/{user_id}/roles/{role_id} PUT /system/users/{user_id}/roles/{role_id}
""" """
ENFORCER.enforce_call(action='identity:create_system_grant_for_user', ENFORCER.enforce_call(action='identity:create_system_grant_for_user',
target_attr=_build_enforcement_target()) build_target=_build_enforcement_target)
PROVIDERS.assignment_api.create_system_grant_for_user(user_id, role_id) PROVIDERS.assignment_api.create_system_grant_for_user(user_id, role_id)
return None, http_client.NO_CONTENT return None, http_client.NO_CONTENT
@ -91,7 +92,9 @@ class SystemUsersResource(flask_restful.Resource):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:revoke_system_grant_for_user', action='identity:revoke_system_grant_for_user',
target_attr=_build_enforcement_target(allow_non_existing=True)) build_target=functools.partial(
_build_enforcement_target,
allow_non_existing=True))
PROVIDERS.assignment_api.delete_system_grant_for_user(user_id, role_id) PROVIDERS.assignment_api.delete_system_grant_for_user(user_id, role_id)
return None, http_client.NO_CONTENT return None, http_client.NO_CONTENT
@ -103,7 +106,7 @@ class SystemGroupsRolesListResource(flask_restful.Resource):
GET/HEAD /system/groups/{group_id}/roles GET/HEAD /system/groups/{group_id}/roles
""" """
ENFORCER.enforce_call(action='identity:list_system_grants_for_group', ENFORCER.enforce_call(action='identity:list_system_grants_for_group',
target_attr=_build_enforcement_target()) build_target=_build_enforcement_target)
refs = PROVIDERS.assignment_api.list_system_grants_for_group(group_id) refs = PROVIDERS.assignment_api.list_system_grants_for_group(group_id)
return ks_flask.ResourceBase.wrap_collection( return ks_flask.ResourceBase.wrap_collection(
refs, collection_name='roles') refs, collection_name='roles')
@ -116,7 +119,7 @@ class SystemGroupsRolestResource(flask_restful.Resource):
GET/HEAD /system/groups/{group_id}/roles/{role_id} GET/HEAD /system/groups/{group_id}/roles/{role_id}
""" """
ENFORCER.enforce_call(action='identity:check_system_grant_for_group', ENFORCER.enforce_call(action='identity:check_system_grant_for_group',
target_attr=_build_enforcement_target()) build_target=_build_enforcement_target)
PROVIDERS.assignment_api.check_system_grant_for_group( PROVIDERS.assignment_api.check_system_grant_for_group(
group_id, role_id) group_id, role_id)
return None, http_client.NO_CONTENT return None, http_client.NO_CONTENT
@ -127,7 +130,7 @@ class SystemGroupsRolestResource(flask_restful.Resource):
PUT /system/groups/{group_id}/roles/{role_id} PUT /system/groups/{group_id}/roles/{role_id}
""" """
ENFORCER.enforce_call(action='identity:create_system_grant_for_group', ENFORCER.enforce_call(action='identity:create_system_grant_for_group',
target_attr=_build_enforcement_target()) build_target=_build_enforcement_target)
PROVIDERS.assignment_api.create_system_grant_for_group( PROVIDERS.assignment_api.create_system_grant_for_group(
group_id, role_id) group_id, role_id)
return None, http_client.NO_CONTENT return None, http_client.NO_CONTENT
@ -139,7 +142,9 @@ class SystemGroupsRolestResource(flask_restful.Resource):
""" """
ENFORCER.enforce_call( ENFORCER.enforce_call(
action='identity:revoke_system_grant_for_group', action='identity:revoke_system_grant_for_group',
target_attr=_build_enforcement_target(allow_non_existing=True)) build_target=functools.partial(
_build_enforcement_target,
allow_non_existing=True))
PROVIDERS.assignment_api.delete_system_grant_for_group( PROVIDERS.assignment_api.delete_system_grant_for_group(
group_id, role_id) group_id, role_id)
return None, http_client.NO_CONTENT return None, http_client.NO_CONTENT

View File

@ -245,7 +245,7 @@ class RBACEnforcer(object):
@classmethod @classmethod
def enforce_call(cls, enforcer=None, action=None, target_attr=None, def enforce_call(cls, enforcer=None, action=None, target_attr=None,
member_target_type=None, member_target=None, member_target_type=None, member_target=None,
filters=None): filters=None, build_target=None):
"""Enforce RBAC on the current request. """Enforce RBAC on the current request.
This will do some legwork and then instantiate the Enforcer if an This will do some legwork and then instantiate the Enforcer if an
@ -282,6 +282,11 @@ class RBACEnforcer(object):
various "list" APIs and are un-used in the default various "list" APIs and are un-used in the default
supplied policies. supplied policies.
:type filters: iterable :type filters: iterable
:param build_target: A function to build the target for enforcement.
This is explicitly done after authentication
in order to not leak existance data before
auth.
:type build_target: function
""" """
# NOTE(morgan) everything in the policy_dict may be used by the policy # NOTE(morgan) everything in the policy_dict may be used by the policy
# DSL to action on RBAC and request information/response data. # DSL to action on RBAC and request information/response data.
@ -335,7 +340,7 @@ class RBACEnforcer(object):
policy_dict.update(flask.request.view_args) policy_dict.update(flask.request.view_args)
# Get the Target Data Set. # Get the Target Data Set.
if target_attr is None: if target_attr is None and build_target is None:
try: try:
policy_dict.update(cls._extract_member_target_data( policy_dict.update(cls._extract_member_target_data(
member_target_type, member_target)) member_target_type, member_target))
@ -362,7 +367,11 @@ class RBACEnforcer(object):
policy_dict.setdefault('target', {}).update( policy_dict.setdefault('target', {}).update(
subj_token_target_data) subj_token_target_data)
else: else:
policy_dict['target'] = target_attr if target_attr and build_target:
raise ValueError('Programming Error: A target_attr or '
'build_target must be provided, but not both')
policy_dict['target'] = target_attr or build_target()
# Pull the data from the submitted json body to generate # Pull the data from the submitted json body to generate
# appropriate input/target attributes, we take an explicit copy here # appropriate input/target attributes, we take an explicit copy here

View File

@ -423,6 +423,43 @@ class TestRBACEnforcerRest(_TestRBACEnforcerBase):
self.assertEqual({}, self.enforcer._extract_member_target_data( self.assertEqual({}, self.enforcer._extract_member_target_data(
member_target={}, member_target_type=None)) member_target={}, member_target_type=None))
def test_call_build_enforcement_target(self):
assertIn = self.assertIn
assertEq = self.assertEqual
ref_uuid = uuid.uuid4().hex
def _enforce_mock_func(credentials, action, target,
do_raise=True):
assertIn('target.domain.id', target)
assertEq(target['target.domain.id'], ref_uuid)
def _build_enforcement_target():
return {'domain': {'id': ref_uuid}}
self.useFixture(fixtures.MockPatchObject(
self.enforcer, '_enforce', _enforce_mock_func))
argument_id = uuid.uuid4().hex
with self.test_client() as c:
path = '/v3/auth/tokens'
body = self._auth_json()
r = c.post(
path,
json=body,
follow_redirects=True,
expected_status_code=201)
token_id = r.headers['X-Subject-Token']
c.get('%s/argument/%s' % (self.restful_api_url_prefix,
argument_id),
headers={'X-Auth-Token': token_id})
self.enforcer.enforce_call(
action='example:allowed',
build_target=_build_enforcement_target)
def test_policy_enforcer_action_decorator(self): def test_policy_enforcer_action_decorator(self):
# Create a method that has an action pre-registered # Create a method that has an action pre-registered
action = 'example:allowed' action = 'example:allowed'