From d779eb6fe3dedcd37e777f1530fa24a1a9343353 Mon Sep 17 00:00:00 2001 From: Kenji Ishii Date: Fri, 22 Jan 2016 18:17:37 +0900 Subject: [PATCH] Add convenient method to get admin roles and permissions admin roles and admin permissions (like 'openstack.roles.xxxx') depends on OPENSTACK_KEYSTONE_ADMIN_ROLES. These information is needed with openstack_auth and Horizon at least as common information. So, this patch provide these methods as a convenient method at openstack_auth. Change-Id: Idad1860684b1e772fc31f16fc8c0263e49fc3919 Closes-Bug: #1536896 --- openstack_auth/backend.py | 2 +- openstack_auth/tests/tests.py | 20 ++++++++++++++++ openstack_auth/user.py | 5 +--- openstack_auth/utils.py | 45 +++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 5 deletions(-) diff --git a/openstack_auth/backend.py b/openstack_auth/backend.py index 2d364a47..fb2c9bf2 100644 --- a/openstack_auth/backend.py +++ b/openstack_auth/backend.py @@ -294,7 +294,7 @@ class KeystoneBackend(object): return set() # TODO(gabrielhurley): Integrate policy-driven RBAC # when supported by Keystone. - role_perms = {"openstack.roles.%s" % role['name'].lower() + role_perms = {utils.get_role_permission(role['name']) for role in user.roles} services = [] diff --git a/openstack_auth/tests/tests.py b/openstack_auth/tests/tests.py index 847c8b60..894eaf6a 100644 --- a/openstack_auth/tests/tests.py +++ b/openstack_auth/tests/tests.py @@ -19,6 +19,7 @@ from django.contrib import auth from django.core.urlresolvers import reverse from django import http from django import test +from django.test.utils import override_settings from keystoneauth1 import exceptions as keystone_exceptions from keystoneauth1.identity import v2 as v2_auth from keystoneauth1.identity import v3 as v3_auth @@ -1107,3 +1108,22 @@ class PolicyTestCaseV3Admin(PolicyTestCase): value = policy.check((("identity", "admin_or_cloud_admin"),), request=self.request) self.assertTrue(value) + + +class RoleTestCaseAdmin(test.TestCase): + + def test_get_admin_roles_with_default_value(self): + admin_roles = utils.get_admin_roles() + self.assertSetEqual({'admin'}, admin_roles) + + @override_settings(OPENSTACK_KEYSTONE_ADMIN_ROLES=['foO', 'BAR', 'admin']) + def test_get_admin_roles(self): + admin_roles = utils.get_admin_roles() + self.assertSetEqual({'foo', 'bar', 'admin'}, admin_roles) + + @override_settings(OPENSTACK_KEYSTONE_ADMIN_ROLES=['foO', 'BAR', 'admin']) + def test_get_admin_permissions(self): + admin_permissions = utils.get_admin_permissions() + self.assertSetEqual({'openstack.roles.foo', + 'openstack.roles.bar', + 'openstack.roles.admin'}, admin_permissions) diff --git a/openstack_auth/user.py b/openstack_auth/user.py index cff107b1..e0f7df45 100644 --- a/openstack_auth/user.py +++ b/openstack_auth/user.py @@ -297,10 +297,7 @@ class User(models.AbstractBaseUser, models.AnonymousUser): Returns ``True`` or ``False``. """ - admin_roles = {role.lower() for role in getattr( - settings, - 'OPENSTACK_KEYSTONE_ADMIN_ROLES', - ['admin'])} + admin_roles = utils.get_admin_roles() user_roles = {role['name'].lower() for role in self.roles} return not admin_roles.isdisjoint(user_roles) diff --git a/openstack_auth/utils.py b/openstack_auth/utils.py index 599e3383..77b71176 100644 --- a/openstack_auth/utils.py +++ b/openstack_auth/utils.py @@ -390,3 +390,48 @@ def get_endpoint_region(endpoint): def using_cookie_backed_sessions(): engine = getattr(settings, 'SESSION_ENGINE', '') return "signed_cookies" in engine + + +def get_admin_roles(): + """Common function for getting the admin roles from settings + + Returns: + Set object including all admin roles. + If there is no role, this will return empty. + { + "foo", "bar", "admin" + } + """ + admin_roles = {role.lower() for role + in getattr(settings, 'OPENSTACK_KEYSTONE_ADMIN_ROLES', + ['admin'])} + return admin_roles + + +def get_role_permission(role): + """Common function for getting the permission froms arg + + This format is 'openstack.roles.xxx' and 'xxx' is a real role name. + + Returns: + String like "openstack.roles.admin" + If role is None, this will return None. + """ + return "openstack.roles.%s" % role.lower() + + +def get_admin_permissions(): + """Common function for getting the admin permissions from settings + + This format is 'openstack.roles.xxx' and 'xxx' is a real role name. + + Returns: + Set object including all admin permission. + If there is no permission, this will return empty. + { + "openstack.roles.foo", + "openstack.roles.bar", + "openstack.roles.admin" + } + """ + return {get_role_permission(role) for role in get_admin_roles()}