Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Fake email address for resources and locations.

  • Loading branch information
cyrusdaboo committed Dec 19, 2015
1 parent 43b9a37 commit 88f221c001f5e96b79436fb63d4cd629d22a0272
@@ -1420,6 +1420,10 @@
<key>TrackUnscheduledResourceData</key>
<true/>

<!-- Add fake email addresses to work around client bug -->
<key>FakeResourceLocationEmail</key>
<false/>

<!-- Maximum number of attendees to request freebusy for -->
<key>LimitFreeBusyAttendees</key>
<integer>30</integer>
@@ -3510,6 +3510,10 @@ def normalizeCalendarUserAddresses(
if oldemail:
oldemail = "mailto:{0}".format(oldemail,)

if config.Scheduling.Options.FakeResourceLocationEmail:
if oldemail.endswith("@do_not_reply"):
oldemail = None

# Get any CN parameter
oldCN = prop.parameterValue("CN")

@@ -3583,6 +3587,10 @@ def normalizeCalendarUserAddresses(
else:
email = None

if config.Scheduling.Options.FakeResourceLocationEmail:
if email and email.endswith("@do_not_reply"):
email = ""

if email:
prop.setParameter("EMAIL", email)
else:
@@ -767,6 +767,7 @@
"AllowResourceWithoutOrganizer" : True, # Allow resources to have events without an Organizer
"TrackUnscheduledLocationData" : True, # Track who the last modifier of an unscheduled location event is
"TrackUnscheduledResourceData" : True, # Track who the last modifier of an unscheduled resource event is
"FakeResourceLocationEmail" : False, # Add fake email addresses to work around client bug
"LimitFreeBusyAttendees" : 30, # Maximum number of attendees to request freebusy for
"AttendeeRefreshBatch" : 5, # Number of attendees to do batched refreshes: 0 - no batching
"AttendeeRefreshCountLimit" : 50, # Number of attendees above which attendee refreshes are suppressed: 0 - no limit
@@ -1768,6 +1769,7 @@ def _updateCompliance(configDict, reloading=False):
)
POST_UPDATE_HOOKS = (
_updateMultiProcess,
_updateUtilityLog, # Must be before _updateDataStore for proper relative path
_updateDataStore,
_updateHostName,
_updateWorkQueue,
@@ -1777,7 +1779,6 @@ def _updateCompliance(configDict, reloading=False):
_updateACLs,
_updateRejectClients,
_updateClientFixes,
_updateUtilityLog,
_updateLogLevels,
_updateNotifications,
_updateICalendar,
@@ -21,6 +21,7 @@
from twisted.trial.unittest import SkipTest
from twisted.internet.defer import inlineCallbacks, succeed

from twistedcaldav.config import config
from twistedcaldav.dateops import normalizeForExpand
from twistedcaldav.ical import Component, Property, InvalidICalendarDataError, \
normalizeCUAddress, normalize_iCalStr, diff_iCalStrs
@@ -8434,6 +8435,73 @@ def lookupFunction(cuaddr, ignored1, ignored2):
self.assertEquals(prop.parameterValue("CN"), "{Restricted} Buzz")


def test_normalizeCalendarUserAddressesWithFakeEmail(self):
"""
Ensure fake email addresses are not inserted as EMAIL parameters.
"""

self.patch(config.Scheduling.Options, "FakeResourceLocationEmail", True)

data = """BEGIN:VCALENDAR
VERSION:2.0
DTSTART:20071114T000000Z
BEGIN:VEVENT
UID:12345-67890
DTSTART:20071114T000000Z
ATTENDEE:/principals/users/foo
ATTENDEE;CN=Fake 1;CUTYPE=ROOM:mailto:fake1@do_not_reply
ATTENDEE;CN=Fake 2;CUTYPE=ROOM;EMAIL=fake2@do_not_reply:mailto:fake2@do_not_reply
LOCATION:Buzz
DTSTAMP:20071114T000000Z
END:VEVENT
END:VCALENDAR
"""

result = """BEGIN:VCALENDAR
VERSION:2.0
DTSTART:20071114T000000Z
BEGIN:VEVENT
UID:12345-67890
DTSTART:20071114T000000Z
ATTENDEE;CN=Foo;EMAIL=foo@example.com:urn:x-uid:foo
ATTENDEE;CN=Fake 1;CUTYPE=ROOM:urn:x-uid:fake1
ATTENDEE;CN=Fake 2;CUTYPE=ROOM:urn:x-uid:fake2
LOCATION:Buzz
DTSTAMP:20071114T000000Z
END:VEVENT
END:VCALENDAR
"""

component = Component.fromString(data)


def lookupFunction(cuaddr, ignored1, ignored2):
return succeed({
"/principals/users/foo" : (
"Foo",
"foo",
"INDIVIDUAL",
("urn:x-uid:foo", "mailto:foo@example.com")
),
"mailto:fake1@do_not_reply" : (
"Fake 1",
"fake1",
"ROOM",
("urn:x-uid:fake1", "mailto:fake1@do_not_reply")
),
"mailto:fake2@do_not_reply" : (
"Fake 2",
"fake2",
"ROOM",
("urn:x-uid:fake2", "mailto:fake2@do_not_reply")
),
}[cuaddr])

component.normalizeCalendarUserAddresses(lookupFunction, None, toURN_UUID=True)

self.assertEqual(normalize_iCalStr(component), normalize_iCalStr(result))


def test_serializationCaching(self):

data = """BEGIN:VCALENDAR
@@ -80,6 +80,11 @@ limitations under the License.
<short-name>sanchezoffice</short-name>
<full-name>Sanchez Office</full-name>
</record>
<record type="resource">
<short-name>resource01</short-name>
<uid>resource01</uid>
<full-name>Resource 01</full-name>
</record>
<record type="location">
<uid>75EA36BE-F71B-40F9-81F9-CF59BF40CA8F</uid>
<guid>75EA36BE-F71B-40F9-81F9-CF59BF40CA8F</guid>
@@ -476,6 +476,7 @@ class AugmentedDirectoryRecord(DirectoryRecord, CalendarDirectoryRecordMixin):

def __init__(self, service, baseRecord, augmentedFields):
DirectoryRecord.__init__(self, service, augmentedFields)
CalendarDirectoryRecordMixin.__init__(self)
self._baseRecord = baseRecord


@@ -25,7 +25,7 @@
MatchType, Operand, MatchExpression, CompoundExpression, MatchFlags,
ExistsExpression, BooleanExpression
)
from twext.who.idirectory import RecordType as BaseRecordType
from twext.who.idirectory import RecordType as BaseRecordType, FieldName as BaseFieldName
from twisted.cred.credentials import UsernamePassword
from twisted.internet.defer import inlineCallbacks, returnValue
from twistedcaldav.config import config
@@ -81,6 +81,10 @@ def recordWithCalendarUserAddress(
address = normalizeCUAddr(address)
record = None

if config.Scheduling.Options.FakeResourceLocationEmail:
if address.startswith("mailto:") and address.endswith("@do_not_reply"):
address = "urn:x-uid:{}".format(address[7:-13].decode("hex"))

if address.startswith("urn:x-uid:"):
uid = address[10:]
record = yield self.recordWithUID(
@@ -341,6 +345,12 @@ class CalendarDirectoryRecordMixin(object):
class
"""

def __init__(self):
if config.Scheduling.Options.FakeResourceLocationEmail:
if self.recordType in (DAVRecordType.location, DAVRecordType.resource) and not getattr(self, "emailAddresses", None):
self.fields[BaseFieldName.emailAddresses] = ("{}@do_not_reply".format(self.uid.encode("hex"),),)


@inlineCallbacks
def verifyCredentials(self, credentials):

@@ -19,15 +19,16 @@
"""

from twisted.internet.defer import inlineCallbacks
from twistedcaldav.config import config
from twistedcaldav.test.util import StoreTestCase
from twext.who.directory import DirectoryRecord
from twext.who.idirectory import FieldName, RecordType
from txdav.who.directory import CalendarDirectoryRecordMixin, AutoScheduleMode
from txdav.who.util import startswithFilter
from uuid import UUID
from twext.who.expression import (
MatchType, MatchFlags, MatchExpression
)
from txdav.who.util import startswithFilter
from uuid import UUID



@@ -205,6 +206,33 @@ def test_recordWithCalendarUserAddress(self):
self.assertEquals(record, None)


@inlineCallbacks
def test_recordWithCalendarUserAddress_no_fake_email(self):
"""
Make sure that recordWithCalendarUserAddress handles fake emails for
resources and locations.
"""

record = yield self.directory.recordWithCalendarUserAddress(u"mailto:{}@do_not_reply".format("resource01".encode("hex")))
self.assertTrue(record is None)
record = yield self.directory.recordWithCalendarUserAddress(u"mailto:{}@do_not_reply".format("75EA36BE-F71B-40F9-81F9-CF59BF40CA8F".encode("hex")))
self.assertTrue(record is None)
record = yield self.directory.recordWithCalendarUserAddress(u"mailto:{}@do_not_reply".format("resource02".encode("hex")))
self.assertTrue(record is None)


@inlineCallbacks
def test_calendarUserAddress_no_fake_email(self):
"""
Make sure that recordWs have fake email addresses.
"""

record = yield self.directory.recordWithUID(u"resource01")
self.assertTrue(record is not None)
self.assertTrue(len(getattr(record, "emailAddresses", ())) == 0)
self.assertTrue(len([cuaddr for cuaddr in record.calendarUserAddresses if cuaddr.startswith("mailto:")]) == 0)


@inlineCallbacks
def test_recordsMatchingTokensNoFilter(self):
"""
@@ -328,3 +356,43 @@ def test_getAutoScheduleMode(self):
),
notInGroupMode
)



