From 18e67b7381479ebd3548dbc87e112107ee68ee20 Mon Sep 17 00:00:00 2001 From: Tom Pusateri Date: Mon, 25 Jul 2022 14:00:27 -0400 Subject: [PATCH 1/3] Create user_principal based on web authenticated user. Pass $remote_user as HTTP_X_REMOTE_USER from a proxy. --- examples/xandikos.nginx.conf | 1 + xandikos/web.py | 8 ++++++++ xandikos/webdav.py | 5 +++++ 3 files changed, 14 insertions(+) diff --git a/examples/xandikos.nginx.conf b/examples/xandikos.nginx.conf index 97acc423..c1fa50a8 100644 --- a/examples/xandikos.nginx.conf +++ b/examples/xandikos.nginx.conf @@ -18,6 +18,7 @@ server { location / { proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Remote-User $remote_user; proxy_redirect off; proxy_buffering off; proxy_pass http://xandikos; diff --git a/xandikos/web.py b/xandikos/web.py index 7b4eda1d..693597ea 100644 --- a/xandikos/web.py +++ b/xandikos/web.py @@ -1030,6 +1030,14 @@ def get_resource(self, relpath): except KeyError: return None + def set_principal(self, user): + principal = "/%s/" % user + if not self.get_resource(principal): + if os.getenv("AUTOCREATE"): + self.create_principal( + principal, create_defaults=True + ) + self._mark_as_principal(principal) class XandikosApp(webdav.WebDAVApp): """A wsgi App that provides a Xandikos web server.""" diff --git a/xandikos/webdav.py b/xandikos/webdav.py index ab61305a..133e4555 100644 --- a/xandikos/webdav.py +++ b/xandikos/webdav.py @@ -2069,7 +2069,12 @@ def handle_wsgi_request(self, environ, start_response): logging.debug('SCRIPT_NAME not set; assuming "".') environ["SCRIPT_NAME"] = "" request = WSGIRequest(environ) + remote_user = environ.get("HTTP_X_REMOTE_USER") environ = {"SCRIPT_NAME": environ["SCRIPT_NAME"]} + if remote_user: + environ["REMOTE_USER"] = remote_user + self.backend.set_principal(remote_user) + try: loop = asyncio.get_event_loop() except RuntimeError: From f79036988ed43a0bd223859447557f32d6219c21 Mon Sep 17 00:00:00 2001 From: Tom Pusateri Date: Mon, 15 Aug 2022 15:33:00 -0400 Subject: [PATCH 2/3] Save autocreate as backend property. --- xandikos/web.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/xandikos/web.py b/xandikos/web.py index 693597ea..b0773a49 100644 --- a/xandikos/web.py +++ b/xandikos/web.py @@ -967,8 +967,9 @@ def open_store_from_path(path: str): class XandikosBackend(webdav.Backend): - def __init__(self, path): + def __init__(self, path, autocreate): self.path = path + self.autocreate = autocreate self._user_principals = set() def _map_to_file_path(self, relpath): @@ -1033,12 +1034,13 @@ def get_resource(self, relpath): def set_principal(self, user): principal = "/%s/" % user if not self.get_resource(principal): - if os.getenv("AUTOCREATE"): + if self.autocreate: self.create_principal( principal, create_defaults=True ) self._mark_as_principal(principal) + class XandikosApp(webdav.WebDAVApp): """A wsgi App that provides a Xandikos web server.""" @@ -1249,7 +1251,7 @@ def run_simple_server( port: TCP Port to listen on (None to disable) socket_path: Unix domain socket path to listen on (None to disable) """ - backend = XandikosBackend(directory) + backend = XandikosBackend(directory, autocreate) backend._mark_as_principal(current_user_principal) if autocreate or defaults: @@ -1410,7 +1412,8 @@ def main(argv=None): # noqa: C901 logging.basicConfig(level=logging.INFO, format='%(message)s') - backend = XandikosBackend(os.path.abspath(options.directory)) + backend = XandikosBackend(os.path.abspath(options.directory), + options.autocreate) backend._mark_as_principal(options.current_user_principal) if options.autocreate or options.defaults: From c80982925c30e33611fb03acd13d4fc07b5691ad Mon Sep 17 00:00:00 2001 From: Tom Pusateri Date: Mon, 15 Aug 2022 22:28:40 -0400 Subject: [PATCH 3/3] Add autocreate to backend creation. --- notes/api-stability.rst | 2 +- xandikos/tests/test_api.py | 2 +- xandikos/tests/test_web.py | 2 +- xandikos/wsgi.py | 3 ++- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/notes/api-stability.rst b/notes/api-stability.rst index 54b097b5..1167dfa2 100644 --- a/notes/api-stability.rst +++ b/notes/api-stability.rst @@ -4,7 +4,7 @@ API Stability There are currently no guarantees about Xandikos Python APIs staying the same across different versions, except the following APIs: -xandikos.web.XandikosBackend(path) +xandikos.web.XandikosBackend(path, autocreate) xandikos.web.XandikosBackend.create_principal(principal, create_defaults=False) xandikos.web.XandikosApp(backend, current_user_principal) xandikos.web.WellknownRedirector(app, path) diff --git a/xandikos/tests/test_api.py b/xandikos/tests/test_api.py index 6c515d80..b44d6999 100644 --- a/xandikos/tests/test_api.py +++ b/xandikos/tests/test_api.py @@ -35,7 +35,7 @@ class WebTests(unittest.TestCase): def test_backend(self): path = tempfile.mkdtemp() try: - backend = XandikosBackend(path) + backend = XandikosBackend(path=path, autocreate=True) backend.create_principal("foo", create_defaults=True) XandikosApp(backend, "foo") finally: diff --git a/xandikos/tests/test_web.py b/xandikos/tests/test_web.py index 6348bd26..eaec8e9d 100644 --- a/xandikos/tests/test_web.py +++ b/xandikos/tests/test_web.py @@ -57,7 +57,7 @@ def setUp(self): self.store = VdirStore.create(os.path.join(self.tempdir, "c")) self.store.load_extra_file_handler(ICalendarFile) - self.backend = XandikosBackend(self.tempdir) + self.backend = XandikosBackend(path=self.tempdir, autocreate=False) self.cal = CalendarCollection(self.backend, "c", self.store) diff --git a/xandikos/wsgi.py b/xandikos/wsgi.py index 5b4b1d89..bcd5203b 100644 --- a/xandikos/wsgi.py +++ b/xandikos/wsgi.py @@ -29,7 +29,8 @@ ) -backend = XandikosBackend(path=os.environ["XANDIKOSPATH"]) +backend = XandikosBackend(path=os.environ["XANDIKOSPATH"], + autocreate=os.getenv("AUTOCREATE")) if not os.path.isdir(backend.path): if os.getenv("AUTOCREATE"): os.makedirs(os.environ["XANDIKOSPATH"])