michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: package org.mozilla.gecko.sync.setup.auth; michael@0: michael@0: import java.util.LinkedList; michael@0: import java.util.Queue; michael@0: michael@0: import org.mozilla.gecko.background.common.log.Logger; michael@0: import org.mozilla.gecko.sync.ThreadPool; michael@0: import org.mozilla.gecko.sync.Utils; michael@0: import org.mozilla.gecko.sync.setup.activities.AccountActivity; michael@0: michael@0: public class AccountAuthenticator { michael@0: private final String LOG_TAG = "AccountAuthenticator"; michael@0: michael@0: private AccountActivity activityCallback; michael@0: private Queue stages; michael@0: michael@0: // Values for authentication. michael@0: public String password; michael@0: public String username; michael@0: michael@0: public String authServer; michael@0: public String nodeServer; michael@0: michael@0: public boolean isSuccess = false; michael@0: public boolean isCanceled = false; michael@0: michael@0: public AccountAuthenticator(AccountActivity activity) { michael@0: activityCallback = activity; michael@0: prepareStages(); michael@0: } michael@0: michael@0: private void prepareStages() { michael@0: stages = new LinkedList(); michael@0: stages.add(new EnsureUserExistenceStage()); michael@0: stages.add(new FetchUserNodeStage()); michael@0: stages.add(new AuthenticateAccountStage()); michael@0: } michael@0: michael@0: public void authenticate(String server, String account, String password) { michael@0: // Set authentication values. michael@0: if (!server.endsWith("/")) { michael@0: server += "/"; michael@0: } michael@0: nodeServer = server; michael@0: this.password = password; michael@0: michael@0: // Calculate and save username hash. michael@0: try { michael@0: username = Utils.usernameFromAccount(account); michael@0: } catch (Exception e) { michael@0: abort(AuthenticationResult.FAILURE_OTHER, e); michael@0: return; michael@0: } michael@0: Logger.pii(LOG_TAG, "Username:" + username); michael@0: Logger.debug(LOG_TAG, "Running first stage."); michael@0: // Start first stage of authentication. michael@0: runNextStage(); michael@0: } michael@0: michael@0: /** michael@0: * Run next stage of authentication. michael@0: */ michael@0: public void runNextStage() { michael@0: if (isCanceled) { michael@0: return; michael@0: } michael@0: if (stages.size() == 0) { michael@0: Logger.debug(LOG_TAG, "Authentication completed."); michael@0: activityCallback.authCallback(isSuccess ? AuthenticationResult.SUCCESS : AuthenticationResult.FAILURE_PASSWORD); michael@0: return; michael@0: } michael@0: AuthenticatorStage nextStage = stages.remove(); michael@0: try { michael@0: nextStage.execute(this); michael@0: } catch (Exception e) { michael@0: Logger.warn(LOG_TAG, "Unhandled exception in stage " + nextStage); michael@0: abort(AuthenticationResult.FAILURE_OTHER, e); michael@0: } michael@0: } michael@0: michael@0: /** michael@0: * Abort authentication. michael@0: * michael@0: * @param result michael@0: * returned to callback. michael@0: * @param e michael@0: * Exception causing abort. michael@0: */ michael@0: public void abort(AuthenticationResult result, Exception e) { michael@0: if (isCanceled) { michael@0: return; michael@0: } michael@0: Logger.warn(LOG_TAG, "Authentication failed.", e); michael@0: activityCallback.authCallback(result); michael@0: } michael@0: michael@0: /* Helper functions */ michael@0: public static void runOnThread(Runnable run) { michael@0: ThreadPool.run(run); michael@0: } michael@0: }