Browse Source

Merge pull request #250 from owncloud/saml_based_federated_single_sign_on_expired

Saml based federated single sign on expired
masensio 11 years ago
parent
commit
cfa974db49
24 changed files with 242 additions and 116 deletions
  1. 8 1
      res/layout-land/account_setup.xml
  2. 9 0
      res/layout/account_setup.xml
  3. 1 1
      res/values-es/strings.xml
  4. 3 1
      res/values/strings.xml
  5. 70 17
      src/com/owncloud/android/authentication/AuthenticatorActivity.java
  6. 5 1
      src/com/owncloud/android/files/services/FileDownloader.java
  7. 57 48
      src/com/owncloud/android/files/services/FileUploader.java
  8. 12 6
      src/com/owncloud/android/network/OwnCloudClientUtils.java
  9. 3 0
      src/com/owncloud/android/operations/ChunkedUploadFileOperation.java
  10. 1 1
      src/com/owncloud/android/operations/CreateFolderOperation.java
  11. 9 8
      src/com/owncloud/android/operations/DownloadFileOperation.java
  12. 2 2
      src/com/owncloud/android/operations/OAuth2GetAccessToken.java
  13. 1 1
      src/com/owncloud/android/operations/OwnCloudServerCheckOperation.java
  14. 20 10
      src/com/owncloud/android/operations/RemoteOperation.java
  15. 7 3
      src/com/owncloud/android/operations/RemoteOperationResult.java
  16. 1 1
      src/com/owncloud/android/operations/RemoveFileOperation.java
  17. 1 1
      src/com/owncloud/android/operations/RenameFileOperation.java
  18. 1 1
      src/com/owncloud/android/operations/SynchronizeFileOperation.java
  19. 2 8
      src/com/owncloud/android/operations/SynchronizeFolderOperation.java
  20. 1 1
      src/com/owncloud/android/operations/UpdateOCVersionOperation.java
  21. 1 1
      src/com/owncloud/android/operations/UploadFileOperation.java
  22. 12 2
      src/com/owncloud/android/syncadapter/FileSyncAdapter.java
  23. 1 1
      src/com/owncloud/android/ui/dialog/SamlWebViewDialog.java
  24. 14 0
      src/eu/alefzero/webdav/WebdavClient.java

+ 8 - 1
res/layout-land/account_setup.xml

@@ -64,7 +64,14 @@
             		android:onClick="onRefreshClick"
 				    android:text="@string/auth_check_server"
 				    android:visibility="gone" />
-		
+				<TextView
+				    android:id="@+id/auth_message"
+				    android:layout_width="wrap_content"
+				    android:layout_height="wrap_content"
+				    android:layout_gravity="fill_horizontal"
+				    android:text="@string/auth_expired_basic_auth_toast" 
+				    android:visibility="gone"
+				    android:layout_marginBottom="10dp"/>
 			    <FrameLayout 
 	        		android:id="@+id/hostUrlFrame"
 					android:layout_width="match_parent"

+ 9 - 0
res/layout/account_setup.xml

@@ -50,6 +50,15 @@
             android:onClick="onRefreshClick"
             android:text="@string/auth_check_server"
             android:visibility="gone" />
+        
+        <TextView
+            android:id="@+id/auth_message"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="fill_horizontal"
+            android:text="@string/auth_expired_basic_auth_toast"
+            android:visibility="gone"
+            android:layout_marginBottom="10dp" />
 
 	    <FrameLayout 
 	        android:id="@+id/hostUrlFrame"

+ 1 - 1
res/values-es/strings.xml

@@ -203,7 +203,7 @@
   <string name="auth_not_found">Ruta errónea</string>
   <string name="auth_internal">Error interno en el servidor, código %1$d</string>
   <string name="auth_wtf_reenter_URL">Estado inesperado; por favor, introduzca la URL del servidor de nuevo</string>
-  <string name="auth_expired_oauth_token_toast">Su autorización ha expirado.\nPor favor, autorice de nuevo</string>
+  <string name="auth_expired_oauth_token_toast">Su autorización ha expirado. Por favor, autorice de nuevo</string>
   <string name="auth_expired_basic_auth_toast">Por favor, introduzca la contraseña actual.</string>
   <string name="crashlog_message">La aplicación finalizó inesperadamente. ¿Desea enviar un reporte de error?</string>
   <string name="crashlog_send_report">Enviar reporte</string>

