Advertisement
faisholtria

AuthenticatorActivity

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