Default role checker should be case-insensitive.
Keystone role names are case-insensistive and Horizon should handle role names in a case-insensitive manner. For example, when keystone bootstraps default roles, it creates “admin”, “member”, and “reader”. If another role, “Member” (note the upper case ‘M’) is created, keystone will return a 409 Conflict since it considers the name “Member” equivalent to “member”. Note that case is preserved in this event. https://docs.openstack.org/keystone/latest/admin/case-insensitive.html#roles Also whatever is written in defaults can be overridden in settings by the operator - especially these days when actually the default should be 'member' (one of the default roles created by Keystone during the bootstrap), not _member_ which is there for legacy reasons I presume. Change-Id: Ibfb80a47a8aaed8f33e4e1dcfb428e70c829f0dd
This commit is contained in:
parent
d862623c27
commit
3aaeadf895
@ -781,7 +781,7 @@ def get_default_role(request):
|
||||
to request. Supports lookup by name or id.
|
||||
"""
|
||||
global DEFAULT_ROLE
|
||||
default = settings.OPENSTACK_KEYSTONE_DEFAULT_ROLE
|
||||
default = settings.OPENSTACK_KEYSTONE_DEFAULT_ROLE.lower()
|
||||
if default and DEFAULT_ROLE is None:
|
||||
try:
|
||||
roles = keystoneclient(request, admin=True).roles.list()
|
||||
@ -789,7 +789,7 @@ def get_default_role(request):
|
||||
roles = []
|
||||
exceptions.handle(request)
|
||||
for role in roles:
|
||||
if default in (role.id, role.name):
|
||||
if default in (role.id.lower(), role.name.lower()):
|
||||
DEFAULT_ROLE = role
|
||||
break
|
||||
return DEFAULT_ROLE
|
||||
|
@ -15,6 +15,7 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from random import choice
|
||||
from unittest import mock
|
||||
|
||||
|
||||
@ -68,6 +69,27 @@ class RoleAPITests(test.APIMockTestCase):
|
||||
role = api.keystone.get_default_role(self.request)
|
||||
keystoneclient.roles.list.assert_called_once_with()
|
||||
|
||||
@mock.patch.object(api.keystone, 'keystoneclient')
|
||||
@mock.patch.object(api.keystone, 'DEFAULT_ROLE', new=None)
|
||||
def test_get_case_insensitive_default_role(self, mock_keystoneclient):
|
||||
def convert_to_random_case(role_):
|
||||
new_name = list()
|
||||
for char in list(role_.name):
|
||||
new_name.append(getattr(char, choice(["lower", "upper"]))())
|
||||
role_.name = role_._info["name"] = "".join(new_name)
|
||||
return role_
|
||||
keystoneclient = mock_keystoneclient.return_value
|
||||
keystoneclient.roles.list.return_value = list()
|
||||
for role in self.roles:
|
||||
role = convert_to_random_case(role)
|
||||
keystoneclient.roles.list.return_value.append(role)
|
||||
role = api.keystone.get_default_role(self.request)
|
||||
self.assertEqual(self.role.name.lower(), role.name.lower())
|
||||
# Verify that a second call doesn't hit the API again,
|
||||
# so we use assert_called_once_with() here.
|
||||
api.keystone.get_default_role(self.request)
|
||||
keystoneclient.roles.list.assert_called_once_with()
|
||||
|
||||
|
||||
class ServiceAPITests(test.APIMockTestCase):
|
||||
@override_settings(OPENSTACK_ENDPOINT_TYPE='internalURL')
|
||||
|
Loading…
Reference in New Issue
Block a user