+ 3 - 1
res/values/strings.xml

@@ -191,6 +191,7 @@
     <string name="auth_not_configured_title">Malformed server configuration</string>
     <string name="auth_not_configured_message">It seems that your server instance is not correctly configured. Contact your administrator for more details.</string>
     <string name="auth_account_not_new">An account for the same user and server already exists in the device</string>
+    <string name="auth_account_not_the_same">The entered user does not match the user of this account</string>
     <string name="auth_unknown_error_title">Unknown error occurred!</string>
     <string name="auth_unknown_error_message">An unknown error occurred. Please contact support and include logs from your device.</string>
     <string name="auth_unknown_host_title">Couldn\'t find host</string>
@@ -210,8 +211,9 @@
     <string name="auth_not_found">Wrong path given</string>
     <string name="auth_internal">Internal server error, code %1$d</string>
     <string name="auth_wtf_reenter_URL">Unexpected state; please, enter the server URL again</string>
-    <string name="auth_expired_oauth_token_toast">Your authorization expired.\nPlease, authorize 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_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_follow_auth_server">Follow instructions above to get authenticated</string>
 	<string name="auth_unsupported_auth_method">The server does not support this authentication method</string>    

+ 70 - 17
src/com/owncloud/android/authentication/AuthenticatorActivity.java

@@ -18,8 +18,6 @@
 
 package com.owncloud.android.authentication;
 
-import java.net.URLDecoder;
-
 import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.app.AlertDialog;
@@ -51,7 +49,6 @@ import android.widget.CheckBox;
 import android.widget.EditText;
 import android.widget.TextView;
 import android.widget.TextView.OnEditorActionListener;
-import android.widget.Toast;
 
 import com.actionbarsherlock.app.SherlockDialogFragment;
 import com.owncloud.android.Log_OC;
@@ -89,6 +86,8 @@ implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
     public static final String EXTRA_ACTION = "ACTION";
     public static final String EXTRA_ENFORCED_UPDATE = "ENFORCE_UPDATE";
 
+    private static final String KEY_AUTH_MESSAGE_VISIBILITY = "AUTH_MESSAGE_VISIBILITY";
+    private static final String KEY_AUTH_MESSAGE_TEXT = "AUTH_MESSAGE_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_ACCOUNT = "ACCOUNT";
@@ -122,7 +121,8 @@ implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
     private String mHostBaseUrl;
     private OwnCloudVersion mDiscoveredVersion;
 
-    private int mServerStatusText, mServerStatusIcon;
+    private String mAuthMessageText;
+    private int mAuthMessageVisibility, mServerStatusText, mServerStatusIcon;
     private boolean mServerIsChecked, mServerIsValid, mIsSslConn;
     private int mAuthStatusText, mAuthStatusIcon;    
     private TextView mAuthStatusLayout;
@@ -140,6 +140,8 @@ implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
     private byte mAction;
     private Account mAccount;
 
+    private TextView mAuthMessage;
+    
     private EditText mHostUrlInput;
     private boolean mHostUrlInputEnabled;
     private View mRefreshButton;
@@ -175,6 +177,7 @@ implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
 
         /// set view and get references to view elements
         setContentView(R.layout.account_setup);
+        mAuthMessage = (TextView) findViewById(R.id.auth_message);
         mHostUrlInput = (EditText) findViewById(R.id.hostUrlInput);
         mHostUrlInput.setText(getString(R.string.server_url));  // valid although R.string.server_url is an empty string
         mUsernameInput = (EditText) findViewById(R.id.account_username);
@@ -216,6 +219,7 @@ implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
         if (savedInstanceState == null) {
             mResumed = false;
             /// connection state and info
+            mAuthMessageVisibility = View.GONE;
             mServerStatusText = mServerStatusIcon = 0;
             mServerIsValid = false;
             mServerIsChecked = false;
@@ -231,6 +235,8 @@ 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);
             }
             initAuthorizationMethod();  // checks intent and setup.xml to determine mCurrentAuthorizationMethod
             mJustCreated = true;
