Exemplo n.º 1
0
def _init_config():
    """Setup configuration dictionary from default, command line and configuration file."""
    cli_opts, parser = _init_command_line_options()
    cli_verbose = cli_opts["verbose"]

    # Set config defaults
    config = copy.deepcopy(DEFAULT_CONFIG)

    # Configuration file overrides defaults
    config_file = cli_opts.get("config_file")
    if config_file:
        file_opts = _read_config_file(config_file, cli_verbose)
        util.deep_update(config, file_opts)
        if cli_verbose != DEFAULT_VERBOSE and "verbose" in file_opts:
            if cli_verbose >= 2:
                print(
                    "Config file defines 'verbose: {}' but is overridden by command line: {}.".format(
                        file_opts["verbose"], cli_verbose
                    )
                )
            config["verbose"] = cli_verbose
    else:
        if cli_verbose >= 2:
            print("Running without configuration file.")

    # Command line overrides file
    if cli_opts.get("port"):
        config["port"] = cli_opts.get("port")
    if cli_opts.get("host"):
        config["host"] = cli_opts.get("host")
    if cli_opts.get("profile") is not None:
        config["profile"] = True
    if cli_opts.get("server") is not None:
        config["server"] = cli_opts.get("server")
    if cli_opts.get("ssl_adapter") is not None:
        config["ssl_adapter"] = cli_opts.get("ssl_adapter")

    # Command line overrides file only if -v or -q where passed:
    if cli_opts.get("verbose") != DEFAULT_VERBOSE:
        config["verbose"] = cli_opts.get("verbose")

    if cli_opts.get("root_path"):
        root_path = os.path.abspath(cli_opts.get("root_path"))
        config["provider_mapping"]["/"] = FilesystemProvider(root_path)

    if config["verbose"] >= 5:
        # TODO: remove passwords from user_mapping
        # config_cleaned = copy.deepcopy(config)
        print("Configuration({}):\n{}".format(cli_opts["config_file"], pformat(config)))

    if not config["provider_mapping"]:
        parser.error("No DAV provider defined.")

    # Quick-configuration of DomainController
    auth = cli_opts.get("auth")
    auth_conf = config.get("http_authenticator", {})
    if auth and auth_conf.get("domain_controller"):
        parser.error(
            "--auth option can only be used when no domain_controller is configured"
        )

    if auth == "anonymous":
        if config["simple_dc"]["user_mapping"]:
            parser.error(
                "--auth=anonymous can only be used when no user_mapping is configured"
            )
        auth_conf.update(
            {
                "domain_controller": "wsgidav.dc.simple_dc.SimpleDomainController",
                "accept_basic": True,
                "accept_digest": True,
                "default_to_digest": True,
            }
        )
        config["simple_dc"]["user_mapping"] = {"*": True}
    elif auth == "nt":
        if config.get("nt_dc"):
            parser.error(
                "--auth=nt can only be used when no nt_dc settings are configured"
            )
        auth_conf.update(
            {
                "domain_controller": "wsgidav.dc.nt_dc.NTDomainController",
                "accept_basic": True,
                "accept_digest": False,
                "default_to_digest": False,
            }
        )
        config["nt_dc"] = {}
    elif auth == "pam-login":
        if config.get("pam_dc"):
            parser.error(
                "--auth=pam-login can only be used when no pam_dc settings are configured"
            )
        auth_conf.update(
            {
                "domain_controller": "wsgidav.dc.pam_dc.PAMDomainController",
                "accept_basic": True,
                "accept_digest": False,
                "default_to_digest": False,
            }
        )
        config["pam_dc"] = {"service": "login"}
    # print(config)

    if cli_opts.get("reload"):
        print("Installing paste.reloader.", file=sys.stderr)
        from paste import reloader  # @UnresolvedImport

        reloader.install()
        if config_file:
            # Add config file changes
            reloader.watch_file(config_file)
        # import pydevd
        # pydevd.settrace()

    return config
