Просмотр исходного кода

Revert "Auth: Introduce login(login, password) method"

This reverts commit e73270bbe5db2cbfe9257efffa2af67318a8cf0f.
Unrud 7 лет назад
Родитель
Сommit
67bdbd8530
2 измененных файлов с 33 добавлено и 40 удалено
  1. 23 22
      radicale/__init__.py
  2. 10 18
      radicale/auth.py

+ 23 - 22
radicale/__init__.py

@@ -440,7 +440,6 @@ class Application:
         authorization = environ.get("HTTP_AUTHORIZATION", "")
         if external_login:
             login, password = external_login
-            login, password = login or "", password or ""
         elif authorization.startswith("Basic"):
             authorization = authorization[len("Basic"):].strip()
             login, password = self.decode(base64.b64decode(
@@ -449,28 +448,30 @@ class Application:
             # DEPRECATED: use remote_user backend instead
             login = environ.get("REMOTE_USER", "")
             password = ""
+        user = self.Auth.map_login_to_user(login)
 
-        user = self.Auth.login(login, password) or "" if login else ""
-        if user and login == user:
-            self.logger.info("Successful login: %r", user)
-        elif user:
-            self.logger.info("Successful login: %r -> %r", login, user)
-        elif login:
-            self.logger.info("Failed login attempt: %r", login)
-            # Random delay to avoid timing oracles and bruteforce attacks
-            delay = self.configuration.getfloat("auth", "delay")
-            if delay > 0:
-                random_delay = delay * (0.5 + random.random())
-                self.logger.debug("Sleeping %.3f seconds", random_delay)
-                time.sleep(random_delay)
-
-        if user and not storage.is_safe_path_component(user):
+        if not user:
+            is_authenticated = True
+        elif not storage.is_safe_path_component(user):
             # Prevent usernames like "user/calendar.ics"
             self.logger.info("Refused unsafe username: %r", user)
-            user = ""
+            is_authenticated = False
+        else:
+            is_authenticated = self.Auth.is_authenticated2(login, user,
+                                                           password)
+            if not is_authenticated:
+                self.logger.info("Failed login attempt: %r", user)
+                # Random delay to avoid timing oracles and bruteforce attacks
+                delay = self.configuration.getfloat("auth", "delay")
+                if delay > 0:
+                    random_delay = delay * (0.5 + random.random())
+                    self.logger.debug("Sleeping %.3f seconds", random_delay)
+                    time.sleep(random_delay)
+            else:
+                self.logger.info("Successful login: %r", user)
 
         # Create principal collection
-        if user:
+        if user and is_authenticated:
             principal_path = "/%s/" % user
             if self.Rights.authorized(user, principal_path, "w"):
                 with self.Collection.acquire_lock("r", user):
@@ -484,7 +485,7 @@ class Application:
                         except ValueError as e:
                             self.logger.warning("Failed to create principal "
                                                 "collection %r: %s", user, e)
-                            user = ""
+                            is_authenticated = False
             else:
                 self.logger.warning("Access to principal path %r denied by "
                                     "rights backend", principal_path)
@@ -499,7 +500,7 @@ class Application:
                     "Request body too large: %d", content_length)
                 return response(*REQUEST_ENTITY_TOO_LARGE)
 
-        if not login or user:
+        if is_authenticated:
             status, headers, answer = function(
                 environ, base_prefix, path, user)
             if (status, headers, answer) == NOT_ALLOWED:
@@ -508,8 +509,8 @@ class Application:
         else:
             status, headers, answer = NOT_ALLOWED
 
-        if ((status, headers, answer) == NOT_ALLOWED and not user and
-                not external_login):
+        if (status, headers, answer) == NOT_ALLOWED and not (
+                user and is_authenticated) and not external_login:
             # Unknown or unauthorized user
             self.logger.debug("Asking client for authentication")
             status = client.UNAUTHORIZED

+ 10 - 18
radicale/auth.py

@@ -102,26 +102,14 @@ class BaseAuth:
         """
         return ()
 
-    def login(self, login, password):
-        """Check credentials and map login to internal user
+    def is_authenticated2(self, login, user, password):
+        """Validate credentials.
 
         ``login`` the login name
 
-        ``password`` the password
-
-        Returns the user name or ``""`` for invalid credentials.
-
-        """
-
-        user = self.map_login_to_user(login)
-        if user and self.is_authenticated2(login, user, password):
-            return user
-        return ""
+        ``user`` the user from ``map_login_to_user(login)``.
 
-    def is_authenticated2(self, login, user, password):
-        """Validate credentials.
-
-        DEPRECATED: use ``login`` instead
+        ``password`` the login password
 
         """
         return self.is_authenticated(user, password)
@@ -129,7 +117,7 @@ class BaseAuth:
     def is_authenticated(self, user, password):
         """Validate credentials.
 
-        DEPRECATED: use ``login`` instead
+        DEPRECATED: use ``is_authenticated2`` instead
 
         """
         raise NotImplementedError
@@ -137,7 +125,11 @@ class BaseAuth:
     def map_login_to_user(self, login):
         """Map login name to internal user.
 
-        DEPRECATED: use ``login`` instead
+        ``login`` the login name, ``""`` for anonymous users
+
+        Returns a string with the user name.
+        If a login can't be mapped to an user, return ``login`` and
+        return ``False`` in ``is_authenticated2(...)``.
 
         """
         return login