remove everything marked as DEPRECATED

This commit is contained in:
Unrud 2018-08-16 07:59:58 +02:00
parent e96410c6e7
commit c7d1936cb6
7 changed files with 32 additions and 107 deletions

View File

@ -449,6 +449,7 @@ class Application:
return response(*NOT_FOUND)
# Ask authentication backend to check rights
login = password = ""
external_login = self.Auth.get_external_login(environ)
authorization = environ.get("HTTP_AUTHORIZATION", "")
if external_login:
@ -458,10 +459,6 @@ class Application:
authorization = authorization[len("Basic"):].strip()
login, password = self.decode(base64.b64decode(
authorization.encode("ascii")), environ).split(":", 1)
else:
# DEPRECATED: use remote_user backend instead
login = environ.get("REMOTE_USER", "")
password = ""
user = self.Auth.login(login, password) or "" if login else ""
if user and login == user:
@ -961,7 +958,7 @@ class Application:
new_props = parent_item.get_meta()
new_props["tag"] = tag
storage.check_and_sanitize_props(new_props)
parent_item.set_meta_all(new_props)
parent_item.set_meta(new_props)
new_item = parent_item.upload(href, items[0])
except ValueError as e:
logger.warning(

View File

@ -62,14 +62,13 @@ from importlib import import_module
from radicale.log import logger
INTERNAL_TYPES = ("None", "none", "remote_user", "http_x_remote_user",
"htpasswd")
INTERNAL_TYPES = ("none", "remote_user", "http_x_remote_user", "htpasswd")
def load(configuration):
"""Load the authentication manager chosen in configuration."""
auth_type = configuration.get("auth", "type")
if auth_type in ("None", "none"): # DEPRECATED: use "none"
if auth_type == "none":
class_ = NoneAuth
elif auth_type == "remote_user":
class_ = RemoteUserAuth
@ -114,39 +113,12 @@ class BaseAuth:
"""
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):
"""Validate credentials.
DEPRECATED: use ``login`` instead
"""
return self.is_authenticated(user, password)
def is_authenticated(self, user, password):
"""Validate credentials.
DEPRECATED: use ``login`` instead
"""
raise NotImplementedError
def map_login_to_user(self, login):
"""Map login name to internal user.
DEPRECATED: use ``login`` instead
"""
return login
class NoneAuth(BaseAuth):
def is_authenticated(self, user, password):
return True
def login(self, login, password):
return login
class Auth(BaseAuth):
@ -239,11 +211,11 @@ class Auth(BaseAuth):
hash_value = hash_value.strip()
return md5_apr1.verify(password, hash_value)
def is_authenticated(self, user, password):
def login(self, login, password):
"""Validate credentials.
Iterate through htpasswd credential file until user matches, extract
hash (encrypted password) and check hash against user-given password,
Iterate through htpasswd credential file until login matches, extract
hash (encrypted password) and check hash against password,
using the method specified in the Radicale config.
The content of the file is not cached because reading is generally a
@ -257,20 +229,21 @@ class Auth(BaseAuth):
line = line.rstrip("\n")
if line.lstrip() and not line.lstrip().startswith("#"):
try:
login, hash_value = line.split(":", maxsplit=1)
hash_login, hash_value = line.split(
":", maxsplit=1)
# Always compare both login and password to avoid
# timing attacks, see #591.
login_ok = hmac.compare_digest(login, user)
login_ok = hmac.compare_digest(hash_login, login)
password_ok = self.verify(hash_value, password)
if login_ok and password_ok:
return True
return login
except ValueError as e:
raise RuntimeError("Invalid htpasswd file %r: %s" %
(self.filename, e)) from e
except OSError as e:
raise RuntimeError("Failed to load htpasswd file %r: %s" %
(self.filename, e)) from e
return False
return ""
class RemoteUserAuth(NoneAuth):

View File

@ -46,16 +46,16 @@ from importlib import import_module
from radicale import storage
from radicale.log import logger
INTERNAL_TYPES = ("None", "none", "authenticated", "owner_write", "owner_only",
INTERNAL_TYPES = ("none", "authenticated", "owner_write", "owner_only",
"from_file")
def load(configuration):
"""Load the rights manager chosen in configuration."""
rights_type = configuration.get("rights", "type")
if configuration.get("auth", "type") in ("None", "none"): # DEPRECATED
rights_type = "None"
if rights_type in ("None", "none"): # DEPRECATED: use "none"
if configuration.get("auth", "type") == "none":
rights_type = "none"
if rights_type == "none":
rights_class = NoneRights
elif rights_type == "authenticated":
rights_class = AuthenticatedRights

View File

@ -495,16 +495,6 @@ class BaseCollection:
"""Collection is a principal."""
return bool(self.path) and "/" not in self.path
@owner.setter
def owner(self, value):
# DEPRECATED: Included for compatibility reasons
pass
@is_principal.setter
def is_principal(self, value):
# DEPRECATED: Included for compatibility reasons
pass
@classmethod
def discover(cls, path, depth="0"):
"""Discover a list of collections under the given ``path``.
@ -596,14 +586,6 @@ class BaseCollection:
raise NotImplementedError
def get_multi(self, hrefs):
"""Fetch multiple items. Duplicate hrefs must be ignored.
DEPRECATED: use ``get_multi2`` instead
"""
return (self.get(href) for href in set(hrefs))
def get_multi2(self, hrefs):
"""Fetch multiple items.
Functionally similar to ``get``, but might bring performance benefits
@ -639,14 +621,6 @@ class BaseCollection:
"""
return ((item, False) for item in self.get_all())
def pre_filtered_list(self, filters):
"""List collection items with optional pre filtering.
DEPRECATED: use ``get_all_filtered`` instead
"""
return self.get_all()
def has(self, href):
"""Check if an item exists by its href.
@ -687,26 +661,10 @@ class BaseCollection:
def set_meta(self, props):
"""Set metadata values for collection.
``props`` a dict with updates for properties. If a value is empty, the
property must be deleted.
DEPRECATED: use ``set_meta_all`` instead
"""
raise NotImplementedError
def set_meta_all(self, props):
"""Set metadata values for collection.
``props`` a dict with values for properties.
"""
delta_props = self.get_meta()
for key in delta_props.keys():
if key not in props:
delta_props[key] = None
delta_props.update(props)
self.set_meta(self, delta_props)
raise NotImplementedError
@property
def last_modified(self):
@ -808,16 +766,11 @@ class Collection(BaseCollection):
lock_path = os.path.join(folder, ".Radicale.lock")
cls._lock = FileBackedRwLock(lock_path)
def __init__(self, path, principal=None, folder=None,
filesystem_path=None):
# DEPRECATED: Remove principal and folder attributes
if folder is None:
folder = self._get_collection_root_folder()
def __init__(self, path, filesystem_path=None):
folder = self._get_collection_root_folder()
# Path should already be sanitized
self.path = sanitize_path(path).strip("/")
self._encoding = self.configuration.get("encoding", "stock")
# DEPRECATED: Use ``self._encoding`` instead
self.encoding = self._encoding
if filesystem_path is None:
filesystem_path = path_to_filesystem(folder, self.path)
self._filesystem_path = filesystem_path
@ -1028,7 +981,7 @@ class Collection(BaseCollection):
tmp_filesystem_path = os.path.join(tmp_dir, "collection")
os.makedirs(tmp_filesystem_path)
self = cls(sane_path, filesystem_path=tmp_filesystem_path)
self.set_meta_all(props)
self.set_meta(props)
if collection:
if props.get("tag") == "VCALENDAR":
@ -1475,7 +1428,7 @@ class Collection(BaseCollection):
text=text, item=vobject_item, uid=uid, name=name,
component_name=tag), (tag, start, end)
def get_multi2(self, hrefs):
def get_multi(self, hrefs):
# It's faster to check for file name collissions here, because
# we only need to call os.listdir once.
files = None
@ -1575,7 +1528,7 @@ class Collection(BaseCollection):
"%r: %s" % (self.path, e)) from e
return self._meta_cache.get(key) if key else self._meta_cache
def set_meta_all(self, props):
def set_meta(self, props):
with self._atomic_write(self._props_path, "w") as f:
json.dump(props, f, sort_keys=True)