Exemplo n.º 2
0
    def __init__(self, config):

        self.config = copy.deepcopy(DEFAULT_CONFIG)
        util.deep_update(self.config, config)
        config = self.config

        # Evaluate configuration and set defaults
        _check_config(config)

        self.verbose = config.get("verbose", 3)

        hotfixes = config.get("hotfixes", {})

        self.re_encode_path_info = hotfixes.get("re_encode_path_info", None)
        if self.re_encode_path_info is None:
            self.re_encode_path_info = compat.PY3

        self.unquote_path_info = hotfixes.get("unquote_path_info", False)

        lock_storage = config.get("lock_manager")
        if lock_storage is True:
            lock_storage = LockStorageDict()

        if not lock_storage:
            self.lock_manager = None
        else:
            self.lock_manager = LockManager(lock_storage)

        self.prop_manager = config.get("property_manager")
        if not self.prop_manager:
            # Normalize False, 0 to None
            self.prop_manager = None
        elif self.prop_manager is True:
            self.prop_manager = PropertyManager()

        self.mount_path = config.get("mount_path")
        auth_conf = config.get("http_authenticator", {})

        # Instantiate DAV resource provider objects for every share.
        # provider_mapping may contain the args that are passed to a
        # `FilesystemProvider` instance:
        #     <mount_path>: <folder_path>
        # or
        #     <mount_path>: { "root": <folder_path>, "readonly": True }
        # or contain a complete new instance:
        #     <mount_path>: <DAVProvider Instance>

        provider_mapping = self.config["provider_mapping"]

        self.provider_map = {}
        self.sorted_share_list = None
        for share, provider in provider_mapping.items():
            self.add_provider(share, provider)

        self.http_authenticator = None
        domain_controller = None

        # Define WSGI application stack
        middleware_stack = config.get("middleware_stack", [])
        mw_list = []

        # This is the 'outer' application, i.e. the WSGI application object that
        # is eventually called by the server.
        self.application = self

        # The `middleware_stack` is configured such that the first app in the
        # list should be called first. Since every app wraps its predecessor, we
        # iterate in reverse order:
        for mw in reversed(middleware_stack):
            # The middleware stack configuration may contain plain strings, dicts,
            # classes, or objects
            app = None
            if compat.is_basestring(mw):
                # If a plain string is passed, try to import it, assuming
                # `BaseMiddleware` signature
                app_class = dynamic_import_class(mw)
                app = app_class(self, self.application, config)
            elif type(mw) is dict:
                # If a dict with one entry is passed, use the key as module/class name
                # and the value as constructor arguments (positional or kwargs).
                assert len(mw) == 1
                name, args = list(mw.items())[0]
                expand = {"${application}": self.application}
                app = dynamic_instantiate_middleware(name, args, expand)
            elif inspect.isclass(mw):
                # If a class is passed, assume BaseMiddleware (or compatible)
                assert issubclass(
                    mw, BaseMiddleware
                )  # TODO: remove this assert with 3.0
                app = mw(self, self.application, config)
            else:
                # Otherwise assume an initialized middleware instance
                app = mw

            # Remember
            if isinstance(app, HTTPAuthenticator):
                self.http_authenticator = app
                domain_controller = app.get_domain_controller()

            # Add middleware to the stack
            if app:
                if callable(getattr(app, "is_disabled", None)) and app.is_disabled():
                    _logger.warning(
                        "App {}.is_disabled() returned True: skipping.".format(app)
                    )
                else:
                    mw_list.append(app)
                    self.application = app
            else:
                _logger.error("Could not add middleware {}.".format(mw))

        domain_controller
        # Print info
        _logger.info(
            "WsgiDAV/{} Python/{} {}".format(
                __version__, util.PYTHON_VERSION, platform.platform(aliased=True)
            )
        )
        if self.verbose >= 4:
            _logger.info(
                "Default encoding: {!r} (file system: {!r})".format(
                    sys.getdefaultencoding(), sys.getfilesystemencoding()
                )
            )

        if self.verbose >= 3:
            _logger.info("Lock manager:      {}".format(self.lock_manager))
            _logger.info("Property manager:  {}".format(self.prop_manager))
            _logger.info("Domain controller: {}".format(domain_controller))

        if self.verbose >= 4:
            # We traversed the stack in reverse order. Now revert again, so
            # we see the order that was configured:
            _logger.info("Middleware stack:")
            for mw in reversed(mw_list):
                _logger.info("  - {}".format(mw))

        if self.verbose >= 3:
            _logger.info("Registered DAV providers by route:")
            for share in self.sorted_share_list:
                provider = self.provider_map[share]
                hint = (
                    " (anonymous)"
                    if domain_controller.is_share_anonymous(share)
                    else ""
                )
                _logger.info("  - '{}': {}{}".format(share, provider, hint))

        if auth_conf.get("accept_basic") and not config.get("ssl_certificate"):
            _logger.warning(
                "Basic authentication is enabled: It is highly recommended to enable SSL."
            )

        if domain_controller:
            for share, provider in self.provider_map.items():
                if domain_controller.is_share_anonymous(share):
                    _logger.warning(
                        "Share '{}' will allow anonymous {} access.".format(
                            share, "read" if provider.is_readonly() else "write"
                        )
                    )
        return
