package com.masterofcode.android.magreader; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import javax.security.cert.CertificateException; import javax.security.cert.X509Certificate; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.app.DialogFragment; import android.content.DialogInterface; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.view.KeyEvent; import android.view.View; import android.webkit.WebView; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import com.masterofcode.android.magreader.inapp.util.Base64; import com.masterofcode.android.magreader.subscription.SubscriptionSignInResult; import com.masterofcode.android.magreader.utils.ApplicationUtils; import com.masterofcode.android.magreader.utils.constants.Constants; import com.sandsmedia.apps.mobile.android.epub.lib.R; public class SubscriptionActivity extends Activity { public final static int SUBSCRIPTION_ACTION_LOGIN = 1; public final static int SUBSCRIPTION_ACTION_LOGOUT = 2; public final static int SUBSCRIPTION_ACTION_REQUEST_NAME = 3; public final static int SUBSCRIPTION_ACTION_REQUEST_PASSWORD = 4; public final static int SUBSCRIPTION_ACTION_REGISTER = 5; private int subscriptionAction = 0; private String actionUrl; private WebView actionWebView; private EditText loginEditText; private EditText passwordEditText; private TextView loginTextView; private TextView passwordTextView; private Button signinButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.subscription_layout); if(savedInstanceState==null) { Intent intent = this.getIntent(); subscriptionAction = intent.getIntExtra(Constants.BUNDLE_KEY_SUBSCRIPTION_ACTION, 0); } else { subscriptionAction = savedInstanceState.getInt(Constants.BUNDLE_KEY_SUBSCRIPTION_ACTION, 0); } if(subscriptionAction==0) { setResult(RESULT_CANCELED); finish(); } actionUrl = urlForSubscriptionAction(subscriptionAction); loginEditText = (EditText) findViewById(R.id.loginEditText); passwordEditText = (EditText) findViewById(R.id.passwordEditText); loginTextView = (TextView) findViewById(R.id.loginTextView); passwordTextView = (TextView) findViewById(R.id.passwordTextView); signinButton = (Button) findViewById(R.id.signInButton); actionWebView = (WebView) findViewById(R.id.actionWebView); if(subscriptionAction==SUBSCRIPTION_ACTION_LOGIN) { actionWebView.setVisibility(View.GONE); loginEditText.requestFocus(); loginEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { passwordEditText.requestFocus(); return true; } }); signinButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { signInPressed(); } }); } else { loginEditText.setVisibility(View.GONE); passwordEditText.setVisibility(View.GONE); loginTextView.setVisibility(View.GONE); passwordTextView.setVisibility(View.GONE); signinButton.setVisibility(View.GONE); actionWebView.getSettings().setJavaScriptEnabled(true); actionWebView.loadUrl(actionUrl); } } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt(Constants.BUNDLE_KEY_SUBSCRIPTION_ACTION, subscriptionAction); } protected void signInPressed() { String login = loginEditText.getText().toString(); String password = passwordEditText.getText().toString(); if(login.equals("")) { loginEditText.requestFocus(); return; } if(password.equals("")) { passwordEditText.requestFocus(); return; } performSignIn(login, password); } protected void performSignIn(String login, String password) { new SignInTask().execute(actionUrl, login, password); } private String urlForSubscriptionAction(int actionId) { String result = null; switch (actionId) { case SUBSCRIPTION_ACTION_LOGIN: result = Constants.BACKEND_AUTH_URL; break; case SUBSCRIPTION_ACTION_REGISTER: result = getString(R.string.subscription_account_action_register_new_account_url); break; case SUBSCRIPTION_ACTION_REQUEST_NAME: result = getString(R.string.subscription_account_action_request_name_url); break; case SUBSCRIPTION_ACTION_REQUEST_PASSWORD: result = getString(R.string.subscription_account_action_request_password_url); break; default: break; } return result; } public void loginSuccessful(String login, String password) { ApplicationUtils.setPrefProperty(this, Constants.PREFERENCE_SUBSCRIPTION_ENABLED, true); ApplicationUtils.setPrefProperty(this, Constants.PREFERENCE_SUBSCRIPTION_NAME, login); ApplicationUtils.setPrefProperty(this, Constants.PREFERENCE_SUBSCRIPTION_PASSWORD, password); Intent intent = new Intent(); intent.putExtra(Constants.BUNDLE_KEY_SUBSCRIPTION_IS_LOGGED_IN, true); setResult(RESULT_OK, intent); finish(); } public void loginFailed(SubscriptionSignInResult result) { String title = null; if(result.isNetworkError()) { title = getString(R.string.subscription_dialog_title_auth_ioerror); } else { title = getString(R.string.subscription_dialog_title_auth_failed); } DialogFragment newFragment = SignInErrorDialogFragment.newInstance(title); newFragment.show(getFragmentManager(), "signin_error_dialog"); } class SignInTask extends AsyncTask<String, Integer, SubscriptionSignInResult> { @Override protected SubscriptionSignInResult doInBackground(String... params) { String urlStr = params[0]; final String login = params[1]; final String password = params[2]; HttpURLConnection http = null; URL url; try { url = new URL(urlStr); /* official android auth callback that failed * Authenticator.setDefault (new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(login, password.toCharArray()); } });*/ if (url.getProtocol().toLowerCase().equals("https")) { trustAllHosts(); HttpsURLConnection https = (HttpsURLConnection) url.openConnection(); https.setHostnameVerifier(DO_NOT_VERIFY); http = https; } else { http = (HttpURLConnection) url.openConnection(); } http.setRequestMethod("GET"); http.setDoInput(true); http.setDoOutput(false); http.setConnectTimeout (10000); http.setUseCaches(false); HttpURLConnection.setFollowRedirects(false); String authPair = login+":"+password; http.setRequestProperty("Authorization", "Basic " + Base64.encode(authPair.getBytes())); http.connect(); if(http.getResponseCode()==200) { // load server response InputStream input = new BufferedInputStream(http.getInputStream()); byte data[] = new byte[1024]; while (input.read(data) > 0) { } input.close(); SubscriptionSignInResult result = new SubscriptionSignInResult(true, false); result.setLogin(login); result.setPassword(password); http.disconnect(); return result; } http.disconnect(); } catch (IOException e) { return new SubscriptionSignInResult(false, true); } return new SubscriptionSignInResult(false, false); } @Override protected void onPostExecute(SubscriptionSignInResult result) { super.onPostExecute(result); if(result.isLoginSuccessful()) { loginSuccessful(result.getLogin(), result.getPassword()); } else { loginFailed(result); } } final HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }; private void trustAllHosts() { // Create a trust manager that does not validate certificate chains TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return new java.security.cert.X509Certificate[] {}; } @SuppressWarnings("unused") public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @SuppressWarnings("unused") public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkClientTrusted( java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException { } @Override public void checkServerTrusted( java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException { } } }; // Install the all-trusting trust manager try { SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection .setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch (Exception e) { e.printStackTrace(); } } } public static class SignInErrorDialogFragment extends DialogFragment { private final static String TITLE_KEY = "reason_is_ioerror"; public static SignInErrorDialogFragment newInstance(String title) { SignInErrorDialogFragment frag = new SignInErrorDialogFragment(); Bundle args = new Bundle(); args.putString(TITLE_KEY, title); frag.setArguments(args); return frag; } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { String title = getArguments().getString(TITLE_KEY); return new AlertDialog.Builder(getActivity()) .setTitle(title) .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { } } ) .create(); } } }