1
0
mirror of https://github.com/owncloud/android-library.git synced 2025-06-07 16:06:08 +00:00

Compare commits

...

4 Commits

Author SHA1 Message Date
Abel García de Prada
8132baa177 Potential fix to oauth error after logging in for first time that makes user to reauthenticate 2023-01-24 13:52:50 +01:00
Abel García de Prada
0e11f0d4b8 Merge pull request #523 from owncloud/fix/unshare_ocis
Unsharing wont return anything anymore since result object was not used
2022-12-20 17:49:03 +01:00
Abel García de Prada
47fd1c2deb Unsharing wont return anything anymore since result object was not used 2022-12-20 17:49:03 +01:00
Abel García de Prada
660304ada1 Add several logs to try to debug potential errors related to oAuth 2022-12-20 13:53:46 +01:00
6 changed files with 43 additions and 45 deletions

View File

@ -37,7 +37,6 @@ import com.owncloud.android.lib.resources.status.RemoteServerInfo
import org.apache.commons.lang3.exception.ExceptionUtils import org.apache.commons.lang3.exception.ExceptionUtils
import timber.log.Timber import timber.log.Timber
import java.io.IOException import java.io.IOException
import java.lang.Exception
/** /**
* ConnectionValidator * ConnectionValidator
@ -46,7 +45,7 @@ import java.lang.Exception
*/ */
class ConnectionValidator( class ConnectionValidator(
val context: Context, val context: Context,
val clearCookiesOnValidation: Boolean private val clearCookiesOnValidation: Boolean
) { ) {
fun validate(baseClient: OwnCloudClient, singleSessionManager: SingleSessionManager, context: Context): Boolean { fun validate(baseClient: OwnCloudClient, singleSessionManager: SingleSessionManager, context: Context): Boolean {
try { try {
@ -61,12 +60,12 @@ class ConnectionValidator(
client.account = baseClient.account client.account = baseClient.account
client.credentials = baseClient.credentials client.credentials = baseClient.credentials
while (validationRetryCount < VALIDATION_RETRY_COUNT) { while (validationRetryCount < VALIDATION_RETRY_COUNT) {
Timber.d("validationRetryCout %d", validationRetryCount) Timber.d("validationRetryCount %d", validationRetryCount)
var successCounter = 0 var successCounter = 0
var failCounter = 0 var failCounter = 0
client.setFollowRedirects(true) client.setFollowRedirects(true)
if (isOnwCloudStatusOk(client)) { if (isOwnCloudStatusOk(client)) {
successCounter++ successCounter++
} else { } else {
failCounter++ failCounter++
@ -103,7 +102,7 @@ class ConnectionValidator(
return false return false
} }
private fun isOnwCloudStatusOk(client: OwnCloudClient): Boolean { private fun isOwnCloudStatusOk(client: OwnCloudClient): Boolean {
val reply = getOwnCloudStatus(client) val reply = getOwnCloudStatus(client)
// dont check status code. It currently relais on the broken redirect code of the owncloud client // dont check status code. It currently relais on the broken redirect code of the owncloud client
// TODO: Use okhttp redirect and add this check again // TODO: Use okhttp redirect and add this check again
@ -138,6 +137,12 @@ class ConnectionValidator(
// test if have all the needed to effectively invalidate ... // test if have all the needed to effectively invalidate ...
shouldInvalidateAccountCredentials = shouldInvalidateAccountCredentials =
shouldInvalidateAccountCredentials and (account.savedAccount != null) shouldInvalidateAccountCredentials and (account.savedAccount != null)
Timber.d(
"""Received error: $httpStatusCode,
account: ${account.name}
credentials are real: ${credentials !is OwnCloudAnonymousCredentials},
so we need to invalidate credentials for account ${account.name} : $shouldInvalidateAccountCredentials"""
)
return shouldInvalidateAccountCredentials return shouldInvalidateAccountCredentials
} }
@ -150,6 +155,7 @@ class ConnectionValidator(
* *
*/ */
private fun invalidateAccountCredentials(account: OwnCloudAccount, credentials: OwnCloudCredentials) { private fun invalidateAccountCredentials(account: OwnCloudAccount, credentials: OwnCloudCredentials) {
Timber.i("Invalidating account credentials for account $account")
val am = AccountManager.get(context) val am = AccountManager.get(context)
am.invalidateAuthToken( am.invalidateAuthToken(
account.savedAccount.type, account.savedAccount.type,
@ -167,8 +173,6 @@ class ConnectionValidator(
* *
* Refresh current credentials if possible, and marks a retry. * Refresh current credentials if possible, and marks a retry.
* *
* @param status
* @param repeatCounter
* @return * @return
*/ */
private fun checkUnauthorizedAccess(client: OwnCloudClient, singleSessionManager: SingleSessionManager, status: Int): Boolean { private fun checkUnauthorizedAccess(client: OwnCloudClient, singleSessionManager: SingleSessionManager, status: Int): Boolean {
@ -181,6 +185,7 @@ class ConnectionValidator(
if (credentials.authTokenCanBeRefreshed()) { if (credentials.authTokenCanBeRefreshed()) {
try { try {
// This command does the actual refresh // This command does the actual refresh
Timber.i("Trying to refresh auth token for account $account")
account.loadCredentials(context) account.loadCredentials(context)
// if mAccount.getCredentials().length() == 0 --> refresh failed // if mAccount.getCredentials().length() == 0 --> refresh failed
client.credentials = account.credentials client.credentials = account.credentials
@ -201,6 +206,7 @@ class ConnectionValidator(
if (!credentialsWereRefreshed) { if (!credentialsWereRefreshed) {
// if credentials are not refreshed, client must be removed // if credentials are not refreshed, client must be removed
// from the OwnCloudClientManager to prevent it is reused once and again // from the OwnCloudClientManager to prevent it is reused once and again
Timber.w("Credentials were not refreshed, client will be removed from the Session Manager to prevent using it over and over")
singleSessionManager.removeClientFor(account) singleSessionManager.removeClientFor(account)
} }
} }
@ -210,6 +216,6 @@ class ConnectionValidator(
} }
companion object { companion object {
private val VALIDATION_RETRY_COUNT = 3 private const val VALIDATION_RETRY_COUNT = 3
} }
} }

View File

@ -31,7 +31,6 @@ import android.net.Uri;
import com.owncloud.android.lib.common.accounts.AccountUtils; import com.owncloud.android.lib.common.accounts.AccountUtils;
import com.owncloud.android.lib.common.authentication.OwnCloudCredentials; import com.owncloud.android.lib.common.authentication.OwnCloudCredentials;
import com.owncloud.android.lib.common.http.HttpClient;
import timber.log.Timber; import timber.log.Timber;
import java.io.IOException; import java.io.IOException;
@ -124,6 +123,24 @@ public class SingleSessionManager {
} }
} else { } else {
Timber.v("reusing client for account %s", accountName); Timber.v("reusing client for account %s", accountName);
if (client.getAccount() != null &&
client.getAccount().getCredentials() != null &&
(client.getAccount().getCredentials().getAuthToken() == null || client.getAccount().getCredentials().getAuthToken().isEmpty())
) {
Timber.i("Client " + client.getAccount().getName() + " needs to refresh credentials");
//the next two lines are a hack because okHttpclient is used as a singleton instead of being an
//injected instance that can be deleted when required
client.clearCookies();
client.clearCredentials();
client.setAccount(account);
account.loadCredentials(context);
client.setCredentials(account.getCredentials());
Timber.i("Client " + account.getName() + " with credentials size" + client.getAccount().getCredentials().getAuthToken().length());
}
reusingKnown = true; reusingKnown = true;
} }

View File

@ -112,6 +112,7 @@ public class AccountUtils {
String username = AccountUtils.getUsernameForAccount(account); String username = AccountUtils.getUsernameForAccount(account);
if (isOauth2) { if (isOauth2) {
Timber.i("Trying to retrieve credentials for oAuth account" + account.name);
String accessToken = am.blockingGetAuthToken( String accessToken = am.blockingGetAuthToken(
account, account,
AccountTypeUtils.getAuthTokenTypeAccessToken(account.type), AccountTypeUtils.getAuthTokenTypeAccessToken(account.type),

View File

@ -36,13 +36,7 @@ import com.owncloud.android.lib.common.http.HttpConstants.VALUE_FORMAT
import com.owncloud.android.lib.common.http.methods.nonwebdav.DeleteMethod import com.owncloud.android.lib.common.http.methods.nonwebdav.DeleteMethod
import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperation
import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.lib.resources.CommonOcsResponse
import com.owncloud.android.lib.resources.shares.responses.ShareItem
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import timber.log.Timber import timber.log.Timber
import java.lang.reflect.Type
import java.net.URL import java.net.URL
/** /**
@ -52,14 +46,10 @@ import java.net.URL
* @author David A. Velasco * @author David A. Velasco
* @author David González Verdugo * @author David González Verdugo
* @author Fernando Sanz Velasco * @author Fernando Sanz Velasco
*/
/**
* Constructor
* *
* @param remoteShareId Share ID * @param remoteShareId Share ID
*/ */
class RemoveRemoteShareOperation(private val remoteShareId: String) : RemoteOperation<ShareResponse>() { class RemoveRemoteShareOperation(private val remoteShareId: String) : RemoteOperation<Unit>() {
private fun buildRequestUri(baseUri: Uri) = private fun buildRequestUri(baseUri: Uri) =
baseUri.buildUpon() baseUri.buildUpon()
@ -68,24 +58,12 @@ class RemoveRemoteShareOperation(private val remoteShareId: String) : RemoteOper
.appendQueryParameter(PARAM_FORMAT, VALUE_FORMAT) .appendQueryParameter(PARAM_FORMAT, VALUE_FORMAT)
.build() .build()
private fun parseResponse(response: String): ShareResponse? {
val moshi = Moshi.Builder().build()
val listOfShareItemType: Type = Types.newParameterizedType(List::class.java, ShareItem::class.java)
val commonOcsType: Type = Types.newParameterizedType(CommonOcsResponse::class.java, listOfShareItemType)
val adapter: JsonAdapter<CommonOcsResponse<List<ShareItem>>> = moshi.adapter(commonOcsType)
return adapter.fromJson(response)?.ocs?.data?.let { listOfShareItems ->
ShareResponse(listOfShareItems.map { shareItem ->
shareItem.toRemoteShare()
})
}
}
private fun onResultUnsuccessful( private fun onResultUnsuccessful(
method: DeleteMethod, method: DeleteMethod,
response: String?, response: String?,
status: Int status: Int
): RemoteOperationResult<ShareResponse> { ): RemoteOperationResult<Unit> {
Timber.e("Failed response while unshare link ") Timber.e("Failed response while removing share ")
if (response != null) { if (response != null) {
Timber.e("*** status code: $status; response message: $response") Timber.e("*** status code: $status; response message: $response")
} else { } else {
@ -94,17 +72,14 @@ class RemoveRemoteShareOperation(private val remoteShareId: String) : RemoteOper
return RemoteOperationResult(method) return RemoteOperationResult(method)
} }
private fun onRequestSuccessful(response: String?): RemoteOperationResult<ShareResponse> { private fun onRequestSuccessful(response: String?): RemoteOperationResult<Unit> {
val result = RemoteOperationResult<ShareResponse>(RemoteOperationResult.ResultCode.OK) val result = RemoteOperationResult<Unit>(RemoteOperationResult.ResultCode.OK)
Timber.d("Successful response: $response") Timber.d("Successful response: $response")
result.data = parseResponse(response!!)
Timber.d("*** Unshare link completed ") Timber.d("*** Unshare link completed ")
return result return result
} }
override fun run(client: OwnCloudClient): RemoteOperationResult<ShareResponse> { override fun run(client: OwnCloudClient): RemoteOperationResult<Unit> {
val requestUri = buildRequestUri(client.baseUri) val requestUri = buildRequestUri(client.baseUri)
val deleteMethod = DeleteMethod(URL(requestUri.toString())).apply { val deleteMethod = DeleteMethod(URL(requestUri.toString())).apply {
@ -129,7 +104,7 @@ class RemoveRemoteShareOperation(private val remoteShareId: String) : RemoteOper
private fun isSuccess(status: Int): Boolean = status == HttpConstants.HTTP_OK private fun isSuccess(status: Int): Boolean = status == HttpConstants.HTTP_OK
companion object { companion object {
//OCS Route // OCS Route
private const val OCS_ROUTE = "ocs/v2.php/apps/files_sharing/api/v1/shares" private const val OCS_ROUTE = "ocs/v2.php/apps/files_sharing/api/v1/shares"
} }
} }

View File

@ -58,5 +58,5 @@ interface ShareService : Service {
publicUpload: Boolean publicUpload: Boolean
): RemoteOperationResult<ShareResponse> ): RemoteOperationResult<ShareResponse>
fun deleteShare(remoteId: String): RemoteOperationResult<ShareResponse> fun deleteShare(remoteId: String): RemoteOperationResult<Unit>
} }

View File

@ -36,8 +36,7 @@ import com.owncloud.android.lib.resources.shares.ShareType
import com.owncloud.android.lib.resources.shares.UpdateRemoteShareOperation import com.owncloud.android.lib.resources.shares.UpdateRemoteShareOperation
import com.owncloud.android.lib.resources.shares.services.ShareService import com.owncloud.android.lib.resources.shares.services.ShareService
class OCShareService(override val client: OwnCloudClient) : class OCShareService(override val client: OwnCloudClient) : ShareService {
ShareService {
override fun getShares( override fun getShares(
remoteFilePath: String, remoteFilePath: String,
reshares: Boolean, reshares: Boolean,
@ -90,7 +89,7 @@ class OCShareService(override val client: OwnCloudClient) :
this.retrieveShareDetails = true this.retrieveShareDetails = true
}.execute(client) }.execute(client)
override fun deleteShare(remoteId: String): RemoteOperationResult<ShareResponse> = override fun deleteShare(remoteId: String): RemoteOperationResult<Unit> =
RemoveRemoteShareOperation( RemoveRemoteShareOperation(
remoteId remoteId
).execute(client) ).execute(client)