Exemplo n.º 3
0
def _init_config():
    """Setup configuration dictionary from default, command line and configuration file."""
    cli_opts, parser = _init_command_line_options()
    cli_verbose = cli_opts["verbose"]

    # Set config defaults
    config = copy.deepcopy(DEFAULT_CONFIG)

    # Configuration file overrides defaults
    config_file = cli_opts.get("config_file")
    if config_file:
        file_opts = _read_config_file(config_file, cli_verbose)
        util.deep_update(config, file_opts)
        if cli_verbose != DEFAULT_VERBOSE and "verbose" in file_opts:
            if cli_verbose >= 2:
                print(
                    "Config file defines 'verbose: {}' but is overridden by command line: {}."
                    .format(file_opts["verbose"], cli_verbose))
            config["verbose"] = cli_verbose
    else:
        if cli_verbose >= 2:
            print("Running without configuration file.")

    # Command line overrides file
    if cli_opts.get("log_file"):
        log_file = cli_opts.get("log_file")
        config['log_file'] = log_file
    if cli_opts.get("port"):
        config["port"] = cli_opts.get("port")
    if cli_opts.get("host"):
        config["host"] = cli_opts.get("host")
    if cli_opts.get("profile") is not None:
        config["profile"] = True
    if cli_opts.get("server") is not None:
        config["server"] = cli_opts.get("server")
    if cli_opts.get("ssl_adapter") is not None:
        config["ssl_adapter"] = cli_opts.get("ssl_adapter")

    # Command line overrides file only if -v or -q where passed:
    if cli_opts.get("verbose") != DEFAULT_VERBOSE:
        config["verbose"] = cli_opts.get("verbose")

    if cli_opts.get("root_path"):
        root_path = os.path.abspath(cli_opts.get("root_path"))
        config["provider_mapping"]["/"] = FilesystemProvider(root_path)

    if config["verbose"] >= 5:
        # TODO: remove passwords from user_mapping
        # config_cleaned = copy.deepcopy(config)
        print("Configuration({}):\n{}".format(cli_opts["config_file"],
                                              pformat(config)))

    if not config["provider_mapping"]:
        parser.error("No DAV provider defined.")

    _loadSeafileSettings(config)

    pid_file = cli_opts.get("pidfile")
    if pid_file:
        pid_file = os.path.abspath(pid_file)
        config["pidfile"] = pid_file
    # Quick-configuration of DomainController
    auth = cli_opts.get("auth")
    auth_conf = config.get("http_authenticator", {})
    if auth and auth_conf.get("domain_controller"):
        parser.error(
            "--auth option can only be used when no domain_controller is configured"
        )

    if auth == "anonymous":
        if config["simple_dc"]["user_mapping"]:
            parser.error(
                "--auth=anonymous can only be used when no user_mapping is configured"
            )
        auth_conf.update({
            "domain_controller": "wsgidav.dc.simple_dc.SimpleDomainController",
            "accept_basic": True,
            "accept_digest": True,
            "default_to_digest": True,
        })
        config["simple_dc"]["user_mapping"] = {"*": True}
    elif auth == "nt":
        if config.get("nt_dc"):
            parser.error(
                "--auth=nt can only be used when no nt_dc settings are configured"
            )
        auth_conf.update({
            "domain_controller": "wsgidav.dc.nt_dc.NTDomainController",
            "accept_basic": True,
            "accept_digest": False,
            "default_to_digest": False,
        })
        config["nt_dc"] = {}
    elif auth == "pam-login":
        if config.get("pam_dc"):
            parser.error(
                "--auth=pam-login can only be used when no pam_dc settings are configured"
            )
        auth_conf.update({
            "domain_controller": "wsgidav.dc.pam_dc.PAMDomainController",
            "accept_basic": True,
            "accept_digest": False,
            "default_to_digest": False,
        })
        config["pam_dc"] = {"service": "login"}
    # print(config)

    if cli_opts.get("reload"):
        print("Installing paste.reloader.", file=sys.stderr)
        from paste import reloader  # @UnresolvedImport

        reloader.install()
        if config_file:
            # Add config file changes
            reloader.watch_file(config_file)
        # import pydevd
        # pydevd.settrace()

    return config
