mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Fix composites comparison for role in is_struct_included keycloak.py … (#6688)
* Fix composites comparison for role in is_struct_included keycloak.py function * Add changelog fragment and unit tests * Update changelogs/fragments/6688-is-struct-included-bug-in-keycloak-py.yml Co-authored-by: Felix Fontein <felix@fontein.de> --------- Co-authored-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
parent
1f6d404deb
commit
032996e005
3 changed files with 114 additions and 3 deletions
|
@ -0,0 +1,2 @@
|
||||||
|
bugfixes:
|
||||||
|
- keycloak module utils - fix ``is_struct_included`` handling of lists of lists/dictionaries (https://github.com/ansible-collections/community.general/pull/6688).
|
|
@ -216,24 +216,30 @@ def is_struct_included(struct1, struct2, exclude=None):
|
||||||
Return True if all element of dict 1 are present in dict 2, return false otherwise.
|
Return True if all element of dict 1 are present in dict 2, return false otherwise.
|
||||||
"""
|
"""
|
||||||
if isinstance(struct1, list) and isinstance(struct2, list):
|
if isinstance(struct1, list) and isinstance(struct2, list):
|
||||||
|
if not struct1 and not struct2:
|
||||||
|
return True
|
||||||
for item1 in struct1:
|
for item1 in struct1:
|
||||||
if isinstance(item1, (list, dict)):
|
if isinstance(item1, (list, dict)):
|
||||||
for item2 in struct2:
|
for item2 in struct2:
|
||||||
if not is_struct_included(item1, item2, exclude):
|
if is_struct_included(item1, item2, exclude):
|
||||||
|
break
|
||||||
|
else:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
if item1 not in struct2:
|
if item1 not in struct2:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
elif isinstance(struct1, dict) and isinstance(struct2, dict):
|
elif isinstance(struct1, dict) and isinstance(struct2, dict):
|
||||||
|
if not struct1 and not struct2:
|
||||||
|
return True
|
||||||
try:
|
try:
|
||||||
for key in struct1:
|
for key in struct1:
|
||||||
if not (exclude and key in exclude):
|
if not (exclude and key in exclude):
|
||||||
if not is_struct_included(struct1[key], struct2[key], exclude):
|
if not is_struct_included(struct1[key], struct2[key], exclude):
|
||||||
return False
|
return False
|
||||||
return True
|
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return False
|
return False
|
||||||
|
return True
|
||||||
elif isinstance(struct1, bool) and isinstance(struct2, bool):
|
elif isinstance(struct1, bool) and isinstance(struct2, bool):
|
||||||
return struct1 == struct2
|
return struct1 == struct2
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
# Copyright (c) Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak import is_struct_included
|
||||||
|
|
||||||
|
|
||||||
|
class KeycloakIsStructIncludedTestCase(unittest.TestCase):
|
||||||
|
dict1 = dict(
|
||||||
|
test1='test1',
|
||||||
|
test2=dict(
|
||||||
|
test1='test1',
|
||||||
|
test2='test2'
|
||||||
|
),
|
||||||
|
test3=['test1', dict(test='test1', test2='test2')]
|
||||||
|
)
|
||||||
|
dict2 = dict(
|
||||||
|
test1='test1',
|
||||||
|
test2=dict(
|
||||||
|
test1='test1',
|
||||||
|
test2='test2',
|
||||||
|
test3='test3'
|
||||||
|
),
|
||||||
|
test3=['test1', dict(test='test1', test2='test2'), 'test3'],
|
||||||
|
test4='test4'
|
||||||
|
)
|
||||||
|
dict3 = dict(
|
||||||
|
test1='test1',
|
||||||
|
test2=dict(
|
||||||
|
test1='test1',
|
||||||
|
test2='test23',
|
||||||
|
test3='test3'
|
||||||
|
),
|
||||||
|
test3=['test1', dict(test='test1', test2='test23'), 'test3'],
|
||||||
|
test4='test4'
|
||||||
|
)
|
||||||
|
|
||||||
|
dict5 = dict(
|
||||||
|
test1='test1',
|
||||||
|
test2=dict(
|
||||||
|
test1=True,
|
||||||
|
test2='test23',
|
||||||
|
test3='test3'
|
||||||
|
),
|
||||||
|
test3=['test1', dict(test='test1', test2='test23'), 'test3'],
|
||||||
|
test4='test4'
|
||||||
|
)
|
||||||
|
|
||||||
|
dict6 = dict(
|
||||||
|
test1='test1',
|
||||||
|
test2=dict(
|
||||||
|
test1='true',
|
||||||
|
test2='test23',
|
||||||
|
test3='test3'
|
||||||
|
),
|
||||||
|
test3=['test1', dict(test='test1', test2='test23'), 'test3'],
|
||||||
|
test4='test4'
|
||||||
|
)
|
||||||
|
dict7 = [
|
||||||
|
{
|
||||||
|
'roles': ['view-clients', 'view-identity-providers', 'view-users', 'query-realms', 'manage-users'],
|
||||||
|
'clientid': 'master-realm'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'roles': ['manage-account', 'view-profile', 'manage-account-links'],
|
||||||
|
'clientid': 'account'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
dict8 = [
|
||||||
|
{
|
||||||
|
'roles': ['view-clients', 'query-realms', 'view-users'],
|
||||||
|
'clientid': 'master-realm'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'roles': ['manage-account-links', 'view-profile', 'manage-account'],
|
||||||
|
'clientid': 'account'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
def test_trivial(self):
|
||||||
|
self.assertTrue(is_struct_included(self.dict1, self.dict1))
|
||||||
|
|
||||||
|
def test_equals_with_dict2_bigger_than_dict1(self):
|
||||||
|
self.assertTrue(is_struct_included(self.dict1, self.dict2))
|
||||||
|
|
||||||
|
def test_not_equals_with_dict2_bigger_than_dict1(self):
|
||||||
|
self.assertFalse(is_struct_included(self.dict2, self.dict1))
|
||||||
|
|
||||||
|
def test_not_equals_with_dict1_different_than_dict3(self):
|
||||||
|
self.assertFalse(is_struct_included(self.dict1, self.dict3))
|
||||||
|
|
||||||
|
def test_equals_with_dict5_contain_bool_and_dict6_contain_true_string(self):
|
||||||
|
self.assertFalse(is_struct_included(self.dict5, self.dict6))
|
||||||
|
self.assertFalse(is_struct_included(self.dict6, self.dict5))
|
||||||
|
|
||||||
|
def test_not_equals_dict7_dict8_compare_dict7_with_list_bigger_than_dict8_but_reverse_equals(self):
|
||||||
|
self.assertFalse(is_struct_included(self.dict7, self.dict8))
|
||||||
|
self.assertTrue(is_struct_included(self.dict8, self.dict7))
|
Loading…
Reference in a new issue