@@ -242,6 +248,8 @@ implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
         } else {
             mResumed = true;
             /// connection state and info
+            mAuthMessageVisibility = savedInstanceState.getInt(KEY_AUTH_MESSAGE_VISIBILITY);
+            mAuthMessageText = savedInstanceState.getString(KEY_AUTH_MESSAGE_TEXT);
             mServerIsValid = savedInstanceState.getBoolean(KEY_SERVER_VALID);
             mServerIsChecked = savedInstanceState.getBoolean(KEY_SERVER_CHECKED);
             mServerStatusText = savedInstanceState.getInt(KEY_SERVER_STATUS_TEXT);
@@ -279,6 +287,12 @@ implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
 
         }
 
+        if (mAuthMessageVisibility== View.VISIBLE) {
+            showAuthMessage(mAuthMessageText);
+        }
+        else {
+            hideAuthMessage();
+        }
         adaptViewAccordingToAuthenticationMethod();
         showServerStatus();
         showAuthStatus();
@@ -411,6 +425,8 @@ implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
         super.onSaveInstanceState(outState);
 
         /// connection state and info
+        outState.putInt(KEY_AUTH_MESSAGE_VISIBILITY, mAuthMessage.getVisibility());
+        outState.putString(KEY_AUTH_MESSAGE_TEXT, mAuthMessage.getText().toString());
         outState.putInt(KEY_SERVER_STATUS_TEXT, mServerStatusText);
         outState.putInt(KEY_SERVER_STATUS_ICON, mServerStatusIcon);
         outState.putBoolean(KEY_SERVER_VALID, mServerIsValid);