Exemplo n.º 4
0
def _init_config():
    """Setup configuration dictionary from default, command line and configuration file."""
    cli_opts = _init_command_line_options()
    cli_verbose = cli_opts["verbose"]

    # Set config defaults
    # config = DEFAULT_CONFIG.copy()
    config = copy.deepcopy(DEFAULT_CONFIG)

    # Configuration file overrides defaults
    config_file = cli_opts.get("config_file")
    if config_file:
        file_opts = _read_config_file(config_file, cli_verbose)
        # config.update(file_opts)
        util.deep_update(config, file_opts)
        if cli_verbose != DEFAULT_VERBOSE and "verbose" in file_opts:
            if cli_verbose >= 2:
                print(
                    "Config file defines 'verbose: {}' but is overridden by command line: {}."
                    .format(file_opts["verbose"], cli_verbose))
            config["verbose"] = cli_verbose
    else:
        if cli_verbose >= 2:
            print("Running without configuration file.")

    # Command line overrides file
    if cli_opts.get("port"):
        config["port"] = cli_opts.get("port")
    if cli_opts.get("host"):
        config["host"] = cli_opts.get("host")
    if cli_opts.get("verbose") is not None:
        config["verbose"] = cli_opts.get("verbose")
    if cli_opts.get("profile") is not None:
        config["profile"] = True
    if cli_opts.get("server") is not None:
        config["server"] = cli_opts.get("server")
    if cli_opts.get("ssl_adapter") is not None:
        config["ssl_adapter"] = cli_opts.get("ssl_adapter")

    if cli_opts.get("root_path"):
        root_path = os.path.abspath(cli_opts.get("root_path"))
        config["provider_mapping"]["/"] = FilesystemProvider(root_path)

    if config["verbose"] >= 5:
        print("Configuration({}):\n{}".format(cli_opts["config_file"],
                                              pformat(config)))

    if not config["provider_mapping"]:
        print("ERROR: No DAV provider defined. Try --help option.",
              file=sys.stderr)
        sys.exit(-1)

    if cli_opts.get("reload"):
        print("Installing paste.reloader.", file=sys.stderr)
        from paste import reloader  # @UnresolvedImport

        reloader.install()
        if config_file:
            # Add config file changes
            reloader.watch_file(config_file)
        # import pydevd
        # pydevd.settrace()

    return config
