def render_consent(self, consent_state, internal_response, language='en'): requester_name = consent_state.get('requester_display_name', None) if not requester_name: requester_name = self._find_requester_name( internal_response.requester, language) requester_logo = consent_state.get('requester_logo', None) gettext.translation('messages', localedir=pkg_resources.resource_filename( 'svs', 'data/i18n/locale'), languages=[language]).install() released_attributes = self._attributes_to_release(internal_response) template = self.template_lookup.get_template('consent.mako') page = template.render( requester_name=requester_name, requester_logo=self._normalize_logo(requester_logo), privacy_url=self.privacy_url, released_claims=released_attributes, form_action='/consent{}'.format(self.endpoint), language=language) page = Template(page).render( requester_name=requester_name, requester_logo=self._normalize_logo(requester_logo), privacy_url=self.privacy_url, released_claims=released_attributes, form_action='/consent{}'.format(self.endpoint), language=language) satosa_logging(logger, logging.INFO, "released attributes: {}".format(released_attributes), consent_state) return Response(page, content='text/html')
def handle_error( self, message: str, troubleshoot: str = "", err="", template_path="templates", error_template="spid_login_error.html", ): """ Todo: Jinja2 tempalte loader and rendering :) """ logger.error(f"Failed to parse authn request: {message} {err}") result = self.error_page.render({ "message": message, "troubleshoot": troubleshoot }) # the raw way :) # msg = ( # f'<b>{message}</b><br>' # f'{troubleshoot}' # ) # result = text_type(msg).encode('utf-8') return Response(result, content="text/html; charset=utf8", status="403")
def ping_endpoint(self, context): """ """ msg = "Ping returning 200 OK" logline = lu.LOG_FMT.format(id=lu.get_session_id(context.state), message=msg) logger.debug(logline) msg = " " return Response(msg)
def ping_endpoint(self, context): """ """ logprefix = PingFrontend.logprefix satosa_logging(logger, logging.DEBUG, "{} ping returning 200 OK".format(logprefix), context.state) msg = " " return Response(msg)
def _metadata_endpoint(self, context): """ Endpoint for retrieving the backend metadata :type context: satosa.context.Context :rtype: satosa.response.Response :param context: The current context :return: response with metadata """ logger.debug("Sending metadata response") conf = self.sp.config metadata = entity_descriptor(conf) # creare gli attribute_consuming_service cnt = 0 for (attribute_consuming_service ) in metadata.spsso_descriptor.attribute_consuming_service: attribute_consuming_service.index = str(cnt) cnt += 1 cnt = 0 for (assertion_consumer_service ) in metadata.spsso_descriptor.assertion_consumer_service: assertion_consumer_service.is_default = "true" if not cnt else "" assertion_consumer_service.index = str(cnt) cnt += 1 # nameformat patch... tutto questo non rispecchia gli standard OASIS for reqattr in metadata.spsso_descriptor.attribute_consuming_service[ 0].requested_attribute: reqattr.name_format = None reqattr.friendly_name = None # attribute consuming service service name patch service_name = metadata.spsso_descriptor.attribute_consuming_service[ 0].service_name[0] service_name.lang = "it" service_name.text = metadata.entity_id # remove extension disco and uuinfo (spid-testenv2) # metadata.spsso_descriptor.extensions = [] # load ContactPerson Extensions self._metadata_contact_person(metadata, conf) # metadata signature secc = security_context(conf) # sign_dig_algs = self.get_kwargs_sign_dig_algs() eid, xmldoc = sign_entity_descriptor(metadata, None, secc, **sign_dig_algs) valid_instance(eid) return Response(text_type(xmldoc).encode("utf-8"), content="text/xml; charset=utf8")
def _reload_metadata(self, context): """ Reload SAML metadata """ logger.debug("Reloading metadata") res = self.sp.reload_metadata( copy.deepcopy(self.config[SAMLBackend.KEY_SP_CONFIG]['metadata']) ) message = "Metadata reload %s" % ("OK" if res else "failed") status = "200 OK" if res else "500 FAILED" return Response(message=message, status=status)
def render_consent(self, internal_response, language='en'): requester_name = self._find_requester_name(internal_response.requester, language) gettext.translation('messages', localedir=pkg_resources.resource_filename('svs', 'data/i18n/locale'), languages=[language]).install() released_attributes = self._attributes_to_release(internal_response) template = self.template_lookup.get_template('consent.mako') page = template.render(client_name=requester_name, released_attributes=released_attributes, form_action='/consent{}'.format(self.endpoint), language=language) return Response(page, content='text/html')
def _metadata_endpoint(self, context): """ Endpoint for retrieving the backend metadata :type context: satosa.context.Context :rtype: satosa.response.Response :param context: The current context :return: response with metadata """ satosa_logging(logger, logging.DEBUG, "Sending metadata response", context.state) metadata_string = create_metadata_string(None, self.sp.config, 4, None, None, None, None, None).decode("utf-8") return Response(metadata_string, content="text/xml")
def _metadata_endpoint(self, context): """ Endpoint for retrieving the backend metadata :type context: satosa.context.Context :rtype: satosa.response.Response :param context: The current context :return: response with metadata """ msg = "Sending metadata response for entityId = {}".format(self.sp.config.entityid) logline = lu.LOG_FMT.format(id=lu.get_session_id(context.state), message=msg) logger.debug(logline) metadata_string = create_metadata_string(None, self.sp.config, 4, None, None, None, None, None).decode("utf-8") return Response(metadata_string, content="text/xml")
def handle_authn_response(self, context, internal_resp): return Response("Auth response received, passed to test frontend")
def start_auth(self, context, internal_request): return Response("Auth request received, passed to test backend")
def _metadata_endpoint(self, context): """ Endpoint for retrieving the backend metadata :type context: satosa.context.Context :rtype: satosa.response.Response :param context: The current context :return: response with metadata """ logger.debug("Sending metadata response") conf = self.sp.config metadata = entity_descriptor(conf) # creare gli attribute_consuming_service cnt = 0 for attribute_consuming_service in metadata.spsso_descriptor.attribute_consuming_service: attribute_consuming_service.index = str(cnt) cnt += 1 cnt = 0 for assertion_consumer_service in metadata.spsso_descriptor.assertion_consumer_service: assertion_consumer_service.is_default = 'true' if not cnt else '' assertion_consumer_service.index = str(cnt) cnt += 1 # nameformat patch... tutto questo non rispecchia gli standard OASIS for reqattr in metadata.spsso_descriptor.attribute_consuming_service[ 0].requested_attribute: reqattr.name_format = None reqattr.friendly_name = None # attribute consuming service service name patch service_name = metadata.spsso_descriptor.attribute_consuming_service[ 0].service_name[0] service_name.lang = 'it' service_name.text = metadata.entity_id # remove extension disco and uuinfo (spid-testenv2) #metadata.spsso_descriptor.extensions = [] ############## # avviso 29 v3 # # https://www.agid.gov.it/sites/default/files/repository_files/spid-avviso-n29v3-specifiche_sp_pubblici_e_privati_0.pdf # Avviso 29v3 SPID_PREFIXES = dict(spid="https://spid.gov.it/saml-extensions", fpa="https://spid.gov.it/invoicing-extensions") saml2.md.SamlBase.register_prefix(SPID_PREFIXES) metadata.contact_person = [] contact_map = conf.contact_person cnt = 0 metadata.contact_person = [] for contact in contact_map: spid_contact = saml2.md.ContactPerson() spid_contact.contact_type = contact['contact_type'] contact_kwargs = { 'email_address': [contact['email_address']], 'telephone_number': [contact['telephone_number']] } if contact['contact_type'] == 'other': spid_contact.loadd(contact_kwargs) contact_kwargs['contact_type'] = contact['contact_type'] spid_extensions = saml2.ExtensionElement( 'Extensions', namespace='urn:oasis:names:tc:SAML:2.0:metadata') for k, v in contact.items(): if k in contact_kwargs: continue ext = saml2.ExtensionElement( k, namespace=SPID_PREFIXES['spid'], text=v) spid_extensions.children.append(ext) elif contact['contact_type'] == 'billing': contact_kwargs['company'] = contact['company'] spid_contact.loadd(contact_kwargs) spid_extensions = saml2.ExtensionElement( 'Extensions', namespace='urn:oasis:names:tc:SAML:2.0:metadata') elements = {} for k, v in contact.items(): if k in contact_kwargs: continue ext = saml2.ExtensionElement( k, namespace=SPID_PREFIXES['fpa'], text=v) elements[k] = ext # DatiAnagrafici IdFiscaleIVA = saml2.ExtensionElement( 'IdFiscaleIVA', namespace=SPID_PREFIXES['fpa'], ) Anagrafica = saml2.ExtensionElement( 'Anagrafica', namespace=SPID_PREFIXES['fpa'], ) Anagrafica.children.append(elements['Denominazione']) IdFiscaleIVA.children.append(elements['IdPaese']) IdFiscaleIVA.children.append(elements['IdCodice']) DatiAnagrafici = saml2.ExtensionElement( 'DatiAnagrafici', namespace=SPID_PREFIXES['fpa'], ) if elements.get('CodiceFiscale'): DatiAnagrafici.children.append(elements['CodiceFiscale']) DatiAnagrafici.children.append(IdFiscaleIVA) DatiAnagrafici.children.append(Anagrafica) CessionarioCommittente = saml2.ExtensionElement( 'CessionarioCommittente', namespace=SPID_PREFIXES['fpa'], ) CessionarioCommittente.children.append(DatiAnagrafici) # Sede Sede = saml2.ExtensionElement( 'Sede', namespace=SPID_PREFIXES['fpa'], ) Sede.children.append(elements['Indirizzo']) Sede.children.append(elements['NumeroCivico']) Sede.children.append(elements['CAP']) Sede.children.append(elements['Comune']) Sede.children.append(elements['Provincia']) Sede.children.append(elements['Nazione']) CessionarioCommittente.children.append(Sede) spid_extensions.children.append(CessionarioCommittente) spid_contact.extensions = spid_extensions metadata.contact_person.append(spid_contact) cnt += 1 # # fine avviso 29v3 ################### # metadata signature secc = security_context(conf) # sign_dig_algs = self.get_kwargs_sign_dig_algs() eid, xmldoc = sign_entity_descriptor(metadata, None, secc, **sign_dig_algs) valid_instance(eid) return Response(text_type(xmldoc).encode('utf-8'), content="text/xml; charset=utf8")
def test_constructor_adding_content_type_header(self): resp = Response("foo", content="bar") headers = dict(resp.headers) assert headers["Content-Type"] == "bar"
def test_call_should_always_return_flat_list_to_comply_with_wsgi( self, data, expected): resp = Response(data) assert resp({}, lambda x, y: None) == expected
def authn_request(self, context, entity_id, internal_req): """ Do an authorization request on idp with given entity id. This is the start of the authorization. :type context: satosa.context.Context :type entity_id: str :type internal_req: satosa.internal_data.InternalRequest :rtype: satosa.response.Response :param context: The curretn context :param entity_id: Target IDP entity id :param internal_req: The request :return: Response """ _cli = self.sp hash_type = UserIdHashType.persistent.name if "hash_type" in self.config: hash_type = self.config["hash_type"] req_args = {"name_id_policy": self.create_name_id_policy(hash_type)} state = context.state try: # Picks a binding to use for sending the Request to the IDP _binding, destination = _cli.pick_binding("single_sign_on_service", self.bindings, "idpsso", entity_id=entity_id) satosa_logging( LOGGER, logging.DEBUG, "binding: %s, destination: %s" % (_binding, destination), state) # Binding here is the response binding that is which binding the # IDP should use to return the response. acs = _cli.config.getattr("endpoints", "sp")["assertion_consumer_service"] # just pick one endp, return_binding = acs[0] req_id, req = _cli.create_authn_request(destination, binding=return_binding, **req_args) relay_state = rndstr() ht_args = _cli.apply_binding(_binding, "%s" % req, destination, relay_state=relay_state) satosa_logging(LOGGER, logging.DEBUG, "ht_args: %s" % ht_args, state) except Exception as exc: satosa_logging(LOGGER, logging.DEBUG, "Failed to construct the AuthnRequest for state", state, exc_info=True) raise SATOSAAuthenticationError( state, "Failed to construct the AuthnRequest") from exc state.add(self.state_id, relay_state) if _binding == BINDING_HTTP_REDIRECT: for param, value in ht_args["headers"]: if param == "Location": resp = SeeOther(str(value)) break else: satosa_logging(LOGGER, logging.DEBUG, "Parameter error for state", state) raise SATOSAAuthenticationError(state, "Parameter error") else: resp = Response(ht_args["data"], headers=ht_args["headers"]) return resp