@@ -465,10 +481,16 @@ implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
     protected void onResume() {
         super.onResume();
         if (mAction == ACTION_UPDATE_TOKEN && mJustCreated && getIntent().getBooleanExtra(EXTRA_ENFORCED_UPDATE, false)) {
-            if (mOAuth2Check.isChecked())
-                Toast.makeText(this, R.string.auth_expired_oauth_token_toast, Toast.LENGTH_LONG).show();
-            else
-                Toast.makeText(this, R.string.auth_expired_basic_auth_toast, Toast.LENGTH_LONG).show();
+            if (AccountAuthenticator.AUTH_TOKEN_TYPE_ACCESS_TOKEN.equals(mAuthTokenType)) {
+                //Toast.makeText(this, R.string.auth_expired_oauth_token_toast, Toast.LENGTH_LONG).show();
+                showAuthMessage(getString(R.string.auth_expired_oauth_token_toast));
+            } else if (AccountAuthenticator.AUTH_TOKEN_TYPE_SAML_WEB_SSO_SESSION_COOKIE.equals(mAuthTokenType)) {
+                //Toast.makeText(this, R.string.auth_expired_saml_sso_token_toast, Toast.LENGTH_LONG).show();
+                showAuthMessage(getString(R.string.auth_expired_saml_sso_token_toast));
+            } else {
+                //Toast.makeText(this, R.string.auth_expired_basic_auth_toast, Toast.LENGTH_LONG).show();
+                showAuthMessage(getString(R.string.auth_expired_basic_auth_toast));
+            }
         }
 
         if (mNewCapturedUriFromOAuth2Redirection != null) {
@@ -774,9 +796,9 @@ implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
         } catch (IllegalArgumentException e) {
             // NOTHING TO DO ; can't find out what situation that leads to the exception in this code, but user logs signal that it happens
         }
-        
-        //if (result.isTemporalRedirection() || result.isIdPRedirection()) {
-        if (result.isIdPRedirection()) {
+        
+        //if (result.isTemporalRedirection() && result.isIdPRedirection()) {
+        if (result.isIdPRedirection()) {
             String url = result.getRedirectedLocation();
             String targetUrl = mHostBaseUrl + AccountUtils.getWebdavPath(mDiscoveredVersion, mAuthTokenType);
             
@@ -1020,6 +1042,9 @@ implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
         case ACCOUNT_NOT_NEW:
             mAuthStatusText = R.string.auth_account_not_new;
             break;
+        case ACCOUNT_NOT_THE_SAME:
+            mAuthStatusText = R.string.auth_account_not_the_same;
+            break;
         case UNHANDLED_HTTP_CODE:
         case UNKNOWN_ERROR:
             mAuthStatusText = R.string.auth_unknown_error_title;
@@ -1084,12 +1109,12 @@ implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
         if (result.isSuccess()) {
             Log_OC.d(TAG, "Successful access - time to save the account");
 
-            boolean success = true;
+            boolean success = false;
             if (mAction == ACTION_CREATE) {
                 success = createAccount();
 
             } else {
-                updateToken();
+                success = updateToken();
             }
 
             if (success) {
@@ -1135,7 +1160,7 @@ implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
      * Sets the proper response to get that the Account Authenticator that started this activity saves 
      * a new authorization token for mAccount.
      */
-    private void updateToken() {
+    private boolean updateToken() {
         Bundle response = new Bundle();
         response.putString(AccountManager.KEY_ACCOUNT_NAME, mAccount.name);
         response.putString(AccountManager.KEY_ACCOUNT_TYPE, mAccount.type);
@@ -1146,6 +1171,17 @@ implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
             mAccountMgr.setAuthToken(mAccount, mAuthTokenType, mAuthToken);
             
         } else if (AccountAuthenticator.AUTH_TOKEN_TYPE_SAML_WEB_SSO_SESSION_COOKIE.equals(mAuthTokenType)) {
+            String username = getUserNameForSamlSso();
+            if (!mUsernameInput.getText().toString().equals(username)) {
+                // fail - not a new account, but an existing one; disallow
+                RemoteOperationResult result = new RemoteOperationResult(ResultCode.ACCOUNT_NOT_THE_SAME); 
+                updateAuthStatusIconAndText(result);
+                showAuthStatus();
+                Log_OC.d(TAG, result.getLogMessage());
+                
+                return false;
+            }
+            
             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);
@@ -1155,6 +1191,8 @@ implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
             mAccountMgr.setPassword(mAccount, mPasswordInput.getText().toString());
         }
         setAccountAuthenticatorResult(response);
+        
+        return true;
     }
 
 
@@ -1191,7 +1229,6 @@ implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
             Log_OC.d(TAG, result.getLogMessage());
             return false;
             
-            
         } else {
         
             if (isOAuth || isSaml) {
@@ -1236,6 +1273,10 @@ implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
             Bundle bundle = new Bundle();
             bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
             ContentResolver.requestSync(mAccount, AccountAuthenticator.AUTHORITY, bundle);
+            syncAccount();
+//          Bundle bundle = new Bundle();
+//          bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
+//          ContentResolver.requestSync(mAccount, AccountAuthenticator.AUTHORITY, bundle);
             return true;
         }
     }
@@ -1554,12 +1595,12 @@ implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
         
         if (sessionCookie != null && sessionCookie.length() > 0) {
             mAuthToken = sessionCookie;
-            boolean success = true;
+            boolean success = false;
             if (mAction == ACTION_CREATE) {
                 success = createAccount();
         
             } else {
-                updateToken();
+                success = updateToken();
             }
             if (success) {
                 finish();
@@ -1592,6 +1633,18 @@ implements  OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
     
     }
     
+    /** Show auth_message 
+     * 
+     * @param message
+     */
+    private void showAuthMessage(String message) {
+       mAuthMessage.setVisibility(View.VISIBLE);
+       mAuthMessage.setText(message);
+    }
+    
+    private void hideAuthMessage() {
+        mAuthMessage.setVisibility(View.GONE);
+    }
 
     private void syncAccount(){
         /// immediately request for the synchronization of the new account

+ 5 - 1
src/com/owncloud/android/files/services/FileDownloader.java

@@ -28,6 +28,7 @@ import java.util.Vector;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
+import com.owncloud.android.authentication.AccountAuthenticator;
 import com.owncloud.android.authentication.AuthenticatorActivity;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
@@ -463,7 +464,10 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
             int contentId = (downloadResult.isSuccess()) ? R.string.downloader_download_succeeded_content : R.string.downloader_download_failed_content;
             Notification finalNotification = new Notification(R.drawable.icon, getString(tickerId), System.currentTimeMillis());
             finalNotification.flags |= Notification.FLAG_AUTO_CANCEL;
-            boolean needsToUpdateCredentials = (downloadResult.getCode() == ResultCode.UNAUTHORIZED);
+            boolean needsToUpdateCredentials = (downloadResult.getCode() == ResultCode.UNAUTHORIZED ||
+                                                // (downloadResult.isTemporalRedirection() && downloadResult.isIdPRedirection()
+                                                  (downloadResult.isIdPRedirection()
+                                                        && AccountAuthenticator.AUTH_TOKEN_TYPE_SAML_WEB_SSO_SESSION_COOKIE.equals(mDownloadClient.getAuthTokenType())));
             if (needsToUpdateCredentials) {
                 // let the user update credentials with one click
                 Intent updateAccountCredentials = new Intent(this, AuthenticatorActivity.class);

+ 57 - 48
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());
 
@@ -791,7 +791,13 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
             Notification finalNotification = new Notification(R.drawable.icon,
                     getString(R.string.uploader_upload_failed_ticker), System.currentTimeMillis());
             finalNotification.flags |= Notification.FLAG_AUTO_CANCEL;
-            if (uploadResult.getCode() == ResultCode.UNAUTHORIZED) {
+            String content = null;
+            
+            boolean needsToUpdateCredentials = (uploadResult.getCode() == ResultCode.UNAUTHORIZED ||
+                    //(uploadResult.isTemporalRedirection() && uploadResult.isIdPRedirection() && 
+                    (uploadResult.isIdPRedirection() &&
+                            AccountAuthenticator.AUTH_TOKEN_TYPE_SAML_WEB_SSO_SESSION_COOKIE.equals(mUploadClient.getAuthTokenType())));
+            if (needsToUpdateCredentials) {
                 // let the user update credentials with one click
                 Intent updateAccountCredentials = new Intent(this, AuthenticatorActivity.class);
                 updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, upload.getAccount());
@@ -801,62 +807,65 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                 updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
                 updateAccountCredentials.addFlags(Intent.FLAG_FROM_BACKGROUND);
                 finalNotification.contentIntent = PendingIntent.getActivity(this, (int)System.currentTimeMillis(), updateAccountCredentials, PendingIntent.FLAG_ONE_SHOT);
+                content =  String.format(getString(R.string.uploader_upload_failed_content_single), upload.getFileName());
+                finalNotification.setLatestEventInfo(getApplicationContext(),
+                        getString(R.string.uploader_upload_failed_ticker), content, finalNotification.contentIntent);
                 mUploadClient = null;   // grant that future retries on the same account will get the fresh credentials
             } else {
                 // TODO put something smart in the contentIntent below
-                finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), (int)System.currentTimeMillis(), new Intent(), 0);
-            }
+            //    finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), (int)System.currentTimeMillis(), new Intent(), 0);
+            //}
             
-            String content = null;
-            if (uploadResult.getCode() == ResultCode.LOCAL_STORAGE_FULL
-                    || uploadResult.getCode() == ResultCode.LOCAL_STORAGE_NOT_COPIED) {
-                // TODO we need a class to provide error messages for the users
-                // from a RemoteOperationResult and a RemoteOperation
-                content = String.format(getString(R.string.error__upload__local_file_not_copied), upload.getFileName(),
-                        getString(R.string.app_name));
-            } else if (uploadResult.getCode() == ResultCode.QUOTA_EXCEEDED) {
-                content = getString(R.string.failed_upload_quota_exceeded_text);
-            } else {
-                content = String
-                        .format(getString(R.string.uploader_upload_failed_content_single), upload.getFileName());
-            }
+                if (uploadResult.getCode() == ResultCode.LOCAL_STORAGE_FULL
+                        || uploadResult.getCode() == ResultCode.LOCAL_STORAGE_NOT_COPIED) {
+                    // TODO we need a class to provide error messages for the users
+                    // from a RemoteOperationResult and a RemoteOperation
+                    content = String.format(getString(R.string.error__upload__local_file_not_copied), upload.getFileName(),
+                            getString(R.string.app_name));
+                } else if (uploadResult.getCode() == ResultCode.QUOTA_EXCEEDED) {
+                    content = getString(R.string.failed_upload_quota_exceeded_text);
+                } else {
+                    content = String
+                            .format(getString(R.string.uploader_upload_failed_content_single), upload.getFileName());
+                }
 
-            // we add only for instant-uploads the InstantUploadActivity and the
-            // db entry
-            Intent detailUploadIntent = null;
-            if (upload.isInstant() && InstantUploadActivity.IS_ENABLED) {
-                detailUploadIntent = new Intent(this, InstantUploadActivity.class);
-                detailUploadIntent.putExtra(FileUploader.KEY_ACCOUNT, upload.getAccount());
-            } else {
-                detailUploadIntent = new Intent(this, FailedUploadActivity.class);
-                detailUploadIntent.putExtra(FailedUploadActivity.MESSAGE, content);
-            }
-            finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(),
-                    (int) System.currentTimeMillis(), detailUploadIntent, PendingIntent.FLAG_UPDATE_CURRENT
-                            | PendingIntent.FLAG_ONE_SHOT);
-
-            if (upload.isInstant()) {
-                DbHandler db = null;
-                try {
-                    db = new DbHandler(this.getBaseContext());
-                    String message = uploadResult.getLogMessage() + " errorCode: " + uploadResult.getCode();
-                    Log_OC.e(TAG, message + " Http-Code: " + uploadResult.getHttpCode());
-                    if (uploadResult.getCode() == ResultCode.QUOTA_EXCEEDED) {
-                        message = getString(R.string.failed_upload_quota_exceeded_text);
-                    }
-                    if (db.updateFileState(upload.getOriginalStoragePath(), DbHandler.UPLOAD_STATUS_UPLOAD_FAILED,
-                            message) == 0) {
-                        db.putFileForLater(upload.getOriginalStoragePath(), upload.getAccount().name, message);
-                    }
-                } finally {
-                    if (db != null) {
-                        db.close();
+                // we add only for instant-uploads the InstantUploadActivity and the
+                // db entry
+                Intent detailUploadIntent = null;
+                if (upload.isInstant() && InstantUploadActivity.IS_ENABLED) {
+                    detailUploadIntent = new Intent(this, InstantUploadActivity.class);
+                    detailUploadIntent.putExtra(FileUploader.KEY_ACCOUNT, upload.getAccount());
+                } else {
+                    detailUploadIntent = new Intent(this, FailedUploadActivity.class);
+                    detailUploadIntent.putExtra(FailedUploadActivity.MESSAGE, content);
+                }
+                finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(),
+                        (int) System.currentTimeMillis(), detailUploadIntent, PendingIntent.FLAG_UPDATE_CURRENT
+                        | PendingIntent.FLAG_ONE_SHOT);
+
+                if (upload.isInstant()) {
+                    DbHandler db = null;
+                    try {
+                        db = new DbHandler(this.getBaseContext());
+                        String message = uploadResult.getLogMessage() + " errorCode: " + uploadResult.getCode();
+                        Log_OC.e(TAG, message + " Http-Code: " + uploadResult.getHttpCode());
+                        if (uploadResult.getCode() == ResultCode.QUOTA_EXCEEDED) {
+                            message = getString(R.string.failed_upload_quota_exceeded_text);
+                        }
+                        if (db.updateFileState(upload.getOriginalStoragePath(), DbHandler.UPLOAD_STATUS_UPLOAD_FAILED,
+                                message) == 0) {
+                            db.putFileForLater(upload.getOriginalStoragePath(), upload.getAccount().name, message);
+                        }
+                    } finally {
+                        if (db != null) {
+                            db.close();
+                        }
                     }
                 }
             }
             finalNotification.setLatestEventInfo(getApplicationContext(),
                     getString(R.string.uploader_upload_failed_ticker), content, finalNotification.contentIntent);
-
+            
             mNotificationManager.notify(R.string.uploader_upload_failed_ticker, finalNotification);
         }
 

+ 12 - 6
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<Bundle> 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<Bundle> 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);

+ 3 - 0
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);