Exemplo n.º 5
0
    def __init__(self, config):

        self.config = copy.deepcopy(DEFAULT_CONFIG)
        util.deep_update(self.config, config)
        # self.config.update(config)
        config = self.config

        # Evaluate configuration and set defaults
        _check_config(config)

        #        response_trailer = config.get("response_trailer", "")
        self.verbose = config.get("verbose", 3)

        lock_storage = config.get("lock_manager")
        if lock_storage is True:
            lock_storage = LockStorageDict()

        if not lock_storage:
            self.lock_manager = None
        else:
            self.lock_manager = LockManager(lock_storage)

        self.prop_manager = config.get("property_manager")
        if not self.prop_manager:
            # Normalize False, 0 to None
            self.prop_manager = None
        elif self.prop_manager is True:
            self.prop_manager = PropertyManager()

        self.mount_path = config.get("mount_path")
        auth_conf = config.get("http_authenticator", {})

        # Instantiate DAV resource provider objects for every share
        # provider_mapping may contain the args that are passed to a `FilesystemProvider`
        # instance:
        #     <mount_path>: <folder_path>
        # or
        #     <mount_path>: [folder_path, is_readonly]
        # or contain a complete new instance:
        #     <mount_path>: <DAVProvider Instance>

        provider_mapping = self.config["provider_mapping"]

        self.provider_map = {}
        self.sorted_share_list = None
        for share, provider in provider_mapping.items():
            self.add_provider(share, provider)

        # Figure out the domain controller, used by http_authenticator
        # dc = config.get("http_authenticator", {}).get("domain_controller")
        # if dc is True or not dc:
        #     # True or null:
        #     dc = SimpleDomainController

        # if compat.is_basestring(dc):
        #     # If a plain string is passed, try to import it as class
        #     dc = dynamic_import_class(dc)

        # if inspect.isclass(dc):
        #     # If a class is passed, instantiate that
        #     # assert issubclass(mw, BaseMiddleware)  # TODO: remove this assert with 3.0
        #     dc = dc(config)

        # domain_controller = dc
        # print(domain_controller)
        domain_controller = None

        # Define WSGI application stack
        middleware_stack = config.get("middleware_stack", [])
        mw_list = []

        # This is the 'outer' application, i.e. the WSGI application object that
        # is eventually called by the server.
        self.application = self

        # When building up the middleware stack, this app will be wrapped and replaced by the
        # next middleware in the list.
        # The `middleware_stack` is configured such that the first app in the list should be
        # called first. But since every app wraps its predecessor, we iterate in reverse
        # order:
        for mw in reversed(middleware_stack):
            # The middleware stack configuration may contain plain strings, dicts,
            # classes, or objects
            app = None
            if compat.is_basestring(mw):
                # If a plain string is passed, try to import it, assuming BaseMiddleware
                # signature
                app_class = dynamic_import_class(mw)
                app = app_class(self, self.application, config)
            elif type(mw) is dict:
                # If a dict with one entry is passed, use the key as module/class name
                # and the value as constructor arguments (positional or kwargs).
                assert len(mw) == 1
                name, args = list(mw.items())[0]
                expand = {"${application}": self.application}
                app = dynamic_instantiate_middleware(name, args, expand)
            elif inspect.isclass(mw):
                # If a class is passed, assume BaseMiddleware (or compatible)
                assert issubclass(
                    mw, BaseMiddleware)  # TODO: remove this assert with 3.0
                app = mw(self, self.application, config)
            else:
                # Otherwise assume an initialized middleware instance
                app = mw

            # FIXME: We should try to generalize this specific code:
            if isinstance(app, HTTPAuthenticator):
                domain_controller = app.get_domain_controller()
                # Check anonymous access
                for share, data in self.provider_map.items():
                    if app.allow_anonymous_access(share):
                        data["allow_anonymous"] = True

            # Add middleware to the stack
            if app:
                mw_list.append(app)
                self.application = app
            else:
                _logger.error("Could not add middleware {}.".format(mw))

        # Print info
        _logger.info("WsgiDAV/{} Python/{} {}".format(
            __version__, util.PYTHON_VERSION, platform.platform(aliased=True)))
        if self.verbose >= 4:
            _logger.info("Default encoding: {!r} (file system: {!r})".format(
                sys.getdefaultencoding(), sys.getfilesystemencoding()))

        if self.verbose >= 3:
            _logger.info("Lock manager:      {}".format(self.lock_manager))
            _logger.info("Property manager:  {}".format(self.prop_manager))
            _logger.info("Domain controller: {}".format(domain_controller))

        if self.verbose >= 4:
            # We traversed the stack in reverse order. Now revert again, so
            # we see the order that was configured:
            _logger.info("Middleware stack:")
            for mw in reversed(mw_list):
                _logger.info("  - {}".format(mw))

        if self.verbose >= 3:
            _logger.info("Registered DAV providers by route:")
            for share in self.sorted_share_list:
                data = self.provider_map[share]
                hint = " (anonymous)" if data["allow_anonymous"] else ""
                _logger.info("  - '{}': {}{}".format(share, data["provider"],
                                                     hint))

        if auth_conf.get("accept_basic") and not config.get("ssl_certificate"):
            _logger.warn(
                "Basic authentication is enabled: It is highly recommended to enable SSL."
            )

        for share, data in self.provider_map.items():
            if data["allow_anonymous"]:
                # TODO: we should only warn here, if --no-auth is not given
                _logger.warn(
                    "Share '{}' will allow anonymous access.".format(share))
        return
