<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[14456] CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.calendarserver.org//changeset/14456">14456</a></dd>
<dt>Author</dt> <dd>cdaboo@apple.com</dd>
<dt>Date</dt> <dd>2015-02-19 17:47:23 -0800 (Thu, 19 Feb 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>Use DAL Record for iMIP tokens.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#CalendarServerbranchesuserscdaboopod2podmigrationtxdavcaldavdatastoreschedulingimipinboundpy">CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/caldav/datastore/scheduling/imip/inbound.py</a></li>
<li><a href="#CalendarServerbranchesuserscdaboopod2podmigrationtxdavcaldavdatastoreschedulingimipoutboundpy">CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/caldav/datastore/scheduling/imip/outbound.py</a></li>
<li><a href="#CalendarServerbranchesuserscdaboopod2podmigrationtxdavcaldavdatastoreschedulingimiptesttest_inboundpy">CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/caldav/datastore/scheduling/imip/test/test_inbound.py</a></li>
<li><a href="#CalendarServerbranchesuserscdaboopod2podmigrationtxdavcaldavdatastoreschedulingimiptesttest_mailgatewaypy">CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/caldav/datastore/scheduling/imip/test/test_mailgateway.py</a></li>
<li><a href="#CalendarServerbranchesuserscdaboopod2podmigrationtxdavcaldavdatastoreschedulingimiptesttest_outboundpy">CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/caldav/datastore/scheduling/imip/test/test_outbound.py</a></li>
<li><a href="#CalendarServerbranchesuserscdaboopod2podmigrationtxdavcommondatastoresqlpy">CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/common/datastore/sql.py</a></li>
<li><a href="#CalendarServerbranchesuserscdaboopod2podmigrationtxdavcommonicommondatastorepy">CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/common/icommondatastore.py</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#CalendarServerbranchesuserscdaboopod2podmigrationtxdavcommondatastoresql_imippy">CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/common/datastore/sql_imip.py</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="CalendarServerbranchesuserscdaboopod2podmigrationtxdavcaldavdatastoreschedulingimipinboundpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/caldav/datastore/scheduling/imip/inbound.py (14455 => 14456)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/caldav/datastore/scheduling/imip/inbound.py        2015-02-20 00:00:46 UTC (rev 14455)
+++ CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/caldav/datastore/scheduling/imip/inbound.py        2015-02-20 01:47:23 UTC (rev 14456)
</span><span class="lines">@@ -260,11 +260,11 @@
</span><span class="cx"> return
</span><span class="cx">
</span><span class="cx"> txn = self.store.newTransaction(label="MailReceiver.processDSN")
</span><del>- result = (yield txn.imipLookupByToken(token))
</del><ins>+ records = (yield txn.imipLookupByToken(token))
</ins><span class="cx"> yield txn.commit()
</span><span class="cx"> try:
</span><span class="cx"> # Note the results are returned as utf-8 encoded strings
</span><del>- organizer, attendee, _ignore_icaluid = result[0]
</del><ins>+ record = records[0]
</ins><span class="cx"> except:
</span><span class="cx"> # This isn't a token we recognize
</span><span class="cx"> log.error(
</span><span class="lines">@@ -272,7 +272,7 @@
</span><span class="cx"> % (token, msgId))
</span><span class="cx"> returnValue(self.UNKNOWN_TOKEN)
</span><span class="cx">
</span><del>- calendar.removeAllButOneAttendee(attendee)
</del><ins>+ calendar.removeAllButOneAttendee(record.attendee)
</ins><span class="cx"> calendar.getOrganizerProperty().setValue(organizer)
</span><span class="cx"> for comp in calendar.subcomponents():
</span><span class="cx"> if comp.name() == "VEVENT":
</span><span class="lines">@@ -288,8 +288,11 @@
</span><span class="cx"> log.warn("Mail gateway processing DSN %s" % (msgId,))
</span><span class="cx"> txn = self.store.newTransaction(label="MailReceiver.processDSN")
</span><span class="cx"> yield txn.enqueue(
</span><del>- IMIPReplyWork, organizer=organizer, attendee=attendee,
- icalendarText=str(calendar))
</del><ins>+ IMIPReplyWork,
+ organizer=record.organizer,
+ attendee=record.attendee,
+ icalendarText=str(calendar)
+ )
</ins><span class="cx"> yield txn.commit()
</span><span class="cx"> returnValue(self.INJECTION_SUBMITTED)
</span><span class="cx">
</span><span class="lines">@@ -313,11 +316,11 @@
</span><span class="cx"> returnValue(self.MALFORMED_TO_ADDRESS)
</span><span class="cx">
</span><span class="cx"> txn = self.store.newTransaction(label="MailReceiver.processReply")
</span><del>- result = (yield txn.imipLookupByToken(token))
</del><ins>+ records = (yield txn.imipLookupByToken(token))
</ins><span class="cx"> yield txn.commit()
</span><span class="cx"> try:
</span><span class="cx"> # Note the results are returned as utf-8 encoded strings
</span><del>- organizer, attendee, _ignore_icaluid = result[0]
</del><ins>+ record = records[0]
</ins><span class="cx"> except:
</span><span class="cx"> # This isn't a token we recognize
</span><span class="cx"> log.error(
</span><span class="lines">@@ -337,11 +340,11 @@
</span><span class="cx"> "in message %s" % (msg['Message-ID'],))
</span><span class="cx">
</span><span class="cx"> toAddr = None
</span><del>- fromAddr = attendee[7:]
- if organizer.startswith("mailto:"):
- toAddr = organizer[7:]
- elif organizer.startswith("urn:x-uid:"):
- uid = organizer[10:]
</del><ins>+ fromAddr = record.attendee[7:]
+ if record.organizer.startswith("mailto:"):
+ toAddr = record.organizer[7:]
+ elif record.organizer.startswith("urn:x-uid:"):
+ uid = record.organizer[10:]
</ins><span class="cx"> record = yield self.directory.recordWithUID(uid)
</span><span class="cx"> try:
</span><span class="cx"> if record and record.emailAddresses:
</span><span class="lines">@@ -376,23 +379,23 @@
</span><span class="cx"> calendar = Component.fromString(calBody)
</span><span class="cx"> event = calendar.mainComponent()
</span><span class="cx">
</span><del>- calendar.removeAllButOneAttendee(attendee)
</del><ins>+ calendar.removeAllButOneAttendee(record.attendee)
</ins><span class="cx"> organizerProperty = calendar.getOrganizerProperty()
</span><span class="cx"> if organizerProperty is None:
</span><span class="cx"> # ORGANIZER is required per rfc2446 section 3.2.3
</span><span class="cx"> log.warn(
</span><span class="cx"> "Mail gateway didn't find an ORGANIZER in REPLY %s"
</span><span class="cx"> % (msg['Message-ID'],))
</span><del>- event.addProperty(Property("ORGANIZER", organizer))
</del><ins>+ event.addProperty(Property("ORGANIZER", record.organizer))
</ins><span class="cx"> else:
</span><del>- organizerProperty.setValue(organizer)
</del><ins>+ organizerProperty.setValue(record.organizer)
</ins><span class="cx">
</span><span class="cx"> if not calendar.getAttendees():
</span><span class="cx"> # The attendee we're expecting isn't there, so add it back
</span><span class="cx"> # with a SCHEDULE-STATUS of SERVICE_UNAVAILABLE.
</span><span class="cx"> # The organizer will then see that the reply was not successful.
</span><span class="cx"> attendeeProp = Property(
</span><del>- "ATTENDEE", attendee,
</del><ins>+ "ATTENDEE", record.attendee,
</ins><span class="cx"> params={
</span><span class="cx"> "SCHEDULE-STATUS": iTIPRequestStatus.SERVICE_UNAVAILABLE,
</span><span class="cx"> }
</span><span class="lines">@@ -406,8 +409,11 @@
</span><span class="cx">
</span><span class="cx"> txn = self.store.newTransaction(label="MailReceiver.processReply")
</span><span class="cx"> yield txn.enqueue(
</span><del>- IMIPReplyWork, organizer=organizer, attendee=attendee,
- icalendarText=str(calendar))
</del><ins>+ IMIPReplyWork,
+ organizer=record.organizer,
+ attendee=record.attendee,
+ icalendarText=str(calendar)
+ )
</ins><span class="cx"> yield txn.commit()
</span><span class="cx"> returnValue(self.INJECTION_SUBMITTED)
</span><span class="cx">
</span></span></pre></div>
<a id="CalendarServerbranchesuserscdaboopod2podmigrationtxdavcaldavdatastoreschedulingimipoutboundpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/caldav/datastore/scheduling/imip/outbound.py (14455 => 14456)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/caldav/datastore/scheduling/imip/outbound.py        2015-02-20 00:00:46 UTC (rev 14455)
+++ CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/caldav/datastore/scheduling/imip/outbound.py        2015-02-20 01:47:23 UTC (rev 14456)
</span><span class="lines">@@ -364,28 +364,29 @@
</span><span class="cx">
</span><span class="cx"> # Reuse or generate a token based on originator, toAddr, and
</span><span class="cx"> # event uid
</span><del>- token = (yield txn.imipGetToken(originator, toAddr.lower(), icaluid))
- if token is None:
</del><ins>+ record = (yield txn.imipGetToken(originator, toAddr.lower(), icaluid))
+ if record is None:
</ins><span class="cx">
</span><span class="cx"> # Because in the past the originator was sometimes in mailto:
</span><span class="cx"> # form, lookup an existing token by mailto: as well
</span><span class="cx"> organizerProperty = calendar.getOrganizerProperty()
</span><span class="cx"> organizerEmailAddress = organizerProperty.parameterValue("EMAIL", None)
</span><span class="cx"> if organizerEmailAddress is not None:
</span><del>- token = (yield txn.imipGetToken("mailto:%s" % (organizerEmailAddress.lower(),), toAddr.lower(), icaluid))
</del><ins>+ record = (yield txn.imipGetToken("mailto:%s" % (organizerEmailAddress.lower(),), toAddr.lower(), icaluid))
</ins><span class="cx">
</span><del>- if token is None:
- token = (yield txn.imipCreateToken(originator, toAddr.lower(), icaluid))
</del><ins>+ if record is None:
+ record = (yield txn.imipCreateToken(originator, toAddr.lower(), icaluid))
</ins><span class="cx"> self.log.debug("Mail gateway created token %s for %s "
</span><span class="cx"> "(originator), %s (recipient) and %s (icaluid)"
</span><del>- % (token, originator, toAddr, icaluid))
</del><ins>+ % (record.token, originator, toAddr, icaluid))
</ins><span class="cx"> inviteState = "new"
</span><span class="cx">
</span><span class="cx"> else:
</span><span class="cx"> self.log.debug("Mail gateway reusing token %s for %s "
</span><span class="cx"> "(originator), %s (recipient) and %s (icaluid)"
</span><del>- % (token, originator, toAddr, icaluid))
</del><ins>+ % (record.token, originator, toAddr, icaluid))
</ins><span class="cx"> inviteState = "update"
</span><ins>+ token = record.token
</ins><span class="cx">
</span><span class="cx"> fullServerAddress = self.address
</span><span class="cx"> _ignore_name, serverAddress = email.utils.parseaddr(fullServerAddress)
</span></span></pre></div>
<a id="CalendarServerbranchesuserscdaboopod2podmigrationtxdavcaldavdatastoreschedulingimiptesttest_inboundpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/caldav/datastore/scheduling/imip/test/test_inbound.py (14455 => 14456)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/caldav/datastore/scheduling/imip/test/test_inbound.py        2015-02-20 00:00:46 UTC (rev 14455)
+++ CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/caldav/datastore/scheduling/imip/test/test_inbound.py        2015-02-20 01:47:23 UTC (rev 14456)
</span><span class="lines">@@ -175,13 +175,13 @@
</span><span class="cx">
</span><span class="cx"> # Make sure a known token *is* processed
</span><span class="cx"> txn = self.store.newTransaction()
</span><del>- token = (yield txn.imipCreateToken(
</del><ins>+ record = (yield txn.imipCreateToken(
</ins><span class="cx"> "urn:x-uid:5A985493-EE2C-4665-94CF-4DFEA3A89500",
</span><span class="cx"> "mailto:user02@example.com",
</span><span class="cx"> "1E71F9C8-AEDA-48EB-98D0-76E898F6BB5C"
</span><span class="cx"> ))
</span><span class="cx"> yield txn.commit()
</span><del>- calBody = template % token
</del><ins>+ calBody = template % record.token
</ins><span class="cx"> result = (yield self.receiver.processDSN(calBody, "xyzzy"))
</span><span class="cx"> self.assertEquals(result, MailReceiver.INJECTION_SUBMITTED)
</span><span class="cx">
</span></span></pre></div>
<a id="CalendarServerbranchesuserscdaboopod2podmigrationtxdavcaldavdatastoreschedulingimiptesttest_mailgatewaypy"></a>
<div class="modfile"><h4>Modified: CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/caldav/datastore/scheduling/imip/test/test_mailgateway.py (14455 => 14456)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/caldav/datastore/scheduling/imip/test/test_mailgateway.py        2015-02-20 00:00:46 UTC (rev 14455)
+++ CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/caldav/datastore/scheduling/imip/test/test_mailgateway.py        2015-02-20 01:47:23 UTC (rev 14456)
</span><span class="lines">@@ -44,9 +44,8 @@
</span><span class="cx"> "icaluid1", token="token1")
</span><span class="cx"> yield migrateTokensToStore(self.path, self.store)
</span><span class="cx"> txn = self.store.newTransaction()
</span><del>- results = yield (txn.imipLookupByToken("token1"))
- organizer, attendee, icaluid = results[0]
</del><ins>+ records = yield (txn.imipLookupByToken("token1"))
</ins><span class="cx"> yield txn.commit()
</span><del>- self.assertEquals(organizer, "urn:uuid:user01")
- self.assertEquals(attendee, "mailto:attendee@example.com")
- self.assertEquals(icaluid, "icaluid1")
</del><ins>+ self.assertEquals(records[0].organizer, "urn:uuid:user01")
+ self.assertEquals(records[0].attendee, "mailto:attendee@example.com")
+ self.assertEquals(records[0].icaluid, "icaluid1")
</ins></span></pre></div>
<a id="CalendarServerbranchesuserscdaboopod2podmigrationtxdavcaldavdatastoreschedulingimiptesttest_outboundpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/caldav/datastore/scheduling/imip/test/test_outbound.py (14455 => 14456)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/caldav/datastore/scheduling/imip/test/test_outbound.py        2015-02-20 00:00:46 UTC (rev 14455)
+++ CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/caldav/datastore/scheduling/imip/test/test_outbound.py        2015-02-20 01:47:23 UTC (rev 14456)
</span><span class="lines">@@ -316,17 +316,17 @@
</span><span class="cx"> yield JobItem.waitEmpty(self.store.newTransaction, reactor, 60)
</span><span class="cx">
</span><span class="cx"> txn = self.store.newTransaction()
</span><del>- token = (yield txn.imipGetToken(
</del><ins>+ record = (yield txn.imipGetToken(
</ins><span class="cx"> ORGANIZER,
</span><span class="cx"> ATTENDEE,
</span><span class="cx"> ICALUID
</span><span class="cx"> ))
</span><del>- self.assertTrue(token)
- organizer, attendee, icaluid = (yield txn.imipLookupByToken(token))[0]
</del><ins>+ self.assertTrue(record is not None)
+ record = (yield txn.imipLookupByToken(record.token))[0]
</ins><span class="cx"> yield txn.commit()
</span><del>- self.assertEquals(organizer, ORGANIZER)
- self.assertEquals(attendee, ATTENDEE)
- self.assertEquals(icaluid, ICALUID)
</del><ins>+ self.assertEquals(record.organizer, ORGANIZER)
+ self.assertEquals(record.attendee, ATTENDEE)
+ self.assertEquals(record.icaluid, ICALUID)
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> @inlineCallbacks
</span><span class="lines">@@ -492,12 +492,12 @@
</span><span class="cx"> if UID: # The organizer is local, and server is sending to remote
</span><span class="cx"> # attendee
</span><span class="cx"> txn = self.store.newTransaction()
</span><del>- token = (yield txn.imipGetToken(inputOriginator, inputRecipient, UID))
</del><ins>+ record = (yield txn.imipGetToken(inputOriginator, inputRecipient, UID))
</ins><span class="cx"> yield txn.commit()
</span><del>- self.assertNotEquals(token, None)
</del><ins>+ self.assertNotEquals(record, None)
</ins><span class="cx"> self.assertEquals(
</span><span class="cx"> msg["Reply-To"],
</span><del>- "server+%s@example.com" % (token,))
</del><ins>+ "server+%s@example.com" % (record.token,))
</ins><span class="cx">
</span><span class="cx"> # Make sure attendee property for organizer exists and matches
</span><span class="cx"> # the CUA of the organizer property
</span><span class="lines">@@ -529,31 +529,31 @@
</span><span class="cx"> @inlineCallbacks
</span><span class="cx"> def test_tokens(self):
</span><span class="cx"> txn = self.store.newTransaction()
</span><del>- token = (yield txn.imipLookupByToken("xyzzy"))
</del><ins>+ self.assertEquals((yield txn.imipLookupByToken("xyzzy")), [])
</ins><span class="cx"> yield txn.commit()
</span><del>- self.assertEquals(token, [])
</del><span class="cx">
</span><span class="cx"> txn = self.store.newTransaction()
</span><del>- token1 = (yield txn.imipCreateToken("organizer", "attendee", "icaluid"))
</del><ins>+ record1 = (yield txn.imipCreateToken("organizer", "attendee", "icaluid"))
</ins><span class="cx"> yield txn.commit()
</span><span class="cx">
</span><span class="cx"> txn = self.store.newTransaction()
</span><del>- token2 = (yield txn.imipGetToken("organizer", "attendee", "icaluid"))
</del><ins>+ record2 = (yield txn.imipGetToken("organizer", "attendee", "icaluid"))
</ins><span class="cx"> yield txn.commit()
</span><del>- self.assertEquals(token1, token2)
</del><ins>+ self.assertEquals(record1.token, record2.token)
</ins><span class="cx">
</span><span class="cx"> txn = self.store.newTransaction()
</span><ins>+ record = (yield txn.imipLookupByToken(record1.token))[0]
</ins><span class="cx"> self.assertEquals(
</span><del>- (yield txn.imipLookupByToken(token1)),
- [["organizer", "attendee", "icaluid"]])
</del><ins>+ [record.organizer, record.attendee, record.icaluid],
+ ["organizer", "attendee", "icaluid"])
</ins><span class="cx"> yield txn.commit()
</span><span class="cx">
</span><span class="cx"> txn = self.store.newTransaction()
</span><del>- yield txn.imipRemoveToken(token1)
</del><ins>+ yield txn.imipRemoveToken(record1.token)
</ins><span class="cx"> yield txn.commit()
</span><span class="cx">
</span><span class="cx"> txn = self.store.newTransaction()
</span><del>- self.assertEquals((yield txn.imipLookupByToken(token1)), [])
</del><ins>+ self.assertEquals((yield txn.imipLookupByToken(record1.token)), [])
</ins><span class="cx"> yield txn.commit()
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -568,7 +568,7 @@
</span><span class="cx"> # Explictly store a token with mailto: CUA for organizer
</span><span class="cx"> # (something that doesn't happen any more, but did in the past)
</span><span class="cx"> txn = self.store.newTransaction()
</span><del>- origToken = (yield txn.imipCreateToken(
</del><ins>+ origRecord = (yield txn.imipCreateToken(
</ins><span class="cx"> organizerEmail,
</span><span class="cx"> "mailto:attendee@example.com",
</span><span class="cx"> "CFDD5E46-4F74-478A-9311-B3FF905449C3"
</span><span class="lines">@@ -588,15 +588,15 @@
</span><span class="cx">
</span><span class="cx"> # Verify we didn't create a new token...
</span><span class="cx"> txn = self.store.newTransaction()
</span><del>- token = (yield txn.imipGetToken(inputOriginator, inputRecipient, UID))
</del><ins>+ record = (yield txn.imipGetToken(inputOriginator, inputRecipient, UID))
</ins><span class="cx"> yield txn.commit()
</span><del>- self.assertEquals(token, None)
</del><ins>+ self.assertEquals(record, None)
</ins><span class="cx">
</span><span class="cx"> # But instead kept the old one...
</span><span class="cx"> txn = self.store.newTransaction()
</span><del>- token = (yield txn.imipGetToken(organizerEmail, inputRecipient, UID))
</del><ins>+ record = (yield txn.imipGetToken(organizerEmail, inputRecipient, UID))
</ins><span class="cx"> yield txn.commit()
</span><del>- self.assertEquals(token, origToken)
</del><ins>+ self.assertEquals(record.token, origRecord.token)
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx"> def generateSampleEmail(self, caltext=initialInviteText):
</span></span></pre></div>
<a id="CalendarServerbranchesuserscdaboopod2podmigrationtxdavcommondatastoresqlpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/common/datastore/sql.py (14455 => 14456)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/common/datastore/sql.py        2015-02-20 00:00:46 UTC (rev 14455)
+++ CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/common/datastore/sql.py        2015-02-20 01:47:23 UTC (rev 14456)
</span><span class="lines">@@ -14,6 +14,7 @@
</span><span class="cx"> # See the License for the specific language governing permissions and
</span><span class="cx"> # limitations under the License.
</span><span class="cx"> ##
</span><ins>+from txdav.common.datastore.sql_imip import imipAPIMixin
</ins><span class="cx">
</span><span class="cx"> """
</span><span class="cx"> SQL data store.
</span><span class="lines">@@ -75,8 +76,7 @@
</span><span class="cx"> HomeChildNameAlreadyExistsError, NoSuchHomeChildError, \
</span><span class="cx"> ObjectResourceNameNotAllowedError, ObjectResourceNameAlreadyExistsError, \
</span><span class="cx"> NoSuchObjectResourceError, AllRetriesFailed, InvalidSubscriptionValues, \
</span><del>- InvalidIMIPTokenValues, TooManyObjectResourcesError, \
- SyncTokenValidException
</del><ins>+ TooManyObjectResourcesError, SyncTokenValidException
</ins><span class="cx"> from txdav.common.idirectoryservice import IStoreDirectoryService, \
</span><span class="cx"> DirectoryRecordNotFoundError
</span><span class="cx"> from txdav.common.inotifications import INotificationCollection, \
</span><span class="lines">@@ -565,7 +565,10 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx">
</span><del>-class CommonStoreTransaction(GroupsAPIMixin, GroupCacherAPIMixin, DelegatesAPIMixin):
</del><ins>+class CommonStoreTransaction(
+ GroupsAPIMixin, GroupCacherAPIMixin, DelegatesAPIMixin,
+ imipAPIMixin,
+):
</ins><span class="cx"> """
</span><span class="cx"> Transaction implementation for SQL database.
</span><span class="cx"> """
</span><span class="lines">@@ -921,121 +924,6 @@
</span><span class="cx"> return self._apnSubscriptionsBySubscriberQuery.on(self, subscriberGUID=guid)
</span><span class="cx">
</span><span class="cx">
</span><del>- # Create IMIP token
-
- @classproperty
- def _insertIMIPTokenQuery(cls):
- imip = schema.IMIP_TOKENS
- return Insert({
- imip.TOKEN: Parameter("token"),
- imip.ORGANIZER: Parameter("organizer"),
- imip.ATTENDEE: Parameter("attendee"),
- imip.ICALUID: Parameter("icaluid"),
- })
-
-
- @inlineCallbacks
- def imipCreateToken(self, organizer, attendee, icaluid, token=None):
- if not (organizer and attendee and icaluid):
- raise InvalidIMIPTokenValues()
-
- if token is None:
- token = str(uuid4())
-
- try:
- yield self._insertIMIPTokenQuery.on(
- self,
- token=token, organizer=organizer, attendee=attendee,
- icaluid=icaluid)
- except Exception:
- # TODO: is it okay if someone else created the same row just now?
- pass
- returnValue(token)
-
- # Lookup IMIP organizer+attendee+icaluid for token
-
-
- @classproperty
- def _selectIMIPTokenByTokenQuery(cls):
- imip = schema.IMIP_TOKENS
- return Select([imip.ORGANIZER, imip.ATTENDEE, imip.ICALUID], From=imip,
- Where=(imip.TOKEN == Parameter("token")))
-
-
- def imipLookupByToken(self, token):
- return self._selectIMIPTokenByTokenQuery.on(self, token=token)
-
- # Lookup IMIP token for organizer+attendee+icaluid
-
-
- @classproperty
- def _selectIMIPTokenQuery(cls):
- imip = schema.IMIP_TOKENS
- return Select(
- [imip.TOKEN],
- From=imip,
- Where=(imip.ORGANIZER == Parameter("organizer")).And(
- imip.ATTENDEE == Parameter("attendee")).And(
- imip.ICALUID == Parameter("icaluid"))
- )
-
-
- @classproperty
- def _updateIMIPTokenQuery(cls):
- imip = schema.IMIP_TOKENS
- return Update(
- {imip.ACCESSED: utcNowSQL, },
- Where=(imip.ORGANIZER == Parameter("organizer")).And(
- imip.ATTENDEE == Parameter("attendee")).And(
- imip.ICALUID == Parameter("icaluid"))
- )
-
-
- @inlineCallbacks
- def imipGetToken(self, organizer, attendee, icaluid):
- row = (yield self._selectIMIPTokenQuery.on(
- self, organizer=organizer,
- attendee=attendee, icaluid=icaluid))
- if row:
- token = row[0][0]
- # update the timestamp
- yield self._updateIMIPTokenQuery.on(
- self, organizer=organizer,
- attendee=attendee, icaluid=icaluid)
- else:
- token = None
- returnValue(token)
-
-
- # Remove IMIP token
- @classproperty
- def _removeIMIPTokenQuery(cls):
- imip = schema.IMIP_TOKENS
- return Delete(From=imip,
- Where=(imip.TOKEN == Parameter("token")))
-
-
- def imipRemoveToken(self, token):
- return self._removeIMIPTokenQuery.on(self, token=token)
-
-
- # Purge old IMIP tokens
- @classproperty
- def _purgeOldIMIPTokensQuery(cls):
- imip = schema.IMIP_TOKENS
- return Delete(From=imip,
- Where=(imip.ACCESSED < Parameter("olderThan")))
-
-
- def purgeOldIMIPTokens(self, olderThan):
- """
- @type olderThan: datetime
- """
- return self._purgeOldIMIPTokensQuery.on(self, olderThan=olderThan)
-
- # End of IMIP
-
-
</del><span class="cx"> def preCommit(self, operation):
</span><span class="cx"> """
</span><span class="cx"> Run things before C{commit}. (Note: only provided by SQL
</span></span></pre></div>
<a id="CalendarServerbranchesuserscdaboopod2podmigrationtxdavcommondatastoresql_imippy"></a>
<div class="addfile"><h4>Added: CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/common/datastore/sql_imip.py (0 => 14456)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/common/datastore/sql_imip.py         (rev 0)
+++ CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/common/datastore/sql_imip.py        2015-02-20 01:47:23 UTC (rev 14456)
</span><span class="lines">@@ -0,0 +1,102 @@
</span><ins>+# -*- test-case-name: twext.enterprise.dal.test.test_record -*-
+##
+# Copyright (c) 2015 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+from twext.enterprise.dal.record import SerializableRecord, fromTable
+from twext.enterprise.dal.syntax import utcNowSQL
+from twext.python.log import Logger
+from twisted.internet.defer import inlineCallbacks, returnValue
+from txdav.common.datastore.sql_tables import schema
+from txdav.common.icommondatastore import InvalidIMIPTokenValues
+from uuid import uuid4
+
+log = Logger()
+
+"""
+Classes and methods that relate to iMIP objects in the SQL store.
+"""
+
+class iMIPTokensRecord(SerializableRecord, fromTable(schema.IMIP_TOKENS)):
+ """
+ @DynamicAttrs
+ L{Record} for L{schema.IMIP_TOKENS}.
+ """
+ pass
+
+
+
+class imipAPIMixin(object):
+ """
+ A mixin for L{CommonStoreTransaction} that covers the iMIP API.
+ """
+
+ # Create IMIP token
+ @inlineCallbacks
+ def imipCreateToken(self, organizer, attendee, icaluid, token=None):
+ if not (organizer and attendee and icaluid):
+ raise InvalidIMIPTokenValues()
+
+ if token is None:
+ token = str(uuid4())
+
+ try:
+ record = yield iMIPTokensRecord.create(
+ self,
+ token=token,
+ organizer=organizer,
+ attendee=attendee,
+ icaluid=icaluid
+ )
+ except Exception:
+ # TODO: is it okay if someone else created the same row just now?
+ record = yield self.imipGetToken(organizer, attendee, icaluid)
+ returnValue(record)
+
+
+ # Lookup IMIP organizer+attendee+icaluid for token
+ def imipLookupByToken(self, token):
+ return iMIPTokensRecord.querysimple(self, token=token)
+
+
+ # Lookup IMIP token for organizer+attendee+icaluid
+ @inlineCallbacks
+ def imipGetToken(self, organizer, attendee, icaluid):
+ records = yield iMIPTokensRecord.querysimple(
+ self,
+ organizer=organizer,
+ attendee=attendee,
+ icaluid=icaluid,
+ )
+ if records:
+ # update the timestamp
+ record = records[0]
+ yield record.update(accessed=utcNowSQL)
+ else:
+ record = None
+ returnValue(record)
+
+
+ # Remove IMIP token
+ def imipRemoveToken(self, token):
+ return iMIPTokensRecord.deletesimple(self, token=token)
+
+
+ # Purge old IMIP tokens
+ def purgeOldIMIPTokens(self, olderThan):
+ """
+ @type olderThan: datetime
+ """
+ return iMIPTokensRecord.delete(self, iMIPTokensRecord.accessed < olderThan)
</ins></span></pre></div>
<a id="CalendarServerbranchesuserscdaboopod2podmigrationtxdavcommonicommondatastorepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/common/icommondatastore.py (14455 => 14456)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/common/icommondatastore.py        2015-02-20 00:00:46 UTC (rev 14455)
+++ CalendarServer/branches/users/cdaboo/pod2pod-migration/txdav/common/icommondatastore.py        2015-02-20 01:47:23 UTC (rev 14456)
</span><span class="lines">@@ -389,8 +389,8 @@
</span><span class="cx"> """
</span><span class="cx"> Returns the organizer, attendee, and icaluid corresponding to the token
</span><span class="cx">
</span><del>- @param token: the token to look up
- @type token: C{str}
</del><ins>+ @param token: the token record
+ @type token: L{Record}
</ins><span class="cx"> """
</span><span class="cx">
</span><span class="cx"> def imipGetToken(organizer, attendee, icaluid): #@NoSelf
</span></span></pre>
</div>
</div>
</body>
</html>