Merge branch 'master' of git://gitorious.org/~clebail/radicale/ares-radicale

Conflicts:
	radicale/xmlutils.py
This commit is contained in:
System User 2011-02-17 10:42:02 +01:00
commit bb7f36fc59
6 changed files with 57 additions and 38 deletions

11
config
View File

@ -52,11 +52,10 @@ LDAPAppend = ou=users,dc=exmaple,dc=dom
# created if not present # created if not present
folder = ~/.config/radicale/calendars folder = ~/.config/radicale/calendars
[logging] [Logging]
# Full path of logfile # Logging filename
file = ~/.config/radicale/radicale.log logfile = ~/.config/radicale/radicale.log
# Logging messages which are less severe than level will be ignored # Log facility 10: DEBUG, 20: INFO, 30 WARNING, 40 ERROR, 50 CRITICAL
# Log level are (debug, info, warning, error, critical) facility = 50
level = error
# vim:ft=cfg # vim:ft=cfg

View File

@ -53,6 +53,7 @@ VERSION = "git"
def _check(request, function): def _check(request, function):
"""Check if user has sufficient rights for performing ``request``.""" """Check if user has sufficient rights for performing ``request``."""
log.log(10, "Check if user has sufficient rights for performing ``request``.")
# ``_check`` decorator can access ``request`` protected functions # ``_check`` decorator can access ``request`` protected functions
# pylint: disable=W0212 # pylint: disable=W0212
@ -69,8 +70,10 @@ def _check(request, function):
user = password = None user = password = None
if request.server.acl.has_right(request._calendar.owner, user, password): if request.server.acl.has_right(request._calendar.owner, user, password):
log.log(20, "Sufficient rights for performing ``request``.")
function(request) function(request)
else: else:
log.log(40, "No sufficient rights for performing ``request``.")
request.send_response(client.UNAUTHORIZED) request.send_response(client.UNAUTHORIZED)
request.send_header( request.send_header(
"WWW-Authenticate", "WWW-Authenticate",
@ -87,6 +90,7 @@ class HTTPServer(server.HTTPServer):
# pylint: disable=W0231 # pylint: disable=W0231
def __init__(self, address, handler): def __init__(self, address, handler):
"""Create server.""" """Create server."""
log.log(10, "Create HTTP server.")
server.HTTPServer.__init__(self, address, handler) server.HTTPServer.__init__(self, address, handler)
self.acl = acl.load() self.acl = acl.load()
# pylint: enable=W0231 # pylint: enable=W0231
@ -98,6 +102,7 @@ class HTTPSServer(HTTPServer):
def __init__(self, address, handler): def __init__(self, address, handler):
"""Create server by wrapping HTTP socket in an SSL socket.""" """Create server by wrapping HTTP socket in an SSL socket."""
log.log(10, "Create server by wrapping HTTP socket in an SSL socket.")
# Fails with Python 2.5, import if needed # Fails with Python 2.5, import if needed
# pylint: disable=F0401 # pylint: disable=F0401
import ssl import ssl
@ -116,6 +121,7 @@ class HTTPSServer(HTTPServer):
class CalendarHTTPHandler(server.BaseHTTPRequestHandler): class CalendarHTTPHandler(server.BaseHTTPRequestHandler):
"""HTTP requests handler for calendars.""" """HTTP requests handler for calendars."""
log.log(10, "HTTP requests handler for calendars.")
_encoding = config.get("encoding", "request") _encoding = config.get("encoding", "request")
# Decorator checking rights before performing request # Decorator checking rights before performing request
@ -124,6 +130,7 @@ class CalendarHTTPHandler(server.BaseHTTPRequestHandler):
@property @property
def _calendar(self): def _calendar(self):
"""The ``ical.Calendar`` object corresponding to the given path.""" """The ``ical.Calendar`` object corresponding to the given path."""
log.log(10, "The ``ical.Calendar`` object corresponding to the given path.")
# ``self.path`` must be something like a posix path # ``self.path`` must be something like a posix path
# ``normpath`` should clean malformed and malicious request paths # ``normpath`` should clean malformed and malicious request paths
attributes = posixpath.normpath(self.path.strip("/")).split("/") attributes = posixpath.normpath(self.path.strip("/")).split("/")
@ -133,6 +140,7 @@ class CalendarHTTPHandler(server.BaseHTTPRequestHandler):
def _decode(self, text): def _decode(self, text):
"""Try to decode text according to various parameters.""" """Try to decode text according to various parameters."""
log.log(10, "Try to decode text according to various parameters.")
# List of charsets to try # List of charsets to try
charsets = [] charsets = []
@ -159,6 +167,7 @@ class CalendarHTTPHandler(server.BaseHTTPRequestHandler):
def do_GET(self): def do_GET(self):
"""Manage GET request.""" """Manage GET request."""
log.log(10, "Manage GET request.")
self.do_HEAD() self.do_HEAD()
if self._answer: if self._answer:
self.wfile.write(self._answer) self.wfile.write(self._answer)
@ -166,6 +175,7 @@ class CalendarHTTPHandler(server.BaseHTTPRequestHandler):
@check_rights @check_rights
def do_HEAD(self): def do_HEAD(self):
"""Manage HEAD request.""" """Manage HEAD request."""
log.log(10, "Manage HEAD request.")
item_name = xmlutils.name_from_path(self.path) item_name = xmlutils.name_from_path(self.path)
if item_name: if item_name:
# Get calendar item # Get calendar item
@ -196,6 +206,7 @@ class CalendarHTTPHandler(server.BaseHTTPRequestHandler):
@check_rights @check_rights
def do_DELETE(self): def do_DELETE(self):
"""Manage DELETE request.""" """Manage DELETE request."""
log.log(10, "Manage DELETE request.")
item = self._calendar.get_item(xmlutils.name_from_path(self.path)) item = self._calendar.get_item(xmlutils.name_from_path(self.path))
if item and self.headers.get("If-Match", item.etag) == item.etag: if item and self.headers.get("If-Match", item.etag) == item.etag:
# No ETag precondition or precondition verified, delete item # No ETag precondition or precondition verified, delete item
@ -217,6 +228,7 @@ class CalendarHTTPHandler(server.BaseHTTPRequestHandler):
def do_OPTIONS(self): def do_OPTIONS(self):
"""Manage OPTIONS request.""" """Manage OPTIONS request."""
log.log(10, "Manage OPTIONS request.")
self.send_response(client.OK) self.send_response(client.OK)
self.send_header( self.send_header(
"Allow", "DELETE, HEAD, GET, MKCALENDAR, " "Allow", "DELETE, HEAD, GET, MKCALENDAR, "
@ -226,6 +238,7 @@ class CalendarHTTPHandler(server.BaseHTTPRequestHandler):
def do_PROPFIND(self): def do_PROPFIND(self):
"""Manage PROPFIND request.""" """Manage PROPFIND request."""
log.log(10, "Manage PROPFIND request.")
xml_request = self.rfile.read(int(self.headers["Content-Length"])) xml_request = self.rfile.read(int(self.headers["Content-Length"]))
self._answer = xmlutils.propfind( self._answer = xmlutils.propfind(
self.path, xml_request, self._calendar, self.path, xml_request, self._calendar,
@ -241,6 +254,7 @@ class CalendarHTTPHandler(server.BaseHTTPRequestHandler):
@check_rights @check_rights
def do_PUT(self): def do_PUT(self):
"""Manage PUT request.""" """Manage PUT request."""
log.log(10, "Manage PUT request.")
item_name = xmlutils.name_from_path(self.path) item_name = xmlutils.name_from_path(self.path)
item = self._calendar.get_item(item_name) item = self._calendar.get_item(item_name)
if (not item and not self.headers.get("If-Match")) or \ if (not item and not self.headers.get("If-Match")) or \
@ -264,6 +278,7 @@ class CalendarHTTPHandler(server.BaseHTTPRequestHandler):
@check_rights @check_rights
def do_REPORT(self): def do_REPORT(self):
"""Manage REPORT request.""" """Manage REPORT request."""
log.log(10, "Manage REPORT request.")
xml_request = self.rfile.read(int(self.headers["Content-Length"])) xml_request = self.rfile.read(int(self.headers["Content-Length"]))
self._answer = xmlutils.report(self.path, xml_request, self._calendar) self._answer = xmlutils.report(self.path, xml_request, self._calendar)
@ -272,4 +287,7 @@ class CalendarHTTPHandler(server.BaseHTTPRequestHandler):
self.end_headers() self.end_headers()
self.wfile.write(self._answer) self.wfile.write(self._answer)
def log_message(self, format, *args):
log.log(10, format % (args))
# pylint: enable=C0103 # pylint: enable=C0103

View File

@ -12,12 +12,15 @@ def has_right(owner, user, password):
if owner != user: if owner != user:
return False return False
try: try:
log.log(10, "Open LDAP server connexion")
l=ldap.open(LDAPSERVER, 389) l=ldap.open(LDAPSERVER, 389)
dn="%s%s,%s" % (LDAPPREPEND, user, LDAPAPPEND) cn="%s%s,%s" % (LDAPPREPEND, user, LDAPAPPEND)
l.simple_bind_s(dn, password); log.log(10, "LDAP bind with dn: %s" %(cn))
l.simple_bind_s(cn, password);
log.log(20, "LDAP bind Ok")
return True return True
except: except:
log.error(sys.exc_info()[0]) log.log(40, "LDAP bind error")
return False return False
LDAPSERVER = config.get("authLdap", "LDAPServer") LDAPSERVER = config.get("authLdap", "LDAPServer")

View File

@ -55,14 +55,13 @@ INITIAL_CONFIG = {
"encryption": "crypt"}, "encryption": "crypt"},
"storage": { "storage": {
"folder": os.path.expanduser("~/.config/radicale/calendars")}, "folder": os.path.expanduser("~/.config/radicale/calendars")},
"logging": {
"logfile": os.path.expanduser("~/.config/radicale/radicale.log"),
"facility": 10},
"authLdap": { "authLdap": {
"LDAPServer": "127.0.0.1", "LDAPServer": "127.0.0.1",
"LDAPPrepend": "uid=", "LDAPPrepend": "uid=",
"LDAPAppend": "ou=users,dc=example,dc=com"}, "LDAPAppend": "ou=users,dc=example,dc=com"}}
"logging": {
"file": os.path.expanduser("~/.config/radicale/radicale.log"),
"level": "error"}
}
# Create a ConfigParser and configure it # Create a ConfigParser and configure it
_CONFIG_PARSER = ConfigParser() _CONFIG_PARSER = ConfigParser()

View File

@ -1,29 +1,23 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import sys import logging, sys
import logging
import os
from radicale import config from radicale import config
LEVELS = { 'debug': logging.DEBUG, class log:
'info': logging.INFO, def __init__(self):
'warning': logging.WARNING, self.logger=logging.getLogger("radicale")
'error': logging.ERROR, self.logger.setLevel(config.get("logging", "facility"))
'critical': logging.CRITICAL}
level=LEVELS.get(config.get("logging", "level"), logging.NOTSET) handler=logging.FileHandler(config.get("logging", "logfile"))
logger=logging.getLogger("radicale") formatter = logging.Formatter('%(name)s %(asctime)s %(levelname)s %(message)s')
logger.setLevel(level=level) handler.setFormatter(formatter)
handler=logging.FileHandler(os.path.expanduser(config.get("logging", "file"))) self.logger.addHandler(handler)
handler.setLevel(level=level) def log(self, level, msg):
self.logger.log(level, msg)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") _LOGGING = log()
handler.setFormatter(formatter) sys.modules[__name__] = _LOGGING
logger.addHandler(handler)
sys.modules[__name__] = logger

View File

@ -29,7 +29,7 @@ in them for XML requests (all but PUT).
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from radicale import client, config, ical from radicale import client, config, ical, log
NAMESPACES = { NAMESPACES = {
@ -45,11 +45,13 @@ def _tag(short_name, local):
def _response(code): def _response(code):
"""Return full W3C names from HTTP status codes.""" """Return full W3C names from HTTP status codes."""
log.log(10, "Return full W3C names from HTTP status codes.")
return "HTTP/1.1 %i %s" % (code, client.responses[code]) return "HTTP/1.1 %i %s" % (code, client.responses[code])
def name_from_path(path): def name_from_path(path):
"""Return Radicale item name from ``path``.""" """Return Radicale item name from ``path``."""
log.log(10, "Return Radicale item name from ``path``.")
path_parts = path.strip("/").split("/") path_parts = path.strip("/").split("/")
return path_parts[-1] if len(path_parts) > 2 else None return path_parts[-1] if len(path_parts) > 2 else None
@ -61,6 +63,7 @@ def delete(path, calendar):
""" """
# Reading request # Reading request
log.log(10, "Read and answer DELETE requests.")
calendar.remove(name_from_path(path)) calendar.remove(name_from_path(path))
# Writing answer # Writing answer
@ -86,6 +89,7 @@ def propfind(path, xml_request, calendar, depth):
""" """
# Reading request # Reading request
log.log(10, "Read and answer PROPFIND requests.")
root = ET.fromstring(xml_request) root = ET.fromstring(xml_request)
prop_element = root.find(_tag("D", "prop")) prop_element = root.find(_tag("D", "prop"))
@ -172,6 +176,7 @@ def propfind(path, xml_request, calendar, depth):
def put(path, ical_request, calendar): def put(path, ical_request, calendar):
"""Read PUT requests.""" """Read PUT requests."""
log.log(10, "Read PUT requests.")
name = name_from_path(path) name = name_from_path(path)
if name in (item.name for item in calendar.items): if name in (item.name for item in calendar.items):
# PUT is modifying an existing item # PUT is modifying an existing item
@ -188,6 +193,7 @@ def report(path, xml_request, calendar):
""" """
# Reading request # Reading request
log.log(10, "Read and answer REPORT requests.")
root = ET.fromstring(xml_request) root = ET.fromstring(xml_request)
prop_element = root.find(_tag("D", "prop")) prop_element = root.find(_tag("D", "prop"))