Exemplo n.º 6
0
    def __init__(self, config):

        self.config = copy.deepcopy(DEFAULT_CONFIG)
        util.deep_update(self.config, config)
        config = self.config

        # Evaluate configuration and set defaults
        _check_config(config)

        self.verbose = config.get("verbose", 3)

        hotfixes = config.get("hotfixes", {})

        self.re_encode_path_info = hotfixes.get("re_encode_path_info", None)
        if self.re_encode_path_info is None:
            self.re_encode_path_info = compat.PY3

        self.unquote_path_info = hotfixes.get("unquote_path_info", False)

        lock_storage = config.get("lock_manager")
        if lock_storage is True:
            lock_storage = LockStorageDict()

        if not lock_storage:
            self.lock_manager = None
        else:
            self.lock_manager = LockManager(lock_storage)

        self.prop_manager = config.get("property_manager")
        if not self.prop_manager:
            # Normalize False, 0 to None
            self.prop_manager = None
        elif self.prop_manager is True:
            self.prop_manager = PropertyManager()

        self.mount_path = config.get("mount_path")
        auth_conf = config.get("http_authenticator", {})

        # Instantiate DAV resource provider objects for every share.
        # provider_mapping may contain the args that are passed to a
        # `FilesystemProvider` instance:
        #     <mount_path>: <folder_path>
        # or
        #     <mount_path>: { "root": <folder_path>, "readonly": True }
        # or contain a complete new instance:
        #     <mount_path>: <DAVProvider Instance>

        provider_mapping = self.config["provider_mapping"]

        self.provider_map = {}
        self.sorted_share_list = None
        for share, provider in provider_mapping.items():
            self.add_provider(share, provider)

        self.http_authenticator = None
        domain_controller = None

        # Define WSGI application stack
        middleware_stack = config.get("middleware_stack", [])
        mw_list = []

        # This is the 'outer' application, i.e. the WSGI application object that
        # is eventually called by the server.
        self.application = self

        # The `middleware_stack` is configured such that the first app in the
        # list should be called first. Since every app wraps its predecessor, we
        # iterate in reverse order:
        for mw in reversed(middleware_stack):
            # The middleware stack configuration may contain plain strings, dicts,
            # classes, or objects
            app = None
            if compat.is_basestring(mw):
                # If a plain string is passed, try to import it, assuming
                # `BaseMiddleware` signature
                app_class = dynamic_import_class(mw)
                app = app_class(self, self.application, config)
            elif type(mw) is dict:
                # If a dict with one entry is passed, use the key as module/class name
                # and the value as constructor arguments (positional or kwargs).
                assert len(mw) == 1
                name, args = list(mw.items())[0]
                expand = {"${application}": self.application}
                app = dynamic_instantiate_middleware(name, args, expand)
            elif inspect.isclass(mw):
                # If a class is passed, assume BaseMiddleware (or compatible)
                assert issubclass(
                    mw, BaseMiddleware)  # TODO: remove this assert with 3.0
                app = mw(self, self.application, config)
            else:
                # Otherwise assume an initialized middleware instance
                app = mw

            # Remember
            if isinstance(app, HTTPAuthenticator):
                self.http_authenticator = app
                domain_controller = app.get_domain_controller()

            # Add middleware to the stack
            if app:
                if callable(getattr(app, "is_disabled",
                                    None)) and app.is_disabled():
                    _logger.warning(
                        "App {}.is_disabled() returned True: skipping.".format(
                            app))
                else:
                    mw_list.append(app)
                    self.application = app
            else:
                _logger.error("Could not add middleware {}.".format(mw))

        domain_controller
        # Print info
        _logger.info("WsgiDAV/{} Python/{} {}".format(
            __version__, util.PYTHON_VERSION, platform.platform(aliased=True)))
        if self.verbose >= 4:
            _logger.info("Default encoding: {!r} (file system: {!r})".format(
                sys.getdefaultencoding(), sys.getfilesystemencoding()))

        if self.verbose >= 3:
            _logger.info("Lock manager:      {}".format(self.lock_manager))
            _logger.info("Property manager:  {}".format(self.prop_manager))
            _logger.info("Domain controller: {}".format(domain_controller))

        if self.verbose >= 4:
            # We traversed the stack in reverse order. Now revert again, so
            # we see the order that was configured:
            _logger.info("Middleware stack:")
            for mw in reversed(mw_list):
                _logger.info("  - {}".format(mw))

        if self.verbose >= 3:
            _logger.info("Registered DAV providers by route:")
            for share in self.sorted_share_list:
                provider = self.provider_map[share]
                hint = (" (anonymous)"
                        if domain_controller.is_share_anonymous(share) else "")
                _logger.info("  - '{}': {}{}".format(share, provider, hint))

        if auth_conf.get("accept_basic") and not config.get("ssl_certificate"):
            _logger.warning(
                "Basic authentication is enabled: It is highly recommended to enable SSL."
            )

        if domain_controller:
            for share, provider in self.provider_map.items():
                if domain_controller.is_share_anonymous(share):
                    _logger.warning(
                        "Share '{}' will allow anonymous {} access.".format(
                            share,
                            "read" if provider.is_readonly() else "write"))
        return