def _listener_http(self, config, listener_config): port = listener_config["port"] bind_addresses = listener_config["bind_addresses"] tls = listener_config.get("tls", False) site_tag = listener_config.get("tag", port) resources = {} for res in listener_config["resources"]: for name in res["names"]: if name == "openid" and "federation" in res["names"]: # Skip loading openid resource if federation is defined # since federation resource will include openid continue resources.update( self._configure_named_resource(name, res.get("compress", False))) additional_resources = listener_config.get("additional_resources", {}) logger.debug("Configuring additional resources: %r", additional_resources) module_api = ModuleApi(self, self.get_auth_handler()) for path, resmodule in additional_resources.items(): handler_cls, config = load_module(resmodule) handler = handler_cls(config, module_api) if IResource.providedBy(handler): resource = handler elif hasattr(handler, "handle_request"): resource = AdditionalResource(self, handler.handle_request) else: raise ConfigError( "additional_resource %s does not implement a known interface" % (resmodule["module"], )) resources[path] = resource # try to find something useful to redirect '/' to if WEB_CLIENT_PREFIX in resources: root_resource = RootRedirect(WEB_CLIENT_PREFIX) elif STATIC_PREFIX in resources: root_resource = RootRedirect(STATIC_PREFIX) else: root_resource = NoResource() root_resource = create_resource_tree(resources, root_resource) if tls: ports = listen_ssl( bind_addresses, port, SynapseSite( "synapse.access.https.%s" % (site_tag, ), site_tag, listener_config, root_resource, self.version_string, ), self.tls_server_context_factory, reactor=self.get_reactor(), ) logger.info("Synapse now listening on TCP port %d (TLS)", port) else: ports = listen_tcp( bind_addresses, port, SynapseSite( "synapse.access.http.%s" % (site_tag, ), site_tag, listener_config, root_resource, self.version_string, ), reactor=self.get_reactor(), ) logger.info("Synapse now listening on TCP port %d", port) return ports
def get_module_api(self) -> ModuleApi: return ModuleApi(self, self.get_auth_handler())
def __init__(self, hs): """ Args: hs (synapse.server.HomeServer): """ super(AuthHandler, self).__init__(hs) self.checkers = {} # type: Dict[str, UserInteractiveAuthChecker] for auth_checker_class in INTERACTIVE_AUTH_CHECKERS: inst = auth_checker_class(hs) if inst.is_enabled(): self.checkers[inst.AUTH_TYPE] = inst # type: ignore self.bcrypt_rounds = hs.config.bcrypt_rounds account_handler = ModuleApi(hs, self) self.password_providers = [ module(config=config, account_handler=account_handler) for module, config in hs.config.password_providers ] logger.info("Extra password_providers: %r", self.password_providers) self.hs = hs # FIXME better possibility to access registrationHandler later? self.macaroon_gen = hs.get_macaroon_generator() self._password_enabled = hs.config.password_enabled self._sso_enabled = (hs.config.cas_enabled or hs.config.saml2_enabled or hs.config.oidc_enabled) # we keep this as a list despite the O(N^2) implication so that we can # keep PASSWORD first and avoid confusing clients which pick the first # type in the list. (NB that the spec doesn't require us to do so and # clients which favour types that they don't understand over those that # they do are technically broken) login_types = [] if self._password_enabled: login_types.append(LoginType.PASSWORD) for provider in self.password_providers: if hasattr(provider, "get_supported_login_types"): for t in provider.get_supported_login_types().keys(): if t not in login_types: login_types.append(t) self._supported_login_types = login_types # Login types and UI Auth types have a heavy overlap, but are not # necessarily identical. Login types have SSO (and other login types) # added in the rest layer, see synapse.rest.client.v1.login.LoginRestServerlet.on_GET. ui_auth_types = login_types.copy() if self._sso_enabled: ui_auth_types.append(LoginType.SSO) self._supported_ui_auth_types = ui_auth_types # Ratelimiter for failed auth during UIA. Uses same ratelimit config # as per `rc_login.failed_attempts`. self._failed_uia_attempts_ratelimiter = Ratelimiter( clock=self.clock, rate_hz=self.hs.config.rc_login_failed_attempts.per_second, burst_count=self.hs.config.rc_login_failed_attempts.burst_count, ) self._clock = self.hs.get_clock() # Expire old UI auth sessions after a period of time. if hs.config.worker_app is None: self._clock.looping_call( run_as_background_process, 5 * 60 * 1000, "expire_old_sessions", self._expire_old_sessions, ) # Load the SSO HTML templates. # The following template is shown to the user during a client login via SSO, # after the SSO completes and before redirecting them back to their client. # It notifies the user they are about to give access to their matrix account # to the client. self._sso_redirect_confirm_template = load_jinja2_templates( hs.config.sso_template_dir, ["sso_redirect_confirm.html"], )[0] # The following template is shown during user interactive authentication # in the fallback auth scenario. It notifies the user that they are # authenticating for an operation to occur on their account. self._sso_auth_confirm_template = load_jinja2_templates( hs.config.sso_template_dir, ["sso_auth_confirm.html"], )[0] # The following template is shown after a successful user interactive # authentication session. It tells the user they can close the window. self._sso_auth_success_template = hs.config.sso_auth_success_template # The following template is shown during the SSO authentication process if # the account is deactivated. self._sso_account_deactivated_template = ( hs.config.sso_account_deactivated_template) self._server_name = hs.config.server_name # cast to tuple for use with str.startswith self._whitelisted_sso_clients = tuple(hs.config.sso_client_whitelist)
def __init__(self, config, api: ModuleApi): api.register_password_auth_provider_callbacks(auth_checkers={ ("test.login_type", ("test_field", )): self.check_auth }, )