// Copyright (c) 2011, Chute Corporation. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Chute Corporation nor the names
// of its contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//
package com.chute.sdk.v2.api.authentication;
import android.accounts.AccountAuthenticatorActivity;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import com.chute.sdk.v2.model.enums.AccountType;
import com.chute.sdk.v2.utils.Utils;
import com.dg.libs.rest.callbacks.HttpCallback;
import com.dg.libs.rest.domain.ResponseStatus;
import com.dg.libs.rest.parsers.StringHttpResponseParser;
import org.json.JSONException;
import org.json.JSONObject;
public class AuthenticationActivity extends AccountAuthenticatorActivity {
private static final String TAG = AuthenticationActivity.class
.getSimpleName();
public static final int CODE_HTTP_EXCEPTION = 4;
public static final int CODE_HTTP_ERROR = 5;
public static final int CODE_PARSER_EXCEPTION = 6;
public static final int RESULT_DIFFERENT_CHUTE_USER_AUTHENTICATED = 7;
public static final String INTENT_DIFFERENT_CHUTE_USER_TOKEN = "intent_different_chute_user_token";
private WebView webViewAuthentication;
private AuthenticationFactory authenticationFactory;
private ProgressBar pb;
private String loadWebViewUrl;
private AccountType accountType;
private boolean shouldClearCookiesForAccount;
private boolean shouldClearAllCookies;
private CookieManager cookieManager;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
authenticationFactory = AuthenticationFactory.getInstance();
accountType = AccountType.values()[getIntent().getExtras().getInt(
AuthenticationFactory.EXTRA_ACCOUNT_TYPE)];
boolean shouldRetainSession = getIntent().getExtras().getBoolean(
AuthenticationFactory.EXTRA_RETAIN_SESSION);
loadWebViewUrl = authenticationFactory.getAuthenticationURL(
accountType, shouldRetainSession);
shouldClearCookiesForAccount = getIntent().getExtras().getBoolean(
AuthenticationFactory.EXTRA_COOKIE_ACCOUNTS);
shouldClearAllCookies = getIntent().getExtras().getBoolean(AuthenticationFactory.EXTRA_ALL_COOKIES);
webViewAuthentication = new WebView(this);
webViewAuthentication.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
webViewAuthentication.setWebViewClient(new AuthWebViewClient());
webViewAuthentication.getSettings().setJavaScriptEnabled(true);
webViewAuthentication
.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
CookieSyncManager.createInstance(webViewAuthentication.getContext());
cookieManager = CookieManager.getInstance();
final WebSettings mWebSettings = webViewAuthentication.getSettings();
if (TokenAuthenticationProvider.getInstance().isTokenValid() == false || shouldClearAllCookies == true) {
clearAllCookies(mWebSettings);
}
if (shouldClearCookiesForAccount == true) {
CookieSyncManager.getInstance().sync(); // Get the cookie from
// cookie jar
String cookieUrl = accountType.getLoginMethod().toLowerCase()
+ ".com";
String cookie = cookieManager.getCookie(cookieUrl);
if (cookie == null) {
Log.d(TAG, "No cookies");
} else {
Log.d(TAG, "cookie: " + cookie);
removeCookies(cookie, cookieUrl);
}
}
final FrameLayout frameLayout = new FrameLayout(this);
frameLayout.setLayoutParams(new FrameLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
pb = new ProgressBar(this);
final FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
100, 100);
layoutParams.gravity = Gravity.CENTER;
pb.setLayoutParams(layoutParams);
frameLayout.addView(webViewAuthentication);
frameLayout.addView(pb);
setContentView(frameLayout);
webViewAuthentication.loadUrl(loadWebViewUrl);
}
private final class AuthenticationCodeCallback implements
HttpCallback<String> {
public AuthenticationCodeCallback() {
pb.setVisibility(View.VISIBLE);
}
@Override
public void onSuccess(final String responseData, ResponseStatus responseStatus) {
TokenAuthenticationProvider tokenProvider = TokenAuthenticationProvider
.getInstance();
String token = null;
try {
JSONObject obj = new JSONObject(responseData);
token = obj.getString("access_token");
} catch (JSONException e) {
Log.d(TAG, "JSONException: " + e.getMessage());
}
if (tokenProvider.isTokenValid()
&& !token.equals(tokenProvider.getToken())) {
Intent intent = new Intent();
intent.putExtra(INTENT_DIFFERENT_CHUTE_USER_TOKEN, token);
setResult(RESULT_DIFFERENT_CHUTE_USER_AUTHENTICATED, intent);
} else {
tokenProvider.setToken(token);
setResult(Activity.RESULT_OK);
}
pb.setVisibility(View.GONE);
finish();
}
@Override
public void onHttpError(ResponseStatus responseCode) {
Log.d(TAG, "Response Not Valid, " + " Code: " + responseCode);
setResult(CODE_HTTP_ERROR);
pb.setVisibility(View.GONE);
finish();
}
}
/**
* @author darko.grozdanovski
*/
private final class AuthenticationResponseParser extends
StringHttpResponseParser<String> {
@Override
public String parse(final String responseBody) throws JSONException {
return responseBody;
}
}
private class AuthWebViewClient extends WebViewClient {
/**
* @author darko.grozdanovski
*/
@Override
public boolean shouldOverrideUrlLoading(final WebView view,
final String url) {
Log.e(TAG, "Override " + url);
return super.shouldOverrideUrlLoading(view, url);
}
@Override
public void onPageStarted(final WebView view, final String url,
final Bitmap favicon) {
Log.d(TAG, "Page started " + url);
pb.setVisibility(View.VISIBLE);
try {
if (authenticationFactory.isRedirectUri(url)) {
final Bundle params = Utils.decodeUrl(url);
final String code = params.getString("code");
if (TextUtils.isEmpty(code)) {
setResult(CODE_HTTP_ERROR);
finish();
}
view.stopLoading();
new AuthenticationTokenRequest<>(
AuthenticationFactory
.getInstance().getAuthConstants(), code,
new AuthenticationResponseParser(),
new AuthenticationCodeCallback()).executeAsync();
}
if (authenticationFactory
.isAuthenticationCancelcedRedirectUri(url)) {
Log.d(TAG, "AUTHENTICATION CANCELED");
setResult(RESULT_CANCELED);
finish();
}
} catch (final Exception e) {
Log.d(TAG, "AUTHENTICATION FAILED", e);
setResult(CODE_HTTP_EXCEPTION);
finish();
}
super.onPageStarted(view, url, favicon);
}
@Override
public void onPageFinished(final WebView view, final String url) {
Log.e(TAG, "Page finished " + url);
if (shouldClearCookiesForAccount == true) {
CookieSyncManager.getInstance().sync();
}
pb.setVisibility(View.GONE);
super.onPageFinished(view, url);
}
@Override
public void onReceivedError(final WebView view, final int errorCode,
final String description, final String failingUrl) {
Log.e(TAG, "Error " + failingUrl);
super.onReceivedError(view, errorCode, description, failingUrl);
}
}
private void removeCookies(String cookie, String url) {
String[] cookieValues = cookie.split(";");
for (int i = 0; i < cookieValues.length; ++i) {
String[] parts = cookieValues[i].split("=", 2);
String cookieString = "cookieName=;expires=Sat, 31 Dec 2005 23:59:59 GMT;";
cookieManager.setCookie(url, cookieString);
cookieManager.removeSessionCookie();
cookieManager.removeExpiredCookie();
}
}
private void clearAllCookies(WebSettings mWebSettings) {
webViewAuthentication.clearCache(true);
mWebSettings.setSavePassword(false);
mWebSettings.setSaveFormData(false);
this.getBaseContext().deleteDatabase("webview.db");
this.getBaseContext().deleteDatabase("webviewCache.db");
cookieManager.removeAllCookie();
}
}