From e07df9fd1d6bddeede029f356db7f7d56b1b828f Mon Sep 17 00:00:00 2001 From: Unrud Date: Sun, 19 Jan 2020 18:01:13 +0100 Subject: [PATCH] Prefix internal attributes with underscore --- radicale/app/__init__.py | 24 ++++++++++----------- radicale/app/delete.py | 6 +++--- radicale/app/get.py | 4 ++-- radicale/app/mkcalendar.py | 4 ++-- radicale/app/mkcol.py | 2 +- radicale/app/move.py | 10 ++++----- radicale/app/propfind.py | 8 +++---- radicale/app/proppatch.py | 8 +++---- radicale/app/put.py | 6 +++--- radicale/app/report.py | 8 +++---- radicale/auth/htpasswd.py | 41 ++++++++++++++++++------------------ radicale/rights/from_file.py | 10 ++++----- 12 files changed, 65 insertions(+), 66 deletions(-) diff --git a/radicale/app/__init__.py b/radicale/app/__init__.py index 7da5cb4..5c445b9 100644 --- a/radicale/app/__init__.py +++ b/radicale/app/__init__.py @@ -96,7 +96,7 @@ class Application( return request_environ - def decode(self, text, environ): + def _decode(self, text, environ): """Try to magically decode ``text`` according to given ``environ``.""" # List of charsets to try charsets = [] @@ -238,7 +238,7 @@ class Application( login, password = login or "", password or "" elif authorization.startswith("Basic"): authorization = authorization[len("Basic"):].strip() - login, password = self.decode(base64.b64decode( + login, password = self._decode(base64.b64decode( authorization.encode("ascii")), environ).split(":", 1) user = self._auth.login(login, password) or "" if login else "" @@ -312,7 +312,7 @@ class Application( return response(status, headers, answer) - def access(self, user, path, permission, item=None): + def _access(self, user, path, permission, item=None): if permission not in "rw": raise ValueError("Invalid permission argument: %r" % permission) if not item: @@ -336,7 +336,7 @@ class Application( return True return False - def read_raw_content(self, environ): + def _read_raw_content(self, environ): content_length = int(environ.get("CONTENT_LENGTH") or 0) if not content_length: return b"" @@ -345,13 +345,13 @@ class Application( raise RuntimeError("Request body too short: %d" % len(content)) return content - def read_content(self, environ): - content = self.decode(self.read_raw_content(environ), environ) + def _read_content(self, environ): + content = self._decode(self._read_raw_content(environ), environ) logger.debug("Request content:\n%s", content) return content - def read_xml_content(self, environ): - content = self.decode(self.read_raw_content(environ), environ) + def _read_xml_content(self, environ): + content = self._decode(self._read_raw_content(environ), environ) if not content: return None try: @@ -364,7 +364,7 @@ class Application( xmlutils.pretty_xml(xml_content)) return xml_content - def write_xml_content(self, xml_content): + def _write_xml_content(self, xml_content): if logger.isEnabledFor(logging.DEBUG): logger.debug("Response content:\n%s", xmlutils.pretty_xml(xml_content)) @@ -373,10 +373,10 @@ class Application( xml_declaration=True) return f.getvalue() - def webdav_error_response(self, namespace, name, - status=httputils.WEBDAV_PRECONDITION_FAILED[0]): + def _webdav_error_response(self, namespace, name, + status=httputils.WEBDAV_PRECONDITION_FAILED[0]): """Generate XML error response.""" headers = {"Content-Type": "text/xml; charset=%s" % self._encoding} - content = self.write_xml_content( + content = self._write_xml_content( xmlutils.webdav_error(namespace, name)) return status, headers, content diff --git a/radicale/app/delete.py b/radicale/app/delete.py index 83db11b..02bdc0d 100644 --- a/radicale/app/delete.py +++ b/radicale/app/delete.py @@ -49,13 +49,13 @@ def xml_delete(base_prefix, path, collection, href=None): class ApplicationDeleteMixin: def do_DELETE(self, environ, base_prefix, path, user): """Manage DELETE request.""" - if not self.access(user, path, "w"): + if not self._access(user, path, "w"): return httputils.NOT_ALLOWED with self._storage.acquire_lock("w", user): item = next(self._storage.discover(path), None) if not item: return httputils.NOT_FOUND - if not self.access(user, path, "w", item): + if not self._access(user, path, "w", item): return httputils.NOT_ALLOWED if_match = environ.get("HTTP_IF_MATCH", "*") if if_match not in ("*", item.etag): @@ -67,4 +67,4 @@ class ApplicationDeleteMixin: xml_answer = xml_delete( base_prefix, path, item.collection, item.href) headers = {"Content-Type": "text/xml; charset=%s" % self._encoding} - return client.OK, headers, self.write_xml_content(xml_answer) + return client.OK, headers, self._write_xml_content(xml_answer) diff --git a/radicale/app/get.py b/radicale/app/get.py index 5a3d7b7..c191c64 100644 --- a/radicale/app/get.py +++ b/radicale/app/get.py @@ -70,13 +70,13 @@ class ApplicationGetMixin: # Dispatch .web URL to web module if path == "/.web" or path.startswith("/.web/"): return self._web.get(environ, base_prefix, path, user) - if not self.access(user, path, "r"): + if not self._access(user, path, "r"): return httputils.NOT_ALLOWED with self._storage.acquire_lock("r", user): item = next(self._storage.discover(path), None) if not item: return httputils.NOT_FOUND - if not self.access(user, path, "r", item): + if not self._access(user, path, "r", item): return httputils.NOT_ALLOWED if isinstance(item, storage.BaseCollection): tag = item.get_meta("tag") diff --git a/radicale/app/mkcalendar.py b/radicale/app/mkcalendar.py index ade1f27..2896ab2 100644 --- a/radicale/app/mkcalendar.py +++ b/radicale/app/mkcalendar.py @@ -33,7 +33,7 @@ class ApplicationMkcalendarMixin: if not self._rights.authorized(user, path, "w"): return httputils.NOT_ALLOWED try: - xml_content = self.read_xml_content(environ) + xml_content = self._read_xml_content(environ) except RuntimeError as e: logger.warning( "Bad MKCALENDAR request on %r: %s", path, e, exc_info=True) @@ -54,7 +54,7 @@ class ApplicationMkcalendarMixin: with self._storage.acquire_lock("w", user): item = next(self._storage.discover(path), None) if item: - return self.webdav_error_response( + return self._webdav_error_response( "D", "resource-must-be-null") parent_path = pathutils.unstrip_path( posixpath.dirname(pathutils.strip_path(path)), True) diff --git a/radicale/app/mkcol.py b/radicale/app/mkcol.py index 8d31861..e6610da 100644 --- a/radicale/app/mkcol.py +++ b/radicale/app/mkcol.py @@ -34,7 +34,7 @@ class ApplicationMkcolMixin: if not permissions: return httputils.NOT_ALLOWED try: - xml_content = self.read_xml_content(environ) + xml_content = self._read_xml_content(environ) except RuntimeError as e: logger.warning( "Bad MKCOL request on %r: %s", path, e, exc_info=True) diff --git a/radicale/app/move.py b/radicale/app/move.py index 46feda0..7573198 100644 --- a/radicale/app/move.py +++ b/radicale/app/move.py @@ -34,7 +34,7 @@ class ApplicationMoveMixin: logger.info("Unsupported destination address: %r", raw_dest) # Remote destination server, not supported return httputils.REMOTE_DESTINATION - if not self.access(user, path, "w"): + if not self._access(user, path, "w"): return httputils.NOT_ALLOWED to_path = pathutils.sanitize_path(to_url.path) if not (to_path + "/").startswith(base_prefix + "/"): @@ -42,15 +42,15 @@ class ApplicationMoveMixin: "start with base prefix", to_path, path) return httputils.NOT_ALLOWED to_path = to_path[len(base_prefix):] - if not self.access(user, to_path, "w"): + if not self._access(user, to_path, "w"): return httputils.NOT_ALLOWED with self._storage.acquire_lock("w", user): item = next(self._storage.discover(path), None) if not item: return httputils.NOT_FOUND - if (not self.access(user, path, "w", item) or - not self.access(user, to_path, "w", item)): + if (not self._access(user, path, "w", item) or + not self._access(user, to_path, "w", item)): return httputils.NOT_ALLOWED if isinstance(item, storage.BaseCollection): # TODO: support moving collections @@ -74,7 +74,7 @@ class ApplicationMoveMixin: not to_item and to_collection.path != item.collection.path and to_collection.has_uid(item.uid)): - return self.webdav_error_response( + return self._webdav_error_response( "C" if tag == "VCALENDAR" else "CR", "no-uid-conflict") to_href = posixpath.basename(pathutils.strip_path(to_path)) try: diff --git a/radicale/app/propfind.py b/radicale/app/propfind.py index 25d55e7..6002f53 100644 --- a/radicale/app/propfind.py +++ b/radicale/app/propfind.py @@ -357,10 +357,10 @@ class ApplicationPropfindMixin: def do_PROPFIND(self, environ, base_prefix, path, user): """Manage PROPFIND request.""" - if not self.access(user, path, "r"): + if not self._access(user, path, "r"): return httputils.NOT_ALLOWED try: - xml_content = self.read_xml_content(environ) + xml_content = self._read_xml_content(environ) except RuntimeError as e: logger.warning( "Bad PROPFIND request on %r: %s", path, e, exc_info=True) @@ -375,7 +375,7 @@ class ApplicationPropfindMixin: item = next(items, None) if not item: return httputils.NOT_FOUND - if not self.access(user, path, "r", item): + if not self._access(user, path, "r", item): return httputils.NOT_ALLOWED # put item back items = itertools.chain([item], items) @@ -387,4 +387,4 @@ class ApplicationPropfindMixin: self._encoding) if status == client.FORBIDDEN: return httputils.NOT_ALLOWED - return status, headers, self.write_xml_content(xml_answer) + return status, headers, self._write_xml_content(xml_answer) diff --git a/radicale/app/proppatch.py b/radicale/app/proppatch.py index f291d80..d476785 100644 --- a/radicale/app/proppatch.py +++ b/radicale/app/proppatch.py @@ -87,10 +87,10 @@ def xml_proppatch(base_prefix, path, xml_request, collection): class ApplicationProppatchMixin: def do_PROPPATCH(self, environ, base_prefix, path, user): """Manage PROPPATCH request.""" - if not self.access(user, path, "w"): + if not self._access(user, path, "w"): return httputils.NOT_ALLOWED try: - xml_content = self.read_xml_content(environ) + xml_content = self._read_xml_content(environ) except RuntimeError as e: logger.warning( "Bad PROPPATCH request on %r: %s", path, e, exc_info=True) @@ -102,7 +102,7 @@ class ApplicationProppatchMixin: item = next(self._storage.discover(path), None) if not item: return httputils.NOT_FOUND - if not self.access(user, path, "w", item): + if not self._access(user, path, "w", item): return httputils.NOT_ALLOWED if not isinstance(item, storage.BaseCollection): return httputils.FORBIDDEN @@ -116,4 +116,4 @@ class ApplicationProppatchMixin: "Bad PROPPATCH request on %r: %s", path, e, exc_info=True) return httputils.BAD_REQUEST return (client.MULTI_STATUS, headers, - self.write_xml_content(xml_answer)) + self._write_xml_content(xml_answer)) diff --git a/radicale/app/put.py b/radicale/app/put.py index c0ee164..428244b 100644 --- a/radicale/app/put.py +++ b/radicale/app/put.py @@ -114,10 +114,10 @@ def prepare(vobject_items, path, content_type, permissions, parent_permissions, class ApplicationPutMixin: def do_PUT(self, environ, base_prefix, path, user): """Manage PUT request.""" - if not self.access(user, path, "w"): + if not self._access(user, path, "w"): return httputils.NOT_ALLOWED try: - content = self.read_content(environ) + content = self._read_content(environ) except RuntimeError as e: logger.warning("Bad PUT request on %r: %s", path, e, exc_info=True) return httputils.BAD_REQUEST @@ -201,7 +201,7 @@ class ApplicationPutMixin: prepared_item, = prepared_items if (item and item.uid != prepared_item.uid or not item and parent_item.has_uid(prepared_item.uid)): - return self.webdav_error_response( + return self._webdav_error_response( "C" if tag == "VCALENDAR" else "CR", "no-uid-conflict") diff --git a/radicale/app/report.py b/radicale/app/report.py index d01170b..48a37f8 100644 --- a/radicale/app/report.py +++ b/radicale/app/report.py @@ -257,10 +257,10 @@ def xml_item_response(base_prefix, href, found_props=(), not_found_props=(), class ApplicationReportMixin: def do_REPORT(self, environ, base_prefix, path, user): """Manage REPORT request.""" - if not self.access(user, path, "r"): + if not self._access(user, path, "r"): return httputils.NOT_ALLOWED try: - xml_content = self.read_xml_content(environ) + xml_content = self._read_xml_content(environ) except RuntimeError as e: logger.warning( "Bad REPORT request on %r: %s", path, e, exc_info=True) @@ -273,7 +273,7 @@ class ApplicationReportMixin: item = next(self._storage.discover(path), None) if not item: return httputils.NOT_FOUND - if not self.access(user, path, "r", item): + if not self._access(user, path, "r", item): return httputils.NOT_ALLOWED if isinstance(item, storage.BaseCollection): collection = item @@ -288,4 +288,4 @@ class ApplicationReportMixin: logger.warning( "Bad REPORT request on %r: %s", path, e, exc_info=True) return httputils.BAD_REQUEST - return (status, headers, self.write_xml_content(xml_answer)) + return (status, headers, self._write_xml_content(xml_answer)) diff --git a/radicale/auth/htpasswd.py b/radicale/auth/htpasswd.py index 92a9a4c..7c8d301 100644 --- a/radicale/auth/htpasswd.py +++ b/radicale/auth/htpasswd.py @@ -63,24 +63,24 @@ from radicale import auth class Auth(auth.BaseAuth): def __init__(self, configuration): super().__init__(configuration) - self.filename = configuration.get("auth", "htpasswd_filename") - self.encryption = configuration.get("auth", "htpasswd_encryption") + self._filename = configuration.get("auth", "htpasswd_filename") + encryption = configuration.get("auth", "htpasswd_encryption") - if self.encryption == "ssha": - self.verify = self._ssha - elif self.encryption == "sha1": - self.verify = self._sha1 - elif self.encryption == "plain": - self.verify = self._plain - elif self.encryption == "md5": + if encryption == "ssha": + self._verify = self._ssha + elif encryption == "sha1": + self._verify = self._sha1 + elif encryption == "plain": + self._verify = self._plain + elif encryption == "md5": try: from passlib.hash import apr_md5_crypt except ImportError as e: raise RuntimeError( "The htpasswd encryption method 'md5' requires " "the passlib module.") from e - self.verify = functools.partial(self._md5apr1, apr_md5_crypt) - elif self.encryption == "bcrypt": + self._verify = functools.partial(self._md5apr1, apr_md5_crypt) + elif encryption == "bcrypt": try: from passlib.hash import bcrypt except ImportError as e: @@ -91,19 +91,18 @@ class Auth(auth.BaseAuth): # good error message if bcrypt backend is not available. Trigger # this here. bcrypt.hash("test-bcrypt-backend") - self.verify = functools.partial(self._bcrypt, bcrypt) - elif self.encryption == "crypt": + self._verify = functools.partial(self._bcrypt, bcrypt) + elif encryption == "crypt": try: import crypt except ImportError as e: raise RuntimeError( "The htpasswd encryption method 'crypt' requires " "the crypt() system support.") from e - self.verify = functools.partial(self._crypt, crypt) + self._verify = functools.partial(self._crypt, crypt) else: - raise RuntimeError( - "The htpasswd encryption method %r is not " - "supported." % self.encryption) + raise RuntimeError("The htpasswd encryption method %r is not " + "supported." % encryption) def _plain(self, hash_value, password): """Check if ``hash_value`` and ``password`` match, plain method.""" @@ -162,7 +161,7 @@ class Auth(auth.BaseAuth): """ try: - with open(self.filename) as f: + with open(self._filename) as f: for line in f: line = line.rstrip("\n") if line.lstrip() and not line.lstrip().startswith("#"): @@ -172,13 +171,13 @@ class Auth(auth.BaseAuth): # Always compare both login and password to avoid # timing attacks, see #591. login_ok = hmac.compare_digest(hash_login, login) - password_ok = self.verify(hash_value, password) + password_ok = self._verify(hash_value, password) if login_ok and password_ok: return login except ValueError as e: raise RuntimeError("Invalid htpasswd file %r: %s" % - (self.filename, e)) from e + (self._filename, e)) from e except OSError as e: raise RuntimeError("Failed to load htpasswd file %r: %s" % - (self.filename, e)) from e + (self._filename, e)) from e return "" diff --git a/radicale/rights/from_file.py b/radicale/rights/from_file.py index 6a20381..4dffb8a 100644 --- a/radicale/rights/from_file.py +++ b/radicale/rights/from_file.py @@ -43,7 +43,7 @@ from radicale.log import logger class Rights(rights.BaseRights): def __init__(self, configuration): super().__init__(configuration) - self.filename = configuration.get("rights", "file") + self._filename = configuration.get("rights", "file") def authorized(self, user, path, permissions): user = user or "" @@ -54,12 +54,12 @@ class Rights(rights.BaseRights): rights_config = configparser.ConfigParser( {"login": user_escaped, "path": sane_path_escaped}) try: - if not rights_config.read(self.filename): + if not rights_config.read(self._filename): raise RuntimeError("No such file: %r" % - self.filename) + self._filename) except Exception as e: raise RuntimeError("Failed to load rights file %r: %s" % - (self.filename, e)) from e + (self._filename, e)) from e for section in rights_config.sections(): try: user_pattern = rights_config.get(section, "user") @@ -70,7 +70,7 @@ class Rights(rights.BaseRights): *map(re.escape, user_match.groups())), sane_path) except Exception as e: raise RuntimeError("Error in section %r of rights file %r: " - "%s" % (section, self.filename, e)) from e + "%s" % (section, self._filename, e)) from e if user_match and collection_match: logger.debug("Rule %r:%r matches %r:%r from section %r", user, sane_path, user_pattern,