merge of 'bb27badf50d6df9168d73f3e08a4f10ce3626700'

and 'd63fe31c81597a22c53b5925bcf6bca60fc0e252'

Monotone-Parent: bb27badf50d6df9168d73f3e08a4f10ce3626700
Monotone-Parent: d63fe31c81597a22c53b5925bcf6bca60fc0e252
Monotone-Revision: 4158f1d28c04b0be7b69ff93cf2e4b055de655a2

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2012-05-14T17:11:33
maint-2.0.2
Wolfgang Sourdeau 2012-05-14 17:11:33 +00:00
commit 94aa42a4ab
13 changed files with 374 additions and 122 deletions

View File

@ -5,6 +5,28 @@
IE, we use $$() now so that we can invoke "each" on the result set
without triggering an exception.
2012-05-09 Jean Raby <jraby@inverse.ca>
* SoObjects/Appointments/SOGoAppointmentObject.m (PUTAction):
Delete bitrotten code that could end up duplicating attendees.
Behavior exposed by the new caldav tests
* Tests/Integration/config.py.in
* Tests/Integration/test-caldav-scheduling.py
* Tests/Integration/test-ical.py
* Tests/Integration/test-davacl.py:
Use an unprivileged webdavclient where possible.
This would have uncovered the resources calendar autocreation bug.
* Tests/Integration/test-caldav-scheduling.py:
New tests to excercise somewhat fragile code in dav autoscheduling.
2012-05-09 Jean Raby <jraby@inverse.ca>
* SoObject/SOGo/SOGoParentFolder.m (_createPersonalFolder):
Automatically create the folder if its owner is a resource.
(not if the active user is a resource)
2012-05-09 Ludovic Marcotte <lmarcotte@inverse.ca>
* SoObjects/Mailer/SOGoDraftObject.m - don't encode message/rfc822

5
NEWS
View File

@ -1,4 +1,4 @@
1.3.15 (2012-04-DD)
1.3.15 (2012-05-DD)
-------------------
New Features
- sources address books are now exposed in Apple and iOS AddressBook app
@ -9,6 +9,8 @@ New Features
calculator
- new domain default (SOGoMailCustomFromEnabled) to allow users to change
their "from" and "reply-to" headers
- new domain default (SOGoHideSystemEMail) to hide or not the system
email. This is currently limited to CalDAV operations
Enhancements
- updated Spanish (Argentina), German, Dutch translations
@ -17,6 +19,7 @@ Enhancements
being added to the master event
- replaced the Scriptaculous Javascript framework by jQuery to improve the
drag'n'drop experience
- updated timezone definition files
Bug Fixes
- fixed wrong date validation in preferences module affecting French users

View File

@ -27,6 +27,10 @@
#import "EOQualifier+GCS.h"
#if __GNU_LIBOBJC__ >= 20100911
# define sel_eq(__A__,__B__) sel_isEqual(__A__,__B__)
#endif
@implementation EOQualifier(GCS)
- (void)_appendAndQualifier:(EOAndQualifier *)_q

View File

@ -44,6 +44,10 @@
#import "EOQualifier+GCS.h"
#import "GCSStringFormatter.h"
#if __GNU_LIBOBJC__ >= 20100911
# define sel_eq(__A__,__B__) sel_isEqual(__A__,__B__)
#endif
typedef enum {
noTableRequired = 0,
quickTableRequired = 1,

View File

@ -1891,16 +1891,6 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
// one from the request.
[rq setContent: [[[newEvent parent] versitString] dataUsingEncoding: [rq contentEncoding]]];
}
// A RECURRENCE-ID was removed so there has to be a change in the master event
// We could also have an EXDATE added in the master component of the attendees
// so we always compare the MASTER event.
if (!master)
{
newEvent = [newEvents objectAtIndex: 0];
oldEvent = [oldEvents objectAtIndex: 0];
[self _handleUpdatedEvent: newEvent fromOldEvent: oldEvent];
}
}
//
// else => attendee is responding

View File

