From f9836ab093fe527390568c0dc99c020855ec219e Mon Sep 17 00:00:00 2001 From: Guillaume Ayoub Date: Mon, 13 Jun 2011 22:15:52 +0200 Subject: [PATCH] Clean support of public calendars, add support of private calendars --- NEWS | 2 +- config | 4 ++++ radicale/__init__.py | 21 ++++++++++++++------- radicale/acl/LDAP.py | 6 +++--- radicale/acl/__init__.py | 16 ++++++++++++++++ radicale/acl/htpasswd.py | 4 ++-- radicale/config.py | 2 ++ 7 files changed, 42 insertions(+), 13 deletions(-) diff --git a/NEWS b/NEWS index 2ac2108..491d0a0 100644 --- a/NEWS +++ b/NEWS @@ -14,7 +14,7 @@ * Smart, verbose and configurable logs * Apple iCal 4 and iPhone support (by Łukasz Langa) * LDAP auth backend (by Corentin Le Bail) -* Owner-less calendars (by René Neumann) +* Public and private calendars (by René Neumann) * PID file * Journal entries support * Drop Python 2.5 support diff --git a/config b/config index 49e4d90..8f7b616 100644 --- a/config +++ b/config @@ -36,6 +36,10 @@ stock = utf-8 # Access method # Value: None | htpasswd | LDAP type = None +# Usernames used for public calendars, separated by a comma +public_users = public +# Usernames used for private calendars, separated by a comma +private_users = private # Htpasswd filename htpasswd_filename = /etc/radicale/users # Htpasswd encryption method diff --git a/radicale/__init__.py b/radicale/__init__.py index 74ab55d..c82c125 100644 --- a/radicale/__init__.py +++ b/radicale/__init__.py @@ -183,17 +183,24 @@ class Application(object): if last_allowed: calendars.append(calendar) continue - log.LOGGER.info( - "Checking rights for calendar owned by %s" % ( - calendar.owner or "nobody")) - if self.acl.has_right(calendar.owner, user, password): - log.LOGGER.info("%s allowed" % (user or "anonymous user")) + if calendar.owner in acl.PUBLIC_USERS: + log.LOGGER.info("Public calendar") calendars.append(calendar) last_allowed = True else: - log.LOGGER.info("%s refused" % (user or "anonymous user")) - last_allowed = False + log.LOGGER.info( + "Checking rights for calendar owned by %s" % ( + calendar.owner or "nobody")) + if self.acl.has_right(calendar.owner, user, password): + log.LOGGER.info( + "%s allowed" % (user or "Anonymous user")) + calendars.append(calendar) + last_allowed = True + else: + log.LOGGER.info( + "%s refused" % (user or "Anonymous user")) + last_allowed = False if calendars: status, headers, answer = function(environ, calendars, content) diff --git a/radicale/acl/LDAP.py b/radicale/acl/LDAP.py index 16162b9..dfde79f 100644 --- a/radicale/acl/LDAP.py +++ b/radicale/acl/LDAP.py @@ -26,7 +26,7 @@ Authentication based on the ``python-ldap`` module """ import ldap -from radicale import config, log +from radicale import acl, config, log BASE = config.get("acl", "ldap_base") @@ -38,8 +38,8 @@ PASSWORD = config.get("acl", "ldap_password") def has_right(owner, user, password): """Check if ``user``/``password`` couple is valid.""" - if not user or (owner and user != owner): - # No user given, or owner is set and is not user, forbidden + if not user or (owner not in acl.PRIVATE_USERS and user != owner): + # No user given, or owner is not private and is not user, forbidden return False if BINDDN and PASSWORD: diff --git a/radicale/acl/__init__.py b/radicale/acl/__init__.py index 6745c76..f9166c3 100644 --- a/radicale/acl/__init__.py +++ b/radicale/acl/__init__.py @@ -29,11 +29,27 @@ configuration. from radicale import config +PUBLIC_USERS = [] +PRIVATE_USERS = [None] + + +def _config_users(name): + """Get an iterable of strings from the configuraton string [acl] ``name``. + + The values must be separated by a comma. The whitespace characters are + stripped at the beginning and at the end of the values. + + """ + return (user.strip() for user in config.get("acl", name).split(",")) + + def load(): """Load list of available ACL managers.""" acl_type = config.get("acl", "type") if acl_type == "None": return None else: + PUBLIC_USERS.extend(_config_users("public_users")) + PRIVATE_USERS.extend(_config_users("private_users")) module = __import__("radicale.acl", fromlist=[acl_type]) return getattr(module, acl_type) diff --git a/radicale/acl/htpasswd.py b/radicale/acl/htpasswd.py index d100049..e624e91 100644 --- a/radicale/acl/htpasswd.py +++ b/radicale/acl/htpasswd.py @@ -30,7 +30,7 @@ supported, but md5 is not (see ``htpasswd`` man page to understand why). import base64 import hashlib -from radicale import config +from radicale import acl, config FILENAME = config.get("acl", "htpasswd_filename") @@ -63,6 +63,6 @@ def has_right(owner, user, password): for line in open(FILENAME).readlines(): if line.strip(): login, hash_value = line.strip().split(":") - if login == user and (not owner or owner == user): + if login == user and (owner in acl.PRIVATE_USERS or owner == user): return globals()["_%s" % ENCRYPTION](hash_value, password) return False diff --git a/radicale/config.py b/radicale/config.py index 5204f4c..63cab7b 100644 --- a/radicale/config.py +++ b/radicale/config.py @@ -50,6 +50,8 @@ INITIAL_CONFIG = { "stock": "utf-8"}, "acl": { "type": "None", + "public_users": "public", + "private_users": "private", "httpasswd_filename": "/etc/radicale/users", "httpasswd_encryption": "crypt", "ldap_url": "ldap://localhost:389/",