def parse_federation_registration_response(self, resp, **kwargs): """ Receives a dynamic client registration response, :param resp: An entity statement instance :return: A set of metadata claims """ _sc = self.service_context _fe = _sc.federation_entity # Can not collect trust chain. Have to verify the signed JWT with keys I have kj = self.service_context.federation_entity.keyjar _jwt = factory(resp) entity_statement = _jwt.verify_compact(resp, keys=kj.get_jwt_verify_keys( _jwt.jwt)) _trust_anchor_id = self.get_trust_anchor_id(entity_statement) chosen = None for op_statement in _fe.op_statements: if op_statement.fo == _trust_anchor_id: chosen = op_statement break if not chosen: raise ValueError('No matching federation operator') # based on the Federation ID, conclude which OP config to use op_claims = chosen.metadata # _sc.trust_path = (chosen.fo, _fe.op_paths[statement.fo][0]) _sc.provider_info = self.response_cls(**op_claims) # To create RPs metadata collect the trust chains tree = {} for ah in _fe.authority_hints: tree[ah] = _fe.collector.collect_intermediate(_fe.entity_id, ah) _node = {_fe.entity_id: (resp, tree)} chains = branch2lists(_node) # Get the policies policy_chains_tup = [ eval_policy_chain(c, _fe.keyjar, _fe.entity_type) for c in chains ] _policy = combine_policy( policy_chains_tup[0][1], entity_statement['metadata_policy'][_fe.entity_type]) logger.debug("Combined policy: {}".format(_policy)) _uev = unverified_entity_statement(kwargs["request_body"]) logger.debug("Registration request: {}".format(_uev)) _query = _uev["metadata"][_fe.entity_type] _sc.registration_response = apply_policy(_query, _policy) return _sc.registration_response
def map_configuration_to_preference(provider_configuration, client_preference): """ Given a provider configuration and client registration attribute preferences initiate a ClientRegistration class. :param provider_configuration: A ProviderConfigurationResponse :param client_preference: An dictionary with client preferences :return: A ClientRegistration instance """ _allowed = translate_configuration(provider_configuration) args = apply_policy(client_preference, _allowed) return list_to_singleton(args, RegistrationRequest)
def eval_chain(chain, key_jar, entity_type, apply_policies=True): """ :param chain: A chain of entity statements :param key_jar: A :py:class:`cryptojwt.key_jar.KeyJar` instance :param entity_type: Which type of metadata you want returned :param apply_policies: Apply policies to the metadata or not :returns: A TrustChain instances """ logger.debug("Evaluate trust chain") ves = verify_trust_chain(chain, key_jar) if not ves: return None tp_exp = trust_chain_expires_at(ves) statement = TrustChain(exp=tp_exp, verified_chain=ves) if apply_policies: if len(ves) > 1: # Combine the metadata policies from the trust root and all intermediates combined_policy = gather_policies(ves[:-1], entity_type) logger.debug("Combined policy: %s", combined_policy) try: metadata = ves[-1]['metadata'][entity_type] except KeyError: statement.metadata = None else: # apply the combined metadata policies on the metadata statement.metadata = apply_policy(metadata, combined_policy) logger.debug("After applied policy: %s", statement.metadata) statement.combined_policy = combined_policy else: statement.metadata = ves[0]["metadata"][entity_type] statement.combined_policy = {} else: # accept what ever is in the statement provided by the leaf entity statement.metadata = ves[-1] iss_path = [x['iss'] for x in ves] statement.anchor = iss_path[0] iss_path.reverse() statement.iss_path = iss_path return statement
def test_apply_policies(): comb_policy = combine_policy(FED1, ORG1) res = apply_policy(RP, comb_policy) assert set(res.keys()) == set(RES1.keys()) for claim, value in res.items(): if isinstance(value, list): if isinstance(RES1[claim], list): assert set(value) == set(RES1[claim]) else: assert set(value) == {RES1[claim]} else: if isinstance(RES1[claim], list): assert {value} == set(RES1[claim]) else: assert value == RES1[claim]
def parse_federation_registration_response(self, resp, **kwargs): """ Receives a dynamic client registration response, :param resp: An entity statement instance :return: A set of metadata claims """ _context = self.client_get("service_context") _fe = _context.federation_entity _fe_ctx = _fe.context # Can not collect trust chain. Have to verify the signed JWT with keys I have kj = _fe_ctx.keyjar _jwt = factory(resp) entity_statement = _jwt.verify_compact(resp, keys=kj.get_jwt_verify_keys(_jwt.jwt)) _trust_anchor_id = self.get_trust_anchor_id(entity_statement) logger.debug("trust_anchor_id: {}".format(_trust_anchor_id)) chosen = None for op_statement in _fe_ctx.op_statements: if op_statement.anchor == _trust_anchor_id: chosen = op_statement break if not chosen: raise ValueError('No matching federation operator') # based on the Federation ID, conclude which OP config to use op_claims = chosen.metadata logger.debug("OP claims: {}".format(op_claims)) # _sc.trust_path = (chosen.anchor, _fe.op_paths[statement.anchor][0]) _context.provider_info = ProviderConfigurationResponse(**op_claims) # To create RPs metadata collect the trust chains tree = {} for ah in _fe_ctx.authority_hints: tree[ah] = _fe.collector.collect_intermediate(_fe_ctx.entity_id, ah) _node = {_fe_ctx.entity_id: (resp, tree)} chains = branch2lists(_node) logger.debug("%d chains", len(chains)) logger.debug("Evaluate policy chains") # Get the policies policy_chains_tup = [eval_policy_chain(c, _fe_ctx.keyjar, _fe_ctx.entity_type) for c in chains] # Weed out unusable chains policy_chains_tup = [pct for pct in policy_chains_tup if pct is not None] # Should leave me with one. The one ending in the chosen trust anchor. policy_chains_tup = [pct for pct in policy_chains_tup if pct[0] == _trust_anchor_id] if policy_chains_tup == []: logger.warning("No chain that ends in chosen trust anchor (%s)", _trust_anchor_id) raise ValueError("No trust chain that ends in chosen trust anchor (%s)", _trust_anchor_id) _policy = combine_policy(policy_chains_tup[0][1], entity_statement['metadata_policy'][_fe_ctx.entity_type]) logger.debug("Effective policy: {}".format(_policy)) _req = kwargs.get("request") if _req is None: _req = kwargs.get("request_body") _uev = unverified_entity_statement(_req) logger.debug("Registration request: {}".format(_uev)) _query = _uev["metadata"][_fe_ctx.entity_type] _resp = apply_policy(_query, _policy) _context.set("registration_response", _resp) return _resp