@ -157,14 +157,16 @@ static SoSecurityManager *sm = nil;
{
NSArray *roles;
SOGoGCSFolder *folder;
SOGoUser *folderOwner;
roles = [[context activeUser] rolesForObject: self inContext: context];
folderOwner = [SOGoUser userWithLogin: [self ownerInContext: context]];
// We autocreate the calendars if the user is the owner, a superuser or
// if it's a resource as we won't necessarily want to login as a resource
// in order to create its database tables.
if ([roles containsObject: SoRole_Owner] ||
[[context activeUser] isResource])
(folderOwner && [folderOwner isResource]))
{
folder = [subFolderClass objectWithName: @"personal" inContainer: self];
[folder setDisplayName: [self defaultFolderName]];

View File

@ -1,16 +1,24 @@
# setup: username must be super-user or have read-access to PUBLIC events in
# both attendee and delegate's personal calendar
# setup: 4 user are needed: username, superuser, attendee1, attendee1_delegate
# superuser must be a sogo superuser...
hostname = "localhost"
port = "80"
username = "myuser"
password = "mypass"
superuser = "super"
superuser_password="pass"
subscriber_username = "otheruser"
subscriber_password = "otherpass"
attendee1 = "user@domain.com"
attendee1_delegate = "otheruser@domain.com"
attendee1_username = "user"
attendee1_password = "pass"
attendee1_delegate = "user2@domain.com"
attendee1_delegate_username = "sogo2"
attendee1_delegate_password = "sogo"
resource_no_overbook = "res"
resource_can_overbook = "res-nolimit"

View File

@ -1,10 +1,15 @@
#!/usr/bin/python
# setup: username must be super-user or have read-access to PUBLIC events in
# both attendee and delegate's personal calendar
# setup: 4 users are needed: username, attendee1_username,
# attendee1_delegate_username and superuser.
# when writing new tests, avoid using superuser when not absolutely needed
from config import hostname, port, username, password, \
attendee1, attendee1_delegate, \
superuser, superuser_password, \
attendee1, attendee1_username, \
attendee1_password, \
attendee1_delegate, attendee1_delegate_username, \
attendee1_delegate_password, \
resource_no_overbook, resource_can_overbook
import datetime
@ -98,10 +103,17 @@ class CalDAVPropertiesTest(unittest.TestCase):
% (proppatch.response["status"],
proppatch.response["body"]))
class CalDAVITIPDelegationTest(unittest.TestCase):
class CalDAVSchedulingTest(unittest.TestCase):
def setUp(self):
self.superuser_client = webdavlib.WebDAVClient(hostname, port,
superuser, superuser_password)
self.client = webdavlib.WebDAVClient(hostname, port,
username, password)
self.attendee1_client = webdavlib.WebDAVClient(hostname, port,
attendee1_username, attendee1_password)
self.attendee1_delegate_client = webdavlib.WebDAVClient(hostname, port,
attendee1_delegate_username, attendee1_password)
utility = utilities.TestUtility(self, self.client)
(self.user_name, self.user_email) = utility.fetchUserInfo(username)
(self.attendee1_name, self.attendee1_email) = utility.fetchUserInfo(attendee1)
@ -113,18 +125,24 @@ class CalDAVITIPDelegationTest(unittest.TestCase):
self.attendee1_calendar = "/SOGo/dav/%s/Calendar/personal/" % attendee1
self.attendee1_delegate_calendar = "/SOGo/dav/%s/Calendar/personal/" % attendee1_delegate
# fetch non existing event to let sogo create the calendars in the db
self._getEvent(self.client, "%snonexistent" % self.user_calendar, exp_status=404)
self._getEvent(self.attendee1_client, "%snonexistent" % self.attendee1_calendar, exp_status=404)
self._getEvent(self.attendee1_delegate_client, "%snonexistent" %
self.attendee1_delegate_calendar, exp_status=404)
def tearDown(self):
self._deleteEvent(self.client,
"%stest-delegation.ics" % self.user_calendar, None)
self._deleteEvent(self.client,
self._deleteEvent(self.attendee1_client,
"%stest-delegation.ics" % self.attendee1_calendar, None)
self._deleteEvent(self.client,
self._deleteEvent(self.attendee1_delegate_client,
"%stest-delegation.ics" % self.attendee1_delegate_calendar,
None)
self._deleteEvent(self.client,
"%stest-add-attendee.ics" % self.user_calendar, None)
self._deleteEvent(self.client,
self._deleteEvent(self.attendee1_client,
"%stest-add-attendee.ics" % self.attendee1_calendar, None)
self._deleteEvent(self.client,
"%stest-no-overbook.ics" % self.user_calendar, None)
@ -135,9 +153,13 @@ class CalDAVITIPDelegationTest(unittest.TestCase):
self._deleteEvent(self.client,
"%stest-can-overbook-overlap.ics" % self.user_calendar, None)
self._deleteEvent(self.client,
"%stest-remove-attendee.ics" % self.user_calendar, None)
"%stest-rrule-exception-invitation-dance.ics" % self.user_calendar, None)
self._deleteEvent(self.attendee1_client,
"%stest-rrule-exception-invitation-dance.ics" % self.attendee1_calendar, None)
self._deleteEvent(self.client,
"%stest-remove-attendee-no-org.ics" % self.user_calendar, None)
"%stest-rrule-invitation-deleted-exdate-dance.ics" % self.user_calendar, None)
self._deleteEvent(self.attendee1_client,
"%stest-rrule-invitation-deleted-exdate-dance.ics" % self.attendee1_calendar, None)
def _newEvent(self, summary="test event", uid="test", transp=0):
transparency = ("OPAQUE", "TRANSPARENT")
@ -156,7 +178,7 @@ class CalDAVITIPDelegationTest(unittest.TestCase):
vevent.add('dtstamp').value = now
vevent.add('last-modified').value = now
vevent.add('created').value = now
vevent.add('class').value = "PUBLIC"
vevent.add('sequence').value = "0"
return newCal
@ -242,6 +264,41 @@ class CalDAVITIPDelegationTest(unittest.TestCase):
% (email,
compared_attendees[email], attendees[email]))
def testAddAttendee(self):
""" add attendee after event creation """
# make sure the event doesn't exist
ics_name = "test-add-attendee.ics"
self._deleteEvent(self.client,
"%s%s" % (self.user_calendar,ics_name), None)
self._deleteEvent(self.attendee1_client,
"%s%s" % (self.attendee1_calendar,ics_name), None)
# 1. create an event in the organiser's calendar
event = self._newEvent(summary="Test add attendee", uid="Test add attendee")
organizer = event.vevent.add('organizer')
organizer.cn_param = self.user_name
organizer.value = self.user_email
self._putEvent(self.client, "%s%s" % (self.user_calendar, ics_name), event)
# 2. add an attendee
event.add("method").value = "REQUEST"
attendee = event.vevent.add('attendee')
attendee.cn_param = self.attendee1_name
attendee.rsvp_param = "TRUE"
attendee.partstat_param = "NEEDS-ACTION"
attendee.value = self.attendee1_email
self._putEvent(self.client, "%s%s" % (self.user_calendar, ics_name), event,
exp_status=204)
# 3. verify that the attendee has the event
attendee_event = self._getEvent(self.attendee1_client, "%s%s" % (self.attendee1_calendar, ics_name))
# 4. make sure the received event match the original one
# XXX is this enough?
self.assertEquals(event.vevent.uid, attendee_event.vevent.uid)
def testUninviteAttendee(self):
""" Remove attendee after event creation """
@ -249,7 +306,7 @@ class CalDAVITIPDelegationTest(unittest.TestCase):
ics_name = "test-remove-attendee.ics"
self._deleteEvent(self.client,
"%s%s" % (self.user_calendar,ics_name), None)
self._deleteEvent(self.client,
self._deleteEvent(self.attendee1_client,
"%s%s" % (self.attendee1_calendar,ics_name), None)
# 1. create an event in the organiser's calendar
@ -275,7 +332,7 @@ class CalDAVITIPDelegationTest(unittest.TestCase):
exp_status=204)
# 3. verify that the attendee has the event
attendee_event = self._getEvent(self.client, "%s%s" % (self.attendee1_calendar, ics_name))
attendee_event = self._getEvent(self.attendee1_client, "%s%s" % (self.attendee1_calendar, ics_name))
# 4. make sure the received event match the original one
self.assertEquals(event.vevent.uid, attendee_event.vevent.uid)
@ -287,92 +344,42 @@ class CalDAVITIPDelegationTest(unittest.TestCase):
exp_status=204)
# 6. verify that the attendee doesn't have the event anymore
attendee_event = self._getEvent(self.client, "%s%s" % (self.attendee1_calendar, ics_name), 404)
attendee_event = self._getEvent(self.attendee1_client, "%s%s" % (self.attendee1_calendar, ics_name), 404)
def testUninviteAttendeeNoOrganizer(self):
""" Remove attendee and organizer after event creation """
def testAddAttendee(self):
""" add attendee after event creation """
# make sure the event doesn't exist
ics_name = "test-remove-attendee-no-org.ics"
ics_name = "test-add-attendee.ics"
self._deleteEvent(self.client,
"%s%s" % (self.user_calendar,ics_name), None)
self._deleteEvent(self.client,
"%s%s" % (self.attendee1_calendar,ics_name), None)
# 1. create an event in the organiser's calendar
event = self._newEvent(summary="Test uninvite attendee no org", uid="Test uninvite attendee no org")
# keep a copy around for updates without other attributes
plainEvent = vobject.iCalendar()
plainEvent.copy(event)
event = self._newEvent(summary="Test add attendee", uid="Test add attendee")
organizer = event.vevent.add('organizer')
organizer.cn_param = self.user_name
organizer.value = self.user_email
self._putEvent(self.client, "%s%s" % (self.user_calendar, ics_name), event)
# 2. add an attendee
event.add("method").value = "REQUEST"
attendee = event.vevent.add('attendee')
attendee.cn_param = self.attendee1_name
attendee.rsvp_param = "TRUE"
attendee.partstat_param = "NEEDS-ACTION"
attendee.value = self.attendee1_email
self._putEvent(self.client, "%s%s" % (self.user_calendar, ics_name), event,
exp_status=204)
exp_status=204)
# 3. verify that the attendee has the event
attendee_event = self._getEvent(self.client, "%s%s" % (self.attendee1_calendar, ics_name))
attendee_event = self._getEvent(self.attendee1_client, "%s%s" % (self.attendee1_calendar, ics_name))
# 4. make sure the received event match the original one
# XXX is this enough?
self.assertEquals(event.vevent.uid, attendee_event.vevent.uid)
# 5. put the event back without attendee or organizer
now = datetime.datetime.now(dateutil.tz.gettz("America/Montreal"))
plainEvent.vevent.last_modified.value = now
self._putEvent(self.client, "%s%s" % (self.user_calendar, ics_name), plainEvent,
exp_status=204)
# 6. verify that the attendee doesn't have the event anymore
attendee_event = self._getEvent(self.client, "%s%s" % (self.attendee1_calendar, ics_name), 404)
def testAddAttendee(self):
""" add attendee after event creation """
# make sure the event doesn't exist
ics_name = "test-add-attendee.ics"
self._deleteEvent(self.client,
"%s%s" % (self.user_calendar,ics_name), None)
self._deleteEvent(self.client,
"%s%s" % (self.attendee1_calendar,ics_name), None)
# 1. create an event in the organiser's calendar
event = self._newEvent(summary="Test add attendee", uid="Test add attendee")
organizer = event.vevent.add('organizer')
organizer.cn_param = self.user_name
organizer.value = self.user_email
self._putEvent(self.client, "%s%s" % (self.user_calendar, ics_name), event)
# 2. add an attendee
event.add("method").value = "REQUEST"
attendee = event.vevent.add('attendee')
attendee.cn_param = self.attendee1_name
attendee.rsvp_param = "TRUE"
attendee.partstat_param = "NEEDS-ACTION"
attendee.value = self.attendee1_email
self._putEvent(self.client, "%s%s" % (self.user_calendar, ics_name), event,
exp_status=204)
# 3. verify that the attendee has the event
attendee_event = self._getEvent(self.client, "%s%s" % (self.attendee1_calendar, ics_name))
# 4. make sure the received event match the original one
# XXX is this enough?
self.assertEquals(event.vevent.uid, attendee_event.vevent.uid)
def testResourceNoOverbook(self):
""" try to overbook a resource """
@ -450,15 +457,221 @@ class CalDAVITIPDelegationTest(unittest.TestCase):
self._putEvent(self.client, "%s%s" % (self.user_calendar, ob_ics_name), event)
def testRruleExceptionInvitationDance(self):
""" RRULE exception invitation dance """
# This workflow is based on what lightning 1.2.1 does
# create a reccurring event
# add an exception
# invite bob to the exception:
# bob is declined in the master event
# bob needs-action in the exception
# bob accepts
# bob is declined in the master event
# bob is accepted in the exception
# the organizer 'uninvites' bob
# the event disappears from bob's calendar
# bob isn't in the master+exception event
ics_name = "test-rrule-exception-invitation-dance.ics"
self._deleteEvent(self.client,
"%s%s" % (self.user_calendar, ics_name), None)
self._deleteEvent(self.attendee1_client,
"%s%s" % (self.attendee1_calendar, ics_name), None)
# 1. create a recurring event in the organiser's calendar
summary="Test reccuring exception invite cancel"
uid="Test-recurring-exception-invite-cancel"
event = self._newEvent(summary, uid)
event.vevent.add('rrule').value = "FREQ=DAILY;COUNT=5"
self._putEvent(self.client, "%s%s" % (self.user_calendar, ics_name), event)
# read the event back from the server
org_ev = self._getEvent(self.client, "%s%s" % (self.user_calendar, ics_name))
# 2. Add an exception to the master event and invite attendee1 to it
now = datetime.datetime.now(dateutil.tz.gettz("America/Montreal"))
org_ev.vevent.last_modified.value = now
orig_dtstart = org_ev.vevent.dtstart.value
orig_dtend = org_ev.vevent.dtend.value
ev_exception = org_ev.add("vevent")
ev_exception.add('created').value = now
ev_exception.add('last-modified').value = now
ev_exception.add('dtstamp').value = now
ev_exception.add('uid').value = uid
ev_exception.add('summary').value = summary
# out of laziness, add the exception for the first occurence of the event
recurrence_id = orig_dtstart
ev_exception.add('recurrence-id').value = recurrence_id
ev_exception.add('transp').value = "OPAQUE"
ev_exception.add('description').value = "Exception"
ev_exception.add('sequence').value = "1"
ev_exception.add('dtstart').value = orig_dtstart
ev_exception.add('dtend').value = orig_dtend
# 2.1 Add attendee1 and organizer to the exception
organizer = ev_exception.add('organizer')
organizer.cn_param = self.user_name
organizer.partstat_param = "ACCEPTED"
organizer.value = self.user_email
attendee = ev_exception.add('attendee')
attendee.cn_param = self.attendee1_name
attendee.rsvp_param = "TRUE"
attendee.role_param = "REQ-PARTICIPANT"
attendee.partstat_param = "NEEDS-ACTION"
attendee.value = self.attendee1_email
self._putEvent(self.client, "%s%s" % (self.user_calendar, ics_name), org_ev,
exp_status=204)
# 3. Make sure the attendee got the event
attendee_ev = self._getEvent(self.attendee1_client, "%s%s" % (self.attendee1_calendar, ics_name))
for ev in attendee_ev.vevent_list:
try:
if (ev.recurrence_id.value):
attendee_ev_exception = ev
except:
attendee_ev_master = ev
# make sure sogo doesn't duplicate attendees - yes, we've seen that
self.assertEquals(len(attendee_ev_master.attendee_list), 1)
self.assertEquals(len(attendee_ev_exception.attendee_list), 1)
# 4. The master event must contain the invitation, declined
self.assertEquals(attendee_ev_master.attendee.partstat_param, "DECLINED")
# 5. The exception event contain the invitation, NEEDS-ACTION
self.assertEquals(attendee_ev_exception.attendee.partstat_param, "NEEDS-ACTION")
# 6. attendee accepts invitation
attendee_ev_exception.attendee.partstat_param = "ACCEPTED"
self._putEvent(self.attendee1_client, "%s%s" % (self.attendee1_calendar, ics_name),
attendee_ev, exp_status=204)
# fetch the organizer's event
org_ev = self._getEvent(self.client, "%s%s" % (self.user_calendar, ics_name))
for ev in org_ev.vevent_list:
try:
if (ev.recurrence_id.value):
org_ev_exception = ev
except:
org_ev_master = ev
# make sure sogo doesn't duplicate attendees
self.assertEquals(len(org_ev_master.attendee_list), 1)
self.assertEquals(len(org_ev_exception.attendee_list), 1)
# 7. Make sure organizer got the accept for the exception and
# that the attendee is still declined in the master
self.assertEquals(org_ev_exception.attendee.partstat_param, "ACCEPTED")
self.assertEquals(org_ev_master.attendee.partstat_param, "DECLINED")
# 8. delete the attendee from the master event (uninvite)
# The event should be deleted from the attendee's calendar
del org_ev_exception.attendee
self._putEvent(self.client, "%s%s" % (self.user_calendar, ics_name),
org_ev, exp_status=204)
del org_ev_master.attendee
self._putEvent(self.client, "%s%s" % (self.user_calendar, ics_name),
org_ev, exp_status=204)
self._getEvent(self.client, "%s%s" % (self.attendee1_calendar, ics_name),
exp_status=404)
# now be happy
def testRruleInvitationDeleteExdate(self):
"""RRULE invitation delete exdate dance"""
# Workflow:
# Create an recurring event and invite Bob
# Add an exdate to the master event
# Verify that the exdate has propagated to Bob's calendar
# Add an exdate to bob's version of the event
# Verify that an exception has been created in the org's calendar
# and that bob is 'declined'
ics_name = "test-rrule-invitation-deleted-exdate-dance.ics"
self._deleteEvent(self.client,
"%s%s" % (self.user_calendar, ics_name), None)
self._deleteEvent(self.attendee1_client,
"%s%s" % (self.attendee1_calendar, ics_name), None)
# 1. create a recurring event in the organiser's calendar
summary="Test-rrule-invitation-deleted-exdate-dance"
uid=summary
event = self._newEvent(summary, uid)
event.vevent.add('rrule').value = "FREQ=DAILY;COUNT=5"
organizer = event.vevent.add('organizer')
organizer.cn_param = self.user_name
organizer.partstat_param = "ACCEPTED"
organizer.value = self.user_email
attendee = event.vevent.add('attendee')
attendee.cn_param = self.attendee1_name
attendee.rsvp_param = "TRUE"
attendee.role_param = "REQ-PARTICIPANT"
attendee.partstat_param = "NEEDS-ACTION"
attendee.value = self.attendee1_email
self._putEvent(self.client, "%s%s" % (self.user_calendar, ics_name), event)
# 2. Make sure the attendee got it
self._getEvent(self.attendee1_client, "%s%s" % (self.attendee1_calendar, ics_name))
# 3. Add exdate to master event
org_ev=self._getEvent(self.client, "%s%s" % (self.user_calendar, ics_name))
orig_dtstart = org_ev.vevent.dtstart.value
# exdate is a list in vobject.icalendar
org_exdate = [orig_dtstart.astimezone(dateutil.tz.gettz("UTC"))]
org_ev.vevent.add('exdate').value = org_exdate
self._putEvent(self.client, "%s%s" % (self.user_calendar, ics_name), org_ev, exp_status=204)
# 4. make sure the attendee has the exdate
attendee_ev = self._getEvent(self.attendee1_client, "%s%s" %
(self.attendee1_calendar, ics_name))
self.assertEqual(org_exdate, attendee_ev.vevent.exdate.value)
# 5. Create an exdate in the attendee's calendar
new_exdate = orig_dtstart + datetime.timedelta(days=2)
attendee_exdate = [new_exdate.astimezone(dateutil.tz.gettz("UTC"))]
attendee_ev.vevent.add('exdate').value = attendee_exdate
now = datetime.datetime.now(dateutil.tz.gettz("America/Montreal"))
attendee_ev.vevent.last_modified.value = now
self._putEvent(self.attendee1_client, "%s%s" % (self.attendee1_calendar, ics_name),
attendee_ev, exp_status=204)
# 6. Make sure the attendee is:
# needs-action in master event
# declined in the new exception created by the exdate above
org_ev=self._getEvent(self.client, "%s%s" % (self.user_calendar, ics_name))
for ev in org_ev.vevent_list:
try:
if (ev.recurrence_id.value == attendee_exdate[0]):
org_ev_exception = ev
except:
org_ev_master = ev
self.assertTrue(org_ev_exception)
# make sure sogo doesn't duplicate attendees
self.assertEquals(len(org_ev_master.attendee_list), 1)
self.assertEquals(len(org_ev_exception.attendee_list), 1)
self.assertEqual(org_ev_master.attendee.partstat_param, "NEEDS-ACTION");
self.assertEqual(org_ev_exception.attendee.partstat_param, "DECLINED");
def testInvitationDelegation(self):
""" invitation delegation """
# the invitation must not exist
self._deleteEvent(self.client,
"%stest-delegation.ics" % self.user_calendar, None)
self._deleteEvent(self.client,
self._deleteEvent(self.attendee1_client,
"%stest-delegation.ics" % self.attendee1_calendar, None)
self._deleteEvent(self.client,
self._deleteEvent(self.attendee1_delegate_client,
"%stest-delegation.ics" % self.attendee1_delegate_calendar,
None)
@ -482,7 +695,7 @@ class CalDAVITIPDelegationTest(unittest.TestCase):
"%stest-delegation.ics" % self.user_calendar,
invitation)
att_inv = self._getEvent(self.client,
att_inv = self._getEvent(self.attendee1_client,
"%stest-delegation.ics"
% self.attendee1_calendar)
self._compareAttendees(att_inv, invitation)
@ -502,19 +715,19 @@ class CalDAVITIPDelegationTest(unittest.TestCase):
delegate.partstat_param = "NEEDS-ACTION"
delegate.value = self.attendee1_delegate_email
self._postEvent(self.client,
self._postEvent(self.attendee1_client,
self.attendee1_calendar, invitation,
self.attendee1_email, [self.attendee1_delegate_email])
invitation.method.value = "REPLY"
self._postEvent(self.client,
self._postEvent(self.attendee1_client,
self.attendee1_calendar, invitation,
self.attendee1_email, [self.user_email])
del invitation.method
self._putEvent(self.client,
self._putEvent(self.attendee1_client,
"%stest-delegation.ics" % self.attendee1_calendar,
invitation, 204)
del_inv = self._getEvent(self.client,
del_inv = self._getEvent(self.attendee1_delegate_client,
"%stest-delegation.ics"
% self.attendee1_delegate_calendar)
self._compareAttendees(del_inv, invitation)
@ -528,18 +741,18 @@ class CalDAVITIPDelegationTest(unittest.TestCase):
invitation.add("method").value = "REPLY"
delegate.partstat_param = "ACCEPTED"
self._postEvent(self.client,
self._postEvent(self.attendee1_delegate_client,
self.attendee1_delegate_calendar, invitation,
self.attendee1_delegate_email, [self.user_email, self.attendee1_email])
del invitation.method
self._putEvent(self.client,
self._putEvent(self.attendee1_delegate_client,
"%stest-delegation.ics" % self.attendee1_delegate_calendar,
invitation, 204)
org_inv = self._getEvent(self.client,
"%stest-delegation.ics" % self.user_calendar)
self._compareAttendees(org_inv, invitation)
att_inv = self._getEvent(self.client,
att_inv = self._getEvent(self.attendee1_client,
"%stest-delegation.ics" % self.attendee1_calendar)
self._compareAttendees(att_inv, invitation)
@ -551,7 +764,7 @@ class CalDAVITIPDelegationTest(unittest.TestCase):
cancellation.copy(invitation)
cancellation.add("method").value = "CANCEL"
cancellation.vevent.sequence.value = "1"
self._postEvent(self.client,
self._postEvent(self.attendee1_client,
self.attendee1_calendar, cancellation,
self.attendee1_email, [self.attendee1_delegate_email])
@ -560,12 +773,12 @@ class CalDAVITIPDelegationTest(unittest.TestCase):
del attendee1.delegated_to_param
invitation.add("method").value = "REPLY"
invitation.vevent.remove(delegate)
self._postEvent(self.client,
self._postEvent(self.attendee1_client,
self.attendee1_calendar, invitation,
self.attendee1_email, [self.user_email])
del invitation.method
self._putEvent(self.client,
self._putEvent(self.attendee1_client,
"%stest-delegation.ics" % self.attendee1_calendar,
invitation, 204)
@ -573,7 +786,7 @@ class CalDAVITIPDelegationTest(unittest.TestCase):
"%stest-delegation.ics" % self.user_calendar)
self._compareAttendees(org_inv, invitation)
del_inv = self._getEvent(self.client,
del_inv = self._getEvent(self.attendee1_delegate_client,
"%stest-delegation.ics" % self.attendee1_delegate_calendar, 404)
# 5. org updates inv.
@ -595,7 +808,7 @@ class CalDAVITIPDelegationTest(unittest.TestCase):
"%stest-delegation.ics" % self.user_calendar,
invitation, 204)
att_inv = self._getEvent(self.client,
att_inv = self._getEvent(self.attendee1_client,
"%stest-delegation.ics" % self.attendee1_calendar)
self._compareAttendees(att_inv, invitation)
@ -613,22 +826,22 @@ class CalDAVITIPDelegationTest(unittest.TestCase):
delegate.partstat_param = "NEEDS-ACTION"
delegate.value = self.attendee1_delegate_email
self._postEvent(self.client,
self._postEvent(self.attendee1_client,
self.attendee1_calendar, invitation,
self.attendee1_email, [self.attendee1_delegate_email])
invitation.method.value = "REPLY"
self._postEvent(self.client,
self._postEvent(self.attendee1_client,
self.attendee1_calendar, invitation,
self.attendee1_email, [self.user_email])
del invitation.method
self._putEvent(self.client,
self._putEvent(self.attendee1_client,
"%stest-delegation.ics" % self.attendee1_calendar,
invitation, 204)
org_inv = self._getEvent(self.client,
"%stest-delegation.ics" % self.user_calendar)
self._compareAttendees(org_inv, invitation)
del_inv = self._getEvent(self.client,
del_inv = self._getEvent(self.attendee1_delegate_client,
"%stest-delegation.ics"
% self.attendee1_delegate_calendar)
self._compareAttendees(del_inv, invitation)
@ -638,19 +851,19 @@ class CalDAVITIPDelegationTest(unittest.TestCase):
invitation.add("method").value = "REPLY"
delegate.partstat_param = "ACCEPTED"
self._postEvent(self.client,
self._postEvent(self.attendee1_delegate_client,
self.attendee1_delegate_calendar, invitation,
self.attendee1_delegate_email, [self.user_email,
self.attendee1_email])
del invitation.method
self._putEvent(self.client,
self._putEvent(self.attendee1_delegate_client,
"%stest-delegation.ics" % self.attendee1_delegate_calendar,
invitation, 204)
org_inv = self._getEvent(self.client,
"%stest-delegation.ics" % self.user_calendar)
self._compareAttendees(org_inv, invitation)
att_inv = self._getEvent(self.client,
att_inv = self._getEvent(self.attendee1_client,
"%stest-delegation.ics" % self.attendee1_calendar)
self._compareAttendees(att_inv, invitation)
@ -674,10 +887,10 @@ class CalDAVITIPDelegationTest(unittest.TestCase):
"%stest-delegation.ics" % self.user_calendar,
invitation, 204)
att_inv = self._getEvent(self.client,
att_inv = self._getEvent(self.attendee1_client,
"%stest-delegation.ics" % self.attendee1_calendar)
self._compareAttendees(att_inv, invitation)
del_inv = self._getEvent(self.client,
del_inv = self._getEvent(self.attendee1_client,
"%stest-delegation.ics" % self.attendee1_calendar)
self._compareAttendees(del_inv, invitation)
@ -702,9 +915,9 @@ class CalDAVITIPDelegationTest(unittest.TestCase):
"%stest-delegation.ics" % self.user_calendar,
invitation, 204)
att_inv = self._getEvent(self.client,
att_inv = self._getEvent(self.attendee1_client,
"%stest-delegation.ics" % self.attendee1_calendar, 404)
del_inv = self._getEvent(self.client,
del_inv = self._getEvent(self.attendee1_delegate_client,
"%stest-delegation.ics" % self.attendee1_delegate_calendar, 404)
if __name__ == "__main__":

View File

@ -1,6 +1,7 @@
#!/usr/bin/python
from config import hostname, port, username, password, subscriber_username, subscriber_password
from config import hostname, port, username, password, subscriber_username, subscriber_password, \
superuser, superuser_password
import sys
import unittest
@ -25,7 +26,7 @@ import utilities
class DAVCalendarSuperUserAclTest(unittest.TestCase):
def __init__(self, arg):
self.client = webdavlib.WebDAVClient(hostname, port,
username, password)
superuser, superuser_password)
self.resource = "/SOGo/dav/%s/Calendar/test-dav-superuser-acl/" % subscriber_username
self.filename = "suevent.ics"
self.url = "%s%s" % (self.resource, self.filename)
@ -949,6 +950,8 @@ class DAVPublicAccessTest(unittest.TestCase):
class DAVCalendarPublicAclTest(unittest.TestCase):
def setUp(self):
self.createdRsrc = None
self.superuser_client = webdavlib.WebDAVClient(hostname, port,
superuser, superuser_password)
self.client = webdavlib.WebDAVClient(hostname, port,
username, password)
self.subscriber_client = webdavlib.WebDAVClient(hostname, port,
@ -959,7 +962,7 @@ class DAVCalendarPublicAclTest(unittest.TestCase):
def tearDown(self):
if self.createdRsrc is not None:
delete = webdavlib.WebDAVDELETE(self.createdRsrc)
self.client.execute(delete)
self.superuser_client.execute(delete)
def testCollectionAccessNormalUser(self):
"""normal user access to (non-)shared resource from su"""
@ -1091,7 +1094,7 @@ class DAVCalendarPublicAclTest(unittest.TestCase):
for rsrc in [ 'personal', 'test-dav-acl' ]:
resource = '%s%s/' % (parentColl, rsrc)
mkcol = webdavlib.WebDAVMKCOL(resource)
self.client.execute(mkcol)
self.superuser_client.execute(mkcol)
acl_utility = utilities.TestCalendarACLUtility(self,
self.subscriber_client,
resource)

View File

@ -1,6 +1,9 @@
#!/usr/bin/python
from config import hostname, port, username, password, subscriber_username
# FIXME: we should avoid using superuser if possible
from config import hostname, port, username, password, subscriber_username, \
superuser, superuser_password
import unittest
import sogotests
@ -48,7 +51,7 @@ class iCalTest(unittest.TestCase):
for x in members ]
props = { "{DAV:}group-member-set": membersHref }
proppatch = webdavlib.WebDAVPROPPATCH(resource, props)
client = webdavlib.WebDAVClient(hostname, port, username, password)
client = webdavlib.WebDAVClient(hostname, port, superuser, superuser_password)
client.user_agent = "DAVKit/4.0.1 (730); CalendarStore/4.0.1 (973); iCal/4.0.1 (1374); Mac OS X/10.6.2 (10C540)"
client.execute(proppatch)
self.assertEquals(proppatch.response["status"], 207,
@ -60,7 +63,7 @@ class iCalTest(unittest.TestCase):
resource = '/SOGo/dav/%s/' % user
propfind = webdavlib.WebDAVPROPFIND(resource,
["{DAV:}group-membership"], 0)
client = webdavlib.WebDAVClient(hostname, port, username, password)
client = webdavlib.WebDAVClient(hostname, port, superuser, superuser_password)
client.user_agent = "DAVKit/4.0.1 (730); CalendarStore/4.0.1 (973); iCal/4.0.1 (1374); Mac OS X/10.6.2 (10C540)"
client.execute(propfind)
@ -73,7 +76,7 @@ class iCalTest(unittest.TestCase):
resource = '/SOGo/dav/%s/' % user
prop = "{http://calendarserver.org/ns/}calendar-proxy-%s-for" % perm
propfind = webdavlib.WebDAVPROPFIND(resource, [prop], 0)
client = webdavlib.WebDAVClient(hostname, port, username, password)
client = webdavlib.WebDAVClient(hostname, port, superuser, superuser_password)
client.user_agent = "DAVKit/4.0.1 (730); CalendarStore/4.0.1 (973); iCal/4.0.1 (1374); Mac OS X/10.6.2 (10C540)"
client.execute(propfind)
@ -136,7 +139,7 @@ class iCalTest(unittest.TestCase):
def testCalendarProxy2(self):
"""calendar-proxy as used from SOGo"""
client = webdavlib.WebDAVClient(hostname, port, username, password)
client = webdavlib.WebDAVClient(hostname, port, superuser, superuser_password)
client.user_agent = "DAVKit/4.0.1 (730); CalendarStore/4.0.1 (973); iCal/4.0.1 (1374); Mac OS X/10.6.2 (10C540)"
personal_resource = "/SOGo/dav/%s/Calendar/personal/" % username
dav_utility = utilities.TestCalendarACLUtility(self,