+ 1 - 1
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());
                 

+ 9 - 8
src/com/owncloud/android/operations/DownloadFileOperation.java

@@ -58,6 +58,7 @@ public class DownloadFileOperation extends RemoteOperation {
     private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
     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<OnDatatransferProgressListener> 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;
     }

+ 2 - 2
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());
                 }
             }
             

+ 1 - 1
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) {

+ 20 - 10
src/com/owncloud/android/operations/RemoteOperation.java

@@ -242,18 +242,28 @@ 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() && result.isIdPRedirection()))) {
+                    (result.getCode() == ResultCode.UNAUTHORIZED || result.isIdPRedirection())) {
+                /// 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);
         

+ 7 - 3
src/com/owncloud/android/operations/RemoteOperationResult.java

@@ -51,7 +51,7 @@ import com.owncloud.android.network.CertificateCombinedException;
 public class RemoteOperationResult implements Serializable {
 
     /** Generated - should be refreshed every time the class changes!! */
-    private static final long serialVersionUID = 3267227833178885664L;
+    private static final long serialVersionUID = -4415103901492836870L;
 
     
     private static final String TAG = "RemoteOperationResult";
@@ -86,7 +86,8 @@ public class RemoteOperationResult implements Serializable {
         QUOTA_EXCEEDED, 
         ACCOUNT_NOT_FOUND, 
         ACCOUNT_EXCEPTION, 
-        ACCOUNT_NOT_NEW
+        ACCOUNT_NOT_NEW, 
+        ACCOUNT_NOT_THE_SAME
     }
 
     private boolean mSuccess = false;
@@ -100,7 +101,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;
 
@@ -301,6 +302,9 @@ public class RemoteOperationResult implements Serializable {
 
         } else if (mCode == ResultCode.ACCOUNT_NOT_NEW) {
             return "Account already existing when creating a new one";
+
+        } else if (mCode == ResultCode.ACCOUNT_NOT_THE_SAME) {
+            return "Authenticated with a different account than the one updating";
         }
 
         return "Operation finished with HTTP status code " + mHttpCode + " (" + (isSuccess() ? "success" : "fail") + ")";

+ 1 - 1
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) {

+ 1 - 1
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) {

+ 1 - 1
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());
                     }
                 }
                 

