Merge remote-tracking branch 'upstream/master'
Conflicts: radicale/__init__.py radicale/acl/courier.py
This commit is contained in:
commit
55a13d4c39
17
.project
Normal file
17
.project
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>Radicale</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.python.pydev.PyDevBuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.python.pydev.pythonNature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
10
.pydevproject
Normal file
10
.pydevproject
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<?eclipse-pydev version="1.0"?>
|
||||||
|
|
||||||
|
<pydev_project>
|
||||||
|
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
|
||||||
|
<path>/Radicale</path>
|
||||||
|
</pydev_pathproperty>
|
||||||
|
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
|
||||||
|
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
|
||||||
|
</pydev_project>
|
4
.settings/org.eclipse.core.resources.prefs
Normal file
4
.settings/org.eclipse.core.resources.prefs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#Sat Aug 04 10:58:22 CEST 2012
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
encoding//radicale/__init__.py=utf-8
|
||||||
|
encoding//radicale/__main__.py=utf-8
|
12
NEWS.rst
12
NEWS.rst
@ -3,6 +3,18 @@
|
|||||||
======
|
======
|
||||||
|
|
||||||
|
|
||||||
|
0.7.1 - Waterfalls
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Many address books fixes
|
||||||
|
* New IMAP ACL (by Daniel Aleksandersen)
|
||||||
|
* PAM ACL fixed (by Daniel Aleksandersen)
|
||||||
|
* Courier ACL fixed (by Benjamin Frank)
|
||||||
|
* Always set display name to collections (by Oskari Timperi)
|
||||||
|
* Various DELETE responses fixed
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
0.7 - Eternal Sunshine
|
0.7 - Eternal Sunshine
|
||||||
======================
|
======================
|
||||||
|
|
||||||
|
@ -216,20 +216,29 @@ class Application(object):
|
|||||||
|
|
||||||
if access.is_authenticated(user, password):
|
if access.is_authenticated(user, password):
|
||||||
|
|
||||||
collections = []
|
last_collection_allowed = None
|
||||||
for collection in items:
|
allowed_items = []
|
||||||
log.LOGGER.debug("Testing %s" % (collection.name))
|
for item in items:
|
||||||
if not isinstance(collection, ical.Collection):
|
log.LOGGER.debug("Testing %s" % (item.name))
|
||||||
log.LOGGER.info("not a collection: " + collection.name)
|
if not isinstance(item, ical.Collection):
|
||||||
|
# item is not a colleciton, it's the child of the last
|
||||||
|
# collection we've met in the loop. Only add this item if
|
||||||
|
# this last collection was allowed. log.LOGGER.info("not a collection: " + collection.name)
|
||||||
# collections.append(collection)
|
# collections.append(collection)
|
||||||
elif access.may_read(user, collection) or access.may_write(user, collection):
|
if last_collection_allowed:
|
||||||
log.LOGGER.info("Has access to " + collection.name)
|
allowed_items.append(item)
|
||||||
collections.append(collection)
|
else:
|
||||||
|
if access.may_read(user, item) or access.may_write(user, item):
|
||||||
|
log.LOGGER.info(user + "has access to " + item.name)
|
||||||
|
last_collection_allowed = True
|
||||||
|
allowed_items.append(item)
|
||||||
|
else:
|
||||||
|
last_collection_allowed = False
|
||||||
|
|
||||||
if collections:
|
if allowed_items:
|
||||||
# Collections found
|
# Collections found
|
||||||
status, headers, answer = function(
|
status, headers, answer = function(
|
||||||
environ, collections, content, user)
|
environ, allowed_items, content, user)
|
||||||
else:
|
else:
|
||||||
# Good user and no collections found, redirect user to home
|
# Good user and no collections found, redirect user to home
|
||||||
location = "/%s/" % str(quote(user))
|
location = "/%s/" % str(quote(user))
|
||||||
@ -241,7 +250,7 @@ class Application(object):
|
|||||||
else:
|
else:
|
||||||
# Send answer anyway since else we're getting into a redirect loop
|
# Send answer anyway since else we're getting into a redirect loop
|
||||||
status, headers, answer = function(
|
status, headers, answer = function(
|
||||||
environ, collections, content, user)
|
environ, allowed_items, content, user)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
|
@ -91,6 +91,8 @@ def run():
|
|||||||
|
|
||||||
# Fork if Radicale is launched as daemon
|
# Fork if Radicale is launched as daemon
|
||||||
if options.daemon:
|
if options.daemon:
|
||||||
|
if options.pid and os.path.exists(options.pid):
|
||||||
|
raise OSError("PID file exists: %s" % options.pid)
|
||||||
pid = os.fork()
|
pid = os.fork()
|
||||||
if pid:
|
if pid:
|
||||||
try:
|
try:
|
||||||
|
@ -33,7 +33,7 @@ def is_authenticated(user, password):
|
|||||||
"""Check if ``user``/``password`` couple is valid."""
|
"""Check if ``user``/``password`` couple is valid."""
|
||||||
|
|
||||||
line = "%s\nlogin\n%s\n%s" % (sys.argv[0], user, password)
|
line = "%s\nlogin\n%s\n%s" % (sys.argv[0], user, password)
|
||||||
line = "%i\n%s" % (len(line), line)
|
line = "AUTH %i\n%s" % (len(line), line)
|
||||||
try:
|
try:
|
||||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
sock.connect(COURIER_SOCKET)
|
sock.connect(COURIER_SOCKET)
|
||||||
@ -48,7 +48,13 @@ def is_authenticated(user, password):
|
|||||||
|
|
||||||
log.LOGGER.debug("Got Courier socket response: %r" % data)
|
log.LOGGER.debug("Got Courier socket response: %r" % data)
|
||||||
|
|
||||||
if repr(data) == "FAIL":
|
# Address, HOME, GID, and either UID or USERNAME are mandatory in resposne
|
||||||
return False
|
# see http://www.courier-mta.org/authlib/README_authlib.html#authpipeproto
|
||||||
|
for line in data.split():
|
||||||
|
if 'GID' in line:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
# default is reject
|
||||||
|
# this alleviates the problem of a possibly empty reply from authlib
|
||||||
|
# see http://www.courier-mta.org/authlib/README_authlib.html#authpipeproto
|
||||||
|
return False
|
||||||
|
@ -422,8 +422,7 @@ def report(path, xml_request, collection):
|
|||||||
props = [prop.tag for prop in prop_element]
|
props = [prop.tag for prop in prop_element]
|
||||||
|
|
||||||
if collection:
|
if collection:
|
||||||
if root.tag in (
|
if root.tag in (_tag("C", "calendar-multiget"),
|
||||||
_tag("C", "calendar-multiget"),
|
|
||||||
_tag("CR", "addressbook-multiget")):
|
_tag("CR", "addressbook-multiget")):
|
||||||
# Read rfc4791-7.9 for info
|
# Read rfc4791-7.9 for info
|
||||||
hreferences = set(
|
hreferences = set(
|
||||||
@ -472,8 +471,8 @@ def report(path, xml_request, collection):
|
|||||||
element = ET.Element(tag)
|
element = ET.Element(tag)
|
||||||
if tag == _tag("D", "getetag"):
|
if tag == _tag("D", "getetag"):
|
||||||
element.text = item.etag
|
element.text = item.etag
|
||||||
elif tag in (
|
elif tag in (_tag("C", "calendar-data"),
|
||||||
_tag("C", "calendar-data"), _tag("CR", "address-data")):
|
_tag("CR", "address-data")):
|
||||||
if isinstance(item, ical.Component):
|
if isinstance(item, ical.Component):
|
||||||
element.text = ical.serialize(
|
element.text = ical.serialize(
|
||||||
collection_tag, collection_headers,
|
collection_tag, collection_headers,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user