Advertisement
faisholtria

AuthenticatorActivity

Jul 16th, 2018
237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 103.38 KB | None | 0 0
  1. /*
  2.  * ownCloud Android client application
  3.  *
  4.  * @author Bartek Przybylski
  5.  * @author David A. Velasco
  6.  * @author masensio
  7.  * @author Mario Danic
  8.  * Copyright (C) 2012  Bartek Przybylski
  9.  * Copyright (C) 2015 ownCloud Inc.
  10.  * Copyright (C) 2017 Mario Danic
  11.  *
  12.  * This program is free software: you can redistribute it and/or modify
  13.  * it under the terms of the GNU General Public License version 2,
  14.  * as published by the Free Software Foundation.
  15.  *
  16.  * This program is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  23.  *
  24.  * All changes by Mario Danic are distributed under the following terms:
  25.  *
  26.  * This program is free software: you can redistribute it and/or modify
  27.  * it under the terms of the GNU Affero General Public License as published by
  28.  * the Free Software Foundation, either version 3 of the License, or
  29.  * at your option) any later version.
  30.  *
  31.  * This program is distributed in the hope that it will be useful,
  32.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  33.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  34.  * GNU Affero General Public License for more details.
  35.  *
  36.  * You should have received a copy of the GNU Affero General Public License
  37.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  38.  *
  39.  */
  40.  
  41. package com.telkomsigma.mobilecloudbisnis.authentication;
  42.  
  43. import android.accounts.Account;
  44. import android.accounts.AccountManager;
  45. import android.app.Dialog;
  46. import android.app.ProgressDialog;
  47. import android.content.ComponentName;
  48. import android.content.Context;
  49. import android.content.Intent;
  50. import android.content.ServiceConnection;
  51. import android.content.SharedPreferences;
  52. import android.content.pm.ActivityInfo;
  53. import android.graphics.Rect;
  54. import android.graphics.drawable.Drawable;
  55. import android.net.Uri;
  56. import android.net.http.SslError;
  57. import android.os.Build;
  58. import android.os.Bundle;
  59. import android.os.Handler;
  60. import android.os.IBinder;
  61. import android.preference.PreferenceManager;
  62. import android.support.annotation.Nullable;
  63. import android.support.design.widget.Snackbar;
  64. import android.support.design.widget.TextInputLayout;
  65. import android.support.v4.app.DialogFragment;
  66. import android.support.v4.app.Fragment;
  67. import android.support.v4.app.FragmentManager;
  68. import android.support.v4.app.FragmentTransaction;
  69. import android.text.Editable;
  70. import android.text.InputType;
  71. import android.text.TextUtils;
  72. import android.text.TextWatcher;
  73. import android.util.AndroidRuntimeException;
  74. import android.util.Log;
  75. import android.view.KeyEvent;
  76. import android.view.MotionEvent;
  77. import android.view.View;
  78. import android.view.View.OnFocusChangeListener;
  79. import android.view.View.OnTouchListener;
  80. import android.view.inputmethod.EditorInfo;
  81. import android.webkit.CookieManager;
  82. import android.webkit.CookieSyncManager;
  83. import android.webkit.HttpAuthHandler;
  84. import android.webkit.SslErrorHandler;
  85. import android.webkit.WebView;
  86. import android.webkit.WebViewClient;
  87. import android.widget.Button;
  88. import android.widget.CheckBox;
  89. import android.widget.EditText;
  90. import android.widget.ImageButton;
  91. import android.widget.LinearLayout;
  92. import android.widget.ProgressBar;
  93. import android.widget.TextView;
  94. import android.widget.TextView.OnEditorActionListener;
  95. import android.widget.Toast;
  96.  
  97. import com.owncloud.android.lib.common.OwnCloudAccount;
  98. import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
  99. import com.owncloud.android.lib.common.OwnCloudCredentials;
  100. import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
  101. import com.owncloud.android.lib.common.UserInfo;
  102. import com.owncloud.android.lib.common.accounts.AccountTypeUtils;
  103. import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
  104. import com.owncloud.android.lib.common.accounts.AccountUtils.Constants;
  105. import com.owncloud.android.lib.common.network.CertificateCombinedException;
  106. import com.owncloud.android.lib.common.network.NetworkUtils;
  107. import com.owncloud.android.lib.common.operations.OnRemoteOperationListener;
  108. import com.owncloud.android.lib.common.operations.RemoteOperation;
  109. import com.owncloud.android.lib.common.operations.RemoteOperationResult;
  110. import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
  111. import com.owncloud.android.lib.common.utils.Log_OC;
  112. import com.owncloud.android.lib.resources.status.OwnCloudVersion;
  113. import com.owncloud.android.lib.resources.users.GetRemoteUserInfoOperation;
  114. import com.telkomsigma.mobilecloudbisnis.MainApp;
  115. import com.telkomsigma.mobilecloudbisnis.custom.Config;
  116. import com.telkomsigma.mobilecloudbisnis.custom.SharedPrefManager;
  117. import com.telkomsigma.mobilecloudbisnis.operations.DetectAuthenticationMethodOperation.AuthenticationMethod;
  118. import com.telkomsigma.mobilecloudbisnis.operations.GetServerInfoOperation;
  119. import com.telkomsigma.mobilecloudbisnis.operations.OAuth2GetAccessToken;
  120. import com.telkomsigma.mobilecloudbisnis.services.OperationsService;
  121. import com.telkomsigma.mobilecloudbisnis.services.OperationsService.OperationsServiceBinder;
  122. import com.telkomsigma.mobilecloudbisnis.ui.activity.ActivateOTPActivity;
  123. import com.telkomsigma.mobilecloudbisnis.ui.activity.IndihomeAuthActivity;
  124. import com.telkomsigma.mobilecloudbisnis.ui.activity.PreLoginActivity;
  125. import com.telkomsigma.mobilecloudbisnis.ui.activity.RegisterActivity;
  126. import com.telkomsigma.mobilecloudbisnis.ui.activity.ForgotPassActivity;
  127. import com.telkomsigma.mobilecloudbisnis.ui.components.CustomEditText;
  128. import com.telkomsigma.mobilecloudbisnis.ui.dialog.CredentialsDialogFragment;
  129. import com.telkomsigma.mobilecloudbisnis.ui.dialog.IndeterminateProgressDialog;
  130. import com.telkomsigma.mobilecloudbisnis.ui.dialog.SamlWebViewDialog;
  131. import com.telkomsigma.mobilecloudbisnis.ui.dialog.SslUntrustedCertDialog;
  132. import com.telkomsigma.mobilecloudbisnis.utils.AnalyticsUtils;
  133. import com.telkomsigma.mobilecloudbisnis.utils.DisplayUtils;
  134. import com.telkomsigma.mobilecloudbisnis.utils.ErrorMessageAdapter;
  135.  
  136. import java.io.InputStream;
  137. import java.net.URLDecoder;
  138. import java.security.cert.X509Certificate;
  139. import java.util.HashMap;
  140. import java.util.Map;
  141.  
  142. import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
  143.  
  144. /**
  145.  * This Activity is used to add an ownCloud account to the App
  146.  */
  147. public class AuthenticatorActivity extends AccountAuthenticatorActivity
  148.         implements OnRemoteOperationListener, OnFocusChangeListener, OnEditorActionListener,
  149.         SsoWebViewClient.SsoWebViewClientListener, SslUntrustedCertDialog.OnSslUntrustedCertListener,
  150.         AuthenticatorAsyncTask.OnAuthenticatorTaskListener {
  151.  
  152.     public static final String EXTRA_ACTION = "ACTION";
  153.     public static final String EXTRA_ACCOUNT = "ACCOUNT";
  154.     public static final byte ACTION_CREATE = 0;
  155.     public static final byte ACTION_UPDATE_TOKEN = 1;               // requested by the user
  156.     public static final byte ACTION_UPDATE_EXPIRED_TOKEN = 2;       // detected by the app
  157.     public static final String PROTOCOL_SUFFIX = "://";
  158.     public static final String LOGIN_URL_DATA_KEY_VALUE_SEPARATOR = ":";
  159.     public static final String HTTPS_PROTOCOL = "https://";
  160.     public static final String HTTP_PROTOCOL = "http://";
  161.     public static final String REGULAR_SERVER_INPUT_TYPE = "regular";
  162.     public static final String SUBDOMAIN_SERVER_INPUT_TYPE = "prefix";
  163.     public static final String DIRECTORY_SERVER_INPUT_TYPE = "suffix";
  164.     private static final String TAG = AuthenticatorActivity.class.getSimpleName();
  165.     private static final String SCREEN_NAME = "Login";
  166.     private static final String KEY_AUTH_TOKEN_TYPE = "AUTH_TOKEN_TYPE";
  167.     private static final String KEY_HOST_URL_TEXT = "HOST_URL_TEXT";
  168.     private static final String KEY_OC_VERSION = "OC_VERSION";
  169.     private static final String KEY_SERVER_VALID = "SERVER_VALID";
  170.     private static final String KEY_SERVER_CHECKED = "SERVER_CHECKED";
  171.     private static final String KEY_SERVER_STATUS_TEXT = "SERVER_STATUS_TEXT";
  172.     private static final String KEY_SERVER_STATUS_ICON = "SERVER_STATUS_ICON";
  173.     private static final String KEY_IS_SSL_CONN = "IS_SSL_CONN";
  174.     private static final String KEY_PASSWORD_EXPOSED = "PASSWORD_VISIBLE";
  175.     private static final String KEY_AUTH_STATUS_TEXT = "AUTH_STATUS_TEXT";
  176.     private static final String KEY_AUTH_STATUS_ICON = "AUTH_STATUS_ICON";
  177.     private static final String KEY_SERVER_AUTH_METHOD = "SERVER_AUTH_METHOD";
  178.     private static final String KEY_WAITING_FOR_OP_ID = "WAITING_FOR_OP_ID";
  179.     private static final String KEY_AUTH_TOKEN = "AUTH_TOKEN";
  180.     private static final String AUTH_ON = "on";
  181.     private static final String AUTH_OPTIONAL = "optional";
  182.     private static final String UNTRUSTED_CERT_DIALOG_TAG = "UNTRUSTED_CERT_DIALOG";
  183.     private static final String SAML_DIALOG_TAG = "SAML_DIALOG";
  184.     private static final String WAIT_DIALOG_TAG = "WAIT_DIALOG";
  185.     private static final String CREDENTIALS_DIALOG_TAG = "CREDENTIALS_DIALOG";
  186.     private static final String KEY_AUTH_IS_FIRST_ATTEMPT_TAG = "KEY_AUTH_IS_FIRST_ATTEMPT";
  187.     private static final String KEY_USERNAME = "USERNAME";
  188.     private static final String KEY_PASSWORD = "PASSWORD";
  189.     private static final String KEY_ASYNC_TASK_IN_PROGRESS = "AUTH_IN_PROGRESS";
  190.     private static final String WEB_LOGIN = "/index.php/login/flow";
  191.     /// activity-level references / state
  192.     private final Handler mHandler = new Handler();
  193.     private final String BASIC_TOKEN_TYPE = AccountTypeUtils.getAuthTokenTypePass(MainApp.getAccountType());
  194.     private final String OAUTH_TOKEN_TYPE = AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType());
  195.     private final String SAML_TOKEN_TYPE = AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType());
  196.     /// parameters from EXTRAs in starter Intent
  197.     private byte mAction;
  198.     private Account mAccount;
  199.     private String mAuthTokenType;
  200.     private ServiceConnection mOperationsServiceConnection = null;
  201.     private OperationsServiceBinder mOperationsServiceBinder = null;
  202.     private AccountManager mAccountMgr;
  203.     private Uri mNewCapturedUriFromOAuth2Redirection;
  204.     /// Server PRE-Fragment elements
  205.     private CustomEditText mHostUrlInput;
  206.     private View mRefreshButton;
  207.     private TextView mServerStatusView;
  208.     private TextWatcher mHostUrlInputWatcher;
  209.     private String mServerStatusText;
  210.     private int mServerStatusIcon = 0;
  211.     private boolean mServerIsChecked = false;
  212.     private boolean mServerIsValid = false;
  213.     private GetServerInfoOperation.ServerInfo mServerInfo = new GetServerInfoOperation.ServerInfo();
  214.     /// Authentication PRE-Fragment elements
  215.     private CheckBox mOAuth2Check;
  216.     private TextView mOAuthAuthEndpointText;
  217.     private TextView mOAuthTokenEndpointText;
  218.     private EditText mUsernameInput;
  219.     private EditText mPasswordInput;
  220.     private View mOkButton;
  221.     private TextView mAuthStatusView;
  222.     private ImageButton mTestServerButton;
  223.     private WebView mLoginWebView;
  224.     private String mAuthStatusText;
  225.     private int mAuthStatusIcon = 0;
  226.     private String mAuthToken = "";
  227.     private AuthenticatorAsyncTask mAsyncTask;
  228.     private boolean mIsFirstAuthAttempt;
  229.     /// Identifier of operation in progress which result shouldn't be lost
  230.     private long mWaitingForOpId = Long.MAX_VALUE;
  231.     private boolean webViewLoginMethod;
  232.     private String webViewUser;
  233.     private String webViewPassword;
  234.     private TextInputLayout mUsernameInputLayout;
  235.     private TextInputLayout mPasswordInputLayout;
  236.     private boolean forceOldLoginMethod = false;
  237.  
  238.     private LinearLayout ll_login;
  239.     private Button btn_pembukalogin, btnPrelogin;
  240.  
  241.     private ProgressDialog dialog;
  242.  
  243.     private static String getWebLoginUserAgent() {
  244.         return Build.MANUFACTURER.substring(0, 1).toUpperCase() +
  245.                 Build.MANUFACTURER.substring(1).toLowerCase() + " " + Build.MODEL;
  246.     }
  247.  
  248.     /**
  249.      * parses a URI string and returns a login data object with the information from the URI string.
  250.      *
  251.      * @param prefix     URI beginning, e.g. cloud://login/
  252.      * @param dataString the complete URI
  253.      * @return login data
  254.      * @throws IllegalArgumentException when
  255.      */
  256.     public static LoginUrlInfo parseLoginDataUrl(String prefix, String dataString) throws IllegalArgumentException {
  257.         if (dataString.length() < prefix.length()) {
  258.             throw new IllegalArgumentException("Invalid login URL detected");
  259.         }
  260.         LoginUrlInfo loginUrlInfo = new LoginUrlInfo();
  261.  
  262.         // format is basically xxx://login/server:xxx&user:xxx&password while all variables are optional
  263.         String data = dataString.substring(prefix.length());
  264.  
  265.         // parse data
  266.         String[] values = data.split("&");
  267.  
  268.         if (values.length < 1 || values.length > 3) {
  269.             // error illegal number of URL elements detected
  270.             throw new IllegalArgumentException("Illegal number of login URL elements detected: " + values.length);
  271.         }
  272.  
  273.         for (String value : values) {
  274.             if (value.startsWith("user" + LOGIN_URL_DATA_KEY_VALUE_SEPARATOR)) {
  275.                 loginUrlInfo.username = URLDecoder.decode(
  276.                         value.substring(("user" + LOGIN_URL_DATA_KEY_VALUE_SEPARATOR).length()));
  277.             } else if (value.startsWith("password" + LOGIN_URL_DATA_KEY_VALUE_SEPARATOR)) {
  278.                 loginUrlInfo.password = URLDecoder.decode(
  279.                         value.substring(("password" + LOGIN_URL_DATA_KEY_VALUE_SEPARATOR).length()));
  280.             } else if (value.startsWith("server" + LOGIN_URL_DATA_KEY_VALUE_SEPARATOR)) {
  281.                 loginUrlInfo.serverAddress = URLDecoder.decode(
  282.                         value.substring(("server" + LOGIN_URL_DATA_KEY_VALUE_SEPARATOR).length()));
  283.             } else {
  284.                 // error illegal URL element detected
  285.                 throw new IllegalArgumentException("Illegal magic login URL element detected: " + value);
  286.             }
  287.         }
  288.  
  289.         return loginUrlInfo;
  290.     }
  291.  
  292.     /**
  293.      * {@inheritDoc}
  294.      * <p>
  295.      * IMPORTANT ENTRY POINT 1: activity is shown to the user
  296.      */
  297.     @Override
  298.     protected void onCreate(Bundle savedInstanceState) {
  299.         //Log_OC.e(TAG,  "onCreate init");
  300.         super.onCreate(savedInstanceState);
  301.  
  302.         SharedPreferences spm =getSharedPreferences(SharedPrefManager.SHARED_PREF, Context.MODE_PRIVATE);
  303.         boolean is_otp=spm.getBoolean(SharedPrefManager.IS_LOGIN,false);
  304.         if (!is_otp) {
  305.             Intent intent = new Intent(getApplicationContext(), PreLoginActivity.class);
  306.             startActivity(intent);
  307.         }
  308.  
  309.         // delete cookies for webView
  310.         deleteCookies();
  311.  
  312.         // Workaround, for fixing a problem with Android Library Suppor v7 19
  313.         //getWindow().requestFeature(Window.FEATURE_NO_TITLE);
  314.         if (getSupportActionBar() != null) {
  315.             getSupportActionBar().hide();
  316.  
  317.             getSupportActionBar().setDisplayHomeAsUpEnabled(false);
  318.             getSupportActionBar().setDisplayShowHomeEnabled(false);
  319.             getSupportActionBar().setDisplayShowTitleEnabled(false);
  320.         }
  321.  
  322.         mIsFirstAuthAttempt = true;
  323.  
  324.         /// init activity state
  325.         mAccountMgr = AccountManager.get(this);
  326.         mNewCapturedUriFromOAuth2Redirection = null;
  327.  
  328.         /// get input values
  329.         mAction = getIntent().getByteExtra(EXTRA_ACTION, ACTION_CREATE);
  330.         mAccount = getIntent().getExtras().getParcelable(EXTRA_ACCOUNT);
  331.         if (savedInstanceState == null) {
  332.             initAuthTokenType();
  333.         } else {
  334.             mAuthTokenType = savedInstanceState.getString(KEY_AUTH_TOKEN_TYPE);
  335.             mWaitingForOpId = savedInstanceState.getLong(KEY_WAITING_FOR_OP_ID);
  336.             mIsFirstAuthAttempt = savedInstanceState.getBoolean(KEY_AUTH_IS_FIRST_ATTEMPT_TAG);
  337.         }
  338.  
  339.         webViewLoginMethod = !TextUtils.isEmpty(getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.webview_login_url));
  340.  
  341.         if (webViewLoginMethod) {
  342.             setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
  343.         }
  344.  
  345.         /// load user interface
  346.         if (!webViewLoginMethod) {
  347.             setContentView(com.telkomsigma.mobilecloudbisnis.R.layout.account_setup);
  348.  
  349.             /// initialize general UI elements
  350.             initOverallUi();
  351.  
  352.             findViewById(com.telkomsigma.mobilecloudbisnis.R.id.centeredRefreshButton).setOnClickListener(new View.OnClickListener() {
  353.  
  354.                 @Override
  355.                 public void onClick(View v) {
  356.                     checkOcServer();
  357.                 }
  358.             });
  359.  
  360.             findViewById(com.telkomsigma.mobilecloudbisnis.R.id.embeddedRefreshButton).setOnClickListener(new View.OnClickListener() {
  361.  
  362.                 @Override
  363.                 public void onClick(View v) {
  364.                     checkOcServer();
  365.                 }
  366.             });
  367.  
  368.             /// initialize block to be moved to single Fragment to check server and get info about it
  369.  
  370.             /// initialize block to be moved to single Fragment to retrieve and validate credentials
  371.             initAuthorizationPreFragment(savedInstanceState);
  372.  
  373.         } else {
  374.             setContentView(com.telkomsigma.mobilecloudbisnis.R.layout.account_setup_webview);
  375.             mLoginWebView = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.login_webview);
  376.             initWebViewLogin(null);
  377.         }
  378.  
  379.         initServerPreFragment(savedInstanceState);
  380.         //onTestServerConnectionClick();
  381.     }
  382.  
  383.     private void deleteCookies() {
  384.         try {
  385.             CookieSyncManager.createInstance(this);
  386.             CookieManager cookieManager = CookieManager.getInstance();
  387.  
  388.             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  389.                 cookieManager.removeAllCookies(null);
  390.             } else {
  391.                 cookieManager.removeAllCookie();
  392.             }
  393.         } catch (AndroidRuntimeException e) {
  394.             Log_OC.e(TAG, e.getMessage());
  395.         }
  396.     }
  397.  
  398.     private void initWebViewLogin(String baseURL) {
  399.         mLoginWebView.setVisibility(View.GONE);
  400.  
  401.         final ProgressBar progressBar = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.login_webview_progress_bar);
  402.  
  403.         mLoginWebView.getSettings().setAllowFileAccess(false);
  404.         mLoginWebView.getSettings().setJavaScriptEnabled(true);
  405.         mLoginWebView.getSettings().setDomStorageEnabled(true);
  406.         mLoginWebView.getSettings().setUserAgentString(getWebLoginUserAgent());
  407.         mLoginWebView.getSettings().setSaveFormData(false);
  408.         mLoginWebView.getSettings().setSavePassword(false);
  409.  
  410.         Map<String, String> headers = new HashMap<>();
  411.         headers.put(RemoteOperation.OCS_API_HEADER, RemoteOperation.OCS_API_HEADER_VALUE);
  412.  
  413.         String url;
  414.         if (baseURL != null && !baseURL.isEmpty()) {
  415.             url = baseURL + WEB_LOGIN;
  416.         } else {
  417.             url = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.webview_login_url);
  418.         }
  419.  
  420.         mLoginWebView.loadUrl(url, headers);
  421.  
  422.         mLoginWebView.setWebViewClient(new WebViewClient() {
  423.             @Override
  424.             public boolean shouldOverrideUrlLoading(WebView view, String url) {
  425.                 if (url.startsWith(getString(com.telkomsigma.mobilecloudbisnis.R.string.login_data_own_scheme) + PROTOCOL_SUFFIX + "login/")) {
  426.                     parseAndLoginFromWebView(url);
  427.                     return true;
  428.                 }
  429.                 return false;
  430.             }
  431.  
  432.             @Override
  433.             public void onPageFinished(WebView view, String url) {
  434.                 super.onPageFinished(view, url);
  435.  
  436.                 progressBar.setVisibility(View.GONE);
  437.                 mLoginWebView.setVisibility(View.VISIBLE);
  438.             }
  439.  
  440.             @Override
  441.             public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
  442.                 X509Certificate cert = SsoWebViewClient.getX509CertificateFromError(error);
  443.  
  444.                 try {
  445.                     if (cert != null && NetworkUtils.isCertInKnownServersStore(cert, getApplicationContext())) {
  446.                         handler.proceed();
  447.                     } else {
  448.                         showUntrustedCertDialog(cert, error, handler);
  449.                     }
  450.                 } catch (Exception e) {
  451.                     Log_OC.e(TAG, "Cert could not be verified");
  452.                 }
  453.             }
  454.  
  455.             public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
  456.                 progressBar.setVisibility(View.GONE);
  457.                 mLoginWebView.setVisibility(View.VISIBLE);
  458.  
  459.                 InputStream resources = getResources().openRawResource(com.telkomsigma.mobilecloudbisnis.R.raw.custom_error);
  460.                 String customError = DisplayUtils.getData(resources);
  461.  
  462.                 if (!customError.isEmpty()) {
  463.                     mLoginWebView.loadData(customError, "text/html; charset=UTF-8", null);
  464.                 }
  465.             }
  466.         });
  467.  
  468.         // show snackbar after 60s to switch back to old login method
  469.         new Handler().postDelayed(new Runnable() {
  470.             @Override
  471.             public void run() {
  472.                 Snackbar.make(mLoginWebView, com.telkomsigma.mobilecloudbisnis.R.string.fallback_weblogin_text, Snackbar.LENGTH_INDEFINITE)
  473.                         .setAction(com.telkomsigma.mobilecloudbisnis.R.string.fallback_weblogin_back, new View.OnClickListener() {
  474.                             @Override
  475.                             public void onClick(View v) {
  476.                                 mLoginWebView.setVisibility(View.INVISIBLE);
  477.                                 webViewLoginMethod = false;
  478.  
  479.                                 setContentView(com.telkomsigma.mobilecloudbisnis.R.layout.account_setup);
  480.  
  481.                                 // initialize general UI elements
  482.                                 initOverallUi();
  483.  
  484.                                 mPasswordInputLayout.setVisibility(View.VISIBLE);
  485.                                 mUsernameInputLayout.setVisibility(View.VISIBLE);
  486.                                 mUsernameInput.requestFocus();
  487.                                 mOAuth2Check.setVisibility(View.INVISIBLE);
  488.                                 mAuthStatusView.setVisibility(View.INVISIBLE);
  489.                                 mServerStatusView.setVisibility(View.INVISIBLE);
  490.                                 mTestServerButton.setVisibility(View.INVISIBLE);
  491.                                 forceOldLoginMethod = true;
  492.                                 mOkButton.setVisibility(View.VISIBLE);
  493.  
  494.                                 initServerPreFragment(null);
  495.  
  496.                                 mHostUrlInput.setText(baseURL);
  497.  
  498.                                 checkOcServer();
  499.                             }
  500.                         }).show();
  501.             }
  502.         }, 60000);
  503.     }
  504.  
  505.     private void parseAndLoginFromWebView(String dataString) {
  506.         String prefix = getString(com.telkomsigma.mobilecloudbisnis.R.string.login_data_own_scheme) + PROTOCOL_SUFFIX + "login/";
  507.         LoginUrlInfo loginUrlInfo = parseLoginDataUrl(prefix, dataString);
  508.  
  509.         if (loginUrlInfo != null) {
  510.             mServerInfo.mBaseUrl = AuthenticatorUrlUtils.normalizeUrlSuffix(loginUrlInfo.serverAddress);
  511.             webViewUser = loginUrlInfo.username;
  512.             webViewPassword = loginUrlInfo.password;
  513.             checkOcServer();
  514.         }
  515.     }
  516.  
  517.     private void populateLoginFields(String dataString) throws IllegalArgumentException {
  518.         // check if it is cloud://login/
  519.         if (dataString.startsWith(getString(com.telkomsigma.mobilecloudbisnis.R.string.login_data_own_scheme) + PROTOCOL_SUFFIX + "login/")) {
  520.             String prefix = getString(com.telkomsigma.mobilecloudbisnis.R.string.login_data_own_scheme) + PROTOCOL_SUFFIX + "login/";
  521.             LoginUrlInfo loginUrlInfo = parseLoginDataUrl(prefix, dataString);
  522.  
  523.             if (loginUrlInfo != null) {
  524.                 mHostUrlInput.setText(loginUrlInfo.serverAddress);
  525.                 mUsernameInput.setText(loginUrlInfo.username);
  526.                 mPasswordInput.setText(loginUrlInfo.password);
  527.  
  528.                 if (loginUrlInfo.serverAddress != null && !mServerIsChecked) {
  529.                     onUrlInputFocusLost();
  530.                 }
  531.             }
  532.         }
  533.     }
  534.  
  535.     private void initAuthTokenType() {
  536.         mAuthTokenType = getIntent().getExtras().getString(AccountAuthenticator.KEY_AUTH_TOKEN_TYPE);
  537.         if (mAuthTokenType == null) {
  538.             if (mAccount != null) {
  539.                 boolean oAuthRequired = (mAccountMgr.getUserData(mAccount, Constants.KEY_SUPPORTS_OAUTH2) != null);
  540.                 boolean samlWebSsoRequired = (
  541.                         mAccountMgr.getUserData
  542.                                 (mAccount, Constants.KEY_SUPPORTS_SAML_WEB_SSO) != null
  543.                 );
  544.                 mAuthTokenType = chooseAuthTokenType(oAuthRequired, samlWebSsoRequired);
  545.  
  546.             } else {
  547.                 boolean oAuthSupported = AUTH_ON.equals(getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_method_oauth2));
  548.                 boolean samlWebSsoSupported = AUTH_ON.equals(getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_method_saml_web_sso));
  549.                 mAuthTokenType = chooseAuthTokenType(oAuthSupported, samlWebSsoSupported);
  550.             }
  551.         }
  552.     }
  553.  
  554.     private String chooseAuthTokenType(boolean oauth, boolean saml) {
  555.         if (saml) {
  556.             return SAML_TOKEN_TYPE;
  557.         } else if (oauth) {
  558.             return OAUTH_TOKEN_TYPE;
  559.         } else {
  560.             return BASIC_TOKEN_TYPE;
  561.         }
  562.     }
  563.  
  564.  
  565.     /**
  566.      * Configures elements in the user interface under direct control of the Activity.
  567.      */
  568.     private void initOverallUi() {
  569.         ll_login = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.ll_login);
  570.         btn_pembukalogin = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.btn_pembukalogin);
  571.         mHostUrlInput = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.hostUrlInput);
  572.         mUsernameInputLayout = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.input_layout_account_username);
  573.         mPasswordInputLayout = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.input_layout_account_password);
  574.         mPasswordInput = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.account_password);
  575.         mUsernameInput = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.account_username);
  576.         mAuthStatusView = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.auth_status_text);
  577.         mOAuth2Check = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.oauth_onOff_check);
  578.         mServerStatusView = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.server_status_text);
  579.         mTestServerButton = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.testServerButton);
  580.  
  581.         mOkButton = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.buttonOK);
  582.         mOkButton.setOnClickListener(v -> onOkClick());
  583.         mPasswordInput.setText(Config.DEFAULT_PASSWORD);
  584.         /// step 1 - load and process relevant inputs (resources, intent, savedInstanceState)
  585.         boolean isWelcomeLinkVisible = getResources().getBoolean(com.telkomsigma.mobilecloudbisnis.R.bool.show_welcome_link);
  586.  
  587.         String instructionsMessageText = null;
  588.         if (mAction == ACTION_UPDATE_EXPIRED_TOKEN) {
  589.             if (AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType()).equals(mAuthTokenType)) {
  590.                 instructionsMessageText = getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_expired_oauth_token_toast);
  591.  
  592.             } else if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType())
  593.                     .equals(mAuthTokenType)) {
  594.                 instructionsMessageText = getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_expired_saml_sso_token_toast);
  595.  
  596.             } else {
  597.                 instructionsMessageText = getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_expired_basic_auth_toast);
  598.             }
  599.         }
  600.  
  601.         /// step 2 - set properties of UI elements (text, visibility, enabled...)
  602.         Button welcomeLink = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.welcome_link);
  603.         //welcomeLink.setVisibility(mAction == ACTION_CREATE && isWelcomeLinkVisible ? View.GONE : View.GONE);
  604.         welcomeLink.setText(getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_register));
  605.  
  606.         //mTestServerButton.setVisibility(mAction == ACTION_CREATE ? View.VISIBLE : View.GONE);
  607.  
  608.         btn_pembukalogin.setOnClickListener(new View.OnClickListener() {
  609.             @Override
  610.             public void onClick(View v) {
  611.                 welcomeLink.setVisibility(mAction == ACTION_CREATE && isWelcomeLinkVisible ? View.GONE : View.GONE);
  612.                 mPasswordInput.setVisibility(View.INVISIBLE);
  613.                 dialog = new ProgressDialog(AuthenticatorActivity.this);
  614.                 dialog.setMessage("Please wait...");
  615.                 dialog.show();
  616.                 //SharedPreferences spm =getSharedPreferences(SharedPrefManager.SHARED_PREF, Context.MODE_PRIVATE);
  617.                 SharedPreferences spm =getSharedPreferences(SharedPrefManager.SHARED_PREF, Context.MODE_PRIVATE);
  618.                 String email=spm.getString(SharedPrefManager.USERID,"");
  619.                 mUsernameInput.setText(email);
  620.                 mUsernameInput.setEnabled(false);
  621.                 mPasswordInput.setText(Config.DEFAULT_PASSWORD);
  622.                 mPasswordInput.setEnabled(false);
  623.                 //boolean is_otp=spm.getBoolean(SharedPrefManager.IS_LOGIN,false);
  624.  
  625.  
  626.                 onTestServerConnectionClick();
  627.             }
  628.         });
  629.         //mTestServerButton.setVisibility(mAction == ACTION_CREATE ? View.VISIBLE : View.GONE);
  630. //        Intent intent = getIntent();
  631. //
  632. //        // Get the extras (if there are any)
  633. //        Bundle extras = intent.getExtras();
  634. //        if (extras != null) {
  635. //            if (extras.containsKey("email")) {
  636.  
  637. //            }
  638. //        }
  639.  
  640.         TextView instructionsView = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.instructions_message);
  641.         if (instructionsMessageText != null) {
  642.             instructionsView.setVisibility(View.VISIBLE);
  643.             instructionsView.setText(instructionsMessageText);
  644.         } else {
  645.             instructionsView.setVisibility(View.GONE);
  646.         }
  647.  
  648.         mTestServerButton.setOnClickListener(new View.OnClickListener() {
  649.             @Override
  650.             public void onClick(View view) {
  651.                 checkOcServer();
  652.             }
  653.         });
  654.  
  655.     }
  656.  
  657.     public void onTestServerConnectionClick() {
  658.         checkOcServer();
  659.     }
  660.  
  661.  
  662.     /**
  663.      * @param savedInstanceState Saved activity state, as in {{@link #onCreate(Bundle)}
  664.      */
  665.     private void initServerPreFragment(Bundle savedInstanceState) {
  666.  
  667.         /// step 1 - load and process relevant inputs (resources, intent, savedInstanceState)
  668.         boolean isUrlInputAllowed = getResources().getBoolean(com.telkomsigma.mobilecloudbisnis.R.bool.show_server_url_input);
  669.         if (savedInstanceState == null) {
  670.             if (mAccount != null) {
  671.                 mServerInfo.mBaseUrl = mAccountMgr.getUserData(mAccount, Constants.KEY_OC_BASE_URL);
  672.                 // TODO do next in a setter for mBaseUrl
  673.                 mServerInfo.mIsSslConn = mServerInfo.mBaseUrl.startsWith(HTTPS_PROTOCOL);
  674.                 mServerInfo.mVersion = AccountUtils.getServerVersion(mAccount);
  675.             } else {
  676.                 if (!webViewLoginMethod) {
  677.                     mServerInfo.mBaseUrl = getString(com.telkomsigma.mobilecloudbisnis.R.string.server_url).trim();
  678.                 } else {
  679.                     mServerInfo.mBaseUrl = getString(com.telkomsigma.mobilecloudbisnis.R.string.webview_login_url).trim();
  680.                 }
  681.                 mServerInfo.mIsSslConn = mServerInfo.mBaseUrl.startsWith(HTTPS_PROTOCOL);
  682.             }
  683.         } else {
  684.             mServerStatusText = savedInstanceState.getString(KEY_SERVER_STATUS_TEXT);
  685.             mServerStatusIcon = savedInstanceState.getInt(KEY_SERVER_STATUS_ICON);
  686.  
  687.             mServerIsValid = savedInstanceState.getBoolean(KEY_SERVER_VALID);
  688.             mServerIsChecked = savedInstanceState.getBoolean(KEY_SERVER_CHECKED);
  689.  
  690.             // TODO parcelable
  691.             mServerInfo.mIsSslConn = savedInstanceState.getBoolean(KEY_IS_SSL_CONN);
  692.             mServerInfo.mBaseUrl = savedInstanceState.getString(KEY_HOST_URL_TEXT);
  693.             String ocVersion = savedInstanceState.getString(KEY_OC_VERSION);
  694.             if (ocVersion != null) {
  695.                 mServerInfo.mVersion = new OwnCloudVersion(ocVersion);
  696.             }
  697.             mServerInfo.mAuthMethod = AuthenticationMethod.valueOf(
  698.                     savedInstanceState.getString(KEY_SERVER_AUTH_METHOD));
  699.  
  700.         }
  701.  
  702.         if (!webViewLoginMethod) {
  703.             /// step 2 - set properties of UI elements (text, visibility, enabled...)
  704.             mHostUrlInput = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.hostUrlInput);
  705.             // Convert IDN to Unicode
  706.             mHostUrlInput.setText(DisplayUtils.convertIdn(mServerInfo.mBaseUrl, false));
  707.             if (mAction != ACTION_CREATE) {
  708.                 /// lock things that should not change
  709.                 mHostUrlInput.setEnabled(false);
  710.                 mHostUrlInput.setFocusable(false);
  711.             }
  712.             if (isUrlInputAllowed) {
  713.                 mRefreshButton = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.embeddedRefreshButton);
  714.             } else {
  715.                 findViewById(com.telkomsigma.mobilecloudbisnis.R.id.hostUrlFrame).setVisibility(View.GONE);
  716.                 mRefreshButton = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.centeredRefreshButton);
  717.             }
  718.             showRefreshButton(mServerIsChecked && !mServerIsValid &&
  719.                     mWaitingForOpId > Integer.MAX_VALUE);
  720.             mServerStatusView = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.server_status_text);
  721.             showServerStatus();
  722.  
  723.             /// step 3 - bind some listeners and options
  724.             mHostUrlInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
  725.             mHostUrlInput.setOnEditorActionListener(this);
  726.  
  727.             /// step 4 - create listeners that will be bound at onResume
  728.             mHostUrlInputWatcher = new TextWatcher() {
  729.  
  730.                 @Override
  731.                 public void afterTextChanged(Editable s) {
  732.                     if (mOkButton.isEnabled() &&
  733.                             !mServerInfo.mBaseUrl.equals(
  734.                                     AuthenticatorUrlUtils.normalizeUrl(s.toString(), mServerInfo.mIsSslConn))) {
  735.                         mOkButton.setEnabled(false);
  736.                     }
  737.                 }
  738.  
  739.                 @Override
  740.                 public void beforeTextChanged(CharSequence s, int start, int count, int after) {
  741.                     // not used at the moment
  742.                 }
  743.  
  744.                 @Override
  745.                 public void onTextChanged(CharSequence s, int start, int before, int count) {
  746.                     if (mAuthStatusIcon != 0) {
  747.                         Log_OC.d(TAG, "onTextChanged: hiding authentication status");
  748.                         mAuthStatusIcon = 0;
  749.                         mAuthStatusText = "";
  750.                         showAuthStatus();
  751.                     }
  752.                 }
  753.             };
  754.  
  755.  
  756.             // TODO find out if this is really necessary, or if it can done in a different way
  757.             findViewById(com.telkomsigma.mobilecloudbisnis.R.id.scroll).setOnTouchListener(new OnTouchListener() {
  758.                 @Override
  759.                 public boolean onTouch(View view, MotionEvent event) {
  760.                     if (event.getAction() == MotionEvent.ACTION_DOWN &&
  761.                             AccountTypeUtils
  762.                                     .getAuthTokenTypeSamlSessionCookie(MainApp
  763.                                             .getAccountType()).equals(mAuthTokenType) &&
  764.                             mHostUrlInput.hasFocus()) {
  765.                         checkOcServer();
  766.                     }
  767.                     return false;
  768.                 }
  769.             });
  770.         }
  771.     }
  772.  
  773.  
  774.     /**
  775.      * @param savedInstanceState Saved activity state, as in {{@link #onCreate(Bundle)}
  776.      */
  777.     private void initAuthorizationPreFragment(Bundle savedInstanceState) {
  778.  
  779.         /// step 0 - get UI elements in layout
  780.         mOAuth2Check = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.oauth_onOff_check);
  781.         mOAuthAuthEndpointText = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.oAuthEntryPoint_1);
  782.         mOAuthTokenEndpointText = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.oAuthEntryPoint_2);
  783.         mUsernameInput = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.account_username);
  784.         mPasswordInput = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.account_password);
  785.         mAuthStatusView = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.auth_status_text);
  786.  
  787.         /// step 1 - load and process relevant inputs (resources, intent, savedInstanceState)
  788.         String presetUserName = null;
  789.         boolean isPasswordExposed = false;
  790.         if (savedInstanceState == null) {
  791.             if (mAccount != null) {
  792.                 presetUserName = com.owncloud.android.lib.common.accounts.AccountUtils.getUsernameForAccount(mAccount);
  793.             }
  794.         } else {
  795.             isPasswordExposed = savedInstanceState.getBoolean(KEY_PASSWORD_EXPOSED, false);
  796.             mAuthStatusText = savedInstanceState.getString(KEY_AUTH_STATUS_TEXT);
  797.             mAuthStatusIcon = savedInstanceState.getInt(KEY_AUTH_STATUS_ICON);
  798.             mAuthToken = savedInstanceState.getString(KEY_AUTH_TOKEN);
  799.         }
  800.  
  801.         /// step 2 - set properties of UI elements (text, visibility, enabled...)
  802.         mOAuth2Check.setChecked(
  803.                 AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType())
  804.                         .equals(mAuthTokenType));
  805.         if (presetUserName != null) {
  806.             mUsernameInput.setText(presetUserName);
  807.         }
  808.         if (mAction != ACTION_CREATE) {
  809.             mUsernameInput.setEnabled(false);
  810.             mUsernameInput.setFocusable(false);
  811.         }
  812.         mPasswordInput.setText(""); // clean password to avoid social hacking
  813.         if (isPasswordExposed) {
  814.             showPassword();
  815.         }
  816.         updateAuthenticationPreFragmentVisibility();
  817.         showAuthStatus();
  818.         mOkButton.setEnabled(mServerIsValid);
  819.  
  820.  
  821.         /// step 3 - bind listeners
  822.         // bindings for password input field
  823.         mPasswordInput.setOnFocusChangeListener(this);
  824.         mPasswordInput.setImeOptions(EditorInfo.IME_ACTION_DONE);
  825.         mPasswordInput.setOnEditorActionListener(this);
  826.         mPasswordInput.setOnTouchListener(new RightDrawableOnTouchListener() {
  827.             @Override
  828.             public boolean onDrawableTouch(final MotionEvent event) {
  829.                 if (event.getAction() == MotionEvent.ACTION_UP) {
  830.                     AuthenticatorActivity.this.onViewPasswordClick();
  831.                 }
  832.                 return true;
  833.             }
  834.         });
  835.         SharedPreferences spm =getSharedPreferences(SharedPrefManager.SHARED_PREF, Context.MODE_PRIVATE);
  836.         String email=spm.getString(SharedPrefManager.USERID,"");
  837.         mUsernameInput.setText(email);
  838.         mUsernameInput.setEnabled(false);
  839.         mPasswordInput.setText(Config.DEFAULT_PASSWORD);
  840.         mPasswordInput.setEnabled(false);
  841.  
  842.     }
  843.  
  844.  
  845.     /**
  846.      * Changes the visibility of input elements depending on
  847.      * the current authorization method.
  848.      */
  849.     private void updateAuthenticationPreFragmentVisibility() {
  850.         if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).
  851.                 equals(mAuthTokenType)) {
  852.             // SAML-based web Single Sign On
  853.             mOAuth2Check.setVisibility(View.GONE);
  854.             mOAuthAuthEndpointText.setVisibility(View.GONE);
  855.             mOAuthTokenEndpointText.setVisibility(View.GONE);
  856.             mUsernameInput.setVisibility(View.GONE);
  857.             mPasswordInput.setVisibility(View.GONE);
  858.  
  859.         } else {
  860.             if (mAction == ACTION_CREATE &&
  861.                     AUTH_OPTIONAL.equals(getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_method_oauth2))) {
  862.                 mOAuth2Check.setVisibility(View.VISIBLE);
  863.             } else {
  864.                 mOAuth2Check.setVisibility(View.GONE);
  865.             }
  866.  
  867.             if (AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType()).
  868.                     equals(mAuthTokenType)) {
  869.                 // OAuth 2 authorization
  870.  
  871.                 mOAuthAuthEndpointText.setVisibility(View.VISIBLE);
  872.                 mOAuthTokenEndpointText.setVisibility(View.VISIBLE);
  873.                 mUsernameInput.setVisibility(View.GONE);
  874.                 mPasswordInput.setVisibility(View.GONE);
  875.  
  876.             } else {
  877.                 // basic HTTP authorization
  878.                 mOAuthAuthEndpointText.setVisibility(View.GONE);
  879.                 mOAuthTokenEndpointText.setVisibility(View.GONE);
  880.                 mUsernameInput.setVisibility(View.VISIBLE);
  881.                 mPasswordInput.setVisibility(View.VISIBLE);
  882.             }
  883.         }
  884.     }
  885.  
  886.  
  887.     /**
  888.      * Saves relevant state before {@link #onPause()}
  889.      * <p>
  890.      * Do NOT save {@link #mNewCapturedUriFromOAuth2Redirection}; it keeps a temporal flag,
  891.      * intended to defer the processing of the redirection caught in
  892.      * {@link #onNewIntent(Intent)} until {@link #onResume()}
  893.      * <p>
  894.      * See {@link super#onSaveInstanceState(Bundle)}
  895.      */
  896.     @Override
  897.     protected void onSaveInstanceState(Bundle outState) {
  898.         //Log_OC.e(TAG, "onSaveInstanceState init" );
  899.         super.onSaveInstanceState(outState);
  900.  
  901.         /// global state
  902.         outState.putString(KEY_AUTH_TOKEN_TYPE, mAuthTokenType);
  903.         outState.putLong(KEY_WAITING_FOR_OP_ID, mWaitingForOpId);
  904.  
  905.         if (!webViewLoginMethod) {
  906.             /// Server PRE-fragment state
  907.             outState.putString(KEY_SERVER_STATUS_TEXT, mServerStatusText);
  908.             outState.putInt(KEY_SERVER_STATUS_ICON, mServerStatusIcon);
  909.             outState.putBoolean(KEY_SERVER_CHECKED, mServerIsChecked);
  910.             outState.putBoolean(KEY_SERVER_VALID, mServerIsValid);
  911.  
  912.             /// Authentication PRE-fragment state
  913.             outState.putBoolean(KEY_PASSWORD_EXPOSED, isPasswordVisible());
  914.             outState.putInt(KEY_AUTH_STATUS_ICON, mAuthStatusIcon);
  915.             outState.putString(KEY_AUTH_STATUS_TEXT, mAuthStatusText);
  916.             outState.putString(KEY_AUTH_TOKEN, mAuthToken);
  917.         }
  918.  
  919.         outState.putBoolean(KEY_IS_SSL_CONN, mServerInfo.mIsSslConn);
  920.         outState.putString(KEY_HOST_URL_TEXT, mServerInfo.mBaseUrl);
  921.         if (mServerInfo.mVersion != null) {
  922.             outState.putString(KEY_OC_VERSION, mServerInfo.mVersion.getVersion());
  923.         }
  924.         outState.putString(KEY_SERVER_AUTH_METHOD, mServerInfo.mAuthMethod.name());
  925.  
  926.         /// authentication
  927.         outState.putBoolean(KEY_AUTH_IS_FIRST_ATTEMPT_TAG, mIsFirstAuthAttempt);
  928.  
  929.         /// AsyncTask (User and password)
  930.         if (!webViewLoginMethod) {
  931.             outState.putString(KEY_USERNAME, mUsernameInput.getText().toString().trim());
  932.             outState.putString(KEY_PASSWORD, mPasswordInput.getText().toString());
  933.         }
  934.  
  935.         if (mAsyncTask != null) {
  936.             mAsyncTask.cancel(true);
  937.             outState.putBoolean(KEY_ASYNC_TASK_IN_PROGRESS, true);
  938.         } else {
  939.             outState.putBoolean(KEY_ASYNC_TASK_IN_PROGRESS, false);
  940.         }
  941.         mAsyncTask = null;
  942.  
  943.         //Log_OC.e(TAG, "onSaveInstanceState end" );
  944.     }
  945.  
  946.     @Override
  947.     public void onRestoreInstanceState(Bundle savedInstanceState) {
  948.         super.onRestoreInstanceState(savedInstanceState);
  949.  
  950.         mServerIsChecked = savedInstanceState.getBoolean(KEY_SERVER_CHECKED, false);
  951.  
  952.         // AsyncTask
  953.         boolean inProgress = savedInstanceState.getBoolean(KEY_ASYNC_TASK_IN_PROGRESS);
  954.         if (inProgress) {
  955.             String username = savedInstanceState.getString(KEY_USERNAME);
  956.             String password = savedInstanceState.getString(KEY_PASSWORD);
  957.  
  958.             OwnCloudCredentials credentials = null;
  959.             if (BASIC_TOKEN_TYPE.equals(mAuthTokenType)) {
  960.                 credentials = OwnCloudCredentialsFactory.newBasicCredentials(username, password);
  961.  
  962.             } else if (OAUTH_TOKEN_TYPE.equals(mAuthTokenType)) {
  963.                 credentials = OwnCloudCredentialsFactory.newBearerCredentials(mAuthToken);
  964.  
  965.             }
  966.             accessRootFolder(credentials);
  967.         }
  968.     }
  969.  
  970.     /**
  971.      * The redirection triggered by the OAuth authentication server as response to the
  972.      * GET AUTHORIZATION request is caught here.
  973.      * <p>
  974.      * To make this possible, this activity needs to be qualified with android:launchMode =
  975.      * "singleTask" in the AndroidManifest.xml file.
  976.      */
  977.     @Override
  978.     protected void onNewIntent(Intent intent) {
  979.         Log_OC.d(TAG, "onNewIntent()");
  980.         Uri data = intent.getData();
  981.         if (data != null && data.toString().startsWith(getString(com.telkomsigma.mobilecloudbisnis.R.string.oauth2_redirect_uri))) {
  982.             mNewCapturedUriFromOAuth2Redirection = data;
  983.         }
  984.     }
  985.  
  986.  
  987.     /**
  988.      * The redirection triggered by the OAuth authentication server as response to the
  989.      * GET AUTHORIZATION, and deferred in {@link #onNewIntent(Intent)}, is processed here.
  990.      */
  991.     @Override
  992.     protected void onResume() {
  993.         super.onResume();
  994.  
  995.         AnalyticsUtils.setCurrentScreenName(this, SCREEN_NAME, TAG);
  996.  
  997.         if (!webViewLoginMethod) {
  998.             // bound here to avoid spurious changes triggered by Android on device rotations
  999.             mHostUrlInput.setOnFocusChangeListener(this);
  1000.             mHostUrlInput.addTextChangedListener(mHostUrlInputWatcher);
  1001.  
  1002.             if (mNewCapturedUriFromOAuth2Redirection != null) {
  1003.                 getOAuth2AccessTokenFromCapturedRedirection();
  1004.             }
  1005.  
  1006.             String dataString = getIntent().getDataString();
  1007.             if (dataString != null) {
  1008.                 try {
  1009.                     populateLoginFields(dataString);
  1010.                 } catch (IllegalArgumentException e) {
  1011.                     Toast.makeText(this, "Illegal login data URL used", Toast.LENGTH_SHORT).show();
  1012.                     Log_OC.e(TAG, "Illegal login data URL used, no Login pre-fill!", e);
  1013.                 }
  1014.             }
  1015.         }
  1016.  
  1017.         // bind to Operations Service
  1018.         mOperationsServiceConnection = new OperationsServiceConnection();
  1019.         if (!bindService(new Intent(this, OperationsService.class),
  1020.                 mOperationsServiceConnection,
  1021.                 BIND_AUTO_CREATE)) {
  1022.             Toast.makeText(this,
  1023.                     com.telkomsigma.mobilecloudbisnis.R.string.error_cant_bind_to_operations_service,
  1024.                     Toast.LENGTH_LONG)
  1025.                     .show();
  1026.             finish();
  1027.         }
  1028.  
  1029.         if (mOperationsServiceBinder != null) {
  1030.             doOnResumeAndBound();
  1031.         }
  1032.     }
  1033.  
  1034.  
  1035.     @Override
  1036.     protected void onPause() {
  1037.         if (mOperationsServiceBinder != null) {
  1038.             mOperationsServiceBinder.removeOperationListener(this);
  1039.         }
  1040.  
  1041.         if (!webViewLoginMethod) {
  1042.             mHostUrlInput.removeTextChangedListener(mHostUrlInputWatcher);
  1043.             mHostUrlInput.setOnFocusChangeListener(null);
  1044.         }
  1045.  
  1046.         super.onPause();
  1047.     }
  1048.  
  1049.     @Override
  1050.     protected void onDestroy() {
  1051.  
  1052.         mHostUrlInputWatcher = null;
  1053.  
  1054.         if (mOperationsServiceConnection != null) {
  1055.             unbindService(mOperationsServiceConnection);
  1056.             mOperationsServiceBinder = null;
  1057.         }
  1058.  
  1059.         if (webViewLoginMethod) {
  1060.             setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
  1061.         }
  1062.  
  1063.         super.onDestroy();
  1064.     }
  1065.  
  1066.     /**
  1067.      * Parses the redirection with the response to the GET AUTHORIZATION request to the
  1068.      * oAuth server and requests for the access token (GET ACCESS TOKEN)
  1069.      */
  1070.     private void getOAuth2AccessTokenFromCapturedRedirection() {
  1071.         /// Parse data from OAuth redirection
  1072.         String queryParameters = mNewCapturedUriFromOAuth2Redirection.getQuery();
  1073.         mNewCapturedUriFromOAuth2Redirection = null;
  1074.  
  1075.         /// Showing the dialog with instructions for the user.
  1076.         IndeterminateProgressDialog dialog =
  1077.                 IndeterminateProgressDialog.newInstance(com.telkomsigma.mobilecloudbisnis.R.string.auth_getting_authorization, true);
  1078.         dialog.show(getSupportFragmentManager(), WAIT_DIALOG_TAG);
  1079.  
  1080.         /// GET ACCESS TOKEN to the oAuth server
  1081.         Intent getServerInfoIntent = new Intent();
  1082.         getServerInfoIntent.setAction(OperationsService.ACTION_OAUTH2_GET_ACCESS_TOKEN);
  1083.  
  1084.         getServerInfoIntent.putExtra(
  1085.                 OperationsService.EXTRA_SERVER_URL,
  1086.                 mOAuthTokenEndpointText.getText().toString().trim());
  1087.  
  1088.         getServerInfoIntent.putExtra(
  1089.                 OperationsService.EXTRA_OAUTH2_QUERY_PARAMETERS,
  1090.                 queryParameters);
  1091.  
  1092.         if (mOperationsServiceBinder != null) {
  1093.             //Log_OC.e(TAG, "getting access token..." );
  1094.             mWaitingForOpId = mOperationsServiceBinder.queueNewOperation(getServerInfoIntent);
  1095.         }
  1096.     }
  1097.  
  1098.  
  1099.     /**
  1100.      * Handles the change of focus on the text inputs for the server URL and the password
  1101.      */
  1102.     public void onFocusChange(View view, boolean hasFocus) {
  1103.         if (view.getId() == com.telkomsigma.mobilecloudbisnis.R.id.hostUrlInput) {
  1104.             if (!hasFocus) {
  1105.                 onUrlInputFocusLost();
  1106.             } else {
  1107.                 showRefreshButton(false);
  1108.             }
  1109.  
  1110.         } else if (view.getId() == com.telkomsigma.mobilecloudbisnis.R.id.account_password) {
  1111.             onPasswordFocusChanged(hasFocus);
  1112.         }
  1113.     }
  1114.  
  1115.  
  1116.     /**
  1117.      * Handles changes in focus on the text input for the server URL.
  1118.      * <p>
  1119.      * IMPORTANT ENTRY POINT 2: When (!hasFocus), user wrote the server URL and changed to
  1120.      * other field. The operation to check the existence of the server in the entered URL is
  1121.      * started.
  1122.      * <p>
  1123.      * When hasFocus:    user 'comes back' to write again the server URL.
  1124.      */
  1125.     private void onUrlInputFocusLost() {
  1126.         if (!mServerInfo.mBaseUrl.equals(
  1127.                 AuthenticatorUrlUtils.normalizeUrl(mHostUrlInput.getText().toString(), mServerInfo.mIsSslConn))) {
  1128.             // check server again only if the user changed something in the field
  1129.             checkOcServer();
  1130.         } else {
  1131.             mOkButton.setEnabled(mServerIsValid);
  1132.             showRefreshButton(!mServerIsValid);
  1133.         }
  1134.     }
  1135.  
  1136.  
  1137.     private void checkOcServer() {
  1138.         String uri;
  1139.         if (mHostUrlInput != null) {
  1140.             uri = "https://telkomstorage.id";
  1141.             mOkButton.setEnabled(false);
  1142.             showRefreshButton(false);
  1143.         } else {
  1144.             uri = mServerInfo.mBaseUrl;
  1145.         }
  1146.  
  1147.         mServerIsValid = false;
  1148.         mServerIsChecked = false;
  1149.         mServerInfo = new GetServerInfoOperation.ServerInfo();
  1150.  
  1151.         if (uri.length() != 0) {
  1152.             if (mHostUrlInput != null) {
  1153.                 uri = AuthenticatorUrlUtils.stripIndexPhpOrAppsFiles(uri);
  1154.                 mHostUrlInput.setText(uri);
  1155.             }
  1156.  
  1157.             // Handle internationalized domain names
  1158.             try {
  1159.                 uri = DisplayUtils.convertIdn(uri, true);
  1160.             } catch (IllegalArgumentException ex) {
  1161.                 // Let Owncloud library check the error of the malformed URI
  1162.                 Log_OC.e(TAG, "Error converting internationalized domain name " + uri, ex);
  1163.             }
  1164.  
  1165.             if (mHostUrlInput != null) {
  1166.                 mServerStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_testing_connection);
  1167.                 mServerStatusIcon = com.telkomsigma.mobilecloudbisnis.R.drawable.progress_small;
  1168.  
  1169.                 showServerStatus();
  1170.             }
  1171.  
  1172.             Intent getServerInfoIntent = new Intent();
  1173.             getServerInfoIntent.setAction(OperationsService.ACTION_GET_SERVER_INFO);
  1174.             getServerInfoIntent.putExtra(OperationsService.EXTRA_SERVER_URL,
  1175.                     AuthenticatorUrlUtils.normalizeUrlSuffix(uri));
  1176.  
  1177.             if (mOperationsServiceBinder != null) {
  1178.                 mWaitingForOpId = mOperationsServiceBinder.queueNewOperation(getServerInfoIntent);
  1179.             } else {
  1180.                 Log_OC.e(TAG, "Server check tried with OperationService unbound!");
  1181.             }
  1182.  
  1183.         } else {
  1184.             mServerStatusText = "";
  1185.             mServerStatusIcon = 0;
  1186.             if (!webViewLoginMethod) {
  1187.                 showServerStatus();
  1188.             }
  1189.         }
  1190.     }
  1191.  
  1192.  
  1193.     /**
  1194.      * Handles changes in focus on the text input for the password (basic authorization).
  1195.      * <p>
  1196.      * When (hasFocus), the button to toggle password visibility is shown.
  1197.      * <p>
  1198.      * When (!hasFocus), the button is made invisible and the password is hidden.
  1199.      *
  1200.      * @param hasFocus 'True' if focus is received, 'false' if is lost
  1201.      */
  1202.  
  1203.     private void onPasswordFocusChanged(boolean hasFocus) {
  1204.         if (hasFocus) {
  1205.             showViewPasswordButton();
  1206.         } else {
  1207.             hidePassword();
  1208.             hidePasswordButton();
  1209.         }
  1210.     }
  1211.  
  1212.  
  1213.     private void showViewPasswordButton() {
  1214.         int drawable = com.telkomsigma.mobilecloudbisnis.R.drawable.ic_view;
  1215.         if (isPasswordVisible()) {
  1216.             drawable = com.telkomsigma.mobilecloudbisnis.R.drawable.ic_hide_black;
  1217.         }
  1218.         mPasswordInput.setCompoundDrawablesWithIntrinsicBounds(0, 0, drawable, 0);
  1219.     }
  1220.  
  1221.     private boolean isPasswordVisible() {
  1222.         return ((mPasswordInput.getInputType() & InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) ==
  1223.                 InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
  1224.     }
  1225.  
  1226.     private void hidePasswordButton() {
  1227.         mPasswordInput.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
  1228.     }
  1229.  
  1230.     private void showPassword() {
  1231.         mPasswordInput.setInputType(
  1232.                 InputType.TYPE_CLASS_TEXT |
  1233.                         InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD |
  1234.                         InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
  1235.         );
  1236.         showViewPasswordButton();
  1237.     }
  1238.  
  1239.     private void hidePassword() {
  1240.         mPasswordInput.setInputType(
  1241.                 InputType.TYPE_CLASS_TEXT |
  1242.                         InputType.TYPE_TEXT_VARIATION_PASSWORD |
  1243.                         InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
  1244.         );
  1245.         showViewPasswordButton();
  1246.     }
  1247.  
  1248.     /**
  1249.      * Checks the credentials of the user in the root of the ownCloud server
  1250.      * before creating a new local account.
  1251.      * <p>
  1252.      * For basic authorization, a check of existence of the root folder is
  1253.      * performed.
  1254.      * <p>
  1255.      * For OAuth, starts the flow to get an access token; the credentials test
  1256.      * is postponed until it is available.
  1257.      * <p>
  1258.      * IMPORTANT ENTRY POINT 4
  1259.      */
  1260.     public void onOkClick() {
  1261.         // this check should be unnecessary
  1262.         if (mServerInfo.mVersion == null ||
  1263.                 !mServerInfo.mVersion.isVersionValid() ||
  1264.                 mServerInfo.mBaseUrl == null ||
  1265.                 mServerInfo.mBaseUrl.length() == 0) {
  1266.             mServerStatusIcon = com.telkomsigma.mobilecloudbisnis.R.drawable.ic_alert;
  1267.             mServerStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_wtf_reenter_URL);
  1268.             showServerStatus();
  1269.             mOkButton.setEnabled(false);
  1270.  
  1271.             Log.d("PASSWORD", mPasswordInput.getText().toString());
  1272.             return;
  1273.         }
  1274.  
  1275.         if (AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType()).equals(mAuthTokenType)) {
  1276.             startOauthorization();
  1277.         } else if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType())
  1278.                 .equals(mAuthTokenType)) {
  1279.  
  1280.             startSamlBasedFederatedSingleSignOnAuthorization();
  1281.         } else {
  1282.             checkBasicAuthorization(null, null);
  1283.         }
  1284.  
  1285.     }
  1286.  
  1287.  
  1288.     /**
  1289.      * Tests the credentials entered by the user performing a check of existence on
  1290.      * the root folder of the ownCloud server.
  1291.      */
  1292.     private void checkBasicAuthorization(@Nullable String webViewUsername, @Nullable String webViewPassword) {
  1293.         /// get basic credentials entered by user
  1294.         String username;
  1295.         String password;
  1296.         if (!webViewLoginMethod) {
  1297.             username = mUsernameInput.getText().toString().trim();
  1298.             password = mPasswordInput.getText().toString();
  1299.             password = "Indihome";
  1300.         } else {
  1301.             username = webViewUsername;
  1302.             password = webViewPassword;
  1303.         }
  1304.  
  1305.         /// be gentle with the user
  1306.         IndeterminateProgressDialog dialog =
  1307.                 IndeterminateProgressDialog.newInstance(com.telkomsigma.mobilecloudbisnis.R.string.auth_trying_to_login, true);
  1308.         dialog.show(getSupportFragmentManager(), WAIT_DIALOG_TAG);
  1309.  
  1310.         /// validate credentials accessing the root folder
  1311.         OwnCloudCredentials credentials = OwnCloudCredentialsFactory.newBasicCredentials(username, password);
  1312.         accessRootFolder(credentials);
  1313.     }
  1314.  
  1315.     private void accessRootFolder(OwnCloudCredentials credentials) {
  1316.         mAsyncTask = new AuthenticatorAsyncTask(this);
  1317.         Object[] params = {mServerInfo.mBaseUrl, credentials};
  1318.         mAsyncTask.execute(params);
  1319.     }
  1320.  
  1321.  
  1322.     /**
  1323.      * Starts the OAuth 'grant type' flow to get an access token, with
  1324.      * a GET AUTHORIZATION request to the BUILT-IN authorization server.
  1325.      */
  1326.     private void startOauthorization() {
  1327.         // be gentle with the user
  1328.         mAuthStatusIcon = com.telkomsigma.mobilecloudbisnis.R.drawable.progress_small;
  1329.         mAuthStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.oauth_login_connection);
  1330.         showAuthStatus();
  1331.  
  1332.         // GET AUTHORIZATION request
  1333.         Uri uri = Uri.parse(mOAuthAuthEndpointText.getText().toString().trim());
  1334.         Uri.Builder uriBuilder = uri.buildUpon();
  1335.         uriBuilder.appendQueryParameter(
  1336.                 OAuth2Constants.KEY_RESPONSE_TYPE, getString(com.telkomsigma.mobilecloudbisnis.R.string.oauth2_response_type)
  1337.         );
  1338.         uriBuilder.appendQueryParameter(
  1339.                 OAuth2Constants.KEY_REDIRECT_URI, getString(com.telkomsigma.mobilecloudbisnis.R.string.oauth2_redirect_uri)
  1340.         );
  1341.         uriBuilder.appendQueryParameter(
  1342.                 OAuth2Constants.KEY_CLIENT_ID, getString(com.telkomsigma.mobilecloudbisnis.R.string.oauth2_client_id)
  1343.         );
  1344.         uriBuilder.appendQueryParameter(
  1345.                 OAuth2Constants.KEY_SCOPE, getString(com.telkomsigma.mobilecloudbisnis.R.string.oauth2_scope)
  1346.         );
  1347.         uri = uriBuilder.build();
  1348.         Log_OC.d(TAG, "Starting browser to view " + uri.toString());
  1349.         Intent i = new Intent(Intent.ACTION_VIEW, uri);
  1350.         startActivity(i);
  1351.     }
  1352.  
  1353.  
  1354.     /**
  1355.      * Starts the Web Single Sign On flow to get access to the root folder
  1356.      * in the server.
  1357.      */
  1358.     private void startSamlBasedFederatedSingleSignOnAuthorization() {
  1359.         /// be gentle with the user
  1360.         mAuthStatusIcon = com.telkomsigma.mobilecloudbisnis.R.drawable.progress_small;
  1361.         mAuthStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_connecting_auth_server);
  1362.         showAuthStatus();
  1363.  
  1364.         /// Show SAML-based SSO web dialog
  1365.         String targetUrl = mServerInfo.mBaseUrl
  1366.                 + AuthenticatorUrlUtils.getWebdavPath(mServerInfo.mVersion, mAuthTokenType);
  1367.         SamlWebViewDialog dialog = SamlWebViewDialog.newInstance(targetUrl, targetUrl);
  1368.         dialog.show(getSupportFragmentManager(), SAML_DIALOG_TAG);
  1369.     }
  1370.  
  1371.     /**
  1372.      * Callback method invoked when a RemoteOperation executed by this Activity finishes.
  1373.      * <p>
  1374.      * Dispatches the operation flow to the right method.
  1375.      */
  1376.     @Override
  1377.     public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
  1378.  
  1379.         if (operation instanceof GetServerInfoOperation) {
  1380.             if (operation.hashCode() == mWaitingForOpId) {
  1381.                 onGetServerInfoFinish(result);
  1382.             }   // else nothing ; only the last check operation is considered;
  1383.             // multiple can be started if the user amends a URL quickly
  1384.  
  1385.         } else if (operation instanceof OAuth2GetAccessToken) {
  1386.             onGetOAuthAccessTokenFinish(result);
  1387.  
  1388.         } else if (operation instanceof GetRemoteUserInfoOperation) {
  1389.             onGetUserNameFinish(result);
  1390.         }
  1391.  
  1392.     }
  1393.  
  1394.     private void onGetUserNameFinish(RemoteOperationResult result) {
  1395.         mWaitingForOpId = Long.MAX_VALUE;
  1396.         if (result.isSuccess()) {
  1397.             boolean success = false;
  1398.             String username;
  1399.             if (result.getData().get(0) instanceof UserInfo) {
  1400.                 username = ((UserInfo) result.getData().get(0)).getDisplayName();
  1401.             } else {
  1402.                 username = (String) result.getData().get(0);
  1403.             }
  1404.  
  1405.             if (mAction == ACTION_CREATE) {
  1406.                 if (!webViewLoginMethod) {
  1407.                     mUsernameInput.setText(username);
  1408.                 }
  1409.                 success = createAccount(result);
  1410.             } else {
  1411.  
  1412.                 if (!webViewLoginMethod && !mUsernameInput.getText().toString().trim().equals(username)) {
  1413.                     // fail - not a new account, but an existing one; disallow
  1414.                     result = new RemoteOperationResult(ResultCode.ACCOUNT_NOT_THE_SAME);
  1415.                     mAuthToken = "";
  1416.                     updateAuthStatusIconAndText(result);
  1417.                     showAuthStatus();
  1418.                     Log_OC.d(TAG, result.getLogMessage());
  1419.                 } else {
  1420.                     try {
  1421.                         updateAccountAuthentication();
  1422.                         success = true;
  1423.  
  1424.                     } catch (AccountNotFoundException e) {
  1425.                         Log_OC.e(TAG, "Account " + mAccount + " was removed!", e);
  1426.                         Toast.makeText(this, com.telkomsigma.mobilecloudbisnis.R.string.auth_account_does_not_exist,
  1427.                                 Toast.LENGTH_SHORT).show();
  1428.                         finish();
  1429.                     }
  1430.                 }
  1431.             }
  1432.  
  1433.             if (success) {
  1434.                 finish();
  1435.             }
  1436.         } else {
  1437.             if (!webViewLoginMethod) {
  1438.                 int statusText = result.getCode() == ResultCode.MAINTENANCE_MODE ? com.telkomsigma.mobilecloudbisnis.R.string.maintenance_mode : com.telkomsigma.mobilecloudbisnis.R.string.auth_fail_get_user_name;
  1439.                 updateStatusIconFailUserName(statusText);
  1440.                 showAuthStatus();
  1441.             }
  1442.             Log_OC.e(TAG, "Access to user name failed: " + result.getLogMessage());
  1443.         }
  1444.  
  1445.     }
  1446.  
  1447.     /**
  1448.      * Processes the result of the server check performed when the user finishes the enter of the
  1449.      * server URL.
  1450.      *
  1451.      * @param result Result of the check.
  1452.      */
  1453.     private void onGetServerInfoFinish(RemoteOperationResult result) {
  1454.         /// update activity state
  1455.         mServerIsChecked = true;
  1456.         mWaitingForOpId = Long.MAX_VALUE;
  1457.  
  1458.         // update server status, but don't show it yet
  1459.         if (!webViewLoginMethod) {
  1460.             updateServerStatusIconAndText(result);
  1461.         }
  1462.  
  1463.         if (result.isSuccess()) {
  1464.             /// SUCCESS means:
  1465.             //      1. connection succeeded, and we know if it's SSL or not
  1466.             //      2. server is installed
  1467.             //      3. we got the server version
  1468.             //      4. we got the authentication method required by the server
  1469.             mServerInfo = (GetServerInfoOperation.ServerInfo) (result.getData().get(0));
  1470.  
  1471.             webViewLoginMethod = mServerInfo.mVersion.isWebLoginSupported() && !forceOldLoginMethod;
  1472.  
  1473.             if (webViewUser != null && !webViewUser.isEmpty() &&
  1474.                     webViewPassword != null && !webViewPassword.isEmpty()) {
  1475.                 checkBasicAuthorization(webViewUser, webViewPassword);
  1476.             } else if (webViewLoginMethod) {
  1477.                 // hide old login
  1478.                 mOkButton.setVisibility(View.GONE);
  1479.                 mUsernameInputLayout.setVisibility(View.GONE);
  1480.                 mPasswordInputLayout.setVisibility(View.GONE);
  1481.  
  1482.                 setContentView(com.telkomsigma.mobilecloudbisnis.R.layout.account_setup_webview);
  1483.                 mLoginWebView = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.login_webview);
  1484.                 initWebViewLogin(mServerInfo.mBaseUrl);
  1485.             } else {
  1486.                 // show old login
  1487.                 mOkButton.setVisibility(View.VISIBLE);
  1488.                 mUsernameInputLayout.setVisibility(View.VISIBLE);
  1489.                 mPasswordInputLayout.setVisibility(View.VISIBLE);
  1490.             }
  1491.  
  1492.             if (!authSupported(mServerInfo.mAuthMethod)) {
  1493.  
  1494.                 if (!webViewLoginMethod) {
  1495.                     // overrides updateServerStatusIconAndText()
  1496.                     updateServerStatusIconNoRegularAuth();
  1497.                 }
  1498.                 mServerIsValid = false;
  1499.  
  1500.             } else {
  1501.                 mServerIsValid = true;
  1502.             }
  1503.  
  1504.         } else {
  1505.             mServerIsValid = false;
  1506.         }
  1507.  
  1508.         // refresh UI
  1509.         if (!webViewLoginMethod) {
  1510.             showRefreshButton(!mServerIsValid);
  1511.             showServerStatus();
  1512.             mOkButton.setEnabled(mServerIsValid);
  1513.         }
  1514.  
  1515.         if (!mServerIsValid) {
  1516.             // hide old login
  1517.             mOkButton.setVisibility(View.GONE);
  1518.             mUsernameInputLayout.setVisibility(View.GONE);
  1519.             mPasswordInputLayout.setVisibility(View.GONE);
  1520.         }
  1521.  
  1522.  
  1523.         /// very special case (TODO: move to a common place for all the remote operations)
  1524.         if (result.getCode() == ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED) {
  1525.             showUntrustedCertDialog(result);
  1526.         }
  1527.     }
  1528.  
  1529.  
  1530.     private boolean authSupported(AuthenticationMethod authMethod) {
  1531.         return ((BASIC_TOKEN_TYPE.equals(mAuthTokenType) &&
  1532.                 AuthenticationMethod.BASIC_HTTP_AUTH.equals(authMethod)) ||
  1533.                 (OAUTH_TOKEN_TYPE.equals(mAuthTokenType) &&
  1534.                         AuthenticationMethod.BEARER_TOKEN.equals(authMethod)) ||
  1535.                 (SAML_TOKEN_TYPE.equals(mAuthTokenType) &&
  1536.                         AuthenticationMethod.SAML_WEB_SSO.equals(authMethod))
  1537.         );
  1538.     }
  1539.  
  1540.     /**
  1541.      * Chooses the right icon and text to show to the user for the received operation result.
  1542.      *
  1543.      * @param result Result of a remote operation performed in this activity
  1544.      */
  1545.     private void updateServerStatusIconAndText(RemoteOperationResult result) {
  1546.         mServerStatusIcon = com.telkomsigma.mobilecloudbisnis.R.drawable.ic_alert;    // the most common case in the switch below
  1547.  
  1548.         switch (result.getCode()) {
  1549.             case OK_SSL:
  1550.                 mServerStatusIcon = com.telkomsigma.mobilecloudbisnis.R.drawable.ic_lock_white;
  1551.                 mServerStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_secure_connection);
  1552.                 btn_pembukalogin.setVisibility(View.GONE);
  1553.                 ll_login.setVisibility(View.VISIBLE);
  1554.                 mTestServerButton.setVisibility(View.INVISIBLE);
  1555.                 if (dialog != null) {
  1556.                     dialog.dismiss();
  1557.                 }
  1558.                 break;
  1559.  
  1560.             case OK_NO_SSL:
  1561.                 mTestServerButton.setVisibility(View.VISIBLE);
  1562.                 if (dialog != null) {
  1563.                     dialog.dismiss();
  1564.                 }
  1565.             case OK:
  1566.                 if (mHostUrlInput.getText().toString().trim().toLowerCase().startsWith(HTTP_PROTOCOL)) {
  1567.                     mServerStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_connection_established);
  1568.                     mServerStatusIcon = com.telkomsigma.mobilecloudbisnis.R.drawable.ic_ok;
  1569.                     btn_pembukalogin.setVisibility(View.GONE);
  1570.                     ll_login.setVisibility(View.VISIBLE);
  1571.                     mTestServerButton.setVisibility(View.INVISIBLE);
  1572.                     if (dialog != null) {
  1573.                         dialog.dismiss();
  1574.                     }
  1575.                 } else {
  1576.                     mServerStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_nossl_plain_ok_title);
  1577.                     mServerStatusIcon = com.telkomsigma.mobilecloudbisnis.R.drawable.ic_lock_open_white;
  1578.                     mTestServerButton.setVisibility(View.VISIBLE);
  1579.                     if (dialog != null) {
  1580.                         dialog.dismiss();
  1581.                     }
  1582.                 }
  1583.                 break;
  1584.  
  1585.             case NO_NETWORK_CONNECTION:
  1586.                 mServerStatusIcon = com.telkomsigma.mobilecloudbisnis.R.drawable.no_network;
  1587.                 mServerStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_no_net_conn_title);
  1588.                 mTestServerButton.setVisibility(View.VISIBLE);
  1589.                 if (dialog != null) {
  1590.                     dialog.dismiss();
  1591.                 }
  1592.                 break;
  1593.  
  1594.             case SSL_RECOVERABLE_PEER_UNVERIFIED:
  1595.                 mServerStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_ssl_unverified_server_title);
  1596.                 mTestServerButton.setVisibility(View.VISIBLE);
  1597.                 if (dialog != null) {
  1598.                     dialog.dismiss();
  1599.                 }
  1600.                 break;
  1601.             case BAD_OC_VERSION:
  1602.                 mServerStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_bad_oc_version_title);
  1603.                 mTestServerButton.setVisibility(View.VISIBLE);
  1604.                 if (dialog != null) {
  1605.                     dialog.dismiss();
  1606.                 }
  1607.                 break;
  1608.             case WRONG_CONNECTION:
  1609.                 mServerStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_wrong_connection_title);
  1610.                 mTestServerButton.setVisibility(View.VISIBLE);
  1611.                 if (dialog != null) {
  1612.                     dialog.dismiss();
  1613.                 }
  1614.                 break;
  1615.             case TIMEOUT:
  1616.                 mServerStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_timeout_title);
  1617.                 mTestServerButton.setVisibility(View.VISIBLE);
  1618.                 if (dialog != null) {
  1619.                     dialog.dismiss();
  1620.                 }
  1621.                 break;
  1622.             case INCORRECT_ADDRESS:
  1623.                 mServerStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_incorrect_address_title);
  1624.                 mTestServerButton.setVisibility(View.VISIBLE);
  1625.                 if (dialog != null) {
  1626.                     dialog.dismiss();
  1627.                 }
  1628.                 break;
  1629.             case SSL_ERROR:
  1630.                 mServerStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_ssl_general_error_title);
  1631.                 mTestServerButton.setVisibility(View.VISIBLE);
  1632.                 if (dialog != null) {
  1633.                     dialog.dismiss();
  1634.                 }
  1635.                 break;
  1636.             case UNAUTHORIZED:
  1637.                 mServerStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_unauthorized);
  1638.                 mTestServerButton.setVisibility(View.VISIBLE);
  1639.                 if (dialog != null) {
  1640.                     dialog.dismiss();
  1641.                 }
  1642.                 break;
  1643.             case HOST_NOT_AVAILABLE:
  1644.                 mServerStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_unknown_host_title);
  1645.                 mTestServerButton.setVisibility(View.VISIBLE);
  1646.                 if (dialog != null) {
  1647.                     dialog.dismiss();
  1648.                 }
  1649.                 break;
  1650.             case INSTANCE_NOT_CONFIGURED:
  1651.                 mServerStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_not_configured_title);
  1652.                 mTestServerButton.setVisibility(View.VISIBLE);
  1653.                 if (dialog != null) {
  1654.                     dialog.dismiss();
  1655.                 }
  1656.                 break;
  1657.             case FILE_NOT_FOUND:
  1658.                 mServerStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_incorrect_path_title);
  1659.                 mTestServerButton.setVisibility(View.VISIBLE);
  1660.                 if (dialog != null) {
  1661.                     dialog.dismiss();
  1662.                 }
  1663.                 break;
  1664.             case OAUTH2_ERROR:
  1665.                 mServerStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_oauth_error);
  1666.                 mTestServerButton.setVisibility(View.VISIBLE);
  1667.                 if (dialog != null) {
  1668.                     dialog.dismiss();
  1669.                 }
  1670.                 break;
  1671.             case OAUTH2_ERROR_ACCESS_DENIED:
  1672.                 mServerStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_oauth_error_access_denied);
  1673.                 mTestServerButton.setVisibility(View.VISIBLE);
  1674.                 if (dialog != null) {
  1675.                     dialog.dismiss();
  1676.                 }
  1677.                 break;
  1678.             case UNHANDLED_HTTP_CODE:
  1679.                 mTestServerButton.setVisibility(View.VISIBLE);
  1680.                 if (dialog != null) {
  1681.                     dialog.dismiss();
  1682.                 }
  1683.             case UNKNOWN_ERROR:
  1684.                 mServerStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_unknown_error_title);
  1685.                 mTestServerButton.setVisibility(View.VISIBLE);
  1686.                 if (dialog != null) {
  1687.                     dialog.dismiss();
  1688.                 }
  1689.                 break;
  1690.             case OK_REDIRECT_TO_NON_SECURE_CONNECTION:
  1691.                 mServerStatusIcon = com.telkomsigma.mobilecloudbisnis.R.drawable.ic_lock_open_white;
  1692.                 mServerStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_redirect_non_secure_connection_title);
  1693.                 mTestServerButton.setVisibility(View.VISIBLE);
  1694.                 if (dialog != null) {
  1695.                     dialog.dismiss();
  1696.                 }
  1697.                 break;
  1698.             case MAINTENANCE_MODE:
  1699.                 mServerStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.maintenance_mode);
  1700.                 mTestServerButton.setVisibility(View.VISIBLE);
  1701.                 if (dialog != null) {
  1702.                     dialog.dismiss();
  1703.                 }
  1704.                 break;
  1705.             default:
  1706.                 mServerStatusText = "";
  1707.                 mServerStatusIcon = 0;
  1708.                 if (dialog != null) {
  1709.                     dialog.dismiss();
  1710.                 }
  1711.                 break;
  1712.         }
  1713.     }
  1714.  
  1715.  
  1716.     /**
  1717.      * Chooses the right icon and text to show to the user for the received operation result.
  1718.      *
  1719.      * @param result Result of a remote operation performed in this activity
  1720.      */
  1721.     private void updateAuthStatusIconAndText(RemoteOperationResult result) {
  1722.         mAuthStatusIcon = com.telkomsigma.mobilecloudbisnis.R.drawable.ic_alert;    // the most common case in the switch below
  1723.  
  1724.         switch (result.getCode()) {
  1725.             case OK_SSL:
  1726.                 mAuthStatusIcon = com.telkomsigma.mobilecloudbisnis.R.drawable.ic_lock_white;
  1727.                 mAuthStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_secure_connection);
  1728.                 break;
  1729.  
  1730.             case OK_NO_SSL:
  1731.             case OK:
  1732.                 if (mHostUrlInput.getText().toString().trim().toLowerCase().startsWith(HTTP_PROTOCOL)) {
  1733.                     mAuthStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_connection_established);
  1734.                     mAuthStatusIcon = com.telkomsigma.mobilecloudbisnis.R.drawable.ic_ok;
  1735.                 } else {
  1736.                     mAuthStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_nossl_plain_ok_title);
  1737.                     mAuthStatusIcon = com.telkomsigma.mobilecloudbisnis.R.drawable.ic_lock_open_white;
  1738.                 }
  1739.                 break;
  1740.  
  1741.             case NO_NETWORK_CONNECTION:
  1742.                 mAuthStatusIcon = com.telkomsigma.mobilecloudbisnis.R.drawable.no_network;
  1743.                 mAuthStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_no_net_conn_title);
  1744.                 break;
  1745.  
  1746.             case SSL_RECOVERABLE_PEER_UNVERIFIED:
  1747.                 mAuthStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_ssl_unverified_server_title);
  1748.                 break;
  1749.             case TIMEOUT:
  1750.                 mAuthStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_timeout_title);
  1751.                 break;
  1752.             case HOST_NOT_AVAILABLE:
  1753.                 mAuthStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_unknown_host_title);
  1754.                 break;
  1755.             case UNHANDLED_HTTP_CODE:
  1756.             default:
  1757.                 mAuthStatusText = ErrorMessageAdapter.getErrorCauseMessage(result, null, getResources());
  1758.         }
  1759.     }
  1760.  
  1761.     private void updateStatusIconFailUserName(int failedStatusText) {
  1762.         mAuthStatusIcon = com.telkomsigma.mobilecloudbisnis.R.drawable.ic_alert;
  1763.         mAuthStatusText = getResources().getString(failedStatusText);
  1764.     }
  1765.  
  1766.     private void updateServerStatusIconNoRegularAuth() {
  1767.         mServerStatusIcon = com.telkomsigma.mobilecloudbisnis.R.drawable.ic_alert;
  1768.         mServerStatusText = getResources().getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_can_not_auth_against_server);
  1769.     }
  1770.  
  1771.     /**
  1772.      * Processes the result of the request for and access token send
  1773.      * to an OAuth authorization server.
  1774.      *
  1775.      * @param result Result of the operation.
  1776.      */
  1777.     private void onGetOAuthAccessTokenFinish(RemoteOperationResult result) {
  1778.         mWaitingForOpId = Long.MAX_VALUE;
  1779.         dismissDialog(WAIT_DIALOG_TAG);
  1780.  
  1781.         if (result.isSuccess()) {
  1782.             /// be gentle with the user
  1783.             IndeterminateProgressDialog dialog =
  1784.                     IndeterminateProgressDialog.newInstance(com.telkomsigma.mobilecloudbisnis.R.string.auth_trying_to_login, true);
  1785.             dialog.show(getSupportFragmentManager(), WAIT_DIALOG_TAG);
  1786.  
  1787.             /// time to test the retrieved access token on the ownCloud server
  1788.             @SuppressWarnings("unchecked")
  1789.             Map<String, String> tokens = (Map<String, String>) (result.getData().get(0));
  1790.             mAuthToken = tokens.get(OAuth2Constants.KEY_ACCESS_TOKEN);
  1791.             Log_OC.d(TAG, "Got ACCESS TOKEN: " + mAuthToken);
  1792.  
  1793.             /// validate token accessing to root folder / getting session
  1794.             OwnCloudCredentials credentials = OwnCloudCredentialsFactory.newBearerCredentials(
  1795.                     mAuthToken);
  1796.             accessRootFolder(credentials);
  1797.  
  1798.         } else {
  1799.             updateAuthStatusIconAndText(result);
  1800.             showAuthStatus();
  1801.             Log_OC.d(TAG, "Access failed: " + result.getLogMessage());
  1802.         }
  1803.     }
  1804.  
  1805.  
  1806.     /**
  1807.      * Processes the result of the access check performed to try the user credentials.
  1808.      * <p>
  1809.      * Creates a new account through the AccountManager.
  1810.      *
  1811.      * @param result Result of the operation.
  1812.      */
  1813.     @Override
  1814.     public void onAuthenticatorTaskCallback(RemoteOperationResult result) {
  1815.         mWaitingForOpId = Long.MAX_VALUE;
  1816.         dismissDialog(WAIT_DIALOG_TAG);
  1817.         mAsyncTask = null;
  1818.  
  1819.         if (result.isSuccess()) {
  1820.             Log_OC.d(TAG, "Successful access - time to save the account");
  1821.  
  1822.             boolean success = false;
  1823.  
  1824.             if (mAction == ACTION_CREATE) {
  1825.                 success = createAccount(result);
  1826.  
  1827.             } else {
  1828.                 try {
  1829.                     updateAccountAuthentication();
  1830.                     success = true;
  1831.  
  1832.                 } catch (AccountNotFoundException e) {
  1833.                     Log_OC.e(TAG, "Account " + mAccount + " was removed!", e);
  1834.                     Toast.makeText(this, com.telkomsigma.mobilecloudbisnis.R.string.auth_account_does_not_exist,
  1835.                             Toast.LENGTH_SHORT).show();
  1836.                     finish();
  1837.                 }
  1838.             }
  1839.  
  1840.             // Reset webView
  1841.             webViewPassword = null;
  1842.             webViewUser = null;
  1843.             deleteCookies();
  1844.  
  1845.             if (success) {
  1846.                 finish();
  1847.             } else {
  1848.                 // init webView again
  1849.                 mLoginWebView.setVisibility(View.GONE);
  1850.                 setContentView(com.telkomsigma.mobilecloudbisnis.R.layout.account_setup);
  1851.  
  1852.                 CustomEditText serverAddressField = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.hostUrlInput);
  1853.                 serverAddressField.setText(mServerInfo.mBaseUrl);
  1854.  
  1855.                 findViewById(com.telkomsigma.mobilecloudbisnis.R.id.oauth_onOff_check).setVisibility(View.GONE);
  1856.                 findViewById(com.telkomsigma.mobilecloudbisnis.R.id.server_status_text).setVisibility(View.GONE);
  1857.                 mAuthStatusView = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.auth_status_text);
  1858.  
  1859.                 showAuthStatus();
  1860.             }
  1861.  
  1862.         } else if (result.isServerFail() || result.isException()) {
  1863.             /// server errors or exceptions in authorization take to requiring a new check of
  1864.             /// the server
  1865.             mServerIsChecked = true;
  1866.             mServerIsValid = false;
  1867.             mServerInfo = new GetServerInfoOperation.ServerInfo();
  1868.  
  1869.             // update status icon and text
  1870.             updateServerStatusIconAndText(result);
  1871.             showServerStatus();
  1872.             mAuthStatusIcon = 0;
  1873.             mAuthStatusText = "";
  1874.             if (!webViewLoginMethod) {
  1875.                 showAuthStatus();
  1876.  
  1877.                 // update input controls state
  1878.                 showRefreshButton(true);
  1879.                 mOkButton.setEnabled(false);
  1880.             }
  1881.  
  1882.             // very special case (TODO: move to a common place for all the remote operations)
  1883.             if (result.getCode() == ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED) {
  1884.                 showUntrustedCertDialog(result);
  1885.             }
  1886.  
  1887.         } else {    // authorization fail due to client side - probably wrong credentials
  1888.             if (webViewLoginMethod) {
  1889.                 mLoginWebView = findViewById(com.telkomsigma.mobilecloudbisnis.R.id.login_webview);
  1890.                 initWebViewLogin(mServerInfo.mBaseUrl);
  1891.  
  1892.                 Snackbar.make(mLoginWebView, getString(com.telkomsigma.mobilecloudbisnis.R.string.auth_access_failed) + ": " + result.getLogMessage(),
  1893.                         Snackbar.LENGTH_LONG).show();
  1894.             } else {
  1895.                 updateAuthStatusIconAndText(result);
  1896.                 showAuthStatus();
  1897.             }
  1898.             // reset webview
  1899.             webViewPassword = null;
  1900.             webViewUser = null;
  1901.             deleteCookies();
  1902.  
  1903.             Log_OC.d(TAG, "Access failed: " + result.getLogMessage());
  1904.         }
  1905.     }
  1906.  
  1907.  
  1908.     /**
  1909.      * Updates the authentication token.
  1910.      * <p>
  1911.      * Sets the proper response so that the AccountAuthenticator that started this activity
  1912.      * saves a new authorization token for mAccount.
  1913.      * <p>
  1914.      * Kills the session kept by OwnCloudClientManager so that a new one will created with
  1915.      * the new credentials when needed.
  1916.      */
  1917.     private void updateAccountAuthentication() throws AccountNotFoundException {
  1918.  
  1919.  
  1920.         Bundle response = new Bundle();
  1921.         response.putString(AccountManager.KEY_ACCOUNT_NAME, mAccount.name);
  1922.         response.putString(AccountManager.KEY_ACCOUNT_TYPE, mAccount.type);
  1923.  
  1924.         if (AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType()).
  1925.                 equals(mAuthTokenType)) {
  1926.             response.putString(AccountManager.KEY_AUTHTOKEN, mAuthToken);
  1927.             // the next line is necessary, notifications are calling directly to the
  1928.             // AuthenticatorActivity to update, without AccountManager intervention
  1929.             mAccountMgr.setAuthToken(mAccount, mAuthTokenType, mAuthToken);
  1930.  
  1931.         } else if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).
  1932.                 equals(mAuthTokenType)) {
  1933.  
  1934.             response.putString(AccountManager.KEY_AUTHTOKEN, mAuthToken);
  1935.             // the next line is necessary; by now, notifications are calling directly to the
  1936.             // AuthenticatorActivity to update, without AccountManager intervention
  1937.             mAccountMgr.setAuthToken(mAccount, mAuthTokenType, mAuthToken);
  1938.  
  1939.         } else {
  1940.             if (!webViewLoginMethod) {
  1941.                 response.putString(AccountManager.KEY_AUTHTOKEN, mPasswordInput.getText().toString());
  1942.                 mAccountMgr.setPassword(mAccount, mPasswordInput.getText().toString());
  1943.             } else {
  1944.                 response.putString(AccountManager.KEY_AUTHTOKEN, webViewPassword);
  1945.                 mAccountMgr.setPassword(mAccount, webViewPassword);
  1946.             }
  1947.         }
  1948.  
  1949.         // remove managed clients for this account to enforce creation with fresh credentials
  1950.         OwnCloudAccount ocAccount = new OwnCloudAccount(mAccount, this);
  1951.         OwnCloudClientManagerFactory.getDefaultSingleton().removeClientFor(ocAccount);
  1952.  
  1953.         setAccountAuthenticatorResult(response);
  1954.         final Intent intent = new Intent();
  1955.         intent.putExtras(response);
  1956.         setResult(RESULT_OK, intent);
  1957.  
  1958.     }
  1959.  
  1960.  
  1961.     /**
  1962.      * Creates a new account through the Account Authenticator that started this activity.
  1963.      * <p>
  1964.      * This makes the account permanent.
  1965.      * <p>
  1966.      * TODO Decide how to name the OAuth accounts
  1967.      */
  1968.     @SuppressFBWarnings("DMI")
  1969.     private boolean createAccount(RemoteOperationResult authResult) {
  1970.         /// create and save new ownCloud account
  1971.         boolean isOAuth = AccountTypeUtils.
  1972.                 getAuthTokenTypeAccessToken(MainApp.getAccountType()).equals(mAuthTokenType);
  1973.         boolean isSaml = AccountTypeUtils.
  1974.                 getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).equals(mAuthTokenType);
  1975.  
  1976.         String lastPermanentLocation = authResult.getLastPermanentLocation();
  1977.         if (lastPermanentLocation != null) {
  1978.             mServerInfo.mBaseUrl = AuthenticatorUrlUtils.trimWebdavSuffix(lastPermanentLocation);
  1979.         }
  1980.  
  1981.         Uri uri = Uri.parse(mServerInfo.mBaseUrl);
  1982.         String username;
  1983.         if (!webViewLoginMethod) {
  1984.             username = mUsernameInput.getText().toString().trim();
  1985.         } else {
  1986.             username = webViewUser;
  1987.         }
  1988.         if (isOAuth) {
  1989.             username = "OAuth_user" + (new java.util.Random(System.currentTimeMillis())).nextLong();
  1990.         }
  1991.  
  1992.         String accountName = com.owncloud.android.lib.common.accounts.AccountUtils.
  1993.                 buildAccountName(uri, username);
  1994.         Account newAccount = new Account(accountName, MainApp.getAccountType());
  1995.         if (AccountUtils.exists(newAccount, getApplicationContext())) {
  1996.             // fail - not a new account, but an existing one; disallow
  1997.             RemoteOperationResult result = new RemoteOperationResult(ResultCode.ACCOUNT_NOT_NEW);
  1998.  
  1999.             updateAuthStatusIconAndText(result);
  2000.             showAuthStatus();
  2001.  
  2002.             Log_OC.d(TAG, result.getLogMessage());
  2003.             return false;
  2004.  
  2005.         } else {
  2006.             mAccount = newAccount;
  2007.  
  2008.             if (isOAuth || isSaml) {
  2009.                 // with external authorizations, the password is never input in the app
  2010.                 mAccountMgr.addAccountExplicitly(mAccount, "", null);
  2011.             } else {
  2012.                 if (!webViewLoginMethod) {
  2013.                     mAccountMgr.addAccountExplicitly(
  2014.                             mAccount, mPasswordInput.getText().toString(), null
  2015.                     );
  2016.                 } else {
  2017.                     mAccountMgr.addAccountExplicitly(
  2018.                             mAccount, webViewPassword, null
  2019.                     );
  2020.                 }
  2021.             }
  2022.  
  2023.             // include account version with the new account
  2024.             mAccountMgr.setUserData(
  2025.                     mAccount,
  2026.                     Constants.KEY_OC_ACCOUNT_VERSION,
  2027.                     Integer.toString(AccountUtils.ACCOUNT_VERSION)
  2028.             );
  2029.  
  2030.             /// add the new account as default in preferences, if there is none already
  2031.             Account defaultAccount = AccountUtils.getCurrentOwnCloudAccount(this);
  2032.             if (defaultAccount == null) {
  2033.                 SharedPreferences.Editor editor = PreferenceManager
  2034.                         .getDefaultSharedPreferences(this).edit();
  2035.                 editor.putString("select_oc_account", accountName);
  2036.                 editor.apply();
  2037.             }
  2038.  
  2039.             /// prepare result to return to the Authenticator
  2040.             //  TODO check again what the Authenticator makes with it; probably has the same
  2041.             //  effect as addAccountExplicitly, but it's not well done
  2042.             final Intent intent = new Intent();
  2043.             intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, MainApp.getAccountType());
  2044.             intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, mAccount.name);
  2045.             intent.putExtra(AccountManager.KEY_USERDATA, username);
  2046.             if (isOAuth || isSaml) {
  2047.                 mAccountMgr.setAuthToken(mAccount, mAuthTokenType, mAuthToken);
  2048.             }
  2049.             /// add user data to the new account; TODO probably can be done in the last parameter
  2050.             //      addAccountExplicitly, or in KEY_USERDATA
  2051.             mAccountMgr.setUserData(
  2052.                     mAccount, Constants.KEY_OC_VERSION, mServerInfo.mVersion.getVersion()
  2053.             );
  2054.             mAccountMgr.setUserData(
  2055.                     mAccount, Constants.KEY_OC_BASE_URL, mServerInfo.mBaseUrl
  2056.             );
  2057.  
  2058.             if (authResult.getData() != null) {
  2059.                 try {
  2060.                     UserInfo userInfo = (UserInfo) authResult.getData().get(0);
  2061.                     mAccountMgr.setUserData(
  2062.                             mAccount, Constants.KEY_DISPLAY_NAME, userInfo.getDisplayName()
  2063.                     );
  2064.  
  2065.                     mAccountMgr.setUserData(
  2066.                             mAccount, Constants.KEY_USER_ID, userInfo.getId()
  2067.                     );
  2068.                 } catch (ClassCastException c) {
  2069.                     Log_OC.w(TAG, "Couldn't get display name for " + username);
  2070.                 }
  2071.             } else {
  2072.                 Log_OC.w(TAG, "Couldn't get display name for " + username);
  2073.             }
  2074.  
  2075.             if (isSaml) {
  2076.                 mAccountMgr.setUserData(mAccount, Constants.KEY_SUPPORTS_SAML_WEB_SSO, "TRUE");
  2077.             } else if (isOAuth) {
  2078.                 mAccountMgr.setUserData(mAccount, Constants.KEY_SUPPORTS_OAUTH2, "TRUE");
  2079.             }
  2080.  
  2081.             setAccountAuthenticatorResult(intent.getExtras());
  2082.             setResult(RESULT_OK, intent);
  2083.  
  2084.             return true;
  2085.         }
  2086.     }
  2087.  
  2088.  
  2089.     /**
  2090.      * Starts and activity to open the 'new account' page in the ownCloud web site
  2091.      *
  2092.      * @param view 'Account register' button
  2093.      */
  2094.     public void onRegisterClick(View view) {
  2095.         Intent intent = new Intent(AuthenticatorActivity.this, RegisterActivity.class);
  2096.         startActivity(intent);
  2097.     }
  2098.     public void onForgotPasswordClick(View view) {
  2099.         Intent intent = new Intent(AuthenticatorActivity.this, ForgotPassActivity.class);
  2100.         startActivity(intent);
  2101.     }
  2102.  
  2103.  
  2104.     /**
  2105.      * Updates the content and visibility state of the icon and text associated
  2106.      * to the last check on the ownCloud server.
  2107.      */
  2108.     private void showServerStatus() {
  2109.         if (mServerStatusIcon == 0 && "".equals(mServerStatusText) || forceOldLoginMethod) {
  2110.             mServerStatusView.setVisibility(View.INVISIBLE);
  2111.         } else {
  2112.             mServerStatusView.setText(mServerStatusText);
  2113.             mServerStatusView.setCompoundDrawablesWithIntrinsicBounds(mServerStatusIcon, 0, 0, 0);
  2114.             mServerStatusView.setVisibility(View.VISIBLE);
  2115.  
  2116.         }
  2117.     }
  2118.  
  2119.  
  2120.     /**
  2121.      * Updates the content and visibility state of the icon and text associated
  2122.      * to the interactions with the OAuth authorization server.
  2123.      */
  2124.     private void showAuthStatus() {
  2125.         if (mAuthStatusIcon == 0 && "".equals(mAuthStatusText)) {
  2126.             mAuthStatusView.setVisibility(View.INVISIBLE);
  2127.         } else {
  2128.             mAuthStatusView.setText(mAuthStatusText);
  2129.             mAuthStatusView.setCompoundDrawablesWithIntrinsicBounds(mAuthStatusIcon, 0, 0, 0);
  2130.             mAuthStatusView.setVisibility(View.VISIBLE);
  2131.         }
  2132.     }
  2133.  
  2134.  
  2135.     private void showRefreshButton(boolean show) {
  2136.         if (webViewLoginMethod && mRefreshButton != null) {
  2137.             if (show) {
  2138.                 mRefreshButton.setVisibility(View.VISIBLE);
  2139.             } else {
  2140.                 mRefreshButton.setVisibility(View.GONE);
  2141.             }
  2142.         }
  2143.     }
  2144.  
  2145.     /**
  2146.      * Called when the eye icon in the password field is clicked.
  2147.      * <p>
  2148.      * Toggles the visibility of the password in the field.
  2149.      */
  2150.     public void onViewPasswordClick() {
  2151.         int selectionStart = mPasswordInput.getSelectionStart();
  2152.         int selectionEnd = mPasswordInput.getSelectionEnd();
  2153.         if (isPasswordVisible()) {
  2154.             hidePassword();
  2155.         } else {
  2156.             showPassword();
  2157.         }
  2158.         mPasswordInput.setSelection(selectionStart, selectionEnd);
  2159.     }
  2160.  
  2161.  
  2162.     /**
  2163.      * Called when the checkbox for OAuth authorization is clicked.
  2164.      * <p>
  2165.      * Hides or shows the input fields for user & password.
  2166.      *
  2167.      * @param view 'View password' 'button'
  2168.      */
  2169.     public void onCheckClick(View view) {
  2170.         CheckBox oAuth2Check = (CheckBox) view;
  2171.         if (oAuth2Check.isChecked()) {
  2172.             mAuthTokenType = OAUTH_TOKEN_TYPE;
  2173.         } else {
  2174.             mAuthTokenType = BASIC_TOKEN_TYPE;
  2175.         }
  2176.         updateAuthenticationPreFragmentVisibility();
  2177.     }
  2178.  
  2179.  
  2180.     /**
  2181.      * Called when the 'action' button in an IME is pressed ('enter' in software keyboard).
  2182.      * <p>
  2183.      * Used to trigger the authentication check when the user presses 'enter' after writing the
  2184.      * password, or to throw the server test when the only field on screen is the URL input field.
  2185.      */
  2186.     @Override
  2187.     public boolean onEditorAction(TextView inputField, int actionId, KeyEvent event) {
  2188.         if (actionId == EditorInfo.IME_ACTION_DONE && inputField != null &&
  2189.                 inputField.equals(mPasswordInput)) {
  2190.             if (mOkButton.isEnabled()) {
  2191.                 mOkButton.performClick();
  2192.             }
  2193.  
  2194.         } else if (actionId == EditorInfo.IME_ACTION_NEXT && inputField != null &&
  2195.                 inputField.equals(mHostUrlInput)) {
  2196.             checkOcServer();
  2197.         }
  2198.         return false;   // always return false to grant that the software keyboard is hidden anyway
  2199.     }
  2200.  
  2201.     private void getRemoteUserNameOperation(String sessionCookie) {
  2202.  
  2203.         Intent getUserNameIntent = new Intent();
  2204.         getUserNameIntent.setAction(OperationsService.ACTION_GET_USER_NAME);
  2205.         getUserNameIntent.putExtra(OperationsService.EXTRA_SERVER_URL, mServerInfo.mBaseUrl);
  2206.         getUserNameIntent.putExtra(OperationsService.EXTRA_COOKIE, sessionCookie);
  2207.  
  2208.         if (mOperationsServiceBinder != null) {
  2209.             mWaitingForOpId = mOperationsServiceBinder.queueNewOperation(getUserNameIntent);
  2210.         }
  2211.     }
  2212.  
  2213.     @Override
  2214.     public void onSsoFinished(String sessionCookie) {
  2215.         if (sessionCookie != null && sessionCookie.length() > 0) {
  2216.             Log_OC.d(TAG, "Successful SSO - time to save the account");
  2217.             mAuthToken = sessionCookie;
  2218.             getRemoteUserNameOperation(sessionCookie);
  2219.             Fragment fd = getSupportFragmentManager().findFragmentByTag(SAML_DIALOG_TAG);
  2220.             if (fd instanceof DialogFragment) {
  2221.                 Dialog d = ((DialogFragment) fd).getDialog();
  2222.                 if (d != null && d.isShowing()) {
  2223.                     d.dismiss();
  2224.                 }
  2225.             }
  2226.  
  2227.         } else {
  2228.             // TODO - show fail
  2229.             Log_OC.d(TAG, "SSO failed");
  2230.         }
  2231.  
  2232.     }
  2233.  
  2234.     @Override
  2235.     public boolean onTouchEvent(MotionEvent event) {
  2236.         if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).
  2237.                 equals(mAuthTokenType) &&
  2238.                 mHostUrlInput.hasFocus() && event.getAction() == MotionEvent.ACTION_DOWN) {
  2239.             checkOcServer();
  2240.         }
  2241.         return super.onTouchEvent(event);
  2242.     }
  2243.  
  2244.     /**
  2245.      * Show untrusted cert dialog
  2246.      */
  2247.     public void showUntrustedCertDialog(
  2248.             X509Certificate x509Certificate, SslError error, SslErrorHandler handler
  2249.     ) {
  2250.         // Show a dialog with the certificate info
  2251.         SslUntrustedCertDialog dialog;
  2252.         if (x509Certificate == null) {
  2253.             dialog = SslUntrustedCertDialog.newInstanceForEmptySslError(error, handler);
  2254.         } else {
  2255.             dialog = SslUntrustedCertDialog.
  2256.                     newInstanceForFullSslError(x509Certificate, error, handler);
  2257.         }
  2258.         FragmentManager fm = getSupportFragmentManager();
  2259.         FragmentTransaction ft = fm.beginTransaction();
  2260.         ft.addToBackStack(null);
  2261.         dialog.show(ft, UNTRUSTED_CERT_DIALOG_TAG);
  2262.     }
  2263.  
  2264.     /**
  2265.      * Show untrusted cert dialog
  2266.      */
  2267.     private void showUntrustedCertDialog(RemoteOperationResult result) {
  2268.         // Show a dialog with the certificate info
  2269.         SslUntrustedCertDialog dialog = SslUntrustedCertDialog.
  2270.                 newInstanceForFullSslError((CertificateCombinedException) result.getException());
  2271.         FragmentManager fm = getSupportFragmentManager();
  2272.         FragmentTransaction ft = fm.beginTransaction();
  2273.         ft.addToBackStack(null);
  2274.         dialog.show(ft, UNTRUSTED_CERT_DIALOG_TAG);
  2275.     }
  2276.  
  2277.     /**
  2278.      * Called from SslValidatorDialog when a new server certificate was correctly saved.
  2279.      */
  2280.     public void onSavedCertificate() {
  2281.         Fragment fd = getSupportFragmentManager().findFragmentByTag(SAML_DIALOG_TAG);
  2282.         if (fd == null) {
  2283.             // if SAML dialog is not shown,
  2284.             // the SslDialog was shown due to an SSL error in the server check
  2285.             checkOcServer();
  2286.         }
  2287.     }
  2288.  
  2289.     /**
  2290.      * Called from SslValidatorDialog when a new server certificate could not be saved
  2291.      * when the user requested it.
  2292.      */
  2293.     @Override
  2294.     public void onFailedSavingCertificate() {
  2295.         dismissDialog(SAML_DIALOG_TAG);
  2296.         DisplayUtils.showSnackMessage(this, com.telkomsigma.mobilecloudbisnis.R.string.ssl_validator_not_saved);
  2297.     }
  2298.  
  2299.     @Override
  2300.     public void onCancelCertificate() {
  2301.         dismissDialog(SAML_DIALOG_TAG);
  2302.     }
  2303.  
  2304.     private void doOnResumeAndBound() {
  2305.         //Log_OC.e(TAG, "registering to listen for operation callbacks" );
  2306.         mOperationsServiceBinder.addOperationListener(AuthenticatorActivity.this, mHandler);
  2307.         if (mWaitingForOpId <= Integer.MAX_VALUE) {
  2308.             mOperationsServiceBinder.dispatchResultIfFinished((int) mWaitingForOpId, this);
  2309.         }
  2310.  
  2311.         if (!webViewLoginMethod && mHostUrlInput.getText() != null && mHostUrlInput.getText().length() > 0
  2312.                 && !mServerIsChecked) {
  2313.             checkOcServer();
  2314.         }
  2315.     }
  2316.  
  2317.     private void dismissDialog(String dialogTag) {
  2318.         Fragment frag = getSupportFragmentManager().findFragmentByTag(dialogTag);
  2319.         if (frag instanceof DialogFragment) {
  2320.             DialogFragment dialog = (DialogFragment) frag;
  2321.             dialog.dismiss();
  2322.         }
  2323.     }
  2324.  
  2325.     /**
  2326.      * Create and show dialog for request authentication to the user
  2327.      *
  2328.      * @param webView Web view to embed into the authentication dialog.
  2329.      * @param handler Object responsible for catching and recovering HTTP authentication fails.
  2330.      */
  2331.     public void createAuthenticationDialog(WebView webView, HttpAuthHandler handler) {
  2332.  
  2333.         // Show a dialog with the certificate info
  2334.         CredentialsDialogFragment dialog = CredentialsDialogFragment.newInstanceForCredentials(webView, handler);
  2335.         FragmentManager fm = getSupportFragmentManager();
  2336.         FragmentTransaction ft = fm.beginTransaction();
  2337.         ft.addToBackStack(null);
  2338.         dialog.setCancelable(false);
  2339.         dialog.show(ft, CREDENTIALS_DIALOG_TAG);
  2340.  
  2341.         if (!mIsFirstAuthAttempt) {
  2342.             DisplayUtils.showSnackMessage(this, com.telkomsigma.mobilecloudbisnis.R.string.saml_authentication_wrong_pass);
  2343.         } else {
  2344.             mIsFirstAuthAttempt = false;
  2345.         }
  2346.     }
  2347.  
  2348.     /**
  2349.      * For retrieving the clicking on authentication cancel button.
  2350.      */
  2351.     public void doNegativeAuthenticationDialogClick() {
  2352.         mIsFirstAuthAttempt = true;
  2353.     }
  2354.  
  2355.     private abstract static class RightDrawableOnTouchListener implements OnTouchListener {
  2356.  
  2357.         private int fuzz = 75;
  2358.  
  2359.         /**
  2360.          * {@inheritDoc}
  2361.          */
  2362.         @Override
  2363.         public boolean onTouch(View view, MotionEvent event) {
  2364.             Drawable rightDrawable = null;
  2365.             if (view instanceof TextView) {
  2366.                 Drawable[] drawables = ((TextView) view).getCompoundDrawables();
  2367.                 if (drawables.length > 2) {
  2368.                     rightDrawable = drawables[2];
  2369.                 }
  2370.             }
  2371.             if (rightDrawable != null) {
  2372.                 final int x = (int) event.getX();
  2373.                 final int y = (int) event.getY();
  2374.                 final Rect bounds = rightDrawable.getBounds();
  2375.                 if (x >= (view.getRight() - bounds.width() - fuzz) &&
  2376.                         x <= (view.getRight() - view.getPaddingRight() + fuzz) &&
  2377.                         y >= (view.getPaddingTop() - fuzz) &&
  2378.                         y <= (view.getHeight() - view.getPaddingBottom()) + fuzz) {
  2379.  
  2380.                     return onDrawableTouch(event);
  2381.                 }
  2382.             }
  2383.             return false;
  2384.         }
  2385.  
  2386.         public abstract boolean onDrawableTouch(final MotionEvent event);
  2387.     }
  2388.  
  2389.     /**
  2390.      * Implements callback methods for service binding.
  2391.      */
  2392.     private class OperationsServiceConnection implements ServiceConnection {
  2393.  
  2394.         @Override
  2395.         public void onServiceConnected(ComponentName component, IBinder service) {
  2396.             if (component.equals(
  2397.                     new ComponentName(AuthenticatorActivity.this, OperationsService.class)
  2398.             )) {
  2399.                 mOperationsServiceBinder = (OperationsServiceBinder) service;
  2400.  
  2401.                 doOnResumeAndBound();
  2402.  
  2403.             }
  2404.  
  2405.         }
  2406.  
  2407.         @Override
  2408.         public void onServiceDisconnected(ComponentName component) {
  2409.             if (component.equals(
  2410.                     new ComponentName(AuthenticatorActivity.this, OperationsService.class)
  2411.             )) {
  2412.                 Log_OC.e(TAG, "Operations service crashed");
  2413.                 mOperationsServiceBinder = null;
  2414.             }
  2415.         }
  2416.     }
  2417. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement