зеркало из https://github.com/mozilla/pjs.git
Fix bug 428392 - Accepting Events not adding event to calender - falsely reporting "not an attendee". r=ctalbert
This commit is contained in:
Родитель
f77453869b
Коммит
79f422b4c1
|
@ -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);
|
||||
}
|
||||
|
@ -363,7 +355,7 @@ calItipProcessor.prototype = {
|
|||
if (!aExistingItem)
|
||||
throw new Error("_processCalendarAction: Item to update not found");
|
||||
|
||||
// TODO: Handle generation properly - Bug 418345
|
||||
// TODO: Handle generation properly - Bug 418345
|
||||
aCalItem.generation = aExistingItem.generation;
|
||||
// We also have to ensure that the calendar is set properly on
|
||||
// the new item, or items with alarms will throw during the
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче