diff --git a/Dockerfile b/Dockerfile index 5f85126..7acc5ff 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,7 +23,7 @@ COPY uv.lock pyproject.toml ./ RUN uv sync --no-dev -COPY main.py ./ +COPY main.py favicon.ico ./ COPY src ./src/ ENTRYPOINT [ "uv", "run", "--no-sync", "main.py"] \ No newline at end of file diff --git a/data/.gitignore b/data/.gitignore index e948666..c96a04f 100644 --- a/data/.gitignore +++ b/data/.gitignore @@ -1,3 +1,2 @@ * -!.gitignore -!favicon.ico \ No newline at end of file +!.gitignore \ No newline at end of file diff --git a/data/favicon.ico b/favicon.ico similarity index 100% rename from data/favicon.ico rename to favicon.ico diff --git a/src/data_dir.py b/src/data_dir.py index 78c8ffa..2a831e6 100644 --- a/src/data_dir.py +++ b/src/data_dir.py @@ -12,11 +12,18 @@ if typing.TYPE_CHECKING: class DataDir: HOST_FILE = ".host" PATH_REGEX = re.compile(r"^[\w-]+$") + NEEDED_FILES: typing.ClassVar[list[str]] = ["favicon.ico"] def __init__(self, root_path: str) -> None: self.logger = logging.getLogger(self.__class__.__name__) self.root_path = pathlib.Path(root_path) + def init(self) -> None: + for file in self.NEEDED_FILES: + if not (self.root_path / file).is_file(): + (pathlib.Path.cwd() / file).copy_into(self.root_path) + self.logger.debug("Copied %s into data dir", file) + def list_paths(self) -> list[str]: paths: list[str] = [] for path in self.root_path.iterdir(): diff --git a/src/handler.py b/src/handler.py index 9b97c81..94d07d0 100644 --- a/src/handler.py +++ b/src/handler.py @@ -117,7 +117,7 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler): return self.certbot_www + path.removeprefix(self.CERTBOT_CHALLENGE_PATH) if (page := self.registry.get_from_host(self.__get_host())) is not None: path = f"/{page.path}" + path - if ( + elif ( path not in self.AUTHORIZED_PATHS and self.__get_subpath(path) is None ): # not a valid path return "" diff --git a/src/server.py b/src/server.py index 87634bc..99de631 100644 --- a/src/server.py +++ b/src/server.py @@ -3,7 +3,7 @@ import http.server import logging import typing -from . import cert, handler, project, registry +from . import cert, data_dir, handler, project, registry if typing.TYPE_CHECKING: from . import params @@ -15,6 +15,7 @@ class StaplerServer: self.params = params self.registry = registry.Registry(params) self.cert_manager = cert.CertManager(params) + self.data_dir = data_dir.DataDir(params.data_dir) self.default_host = params.host.split(":", maxsplit=2)[0] def request_handler(self, *args: typing.Any) -> http.server.BaseHTTPRequestHandler: @@ -33,6 +34,7 @@ class StaplerServer: self.registry.load_pages() if self.params.with_certificates: self.cert_manager.init(self.__get_all_hosts()) + self.data_dir.init() if not len(self.params.token): self.logger.warning("No token provided update requests will fail") @@ -73,6 +75,7 @@ class StaplerServer: self.logger.warning("Cannot renew without certificates") return 1 self.registry.load_pages() + self.cert_manager.init(self.__get_all_hosts()) for host in self.__get_all_hosts(): self.cert_manager.create_or_update(host) return 0