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.
|
to request. Supports lookup by name or id.
|
||||||
"""
|
"""
|
||||||
global DEFAULT_ROLE
|
global DEFAULT_ROLE
|
||||||
default = settings.OPENSTACK_KEYSTONE_DEFAULT_ROLE
|
default = settings.OPENSTACK_KEYSTONE_DEFAULT_ROLE.lower()
|
||||||
if default and DEFAULT_ROLE is None:
|
if default and DEFAULT_ROLE is None:
|
||||||
try:
|
try:
|
||||||
roles = keystoneclient(request, admin=True).roles.list()
|
roles = keystoneclient(request, admin=True).roles.list()
|
||||||
@ -789,7 +789,7 @@ def get_default_role(request):
|
|||||||
roles = []
|
roles = []
|
||||||
exceptions.handle(request)
|
exceptions.handle(request)
|
||||||
for role in roles:
|
for role in roles:
|
||||||
if default in (role.id, role.name):
|
if default in (role.id.lower(), role.name.lower()):
|
||||||
DEFAULT_ROLE = role
|
DEFAULT_ROLE = role
|
||||||
break
|
break
|
||||||
return DEFAULT_ROLE
|
return DEFAULT_ROLE
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
from random import choice
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
|
|
||||||
@ -68,6 +69,27 @@ class RoleAPITests(test.APIMockTestCase):
|
|||||||
role = api.keystone.get_default_role(self.request)
|
role = api.keystone.get_default_role(self.request)
|
||||||
keystoneclient.roles.list.assert_called_once_with()
|
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):
|
class ServiceAPITests(test.APIMockTestCase):
|
||||||
@override_settings(OPENSTACK_ENDPOINT_TYPE='internalURL')
|
@override_settings(OPENSTACK_ENDPOINT_TYPE='internalURL')
|
||||||
|
Loading…
Reference in New Issue
Block a user