mirror of
https://github.com/nextcloud/android.git
synced 2024-11-29 10:49:04 +03:00
Merge pull request #3889 from nextcloud/checkUserId
Cleanup authentication
This commit is contained in:
commit
03e04e516e
32 changed files with 114 additions and 1445 deletions
|
@ -59,6 +59,9 @@
|
||||||
</value>
|
</value>
|
||||||
</option>
|
</option>
|
||||||
</JavaCodeStyleSettings>
|
</JavaCodeStyleSettings>
|
||||||
|
<MarkdownNavigatorCodeStyleSettings>
|
||||||
|
<option name="RIGHT_MARGIN" value="120" />
|
||||||
|
</MarkdownNavigatorCodeStyleSettings>
|
||||||
<Objective-C-extensions>
|
<Objective-C-extensions>
|
||||||
<file>
|
<file>
|
||||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
439
|
436
|
|
@ -40,14 +40,6 @@
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:launchMode="singleTask"
|
android:launchMode="singleTask"
|
||||||
android:theme="@style/Theme.ownCloud.noActionBar.Login">
|
android:theme="@style/Theme.ownCloud.noActionBar.Login">
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.VIEW" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
|
||||||
|
|
||||||
<data android:scheme="@string/oauth2_redirect_scheme" />
|
|
||||||
</intent-filter>
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="com.owncloud.android.workaround.accounts.CREATE" />
|
<action android:name="com.owncloud.android.workaround.accounts.CREATE" />
|
||||||
|
|
||||||
|
|
|
@ -265,14 +265,6 @@
|
||||||
android:launchMode="singleTask"
|
android:launchMode="singleTask"
|
||||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||||
android:theme="@style/Theme.ownCloud.noActionBar.Login">
|
android:theme="@style/Theme.ownCloud.noActionBar.Login">
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.VIEW" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
|
||||||
|
|
||||||
<data android:scheme="@string/oauth2_redirect_scheme" />
|
|
||||||
</intent-filter>
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="com.owncloud.android.workaround.accounts.CREATE" />
|
<action android:name="com.owncloud.android.workaround.accounts.CREATE" />
|
||||||
|
|
||||||
|
|
|
@ -170,23 +170,6 @@ public class UserAccountManagerImpl implements UserAccountManager {
|
||||||
accountMgr.getUserData(account, com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_COOKIES)
|
accountMgr.getUserData(account, com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_COOKIES)
|
||||||
);
|
);
|
||||||
|
|
||||||
// copy type of authentication
|
|
||||||
final String isSamlStr = accountMgr.getUserData(account, com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_SUPPORTS_SAML_WEB_SSO);
|
|
||||||
if (Boolean.parseBoolean(isSamlStr)) {
|
|
||||||
accountMgr.setUserData(newAccount, com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_SUPPORTS_SAML_WEB_SSO, "TRUE");
|
|
||||||
}
|
|
||||||
|
|
||||||
final String isOauthStr = accountMgr.getUserData(account, com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_SUPPORTS_OAUTH2);
|
|
||||||
if (Boolean.parseBoolean(isOauthStr)) {
|
|
||||||
accountMgr.setUserData(newAccount, com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_SUPPORTS_OAUTH2, "TRUE");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO - study if it's possible to run this method in a background thread to copy the authToken
|
|
||||||
if (isOAuth || isSaml) {
|
|
||||||
accountMgr.setAuthToken(newAccount, mAuthTokenType, mAuthToken);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// don't forget the account saved in preferences as the current one
|
// don't forget the account saved in preferences as the current one
|
||||||
if (currentAccount.name.equals(account.name)) {
|
if (currentAccount.name.equals(account.name)) {
|
||||||
AccountUtils.setCurrentOwnCloudAccount(context, newAccountName);
|
AccountUtils.setCurrentOwnCloudAccount(context, newAccountName);
|
||||||
|
|
|
@ -64,7 +64,6 @@ import com.owncloud.android.datastorage.StoragePoint;
|
||||||
import com.owncloud.android.jobs.MediaFoldersDetectionJob;
|
import com.owncloud.android.jobs.MediaFoldersDetectionJob;
|
||||||
import com.owncloud.android.jobs.NCJobCreator;
|
import com.owncloud.android.jobs.NCJobCreator;
|
||||||
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
|
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
|
||||||
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory.Policy;
|
|
||||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||||
import com.owncloud.android.ui.activity.ContactsPreferenceActivity;
|
import com.owncloud.android.ui.activity.ContactsPreferenceActivity;
|
||||||
|
@ -198,16 +197,8 @@ public class MainApp extends MultiDexApplication implements
|
||||||
|
|
||||||
MainApp.storagePath = preferences.getStoragePath(getApplicationContext().getFilesDir().getAbsolutePath());
|
MainApp.storagePath = preferences.getStoragePath(getApplicationContext().getFilesDir().getAbsolutePath());
|
||||||
|
|
||||||
boolean isSamlAuth = AUTH_ON.equals(getString(R.string.auth_method_saml_web_sso));
|
|
||||||
|
|
||||||
OwnCloudClientManagerFactory.setUserAgent(getUserAgent());
|
OwnCloudClientManagerFactory.setUserAgent(getUserAgent());
|
||||||
OwnCloudClientManagerFactory.setNextcloudUserAgent(getNextcloudUserAgent());
|
OwnCloudClientManagerFactory.setNextcloudUserAgent(getNextcloudUserAgent());
|
||||||
if (isSamlAuth) {
|
|
||||||
OwnCloudClientManagerFactory.setDefaultPolicy(Policy.SINGLE_SESSION_PER_ACCOUNT);
|
|
||||||
} else {
|
|
||||||
OwnCloudClientManagerFactory
|
|
||||||
.setDefaultPolicy(Policy.SINGLE_SESSION_PER_ACCOUNT_IF_SERVER_SUPPORTS_SERVER_MONITORING);
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialise thumbnails cache on background thread
|
// initialise thumbnails cache on background thread
|
||||||
new ThumbnailsCacheManager.InitDiskCacheTask().execute();
|
new ThumbnailsCacheManager.InitDiskCacheTask().execute();
|
||||||
|
|
|
@ -242,10 +242,7 @@ public class AccountAuthenticator extends AbstractAccountAuthenticator {
|
||||||
String accountType = MainApp.getAccountType(mContext);
|
String accountType = MainApp.getAccountType(mContext);
|
||||||
|
|
||||||
if (!authTokenType.equals(accountType) &&
|
if (!authTokenType.equals(accountType) &&
|
||||||
!authTokenType.equals(AccountTypeUtils.getAuthTokenTypePass(accountType)) &&
|
!authTokenType.equals(AccountTypeUtils.getAuthTokenTypePass(accountType))) {
|
||||||
!authTokenType.equals(AccountTypeUtils.getAuthTokenTypeAccessToken(accountType)) &&
|
|
||||||
!authTokenType.equals(AccountTypeUtils.getAuthTokenTypeRefreshToken(accountType)) &&
|
|
||||||
!authTokenType.equals(AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(accountType))) {
|
|
||||||
throw new UnsupportedAuthTokenTypeException();
|
throw new UnsupportedAuthTokenTypeException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,6 @@ import android.Manifest;
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
import android.accounts.AccountManager;
|
import android.accounts.AccountManager;
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Dialog;
|
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
@ -55,6 +54,7 @@ import android.content.pm.PackageManager;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.net.http.SslCertificate;
|
||||||
import android.net.http.SslError;
|
import android.net.http.SslError;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
@ -78,7 +78,6 @@ import android.webkit.HttpAuthHandler;
|
||||||
import android.webkit.SslErrorHandler;
|
import android.webkit.SslErrorHandler;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
import android.webkit.WebViewClient;
|
import android.webkit.WebViewClient;
|
||||||
import android.widget.CheckBox;
|
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
|
@ -91,13 +90,11 @@ import com.google.android.material.textfield.TextInputLayout;
|
||||||
import com.nextcloud.client.account.UserAccountManager;
|
import com.nextcloud.client.account.UserAccountManager;
|
||||||
import com.owncloud.android.MainApp;
|
import com.owncloud.android.MainApp;
|
||||||
import com.owncloud.android.R;
|
import com.owncloud.android.R;
|
||||||
import com.owncloud.android.authentication.SsoWebViewClient.SsoWebViewClientListener;
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudAccount;
|
import com.owncloud.android.lib.common.OwnCloudAccount;
|
||||||
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
|
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
|
||||||
import com.owncloud.android.lib.common.OwnCloudCredentials;
|
import com.owncloud.android.lib.common.OwnCloudCredentials;
|
||||||
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
|
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
|
||||||
import com.owncloud.android.lib.common.UserInfo;
|
import com.owncloud.android.lib.common.UserInfo;
|
||||||
import com.owncloud.android.lib.common.accounts.AccountTypeUtils;
|
|
||||||
import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
|
import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
|
||||||
import com.owncloud.android.lib.common.accounts.AccountUtils.Constants;
|
import com.owncloud.android.lib.common.accounts.AccountUtils.Constants;
|
||||||
import com.owncloud.android.lib.common.network.CertificateCombinedException;
|
import com.owncloud.android.lib.common.network.CertificateCombinedException;
|
||||||
|
@ -111,7 +108,6 @@ import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||||
import com.owncloud.android.lib.resources.users.GetRemoteUserInfoOperation;
|
import com.owncloud.android.lib.resources.users.GetRemoteUserInfoOperation;
|
||||||
import com.owncloud.android.operations.DetectAuthenticationMethodOperation.AuthenticationMethod;
|
import com.owncloud.android.operations.DetectAuthenticationMethodOperation.AuthenticationMethod;
|
||||||
import com.owncloud.android.operations.GetServerInfoOperation;
|
import com.owncloud.android.operations.GetServerInfoOperation;
|
||||||
import com.owncloud.android.operations.OAuth2GetAccessToken;
|
|
||||||
import com.owncloud.android.services.OperationsService;
|
import com.owncloud.android.services.OperationsService;
|
||||||
import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
|
import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
|
||||||
import com.owncloud.android.ui.activity.FileDisplayActivity;
|
import com.owncloud.android.ui.activity.FileDisplayActivity;
|
||||||
|
@ -119,16 +115,18 @@ import com.owncloud.android.ui.activity.FirstRunActivity;
|
||||||
import com.owncloud.android.ui.components.CustomEditText;
|
import com.owncloud.android.ui.components.CustomEditText;
|
||||||
import com.owncloud.android.ui.dialog.CredentialsDialogFragment;
|
import com.owncloud.android.ui.dialog.CredentialsDialogFragment;
|
||||||
import com.owncloud.android.ui.dialog.IndeterminateProgressDialog;
|
import com.owncloud.android.ui.dialog.IndeterminateProgressDialog;
|
||||||
import com.owncloud.android.ui.dialog.SamlWebViewDialog;
|
|
||||||
import com.owncloud.android.ui.dialog.SslUntrustedCertDialog;
|
import com.owncloud.android.ui.dialog.SslUntrustedCertDialog;
|
||||||
import com.owncloud.android.ui.dialog.SslUntrustedCertDialog.OnSslUntrustedCertListener;
|
import com.owncloud.android.ui.dialog.SslUntrustedCertDialog.OnSslUntrustedCertListener;
|
||||||
import com.owncloud.android.utils.DisplayUtils;
|
import com.owncloud.android.utils.DisplayUtils;
|
||||||
import com.owncloud.android.utils.ErrorMessageAdapter;
|
import com.owncloud.android.utils.ErrorMessageAdapter;
|
||||||
import com.owncloud.android.utils.PermissionUtil;
|
import com.owncloud.android.utils.PermissionUtil;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
import java.security.SecureRandom;
|
import java.security.cert.Certificate;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
import java.security.cert.CertificateFactory;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -148,8 +146,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
* This Activity is used to add an ownCloud account to the App
|
* This Activity is used to add an ownCloud account to the App
|
||||||
*/
|
*/
|
||||||
public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
implements OnRemoteOperationListener, OnFocusChangeListener, OnEditorActionListener,
|
implements OnRemoteOperationListener, OnFocusChangeListener, OnEditorActionListener, OnSslUntrustedCertListener,
|
||||||
SsoWebViewClientListener, OnSslUntrustedCertListener,
|
|
||||||
AuthenticatorAsyncTask.OnAuthenticatorTaskListener {
|
AuthenticatorAsyncTask.OnAuthenticatorTaskListener {
|
||||||
|
|
||||||
private static final String TAG = AuthenticatorActivity.class.getSimpleName();
|
private static final String TAG = AuthenticatorActivity.class.getSimpleName();
|
||||||
|
@ -158,8 +155,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
public static final String EXTRA_ACCOUNT = "ACCOUNT";
|
public static final String EXTRA_ACCOUNT = "ACCOUNT";
|
||||||
public static final String EXTRA_USE_PROVIDER_AS_WEBLOGIN = "USE_PROVIDER_AS_WEBLOGIN";
|
public static final String EXTRA_USE_PROVIDER_AS_WEBLOGIN = "USE_PROVIDER_AS_WEBLOGIN";
|
||||||
|
|
||||||
private static final String KEY_AUTH_TOKEN_TYPE = "AUTH_TOKEN_TYPE";
|
|
||||||
|
|
||||||
private static final String KEY_HOST_URL_TEXT = "HOST_URL_TEXT";
|
private static final String KEY_HOST_URL_TEXT = "HOST_URL_TEXT";
|
||||||
private static final String KEY_OC_VERSION = "OC_VERSION";
|
private static final String KEY_OC_VERSION = "OC_VERSION";
|
||||||
private static final String KEY_SERVER_VALID = "SERVER_VALID";
|
private static final String KEY_SERVER_VALID = "SERVER_VALID";
|
||||||
|
@ -174,14 +169,10 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
private static final String KEY_WAITING_FOR_OP_ID = "WAITING_FOR_OP_ID";
|
private static final String KEY_WAITING_FOR_OP_ID = "WAITING_FOR_OP_ID";
|
||||||
private static final String KEY_AUTH_TOKEN = "AUTH_TOKEN";
|
private static final String KEY_AUTH_TOKEN = "AUTH_TOKEN";
|
||||||
|
|
||||||
private static final String AUTH_ON = "on";
|
|
||||||
private static final String AUTH_OPTIONAL = "optional";
|
|
||||||
|
|
||||||
public static final byte ACTION_CREATE = 0;
|
public static final byte ACTION_CREATE = 0;
|
||||||
public static final byte ACTION_UPDATE_EXPIRED_TOKEN = 2; // detected by the app
|
public static final byte ACTION_UPDATE_EXPIRED_TOKEN = 2; // detected by the app
|
||||||
|
|
||||||
private static final String UNTRUSTED_CERT_DIALOG_TAG = "UNTRUSTED_CERT_DIALOG";
|
private static final String UNTRUSTED_CERT_DIALOG_TAG = "UNTRUSTED_CERT_DIALOG";
|
||||||
private static final String SAML_DIALOG_TAG = "SAML_DIALOG";
|
|
||||||
private static final String WAIT_DIALOG_TAG = "WAIT_DIALOG";
|
private static final String WAIT_DIALOG_TAG = "WAIT_DIALOG";
|
||||||
private static final String CREDENTIALS_DIALOG_TAG = "CREDENTIALS_DIALOG";
|
private static final String CREDENTIALS_DIALOG_TAG = "CREDENTIALS_DIALOG";
|
||||||
private static final String KEY_AUTH_IS_FIRST_ATTEMPT_TAG = "KEY_AUTH_IS_FIRST_ATTEMPT";
|
private static final String KEY_AUTH_IS_FIRST_ATTEMPT_TAG = "KEY_AUTH_IS_FIRST_ATTEMPT";
|
||||||
|
@ -208,14 +199,12 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
/// parameters from EXTRAs in starter Intent
|
/// parameters from EXTRAs in starter Intent
|
||||||
private byte mAction;
|
private byte mAction;
|
||||||
private Account mAccount;
|
private Account mAccount;
|
||||||
private String mAuthTokenType;
|
|
||||||
|
|
||||||
/// activity-level references / state
|
/// activity-level references / state
|
||||||
private final Handler mHandler = new Handler();
|
private final Handler mHandler = new Handler();
|
||||||
private ServiceConnection mOperationsServiceConnection;
|
private ServiceConnection mOperationsServiceConnection;
|
||||||
private OperationsServiceBinder mOperationsServiceBinder;
|
private OperationsServiceBinder mOperationsServiceBinder;
|
||||||
private AccountManager mAccountMgr;
|
private AccountManager mAccountMgr;
|
||||||
private Uri mNewCapturedUriFromOAuth2Redirection;
|
|
||||||
|
|
||||||
/// Server PRE-Fragment elements
|
/// Server PRE-Fragment elements
|
||||||
private CustomEditText mHostUrlInput;
|
private CustomEditText mHostUrlInput;
|
||||||
|
@ -232,9 +221,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
private GetServerInfoOperation.ServerInfo mServerInfo = new GetServerInfoOperation.ServerInfo();
|
private GetServerInfoOperation.ServerInfo mServerInfo = new GetServerInfoOperation.ServerInfo();
|
||||||
|
|
||||||
/// Authentication PRE-Fragment elements
|
/// Authentication PRE-Fragment elements
|
||||||
private CheckBox mOAuth2Check;
|
|
||||||
private TextView mOAuthAuthEndpointText;
|
|
||||||
private TextView mOAuthTokenEndpointText;
|
|
||||||
private EditText mUsernameInput;
|
private EditText mUsernameInput;
|
||||||
private EditText mPasswordInput;
|
private EditText mPasswordInput;
|
||||||
private View mOkButton;
|
private View mOkButton;
|
||||||
|
@ -254,10 +240,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
/// Identifier of operation in progress which result shouldn't be lost
|
/// Identifier of operation in progress which result shouldn't be lost
|
||||||
private long mWaitingForOpId = Long.MAX_VALUE;
|
private long mWaitingForOpId = Long.MAX_VALUE;
|
||||||
|
|
||||||
private String basicTokenType;
|
|
||||||
private String oauthTokenType;
|
|
||||||
private String samlTokenType;
|
|
||||||
|
|
||||||
private boolean webViewLoginMethod;
|
private boolean webViewLoginMethod;
|
||||||
private String webViewUser;
|
private String webViewUser;
|
||||||
private String webViewPassword;
|
private String webViewPassword;
|
||||||
|
@ -284,10 +266,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
FirstRunActivity.runIfNeeded(this);
|
FirstRunActivity.runIfNeeded(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
basicTokenType = AccountTypeUtils.getAuthTokenTypePass(MainApp.getAccountType(this));
|
|
||||||
oauthTokenType = AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType(this));
|
|
||||||
samlTokenType = AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType(this));
|
|
||||||
|
|
||||||
// delete cookies for webView
|
// delete cookies for webView
|
||||||
deleteCookies();
|
deleteCookies();
|
||||||
|
|
||||||
|
@ -304,15 +282,11 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
|
|
||||||
/// init activity state
|
/// init activity state
|
||||||
mAccountMgr = AccountManager.get(this);
|
mAccountMgr = AccountManager.get(this);
|
||||||
mNewCapturedUriFromOAuth2Redirection = null;
|
|
||||||
|
|
||||||
/// get input values
|
/// get input values
|
||||||
mAction = getIntent().getByteExtra(EXTRA_ACTION, ACTION_CREATE);
|
mAction = getIntent().getByteExtra(EXTRA_ACTION, ACTION_CREATE);
|
||||||
mAccount = getIntent().getExtras().getParcelable(EXTRA_ACCOUNT);
|
mAccount = getIntent().getExtras().getParcelable(EXTRA_ACCOUNT);
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState != null) {
|
||||||
initAuthTokenType();
|
|
||||||
} else {
|
|
||||||
mAuthTokenType = savedInstanceState.getString(KEY_AUTH_TOKEN_TYPE);
|
|
||||||
mWaitingForOpId = savedInstanceState.getLong(KEY_WAITING_FOR_OP_ID);
|
mWaitingForOpId = savedInstanceState.getLong(KEY_WAITING_FOR_OP_ID);
|
||||||
mIsFirstAuthAttempt = savedInstanceState.getBoolean(KEY_AUTH_IS_FIRST_ATTEMPT_TAG);
|
mIsFirstAuthAttempt = savedInstanceState.getBoolean(KEY_AUTH_IS_FIRST_ATTEMPT_TAG);
|
||||||
}
|
}
|
||||||
|
@ -428,7 +402,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
mPasswordInputLayout.setVisibility(View.VISIBLE);
|
mPasswordInputLayout.setVisibility(View.VISIBLE);
|
||||||
mUsernameInputLayout.setVisibility(View.VISIBLE);
|
mUsernameInputLayout.setVisibility(View.VISIBLE);
|
||||||
mUsernameInput.requestFocus();
|
mUsernameInput.requestFocus();
|
||||||
mOAuth2Check.setVisibility(View.INVISIBLE);
|
|
||||||
mAuthStatusView.setVisibility(View.INVISIBLE);
|
mAuthStatusView.setVisibility(View.INVISIBLE);
|
||||||
mServerStatusView.setVisibility(View.INVISIBLE);
|
mServerStatusView.setVisibility(View.INVISIBLE);
|
||||||
mTestServerButton.setVisibility(View.INVISIBLE);
|
mTestServerButton.setVisibility(View.INVISIBLE);
|
||||||
|
@ -486,7 +459,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
|
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
|
||||||
X509Certificate cert = SsoWebViewClient.getX509CertificateFromError(error);
|
X509Certificate cert = getX509CertificateFromError(error);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (cert != null && NetworkUtils.isCertInKnownServersStore(cert, getApplicationContext())) {
|
if (cert != null && NetworkUtils.isCertInKnownServersStore(cert, getApplicationContext())) {
|
||||||
|
@ -591,39 +564,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
return loginUrlInfo;
|
return loginUrlInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initAuthTokenType() {
|
|
||||||
Bundle extras = getIntent().getExtras();
|
|
||||||
mAuthTokenType = null;
|
|
||||||
|
|
||||||
if (extras != null) {
|
|
||||||
mAuthTokenType = extras.getString(AccountAuthenticator.KEY_AUTH_TOKEN_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mAuthTokenType == null) {
|
|
||||||
if (mAccount != null) {
|
|
||||||
boolean oAuthRequired = mAccountMgr.getUserData(mAccount, Constants.KEY_SUPPORTS_OAUTH2) != null;
|
|
||||||
boolean samlWebSsoRequired = mAccountMgr.getUserData
|
|
||||||
(mAccount, Constants.KEY_SUPPORTS_SAML_WEB_SSO) != null;
|
|
||||||
mAuthTokenType = chooseAuthTokenType(oAuthRequired, samlWebSsoRequired);
|
|
||||||
} else {
|
|
||||||
boolean oAuthSupported = AUTH_ON.equals(getString(R.string.auth_method_oauth2));
|
|
||||||
boolean samlWebSsoSupported = AUTH_ON.equals(getString(R.string.auth_method_saml_web_sso));
|
|
||||||
mAuthTokenType = chooseAuthTokenType(oAuthSupported, samlWebSsoSupported);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String chooseAuthTokenType(boolean oauth, boolean saml) {
|
|
||||||
if (saml) {
|
|
||||||
return samlTokenType;
|
|
||||||
} else if (oauth) {
|
|
||||||
return oauthTokenType;
|
|
||||||
} else {
|
|
||||||
return basicTokenType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures elements in the user interface under direct control of the Activity.
|
* Configures elements in the user interface under direct control of the Activity.
|
||||||
*/
|
*/
|
||||||
|
@ -634,7 +574,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
mPasswordInput = findViewById(R.id.account_password);
|
mPasswordInput = findViewById(R.id.account_password);
|
||||||
mUsernameInput = findViewById(R.id.account_username);
|
mUsernameInput = findViewById(R.id.account_username);
|
||||||
mAuthStatusView = findViewById(R.id.auth_status_text);
|
mAuthStatusView = findViewById(R.id.auth_status_text);
|
||||||
mOAuth2Check = findViewById(R.id.oauth_onOff_check);
|
|
||||||
mServerStatusView = findViewById(R.id.server_status_text);
|
mServerStatusView = findViewById(R.id.server_status_text);
|
||||||
mTestServerButton = findViewById(R.id.testServerButton);
|
mTestServerButton = findViewById(R.id.testServerButton);
|
||||||
|
|
||||||
|
@ -650,35 +589,18 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
|
|
||||||
|
|
||||||
private void setupInstructionMessage() {
|
private void setupInstructionMessage() {
|
||||||
String instructionsMessageText = calculateInstructionMessageText(mAction, mAuthTokenType);
|
|
||||||
TextView instructionsView = findViewById(R.id.instructions_message);
|
TextView instructionsView = findViewById(R.id.instructions_message);
|
||||||
|
|
||||||
if (instructionsMessageText != null) {
|
if (mAction == ACTION_UPDATE_EXPIRED_TOKEN) {
|
||||||
instructionsView.setVisibility(View.VISIBLE);
|
instructionsView.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
String instructionsMessageText = getString(R.string.auth_expired_basic_auth_toast);
|
||||||
instructionsView.setText(instructionsMessageText);
|
instructionsView.setText(instructionsMessageText);
|
||||||
} else {
|
} else {
|
||||||
instructionsView.setVisibility(View.GONE);
|
instructionsView.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private String calculateInstructionMessageText(byte action, String authTokenType) {
|
|
||||||
if (action == ACTION_UPDATE_EXPIRED_TOKEN) {
|
|
||||||
if (AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType(this)).equals(authTokenType)) {
|
|
||||||
return getString(R.string.auth_expired_oauth_token_toast);
|
|
||||||
|
|
||||||
} else if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType(this))
|
|
||||||
.equals(authTokenType)) {
|
|
||||||
return getString(R.string.auth_expired_saml_sso_token_toast);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return getString(R.string.auth_expired_basic_auth_toast);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onTestServerConnectionClick(View v) {
|
public void onTestServerConnectionClick(View v) {
|
||||||
checkOcServer();
|
checkOcServer();
|
||||||
}
|
}
|
||||||
|
@ -776,31 +698,15 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// TODO find out if this is really necessary, or if it can done in a different way
|
|
||||||
findViewById(R.id.scroll).setOnTouchListener((view, event) -> {
|
|
||||||
if (event.getAction() == MotionEvent.ACTION_DOWN &&
|
|
||||||
AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(
|
|
||||||
MainApp.getAccountType(getBaseContext())).equals(mAuthTokenType) &&
|
|
||||||
mHostUrlInput.hasFocus()) {
|
|
||||||
checkOcServer();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param savedInstanceState Saved activity state, as in {{@link #onCreate(Bundle)}
|
* @param savedInstanceState Saved activity state, as in {{@link #onCreate(Bundle)}
|
||||||
*/
|
*/
|
||||||
private void initAuthorizationPreFragment(Bundle savedInstanceState) {
|
private void initAuthorizationPreFragment(Bundle savedInstanceState) {
|
||||||
|
|
||||||
/// step 0 - get UI elements in layout
|
/// step 0 - get UI elements in layout
|
||||||
mOAuth2Check = findViewById(R.id.oauth_onOff_check);
|
|
||||||
mOAuthAuthEndpointText = findViewById(R.id.oAuthEntryPoint_1);
|
|
||||||
mOAuthTokenEndpointText = findViewById(R.id.oAuthEntryPoint_2);
|
|
||||||
mUsernameInput = findViewById(R.id.account_username);
|
mUsernameInput = findViewById(R.id.account_username);
|
||||||
mPasswordInput = findViewById(R.id.account_password);
|
mPasswordInput = findViewById(R.id.account_password);
|
||||||
mAuthStatusView = findViewById(R.id.auth_status_text);
|
mAuthStatusView = findViewById(R.id.auth_status_text);
|
||||||
|
@ -820,8 +726,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
/// step 2 - set properties of UI elements (text, visibility, enabled...)
|
/// step 2 - set properties of UI elements (text, visibility, enabled...)
|
||||||
mOAuth2Check.setChecked(
|
|
||||||
AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType(this)).equals(mAuthTokenType));
|
|
||||||
if (presetUserName != null) {
|
if (presetUserName != null) {
|
||||||
mUsernameInput.setText(presetUserName);
|
mUsernameInput.setText(presetUserName);
|
||||||
}
|
}
|
||||||
|
@ -833,7 +737,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
if (isPasswordExposed) {
|
if (isPasswordExposed) {
|
||||||
showPassword();
|
showPassword();
|
||||||
}
|
}
|
||||||
updateAuthenticationPreFragmentVisibility();
|
|
||||||
showAuthStatus();
|
showAuthStatus();
|
||||||
mOkButton.setEnabled(mServerIsValid);
|
mOkButton.setEnabled(mServerIsValid);
|
||||||
|
|
||||||
|
@ -855,53 +758,9 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Changes the visibility of input elements depending on
|
|
||||||
* the current authorization method.
|
|
||||||
*/
|
|
||||||
private void updateAuthenticationPreFragmentVisibility() {
|
|
||||||
if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType(this)).equals(mAuthTokenType)) {
|
|
||||||
// SAML-based web Single Sign On
|
|
||||||
mOAuth2Check.setVisibility(View.GONE);
|
|
||||||
mOAuthAuthEndpointText.setVisibility(View.GONE);
|
|
||||||
mOAuthTokenEndpointText.setVisibility(View.GONE);
|
|
||||||
mUsernameInput.setVisibility(View.GONE);
|
|
||||||
mPasswordInput.setVisibility(View.GONE);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (mAction == ACTION_CREATE &&
|
|
||||||
AUTH_OPTIONAL.equals(getString(R.string.auth_method_oauth2))) {
|
|
||||||
mOAuth2Check.setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
|
||||||
mOAuth2Check.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType(this)).equals(mAuthTokenType)) {
|
|
||||||
// OAuth 2 authorization
|
|
||||||
mOAuthAuthEndpointText.setVisibility(View.VISIBLE);
|
|
||||||
mOAuthTokenEndpointText.setVisibility(View.VISIBLE);
|
|
||||||
mUsernameInput.setVisibility(View.GONE);
|
|
||||||
mPasswordInput.setVisibility(View.GONE);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// basic HTTP authorization
|
|
||||||
mOAuthAuthEndpointText.setVisibility(View.GONE);
|
|
||||||
mOAuthTokenEndpointText.setVisibility(View.GONE);
|
|
||||||
mUsernameInput.setVisibility(View.VISIBLE);
|
|
||||||
mPasswordInput.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves relevant state before {@link #onPause()}
|
* Saves relevant state before {@link #onPause()}
|
||||||
*
|
*
|
||||||
* Do NOT save {@link #mNewCapturedUriFromOAuth2Redirection}; it keeps a temporal flag,
|
|
||||||
* intended to defer the processing of the redirection caught in
|
|
||||||
* {@link #onNewIntent(Intent)} until {@link #onResume()}
|
|
||||||
*
|
|
||||||
* See {@link super#onSaveInstanceState(Bundle)}
|
* See {@link super#onSaveInstanceState(Bundle)}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -910,7 +769,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
super.onSaveInstanceState(outState);
|
super.onSaveInstanceState(outState);
|
||||||
|
|
||||||
/// global state
|
/// global state
|
||||||
outState.putString(KEY_AUTH_TOKEN_TYPE, mAuthTokenType);
|
|
||||||
outState.putLong(KEY_WAITING_FOR_OP_ID, mWaitingForOpId);
|
outState.putLong(KEY_WAITING_FOR_OP_ID, mWaitingForOpId);
|
||||||
|
|
||||||
if (!webViewLoginMethod) {
|
if (!webViewLoginMethod) {
|
||||||
|
@ -966,14 +824,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
String username = savedInstanceState.getString(KEY_USERNAME);
|
String username = savedInstanceState.getString(KEY_USERNAME);
|
||||||
String password = savedInstanceState.getString(KEY_PASSWORD);
|
String password = savedInstanceState.getString(KEY_PASSWORD);
|
||||||
|
|
||||||
OwnCloudCredentials credentials = null;
|
OwnCloudCredentials credentials = OwnCloudCredentialsFactory.newBasicCredentials(username, password);
|
||||||
if (basicTokenType.equals(mAuthTokenType)) {
|
|
||||||
credentials = OwnCloudCredentialsFactory.newBasicCredentials(username, password);
|
|
||||||
|
|
||||||
} else if (oauthTokenType.equals(mAuthTokenType)) {
|
|
||||||
credentials = OwnCloudCredentialsFactory.newBearerCredentials(mAuthToken);
|
|
||||||
|
|
||||||
}
|
|
||||||
accessRootFolder(credentials);
|
accessRootFolder(credentials);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -994,9 +845,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
Uri data = intent.getData();
|
Uri data = intent.getData();
|
||||||
if (data != null && data.toString().startsWith(getString(R.string.oauth2_redirect_uri))) {
|
|
||||||
mNewCapturedUriFromOAuth2Redirection = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data != null && data.toString().startsWith(getString(R.string.login_data_own_scheme))) {
|
if (data != null && data.toString().startsWith(getString(R.string.login_data_own_scheme))) {
|
||||||
parseAndLoginFromWebView(data.toString());
|
parseAndLoginFromWebView(data.toString());
|
||||||
|
@ -1024,10 +872,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
mHostUrlInput.setOnFocusChangeListener(this);
|
mHostUrlInput.setOnFocusChangeListener(this);
|
||||||
mHostUrlInput.addTextChangedListener(mHostUrlInputWatcher);
|
mHostUrlInput.addTextChangedListener(mHostUrlInputWatcher);
|
||||||
|
|
||||||
if (mNewCapturedUriFromOAuth2Redirection != null) {
|
|
||||||
getOAuth2AccessTokenFromCapturedRedirection();
|
|
||||||
}
|
|
||||||
|
|
||||||
String dataString = getIntent().getDataString();
|
String dataString = getIntent().getDataString();
|
||||||
if (dataString != null) {
|
if (dataString != null) {
|
||||||
try {
|
try {
|
||||||
|
@ -1085,39 +929,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the redirection with the response to the GET AUTHORIZATION request to the
|
|
||||||
* oAuth server and requests for the access token (GET ACCESS TOKEN)
|
|
||||||
*/
|
|
||||||
private void getOAuth2AccessTokenFromCapturedRedirection() {
|
|
||||||
/// Parse data from OAuth redirection
|
|
||||||
String queryParameters = mNewCapturedUriFromOAuth2Redirection.getQuery();
|
|
||||||
mNewCapturedUriFromOAuth2Redirection = null;
|
|
||||||
|
|
||||||
/// Showing the dialog with instructions for the user.
|
|
||||||
IndeterminateProgressDialog dialog =
|
|
||||||
IndeterminateProgressDialog.newInstance(R.string.auth_getting_authorization, true);
|
|
||||||
dialog.show(getSupportFragmentManager(), WAIT_DIALOG_TAG);
|
|
||||||
|
|
||||||
/// GET ACCESS TOKEN to the oAuth server
|
|
||||||
Intent getServerInfoIntent = new Intent();
|
|
||||||
getServerInfoIntent.setAction(OperationsService.ACTION_OAUTH2_GET_ACCESS_TOKEN);
|
|
||||||
|
|
||||||
getServerInfoIntent.putExtra(
|
|
||||||
OperationsService.EXTRA_SERVER_URL,
|
|
||||||
mOAuthTokenEndpointText.getText().toString().trim());
|
|
||||||
|
|
||||||
getServerInfoIntent.putExtra(
|
|
||||||
OperationsService.EXTRA_OAUTH2_QUERY_PARAMETERS,
|
|
||||||
queryParameters);
|
|
||||||
|
|
||||||
if (mOperationsServiceBinder != null) {
|
|
||||||
//Log_OC.e(TAG, "getting access token..." );
|
|
||||||
mWaitingForOpId = mOperationsServiceBinder.queueNewOperation(getServerInfoIntent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the change of focus on the text inputs for the server URL and the password
|
* Handles the change of focus on the text inputs for the server URL and the password
|
||||||
*/
|
*/
|
||||||
|
@ -1289,15 +1100,8 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType(this)).equals(mAuthTokenType)) {
|
|
||||||
startOauthorization();
|
|
||||||
} else if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType(this))
|
|
||||||
.equals(mAuthTokenType)) {
|
|
||||||
startSamlBasedFederatedSingleSignOnAuthorization();
|
|
||||||
} else {
|
|
||||||
checkBasicAuthorization(null, null);
|
checkBasicAuthorization(null, null);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1334,57 +1138,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
mAsyncTask.execute(params);
|
mAsyncTask.execute(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the OAuth 'grant type' flow to get an access token, with
|
|
||||||
* a GET AUTHORIZATION request to the BUILT-IN authorization server.
|
|
||||||
*/
|
|
||||||
private void startOauthorization() {
|
|
||||||
// be gentle with the user
|
|
||||||
mAuthStatusIcon = R.drawable.progress_small;
|
|
||||||
mAuthStatusText = getResources().getString(R.string.oauth_login_connection);
|
|
||||||
showAuthStatus();
|
|
||||||
|
|
||||||
// GET AUTHORIZATION request
|
|
||||||
Uri uri = Uri.parse(mOAuthAuthEndpointText.getText().toString().trim());
|
|
||||||
Uri.Builder uriBuilder = uri.buildUpon();
|
|
||||||
uriBuilder.appendQueryParameter(
|
|
||||||
OAuth2Constants.KEY_RESPONSE_TYPE, getString(R.string.oauth2_response_type)
|
|
||||||
);
|
|
||||||
uriBuilder.appendQueryParameter(
|
|
||||||
OAuth2Constants.KEY_REDIRECT_URI, getString(R.string.oauth2_redirect_uri)
|
|
||||||
);
|
|
||||||
uriBuilder.appendQueryParameter(
|
|
||||||
OAuth2Constants.KEY_CLIENT_ID, getString(R.string.oauth2_client_id)
|
|
||||||
);
|
|
||||||
uriBuilder.appendQueryParameter(
|
|
||||||
OAuth2Constants.KEY_SCOPE, getString(R.string.oauth2_scope)
|
|
||||||
);
|
|
||||||
uri = uriBuilder.build();
|
|
||||||
Log_OC.d(TAG, "Starting browser to view " + uri.toString());
|
|
||||||
Intent i = new Intent(Intent.ACTION_VIEW, uri);
|
|
||||||
|
|
||||||
DisplayUtils.startIntentIfAppAvailable(i, this, R.string.no_browser_available);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the Web Single Sign On flow to get access to the root folder
|
|
||||||
* in the server.
|
|
||||||
*/
|
|
||||||
private void startSamlBasedFederatedSingleSignOnAuthorization() {
|
|
||||||
/// be gentle with the user
|
|
||||||
mAuthStatusIcon = R.drawable.progress_small;
|
|
||||||
mAuthStatusText = getResources().getString(R.string.auth_connecting_auth_server);
|
|
||||||
showAuthStatus();
|
|
||||||
|
|
||||||
/// Show SAML-based SSO web dialog
|
|
||||||
String targetUrl = mServerInfo.mBaseUrl
|
|
||||||
+ AuthenticatorUrlUtils.getWebdavPath(mServerInfo.mVersion, mAuthTokenType, this);
|
|
||||||
SamlWebViewDialog dialog = SamlWebViewDialog.newInstance(targetUrl, targetUrl);
|
|
||||||
dialog.show(getSupportFragmentManager(), SAML_DIALOG_TAG);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback method invoked when a RemoteOperation executed by this Activity finishes.
|
* Callback method invoked when a RemoteOperation executed by this Activity finishes.
|
||||||
*
|
*
|
||||||
|
@ -1392,20 +1145,15 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
|
public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
|
||||||
|
|
||||||
if (operation instanceof GetServerInfoOperation) {
|
if (operation instanceof GetServerInfoOperation) {
|
||||||
if (operation.hashCode() == mWaitingForOpId) {
|
if (operation.hashCode() == mWaitingForOpId) {
|
||||||
onGetServerInfoFinish(result);
|
onGetServerInfoFinish(result);
|
||||||
} // else nothing ; only the last check operation is considered;
|
} // else nothing ; only the last check operation is considered;
|
||||||
// multiple can be started if the user amends a URL quickly
|
// multiple can be started if the user amends a URL quickly
|
||||||
|
|
||||||
} else if (operation instanceof OAuth2GetAccessToken) {
|
|
||||||
onGetOAuthAccessTokenFinish(result);
|
|
||||||
|
|
||||||
} else if (operation instanceof GetRemoteUserInfoOperation) {
|
} else if (operation instanceof GetRemoteUserInfoOperation) {
|
||||||
onGetUserNameFinish(result);
|
onGetUserNameFinish(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onGetUserNameFinish(RemoteOperationResult result) {
|
private void onGetUserNameFinish(RemoteOperationResult result) {
|
||||||
|
@ -1548,9 +1296,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean authSupported(AuthenticationMethod authMethod) {
|
private boolean authSupported(AuthenticationMethod authMethod) {
|
||||||
return (basicTokenType.equals(mAuthTokenType) && AuthenticationMethod.BASIC_HTTP_AUTH.equals(authMethod)) ||
|
return AuthenticationMethod.BASIC_HTTP_AUTH.equals(authMethod);
|
||||||
(oauthTokenType.equals(mAuthTokenType) && AuthenticationMethod.BEARER_TOKEN.equals(authMethod)) ||
|
|
||||||
(samlTokenType.equals(mAuthTokenType) && AuthenticationMethod.SAML_WEB_SSO.equals(authMethod));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1706,40 +1452,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
mServerStatusText = getResources().getString(R.string.auth_can_not_auth_against_server);
|
mServerStatusText = getResources().getString(R.string.auth_can_not_auth_against_server);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Processes the result of the request for and access token send
|
|
||||||
* to an OAuth authorization server.
|
|
||||||
*
|
|
||||||
* @param result Result of the operation.
|
|
||||||
*/
|
|
||||||
private void onGetOAuthAccessTokenFinish(RemoteOperationResult result) {
|
|
||||||
mWaitingForOpId = Long.MAX_VALUE;
|
|
||||||
dismissDialog(WAIT_DIALOG_TAG);
|
|
||||||
|
|
||||||
if (result.isSuccess()) {
|
|
||||||
/// be gentle with the user
|
|
||||||
IndeterminateProgressDialog dialog =
|
|
||||||
IndeterminateProgressDialog.newInstance(R.string.auth_trying_to_login, true);
|
|
||||||
dialog.show(getSupportFragmentManager(), WAIT_DIALOG_TAG);
|
|
||||||
|
|
||||||
/// time to test the retrieved access token on the ownCloud server
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Map<String, String> tokens = (Map<String, String>) (result.getData().get(0));
|
|
||||||
mAuthToken = tokens.get(OAuth2Constants.KEY_ACCESS_TOKEN);
|
|
||||||
Log_OC.d(TAG, "Got ACCESS TOKEN: " + mAuthToken);
|
|
||||||
|
|
||||||
/// validate token accessing to root folder / getting session
|
|
||||||
OwnCloudCredentials credentials = OwnCloudCredentialsFactory.newBearerCredentials(
|
|
||||||
mAuthToken);
|
|
||||||
accessRootFolder(credentials);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
updateAuthStatusIconAndText(result);
|
|
||||||
showAuthStatus();
|
|
||||||
Log_OC.d(TAG, "Access failed: " + result.getLogMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes the result of the access check performed to try the user credentials.
|
* Processes the result of the access check performed to try the user credentials.
|
||||||
*
|
*
|
||||||
|
@ -1801,7 +1513,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
CustomEditText serverAddressField = findViewById(R.id.hostUrlInput);
|
CustomEditText serverAddressField = findViewById(R.id.hostUrlInput);
|
||||||
serverAddressField.setText(mServerInfo.mBaseUrl);
|
serverAddressField.setText(mServerInfo.mBaseUrl);
|
||||||
|
|
||||||
findViewById(R.id.oauth_onOff_check).setVisibility(View.GONE);
|
|
||||||
findViewById(R.id.server_status_text).setVisibility(View.GONE);
|
findViewById(R.id.server_status_text).setVisibility(View.GONE);
|
||||||
mAuthStatusView = findViewById(R.id.auth_status_text);
|
mAuthStatusView = findViewById(R.id.auth_status_text);
|
||||||
|
|
||||||
|
@ -1855,7 +1566,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
CustomEditText serverAddressField = findViewById(R.id.hostUrlInput);
|
CustomEditText serverAddressField = findViewById(R.id.hostUrlInput);
|
||||||
serverAddressField.setText(mServerInfo.mBaseUrl);
|
serverAddressField.setText(mServerInfo.mBaseUrl);
|
||||||
|
|
||||||
findViewById(R.id.oauth_onOff_check).setVisibility(View.GONE);
|
|
||||||
findViewById(R.id.server_status_text).setVisibility(View.GONE);
|
findViewById(R.id.server_status_text).setVisibility(View.GONE);
|
||||||
mAuthStatusView = findViewById(R.id.auth_status_text);
|
mAuthStatusView = findViewById(R.id.auth_status_text);
|
||||||
|
|
||||||
|
@ -1884,32 +1594,16 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
* the new credentials when needed.
|
* the new credentials when needed.
|
||||||
*/
|
*/
|
||||||
private void updateAccountAuthentication() throws AccountNotFoundException {
|
private void updateAccountAuthentication() throws AccountNotFoundException {
|
||||||
String accountType = MainApp.getAccountType(this);
|
|
||||||
|
|
||||||
Bundle response = new Bundle();
|
Bundle response = new Bundle();
|
||||||
response.putString(AccountManager.KEY_ACCOUNT_NAME, mAccount.name);
|
response.putString(AccountManager.KEY_ACCOUNT_NAME, mAccount.name);
|
||||||
response.putString(AccountManager.KEY_ACCOUNT_TYPE, mAccount.type);
|
response.putString(AccountManager.KEY_ACCOUNT_TYPE, mAccount.type);
|
||||||
|
|
||||||
if (AccountTypeUtils.getAuthTokenTypeAccessToken(accountType).equals(mAuthTokenType)) {
|
if (webViewLoginMethod) {
|
||||||
response.putString(AccountManager.KEY_AUTHTOKEN, mAuthToken);
|
|
||||||
// the next line is necessary, notifications are calling directly to the
|
|
||||||
// AuthenticatorActivity to update, without AccountManager intervention
|
|
||||||
mAccountMgr.setAuthToken(mAccount, mAuthTokenType, mAuthToken);
|
|
||||||
|
|
||||||
} else if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(accountType).equals(mAuthTokenType)) {
|
|
||||||
response.putString(AccountManager.KEY_AUTHTOKEN, mAuthToken);
|
|
||||||
// the next line is necessary; by now, notifications are calling directly to the
|
|
||||||
// AuthenticatorActivity to update, without AccountManager intervention
|
|
||||||
mAccountMgr.setAuthToken(mAccount, mAuthTokenType, mAuthToken);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (!webViewLoginMethod) {
|
|
||||||
response.putString(AccountManager.KEY_AUTHTOKEN, mPasswordInput.getText().toString());
|
|
||||||
mAccountMgr.setPassword(mAccount, mPasswordInput.getText().toString());
|
|
||||||
} else {
|
|
||||||
response.putString(AccountManager.KEY_AUTHTOKEN, webViewPassword);
|
response.putString(AccountManager.KEY_AUTHTOKEN, webViewPassword);
|
||||||
mAccountMgr.setPassword(mAccount, webViewPassword);
|
mAccountMgr.setPassword(mAccount, webViewPassword);
|
||||||
}
|
} else {
|
||||||
|
response.putString(AccountManager.KEY_AUTHTOKEN, mPasswordInput.getText().toString());
|
||||||
|
mAccountMgr.setPassword(mAccount, mPasswordInput.getText().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove managed clients for this account to enforce creation with fresh credentials
|
// remove managed clients for this account to enforce creation with fresh credentials
|
||||||
|
@ -1936,9 +1630,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
String accountType = MainApp.getAccountType(this);
|
String accountType = MainApp.getAccountType(this);
|
||||||
|
|
||||||
// create and save new ownCloud account
|
// create and save new ownCloud account
|
||||||
boolean isOAuth = AccountTypeUtils.getAuthTokenTypeAccessToken(accountType).equals(mAuthTokenType);
|
|
||||||
boolean isSaml = AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(accountType).equals(mAuthTokenType);
|
|
||||||
|
|
||||||
String lastPermanentLocation = authResult.getLastPermanentLocation();
|
String lastPermanentLocation = authResult.getLastPermanentLocation();
|
||||||
if (lastPermanentLocation != null) {
|
if (lastPermanentLocation != null) {
|
||||||
mServerInfo.mBaseUrl = AuthenticatorUrlUtils.trimWebdavSuffix(lastPermanentLocation);
|
mServerInfo.mBaseUrl = AuthenticatorUrlUtils.trimWebdavSuffix(lastPermanentLocation);
|
||||||
|
@ -1951,9 +1642,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
} else {
|
} else {
|
||||||
username = webViewUser;
|
username = webViewUser;
|
||||||
}
|
}
|
||||||
if (isOAuth) {
|
|
||||||
username = "OAuth_user" + new SecureRandom().nextLong();
|
|
||||||
}
|
|
||||||
|
|
||||||
String accountName = com.owncloud.android.lib.common.accounts.AccountUtils.buildAccountName(uri, username);
|
String accountName = com.owncloud.android.lib.common.accounts.AccountUtils.buildAccountName(uri, username);
|
||||||
Account newAccount = new Account(accountName, accountType);
|
Account newAccount = new Account(accountName, accountType);
|
||||||
|
@ -1970,15 +1658,10 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
} else {
|
} else {
|
||||||
mAccount = newAccount;
|
mAccount = newAccount;
|
||||||
|
|
||||||
if (isOAuth || isSaml) {
|
if (webViewLoginMethod) {
|
||||||
// with external authorizations, the password is never input in the app
|
|
||||||
mAccountMgr.addAccountExplicitly(mAccount, EMPTY_STRING, null);
|
|
||||||
} else {
|
|
||||||
if (!webViewLoginMethod) {
|
|
||||||
mAccountMgr.addAccountExplicitly(mAccount, mPasswordInput.getText().toString(), null);
|
|
||||||
} else {
|
|
||||||
mAccountMgr.addAccountExplicitly(mAccount, webViewPassword, null);
|
mAccountMgr.addAccountExplicitly(mAccount, webViewPassword, null);
|
||||||
}
|
} else {
|
||||||
|
mAccountMgr.addAccountExplicitly(mAccount, mPasswordInput.getText().toString(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// add the new account as default in preferences, if there is none already
|
/// add the new account as default in preferences, if there is none already
|
||||||
|
@ -1996,9 +1679,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, accountType);
|
intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, accountType);
|
||||||
intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, mAccount.name);
|
intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, mAccount.name);
|
||||||
intent.putExtra(AccountManager.KEY_USERDATA, username);
|
intent.putExtra(AccountManager.KEY_USERDATA, username);
|
||||||
if (isOAuth || isSaml) {
|
|
||||||
mAccountMgr.setAuthToken(mAccount, mAuthTokenType, mAuthToken);
|
|
||||||
}
|
|
||||||
/// add user data to the new account; TODO probably can be done in the last parameter
|
/// add user data to the new account; TODO probably can be done in the last parameter
|
||||||
// addAccountExplicitly, or in KEY_USERDATA
|
// addAccountExplicitly, or in KEY_USERDATA
|
||||||
mAccountMgr.setUserData(mAccount, Constants.KEY_OC_VERSION, mServerInfo.mVersion.getVersion());
|
mAccountMgr.setUserData(mAccount, Constants.KEY_OC_VERSION, mServerInfo.mVersion.getVersion());
|
||||||
|
@ -2023,12 +1704,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
Log_OC.w(TAG, "Couldn't get display name and user id for " + username);
|
Log_OC.w(TAG, "Couldn't get display name and user id for " + username);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSaml) {
|
|
||||||
mAccountMgr.setUserData(mAccount, Constants.KEY_SUPPORTS_SAML_WEB_SSO, "TRUE");
|
|
||||||
} else if (isOAuth) {
|
|
||||||
mAccountMgr.setUserData(mAccount, Constants.KEY_SUPPORTS_OAUTH2, "TRUE");
|
|
||||||
}
|
|
||||||
|
|
||||||
setAccountAuthenticatorResult(intent.getExtras());
|
setAccountAuthenticatorResult(intent.getExtras());
|
||||||
setResult(RESULT_OK, intent);
|
setResult(RESULT_OK, intent);
|
||||||
|
|
||||||
|
@ -2125,25 +1800,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
mPasswordInput.setSelection(selectionStart, selectionEnd);
|
mPasswordInput.setSelection(selectionStart, selectionEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the checkbox for OAuth authorization is clicked.
|
|
||||||
*
|
|
||||||
* Hides or shows the input fields for user & password.
|
|
||||||
*
|
|
||||||
* @param view 'View password' 'button'
|
|
||||||
*/
|
|
||||||
public void onCheckClick(View view) {
|
|
||||||
CheckBox oAuth2Check = (CheckBox) view;
|
|
||||||
if (oAuth2Check.isChecked()) {
|
|
||||||
mAuthTokenType = oauthTokenType;
|
|
||||||
} else {
|
|
||||||
mAuthTokenType = basicTokenType;
|
|
||||||
}
|
|
||||||
updateAuthenticationPreFragmentVisibility();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the 'action' button in an IME is pressed ('enter' in software keyboard).
|
* Called when the 'action' button in an IME is pressed ('enter' in software keyboard).
|
||||||
*
|
*
|
||||||
|
@ -2215,38 +1871,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSsoFinished(String sessionCookie) {
|
|
||||||
if (sessionCookie != null && sessionCookie.length() > 0) {
|
|
||||||
Log_OC.d(TAG, "Successful SSO - time to save the account");
|
|
||||||
mAuthToken = sessionCookie;
|
|
||||||
getRemoteUserNameOperation(sessionCookie);
|
|
||||||
Fragment fd = getSupportFragmentManager().findFragmentByTag(SAML_DIALOG_TAG);
|
|
||||||
if (fd instanceof DialogFragment) {
|
|
||||||
Dialog d = ((DialogFragment) fd).getDialog();
|
|
||||||
if (d != null && d.isShowing()) {
|
|
||||||
d.dismiss();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// TODO - show fail
|
|
||||||
Log_OC.d(TAG, "SSO failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onTouchEvent(MotionEvent event) {
|
|
||||||
if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType(this)).equals(mAuthTokenType) &&
|
|
||||||
mHostUrlInput.hasFocus() && event.getAction() == MotionEvent.ACTION_DOWN) {
|
|
||||||
checkOcServer();
|
|
||||||
}
|
|
||||||
return super.onTouchEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show untrusted cert dialog
|
* Show untrusted cert dialog
|
||||||
*/
|
*/
|
||||||
|
@ -2279,34 +1903,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Called from SslValidatorDialog when a new server certificate was correctly saved.
|
|
||||||
*/
|
|
||||||
public void onSavedCertificate() {
|
|
||||||
Fragment fd = getSupportFragmentManager().findFragmentByTag(SAML_DIALOG_TAG);
|
|
||||||
if (fd == null) {
|
|
||||||
// if SAML dialog is not shown,
|
|
||||||
// the SslDialog was shown due to an SSL error in the server check
|
|
||||||
checkOcServer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called from SslValidatorDialog when a new server certificate could not be saved
|
|
||||||
* when the user requested it.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onFailedSavingCertificate() {
|
|
||||||
dismissDialog(SAML_DIALOG_TAG);
|
|
||||||
DisplayUtils.showSnackMessage(this, R.string.ssl_validator_not_saved);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCancelCertificate() {
|
|
||||||
dismissDialog(SAML_DIALOG_TAG);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void doOnResumeAndBound() {
|
private void doOnResumeAndBound() {
|
||||||
//Log_OC.e(TAG, "registering to listen for operation callbacks" );
|
//Log_OC.e(TAG, "registering to listen for operation callbacks" );
|
||||||
mOperationsServiceBinder.addOperationListener(this, mHandler);
|
mOperationsServiceBinder.addOperationListener(this, mHandler);
|
||||||
|
@ -2335,7 +1931,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements callback methods for service binding.
|
* Implements callback methods for service binding.
|
||||||
*/
|
*/
|
||||||
|
@ -2431,4 +2026,43 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
||||||
parseAndLoginFromWebView(result);
|
parseAndLoginFromWebView(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the X509Certificate from SslError
|
||||||
|
*
|
||||||
|
* @param error SslError
|
||||||
|
* @return X509Certificate from error
|
||||||
|
*/
|
||||||
|
public static X509Certificate getX509CertificateFromError(SslError error) {
|
||||||
|
Bundle bundle = SslCertificate.saveState(error.getCertificate());
|
||||||
|
X509Certificate x509Certificate;
|
||||||
|
byte[] bytes = bundle.getByteArray("x509-certificate");
|
||||||
|
if (bytes == null) {
|
||||||
|
x509Certificate = null;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
|
||||||
|
Certificate cert = certFactory.generateCertificate(new ByteArrayInputStream(bytes));
|
||||||
|
x509Certificate = (X509Certificate) cert;
|
||||||
|
} catch (CertificateException e) {
|
||||||
|
x509Certificate = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return x509Certificate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called from SslValidatorDialog when a new server certificate was correctly saved.
|
||||||
|
*/
|
||||||
|
public void onSavedCertificate() {
|
||||||
|
checkOcServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called from SslValidatorDialog when a new server certificate could not be saved when the user requested it.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onFailedSavingCertificate() {
|
||||||
|
DisplayUtils.showSnackMessage(this, R.string.ssl_validator_not_saved);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,6 @@ package com.owncloud.android.authentication;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import com.owncloud.android.MainApp;
|
|
||||||
import com.owncloud.android.lib.common.accounts.AccountTypeUtils;
|
|
||||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -38,9 +36,6 @@ public final class AuthenticatorUrlUtils {
|
||||||
private static final String HTTPS_PROTOCOL = "https://";
|
private static final String HTTPS_PROTOCOL = "https://";
|
||||||
private static final String HTTP_PROTOCOL = "http://";
|
private static final String HTTP_PROTOCOL = "http://";
|
||||||
|
|
||||||
private static final String ODAV_PATH = "/remote.php/odav";
|
|
||||||
private static final String SAML_SSO_PATH = "/remote.php/webdav";
|
|
||||||
|
|
||||||
private AuthenticatorUrlUtils() {
|
private AuthenticatorUrlUtils() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,19 +50,8 @@ public final class AuthenticatorUrlUtils {
|
||||||
* is unknown; versions prior to ownCloud 4 are not supported anymore
|
* is unknown; versions prior to ownCloud 4 are not supported anymore
|
||||||
*/
|
*/
|
||||||
public static String getWebdavPath(OwnCloudVersion version, String authTokenType, Context context) {
|
public static String getWebdavPath(OwnCloudVersion version, String authTokenType, Context context) {
|
||||||
if (version != null) {
|
|
||||||
String accountType = MainApp.getAccountType(context);
|
|
||||||
if (AccountTypeUtils.getAuthTokenTypeAccessToken(accountType).equals(authTokenType)) {
|
|
||||||
return ODAV_PATH;
|
|
||||||
}
|
|
||||||
if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(accountType).equals(authTokenType)) {
|
|
||||||
return SAML_SSO_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
return WEBDAV_PATH_4_0_AND_LATER;
|
return WEBDAV_PATH_4_0_AND_LATER;
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String normalizeUrlSuffix(String url) {
|
public static String normalizeUrlSuffix(String url) {
|
||||||
String normalizedUrl = url;
|
String normalizedUrl = url;
|
||||||
|
@ -107,13 +91,7 @@ public final class AuthenticatorUrlUtils {
|
||||||
if (pos >= 0) {
|
if (pos >= 0) {
|
||||||
trimmedUrl = trimmedUrl.substring(0, pos);
|
trimmedUrl = trimmedUrl.substring(0, pos);
|
||||||
|
|
||||||
} else {
|
|
||||||
pos = trimmedUrl.lastIndexOf(ODAV_PATH);
|
|
||||||
if (pos >= 0) {
|
|
||||||
trimmedUrl = trimmedUrl.substring(0, pos);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return trimmedUrl;
|
return trimmedUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
/*
|
|
||||||
* ownCloud Android client application
|
|
||||||
*
|
|
||||||
* @author David A. Velasco
|
|
||||||
* Copyright (C) 2015 ownCloud Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2,
|
|
||||||
* as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.owncloud.android.authentication;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constant values for OAuth 2 protocol.
|
|
||||||
*
|
|
||||||
* Includes required and optional parameter NAMES used in the 'authorization code' grant type.
|
|
||||||
*/
|
|
||||||
public final class OAuth2Constants {
|
|
||||||
/// Parameters to send to the Authorization Endpoint
|
|
||||||
public static final String KEY_RESPONSE_TYPE = "response_type";
|
|
||||||
public static final String KEY_REDIRECT_URI = "redirect_uri";
|
|
||||||
public static final String KEY_CLIENT_ID = "client_id";
|
|
||||||
public static final String KEY_SCOPE = "scope";
|
|
||||||
public static final String KEY_STATE = "state";
|
|
||||||
|
|
||||||
/// Additional parameters to send to the Token Endpoint
|
|
||||||
public static final String KEY_GRANT_TYPE = "grant_type";
|
|
||||||
public static final String KEY_CODE = "code";
|
|
||||||
|
|
||||||
/// Parameters received in an OK response from the Token Endpoint
|
|
||||||
public static final String KEY_ACCESS_TOKEN = "access_token";
|
|
||||||
public static final String KEY_TOKEN_TYPE = "token_type";
|
|
||||||
public static final String KEY_EXPIRES_IN = "expires_in";
|
|
||||||
public static final String KEY_REFRESH_TOKEN = "refresh_token";
|
|
||||||
|
|
||||||
/// Parameters in an ERROR response
|
|
||||||
public static final String KEY_ERROR = "error";
|
|
||||||
public static final String KEY_ERROR_DESCRIPTION = "error_description";
|
|
||||||
public static final String KEY_ERROR_URI = "error_uri";
|
|
||||||
public static final String VALUE_ERROR_ACCESS_DENIED = "access_denied";
|
|
||||||
|
|
||||||
private OAuth2Constants() {
|
|
||||||
// No instance
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,190 +0,0 @@
|
||||||
/**
|
|
||||||
* ownCloud Android client application
|
|
||||||
*
|
|
||||||
* @author David A. Velasco
|
|
||||||
* Copyright (C) 2015 ownCloud Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2,
|
|
||||||
* as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.owncloud.android.authentication;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.net.http.SslCertificate;
|
|
||||||
import android.net.http.SslError;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Message;
|
|
||||||
import android.view.View;
|
|
||||||
import android.webkit.CookieManager;
|
|
||||||
import android.webkit.HttpAuthHandler;
|
|
||||||
import android.webkit.SslErrorHandler;
|
|
||||||
import android.webkit.WebView;
|
|
||||||
import android.webkit.WebViewClient;
|
|
||||||
|
|
||||||
import com.owncloud.android.lib.common.network.NetworkUtils;
|
|
||||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
import java.security.cert.Certificate;
|
|
||||||
import java.security.cert.CertificateException;
|
|
||||||
import java.security.cert.CertificateFactory;
|
|
||||||
import java.security.cert.X509Certificate;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Custom {@link WebViewClient} client aimed to catch the end of a single-sign-on process
|
|
||||||
* running in the {@link WebView} that is attached to.
|
|
||||||
*
|
|
||||||
* Assumes that the single-sign-on is kept thanks to a cookie set at the end of the
|
|
||||||
* authentication process.
|
|
||||||
*/
|
|
||||||
public class SsoWebViewClient extends WebViewClient {
|
|
||||||
|
|
||||||
private static final String TAG = SsoWebViewClient.class.getSimpleName();
|
|
||||||
|
|
||||||
private Context mContext;
|
|
||||||
private Handler mListenerHandler;
|
|
||||||
private WeakReference<SsoWebViewClientListener> mListenerRef;
|
|
||||||
private String mTargetUrl;
|
|
||||||
private String mLastReloadedUrlAtError;
|
|
||||||
|
|
||||||
public interface SsoWebViewClientListener {
|
|
||||||
void onSsoFinished(String sessionCookie);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SsoWebViewClient (Context context, Handler listenerHandler, SsoWebViewClientListener listener) {
|
|
||||||
mContext = context;
|
|
||||||
mListenerHandler = listenerHandler;
|
|
||||||
mListenerRef = new WeakReference<SsoWebViewClient.SsoWebViewClientListener>(listener);
|
|
||||||
mTargetUrl = "fake://url.to.be.set";
|
|
||||||
mLastReloadedUrlAtError = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTargetUrl() {
|
|
||||||
return mTargetUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTargetUrl(String targetUrl) {
|
|
||||||
mTargetUrl = targetUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPageStarted (WebView view, String url, Bitmap favicon) {
|
|
||||||
Log_OC.d(TAG, "onPageStarted : " + url);
|
|
||||||
view.clearCache(true);
|
|
||||||
super.onPageStarted(view, url, favicon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFormResubmission (WebView view, Message dontResend, Message resend) {
|
|
||||||
Log_OC.d(TAG, "onFormResubMission ");
|
|
||||||
|
|
||||||
// necessary to grant reload of last page when device orientation is changed after sending a form
|
|
||||||
resend.sendToTarget();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onReceivedError (WebView view, int errorCode, String description, String failingUrl) {
|
|
||||||
Log_OC.e(TAG, "onReceivedError : " + failingUrl + ", code " + errorCode + ", description: " + description);
|
|
||||||
if (!failingUrl.equals(mLastReloadedUrlAtError)) {
|
|
||||||
view.reload();
|
|
||||||
mLastReloadedUrlAtError = failingUrl;
|
|
||||||
} else {
|
|
||||||
mLastReloadedUrlAtError = null;
|
|
||||||
super.onReceivedError(view, errorCode, description, failingUrl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPageFinished (WebView view, String url) {
|
|
||||||
Log_OC.d(TAG, "onPageFinished : " + url);
|
|
||||||
mLastReloadedUrlAtError = null;
|
|
||||||
if (url.startsWith(mTargetUrl)) {
|
|
||||||
view.setVisibility(View.GONE);
|
|
||||||
CookieManager cookieManager = CookieManager.getInstance();
|
|
||||||
final String cookies = cookieManager.getCookie(url);
|
|
||||||
//Log_OC.d(TAG, "Cookies: " + cookies);
|
|
||||||
if (mListenerHandler != null && mListenerRef != null) {
|
|
||||||
// this is good idea because onPageFinished is not running in the UI thread
|
|
||||||
mListenerHandler.post(() -> {
|
|
||||||
SsoWebViewClientListener listener = mListenerRef.get();
|
|
||||||
if (listener != null) {
|
|
||||||
// Send Cookies to the listener
|
|
||||||
listener.onSsoFinished(cookies);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onReceivedSslError (final WebView view, final SslErrorHandler handler, SslError error) {
|
|
||||||
Log_OC.e(TAG, "onReceivedSslError : " + error);
|
|
||||||
// Test 1
|
|
||||||
X509Certificate x509Certificate = getX509CertificateFromError(error);
|
|
||||||
boolean isKnownServer = false;
|
|
||||||
|
|
||||||
if (x509Certificate != null) {
|
|
||||||
try {
|
|
||||||
isKnownServer = NetworkUtils.isCertInKnownServersStore(x509Certificate, mContext);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log_OC.e(TAG, "Exception: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isKnownServer) {
|
|
||||||
handler.proceed();
|
|
||||||
} else {
|
|
||||||
((AuthenticatorActivity)mContext).showUntrustedCertDialog(x509Certificate, error, handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtain the X509Certificate from SslError
|
|
||||||
* @param error SslError
|
|
||||||
* @return X509Certificate from error
|
|
||||||
*/
|
|
||||||
public static X509Certificate getX509CertificateFromError(SslError error) {
|
|
||||||
Bundle bundle = SslCertificate.saveState(error.getCertificate());
|
|
||||||
X509Certificate x509Certificate;
|
|
||||||
byte[] bytes = bundle.getByteArray("x509-certificate");
|
|
||||||
if (bytes == null) {
|
|
||||||
x509Certificate = null;
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
|
|
||||||
Certificate cert = certFactory.generateCertificate(new ByteArrayInputStream(bytes));
|
|
||||||
x509Certificate = (X509Certificate) cert;
|
|
||||||
} catch (CertificateException e) {
|
|
||||||
x509Certificate = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return x509Certificate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onReceivedHttpAuthRequest (WebView view, HttpAuthHandler handler, String host, String realm) {
|
|
||||||
Log_OC.d(TAG, "onReceivedHttpAuthRequest : " + host);
|
|
||||||
|
|
||||||
((AuthenticatorActivity)mContext).createAuthenticationDialog(view, handler);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
/**
|
/*
|
||||||
* ownCloud Android client application
|
* ownCloud Android client application
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Bartek Przybylski
|
* Copyright (C) 2012 Bartek Przybylski
|
||||||
|
@ -450,7 +450,7 @@ public class FileDownloader extends Service
|
||||||
|
|
||||||
|
|
||||||
/// perform the download
|
/// perform the download
|
||||||
downloadResult = mCurrentDownload.execute(mDownloadClient, mCurrentDownload.getFile().isEncrypted());
|
downloadResult = mCurrentDownload.execute(mDownloadClient);
|
||||||
if (downloadResult.isSuccess()) {
|
if (downloadResult.isSuccess()) {
|
||||||
saveDownloadedFile();
|
saveDownloadedFile();
|
||||||
}
|
}
|
||||||
|
@ -460,11 +460,8 @@ public class FileDownloader extends Service
|
||||||
downloadResult = new RemoteOperationResult(e);
|
downloadResult = new RemoteOperationResult(e);
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
Pair<DownloadFileOperation, String> removeResult =
|
Pair<DownloadFileOperation, String> removeResult = mPendingDownloads.removePayload(
|
||||||
mPendingDownloads.removePayload(
|
mCurrentAccount.name, mCurrentDownload.getRemotePath());
|
||||||
mCurrentAccount.name,
|
|
||||||
mCurrentDownload.getRemotePath()
|
|
||||||
);
|
|
||||||
|
|
||||||
/// notify result
|
/// notify result
|
||||||
notifyDownloadResult(mCurrentDownload, downloadResult);
|
notifyDownloadResult(mCurrentDownload, downloadResult);
|
||||||
|
|
|
@ -56,7 +56,7 @@ public class CommentFileOperation extends SyncOperation {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected RemoteOperationResult run(OwnCloudClient client) {
|
protected RemoteOperationResult run(OwnCloudClient client) {
|
||||||
RemoteOperationResult result = new CommentFileRemoteOperation(message, fileId, userId).execute(client, true);
|
RemoteOperationResult result = new CommentFileRemoteOperation(message, fileId, userId).execute(client);
|
||||||
|
|
||||||
if (!result.isSuccess()) {
|
if (!result.isSuccess()) {
|
||||||
Log_OC.e(this, "File with Id " + fileId + " could not be commented");
|
Log_OC.e(this, "File with Id " + fileId + " could not be commented");
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class CreateFolderOperation extends SyncOperation implements OnRemoteOper
|
||||||
|
|
||||||
if (result.isSuccess()) {
|
if (result.isSuccess()) {
|
||||||
RemoteOperationResult remoteFolderOperationResult = new ReadFolderRemoteOperation(mRemotePath)
|
RemoteOperationResult remoteFolderOperationResult = new ReadFolderRemoteOperation(mRemotePath)
|
||||||
.execute(client, true);
|
.execute(client);
|
||||||
|
|
||||||
createdRemoteFolder = (RemoteFile) remoteFolderOperationResult.getData().get(0);
|
createdRemoteFolder = (RemoteFile) remoteFolderOperationResult.getData().get(0);
|
||||||
saveFolderInDB();
|
saveFolderInDB();
|
||||||
|
|
|
@ -158,7 +158,7 @@ public class DownloadFileOperation extends RemoteOperation {
|
||||||
while (listener.hasNext()) {
|
while (listener.hasNext()) {
|
||||||
downloadOperation.addDatatransferProgressListener(listener.next());
|
downloadOperation.addDatatransferProgressListener(listener.next());
|
||||||
}
|
}
|
||||||
result = downloadOperation.execute(client, client.isUseNextcloudUserAgent());
|
result = downloadOperation.execute(client);
|
||||||
|
|
||||||
if (result.isSuccess()) {
|
if (result.isSuccess()) {
|
||||||
modificationTimestamp = downloadOperation.getModificationTimestamp();
|
modificationTimestamp = downloadOperation.getModificationTimestamp();
|
||||||
|
|
|
@ -1,197 +0,0 @@
|
||||||
/*
|
|
||||||
* ownCloud Android client application
|
|
||||||
*
|
|
||||||
* Copyright (C) 2015 ownCloud Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2,
|
|
||||||
* as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.owncloud.android.operations;
|
|
||||||
|
|
||||||
import com.owncloud.android.authentication.OAuth2Constants;
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
|
|
||||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
|
||||||
|
|
||||||
import org.apache.commons.httpclient.NameValuePair;
|
|
||||||
import org.apache.commons.httpclient.methods.PostMethod;
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
|
|
||||||
public class OAuth2GetAccessToken extends RemoteOperation {
|
|
||||||
private static final String TAG = OAuth2GetAccessToken.class.getSimpleName();
|
|
||||||
|
|
||||||
private static final int KEY_INDEX = 0;
|
|
||||||
private static final int VALUE_INDEX = 1;
|
|
||||||
|
|
||||||
private String mClientId;
|
|
||||||
private String mRedirectUri;
|
|
||||||
private String mGrantType;
|
|
||||||
|
|
||||||
private String mOAuth2AuthorizationResponse;
|
|
||||||
private Map<String, String> mOAuth2ParsedAuthorizationResponse;
|
|
||||||
private Map<String, String> mResultTokenMap;
|
|
||||||
|
|
||||||
|
|
||||||
public OAuth2GetAccessToken(String clientId, String redirectUri, String grantType, String oAuth2AuthorizationResponse) {
|
|
||||||
mClientId = clientId;
|
|
||||||
mRedirectUri = redirectUri;
|
|
||||||
mGrantType = grantType;
|
|
||||||
mOAuth2AuthorizationResponse = oAuth2AuthorizationResponse;
|
|
||||||
mOAuth2ParsedAuthorizationResponse = new HashMap<>();
|
|
||||||
mResultTokenMap = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
public Map<String, String> getResultTokenMap() {
|
|
||||||
return mResultTokenMap;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("PMD.AvoidDuplicateLiterals")
|
|
||||||
protected RemoteOperationResult run(OwnCloudClient client) {
|
|
||||||
RemoteOperationResult result = null;
|
|
||||||
PostMethod postMethod = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
parseAuthorizationResponse();
|
|
||||||
if (mOAuth2ParsedAuthorizationResponse.keySet().contains(OAuth2Constants.KEY_ERROR)) {
|
|
||||||
if (OAuth2Constants.VALUE_ERROR_ACCESS_DENIED.equals(mOAuth2ParsedAuthorizationResponse.get(OAuth2Constants.KEY_ERROR))) {
|
|
||||||
result = new RemoteOperationResult(ResultCode.OAUTH2_ERROR_ACCESS_DENIED);
|
|
||||||
} else {
|
|
||||||
result = new RemoteOperationResult(ResultCode.OAUTH2_ERROR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result == null) {
|
|
||||||
NameValuePair[] nameValuePairs = new NameValuePair[4];
|
|
||||||
nameValuePairs[0] = new NameValuePair(OAuth2Constants.KEY_GRANT_TYPE, mGrantType);
|
|
||||||
nameValuePairs[1] = new NameValuePair(OAuth2Constants.KEY_CODE, mOAuth2ParsedAuthorizationResponse.get(OAuth2Constants.KEY_CODE));
|
|
||||||
nameValuePairs[2] = new NameValuePair(OAuth2Constants.KEY_REDIRECT_URI, mRedirectUri);
|
|
||||||
nameValuePairs[3] = new NameValuePair(OAuth2Constants.KEY_CLIENT_ID, mClientId);
|
|
||||||
//nameValuePairs[4] = new NameValuePair(OAuth2Constants.KEY_SCOPE, mOAuth2ParsedAuthorizationResponse.get(OAuth2Constants.KEY_SCOPE));
|
|
||||||
|
|
||||||
postMethod = new PostMethod(client.getWebdavUri().toString());
|
|
||||||
postMethod.setRequestBody(nameValuePairs);
|
|
||||||
client.executeMethod(postMethod);
|
|
||||||
|
|
||||||
String response = postMethod.getResponseBodyAsString();
|
|
||||||
if (response != null && response.length() > 0) {
|
|
||||||
JSONObject tokenJson = new JSONObject(response);
|
|
||||||
parseAccessTokenResult(tokenJson);
|
|
||||||
if (mResultTokenMap.get(OAuth2Constants.KEY_ERROR) != null || mResultTokenMap.get(OAuth2Constants.KEY_ACCESS_TOKEN) == null) {
|
|
||||||
result = new RemoteOperationResult(ResultCode.OAUTH2_ERROR);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
result = new RemoteOperationResult(true, postMethod);
|
|
||||||
ArrayList<Object> data = new ArrayList<>();
|
|
||||||
data.add(mResultTokenMap);
|
|
||||||
result.setData(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
result = new RemoteOperationResult(false, postMethod);
|
|
||||||
client.exhaustResponse(postMethod.getResponseBodyAsStream());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
result = new RemoteOperationResult(e);
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
if (postMethod != null) {
|
|
||||||
postMethod.releaseConnection(); // let the connection available for other methods
|
|
||||||
}
|
|
||||||
|
|
||||||
final String code = "code";
|
|
||||||
final String oauth_token_request = "OAuth2 TOKEN REQUEST with auth code ";
|
|
||||||
if (result != null) {
|
|
||||||
if (result.isSuccess()) {
|
|
||||||
Log_OC.i(TAG, oauth_token_request + mOAuth2ParsedAuthorizationResponse.get(code) + " to " + client.getWebdavUri() + ": " + result.getLogMessage());
|
|
||||||
} else if (result.getException() != null) {
|
|
||||||
Log_OC.e(TAG, oauth_token_request + mOAuth2ParsedAuthorizationResponse.get(code) + " to " + client.getWebdavUri() + ": " + result.getLogMessage(), result.getException());
|
|
||||||
} else if (result.getCode() == ResultCode.OAUTH2_ERROR) {
|
|
||||||
Log_OC.e(TAG, oauth_token_request + mOAuth2ParsedAuthorizationResponse.get(code) + " to " + client.getWebdavUri() + ": " + ((mResultTokenMap != null) ? mResultTokenMap.get(OAuth2Constants.KEY_ERROR) : "NULL"));
|
|
||||||
} else {
|
|
||||||
Log_OC.e(TAG, oauth_token_request + mOAuth2ParsedAuthorizationResponse.get(code) + " to " + client.getWebdavUri() + ": " + result.getLogMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void parseAuthorizationResponse() {
|
|
||||||
String[] pairs = mOAuth2AuthorizationResponse.split("&");
|
|
||||||
int i = 0;
|
|
||||||
String key = "";
|
|
||||||
String value;
|
|
||||||
while (pairs.length > i) {
|
|
||||||
int j = 0;
|
|
||||||
String[] part = pairs[i].split("=");
|
|
||||||
while (part.length > j) {
|
|
||||||
String p = part[j];
|
|
||||||
if (j == KEY_INDEX) {
|
|
||||||
key = p;
|
|
||||||
} else if (j == VALUE_INDEX) {
|
|
||||||
value = p;
|
|
||||||
mOAuth2ParsedAuthorizationResponse.put(key, value);
|
|
||||||
}
|
|
||||||
Log_OC.v(TAG, "[" + i + "," + j + "] = " + p);
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void parseAccessTokenResult (JSONObject tokenJson) throws JSONException {
|
|
||||||
mResultTokenMap = new HashMap<>();
|
|
||||||
|
|
||||||
if (tokenJson.has(OAuth2Constants.KEY_ACCESS_TOKEN)) {
|
|
||||||
mResultTokenMap.put(OAuth2Constants.KEY_ACCESS_TOKEN, tokenJson.getString(OAuth2Constants.KEY_ACCESS_TOKEN));
|
|
||||||
}
|
|
||||||
if (tokenJson.has(OAuth2Constants.KEY_TOKEN_TYPE)) {
|
|
||||||
mResultTokenMap.put(OAuth2Constants.KEY_TOKEN_TYPE, tokenJson.getString(OAuth2Constants.KEY_TOKEN_TYPE));
|
|
||||||
}
|
|
||||||
if (tokenJson.has(OAuth2Constants.KEY_EXPIRES_IN)) {
|
|
||||||
mResultTokenMap.put(OAuth2Constants.KEY_EXPIRES_IN, tokenJson.getString(OAuth2Constants.KEY_EXPIRES_IN));
|
|
||||||
}
|
|
||||||
if (tokenJson.has(OAuth2Constants.KEY_REFRESH_TOKEN)) {
|
|
||||||
mResultTokenMap.put(OAuth2Constants.KEY_REFRESH_TOKEN, tokenJson.getString(OAuth2Constants.KEY_REFRESH_TOKEN));
|
|
||||||
}
|
|
||||||
if (tokenJson.has(OAuth2Constants.KEY_SCOPE)) {
|
|
||||||
mResultTokenMap.put(OAuth2Constants.KEY_SCOPE, tokenJson.getString(OAuth2Constants.KEY_SCOPE));
|
|
||||||
}
|
|
||||||
if (tokenJson.has(OAuth2Constants.KEY_ERROR)) {
|
|
||||||
mResultTokenMap.put(OAuth2Constants.KEY_ERROR, tokenJson.getString(OAuth2Constants.KEY_ERROR));
|
|
||||||
}
|
|
||||||
if (tokenJson.has(OAuth2Constants.KEY_ERROR_DESCRIPTION)) {
|
|
||||||
mResultTokenMap.put(OAuth2Constants.KEY_ERROR_DESCRIPTION, tokenJson.getString(OAuth2Constants.KEY_ERROR_DESCRIPTION));
|
|
||||||
}
|
|
||||||
if (tokenJson.has(OAuth2Constants.KEY_ERROR_URI)) {
|
|
||||||
mResultTokenMap.put(OAuth2Constants.KEY_ERROR_URI, tokenJson.getString(OAuth2Constants.KEY_ERROR_URI));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -290,7 +290,7 @@ public class RefreshFolderOperation extends RemoteOperation {
|
||||||
Log_OC.d(TAG, "Checking changes in " + mAccount.name + remotePath);
|
Log_OC.d(TAG, "Checking changes in " + mAccount.name + remotePath);
|
||||||
|
|
||||||
// remote request
|
// remote request
|
||||||
result = new ReadFileRemoteOperation(remotePath).execute(client, true);
|
result = new ReadFileRemoteOperation(remotePath).execute(client);
|
||||||
|
|
||||||
if (result.isSuccess()) {
|
if (result.isSuccess()) {
|
||||||
OCFile remoteFolder = FileStorageUtils.fillOCFile((RemoteFile) result.getData().get(0));
|
OCFile remoteFolder = FileStorageUtils.fillOCFile((RemoteFile) result.getData().get(0));
|
||||||
|
@ -332,7 +332,7 @@ public class RefreshFolderOperation extends RemoteOperation {
|
||||||
|
|
||||||
private RemoteOperationResult fetchAndSyncRemoteFolder(OwnCloudClient client) {
|
private RemoteOperationResult fetchAndSyncRemoteFolder(OwnCloudClient client) {
|
||||||
String remotePath = mLocalFolder.getRemotePath();
|
String remotePath = mLocalFolder.getRemotePath();
|
||||||
RemoteOperationResult result = new ReadFolderRemoteOperation(remotePath).execute(client, true);
|
RemoteOperationResult result = new ReadFolderRemoteOperation(remotePath).execute(client);
|
||||||
Log_OC.d(TAG, "Synchronizing " + mAccount.name + remotePath);
|
Log_OC.d(TAG, "Synchronizing " + mAccount.name + remotePath);
|
||||||
|
|
||||||
if (result.isSuccess()) {
|
if (result.isSuccess()) {
|
||||||
|
|
|
@ -94,7 +94,7 @@ public class RemoveRemoteEncryptedFileOperation extends RemoteOperation {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Lock folder
|
// Lock folder
|
||||||
RemoteOperationResult lockFileOperationResult = new LockFileRemoteOperation(parentId).execute(client, true);
|
RemoteOperationResult lockFileOperationResult = new LockFileRemoteOperation(parentId).execute(client);
|
||||||
|
|
||||||
if (lockFileOperationResult.isSuccess()) {
|
if (lockFileOperationResult.isSuccess()) {
|
||||||
token = (String) lockFileOperationResult.getData().get(0);
|
token = (String) lockFileOperationResult.getData().get(0);
|
||||||
|
@ -105,8 +105,7 @@ public class RemoveRemoteEncryptedFileOperation extends RemoteOperation {
|
||||||
}
|
}
|
||||||
|
|
||||||
// refresh metadata
|
// refresh metadata
|
||||||
RemoteOperationResult getMetadataOperationResult = new GetMetadataRemoteOperation(parentId)
|
RemoteOperationResult getMetadataOperationResult = new GetMetadataRemoteOperation(parentId).execute(client);
|
||||||
.execute(client, true);
|
|
||||||
|
|
||||||
if (getMetadataOperationResult.isSuccess()) {
|
if (getMetadataOperationResult.isSuccess()) {
|
||||||
// decrypt metadata
|
// decrypt metadata
|
||||||
|
@ -138,7 +137,7 @@ public class RemoveRemoteEncryptedFileOperation extends RemoteOperation {
|
||||||
|
|
||||||
// upload metadata
|
// upload metadata
|
||||||
RemoteOperationResult uploadMetadataOperationResult = new UpdateMetadataRemoteOperation(parentId,
|
RemoteOperationResult uploadMetadataOperationResult = new UpdateMetadataRemoteOperation(parentId,
|
||||||
serializedFolderMetadata, token).execute(client, true);
|
serializedFolderMetadata, token).execute(client);
|
||||||
|
|
||||||
if (!uploadMetadataOperationResult.isSuccess()) {
|
if (!uploadMetadataOperationResult.isSuccess()) {
|
||||||
throw new RemoteOperationFailedException("Metadata not uploaded!");
|
throw new RemoteOperationFailedException("Metadata not uploaded!");
|
||||||
|
@ -158,7 +157,7 @@ public class RemoveRemoteEncryptedFileOperation extends RemoteOperation {
|
||||||
// unlock file
|
// unlock file
|
||||||
if (token != null) {
|
if (token != null) {
|
||||||
RemoteOperationResult unlockFileOperationResult = new UnlockFileRemoteOperation(parentId, token)
|
RemoteOperationResult unlockFileOperationResult = new UnlockFileRemoteOperation(parentId, token)
|
||||||
.execute(client, true);
|
.execute(client);
|
||||||
|
|
||||||
if (!unlockFileOperationResult.isSuccess()) {
|
if (!unlockFileOperationResult.isSuccess()) {
|
||||||
Log_OC.e(TAG, "Failed to unlock " + parentId);
|
Log_OC.e(TAG, "Failed to unlock " + parentId);
|
||||||
|
|
|
@ -397,7 +397,7 @@ public class UploadFileOperation extends SyncOperation {
|
||||||
if (mFolderUnlockToken != null && !mFolderUnlockToken.isEmpty()) {
|
if (mFolderUnlockToken != null && !mFolderUnlockToken.isEmpty()) {
|
||||||
UnlockFileRemoteOperation unlockFileOperation = new UnlockFileRemoteOperation(parent.getLocalId(),
|
UnlockFileRemoteOperation unlockFileOperation = new UnlockFileRemoteOperation(parent.getLocalId(),
|
||||||
mFolderUnlockToken);
|
mFolderUnlockToken);
|
||||||
RemoteOperationResult unlockFileOperationResult = unlockFileOperation.execute(client, true);
|
RemoteOperationResult unlockFileOperationResult = unlockFileOperation.execute(client);
|
||||||
|
|
||||||
if (!unlockFileOperationResult.isSuccess()) {
|
if (!unlockFileOperationResult.isSuccess()) {
|
||||||
return unlockFileOperationResult;
|
return unlockFileOperationResult;
|
||||||
|
@ -451,7 +451,7 @@ public class UploadFileOperation extends SyncOperation {
|
||||||
|
|
||||||
// Lock folder
|
// Lock folder
|
||||||
LockFileRemoteOperation lockFileOperation = new LockFileRemoteOperation(parentFile.getLocalId());
|
LockFileRemoteOperation lockFileOperation = new LockFileRemoteOperation(parentFile.getLocalId());
|
||||||
RemoteOperationResult lockFileOperationResult = lockFileOperation.execute(client, true);
|
RemoteOperationResult lockFileOperationResult = lockFileOperation.execute(client);
|
||||||
|
|
||||||
if (lockFileOperationResult.isSuccess()) {
|
if (lockFileOperationResult.isSuccess()) {
|
||||||
token = (String) lockFileOperationResult.getData().get(0);
|
token = (String) lockFileOperationResult.getData().get(0);
|
||||||
|
@ -466,7 +466,7 @@ public class UploadFileOperation extends SyncOperation {
|
||||||
|
|
||||||
// Update metadata
|
// Update metadata
|
||||||
GetMetadataRemoteOperation getMetadataOperation = new GetMetadataRemoteOperation(parentFile.getLocalId());
|
GetMetadataRemoteOperation getMetadataOperation = new GetMetadataRemoteOperation(parentFile.getLocalId());
|
||||||
RemoteOperationResult getMetadataOperationResult = getMetadataOperation.execute(client, true);
|
RemoteOperationResult getMetadataOperationResult = getMetadataOperation.execute(client);
|
||||||
|
|
||||||
DecryptedFolderMetadata metadata;
|
DecryptedFolderMetadata metadata;
|
||||||
|
|
||||||
|
@ -604,7 +604,7 @@ public class UploadFileOperation extends SyncOperation {
|
||||||
throw new OperationCancelledException();
|
throw new OperationCancelledException();
|
||||||
}
|
}
|
||||||
|
|
||||||
result = mUploadOperation.execute(client, true);
|
result = mUploadOperation.execute(client);
|
||||||
|
|
||||||
/// move local temporal file or original file to its corresponding
|
/// move local temporal file or original file to its corresponding
|
||||||
// location in the Nextcloud local folder
|
// location in the Nextcloud local folder
|
||||||
|
@ -636,12 +636,12 @@ public class UploadFileOperation extends SyncOperation {
|
||||||
// update metadata
|
// update metadata
|
||||||
UpdateMetadataRemoteOperation storeMetadataOperation = new UpdateMetadataRemoteOperation(
|
UpdateMetadataRemoteOperation storeMetadataOperation = new UpdateMetadataRemoteOperation(
|
||||||
parentFile.getLocalId(), serializedFolderMetadata, token);
|
parentFile.getLocalId(), serializedFolderMetadata, token);
|
||||||
uploadMetadataOperationResult = storeMetadataOperation.execute(client, true);
|
uploadMetadataOperationResult = storeMetadataOperation.execute(client);
|
||||||
} else {
|
} else {
|
||||||
// store metadata
|
// store metadata
|
||||||
StoreMetadataRemoteOperation storeMetadataOperation = new StoreMetadataRemoteOperation(
|
StoreMetadataRemoteOperation storeMetadataOperation = new StoreMetadataRemoteOperation(
|
||||||
parentFile.getLocalId(), serializedFolderMetadata);
|
parentFile.getLocalId(), serializedFolderMetadata);
|
||||||
uploadMetadataOperationResult = storeMetadataOperation.execute(client, true);
|
uploadMetadataOperationResult = storeMetadataOperation.execute(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!uploadMetadataOperationResult.isSuccess()) {
|
if (!uploadMetadataOperationResult.isSuccess()) {
|
||||||
|
@ -715,7 +715,7 @@ public class UploadFileOperation extends SyncOperation {
|
||||||
|
|
||||||
private RemoteOperationResult unlockFolder(OCFile parentFolder, OwnCloudClient client, String token) {
|
private RemoteOperationResult unlockFolder(OCFile parentFolder, OwnCloudClient client, String token) {
|
||||||
if (token != null) {
|
if (token != null) {
|
||||||
return new UnlockFileRemoteOperation(parentFolder.getLocalId(), token).execute(client, true);
|
return new UnlockFileRemoteOperation(parentFolder.getLocalId(), token).execute(client);
|
||||||
} else {
|
} else {
|
||||||
return new RemoteOperationResult(new Exception("No token available"));
|
return new RemoteOperationResult(new Exception("No token available"));
|
||||||
}
|
}
|
||||||
|
@ -853,7 +853,7 @@ public class UploadFileOperation extends SyncOperation {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.isSuccess() && mUploadOperation != null) {
|
if (result.isSuccess() && mUploadOperation != null) {
|
||||||
result = mUploadOperation.execute(client, mFile.isEncrypted());
|
result = mUploadOperation.execute(client);
|
||||||
|
|
||||||
/// move local temporal file or original file to its corresponding
|
/// move local temporal file or original file to its corresponding
|
||||||
// location in the Nextcloud local folder
|
// location in the Nextcloud local folder
|
||||||
|
@ -1017,7 +1017,7 @@ public class UploadFileOperation extends SyncOperation {
|
||||||
*/
|
*/
|
||||||
private RemoteOperationResult grantFolderExistence(String pathToGrant, OwnCloudClient client) {
|
private RemoteOperationResult grantFolderExistence(String pathToGrant, OwnCloudClient client) {
|
||||||
RemoteOperation operation = new ExistenceCheckRemoteOperation(pathToGrant, false);
|
RemoteOperation operation = new ExistenceCheckRemoteOperation(pathToGrant, false);
|
||||||
RemoteOperationResult result = operation.execute(client, true);
|
RemoteOperationResult result = operation.execute(client);
|
||||||
if (!result.isSuccess() && result.getCode() == ResultCode.FILE_NOT_FOUND && mRemoteFolderToBeCreated) {
|
if (!result.isSuccess() && result.getCode() == ResultCode.FILE_NOT_FOUND && mRemoteFolderToBeCreated) {
|
||||||
SyncOperation syncOp = new CreateFolderOperation(pathToGrant, true);
|
SyncOperation syncOp = new CreateFolderOperation(pathToGrant, true);
|
||||||
result = syncOp.execute(client, getStorageManager());
|
result = syncOp.execute(client, getStorageManager());
|
||||||
|
@ -1318,7 +1318,7 @@ public class UploadFileOperation extends SyncOperation {
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadFileRemoteOperation operation = new ReadFileRemoteOperation(path);
|
ReadFileRemoteOperation operation = new ReadFileRemoteOperation(path);
|
||||||
RemoteOperationResult result = operation.execute(client, mFile.isEncrypted());
|
RemoteOperationResult result = operation.execute(client);
|
||||||
if (result.isSuccess()) {
|
if (result.isSuccess()) {
|
||||||
updateOCFile(file, (RemoteFile) result.getData().get(0));
|
updateOCFile(file, (RemoteFile) result.getData().get(0));
|
||||||
file.setLastSyncDateForProperties(syncDate);
|
file.setLastSyncDateForProperties(syncDate);
|
||||||
|
|
|
@ -39,7 +39,6 @@ import android.os.Process;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
import com.owncloud.android.MainApp;
|
import com.owncloud.android.MainApp;
|
||||||
import com.owncloud.android.R;
|
|
||||||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||||
import com.owncloud.android.datamodel.OCFile;
|
import com.owncloud.android.datamodel.OCFile;
|
||||||
import com.owncloud.android.lib.common.OwnCloudAccount;
|
import com.owncloud.android.lib.common.OwnCloudAccount;
|
||||||
|
@ -64,7 +63,6 @@ import com.owncloud.android.operations.CreateShareViaLinkOperation;
|
||||||
import com.owncloud.android.operations.CreateShareWithShareeOperation;
|
import com.owncloud.android.operations.CreateShareWithShareeOperation;
|
||||||
import com.owncloud.android.operations.GetServerInfoOperation;
|
import com.owncloud.android.operations.GetServerInfoOperation;
|
||||||
import com.owncloud.android.operations.MoveFileOperation;
|
import com.owncloud.android.operations.MoveFileOperation;
|
||||||
import com.owncloud.android.operations.OAuth2GetAccessToken;
|
|
||||||
import com.owncloud.android.operations.RemoveFileOperation;
|
import com.owncloud.android.operations.RemoveFileOperation;
|
||||||
import com.owncloud.android.operations.RenameFileOperation;
|
import com.owncloud.android.operations.RenameFileOperation;
|
||||||
import com.owncloud.android.operations.SynchronizeFileOperation;
|
import com.owncloud.android.operations.SynchronizeFileOperation;
|
||||||
|
@ -117,9 +115,7 @@ public class OperationsService extends Service {
|
||||||
public static final String ACTION_UPDATE_SHARE = "UPDATE_SHARE";
|
public static final String ACTION_UPDATE_SHARE = "UPDATE_SHARE";
|
||||||
public static final String ACTION_UPDATE_SHARE_NOTE = "UPDATE_SHARE_NOTE";
|
public static final String ACTION_UPDATE_SHARE_NOTE = "UPDATE_SHARE_NOTE";
|
||||||
public static final String ACTION_GET_SERVER_INFO = "GET_SERVER_INFO";
|
public static final String ACTION_GET_SERVER_INFO = "GET_SERVER_INFO";
|
||||||
public static final String ACTION_OAUTH2_GET_ACCESS_TOKEN = "OAUTH2_GET_ACCESS_TOKEN";
|
|
||||||
public static final String ACTION_GET_USER_NAME = "GET_USER_NAME";
|
public static final String ACTION_GET_USER_NAME = "GET_USER_NAME";
|
||||||
public static final String ACTION_GET_USER_AVATAR = "GET_USER_AVATAR";
|
|
||||||
public static final String ACTION_RENAME = "RENAME";
|
public static final String ACTION_RENAME = "RENAME";
|
||||||
public static final String ACTION_REMOVE = "REMOVE";
|
public static final String ACTION_REMOVE = "REMOVE";
|
||||||
public static final String ACTION_CREATE_FOLDER = "CREATE_FOLDER";
|
public static final String ACTION_CREATE_FOLDER = "CREATE_FOLDER";
|
||||||
|
@ -640,13 +636,6 @@ public class OperationsService extends Service {
|
||||||
operation = new GetServerInfoOperation(serverUrl, this);
|
operation = new GetServerInfoOperation(serverUrl, this);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTION_OAUTH2_GET_ACCESS_TOKEN:
|
|
||||||
String oauth2QueryParameters = operationIntent.getStringExtra(EXTRA_OAUTH2_QUERY_PARAMETERS);
|
|
||||||
operation = new OAuth2GetAccessToken(getString(R.string.oauth2_client_id),
|
|
||||||
getString(R.string.oauth2_redirect_uri), getString(R.string.oauth2_grant_type),
|
|
||||||
oauth2QueryParameters);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACTION_GET_USER_NAME:
|
case ACTION_GET_USER_NAME:
|
||||||
operation = new GetRemoteUserInfoOperation();
|
operation = new GetRemoteUserInfoOperation();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -605,11 +605,6 @@ public abstract class FileActivity extends DrawerActivity
|
||||||
dialog.show(getSupportFragmentManager(), DIALOG_CERT_NOT_SAVED);
|
dialog.show(getSupportFragmentManager(), DIALOG_CERT_NOT_SAVED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCancelCertificate() {
|
|
||||||
// nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkForNewDevVersionNecessary(View view, Context context) {
|
public void checkForNewDevVersionNecessary(View view, Context context) {
|
||||||
if (getResources().getBoolean(R.bool.dev_version_direct_download_enabled)) {
|
if (getResources().getBoolean(R.bool.dev_version_direct_download_enabled)) {
|
||||||
ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(getContentResolver());
|
ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(getContentResolver());
|
||||||
|
|
|
@ -1,269 +0,0 @@
|
||||||
/**
|
|
||||||
* ownCloud Android client application
|
|
||||||
*
|
|
||||||
* @author Maria Asensio
|
|
||||||
* @author David A. Velasco
|
|
||||||
* Copyright (C) 2015 ownCloud Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2,
|
|
||||||
* as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.owncloud.android.ui.dialog;
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.Dialog;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.webkit.CookieManager;
|
|
||||||
import android.webkit.CookieSyncManager;
|
|
||||||
import android.webkit.WebSettings;
|
|
||||||
import android.webkit.WebView;
|
|
||||||
import android.widget.RelativeLayout;
|
|
||||||
|
|
||||||
import com.owncloud.android.MainApp;
|
|
||||||
import com.owncloud.android.R;
|
|
||||||
import com.owncloud.android.authentication.SsoWebViewClient;
|
|
||||||
import com.owncloud.android.authentication.SsoWebViewClient.SsoWebViewClientListener;
|
|
||||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
|
||||||
|
|
||||||
import androidx.fragment.app.DialogFragment;
|
|
||||||
import androidx.fragment.app.FragmentManager;
|
|
||||||
import androidx.fragment.app.FragmentTransaction;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dialog to show the WebView for SAML Authentication
|
|
||||||
*/
|
|
||||||
public class SamlWebViewDialog extends DialogFragment {
|
|
||||||
|
|
||||||
private final static String TAG = SamlWebViewDialog.class.getSimpleName();
|
|
||||||
|
|
||||||
private static final String ARG_INITIAL_URL = "INITIAL_URL";
|
|
||||||
private static final String ARG_TARGET_URL = "TARGET_URL";
|
|
||||||
|
|
||||||
private WebView mSsoWebView;
|
|
||||||
private SsoWebViewClient mWebViewClient;
|
|
||||||
|
|
||||||
private String mInitialUrl;
|
|
||||||
private String mTargetUrl;
|
|
||||||
|
|
||||||
private SsoWebViewClientListener mSsoWebViewClientListener;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Public factory method to get dialog instances.
|
|
||||||
*
|
|
||||||
* @param url Url to open at WebView
|
|
||||||
* @param targetUrl mBaseUrl + AccountUtils.getWebdavPath(mDiscoveredVersion, m
|
|
||||||
* CurrentAuthTokenType)
|
|
||||||
* @return New dialog instance, ready to show.
|
|
||||||
*/
|
|
||||||
public static SamlWebViewDialog newInstance(String url, String targetUrl) {
|
|
||||||
SamlWebViewDialog fragment = new SamlWebViewDialog();
|
|
||||||
Bundle args = new Bundle();
|
|
||||||
args.putString(ARG_INITIAL_URL, url);
|
|
||||||
args.putString(ARG_TARGET_URL, targetUrl);
|
|
||||||
fragment.setArguments(args);
|
|
||||||
return fragment;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAttach(Activity activity) {
|
|
||||||
Log_OC.v(TAG, "onAttach");
|
|
||||||
super.onAttach(activity);
|
|
||||||
try {
|
|
||||||
mSsoWebViewClientListener = (SsoWebViewClientListener) activity;
|
|
||||||
Handler mHandler = new Handler();
|
|
||||||
mWebViewClient = new SsoWebViewClient(activity, mHandler, mSsoWebViewClientListener);
|
|
||||||
|
|
||||||
} catch (ClassCastException e) {
|
|
||||||
throw new IllegalArgumentException(activity.toString() + " must implement " +
|
|
||||||
SsoWebViewClientListener.class.getSimpleName(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@SuppressLint("SetJavaScriptEnabled")
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
Log_OC.v(TAG, "onCreate, savedInstanceState is " + savedInstanceState);
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
setRetainInstance(true);
|
|
||||||
|
|
||||||
CookieSyncManager.createInstance(getActivity().getApplicationContext());
|
|
||||||
|
|
||||||
if (savedInstanceState == null) {
|
|
||||||
mInitialUrl = getArguments().getString(ARG_INITIAL_URL);
|
|
||||||
mTargetUrl = getArguments().getString(ARG_TARGET_URL);
|
|
||||||
} else {
|
|
||||||
mInitialUrl = savedInstanceState.getString(ARG_INITIAL_URL);
|
|
||||||
mTargetUrl = savedInstanceState.getString(ARG_TARGET_URL);
|
|
||||||
}
|
|
||||||
|
|
||||||
setStyle(DialogFragment.STYLE_NO_TITLE, R.style.Theme_ownCloud_Dialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
@SuppressLint("SetJavaScriptEnabled")
|
|
||||||
@Override
|
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
|
||||||
Bundle savedInstanceState) {
|
|
||||||
Log_OC.v(TAG, "onCreateView, savedInsanceState is " + savedInstanceState);
|
|
||||||
|
|
||||||
// Inflate layout of the dialog
|
|
||||||
RelativeLayout ssoRootView = (RelativeLayout) inflater.inflate(R.layout.sso_dialog,
|
|
||||||
container, false); // null parent view because it will go in the dialog layout
|
|
||||||
|
|
||||||
if (mSsoWebView == null) {
|
|
||||||
// initialize the WebView
|
|
||||||
mSsoWebView = new SsoWebView(getActivity().getApplicationContext());
|
|
||||||
mSsoWebView.setFocusable(true);
|
|
||||||
mSsoWebView.setFocusableInTouchMode(true);
|
|
||||||
mSsoWebView.setClickable(true);
|
|
||||||
|
|
||||||
WebSettings webSettings = mSsoWebView.getSettings();
|
|
||||||
webSettings.setJavaScriptEnabled(true);
|
|
||||||
webSettings.setDomStorageEnabled(true);
|
|
||||||
webSettings.setSavePassword(false);
|
|
||||||
webSettings.setUserAgentString(MainApp.getUserAgent());
|
|
||||||
webSettings.setSaveFormData(false);
|
|
||||||
// next two settings grant that non-responsive webs are zoomed out when loaded
|
|
||||||
webSettings.setUseWideViewPort(true);
|
|
||||||
webSettings.setLoadWithOverviewMode(true);
|
|
||||||
// next three settings allow the user use pinch gesture to zoom in / out
|
|
||||||
webSettings.setSupportZoom(true);
|
|
||||||
webSettings.setBuiltInZoomControls(true);
|
|
||||||
webSettings.setDisplayZoomControls(false);
|
|
||||||
webSettings.setAllowFileAccess(false);
|
|
||||||
|
|
||||||
CookieManager cookieManager = CookieManager.getInstance();
|
|
||||||
cookieManager.setAcceptCookie(true);
|
|
||||||
cookieManager.removeAllCookie();
|
|
||||||
|
|
||||||
mSsoWebView.loadUrl(mInitialUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
mWebViewClient.setTargetUrl(mTargetUrl);
|
|
||||||
mSsoWebView.setWebViewClient(mWebViewClient);
|
|
||||||
|
|
||||||
// add the webview into the layout
|
|
||||||
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
|
|
||||||
RelativeLayout.LayoutParams.MATCH_PARENT,
|
|
||||||
RelativeLayout.LayoutParams.MATCH_PARENT
|
|
||||||
);
|
|
||||||
ssoRootView.addView(mSsoWebView, layoutParams);
|
|
||||||
ssoRootView.requestLayout();
|
|
||||||
|
|
||||||
return ssoRootView;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
|
||||||
Log_OC.v(TAG, "onSaveInstanceState being CALLED");
|
|
||||||
super.onSaveInstanceState(outState);
|
|
||||||
|
|
||||||
// save URLs
|
|
||||||
outState.putString(ARG_INITIAL_URL, mInitialUrl);
|
|
||||||
outState.putString(ARG_TARGET_URL, mTargetUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroyView() {
|
|
||||||
Log_OC.v(TAG, "onDestroyView");
|
|
||||||
|
|
||||||
if (mSsoWebView.getParent() != null) {
|
|
||||||
((ViewGroup)mSsoWebView.getParent()).removeView(mSsoWebView);
|
|
||||||
}
|
|
||||||
|
|
||||||
mSsoWebView.setWebViewClient(null);
|
|
||||||
|
|
||||||
// Work around bug: http://code.google.com/p/android/issues/detail?id=17423
|
|
||||||
Dialog dialog = getDialog();
|
|
||||||
if (dialog != null) {
|
|
||||||
dialog.setOnDismissListener(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
super.onDestroyView();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
Log_OC.v(TAG, "onDestroy");
|
|
||||||
super.onDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDetach() {
|
|
||||||
Log_OC.v(TAG, "onDetach");
|
|
||||||
mSsoWebViewClientListener = null;
|
|
||||||
mWebViewClient = null;
|
|
||||||
super.onDetach();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCancel (DialogInterface dialog) {
|
|
||||||
Log_OC.d(TAG, "onCancel");
|
|
||||||
super.onCancel(dialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDismiss (DialogInterface dialog) {
|
|
||||||
Log_OC.d(TAG, "onDismiss");
|
|
||||||
super.onDismiss(dialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
Log_OC.v(TAG, "onStart");
|
|
||||||
super.onStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStop() {
|
|
||||||
Log_OC.v(TAG, "onStop");
|
|
||||||
super.onStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
Log_OC.v(TAG, "onResume");
|
|
||||||
super.onResume();
|
|
||||||
mSsoWebView.onResume();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPause() {
|
|
||||||
Log_OC.v(TAG, "onPause");
|
|
||||||
mSsoWebView.onPause();
|
|
||||||
super.onPause();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int show (FragmentTransaction transaction, String tag) {
|
|
||||||
Log_OC.v(TAG, "show (transaction)");
|
|
||||||
return super.show(transaction, tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void show (FragmentManager manager, String tag) {
|
|
||||||
Log_OC.v(TAG, "show (manager)");
|
|
||||||
super.show(manager, tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -256,8 +256,7 @@ public class SetupEncryptionDialogFragment extends DialogFragment {
|
||||||
// get user id
|
// get user id
|
||||||
String userID;
|
String userID;
|
||||||
GetRemoteUserInfoOperation remoteUserNameOperation = new GetRemoteUserInfoOperation();
|
GetRemoteUserInfoOperation remoteUserNameOperation = new GetRemoteUserInfoOperation();
|
||||||
RemoteOperationResult remoteUserNameOperationResult = remoteUserNameOperation.execute(account,
|
RemoteOperationResult remoteUserNameOperationResult = remoteUserNameOperation.execute(account, getContext());
|
||||||
getContext(), true);
|
|
||||||
|
|
||||||
if (remoteUserNameOperationResult.isSuccess() && remoteUserNameOperationResult.getData() != null) {
|
if (remoteUserNameOperationResult.isSuccess() && remoteUserNameOperationResult.getData() != null) {
|
||||||
UserInfo userInfo = (UserInfo) remoteUserNameOperationResult.getData().get(0);
|
UserInfo userInfo = (UserInfo) remoteUserNameOperationResult.getData().get(0);
|
||||||
|
@ -267,7 +266,7 @@ public class SetupEncryptionDialogFragment extends DialogFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
GetPublicKeyOperation publicKeyOperation = new GetPublicKeyOperation(userID);
|
GetPublicKeyOperation publicKeyOperation = new GetPublicKeyOperation(userID);
|
||||||
RemoteOperationResult publicKeyResult = publicKeyOperation.execute(account, getContext(), true);
|
RemoteOperationResult publicKeyResult = publicKeyOperation.execute(account, getContext());
|
||||||
|
|
||||||
if (publicKeyResult.isSuccess()) {
|
if (publicKeyResult.isSuccess()) {
|
||||||
Log_OC.d(TAG, "public key successful downloaded for " + account.name);
|
Log_OC.d(TAG, "public key successful downloaded for " + account.name);
|
||||||
|
@ -280,7 +279,7 @@ public class SetupEncryptionDialogFragment extends DialogFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
GetPrivateKeyOperation privateKeyOperation = new GetPrivateKeyOperation();
|
GetPrivateKeyOperation privateKeyOperation = new GetPrivateKeyOperation();
|
||||||
RemoteOperationResult privateKeyResult = privateKeyOperation.execute(account, getContext(), true);
|
RemoteOperationResult privateKeyResult = privateKeyOperation.execute(account, getContext());
|
||||||
|
|
||||||
if (privateKeyResult.isSuccess()) {
|
if (privateKeyResult.isSuccess()) {
|
||||||
Log_OC.d(TAG, "private key successful downloaded for " + account.name);
|
Log_OC.d(TAG, "private key successful downloaded for " + account.name);
|
||||||
|
@ -351,8 +350,8 @@ public class SetupEncryptionDialogFragment extends DialogFragment {
|
||||||
// get user id
|
// get user id
|
||||||
String userID;
|
String userID;
|
||||||
GetRemoteUserInfoOperation remoteUserNameOperation = new GetRemoteUserInfoOperation();
|
GetRemoteUserInfoOperation remoteUserNameOperation = new GetRemoteUserInfoOperation();
|
||||||
RemoteOperationResult remoteUserNameOperationResult = remoteUserNameOperation
|
RemoteOperationResult remoteUserNameOperationResult = remoteUserNameOperation.execute(account,
|
||||||
.execute(account, getContext(), true);
|
getContext());
|
||||||
|
|
||||||
if (remoteUserNameOperationResult.isSuccess() &&
|
if (remoteUserNameOperationResult.isSuccess() &&
|
||||||
remoteUserNameOperationResult.getData() != null) {
|
remoteUserNameOperationResult.getData() != null) {
|
||||||
|
@ -366,7 +365,7 @@ public class SetupEncryptionDialogFragment extends DialogFragment {
|
||||||
String urlEncoded = CsrHelper.generateCsrPemEncodedString(keyPair, userID);
|
String urlEncoded = CsrHelper.generateCsrPemEncodedString(keyPair, userID);
|
||||||
|
|
||||||
SendCSROperation operation = new SendCSROperation(urlEncoded);
|
SendCSROperation operation = new SendCSROperation(urlEncoded);
|
||||||
RemoteOperationResult result = operation.execute(account, getContext(), true);
|
RemoteOperationResult result = operation.execute(account, getContext());
|
||||||
|
|
||||||
if (result.isSuccess()) {
|
if (result.isSuccess()) {
|
||||||
Log_OC.d(TAG, "public key success");
|
Log_OC.d(TAG, "public key success");
|
||||||
|
@ -384,8 +383,7 @@ public class SetupEncryptionDialogFragment extends DialogFragment {
|
||||||
|
|
||||||
// upload encryptedPrivateKey
|
// upload encryptedPrivateKey
|
||||||
StorePrivateKeyOperation storePrivateKeyOperation = new StorePrivateKeyOperation(encryptedPrivateKey);
|
StorePrivateKeyOperation storePrivateKeyOperation = new StorePrivateKeyOperation(encryptedPrivateKey);
|
||||||
RemoteOperationResult storePrivateKeyResult = storePrivateKeyOperation.execute(account, getContext(),
|
RemoteOperationResult storePrivateKeyResult = storePrivateKeyOperation.execute(account, getContext());
|
||||||
true);
|
|
||||||
|
|
||||||
if (storePrivateKeyResult.isSuccess()) {
|
if (storePrivateKeyResult.isSuccess()) {
|
||||||
Log_OC.d(TAG, "private key success");
|
Log_OC.d(TAG, "private key success");
|
||||||
|
@ -400,7 +398,7 @@ public class SetupEncryptionDialogFragment extends DialogFragment {
|
||||||
return (String) storePrivateKeyResult.getData().get(0);
|
return (String) storePrivateKeyResult.getData().get(0);
|
||||||
} else {
|
} else {
|
||||||
DeletePublicKeyOperation deletePublicKeyOperation = new DeletePublicKeyOperation();
|
DeletePublicKeyOperation deletePublicKeyOperation = new DeletePublicKeyOperation();
|
||||||
deletePublicKeyOperation.execute(account, getContext(), true);
|
deletePublicKeyOperation.execute(account, getContext());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log_OC.e(TAG, e.getMessage());
|
Log_OC.e(TAG, e.getMessage());
|
||||||
|
|
|
@ -194,7 +194,6 @@ public class SslUntrustedCertDialog extends DialogFragment {
|
||||||
if (mHandler != null) {
|
if (mHandler != null) {
|
||||||
mHandler.cancel();
|
mHandler.cancel();
|
||||||
}
|
}
|
||||||
((OnSslUntrustedCertListener)getActivity()).onCancelCertificate();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,8 +225,6 @@ public class SslUntrustedCertDialog extends DialogFragment {
|
||||||
void onSavedCertificate();
|
void onSavedCertificate();
|
||||||
|
|
||||||
void onFailedSavingCertificate();
|
void onFailedSavingCertificate();
|
||||||
|
|
||||||
void onCancelCertificate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface ErrorViewAdapter {
|
public interface ErrorViewAdapter {
|
||||||
|
|
|
@ -1585,7 +1585,7 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
||||||
|
|
||||||
ToggleEncryptionRemoteOperation toggleEncryptionOperation = new ToggleEncryptionRemoteOperation(
|
ToggleEncryptionRemoteOperation toggleEncryptionOperation = new ToggleEncryptionRemoteOperation(
|
||||||
event.localId, event.remotePath, event.shouldBeEncrypted);
|
event.localId, event.remotePath, event.shouldBeEncrypted);
|
||||||
RemoteOperationResult remoteOperationResult = toggleEncryptionOperation.execute(mClient, true);
|
RemoteOperationResult remoteOperationResult = toggleEncryptionOperation.execute(mClient);
|
||||||
|
|
||||||
if (remoteOperationResult.isSuccess()) {
|
if (remoteOperationResult.isSuccess()) {
|
||||||
mAdapter.setEncryptionAttributeForItemID(event.remoteId, event.shouldBeEncrypted);
|
mAdapter.setEncryptionAttributeForItemID(event.remoteId, event.shouldBeEncrypted);
|
||||||
|
|
|
@ -219,7 +219,7 @@ public final class EncryptionUtils {
|
||||||
DecryptedFolderMetadata downloadFolderMetadata(OCFile folder, OwnCloudClient client,
|
DecryptedFolderMetadata downloadFolderMetadata(OCFile folder, OwnCloudClient client,
|
||||||
Context context, Account account) {
|
Context context, Account account) {
|
||||||
RemoteOperationResult getMetadataOperationResult = new GetMetadataRemoteOperation(folder.getLocalId())
|
RemoteOperationResult getMetadataOperationResult = new GetMetadataRemoteOperation(folder.getLocalId())
|
||||||
.execute(client, true);
|
.execute(client);
|
||||||
|
|
||||||
if (!getMetadataOperationResult.isSuccess()) {
|
if (!getMetadataOperationResult.isSuccess()) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -158,62 +158,6 @@
|
||||||
android:minHeight="@dimen/display_text_min_height"
|
android:minHeight="@dimen/display_text_min_height"
|
||||||
android:contentDescription="@string/auth_testing_connection"/>
|
android:contentDescription="@string/auth_testing_connection"/>
|
||||||
|
|
||||||
<CheckBox
|
|
||||||
android:id="@+id/oauth_onOff_check"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:checked="false"
|
|
||||||
android:onClick="onCheckClick"
|
|
||||||
android:text="@string/oauth_check_onoff"
|
|
||||||
android:textColor="@color/primary"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
|
||||||
android:contentDescription="@string/oauth_check_onoff"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
|
||||||
android:id="@+id/input_layout_oAuthEntryPoint_1"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
|
||||||
android:id="@+id/oAuthEntryPoint_1"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ems="10"
|
|
||||||
android:enabled="false"
|
|
||||||
android:hint="@string/oauth_2_0_auth_end_point_address_hint"
|
|
||||||
android:inputType="textUri"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:text="@string/oauth2_url_endpoint_auth"
|
|
||||||
android:textColor="@color/login_text_color"
|
|
||||||
android:textColorHint="@color/login_text_hint_color"
|
|
||||||
android:importantForAutofill="no"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
|
||||||
android:id="@+id/input_layout_oAuthEntryPoint_2"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
|
||||||
android:id="@+id/oAuthEntryPoint_2"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ems="10"
|
|
||||||
android:enabled="false"
|
|
||||||
android:hint="@string/oauth_2_0_access_end_point_address_hint"
|
|
||||||
android:inputType="textUri"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:text="@string/oauth2_url_endpoint_access"
|
|
||||||
android:textColor="@color/login_text_color"
|
|
||||||
android:textColorHint="@color/login_text_hint_color"
|
|
||||||
android:importantForAutofill="no"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/input_layout_account_username"
|
android:id="@+id/input_layout_account_username"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -151,62 +151,6 @@
|
||||||
android:minHeight="@dimen/display_text_min_height"
|
android:minHeight="@dimen/display_text_min_height"
|
||||||
android:contentDescription="@string/auth_testing_connection"/>
|
android:contentDescription="@string/auth_testing_connection"/>
|
||||||
|
|
||||||
<CheckBox
|
|
||||||
android:id="@+id/oauth_onOff_check"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:checked="false"
|
|
||||||
android:onClick="onCheckClick"
|
|
||||||
android:text="@string/oauth_check_onoff"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
|
||||||
android:textColor="@color/login_text_hint_color"
|
|
||||||
android:contentDescription="@string/oauth_check_onoff"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
|
||||||
android:id="@+id/input_layout_oAuthEntryPoint_1"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
|
||||||
android:id="@+id/oAuthEntryPoint_1"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ems="10"
|
|
||||||
android:enabled="false"
|
|
||||||
android:hint="@string/oauth_2_0_auth_end_point_address_hint"
|
|
||||||
android:inputType="textUri"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:text="@string/oauth2_url_endpoint_auth"
|
|
||||||
android:textColor="@color/login_text_color"
|
|
||||||
android:textColorHint="@color/login_text_hint_color"
|
|
||||||
android:visibility="gone"
|
|
||||||
android:importantForAutofill="no"/>
|
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
|
||||||
android:id="@+id/input_layout_oAuthEntryPoint_2"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
|
||||||
android:id="@+id/oAuthEntryPoint_2"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ems="10"
|
|
||||||
android:enabled="false"
|
|
||||||
android:hint="@string/oauth_2_0_access_end_point_address_hint"
|
|
||||||
android:inputType="textUri"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:text="@string/oauth2_url_endpoint_access"
|
|
||||||
android:textColor="@color/login_text_color"
|
|
||||||
android:textColorHint="@color/login_text_hint_color"
|
|
||||||
android:importantForAutofill="no"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/input_layout_account_username"
|
android:id="@+id/input_layout_account_username"
|
||||||
android:theme="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
android:theme="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
ownCloud Android client application
|
|
||||||
|
|
||||||
Copyright (C) 2015 ownCloud Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License version 2,
|
|
||||||
as published by the Free Software Foundation.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
-->
|
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
|
@ -1,16 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<!-- constants that must be respected by the authorization server; if changed, the app must be rebuild -->
|
|
||||||
<string name="oauth2_redirect_scheme">owncloud</string>
|
|
||||||
<string name="oauth2_redirect_uri">owncloud://callback</string>
|
|
||||||
|
|
||||||
<!-- values that should be provided by ownCloud server -->
|
|
||||||
<string name="oauth2_url_endpoint_auth">http://oauth2.authorization.server.org/path/to/endpoint/for/authorization</string>
|
|
||||||
<string name="oauth2_url_endpoint_access">http://oauth2.authorization.server.org/path/to/endpoint/for/access/token</string>
|
|
||||||
<string name="oauth2_scope">owncloud</string>
|
|
||||||
<string name="oauth2_grant_type">authorization_code</string> <!-- the only one supported right now -->
|
|
||||||
<string name="oauth2_response_type">code</string> <!-- depends on oauth2_grant_type -->
|
|
||||||
|
|
||||||
<!-- values that should be pre-agreed between app and authorization server, but can be loaded without rebuilding the app -->
|
|
||||||
<string name="oauth2_client_id">com.owncloud.android</string> <!-- preferable that client decides this -->
|
|
||||||
</resources>
|
|
|
@ -30,10 +30,6 @@
|
||||||
<bool name="show_provider_or_own_installation">true</bool>
|
<bool name="show_provider_or_own_installation">true</bool>
|
||||||
<string name="provider_registration_server">https://www.nextcloud.com/register</string>
|
<string name="provider_registration_server">https://www.nextcloud.com/register</string>
|
||||||
|
|
||||||
<!-- Flags to setup the authentication methods available in the app -->
|
|
||||||
<string name="auth_method_oauth2">off</string>
|
|
||||||
<string name="auth_method_saml_web_sso">off</string>
|
|
||||||
|
|
||||||
<!-- Flags to enable/disable some features -->
|
<!-- Flags to enable/disable some features -->
|
||||||
<string name="send_files_to_other_apps">on</string>
|
<string name="send_files_to_other_apps">on</string>
|
||||||
<bool name="share_via_link_feature">true</bool>
|
<bool name="share_via_link_feature">true</bool>
|
||||||
|
|
|
@ -232,7 +232,6 @@
|
||||||
<string name="media_play_pause_description">Play or pause button</string>
|
<string name="media_play_pause_description">Play or pause button</string>
|
||||||
<string name="media_forward_description">Fast forward button</string>
|
<string name="media_forward_description">Fast forward button</string>
|
||||||
|
|
||||||
<string name="auth_getting_authorization">Getting authorization…</string>
|
|
||||||
<string name="auth_trying_to_login">Trying to log in…</string>
|
<string name="auth_trying_to_login">Trying to log in…</string>
|
||||||
<string name="auth_no_net_conn_title">No network connection</string>
|
<string name="auth_no_net_conn_title">No network connection</string>
|
||||||
<string name="auth_nossl_plain_ok_title">Secure connection unavailable.</string>
|
<string name="auth_nossl_plain_ok_title">Secure connection unavailable.</string>
|
||||||
|
@ -257,10 +256,7 @@
|
||||||
<string name="auth_oauth_error">Unsuccessful authorization</string>
|
<string name="auth_oauth_error">Unsuccessful authorization</string>
|
||||||
<string name="auth_oauth_error_access_denied">Access denied by authorization server</string>
|
<string name="auth_oauth_error_access_denied">Access denied by authorization server</string>
|
||||||
<string name="auth_wtf_reenter_URL">Unexpected state, please enter the server address again</string>
|
<string name="auth_wtf_reenter_URL">Unexpected state, please enter the server address again</string>
|
||||||
<string name="auth_expired_oauth_token_toast">Your authorization expired. Please, authorize again</string>
|
|
||||||
<string name="auth_expired_basic_auth_toast">Please enter the current password</string>
|
<string name="auth_expired_basic_auth_toast">Please enter the current password</string>
|
||||||
<string name="auth_expired_saml_sso_token_toast">Your session expired. Please connect again</string>
|
|
||||||
<string name="auth_connecting_auth_server">Connecting to authentication server…</string>
|
|
||||||
<string name="auth_unsupported_multiaccount">%1$s does not support multiple accounts</string>
|
<string name="auth_unsupported_multiaccount">%1$s does not support multiple accounts</string>
|
||||||
<string name="auth_fail_get_user_name">Your server is not returning a correct user ID, please contact an admin</string>
|
<string name="auth_fail_get_user_name">Your server is not returning a correct user ID, please contact an admin</string>
|
||||||
<string name="auth_can_not_auth_against_server">Cannot authenticate to this server</string>
|
<string name="auth_can_not_auth_against_server">Cannot authenticate to this server</string>
|
||||||
|
@ -292,10 +288,6 @@
|
||||||
<string name="filedisplay_no_file_selected">No file selected</string>
|
<string name="filedisplay_no_file_selected">No file selected</string>
|
||||||
<string name="activity_chooser_title">Send link to…</string>
|
<string name="activity_chooser_title">Send link to…</string>
|
||||||
<string name="wait_for_tmp_copy_from_private_storage">Copying file from private storage</string>
|
<string name="wait_for_tmp_copy_from_private_storage">Copying file from private storage</string>
|
||||||
|
|
||||||
<string name="oauth_check_onoff">Log in with OAuth 2.0</string>
|
|
||||||
<string name="oauth_login_connection">Connecting to OAuth 2.0 server…</string>
|
|
||||||
|
|
||||||
<string name="ssl_validator_header">The identity of the server could not be verified</string>
|
<string name="ssl_validator_header">The identity of the server could not be verified</string>
|
||||||
<string name="ssl_validator_reason_cert_not_trusted">- The server certificate is not trusted</string>
|
<string name="ssl_validator_reason_cert_not_trusted">- The server certificate is not trusted</string>
|
||||||
<string name="ssl_validator_reason_cert_expired">- The server certificate expired</string>
|
<string name="ssl_validator_reason_cert_expired">- The server certificate expired</string>
|
||||||
|
@ -751,8 +743,6 @@
|
||||||
<string name="notification_channel_push_description">Show push notifications sent by the server: Mentions in comments, reception of new remote shares, announcements posted by an admin etc.</string>
|
<string name="notification_channel_push_description">Show push notifications sent by the server: Mentions in comments, reception of new remote shares, announcements posted by an admin etc.</string>
|
||||||
<string name="sendbutton_description">Send button icon</string>
|
<string name="sendbutton_description">Send button icon</string>
|
||||||
|
|
||||||
<string name="oauth_2_0_auth_end_point_address_hint">Auth end point address</string>
|
|
||||||
<string name="oauth_2_0_access_end_point_address_hint">Access end point address</string>
|
|
||||||
<string name="hidden_character" translatable="false">*</string>
|
<string name="hidden_character" translatable="false">*</string>
|
||||||
<string name="hint_name">Name</string>
|
<string name="hint_name">Name</string>
|
||||||
<string name="hint_password">Password</string>
|
<string name="hint_password">Password</string>
|
||||||
|
|
Loading…
Reference in a new issue