Bug 954682 - part 2 - Show buddy authorization requests for JS-XMPP, r=clokep.

This commit is contained in:
Florian Quèze 2012-02-20 18:25:55 +01:00
Родитель 2e0ddd9051
Коммит ff9b8db6f9
6 изменённых файлов: 133 добавлений и 24 удалений

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

@ -41,6 +41,9 @@ interface imIAccount;
interface nsIDOMWindow;
interface nsIWebProgress;
/* This interface is for use in the browser-request notification, to
let protocol plugins open a browser window. This is an unfortunate
necessity for protocols that require an OAuth authentication. */
[scriptable, uuid(b89dbb38-0de4-11e0-b3d0-0002e304243c)]
interface prplIRequestBrowser: nsISupports {
readonly attribute AUTF8String promptText;
@ -50,3 +53,17 @@ interface prplIRequestBrowser: nsISupports {
void loaded(in nsIDOMWindow aWindow,
in nsIWebProgress aWebProgress);
};
/* This interface is used for buddy authorization requests, when the
user needs to confirm if a remote contact should be allowed to see
his presence information. It is implemented by the aSubject
parameter of the buddy-authorization-request and
buddy-authorization-request-canceled notifications.
*/
[scriptable, uuid(a55c1e24-17cc-4ddc-8c64-3bc315a3c3b1)]
interface prplIBuddyRequest: nsISupports {
readonly attribute imIAccount account;
readonly attribute AUTF8String userName;
void grant();
void deny();
};

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

@ -407,14 +407,16 @@ const XMPPAccountBuddyPrototype = {
let resource =
this._account._parseJID(aStanza.attributes["from"]).resource || "";
if (aStanza.attributes["type"] == "unavailable") {
let type = aStanza.attributes["type"];
if (type == "unavailable") {
if (!this._resources || !(resource in this._resources))
return; // ignore for already offline resources.
delete this._resources[resource];
if (preferred == resource)
preferred = undefined;
}
else {
else if (type != "unsubscribe" && type != "unsubscribed" &&
type != "subscribed") {
let statusType = Ci.imIStatusInfo.STATUS_AVAILABLE;
let show = aStanza.getElement(["show"]);
if (show) {
@ -460,8 +462,8 @@ const XMPPAccountBuddyPrototype = {
// FIXME also compare priorities...
preferred = r;
}
if (preferred == this._preferredResource && resource != preferred) {
if (preferred != undefined && preferred == this._preferredResource &&
resource != preferred) {
// The presence information change is only for an unused resource,
// only potential buddy tooltips need to be refreshed.
this._notifyObservers("status-detail-changed");
@ -477,8 +479,12 @@ const XMPPAccountBuddyPrototype = {
delete this._account._conv[this.normalizedName]._targetResource;
this._preferredResource = preferred;
if (preferred === undefined)
this.setStatus(Ci.imIStatusInfo.STATUS_OFFLINE, "");
if (preferred === undefined) {
let statusType = Ci.imIStatusInfo.STATUS_UNKNOWN;
if (type == "unavailable")
statusType = Ci.imIStatusInfo.STATUS_OFFLINE;
this.setStatus(statusType, "");
}
else {
preferred = this._resources[preferred];
this.setStatus(preferred.statusType, preferred.statusText);
@ -512,6 +518,7 @@ const XMPPAccountPrototype = {
this._conv = {};
this._buddies = {};
this._mucs = {};
this._pendingAuthRequests = [];
},
get canJoinChat() true,
@ -633,18 +640,20 @@ const XMPPAccountPrototype = {
throw "Invalid username";
if (this._buddies.hasOwnProperty(jid)) {
DEBUG("not re-adding an existing buddy");
// TODO: check if the subscription is ok or if we should resend
// a presence subscription request.
return;
let subscription = this._buddies[jid].subscription;
if (subscription && (subscription == "both" || subscription == "to")) {
DEBUG("not re-adding an existing buddy");
return;
}
}
else {
let s = Stanza.iq("set", null, null,
Stanza.node("query", Stanza.NS.roster, null,
Stanza.node("item", null, {jid: jid},
Stanza.node("group", null, null,
aTag.name))));
this._connection.sendStanza(s);
}
let s = Stanza.iq("set", null, null,
Stanza.node("query", Stanza.NS.roster, null,
Stanza.node("item", null, {jid: jid},
Stanza.node("group", null, null,
aTag.name))));
this._connection.sendStanza(s);
this._connection.sendStanza(Stanza.presence({to: jid, type: "subscribe"}));
},
@ -720,6 +729,33 @@ const XMPPAccountPrototype = {
}
this._mucs[jid].onPresenceStanza(aStanza);
}
else if (aStanza.attributes["type"] == "subscribe") {
let authRequest = {
_account: this,
get account() this._account.imAccount,
userName: jid,
_sendReply: function(aReply) {
let connection = this._account._connection;
if (!connection)
return;
this._account._pendingAuthRequests =
this._account._pendingAuthRequests.filter(function(r) r !== this);
connection.sendStanza(Stanza.presence({to: this.userName,
type: aReply}));
},
grant: function() { this._sendReply("subscribed"); },
deny: function() { this._sendReply("unsubscribed"); },
cancel: function() {
Services.obs.notifyObservers(this,
"buddy-authorization-request-canceled",
null);
},
QueryInterface: XPCOMUtils.generateQI([Ci.prplIBuddyRequest])
};
Services.obs.notifyObservers(authRequest, "buddy-authorization-request",
null);
this._pendingAuthRequests.push(authRequest);
}
else if (from != this._connection._jid.jid)
WARN("received presence stanza for unknown buddy " + from);
},
@ -964,6 +1000,10 @@ const XMPPAccountPrototype = {
b.setStatus(Ci.imIStatusInfo.STATUS_UNKNOWN, "");
}
for each (let request in this._pendingAuthRequests)
request.cancel();
this._pendingAuthRequests = [];
this._connection.disconnect();
delete this._connection;

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

@ -171,3 +171,12 @@ conv {
#buddyListMsg[listedConvCount="0"] > .listboxHeader {
display: none;
}
/* Make the notification bar work with narrow windows. */
.notification-inner > hbox {
display: inline-block;
}
.notification-inner > hbox > .messageImage {
display: none;
}

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

@ -37,7 +37,9 @@
Components.utils.import("resource:///modules/imStatusUtils.jsm");
const events = ["contact-availability-changed",
const events = ["buddy-authorization-request",
"buddy-authorization-request-canceled",
"contact-availability-changed",
"contact-added",
"contact-tag-added",
"contact-tag-removed",
@ -382,12 +384,47 @@ var buddyList = {
this.convBox._updateListConvCount();
return;
}
else if (aTopic == "showing-ui-conversation") {
if (aTopic == "showing-ui-conversation") {
if (this.convBox.listedConvs.hasOwnProperty(aSubject.id))
this.convBox.listedConvs[aSubject.id].removeNode();
return;
}
if (aTopic == "buddy-authorization-request") {
aSubject.QueryInterface(Ci.prplIBuddyRequest);
let bundle = document.getElementById("instantbirdBundle").stringBundle;
let label = bundle.formatStringFromName("buddy.authRequest.label",
[aSubject.userName], 1);
let value =
"buddy-auth-request-" + aSubject.account.id + aSubject.userName;
let acceptButton = {
accessKey: bundle.GetStringFromName("buddy.authRequest.allow.accesskey"),
label: bundle.GetStringFromName("buddy.authRequest.allow.label"),
callback: function() { aSubject.grant(); }
};
let denyButton = {
accessKey: bundle.GetStringFromName("buddy.authRequest.deny.accesskey"),
label: bundle.GetStringFromName("buddy.authRequest.deny.label"),
callback: function() { aSubject.deny(); }
};
let box = document.getElementById("buddyListMsg");
box.appendNotification(label, value, null, box.PRIORITY_INFO_HIGH,
[acceptButton, denyButton]);
window.getAttention();
return;
}
if (aTopic == "buddy-authorization-request-canceled") {
aSubject.QueryInterface(Ci.prplIBuddyRequest);
let value =
"buddy-auth-request-" + aSubject.account.id + aSubject.userName;
let notification =
document.getElementById("buddyListMsg")
.getNotificationWithValue(value);
if (notification)
notification.close();
return;
}
// aSubject is an imIContact
if (aSubject.online || this._showOffline) {
aSubject.getTags().forEach(function (aTag) {

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

@ -21,11 +21,6 @@ account.deletePrompt.message=Are you sure you want to delete this account?
account.deletePrompt.checkbox=Do &not ask next time
account.deletePrompt.button=&Delete
requestAuthorizeTitle=Authorization request
requestAuthorizeAllow=&Allow
requestAuthorizeDeny=&Deny
requestAuthorizeText=%S added you to his/her buddy list, do you want to allow him/her to see you?
accountsManager.notification.button.accessKey=C
accountsManager.notification.button.label=Connect Now
accountsManager.notification.userDisabled.label=You have disabled automatic connections.

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

@ -11,6 +11,17 @@ newTagPromptMessage=Please enter the name of the new tag:
# this is used in the addBuddies dialog if the list of existing groups is empty
defaultGroup=Contacts
#LOCALIZATION NOTE This string appears in a notification bar at the
# top of the Contacts window when someone added the user to his/her
# contact list, to request the permission from the user to share
# status information with this potential new contact.
# %S is replaced with the user name of the potential new contact.
buddy.authRequest.label=%S wants to chat with you
buddy.authRequest.allow.label=Allow
buddy.authRequest.allow.accesskey=A
buddy.authRequest.deny.label=Deny
buddy.authRequest.deny.accesskey=D
#LOCALIZATION NOTE
# %S here will be replaced by the alias (or username) of a buddy about
# to be removed from the buddy list.