mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 16:55:40 +00:00
Bug 1204937 - Part 3: Add Accounts:UpdateAccountFromJSON message. r=sebastian
This commit does a few things. First, it fixes a typo (s/ForResponse/ForResult/). It's not clear how this /ever/ worked, but it did. Second, it adds an UpdateAccountFromJSON sibling to CreateAccountFromJSON. It would have been reasonable to have the create message do double-duty and update an existing account (we have the latitude to change the meaning since this API is not yet public) but I generally prefer each consumer to perform the conditional state check and to act appropriately. Third, it generalizes the existing Accounts:Exist message to provide some details (including email and UID) of any existing Firefox Account. The Accounts.exist() API /is/ public, so I introduce a new (not yet public) API for this richer information. --HG-- extra : commitid : 5OcLn2ejQzZ extra : rebase_source : dca7f1ab0cb101948e9d67db4595b91127f0bfd6
This commit is contained in:
parent
83fab33f78
commit
803a8d2abf
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.mozilla.gecko;
|
package org.mozilla.gecko;
|
||||||
|
|
||||||
|
import android.accounts.Account;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@ -46,6 +47,7 @@ public class AccountsHelper implements NativeEventListener {
|
|||||||
}
|
}
|
||||||
dispatcher.registerGeckoThreadListener(this,
|
dispatcher.registerGeckoThreadListener(this,
|
||||||
"Accounts:CreateFirefoxAccountFromJSON",
|
"Accounts:CreateFirefoxAccountFromJSON",
|
||||||
|
"Accounts:UpdateFirefoxAccountFromJSON",
|
||||||
"Accounts:Create",
|
"Accounts:Create",
|
||||||
"Accounts:Exist");
|
"Accounts:Exist");
|
||||||
}
|
}
|
||||||
@ -58,6 +60,7 @@ public class AccountsHelper implements NativeEventListener {
|
|||||||
}
|
}
|
||||||
dispatcher.unregisterGeckoThreadListener(this,
|
dispatcher.unregisterGeckoThreadListener(this,
|
||||||
"Accounts:CreateFirefoxAccountFromJSON",
|
"Accounts:CreateFirefoxAccountFromJSON",
|
||||||
|
"Accounts:UpdateFirefoxAccountFromJSON",
|
||||||
"Accounts:Create",
|
"Accounts:Create",
|
||||||
"Accounts:Exist");
|
"Accounts:Exist");
|
||||||
}
|
}
|
||||||
@ -101,6 +104,39 @@ public class AccountsHelper implements NativeEventListener {
|
|||||||
callback.sendSuccess(fxAccount != null);
|
callback.sendSuccess(fxAccount != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if ("Accounts:UpdateFirefoxAccountFromJSON".equals(event)) {
|
||||||
|
try {
|
||||||
|
final Account account = FirefoxAccounts.getFirefoxAccount(mContext);
|
||||||
|
if (account == null) {
|
||||||
|
if (callback != null) {
|
||||||
|
callback.sendError("Could not update Firefox Account since non exists");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final NativeJSObject json = message.getObject("json");
|
||||||
|
final String email = json.getString("email");
|
||||||
|
final String uid = json.getString("uid");
|
||||||
|
final boolean verified = json.optBoolean("verified", false);
|
||||||
|
final byte[] unwrapkB = Utils.hex2Byte(json.getString("unwrapBKey"));
|
||||||
|
final byte[] sessionToken = Utils.hex2Byte(json.getString("sessionToken"));
|
||||||
|
final byte[] keyFetchToken = Utils.hex2Byte(json.getString("keyFetchToken"));
|
||||||
|
final State state = new Engaged(email, uid, verified, unwrapkB, sessionToken, keyFetchToken);
|
||||||
|
|
||||||
|
final AndroidFxAccount fxAccount = new AndroidFxAccount(mContext, account);
|
||||||
|
fxAccount.setState(state);
|
||||||
|
|
||||||
|
if (callback != null) {
|
||||||
|
callback.sendSuccess(true);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.w(LOGTAG, "Got exception updating Firefox Account from JSON; ignoring.", e);
|
||||||
|
if (callback != null) {
|
||||||
|
callback.sendError("Could not update Firefox Account from JSON: " + e.toString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else if ("Accounts:Create".equals(event)) {
|
} else if ("Accounts:Create".equals(event)) {
|
||||||
// Do exactly the same thing as if you tapped 'Sync' in Settings.
|
// Do exactly the same thing as if you tapped 'Sync' in Settings.
|
||||||
final Intent intent = new Intent(FxAccountConstants.ACTION_FXA_GET_STARTED);
|
final Intent intent = new Intent(FxAccountConstants.ACTION_FXA_GET_STARTED);
|
||||||
@ -126,7 +162,26 @@ public class AccountsHelper implements NativeEventListener {
|
|||||||
FirefoxAccounts.firefoxAccountsExist(mContext));
|
FirefoxAccounts.firefoxAccountsExist(mContext));
|
||||||
callback.sendSuccess(response);
|
callback.sendSuccess(response);
|
||||||
} else if ("fxa".equals(kind)) {
|
} else if ("fxa".equals(kind)) {
|
||||||
response.put("exists", FirefoxAccounts.firefoxAccountsExist(mContext));
|
final Account account = FirefoxAccounts.getFirefoxAccount(mContext);
|
||||||
|
response.put("exists", account != null);
|
||||||
|
if (account != null) {
|
||||||
|
response.put("email", account.name);
|
||||||
|
// We should always be able to extract the server endpoints.
|
||||||
|
final AndroidFxAccount fxAccount = new AndroidFxAccount(mContext, account);
|
||||||
|
response.put("authServerEndpoint", fxAccount.getAccountServerURI());
|
||||||
|
response.put("profileServerEndpoint", fxAccount.getProfileServerURI());
|
||||||
|
response.put("tokenServerEndpoint", fxAccount.getTokenServerURI());
|
||||||
|
try {
|
||||||
|
// It is possible for the state fetch to fail and us to not be able to provide a UID.
|
||||||
|
// Long term, the UID (and verification flag) will be attached to the Android account
|
||||||
|
// user data and not the internal state representation.
|
||||||
|
final State state = fxAccount.getState();
|
||||||
|
response.put("uid", state.uid);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.w(LOGTAG, "Got exception extracting account UID; ignoring.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
callback.sendSuccess(response);
|
callback.sendSuccess(response);
|
||||||
} else if ("sync11".equals(kind)) {
|
} else if ("sync11".equals(kind)) {
|
||||||
response.put("exists", SyncAccounts.syncAccountsExist(mContext));
|
response.put("exists", SyncAccounts.syncAccountsExist(mContext));
|
||||||
|
@ -8,9 +8,9 @@ this.EXPORTED_SYMBOLS = ["Accounts"];
|
|||||||
|
|
||||||
const { utils: Cu } = Components;
|
const { utils: Cu } = Components;
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/Messaging.jsm");
|
Cu.import("resource://gre/modules/Messaging.jsm"); /*global Messaging */
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Promise.jsm"); /*global Promise */
|
||||||
Cu.import("resource://gre/modules/Promise.jsm");
|
Cu.import("resource://gre/modules/Services.jsm"); /*global Services */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A promise-based API for querying the existence of Sync accounts,
|
* A promise-based API for querying the existence of Sync accounts,
|
||||||
@ -68,6 +68,19 @@ let Accounts = Object.freeze({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_addDefaultEndpoints: function (json) {
|
||||||
|
let newData = Cu.cloneInto(json, {}, { cloneFunctions: false });
|
||||||
|
let associations = {
|
||||||
|
authServerEndpoint: 'identity.fxaccounts.auth.uri',
|
||||||
|
profileServerEndpoint: 'identity.fxaccounts.remote.profile.uri',
|
||||||
|
tokenServerEndpoint: 'identity.sync.tokenserver.uri'
|
||||||
|
};
|
||||||
|
for (let key in associations) {
|
||||||
|
newData[key] = newData[key] || Services.urlFormatter.formatURLPref(associations[key]);
|
||||||
|
}
|
||||||
|
return newData;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new Android Account corresponding to the given
|
* Create a new Android Account corresponding to the given
|
||||||
* fxa-content-server "login" JSON datum. The new account will be
|
* fxa-content-server "login" JSON datum. The new account will be
|
||||||
@ -78,9 +91,45 @@ let Accounts = Object.freeze({
|
|||||||
* Returns a Promise that resolves to a boolean indicating success.
|
* Returns a Promise that resolves to a boolean indicating success.
|
||||||
*/
|
*/
|
||||||
createFirefoxAccountFromJSON: function (json) {
|
createFirefoxAccountFromJSON: function (json) {
|
||||||
return Messaging.sendRequestForResponse({
|
return Messaging.sendRequestForResult({
|
||||||
type: "Accounts:CreateFirefoxAccountFromJSON",
|
type: "Accounts:CreateFirefoxAccountFromJSON",
|
||||||
json: json
|
json: this._addDefaultEndpoints(json)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move an existing Android Account to the "Engaged" state with the given
|
||||||
|
* fxa-content-server "login" JSON datum. The account will (re)start
|
||||||
|
* syncing immediately, unless the user has manually configured the account
|
||||||
|
* to not Sync.
|
||||||
|
*
|
||||||
|
* It is an error if no Android Account exists.
|
||||||
|
*
|
||||||
|
* Returns a Promise that resolves to a boolean indicating success.
|
||||||
|
*/
|
||||||
|
updateFirefoxAccountFromJSON: function (json) {
|
||||||
|
return Messaging.sendRequestForResult({
|
||||||
|
type: "Accounts:UpdateFirefoxAccountFromJSON",
|
||||||
|
json: this._addDefaultEndpoints(json)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch information about an existing Android Firefox Account.
|
||||||
|
*
|
||||||
|
* Returns a Promise that resolves to null if no Android Firefox Account
|
||||||
|
* exists, or an object including at least a string-valued 'email' key.
|
||||||
|
*/
|
||||||
|
getFirefoxAccount: function () {
|
||||||
|
return Messaging.sendRequestForResult({
|
||||||
|
type: "Accounts:Exist",
|
||||||
|
kind: "fxa",
|
||||||
|
}).then(data => {
|
||||||
|
if (!data || !data.exists) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
delete data.exists;
|
||||||
|
return data;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user