Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix AuthenticationDialog crash; Add support for testing Authenticatio… #1254

Merged
merged 6 commits into from
Jul 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ class MockWebRequestHandler implements IWebRequestHandler {

private String mReturnException;

private String mClientVersion;

@Override
public HttpWebResponse sendGet(URL url, Map<String, String> headers) throws IOException {
mRequestUrl = url;
Expand Down Expand Up @@ -107,7 +109,8 @@ public void setRequestCorrelationId(UUID correlationId) {
}

@Override
public void setClientVersion(String clientVersion) {
// Wire up if needed.
public void setClientVersion(String clientVersion) {
mClientVersion = clientVersion;
}

}
7 changes: 7 additions & 0 deletions adal/src/main/java/com/microsoft/aad/adal/ADALError.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,13 @@ public enum ADALError {
*/
DEVELOPER_DIALOG_LAYOUT_INVALID("dialog_authentication.xml file has invalid elements"),

/**
* An exception occurred attempting to inflate the authentication dialog. This exception
* can occur for a number of different reasons
* https://developer.android.com/reference/android/view/InflateException
*/
DEVELOPER_DIALOG_INFLATION_ERROR("An error occur when attempting to inflate the authentication dialog"),

/**
* Invalid request to server.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.util.Log;

Expand Down Expand Up @@ -542,7 +543,7 @@ private void acquireTokenInteractiveFlow(final CallbackHandler callbackHandle,
if (activity == null && !useDialog) {
throw new AuthenticationException(
ADALError.AUTH_REFRESH_FAILED_PROMPT_NOT_ALLOWED, authenticationRequest.getLogInfo()
+ " Cannot launch webview, acitivity is null.");
+ " Cannot launch webview, activity is null.");
}

HttpWebRequest.throwIfNetworkNotAvailable(mContext);
Expand Down Expand Up @@ -888,9 +889,7 @@ private boolean isAccessTokenReturned(final AuthenticationResult authResult) {

private synchronized Handler getHandler() {
if (sHandler == null) {
HandlerThread acquireTokenHandlerThread = new HandlerThread("AcquireTokenRequestHandlerThread");
acquireTokenHandlerThread.start();
sHandler = new Handler(acquireTokenHandlerThread.getLooper());
sHandler = new Handler(Looper.getMainLooper());
}

return sHandler;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Handler;
import android.util.Log;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
Expand Down Expand Up @@ -84,11 +86,25 @@ public void run() {
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);

//Need to be sure that the resource id is actually found
int dialogAuthenticationResourceId = getResourceId("dialog_authentication", "layout");


View webviewInDialog = null;
// using static layout
View webviewInDialog = inflater.inflate(
getResourceId("dialog_authentication", "layout"), null);
mWebView = (WebView) webviewInDialog.findViewById(getResourceId(
"com_microsoft_aad_adal_webView1", "id"));
try {
webviewInDialog = inflater.inflate(dialogAuthenticationResourceId, null);
}catch(InflateException e){
//This code was added to debug a threading issue; however there could be other cases when this would occur... so leaving in.
//NOTE: With the threading issue even though the exception was caught the test app still interrupted (looks like a crash)... presumably because of
//The Android System Webview (Chromium) crashed; however the app does continue after Android restarts the system web view
Logger.e(TAG, "Failed to inflate authentication dialog", "", ADALError.DEVELOPER_DIALOG_INFLATION_ERROR, e);
}

if(webviewInDialog != null) {
mWebView = (WebView) webviewInDialog.findViewById(getResourceId(
"com_microsoft_aad_adal_webView1", "id"));
}
if (mWebView == null) {
Logger.e(
TAG + methodName,
Expand Down
8 changes: 8 additions & 0 deletions automationtestapp/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@
<activity android:name=".ResultActivity"
android:configChanges="orientation|keyboardHidden|screenSize">
</activity>
<activity
android:name=".WebViewActivity"
android:configChanges="orientation|keyboardHidden|screenSize">
</activity>
<activity
android:name="com.microsoft.aad.adal.AuthenticationActivity"
android:label="@string/auth_dialog_title" >
</activity>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.microsoft.aad.automation.testapp;

import android.content.Intent;
import android.net.Uri;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class CustomWebViewClient extends WebViewClient {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious why a CustomWebViewClient if we are just returning false from shouldOverrideUrl

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

False indicates that the webview itself handles the redirect. Which is fine in this case.


@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public class MainActivity extends AppCompatActivity {
public static final int INVALIDATE_REFRESH_TOKEN = 1004;
public static final int INVALIDATE_FAMILY_REFRESH_TOKEN = 1006;
public static final int READ_CACHE = 1005;
public static final int RUN_STRESS_TEST = 1007;

private Context mContext;

Expand Down Expand Up @@ -119,6 +120,22 @@ public void onClick(View v) {
processEmptyCacheRequest();
}
});

final Button runStressTest = (Button) findViewById(R.id.runStressTest);
runStressTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
launchAuthenticationInfoActivity(RUN_STRESS_TEST);
}
});

final Button openWebView = (Button) findViewById(R.id.openWebView);
openWebView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openWebViewActivity();
}
});
}

private void launchAuthenticationInfoActivity(int flowCode) {
Expand All @@ -128,6 +145,11 @@ private void launchAuthenticationInfoActivity(int flowCode) {
this.startActivity(intent);
}

private void openWebViewActivity(){
final Intent intent = new Intent(mContext, WebViewActivity.class);
this.startActivity(intent);
}

private void processEmptyCacheRequest() {
final AuthenticationContext authenticationContext = createAuthenticationContext();
Intent intent = new Intent();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import static com.microsoft.aad.adal.CacheKey.createCacheKeyForFRT;
import static com.microsoft.aad.adal.CacheKey.createCacheKeyForMRRT;
Expand Down Expand Up @@ -85,6 +91,7 @@ public class SignInActivity extends AppCompatActivity {
public static final String CORRELATION_ID = "correlation_id";
public static final String FAMLIY_CLIENT_ID = "foci";
public static final String FORCE_REFRESH = "force_refresh";
public static final String USE_DIALOG = "use_dialog";

static final String INVALID_REFRESH_TOKEN = "some invalid refresh token";

Expand All @@ -105,6 +112,7 @@ public class SignInActivity extends AppCompatActivity {
private String mFamilyClientId;
private boolean mForceRefresh;
private boolean mForceRefreshParameterProvided;
private boolean mUseDialogForAcquireToken;

@Override
public void onCreate(Bundle savedInstanceState) {
Expand Down Expand Up @@ -150,7 +158,18 @@ private void performAuthentication() {
setAuthenticationData(inputItems);
AuthenticationSettings.INSTANCE.setUseBroker(mUseBroker);

mAuthenticationContext = new AuthenticationContext(getApplicationContext(), mAuthority, mValidateAuthority);

if(mUseDialogForAcquireToken) {
//Note: Dialog is not compatible with Broker
if(mUseBroker){
throw new IllegalArgumentException("Cannot use dialog when broker is enabled");
}
//Note: Dialog expects the context provided to the AuthenticationContext to be an activity rather than the app context
mAuthenticationContext = new AuthenticationContext(this, mAuthority, mValidateAuthority);
}else{
mAuthenticationContext = new AuthenticationContext(getApplicationContext(), mAuthority, mValidateAuthority);
}


switch (flowCode) {
case MainActivity.ACQUIRE_TOKEN:
Expand All @@ -168,6 +187,13 @@ private void performAuthentication() {
case MainActivity.INVALIDATE_FAMILY_REFRESH_TOKEN:
processInvalidateFamilyRefreshTokenRequest();
break;
case MainActivity.RUN_STRESS_TEST:
try {
runStressTest();
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
default:
sendErrorToResultActivity("unknown_request", "Unknown request is received");
break;
Expand All @@ -182,6 +208,41 @@ static Intent getErrorIntentForResultActivity(final String error, final String e
return intent;
}

private void runStressTest() throws InterruptedException {
final int MAX_AVAILABLE = 10;
final int TIME_LIMIT = 5 * 60 * 1000;
final long startTime = System.currentTimeMillis();


mAuthenticationContext.getCache().removeAll();
BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable>(10);
ExecutorService executor = new ThreadPoolExecutor(MAX_AVAILABLE, MAX_AVAILABLE, 0L, TimeUnit.MILLISECONDS, blockingQueue);

while(System.currentTimeMillis() - startTime < TIME_LIMIT) {
executor.submit(new Runnable() {
@Override
public void run() {
mAuthenticationContext.acquireTokenSilentAsync(mResource, mClientId, mUserId, new AuthenticationCallback<AuthenticationResult>() {
@Override
public void onSuccess(AuthenticationResult authenticationResult) {
System.err.println( "Stress test success result");
}
@Override
public void onError(Exception exc) {
System.err.println( "Stress test error result");
}
});
}
});
Thread.sleep(50);
}
executor.shutdownNow();

final Intent intent = new Intent();
intent.putExtra(Constants.INVALIDATED_FAMILY_REFRESH_TOKEN_COUNT, String.valueOf("1"));
launchResultActivity(intent);
}

private void sendErrorToResultActivity(final String error, final String errorDescription) {
launchResultActivity(getErrorIntentForResultActivity(error, errorDescription));
}
Expand Down Expand Up @@ -273,6 +334,7 @@ private void setAuthenticationData(final Map<String, String> inputItems) {
inputItems.get(VALIDATE_AUTHORITY));
mForceRefreshParameterProvided = inputItems.get(FORCE_REFRESH) == null ? false : true;
mForceRefresh = inputItems.get(FORCE_REFRESH) == null ? false : Boolean.valueOf(inputItems.get(FORCE_REFRESH));
mUseDialogForAcquireToken = inputItems.get(USE_DIALOG) == null ? false : Boolean.valueOf(inputItems.get(USE_DIALOG));

if (!TextUtils.isEmpty(inputItems.get(UNIQUE_ID))) {
mUserId = inputItems.get(UNIQUE_ID);
Expand Down Expand Up @@ -315,8 +377,17 @@ PromptBehavior getPromptBehavior(final String inputPromptBehaviorString) {
}

private void acquireToken() {
mAuthenticationContext.acquireToken(SignInActivity.this, mResource, mClientId,
mRedirectUri, mLoginHint, mPromptBehavior, mExtraQueryParam, getAdalCallback());
try {
if(mUseDialogForAcquireToken){
mAuthenticationContext.acquireToken( mResource, mClientId,
mRedirectUri, mLoginHint, PromptBehavior.Auto, mExtraQueryParam, getAdalCallback());
}else {
mAuthenticationContext.acquireToken(SignInActivity.this, mResource, mClientId,
mRedirectUri, mLoginHint, PromptBehavior.Auto, mExtraQueryParam, getAdalCallback());
}
}catch(Exception e){
e.printStackTrace();
}
}

private void acquireTokenSilent() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.microsoft.aad.automation.testapp;

import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebSettings;
import android.webkit.WebView;

public class WebViewActivity extends Activity {

private WebView mWebView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_webview);

mWebView = findViewById(R.id.activity_webview);

WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);

mWebView.setWebViewClient(new CustomWebViewClient());
mWebView.loadUrl("https://www.cnn.com");

}

}
18 changes: 18 additions & 0 deletions automationtestapp/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,22 @@
android:layout_below="@+id/readCache"
android:layout_centerHorizontal="true"
android:text="@string/empty_cache" />

<!-- Run Stress Test Button -->
<Button
android:id="@+id/runStressTest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/clearCache"
android:layout_centerHorizontal="true"
android:text="Run Stress" />

<!-- Open WebView Button -->
<Button
android:id="@+id/openWebView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/runStressTest"
android:layout_centerHorizontal="true"
android:text="Open WebView" />
</RelativeLayout>
11 changes: 11 additions & 0 deletions automationtestapp/src/main/res/layout/activity_webview.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".WebViewActivity">

<WebView
android:id="@+id/activity_webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />

</RelativeLayout>
3 changes: 3 additions & 0 deletions automationtestapp/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
<string name="invalidate_token">Invalidate Refresh Token</string>
<string name="empty_cache">Clear Cache</string>
<string name="read_cache">Read Cache</string>
<string name="run_stress">Run Stress</string>
<string name="open_webview">Open WebView</string>
<string name="auth_dialog_title">Test Title</string>
<string name="signin_info">Enter the sign-in info</string>
<string name="go">Go</string>
<string name="enter_signin_info">Please enter the sign in info here...</string>
Expand Down