View File

@ -27,5 +27,7 @@ from radicale import auth
class Auth(auth.BaseAuth):
def is_authenticated(self, user, password):
return user == "tmp"
def login(self, login, password):
if login == "tmp":
return login
return ""

View File

@ -45,13 +45,13 @@ MIMETYPES = {
".xml": "text/xml"}
FALLBACK_MIMETYPE = "application/octet-stream"
INTERNAL_TYPES = ("None", "none", "internal")
INTERNAL_TYPES = ("none", "internal")
def load(configuration):
"""Load the web module chosen in configuration."""
web_type = configuration.get("web", "type")
if web_type in ("None", "none"): # DEPRECATED: use "none"
if web_type == "none":
web_class = NoneWeb
elif web_type == "internal":
web_class = Web

View File

@ -1121,7 +1121,7 @@ def proppatch(base_prefix, path, xml_request, collection):
pass
_add_propstat_to(response, short_name, 200)
storage.check_and_sanitize_props(new_props)
collection.set_meta_all(new_props)
collection.set_meta(new_props)
return multistatus
@ -1229,7 +1229,7 @@ def report(base_prefix, path, xml_request, collection):
# Reference is a collection
collection_requested = True
for name, item in collection.get_multi2(get_names()):
for name, item in collection.get_multi(get_names()):
if not item:
uri = "/" + posixpath.join(collection.path, name)
response = _item_response(base_prefix, uri,