From 23a1ea68e0362d8169a15c49e470fb3137692780 Mon Sep 17 00:00:00 2001 From: "David A. Velasco" Date: Wed, 7 Aug 2013 19:13:00 +0200 Subject: [PATCH 1/2] Foreground operations on files (remove, rename, new folder) failed due to SAML SSO session expired redirect the app to the login view for a new authentication --- res/values/strings.xml | 1 + .../authentication/AuthenticatorActivity.java | 14 +++++++-- .../android/files/services/FileUploader.java | 2 +- .../android/network/OwnCloudClientUtils.java | 18 ++++++++---- .../ChunkedUploadFileOperation.java | 3 ++ .../operations/CreateFolderOperation.java | 2 +- .../operations/DownloadFileOperation.java | 17 ++++++----- .../operations/OAuth2GetAccessToken.java | 4 +-- .../OwnCloudServerCheckOperation.java | 2 +- .../android/operations/RemoteOperation.java | 29 ++++++++++++------- .../operations/RemoteOperationResult.java | 2 +- .../operations/RemoveFileOperation.java | 2 +- .../operations/RenameFileOperation.java | 2 +- .../operations/SynchronizeFileOperation.java | 2 +- .../SynchronizeFolderOperation.java | 4 +-- .../operations/UpdateOCVersionOperation.java | 2 +- .../operations/UploadFileOperation.java | 2 +- src/eu/alefzero/webdav/WebdavClient.java | 4 +++ 18 files changed, 73 insertions(+), 39 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index f07198267c..648e54834f 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -211,6 +211,7 @@ Unexpected state; please, enter the server URL again Your authorization expired.\nPlease, authorize again Please, enter the current password + Your session expired.\nPlease, authenticate again Connecting to authentication server… Follow instructions above to get authenticated The server does not support this authentication method diff --git a/src/com/owncloud/android/authentication/AuthenticatorActivity.java b/src/com/owncloud/android/authentication/AuthenticatorActivity.java index 0e8ba48cc2..a21205ae61 100644 --- a/src/com/owncloud/android/authentication/AuthenticatorActivity.java +++ b/src/com/owncloud/android/authentication/AuthenticatorActivity.java @@ -229,6 +229,9 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList } mHostBaseUrl = normalizeUrl(mAccountMgr.getUserData(mAccount, AccountAuthenticator.KEY_OC_BASE_URL)); mHostUrlInput.setText(mHostBaseUrl); + String userName = mAccount.name.substring(0, mAccount.name.lastIndexOf('@')); + mUsernameInput.setText(userName); + mAccountNameInput.setText(userName); } initAuthorizationMethod(); // checks intent and setup.xml to determine mCurrentAuthorizationMethod mJustCreated = true; @@ -289,6 +292,8 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList mUsernameInput.setEnabled(false); mUsernameInput.setFocusable(false); mOAuth2Check.setVisibility(View.GONE); + mAccountNameInput.setEnabled(false); + mAccountNameInput.setFocusable(false); } //if (mServerIsChecked && !mServerIsValid && mRefreshButtonEnabled) showRefreshButton(); @@ -480,10 +485,15 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList protected void onResume() { super.onResume(); if (mAction == ACTION_UPDATE_TOKEN && mJustCreated && getIntent().getBooleanExtra(EXTRA_ENFORCED_UPDATE, false)) { - if (mOAuth2Check.isChecked()) + if (AccountAuthenticator.AUTH_TOKEN_TYPE_ACCESS_TOKEN.equals(mCurrentAuthTokenType)) { Toast.makeText(this, R.string.auth_expired_oauth_token_toast, Toast.LENGTH_LONG).show(); - else + + } else if (AccountAuthenticator.AUTH_TOKEN_TYPE_SAML_WEB_SSO_SESSION_COOKIE.equals(mCurrentAuthTokenType)) { + Toast.makeText(this, R.string.auth_expired_saml_sso_token_toast, Toast.LENGTH_LONG).show(); + + } else { Toast.makeText(this, R.string.auth_expired_basic_auth_toast, Toast.LENGTH_LONG).show(); + } } if (mNewCapturedUriFromOAuth2Redirection != null) { diff --git a/src/com/owncloud/android/files/services/FileUploader.java b/src/com/owncloud/android/files/services/FileUploader.java index e9f445a0c9..96c7fdcfbf 100644 --- a/src/com/owncloud/android/files/services/FileUploader.java +++ b/src/com/owncloud/android/files/services/FileUploader.java @@ -579,7 +579,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe mUploadClient.exhaustResponse(propfind.getResponseBodyAsStream()); } - result = new RemoteOperationResult(isMultiStatus, status); + result = new RemoteOperationResult(isMultiStatus, status, propfind.getResponseHeaders()); Log_OC.i(TAG, "Update: synchronizing properties for uploaded " + mCurrentUpload.getRemotePath() + ": " + result.getLogMessage()); diff --git a/src/com/owncloud/android/network/OwnCloudClientUtils.java b/src/com/owncloud/android/network/OwnCloudClientUtils.java index 17abf6f836..75aed4ac45 100644 --- a/src/com/owncloud/android/network/OwnCloudClientUtils.java +++ b/src/com/owncloud/android/network/OwnCloudClientUtils.java @@ -32,6 +32,7 @@ import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; +import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.protocol.Protocol; import org.apache.http.conn.ssl.BrowserCompatHostnameVerifier; import org.apache.http.conn.ssl.X509HostnameVerifier; @@ -90,13 +91,15 @@ public class OwnCloudClientUtils { //Log_OC.d(TAG, "Creating WebdavClient associated to " + account.name); Uri uri = Uri.parse(AccountUtils.constructFullURLForAccount(appContext, account)); - WebdavClient client = createOwnCloudClient(uri, appContext, true); AccountManager am = AccountManager.get(appContext); - if (am.getUserData(account, AccountAuthenticator.KEY_SUPPORTS_OAUTH2) != null) { // TODO avoid a call to getUserData here + boolean isOauth2 = am.getUserData(account, AccountAuthenticator.KEY_SUPPORTS_OAUTH2) != null; // TODO avoid calling to getUserData here + boolean isSamlSso = am.getUserData(account, AccountAuthenticator.KEY_SUPPORTS_SAML_WEB_SSO) != null; + WebdavClient client = createOwnCloudClient(uri, appContext, !isSamlSso); + if (isOauth2) { String accessToken = am.blockingGetAuthToken(account, AccountAuthenticator.AUTH_TOKEN_TYPE_ACCESS_TOKEN, false); client.setBearerCredentials(accessToken); // TODO not assume that the access token is a bearer token - } else if (am.getUserData(account, AccountAuthenticator.KEY_SUPPORTS_SAML_WEB_SSO) != null) { // TODO avoid a call to getUserData here + } else if (isSamlSso) { // TODO avoid a call to getUserData here String accessToken = am.blockingGetAuthToken(account, AccountAuthenticator.AUTH_TOKEN_TYPE_SAML_WEB_SSO_SESSION_COOKIE, false); client.setSsoSessionCookie(accessToken); @@ -113,16 +116,19 @@ public class OwnCloudClientUtils { public static WebdavClient createOwnCloudClient (Account account, Context appContext, Activity currentActivity) throws OperationCanceledException, AuthenticatorException, IOException, AccountNotFoundException { Uri uri = Uri.parse(AccountUtils.constructFullURLForAccount(appContext, account)); - WebdavClient client = createOwnCloudClient(uri, appContext, true); AccountManager am = AccountManager.get(appContext); - if (am.getUserData(account, AccountAuthenticator.KEY_SUPPORTS_OAUTH2) != null) { // TODO avoid a call to getUserData here + boolean isOauth2 = am.getUserData(account, AccountAuthenticator.KEY_SUPPORTS_OAUTH2) != null; // TODO avoid calling to getUserData here + boolean isSamlSso = am.getUserData(account, AccountAuthenticator.KEY_SUPPORTS_SAML_WEB_SSO) != null; + WebdavClient client = createOwnCloudClient(uri, appContext, !isSamlSso); + + if (isOauth2) { // TODO avoid a call to getUserData here AccountManagerFuture future = am.getAuthToken(account, AccountAuthenticator.AUTH_TOKEN_TYPE_ACCESS_TOKEN, null, currentActivity, null, null); Bundle result = future.getResult(); String accessToken = result.getString(AccountManager.KEY_AUTHTOKEN); if (accessToken == null) throw new AuthenticatorException("WTF!"); client.setBearerCredentials(accessToken); // TODO not assume that the access token is a bearer token - } else if (am.getUserData(account, AccountAuthenticator.KEY_SUPPORTS_SAML_WEB_SSO) != null) { // TODO avoid a call to getUserData here + } else if (isSamlSso) { // TODO avoid a call to getUserData here AccountManagerFuture future = am.getAuthToken(account, AccountAuthenticator.AUTH_TOKEN_TYPE_SAML_WEB_SSO_SESSION_COOKIE, null, currentActivity, null, null); Bundle result = future.getResult(); String accessToken = result.getString(AccountManager.KEY_AUTHTOKEN); diff --git a/src/com/owncloud/android/operations/ChunkedUploadFileOperation.java b/src/com/owncloud/android/operations/ChunkedUploadFileOperation.java index 697c154ed7..02e1ad04a2 100644 --- a/src/com/owncloud/android/operations/ChunkedUploadFileOperation.java +++ b/src/com/owncloud/android/operations/ChunkedUploadFileOperation.java @@ -68,6 +68,9 @@ public class ChunkedUploadFileOperation extends UploadFileOperation { String uriPrefix = client.getBaseUri() + WebdavUtils.encodePath(getRemotePath()) + "-chunking-" + Math.abs((new Random()).nextInt(9000)+1000) + "-" ; long chunkCount = (long) Math.ceil((double)file.length() / CHUNK_SIZE); for (int chunkIndex = 0; chunkIndex < chunkCount ; chunkIndex++, offset += CHUNK_SIZE) { + if (mPutMethod != null) { + mPutMethod.releaseConnection(); // let the connection available for other methods + } mPutMethod = new PutMethod(uriPrefix + chunkCount + "-" + chunkIndex); mPutMethod.addRequestHeader(OC_CHUNKED_HEADER, OC_CHUNKED_HEADER); ((ChunkFromFileChannelRequestEntity)mEntity).setOffset(offset); diff --git a/src/com/owncloud/android/operations/CreateFolderOperation.java b/src/com/owncloud/android/operations/CreateFolderOperation.java index 03c6868c34..1a38cdbff2 100644 --- a/src/com/owncloud/android/operations/CreateFolderOperation.java +++ b/src/com/owncloud/android/operations/CreateFolderOperation.java @@ -77,7 +77,7 @@ public class CreateFolderOperation extends RemoteOperation { mStorageManager.saveFile(newDir); } - result = new RemoteOperationResult(mkcol.succeeded(), status); + result = new RemoteOperationResult(mkcol.succeeded(), status, mkcol.getResponseHeaders()); Log_OC.d(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage()); client.exhaustResponse(mkcol.getResponseBodyAsStream()); diff --git a/src/com/owncloud/android/operations/DownloadFileOperation.java b/src/com/owncloud/android/operations/DownloadFileOperation.java index 5745b973c0..02098b8128 100644 --- a/src/com/owncloud/android/operations/DownloadFileOperation.java +++ b/src/com/owncloud/android/operations/DownloadFileOperation.java @@ -58,6 +58,7 @@ public class DownloadFileOperation extends RemoteOperation { private Set mDataTransferListeners = new HashSet(); private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); private long mModificationTimestamp = 0; + private GetMethod mGet; public DownloadFileOperation(Account account, OCFile file) { @@ -154,7 +155,7 @@ public class DownloadFileOperation extends RemoteOperation { if (!moved) result = new RemoteOperationResult(RemoteOperationResult.ResultCode.LOCAL_STORAGE_NOT_MOVED); else - result = new RemoteOperationResult(isSuccess(status), status); + result = new RemoteOperationResult(isSuccess(status), status, (mGet != null ? mGet.getResponseHeaders() : null)); Log_OC.i(TAG, "Download of " + mFile.getRemotePath() + " to " + getSavePath() + ": " + result.getLogMessage()); } catch (Exception e) { @@ -174,15 +175,15 @@ public class DownloadFileOperation extends RemoteOperation { protected int downloadFile(WebdavClient client, File targetFile) throws HttpException, IOException, OperationCancelledException { int status = -1; boolean savedFile = false; - GetMethod get = new GetMethod(client.getBaseUri() + WebdavUtils.encodePath(mFile.getRemotePath())); + mGet = new GetMethod(client.getBaseUri() + WebdavUtils.encodePath(mFile.getRemotePath())); Iterator it = null; FileOutputStream fos = null; try { - status = client.executeMethod(get); + status = client.executeMethod(mGet); if (isSuccess(status)) { targetFile.createNewFile(); - BufferedInputStream bis = new BufferedInputStream(get.getResponseBodyAsStream()); + BufferedInputStream bis = new BufferedInputStream(mGet.getResponseBodyAsStream()); fos = new FileOutputStream(targetFile); long transferred = 0; @@ -191,7 +192,7 @@ public class DownloadFileOperation extends RemoteOperation { while ((readResult = bis.read(bytes)) != -1) { synchronized(mCancellationRequested) { if (mCancellationRequested.get()) { - get.abort(); + mGet.abort(); throw new OperationCancelledException(); } } @@ -205,14 +206,14 @@ public class DownloadFileOperation extends RemoteOperation { } } savedFile = true; - Header modificationTime = get.getResponseHeader("Last-Modified"); + Header modificationTime = mGet.getResponseHeader("Last-Modified"); if (modificationTime != null) { Date d = WebdavUtils.parseResponseDate((String) modificationTime.getValue()); mModificationTimestamp = (d != null) ? d.getTime() : 0; } } else { - client.exhaustResponse(get.getResponseBodyAsStream()); + client.exhaustResponse(mGet.getResponseBodyAsStream()); } } finally { @@ -220,7 +221,7 @@ public class DownloadFileOperation extends RemoteOperation { if (!savedFile && targetFile.exists()) { targetFile.delete(); } - get.releaseConnection(); // let the connection available for other methods + mGet.releaseConnection(); // let the connection available for other methods } return status; } diff --git a/src/com/owncloud/android/operations/OAuth2GetAccessToken.java b/src/com/owncloud/android/operations/OAuth2GetAccessToken.java index 6d43caf1d1..5d46804169 100644 --- a/src/com/owncloud/android/operations/OAuth2GetAccessToken.java +++ b/src/com/owncloud/android/operations/OAuth2GetAccessToken.java @@ -80,12 +80,12 @@ public class OAuth2GetAccessToken extends RemoteOperation { result = new RemoteOperationResult(ResultCode.OAUTH2_ERROR); } else { - result = new RemoteOperationResult(true, status); + result = new RemoteOperationResult(true, status, postMethod.getResponseHeaders()); } } else { client.exhaustResponse(postMethod.getResponseBodyAsStream()); - result = new RemoteOperationResult(false, status); + result = new RemoteOperationResult(false, status, postMethod.getResponseHeaders()); } } diff --git a/src/com/owncloud/android/operations/OwnCloudServerCheckOperation.java b/src/com/owncloud/android/operations/OwnCloudServerCheckOperation.java index 4982c664b9..d95b30551b 100644 --- a/src/com/owncloud/android/operations/OwnCloudServerCheckOperation.java +++ b/src/com/owncloud/android/operations/OwnCloudServerCheckOperation.java @@ -80,7 +80,7 @@ public class OwnCloudServerCheckOperation extends RemoteOperation { } } else { - mLatestResult = new RemoteOperationResult(false, status); + mLatestResult = new RemoteOperationResult(false, status, get.getResponseHeaders()); } } catch (JSONException e) { diff --git a/src/com/owncloud/android/operations/RemoteOperation.java b/src/com/owncloud/android/operations/RemoteOperation.java index 9afb856fd0..16ecf27f41 100644 --- a/src/com/owncloud/android/operations/RemoteOperation.java +++ b/src/com/owncloud/android/operations/RemoteOperation.java @@ -242,18 +242,27 @@ public abstract class RemoteOperation implements Runnable { result = run(mClient); repeat = false; - if (mCallerActivity != null && mAccount != null && mContext != null && !result.isSuccess() && result.getCode() == ResultCode.UNAUTHORIZED) { - /// fail due to lack of authorization in an operation performed in foreground - AccountManager am = AccountManager.get(mContext); + if (mCallerActivity != null && mAccount != null && mContext != null && !result.isSuccess() && + (result.getCode() == ResultCode.UNAUTHORIZED || result.isTemporalRedirection())) { + /// possible fail due to lack of authorization in an operation performed in foreground Credentials cred = mClient.getCredentials(); - if (cred instanceof BearerCredentials) { - am.invalidateAuthToken(AccountAuthenticator.ACCOUNT_TYPE, ((BearerCredentials)cred).getAccessToken()); - } else { - am.clearPassword(mAccount); + String ssoSessionCookie = mClient.getSsoSessionCookie(); + if (cred != null || ssoSessionCookie != null) { + /// confirmed : unauthorized operation + AccountManager am = AccountManager.get(mContext); + boolean bearerAuthorization = (cred != null && cred instanceof BearerCredentials); + boolean samlBasedSsoAuthorization = (cred == null && ssoSessionCookie != null); + if (bearerAuthorization) { + am.invalidateAuthToken(AccountAuthenticator.ACCOUNT_TYPE, ((BearerCredentials)cred).getAccessToken()); + } else if (samlBasedSsoAuthorization ) { + am.invalidateAuthToken(AccountAuthenticator.ACCOUNT_TYPE, ssoSessionCookie); + } else { + am.clearPassword(mAccount); + } + mClient = null; + repeat = true; // when repeated, the creation of a new OwnCloudClient after erasing the saved credentials will trigger the login activity + result = null; } - mClient = null; - repeat = true; // when repeated, the creation of a new OwnCloudClient after erasing the saved credentials will trigger the login activity - result = null; } } while (repeat); diff --git a/src/com/owncloud/android/operations/RemoteOperationResult.java b/src/com/owncloud/android/operations/RemoteOperationResult.java index cc2ee67f60..0a0b932c79 100644 --- a/src/com/owncloud/android/operations/RemoteOperationResult.java +++ b/src/com/owncloud/android/operations/RemoteOperationResult.java @@ -100,7 +100,7 @@ public class RemoteOperationResult implements Serializable { mSuccess = (code == ResultCode.OK || code == ResultCode.OK_SSL || code == ResultCode.OK_NO_SSL); } - public RemoteOperationResult(boolean success, int httpCode) { + private RemoteOperationResult(boolean success, int httpCode) { mSuccess = success; mHttpCode = httpCode; diff --git a/src/com/owncloud/android/operations/RemoveFileOperation.java b/src/com/owncloud/android/operations/RemoveFileOperation.java index 8348b72f50..9dabfafd56 100644 --- a/src/com/owncloud/android/operations/RemoveFileOperation.java +++ b/src/com/owncloud/android/operations/RemoveFileOperation.java @@ -88,7 +88,7 @@ public class RemoveFileOperation extends RemoteOperation { } } delete.getResponseBodyAsString(); // exhaust the response, although not interesting - result = new RemoteOperationResult((delete.succeeded() || status == HttpStatus.SC_NOT_FOUND), status); + result = new RemoteOperationResult((delete.succeeded() || status == HttpStatus.SC_NOT_FOUND), status, delete.getResponseHeaders()); Log_OC.i(TAG, "Remove " + mFileToRemove.getRemotePath() + ": " + result.getLogMessage()); } catch (Exception e) { diff --git a/src/com/owncloud/android/operations/RenameFileOperation.java b/src/com/owncloud/android/operations/RenameFileOperation.java index 1c636fba5e..fddb84993e 100644 --- a/src/com/owncloud/android/operations/RenameFileOperation.java +++ b/src/com/owncloud/android/operations/RenameFileOperation.java @@ -136,7 +136,7 @@ public class RenameFileOperation extends RemoteOperation { } move.getResponseBodyAsString(); // exhaust response, although not interesting - result = new RemoteOperationResult(move.succeeded(), status); + result = new RemoteOperationResult(move.succeeded(), status, move.getResponseHeaders()); Log_OC.i(TAG, "Rename " + mFile.getRemotePath() + " to " + mNewRemotePath + ": " + result.getLogMessage()); } catch (Exception e) { diff --git a/src/com/owncloud/android/operations/SynchronizeFileOperation.java b/src/com/owncloud/android/operations/SynchronizeFileOperation.java index b0f2ce26f4..5be116bc1d 100644 --- a/src/com/owncloud/android/operations/SynchronizeFileOperation.java +++ b/src/com/owncloud/android/operations/SynchronizeFileOperation.java @@ -101,7 +101,7 @@ public class SynchronizeFileOperation extends RemoteOperation { } else { client.exhaustResponse(propfind.getResponseBodyAsStream()); - result = new RemoteOperationResult(false, status); + result = new RemoteOperationResult(false, status, propfind.getResponseHeaders()); } } diff --git a/src/com/owncloud/android/operations/SynchronizeFolderOperation.java b/src/com/owncloud/android/operations/SynchronizeFolderOperation.java index 3d2c3deb57..0236a139b3 100644 --- a/src/com/owncloud/android/operations/SynchronizeFolderOperation.java +++ b/src/com/owncloud/android/operations/SynchronizeFolderOperation.java @@ -242,10 +242,10 @@ public class SynchronizeFolderOperation extends RemoteOperation { result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT); // should be different result, but will do the job } else { - result = new RemoteOperationResult(true, status); + result = new RemoteOperationResult(true, status, query.getResponseHeaders()); } } else { - result = new RemoteOperationResult(false, status); + result = new RemoteOperationResult(false, status, query.getResponseHeaders()); } diff --git a/src/com/owncloud/android/operations/UpdateOCVersionOperation.java b/src/com/owncloud/android/operations/UpdateOCVersionOperation.java index 1b56bfbbca..1643377b84 100644 --- a/src/com/owncloud/android/operations/UpdateOCVersionOperation.java +++ b/src/com/owncloud/android/operations/UpdateOCVersionOperation.java @@ -65,7 +65,7 @@ public class UpdateOCVersionOperation extends RemoteOperation { int status = client.executeMethod(get); if (status != HttpStatus.SC_OK) { client.exhaustResponse(get.getResponseBodyAsStream()); - result = new RemoteOperationResult(false, status); + result = new RemoteOperationResult(false, status, get.getResponseHeaders()); } else { String response = get.getResponseBodyAsString(); diff --git a/src/com/owncloud/android/operations/UploadFileOperation.java b/src/com/owncloud/android/operations/UploadFileOperation.java index 2c891be946..cae1f17986 100644 --- a/src/com/owncloud/android/operations/UploadFileOperation.java +++ b/src/com/owncloud/android/operations/UploadFileOperation.java @@ -304,7 +304,7 @@ public class UploadFileOperation extends RemoteOperation { } } - result = new RemoteOperationResult(isSuccess(status), status); + result = new RemoteOperationResult(isSuccess(status), status, (mPutMethod != null ? mPutMethod.getResponseHeaders() : null)); } catch (Exception e) { // TODO something cleaner with cancellations diff --git a/src/eu/alefzero/webdav/WebdavClient.java b/src/eu/alefzero/webdav/WebdavClient.java index 570ebb8566..43a6743c76 100644 --- a/src/eu/alefzero/webdav/WebdavClient.java +++ b/src/eu/alefzero/webdav/WebdavClient.java @@ -206,6 +206,10 @@ public class WebdavClient extends HttpClient { public final Credentials getCredentials() { return mCredentials; } + + public final String getSsoSessionCookie() { + return mSsoSessionCookie; + } public void setFollowRedirects(boolean followRedirects) { mFollowRedirects = followRedirects; From 8a2910a0ac2c4cd63d70413e89af047cc91972e1 Mon Sep 17 00:00:00 2001 From: masensio Date: Wed, 14 Aug 2013 09:13:47 +0200 Subject: [PATCH 2/2] Update server-url --- res/values/setup.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values/setup.xml b/res/values/setup.xml index 3e39fabba8..2c46d41540 100644 --- a/res/values/setup.xml +++ b/res/values/setup.xml @@ -1,6 +1,6 @@ - https://bwlsdf-owncloud1.lsdf.kit.edu/oc-shib + true