def filter_on_demands(ava, required=None, optional=None): """ Never return more than is needed. Filters out everything the server is prepared to return but the receiver doesn't ask for :param ava: Attribute value assertion as a dictionary :param required: Required attributes :param optional: Optional attributes :return: The possibly reduced assertion """ # Is all what's required there: if required is None: required = {} for attr, vals in required.items(): if attr in ava: if vals: for val in vals: if val not in ava[attr]: raise MissingValue( "Required attribute value missing: %s,%s" % (attr, val)) else: raise MissingValue("Required attribute missing: %s" % (attr,)) if optional is None: optional = {} # OK, so I can imaging releasing values that are not absolutely necessary # but not attributes for attr, vals in ava.items(): if attr not in required and attr not in optional: del ava[attr] return ava
def _filter_values(vals, vlist=None, must=False): """ Removes values from *vals* that does not appear in vlist :param vals: The values that are to be filtered :param vlist: required or optional value :param must: Whether the allowed values must appear :return: The set of values after filtering """ if not vlist: # No value specified equals any value return vals if isinstance(vlist, basestring): vlist = [vlist] res = [] for val in vlist: if val in vals: res.append(val) if must: if res: return res else: raise MissingValue("Required attribute value missing") else: return res
def filter_on_attributes(ava, required=None, optional=None): """ Filter :param ava: An attribute value assertion as a dictionary :param required: list of RequestedAttribute instances defined to be required :param optional: list of RequestedAttribute instances defined to be optional :return: The modified attribute value assertion """ res = {} if required is None: required = [] for attr in required: found = False nform = "" for nform in ["friendly_name", "name"]: try: _fn = _match(attr[nform], ava) except KeyError: pass else: if _fn: try: values = [av["text"] for av in attr["attribute_value"]] except KeyError: values = [] res[_fn] = _filter_values(ava[_fn], values, True) found = True break if not found: raise MissingValue("Required attribute missing: '%s'" % (attr[nform], )) if optional is None: optional = [] for attr in optional: for nform in ["friendly_name", "name"]: if nform in attr: _fn = _match(attr[nform], ava) if _fn: try: values = [av["text"] for av in attr["attribute_value"]] except KeyError: values = [] try: res[_fn].extend(_filter_values(ava[_fn], values)) except KeyError: res[_fn] = _filter_values(ava[_fn], values) return res
def filter_on_demands(ava, required=None, optional=None): """ Never return more than is needed. Filters out everything the server is prepared to return but the receiver doesn't ask for :param ava: Attribute value assertion as a dictionary :param required: Required attributes :param optional: Optional attributes :return: The possibly reduced assertion """ # Is all what's required there: if required is None: required = {} lava = dict([(k.lower(), k) for k in list(ava.keys())]) for attr, vals in list(required.items()): attr = attr.lower() if attr in lava: if vals: for val in vals: if val not in ava[lava[attr]]: raise MissingValue( "Required attribute value missing: %s,%s" % (attr, val)) else: raise MissingValue("Required attribute missing: %s" % (attr, )) if optional is None: optional = {} oka = [k.lower() for k in list(required.keys())] oka.extend([k.lower() for k in list(optional.keys())]) # OK, so I can imaging releasing values that are not absolutely necessary # but not attributes that are not asked for. for attr in list(lava.keys()): if attr not in oka: del ava[lava[attr]] return ava
def _get_vo_identifier(self, sp_name_qualifier, identity): try: vo = self.voconf[sp_name_qualifier] try: subj_id = identity[vo.common_identifier] except KeyError: raise MissingValue("Common identifier") except (KeyError, TypeError): raise UnknownVO("%s" % sp_name_qualifier) nameid_format = vo.nameid_format if not nameid_format: nameid_format = saml.NAMEID_FORMAT_PERSISTENT return saml.NameID(format=nameid_format, sp_name_qualifier=sp_name_qualifier, text=subj_id)
def filter_on_attributes(ava, required=None, optional=None): """ Filter :param ava: An attribute value assertion as a dictionary :param required: list of RequestedAttribute instances defined to be required :param optional: list of RequestedAttribute instances defined to be optional :return: The modified attribute value assertion """ res = {} if required is None: required = [] for attr in required: if attr.friendly_name in ava: values = [av.text for av in attr.attribute_value] res[attr.friendly_name] = _filter_values(ava[attr.friendly_name], values, True) elif attr.name in ava: values = [av.text for av in attr.attribute_value] res[attr.name] = _filter_values(ava[attr.name], values, True) else: print >> sys.stderr, ava.keys() raise MissingValue("Required attribute missing: '%s'" % (attr.friendly_name,)) if optional is None: optional = [] for attr in optional: if attr.friendly_name in ava: values = [av.text for av in attr.attribute_value] try: res[attr.friendly_name].extend(_filter_values(ava[attr.friendly_name], values)) except KeyError: res[attr.friendly_name] = _filter_values(ava[attr.friendly_name], values) elif attr.name in ava: values = [av.text for av in attr.attribute_value] try: res[attr.name].extend(_filter_values(ava[attr.name], values)) except KeyError: res[attr.name] = _filter_values(ava[attr.name], values) return res
def _get_vo_identifier(self, sp_name_qualifier, userid, identity): try: vo_conf = self.voconf[sp_name_qualifier] if "common_identifier" in vo_conf: try: subj_id = identity[vo_conf["common_identifier"]] except KeyError: raise MissingValue("Common identifier") else: return self.persistent_nameid(sp_name_qualifier, userid) except (KeyError, TypeError): raise UnknownVO("%s" % sp_name_qualifier) try: nameid_format = vo_conf["nameid_format"] except KeyError: nameid_format = saml.NAMEID_FORMAT_PERSISTENT return saml.NameID(format=nameid_format, sp_name_qualifier=sp_name_qualifier, text=subj_id)
def filter_on_attributes(ava, required=None, optional=None, acs=None, fail_on_unfulfilled_requirements=True): """ Filter :param ava: An attribute value assertion as a dictionary :param required: list of RequestedAttribute instances defined to be required :param optional: list of RequestedAttribute instances defined to be optional :param fail_on_unfulfilled_requirements: If required attributes are missing fail or fail not depending on this parameter. :return: The modified attribute value assertion """ res = {} if required is None: required = [] nform = "friendly_name" for attr in required: try: _name = attr[nform] except KeyError: if nform == "friendly_name": _name = get_local_name(acs, attr["name"], attr["name_format"]) else: continue _fn = _match(_name, ava) if not _fn: # In the unlikely case that someone has provided us # with URIs as attribute names _fn = _match(attr["name"], ava) if _fn: try: values = [av["text"] for av in attr["attribute_value"]] except KeyError: values = [] res[_fn] = _filter_values(ava[_fn], values, True) continue elif fail_on_unfulfilled_requirements: desc = "Required attribute missing: '%s' (%s)" % (attr["name"], _name) raise MissingValue(desc) if optional is None: optional = [] for attr in optional: for nform in ["friendly_name", "name"]: if nform in attr: _fn = _match(attr[nform], ava) if _fn: try: values = [av["text"] for av in attr["attribute_value"]] except KeyError: values = [] try: res[_fn].extend(_filter_values(ava[_fn], values)) except KeyError: res[_fn] = _filter_values(ava[_fn], values) return res
def filter_on_attributes(ava, required=None, optional=None, acs=None, fail_on_unfulfilled_requirements=True): """ Filter :param ava: An attribute value assertion as a dictionary :param required: list of RequestedAttribute instances defined to be required :param optional: list of RequestedAttribute instances defined to be optional :param fail_on_unfulfilled_requirements: If required attributes are missing fail or fail not depending on this parameter. :return: The modified attribute value assertion """ def _match_attr_name(attr, ava): local_name = None for a in ['name_format', 'friendly_name']: _val = attr.get(a) if _val: if a == 'name_format': local_name = get_local_name(acs, attr['name'], _val) else: local_name = _val break if local_name: _fn = _match(local_name, ava) else: _fn = None if not _fn: # In the unlikely case that someone has provided us with # URIs as attribute names _fn = _match(attr["name"], ava) return _fn def _apply_attr_value_restrictions(attr, res, must=False): values = [av["text"] for av in attr.get("attribute_value", [])] try: res[_fn].extend(_filter_values(ava[_fn], values)) except KeyError: # ignore duplicate RequestedAttribute entries val = _filter_values(ava[_fn], values) res[_fn] = val if val is not None else [] return _filter_values(ava[_fn], values, must) res = {} if required is None: required = [] for attr in required: _fn = _match_attr_name(attr, ava) if _fn: _apply_attr_value_restrictions(attr, res, True) elif fail_on_unfulfilled_requirements: desc = "Required attribute missing: '%s'" % (attr["name"]) raise MissingValue(desc) if optional is None: optional = [] for attr in optional: _fn = _match_attr_name(attr, ava) if _fn: _apply_attr_value_restrictions(attr, res, False) return res
def filter_on_attributes(ava, required=None, optional=None, acs=None, fail_on_unfulfilled_requirements=True): """ Filter :param ava: An attribute value assertion as a dictionary :param required: list of RequestedAttribute instances defined to be required :param optional: list of RequestedAttribute instances defined to be optional :param fail_on_unfulfilled_requirements: If required attributes are missing fail or fail not depending on this parameter. :return: The modified attribute value assertion """ def _match_attr_name(attr, ava): local_name = get_local_name(acs, attr["name"], attr["name_format"]) if not local_name: try: local_name = attr["friendly_name"] except KeyError: pass _fn = _match(local_name, ava) if not _fn: # In the unlikely case that someone has provided us with # URIs as attribute names _fn = _match(attr["name"], ava) return _fn def _apply_attr_value_restrictions(attr, res, must=False): try: values = [av["text"] for av in attr["attribute_value"]] except KeyError: values = [] try: res[_fn].extend(_filter_values(ava[_fn], values)) except KeyError: res[_fn] = _filter_values(ava[_fn], values) return _filter_values(ava[_fn], values, must) res = {} if required is None: required = [] for attr in required: _fn = _match_attr_name(attr, ava) if _fn: _apply_attr_value_restrictions(attr, res, True) elif fail_on_unfulfilled_requirements: desc = "Required attribute missing: '%s' (%s)" % (attr["name"], _fn) raise MissingValue(desc) if optional is None: optional = [] for attr in optional: _fn = _match_attr_name(attr, ava) if _fn: _apply_attr_value_restrictions(attr, res, False) return res