/* * Copyright 2013-2016 Amazon.com, * Inc. or its affiliates. All Rights Reserved. * * Licensed under the Amazon Software License (the "License"). * You may not use this file except in compliance with the * License. A copy of the License is located at * * http://aws.amazon.com/asl/ * * or in the "license" file accompanying this file. This file is * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, express or implied. See the License * for the specific language governing permissions and * limitations under the License. */ package com.amazonaws.mobileconnectors.cognitoidentityprovider.continuations; import android.content.Context; import android.os.Handler; import com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoUser; import com.amazonaws.mobileconnectors.cognitoidentityprovider.handlers.AuthenticationHandler; import com.amazonaws.mobileconnectors.cognitoidentityprovider.util.CognitoServiceConstants; import com.amazonaws.services.cognitoidentityprovider.model.RespondToAuthChallengeRequest; import com.amazonaws.services.cognitoidentityprovider.model.RespondToAuthChallengeResult; import java.util.HashMap; import java.util.Map; /** * Defines a Continuation for a generic auth-challenge. This Continuation is used for all developer * driven challenges. */ public class ChallengeContinuation implements CognitoIdentityProviderContinuation<Map<String, String>> { // Boolean constants used to indicate where this continuation will run. final public static boolean RUN_IN_BACKGROUND = true; final public static boolean RUN_IN_CURRENT = false; private final RespondToAuthChallengeResult challengeResult; private final Context context; private final String clientId; private final String secretHash; private final CognitoUser user; private final String username; private final AuthenticationHandler callback; protected Map<String, String> challengeResponses; private boolean runInBackground; public ChallengeContinuation(CognitoUser user, Context context, String username, String clientId, String secretHash, RespondToAuthChallengeResult challengeResult, boolean runInBackground, AuthenticationHandler callback) { this.challengeResult = challengeResult; this.context = context; this.clientId = clientId; this.secretHash = secretHash; this.user = user; this.username = username; this.callback = callback; this.runInBackground = runInBackground; challengeResponses = new HashMap<String, String>(); } /** * Returns the challenges parameters for a generic challenge (developer defined) challenge. * The keys in this map are usually determined by the developer. They should contain all the * information and resources required by the app, to determine the type of challenge and to * present the challenge to the user. This opens up the authentication process to the developers * to bring their custom steps to authenticate to Cognito User Pools. * * @return A {@link Map<String, String>} containing parameters for this auth challenge process. */ public Map<String, String> getParameters() { return challengeResult.getChallengeParameters(); } /** * Returns the name of the challenge. Use the challenge name and the challenge parameters to * identity the challenge and correctly present to the user. * * @return the challenge name as a {@link String}. */ public String getChallengeName() { return challengeResult.getChallengeName(); } /** * Add responses to the authentication challenge. The responses are added as key-value pairs. The * keys are usually unique to the challenge and are often determined by the developers who have * set this challenge. <b>Note:</b> Overrides an earlier value set for an attribute * which was already added to this object. * * @param responseKey * @param responseValue */ public void setChallengeResponse(String responseKey, String responseValue) { challengeResponses.put(responseKey, responseValue); } /** * Continues the authentication process by responding to the generic challenge posed by the system. * This invokes the method to respond to the generic authentication challenge in the current or on * a background thread depending up on how the authentication process with initiated. * This method gets a {@link Runnable} which is is always executed in the applications thread. * The mechanism to identify the current thread and to run the returned {@link Runnable} in the apps * thread is implemented in this method. */ public void continueTask() { final RespondToAuthChallengeRequest respondToAuthChallengeRequest = new RespondToAuthChallengeRequest(); challengeResponses.put(CognitoServiceConstants.CHLG_RESP_USERNAME, username); challengeResponses.put(CognitoServiceConstants.CHLG_RESP_SECRET_HASH, secretHash); respondToAuthChallengeRequest.setChallengeName(challengeResult.getChallengeName()); respondToAuthChallengeRequest.setSession(challengeResult.getSession()); respondToAuthChallengeRequest.setClientId(clientId); respondToAuthChallengeRequest.setChallengeResponses(challengeResponses); if (runInBackground) { new Thread(new Runnable() { @Override public void run() { Handler handler = new Handler(context.getMainLooper()); Runnable nextStep; try { nextStep = user.respondToChallenge(respondToAuthChallengeRequest, callback, RUN_IN_BACKGROUND); } catch (final Exception e) { nextStep = new Runnable() { @Override public void run() { callback.onFailure(e); } }; } handler.post(nextStep); } }).start(); } else { Runnable nextStep; try { nextStep = user.respondToChallenge(respondToAuthChallengeRequest, callback, RUN_IN_CURRENT); } catch (final Exception e) { nextStep = new Runnable() { @Override public void run() { callback.onFailure(e); } }; } nextStep.run(); } } }