xandikos
xandikos copied to clipboard
support multiple users
I'm not sure if it is already supported or not, but I can't get multiple users to work: I'm always redirected to the CURRENT_USER_PRINCIPAL, or if I don't set this variable, to the first user found in the collections.
That's correct, there is currently no support for multiple users. I'm hoping to add support for multiple users at some point soon, though initially with every user as a silo - e.g. no ability to share calendars, etc.
There are some notes in HEAD now about multi user support.
FWIW
I did found notes/multi-user.rst
and notes/auth.rst
Next clue seems to be REMOTE_USER
any news about the progress to support more than one user account?
I've made some progress on this, I'm hoping to merge it into master later this month if I don't get swamped by other things.
On November 21, 2018 8:34:21 PM UTC, Marko Bauhardt [email protected] wrote:
any news about the progress to support more than one user account?
-- You are receiving this because you were assigned. Reply to this email directly or view it on GitHub: https://github.com/jelmer/xandikos/issues/61#issuecomment-440800634
Nice!
This has been a little bit delayed, but will hopefully happen sometime in December.
Some more progress: There is now a Xandikos-specific configuration file for collections that will be used to store ACLs. Current user credentials are also being passed around.
Any plans to add Imap auth? for the multi users.
I'm planning to support the username being passed in by the reverse proxy (i.e. the REMOTE_USER environment variable). So you'd be able to use any authentication mechanism that Apache or nginx supports.
@WhyNotHugo See notes/multi-user.rst in the git repository for the current status.
I'm a new user having moved over from radicale and am interested in this multi-user feature. I'm willing to help if you can describe what's left to be done. I looked at the multi-user.rst and it doesn't look like there's too much left to be done. Is multi-user.rst up to date?
The following items still need to be done:
* Support automatic creation of principal on first login of user * Add simple function check_path_access() for checking access ("is this user allowed to access this path?") * Use access checking function everywere
I think the last two and the first one could probably be tackled independently.
Happy to dig into the details a bit more if you're interested in working one of these.
Great. That doesn't sound too bad. Let me stare at the code a bit and then I can give it a shot.
Is everything in the current-user branch or are you working somewhere else? It seems abandoned.
Check the dates of previous messages.
The changes that are done have all landed in master.
Ok, I think I understand the initialization. I'm ready to tackle "Support automatic creation of principal on first login of user". In handle_wsgi_request() I can extract the authenticated user by decoding HTTP_AUTHORIZATION. How would you like to see the current_user_principal set and where should a call to create_principle() be done? Thanks!
Something like this creates the principal when authorized but there may be more to it that I'm missing:
index ab61305..16e2260 100644
--- a/xandikos/webdav.py
+++ b/xandikos/webdav.py
@@ -32,6 +32,7 @@ import functools
import logging
import os
import posixpath
+import base64
from typing import (
Callable,
Dict,
@@ -2069,7 +2070,34 @@ class WebDAVApp(object):
logging.debug('SCRIPT_NAME not set; assuming "".')
environ["SCRIPT_NAME"] = ""
request = WSGIRequest(environ)
+ auth_header = environ.get("HTTP_AUTHORIZATION")
environ = {"SCRIPT_NAME": environ["SCRIPT_NAME"]}
+
+ # set the principal
+ auth_user = None
+ if auth_header:
+ auth_type, encoded_credentials = auth_header.split(" ")
+ if "Basic" in auth_type:
+ decoded_credentials = (
+ base64.b64decode(encoded_credentials).decode("utf-8").split(":")
+ )
+ if os.path.basename(decoded_credentials[0]) != decoded_credentials[0]:
+ logging.info(
+ "Authenticated user may contain path: %s"
+ % decoded_credentials[0]
+ )
+ else:
+ auth_user = decoded_credentials[0]
+
+ if auth_user:
+ current_user_principal = "/%s/" % auth_user
+ if not self.backend.get_resource(current_user_principal):
+ if os.getenv("AUTOCREATE"):
+ self.backend.create_principal(
+ current_user_principal, create_defaults=True
+ )
+ self.backend._mark_as_principal(current_user_principal)
+
try:
loop = asyncio.get_event_loop()
except RuntimeError:
Couple of quick comments:
- I'm keen to leave the authentication up to the reverse proxy; xandikos should just be looking at the REMOTE_USER environment variable that it sets
- This logic belongs in xandikos.web rather xandikos.webdav, as the latter is about the protocol implementation rather than the main business logic
Happy to dig into the details a bit more if you're interested in working one of these.
Can you dig into the details of the check_path_access() function you would like to have?