class DirectoryTestCaseFakeEmail(StoreTestCase):


def configure(self):
"""
Adjust the global configuration for this test.
"""
super(StoreTestCase, self).configure()

config.Scheduling.Options.FakeResourceLocationEmail = True


@inlineCallbacks
def test_recordWithCalendarUserAddress_fake_email(self):
"""
Make sure that recordWithCalendarUserAddress handles fake emails for
resources and locations.
"""

record = yield self.directory.recordWithCalendarUserAddress(u"mailto:{}@do_not_reply".format("resource01".encode("hex")))
self.assertTrue(record is not None)
record = yield self.directory.recordWithCalendarUserAddress(u"mailto:{}@do_not_reply".format("75EA36BE-F71B-40F9-81F9-CF59BF40CA8F".encode("hex")))
self.assertTrue(record is not None)
record = yield self.directory.recordWithCalendarUserAddress(u"mailto:{}@do_not_reply".format("resource02".encode("hex")))
self.assertTrue(record is None)


@inlineCallbacks
def test_calendarUserAddress_fake_email(self):
"""
Make sure that recordWs have fake email addresses.
"""

record = yield self.directory.recordWithUID(u"resource01")
self.assertTrue(record is not None)
self.assertIn(u"{}@do_not_reply".format("resource01".encode("hex")), record.emailAddresses)
self.assertIn(u"mailto:{}@do_not_reply".format("resource01".encode("hex")), record.calendarUserAddresses)
@@ -148,6 +148,11 @@ class DirectoryRecord(BaseDirectoryRecord, CalendarDirectoryRecordMixin):
log = Logger()


def __init__(self, service, fields):
BaseDirectoryRecord.__init__(self, service, fields)
CalendarDirectoryRecordMixin.__init__(self)


@property
def name(self):
return self.shortNames[0]

0 comments on commit 88f221c

Please sign in to comment.
You can’t perform that action at this time.