+ 2 - 8
src/com/owncloud/android/operations/SynchronizeFolderOperation.java

@@ -243,16 +243,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);
-                    Header hCookie = query.getResponseHeader("Cookie");
-                    if (hCookie != null) {
-                        Log_OC.e(TAG, "PROPFIND cookie: " + hCookie.getValue());
-                    } else {
-                        Log_OC.e(TAG, "PROPFIND NO COOKIE");
-                    }
+                    result = new RemoteOperationResult(true, status, query.getResponseHeaders());
                 }
             } else {
-                result = new RemoteOperationResult(false, status);
+                result = new RemoteOperationResult(false, status, query.getResponseHeaders());
             }
             
             

+ 1 - 1
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();

+ 1 - 1
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

+ 12 - 2
src/com/owncloud/android/syncadapter/FileSyncAdapter.java

@@ -28,6 +28,7 @@ import org.apache.jackrabbit.webdav.DavException;
 
 import com.owncloud.android.Log_OC;
 import com.owncloud.android.R;
+import com.owncloud.android.authentication.AccountAuthenticator;
 import com.owncloud.android.authentication.AuthenticatorActivity;
 import com.owncloud.android.datamodel.DataStorageManager;
 import com.owncloud.android.datamodel.FileDataStorageManager;
@@ -223,7 +224,10 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
             sendStickyBroadcast(true, remotePath, null);
             
         } else {
-            if (result.getCode() == RemoteOperationResult.ResultCode.UNAUTHORIZED) {
+            if (result.getCode() == RemoteOperationResult.ResultCode.UNAUTHORIZED ||
+                   // (result.isTemporalRedirection() && result.isIdPRedirection() &&
+                    ( result.isIdPRedirection() && 
+                            AccountAuthenticator.AUTH_TOKEN_TYPE_SAML_WEB_SSO_SESSION_COOKIE.equals(getClient().getAuthTokenType()))) {
                 mSyncResult.stats.numAuthExceptions++;
                 
             } else if (result.getException() instanceof DavException) {
@@ -304,7 +308,13 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
     private void notifyFailedSynchronization() {
         Notification notification = new Notification(R.drawable.icon, getContext().getString(R.string.sync_fail_ticker), System.currentTimeMillis());
         notification.flags |= Notification.FLAG_AUTO_CANCEL;
-        boolean needsToUpdateCredentials = (mLastFailedResult != null && mLastFailedResult.getCode() == ResultCode.UNAUTHORIZED);
+        boolean needsToUpdateCredentials = (mLastFailedResult != null && 
+                                             (  mLastFailedResult.getCode() == ResultCode.UNAUTHORIZED ||
+                                                // (mLastFailedResult.isTemporalRedirection() && mLastFailedResult.isIdPRedirection() && 
+                                                ( mLastFailedResult.isIdPRedirection() && 
+                                                 AccountAuthenticator.AUTH_TOKEN_TYPE_SAML_WEB_SSO_SESSION_COOKIE.equals(getClient().getAuthTokenType()))
+                                             )
+                                           );
         // TODO put something smart in the contentIntent below for all the possible errors
         notification.contentIntent = PendingIntent.getActivity(getContext().getApplicationContext(), (int)System.currentTimeMillis(), new Intent(), 0);
         if (needsToUpdateCredentials) {

+ 1 - 1
src/com/owncloud/android/ui/dialog/SamlWebViewDialog.java

@@ -118,7 +118,7 @@ public class SamlWebViewDialog extends SherlockDialogFragment {
         super.onCreate(savedInstanceState);
         
         CookieSyncManager.createInstance(getActivity());
-        
+
         if (savedInstanceState == null) {
             mInitialUrl = getArguments().getString(ARG_INITIAL_URL);
             mTargetUrl = getArguments().getString(ARG_TARGET_URL);

+ 14 - 0
src/eu/alefzero/webdav/WebdavClient.java

@@ -41,6 +41,7 @@ import org.apache.http.params.CoreProtocolPNames;
 
 import com.owncloud.android.Log_OC;
 
+import com.owncloud.android.authentication.AccountAuthenticator;
 import com.owncloud.android.network.BearerAuthScheme;
 import com.owncloud.android.network.BearerCredentials;
 
@@ -51,6 +52,7 @@ public class WebdavClient extends HttpClient {
     private Credentials mCredentials;
     private boolean mFollowRedirects;
     private String mSsoSessionCookie;
+    private String mAuthTokenType;
     final private static String TAG = "WebdavClient";
     public static final String USER_AGENT = "Android-ownCloud";
     
@@ -66,6 +68,7 @@ public class WebdavClient extends HttpClient {
         getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
         mFollowRedirects = true;
         mSsoSessionCookie = null;
+        mAuthTokenType = AccountAuthenticator.AUTH_TOKEN_TYPE_PASSWORD;
     }
 
     public void setBearerCredentials(String accessToken) {
@@ -78,6 +81,7 @@ public class WebdavClient extends HttpClient {
         mCredentials = new BearerCredentials(accessToken);
         getState().setCredentials(AuthScope.ANY, mCredentials);
         mSsoSessionCookie = null;
+        mAuthTokenType = AccountAuthenticator.AUTH_TOKEN_TYPE_ACCESS_TOKEN;
     }
 
     public void setBasicCredentials(String username, String password) {
@@ -89,6 +93,7 @@ public class WebdavClient extends HttpClient {
         mCredentials = new UsernamePasswordCredentials(username, password);
         getState().setCredentials(AuthScope.ANY, mCredentials);
         mSsoSessionCookie = null;
+        mAuthTokenType = AccountAuthenticator.AUTH_TOKEN_TYPE_PASSWORD;
     }
     
     public void setSsoSessionCookie(String accessToken) {
@@ -96,6 +101,7 @@ public class WebdavClient extends HttpClient {
         getParams().setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
         mSsoSessionCookie = accessToken;
         mCredentials = null;
+        mAuthTokenType = AccountAuthenticator.AUTH_TOKEN_TYPE_SAML_WEB_SSO_SESSION_COOKIE;
     }
     
     
@@ -206,9 +212,17 @@ public class WebdavClient extends HttpClient {
     public final Credentials getCredentials() {
         return mCredentials;
     }
+    
+    public final String getSsoSessionCookie() {
+        return mSsoSessionCookie;
+    }
 
     public void setFollowRedirects(boolean followRedirects) {
         mFollowRedirects = followRedirects;
     }
 
+    public String getAuthTokenType() {
+        return mAuthTokenType;
+    }
+
 }