diff options
Diffstat (limited to 'ipsilon/util/policy.py')
-rw-r--r-- | ipsilon/util/policy.py | 115 |
1 files changed, 96 insertions, 19 deletions
diff --git a/ipsilon/util/policy.py b/ipsilon/util/policy.py index 17363aa..7fdac0c 100644 --- a/ipsilon/util/policy.py +++ b/ipsilon/util/policy.py @@ -65,7 +65,7 @@ class Policy(Log): type(allowed)) self.allowed = allowed - def map_attributes(self, attributes): + def map_attributes(self, attributes, ignore_case=False): if not isinstance(attributes, dict): raise ValueError("Attributes must be dictionary, not %s" % @@ -74,6 +74,17 @@ class Policy(Log): not_mapped = copy.deepcopy(attributes) mapped = dict() + # If ignore_case is True, + # then PD translates case insensitively prefixes + PD = dict() + for k in attributes.keys(): + if ignore_case: + # note duplicates that differ only by case + # will be lost here, beware! + PD[k.lower()] = k + else: + PD[k] = k + for (key, value) in self.mappings: if not isinstance(key, list): key = [key] @@ -93,36 +104,57 @@ class Policy(Log): mapprefix = None mapname = value[0] + if ignore_case: + if prefix: + prefix = prefix.lower() + name = name.lower() + if prefix: - if prefix in attributes: - attr = attributes[prefix] + if prefix in PD: + attr = attributes[PD[prefix]] else: # '*' in a prefix matches nothing continue + + # If ignore_case is True, + # then ND translates case insensitively names + ND = dict() + if isinstance(attr, list): + klist = attr + else: + klist = attr.keys() + for k in klist: + if ignore_case: + # note duplicates that differ only by case + # will be lost here, beware! + ND[k.lower()] = k + else: + ND[k] = k else: attr = attributes + ND = PD - if name in attr: + if name in ND and ND[name] in attr: if isinstance(attr, list): if mapprefix: if mapprefix not in mapped: mapped[mapprefix] = list() mapped[mapprefix].append(mapname) if not_mapped: - if prefix in not_mapped: - while name in not_mapped[prefix]: - not_mapped[prefix].remove(name) + if PD[prefix] in not_mapped: + while ND[name] in not_mapped[PD[prefix]]: + not_mapped[PD[prefix]].remove(ND[name]) else: if mapname not in mapped: mapped[mapname] = list() - mapped[mapname].append(attr[name]) + mapped[mapname].append(attr[ND[name]]) if not_mapped: - if prefix in not_mapped: - del not_mapped[prefix] + if PD[prefix] in not_mapped: + del not_mapped[PD[prefix]] else: - mapin = copy.deepcopy(attr[name]) + mapin = copy.deepcopy(attr[ND[name]]) if mapname == '*': - mapname = name + mapname = ND[name] if mapprefix: if mapprefix not in mapped: mapped[mapprefix] = dict() @@ -131,11 +163,11 @@ class Policy(Log): mapped.update({mapname: mapin}) if not_mapped: if prefix: - if prefix in not_mapped: - if name in not_mapped[prefix]: - del not_mapped[prefix][name] - elif name in not_mapped: - del not_mapped[name] + if PD[prefix] in not_mapped: + if ND[name] in not_mapped[PD[prefix]]: + del not_mapped[PD[prefix]][ND[name]] + elif ND[name] in not_mapped: + del not_mapped[ND[name]] elif name == '*': mapin = copy.deepcopy(attr) # mapname is ignored if name == '*' @@ -147,8 +179,8 @@ class Policy(Log): else: mapped.update(mapin) if not_mapped: - if prefix in not_mapped: - del not_mapped[prefix] + if prefix and PD[prefix] in not_mapped: + del not_mapped[PD[prefix]] else: not_mapped = None else: @@ -316,4 +348,49 @@ if __name__ == '__main__': ret += 1 print 'Expected %s\nObtained %s' % (f2_result, f) + # Case Insensitive matching + tci_attributes = {'oneNameone': 'onevalueone', + 'onenamEtwo': 'onevaluetwo', + 'Two': {'twonameone': 'twovalueone', + 'twonameTwo': 'twovaluetwo'}, + 'thrEE': {'threeNAMEone': 'threevalueone', + 'thrEEnametwo': 'threevaluetwo'}, + 'foUr': {'fournameone': 'fourvalueone', + 'fournametwo': 'fourvaluetwo'}, + 'FIVE': ['one', 'two', 'three'], + 'six': ['ONE', 'two', 'three']} + + tci_mappings = [[['onenameone'], 'onemappedone'], + [['onenametwo'], 'onemappedtwo'], + [['two', '*'], '*'], + [['three', 'threenameone'], 'threemappedone'], + [['three', 'threenameone'], 'threemappedbis'], + [['four', '*'], ['Four', '*']], + [['five'], 'listfive'], + [['six', 'one'], ['six', 'mapone']]] + + mci_result = {'onemappedone': 'onevalueone', + 'onemappedtwo': 'onevaluetwo', + 'twonameone': 'twovalueone', + 'twonameTwo': 'twovaluetwo', + 'threemappedone': 'threevalueone', + 'threemappedbis': 'threevalueone', + 'Four': {'fournameone': 'fourvalueone', + 'fournametwo': 'fourvaluetwo'}, + 'listfive': ['one', 'two', 'three'], + 'six': ['mapone']} + + nci_result = {'thrEE': {'thrEEnametwo': 'threevaluetwo'}, + 'six': ['two', 'three']} + + p = Policy(tci_mappings) + print 'Case insensitive attribute mapping' + m, n = p.map_attributes(tci_attributes, ignore_case=True) + if m == mci_result and n == nci_result: + print 'SUCCESS' + else: + ret += 1 + print 'FAIL: Expected %s // %s\nObtained %s // %s' % \ + (mci_result, nci_result, m, n) + sys.exit(ret) |