From 689e5c9dd58645b8563bcb440a278bc7aca29995 Mon Sep 17 00:00:00 2001 From: Unrud Date: Tue, 30 Aug 2016 23:13:33 +0200 Subject: [PATCH] Map logins to internal users in Auth module This makes it possible to implement #349 as a Auth module. Another use case would be to encode usernames that contain characters unsupported by the file system. --- radicale/__init__.py | 9 +++++---- radicale/auth.py | 17 +++++++++++++---- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/radicale/__init__.py b/radicale/__init__.py index b1631d3..5690223 100644 --- a/radicale/__init__.py +++ b/radicale/__init__.py @@ -167,7 +167,7 @@ class Application: super().__init__() self.configuration = configuration self.logger = logger - self.is_authenticated = auth.load(configuration, logger) + self.Auth = auth.load(configuration, logger) self.Collection = storage.load(configuration, logger) self.authorized = rights.load(configuration, logger) self.encoding = configuration.get("encoding", "request") @@ -288,10 +288,11 @@ class Application: authorization = environ.get("HTTP_AUTHORIZATION", None) if authorization and authorization.startswith("Basic"): authorization = authorization[len("Basic"):].strip() - user, password = self.decode(base64.b64decode( + login, password = self.decode(base64.b64decode( authorization.encode("ascii")), environ).split(":", 1) + user = self.Auth.map_login_to_user(login) else: - user = environ.get("REMOTE_USER") + user = self.Auth.map_login_to_user(environ.get("REMOTE_USER", "")) password = None # If "/.well-known" is not available, clients query "/" @@ -303,7 +304,7 @@ class Application: self.logger.info("Refused unsafe username: %s", user) is_authenticated = False else: - is_authenticated = self.is_authenticated(user, password) + is_authenticated = self.Auth.is_authenticated(user, password) is_valid_user = is_authenticated or not user # Create principal collection diff --git a/radicale/auth.py b/radicale/auth.py index df3d274..2fa2807 100644 --- a/radicale/auth.py +++ b/radicale/auth.py @@ -65,12 +65,12 @@ def load(configuration, logger): auth_type = configuration.get("auth", "type") logger.debug("Authentication type is %s", auth_type) if auth_type == "None": - return lambda user, password: True + class_ = NoneAuth elif auth_type == "htpasswd": - return Auth(configuration, logger).is_authenticated + class_ = Auth else: - module = import_module(auth_type) - return module.Auth(configuration, logger).is_authenticated + class_ = import_module(auth_type).Auth + return class_(configuration, logger) class BaseAuth: @@ -88,6 +88,15 @@ class BaseAuth: """ raise NotImplementedError + def map_login_to_user(self, login): + """Map login to internal username.""" + return login + + +class NoneAuth(BaseAuth): + def is_authenticated(self, user, password): + return True + class Auth(BaseAuth): def __init__(self, configuration, logger):