# (c) 2009-2024 Martin Wendt and contributors; see WsgiDAV https://github.com/mar10/wsgidav# Original PyFileServer (c) 2005 Ho Chun Wei.# Licensed under the MIT license:# http://www.opensource.org/licenses/mit-license.php"""Implementation of a domain controller that uses realm/user_name/password mappingsfrom the configuration file and uses the share path as realm name.user_mapping is defined a follows:: simple_dc: { user_mapping = { "realm1": { "John Smith": { "password": "YouNeverGuessMe", }, "Dan Brown": { "password": "DontGuessMeEither", "roles": ["editor"] } }, "realm2": { ... } }, }The "*" pseudo-share is used to pass a default definition:: user_mapping = { "*": { // every share except for 'realm2' "Dan Brown": { "password": "DontGuessMeEither", "roles": ["editor"] } }, "realm2": { ... } },A share (even the "*" pseudo-share) can be set to True to allow anonymous access:: user_mapping = { "*": { "Dan Brown": { "password": "DontGuessMeEither", "roles": ["editor"] }, }, "realm2": True },The SimpleDomainController fulfills the requirements of a DomainController asused for authentication with http_authenticator.HTTPAuthenticator for theWsgiDAV application.Domain Controllers must provide the methods as described inDomainControllerBase_.. _DomainControllerBase : dc/base_dc.py"""fromwsgidavimportutilfromwsgidav.dc.base_dcimportBaseDomainController__docformat__="reStructuredText"_logger=util.get_module_logger(__name__)
[docs]classSimpleDomainController(BaseDomainController):def__init__(self,wsgidav_app,config):super().__init__(wsgidav_app,config)dc_conf=util.get_dict_value(config,"simple_dc",as_dict=True)self.user_map=dc_conf.get("user_mapping")ifself.user_mapisNone:raiseRuntimeError("Missing option: simple_dc.user_mapping")forshare,datainself.user_map.items():iftype(data)notin(bool,dict)ornotdata:raiseRuntimeError(f"Invalid option: simple_dc.user_mapping[{share!r}]: must be True or non-empty dict.")returndef__str__(self):returnf"{self.__class__.__name__}()"def_get_realm_entry(self,realm,user_name=None):"""Return the matching user_map entry (falling back to default '*' if any)."""realm_entry=self.user_map.get(realm)ifrealm_entryisNone:realm_entry=self.user_map.get("*")ifuser_nameisNoneorrealm_entryisNone:returnrealm_entryreturnrealm_entry.get(user_name)
[docs]defget_domain_realm(self,path_info,environ):"""Resolve a relative url to the appropriate realm name."""realm=self._calc_realm_from_path_provider(path_info,environ)returnrealm
[docs]defrequire_authentication(self,realm,environ):"""Return True if this realm requires authentication (grant anonymous access otherwise)."""realm_entry=self._get_realm_entry(realm)ifrealm_entryisNone:_logger.error(f'Missing configuration simple_dc.user_mapping["{realm}"] (or "*"): '"realm is not accessible!")returnrealm_entryisnotTrue
[docs]defbasic_auth_user(self,realm,user_name,password,environ):"""Returns True if this user_name/password pair is valid for the realm, False otherwise. Used for basic authentication."""user=self._get_realm_entry(realm,user_name)ifuserisnotNoneandpassword==user.get("password"):environ["wsgidav.auth.roles"]=user.get("roles",[])returnTruereturnFalse
[docs]defsupports_http_digest_auth(self):# We have access to a plaintext password (or stored hash)returnTrue