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

This reverts commit e73270bbe5.
This commit is contained in:
Unrud 2018-08-16 07:57:26 +02:00
parent 68740d10f3
commit 67bdbd8530
2 changed files with 34 additions and 41 deletions

View File

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

View File

@ -102,26 +102,14 @@ class BaseAuth:
""" """
return () return ()
def login(self, login, password):
"""Check credentials and map login to internal user
``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 ""
def is_authenticated2(self, login, user, password): def is_authenticated2(self, login, user, password):
"""Validate credentials. """Validate credentials.
DEPRECATED: use ``login`` instead ``login`` the login name
``user`` the user from ``map_login_to_user(login)``.
``password`` the login password
""" """
return self.is_authenticated(user, password) return self.is_authenticated(user, password)
@ -129,7 +117,7 @@ class BaseAuth:
def is_authenticated(self, user, password): def is_authenticated(self, user, password):
"""Validate credentials. """Validate credentials.
DEPRECATED: use ``login`` instead DEPRECATED: use ``is_authenticated2`` instead
""" """
raise NotImplementedError raise NotImplementedError
@ -137,7 +125,11 @@ class BaseAuth:
def map_login_to_user(self, login): def map_login_to_user(self, login):
"""Map login name to internal user. """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 return login