Fix bug 428392 - Accepting Events not adding event to calender - falsely reporting "not an attendee". r=ctalbert

This commit is contained in:
mozilla%kewis.ch 2008-04-28 11:18:27 +00:00
Родитель f77453869b
Коммит 79f422b4c1
9 изменённых файлов: 113 добавлений и 81 удалений

Просмотреть файл

@ -128,6 +128,8 @@ interface calICalendar : nsISupports
* e.g. this generally applies to network calendars;
* default is true (if not present).
* [boolean] cache.enabled If true, the calendar is cached; default is false.
* [string] itip.transportType If the provider implements a custom calIItipTransport
* this is the "type" used in the contract id.
*
* The following calendar capabilities can be used to inform the UI or backend
* that certain features are not supported. If not otherwise mentioned, not

Просмотреть файл

@ -21,6 +21,7 @@
* Contributor(s):
* Clint Talbert <ctalbert.moz@gmail.com>
* Matthew Willis <lilmatt@mozilla.com>
* Philipp Kewisch <mozilla@kewis.ch>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -111,6 +112,13 @@ interface calIItipItem : nsISupports
*/
attribute calICalendar targetCalendar;
/**
* The identity this item was received on. Helps to determine which
* attendee to manipulate. This should be the full email address of the
* attendee that is considered to be the local user.
*/
attribute AUTF8String identity;
/**
* localStatus: The response that the user has made to the invitation in
* this ItipItem.

Просмотреть файл

@ -20,6 +20,7 @@
*
* Contributor(s):
* Clint Talbert <ctalbert.moz@gmail.com>
* Philipp Kewisch <mozilla@kewis.ch>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -51,9 +52,19 @@ interface calIItipTransport : nsISupports
/**
* Default identity for me within this transport. For example, this is
* your default email address in Thunderbird.
*
* XXX This should probably go away, using the default identity is far
* from practical. Only user right now is calUtils's sendItipInvitation.
* See bug 431126.
*/
readonly attribute AUTF8String defaultIdentity;
/**
* Scheme to be used to prefix attendees. For example, the Email transport
* should reuturn "mailto".
*/
readonly attribute AUTF8String scheme;
/**
* Sending identity. This can be set to change the "sender" identity from
* defaultIdentity above.

Просмотреть файл

@ -21,6 +21,7 @@
* Contributor(s):
* Clint Talbert <ctalbert.moz@gmail.com>
* Matthew Willis <lilmatt@mozilla.com>
* Philipp Kewisch <mozilla@kewis.ch>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -146,6 +147,14 @@ calItipItem.prototype = {
return (this.mTargetCalendar = aValue);
},
mIdentity: null,
get identity() {
return this.mIdentity;
},
set identity(aValue) {
return (this.mIdentity = aValue);
},
mLocalStatus: null,
get localStatus() {
return this.mLocalStatus;

Просмотреть файл

@ -22,6 +22,7 @@
* Clint Talbert <ctalbert.moz@gmail.com>
* Eva Or <evaor1012@yahoo.ca>
* Matthew Willis <lilmatt@mozilla.com>
* Philipp Kewisch <mozilla@kewis.ch>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -139,32 +140,29 @@ calItipProcessor.prototype = {
// Check to see if we have an existing item or not, then continue
// processing appropriately
var i =0;
while (calItem) {
this._isExistingItem(calItem, recvMethod, respMethod, targetCalendar,
aListener);
++i;
calItem = itemList[i];
for (var i = 0; i < itemList.length; i++) {
this._isExistingItem(itemList[i], aItipItem, recvMethod, respMethod,
targetCalendar, aListener);
}
// Send the appropriate response
// figure out a good way to determine when a response is needed!
if (recvMethod != respMethod) {
this._getTransport().simpleSendResponse(respItipItem);
this._getTransport(targetCalendar).simpleSendResponse(respItipItem);
}
},
/* Continue processing the iTip Item now that we have determined whether
* there is an existing item or not.
*/
_continueProcessingItem: function cipCPI(newItem, existingItem, recvMethod, respMethod,
calAction, targetCalendar, aListener) {
var transport = this._getTransport();
_continueProcessingItem: function cipCPI(newItem, existingItem, aItipItem,
recvMethod, respMethod, calAction,
targetCalendar, aListener) {
switch (recvMethod) {
case "REQUEST":
// Only add to calendar if we accepted invite
var replyStat = this._getReplyStatus(newItem,
transport.defaultIdentity);
aItipItem.identity);
if (replyStat == "DECLINED") {
break;
}
@ -194,6 +192,7 @@ calItipProcessor.prototype = {
recvMethod);
}
// TODO bug 431127: This is email specific -> Move to transport
// When replying, the reply must only contain the ORGANIZER and the
// status of the ATTENDEE that represents ourselves. Therefore we must
// remove all other ATTENDEEs from the itipItem we send back.
@ -201,22 +200,15 @@ calItipProcessor.prototype = {
// Get the id that represents me.
// XXX Note that this doesn't take into consideration invitations
// sent to email aliases. (ex: lilmatt vs mwillis)
var me;
var idPrefix;
if (transport.type == "email") {
me = transport.defaultIdentity;
idPrefix = "mailto:";
} else {
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
}
var attendees = newItem.getAttendees({});
var transport = this._getTransport(newItem.calendar);
for each (var attendee in attendees) {
// Leave the ORGANIZER alone.
if (!attendee.isOrganizer) {
// example: mailto:joe@domain.com
var meString = idPrefix + me;
var meString = transport.scheme + ":" + aItipItem.identity
if (attendee.id.toLowerCase() != meString.toLowerCase()) {
newItem.removeAttendee(attendee);
}
@ -389,20 +381,10 @@ calItipProcessor.prototype = {
* item for the specified attendee
*/
_getReplyStatus: function cipGRS(aCalItem, aAttendeeId) {
var idPrefix = "mailto:";
// example: mailto:joe@domain.com
var idString = idPrefix + aAttendeeId;
var idString = this._getTransport(aCalItem.calendar).scheme +
":" + aAttendeeId;
var attendee = aCalItem.getAttendeeById(idString);
if (!attendee) {
// Bug 420516 -- we don't support delegation yet TODO: Localize this?
throw new Error("_getReplyStatus: " +
"You are not on the list of invited attendees, delegation " +
"is not supported yet. See bug 420516 for details.");
}
return attendee.participationStatus;
return attendee && attendee.participationStatus;
},
// A placeholder to make sure we don't try to add multiple items from the
@ -414,9 +396,8 @@ calItipProcessor.prototype = {
* or not. It then calls _continueProcessingItem setting calAction and
* existingItem appropirately
*/
_isExistingItem: function cipIEI(aCalItem, aRecvMethod, aRespMethod,
_isExistingItem: function cipIEI(aCalItem, aItipItem, aRecvMethod, aRespMethod,
aTargetCal, aListener) {
var foundItemListener = {
itipProcessor: this,
onOperationComplete:
@ -428,6 +409,7 @@ calItipProcessor.prototype = {
this.itipProcessor._handledID = aCalItem.id;
this.itipProcessor._continueProcessingItem(aCalItem,
null,
aItipItem,
aRecvMethod,
aRespMethod,
CAL_ITIP_PROC_ADD_OP,
@ -441,6 +423,7 @@ calItipProcessor.prototype = {
if (aCount && aItems[0]) {
this.itipProcessor._continueProcessingItem(aCalItem,
aItems[0],
aItipItem,
aRecvMethod,
aRespMethod,
CAL_ITIP_PROC_UPDATE_OP,
@ -455,23 +438,24 @@ calItipProcessor.prototype = {
// Then we do not have a target calendar to search,
// this is probably a DECLINE reply or some other such response,
// allow it to pass through
this._continueProcessingItem(aCalItem, null, aRecvMethod, aRespMethod,
null, aTargetCal, aListener);
this._continueProcessingItem(aCalItem, null, aItipItem, aRecvMethod,
aRespMethod, null, aTargetCal, aListener);
}
},
/**
* Centralized location for obtaining the proper transport. This way it
* will be easy to support multiple transports in the future
* without changing the existing code too much.
* Centralized location for obtaining the proper transport. If a calendar is
* specified, the transport type is taken from the provider. If the provider
* does not specify a transport, or no calendar is specified, the default
* email transport is returned.
*/
_getTransport: function cipGT() {
// XXX Support for transports other than email go here.
// For now we just assume it's email.
var transport = Components.classes["@mozilla.org/calendar/itip-transport;1?type=email"].
createInstance(Components.interfaces.calIItipTransport);
_getTransport: function cipGT(aCalendar) {
var transportType = (aCalendar && aCalendar.getProperty("itip.transportType")) || "email";
var transport = Components.classes["@mozilla.org/calendar/itip-transport;1?type=" + transportType]
.getService(Components.interfaces.calIItipTransport);
if (!transport) {
throw new Error("iTipProcessor cannot instantiate transport");
throw new Error("iTipProcessor cannot instantiate transport" + (aCalendar ? "for " + aCalendar.type : ""));
}
return transport;
}

Просмотреть файл

@ -2180,10 +2180,10 @@ function sendItipInvitation(aItem) {
// is worked into the event dialog (which has been done in the prototype
// dialog to a degree) then we are going to simply hack in some attendee
// support so that we can round-trip iTIP invitations.
// Since there is no way to determine the type of transport an
// attendee requires, we default to email
var emlSvc = Components.classes["@mozilla.org/calendar/itip-transport;1?type=email"]
.createInstance(Components.interfaces.calIItipTransport);
var transportType = aItem.calendar.getProperty("itip.transportType") || "email";
var transport = Components.classes["@mozilla.org/calendar/itip-transport;1?type=" + transportType]
.getService(Components.interfaces.calIItipTransport);
var itipItem = Components.classes["@mozilla.org/calendar/itip-item;1"]
.createInstance(Components.interfaces.calIItipItem);
@ -2219,7 +2219,7 @@ function sendItipInvitation(aItem) {
// For this support, we'll need a real invitation manager component.
var organizer = Components.classes["@mozilla.org/calendar/attendee;1"]
.createInstance(Components.interfaces.calIAttendee);
organizer.id = "mailto:" + emlSvc.defaultIdentity;
organizer.id = tranport.scheme + ":" + transport.defaultIdentity;
organizer.role = "REQ-PARTICIPANT";
organizer.participationStatus = "ACCEPTED";
organizer.isOrganizer = true;
@ -2251,9 +2251,9 @@ function sendItipInvitation(aItem) {
var subject = sb.formatStringFromName("itipRequestSubject",
[summary], 1);
var body = sb.formatStringFromName("itipRequestBody",
[emlSvc.defaultIdentity, summary],
[transport.defaultIdentity, summary],
2);
// Send it!
emlSvc.sendItems(recipients.length, recipients, subject, body, itipItem);
transport.sendItems(recipients.length, recipients, subject, body, itipItem);
}

Просмотреть файл

@ -21,6 +21,7 @@
* Contributor(s):
* Clint Talbert <ctalbert.moz@gmail.com>
* Matthew Willis <lilmatt@mozilla.com>
* Philipp Kewisch <mozilla@kewis.ch>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -66,6 +67,10 @@ calItipEmailTransport.prototype = {
return this.mDefaultIdentity.email;
},
get scheme() {
return "mailto";
},
mSenderAddress: null,
get senderAddress() {
return this.mSenderAddress;

Просмотреть файл

@ -23,6 +23,7 @@
* Clint Talbert <ctalbert.moz@gmail.com>
* Matthew Willis <lilmatt@mozilla.com>
* Mauro Cicognini <mcicogni@libero.it>
* Philipp Kewisch <mozilla@kewis.ch>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -187,14 +188,7 @@ ltnMimeConverter.prototype = {
var observer = Components.classes["@mozilla.org/observer-service;1"].
getService(Components.interfaces.nsIObserverService);
observer.notifyObservers(null, "onItipItemCreation", 0);
} else {
// Thunderbird 1.5.x case: We have no choice but to try
// sending the iTIP item directly with the notification
var observer = Components.classes["@mozilla.org/observer-service;1"].
getService(Components.interfaces.nsIObserverService);
observer.notifyObservers(itipItem, "onItipItemCreation", 0);
}
} catch (e) {
Components.utils.reportError("convertToHTML: " +
"Cannot create itipItem: " + e);

Просмотреть файл

@ -21,6 +21,7 @@
* Contributor(s):
* Clint Talbert <ctalbert.moz@gmail.com>
* Matthew Willis <lilmatt@mozilla.com>
* Philipp Kewisch <mozilla@kewis.ch>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -61,10 +62,6 @@ function checkForItipItem(subject)
// This property was set by LightningTextCalendarConverter.js
itipItem = sinkProps.getPropertyAsInterface("itipItem",
Components.interfaces.calIItipItem);
} else {
// With Thunderbird 1.5.x we have to use the subject to pass the
// iTIP item because we don't have sinkProps available.
itipItem = subject.QueryInterface(Components.interfaces.calIItipItem);
}
} catch (e) {
// This will throw on every message viewed that doesn't have the
@ -74,6 +71,9 @@ function checkForItipItem(subject)
return;
}
// Get the recipient identity and save it with the itip item.
itipItem.identity = getMsgRecipient();
// We are only called upon receipt of an invite, so ensure that isSend
// is false.
itipItem.isSend = false;
@ -232,9 +232,23 @@ function getMsgRecipient()
if (identities.Count() == 0) {
// If we were not able to retrieve identities above, then we have no
// choice but to revert to the default identity
var emailSvc = Components.classes["@mozilla.org/calendar/itip-transport;1?type=email"]
.getService(Components.interfaces.calIItipTransport);
emailMap[emailSvc.defaultIdentity.toLowerCase()] = true;
var acctMgr = Components.classes["@mozilla.org/messenger/account-manager;1"]
.getService(Components.interfaces.nsIMsgAccountManager);
var identity = acctMgr.defaultAccount.defaultIdentity;
if (!identity) {
// If there isn't a default identity (i.e Local Folders is your
// default identity), then go ahead and use the first available
// identity.
var allIdentities = acctMgr.allIdentities;
if (allIdentities.Count() > 0) {
identity = allIdentities.GetElementAt(0)
.QueryInterface(Components.interfaces.nsIMsgIdentity);
} else {
// If there are no identities at all, we cannot get a recipient.
return null;
}
}
emailMap[identity.toLowerCase()] = true;
} else {
// Build a map of usable email addresses
for (var i = 0; i < identities.Count(); i++) {
@ -304,7 +318,7 @@ function getTargetCalendar()
*/
function setAttendeeResponse(type, eventStatus)
{
var myAddress = getMsgRecipient();
var myAddress = gItipItem.identity
if (!myAddress) {
// Bug 420516 -- we don't support delegation yet TODO: Localize this?
throw new Error("setAttendeeResponse: " +
@ -312,26 +326,31 @@ function setAttendeeResponse(type, eventStatus)
"is not supported yet. See bug 420516 for details.");
}
if (type && gItipItem) {
// We set the attendee status appropriately
// Some methods need a target calendar. Prompt for it first.
switch (type) {
case "ACCEPTED":
case "TENTATIVE":
gItipItem.setAttendeeStatus(myAddress, type);
// fall through
case "REPLY":
case "PUBLISH":
var targetCalendar = getTargetCalendar();
gItipItem.targetCalendar = targetCalendar;
doResponse(eventStatus);
break;
gItipItem.targetCalendar = getTargetCalendar();
if (!gItipItem.targetCalendar) {
// The dialog was canceled, we are done.
return;
}
}
// Now set the attendee status and perform the iTIP action. If the
// method is not mentioned here, no further action will be taken.
switch (type) {
case "ACCEPTED":
case "TENTATIVE":
case "DECLINED":
gItipItem.setAttendeeStatus(myAddress, type);
// Fall through
case "REPLY":
case "PUBLISH":
doResponse(eventStatus);
break;
default:
// no-op. The attendee wishes to disregard the mail, so no
// further action is required.
break;
}
}
}
@ -367,7 +386,7 @@ function doResponse(aLocalStatus)
}
var itipProc = Components.classes["@mozilla.org/calendar/itip-processor;1"]
.createInstance(Components.interfaces.calIItipProcessor);
.getService(Components.interfaces.calIItipProcessor);
itipProc.processItipItem(gItipItem, operationListener);
}