diff --git a/app/src/main/kotlin/at/bitfire/davdroid/servicedetection/DavResourceFinder.kt b/app/src/main/kotlin/at/bitfire/davdroid/servicedetection/DavResourceFinder.kt index befcb345883a0a0d6b4d8da76bafdc726899badf..5889a5a0f23f2db02f0178d2260f185efa53ce0e 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/servicedetection/DavResourceFinder.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/servicedetection/DavResourceFinder.kt @@ -4,6 +4,7 @@ package at.bitfire.davdroid.servicedetection import android.content.Context +import android.util.Log import at.bitfire.dav4jvm.DavResource import at.bitfire.dav4jvm.Property import at.bitfire.dav4jvm.Response @@ -483,8 +484,10 @@ class DavResourceFinder( * - Re-throws the exception if it signals that the current thread was interrupted to stop the current operation. */ private fun processException(e: Exception) { - if (e is UnauthorizedException) + if (e is UnauthorizedException) { encountered401 = true + Log.d("DAVResourceFinder.processException()", "encountered401 is set to true") + } else if ((e is InterruptedIOException && e !is SocketTimeoutException) || e is InterruptedException) throw e diff --git a/app/src/main/kotlin/at/bitfire/davdroid/settings/AccountSettings.kt b/app/src/main/kotlin/at/bitfire/davdroid/settings/AccountSettings.kt index f13aa8f6c55f359952743847c173b21876e5861f..c53a8f1b078929d618fc78371aaf808f59f5fbfb 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/settings/AccountSettings.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/settings/AccountSettings.kt @@ -8,6 +8,7 @@ import android.accounts.AccountManager import android.content.* import android.os.Bundle import android.provider.CalendarContract +import android.util.Log import androidx.annotation.WorkerThread import at.bitfire.davdroid.Constants import at.bitfire.davdroid.InvalidAccountException @@ -641,10 +642,15 @@ class AccountSettings( } fun containsPersistentCookie(): Boolean { - return !accountManager.getUserData( + + + val cookie = accountManager.getUserData( account, NCAccountUtils.Constants.KEY_OKHTTP_COOKIES - ).isNullOrBlank() + ) + + Log.d("vincent", "cookie is: $cookie") + return !cookie.isNullOrBlank() } fun clearCookie() { diff --git a/app/src/main/kotlin/at/bitfire/davdroid/syncadapter/SyncManager.kt b/app/src/main/kotlin/at/bitfire/davdroid/syncadapter/SyncManager.kt index 2a6688353d9880c0e1cdb2f9922cf37023b4f303..796b6f7ab30fe271bfcb370901195e7cc86a0674 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/syncadapter/SyncManager.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/syncadapter/SyncManager.kt @@ -14,6 +14,7 @@ import android.net.Uri import android.os.RemoteException import android.provider.CalendarContract import android.provider.ContactsContract +import android.util.Log import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import at.bitfire.dav4jvm.* @@ -182,10 +183,12 @@ abstract class SyncManager, out CollectionType: L val authState = accountSettings.credentials().authState if (authState == null || !authState.needsTokenRefresh) { + Log.d("Vincent", "perform sync doesn't need to refresh token") performSync(DEFAULT_RETRY_AFTER, DEFAULT_SECOND_RETRY_AFTER, DEFAULT_MAX_RETRY_TIME) return } + Log.d("SyncManager.performSync()", "perform sync needs to refresh token") refreshAuthTokenAndSync(authState) } @@ -194,18 +197,11 @@ abstract class SyncManager, out CollectionType: L val clientSecretString = accountSettings.credentials().clientSecret val clientSecret = OpenIdUtils.getClientAuthentication(clientSecretString) + Log.d("SyncManager.performSync()", "Refreshing token") val authorizationService = AuthorizationService(context) + authorizationService.performTokenRequest(tokenRequest, clientSecret) { tokenResponse, ex -> authState.update(tokenResponse, ex) - accountSettings.credentials( - Credentials( - account.name, - null, - authState, - null, - clientSecret = clientSecretString - ) - ) accountSettings.credentials( Credentials( @@ -387,6 +383,14 @@ abstract class SyncManager, out CollectionType: L // all others else -> { + + // Caught HTTP 401 : user need to relogin/update credentials + // In this case we want to show a notification to indicate it to the user + if (e is UnauthorizedException) { + Log.d("Vincent", "caught unauthorized exception "+e.message) + //notifyException(e, local, remote) + } + // sometimes sync is kicked in when no network is not available. // In this case, we don't want to show notification to users. if (!NetworkUtils.isConnectedToNetwork(context)) { @@ -842,7 +846,7 @@ abstract class SyncManager, out CollectionType: L private fun notifyException(e: Throwable, local: ResourceType?, remote: HttpUrl?) { val message: String - + var title: String = localCollection.title when (e) { is IOException, is InterruptedIOException -> { @@ -851,12 +855,15 @@ abstract class SyncManager, out CollectionType: L syncResult.stats.numIoExceptions++ } is UnauthorizedException -> { - message = context.getString(R.string.sync_error_authentication_failed) + message = context.getString(R.string.account_notification_invalid_login) syncResult.stats.numAuthExceptions++ + title = "Account Manager" + Log.d("vincent", "numAuthException ? ${syncResult.stats.numAuthExceptions}") // persistent session cookie is present. Probably the session is outDated. no need to show the notification - if (accountSettings.containsPersistentCookie()) { + if (accountSettings.containsPersistentCookie() /*&& syncResult.stats.numAuthExceptions <= 1*/) { Logger.log.log(Level.FINE, "Authorization error. Session outDated") + Log.d("vincent", "containts persistent cookie so returnbefore notif") return } @@ -865,11 +872,14 @@ abstract class SyncManager, out CollectionType: L * https://gitlab.e.foundation/e/backlog/-/issues/3430 */ Logger.log.log(Level.WARNING, "Authorization error. Do not notify the user") + Log.d("Vincent", "containts google elt do not notif") return } + Log.d("Vincent", "user not authorized anymore") Logger.log.log(Level.SEVERE, "Not authorized anymore", e) } + is HttpException, is DavException -> { Logger.log.log(Level.SEVERE, "HTTP/DAV exception", e) message = context.getString(R.string.sync_error_http_dav, e.localizedMessage) @@ -893,6 +903,7 @@ abstract class SyncManager, out CollectionType: L if (account.type in AccountUtils.getMainAccountTypes(context) && (e is UnauthorizedException || e is NotFoundException)) { + Log.d("vincent", "Add intent to the notification ") contentIntent = Intent(context, SettingsActivity::class.java) contentIntent.putExtra(SettingsActivity.EXTRA_ACCOUNT, if (authority == ContactsContract.AUTHORITY) @@ -900,6 +911,7 @@ abstract class SyncManager, out CollectionType: L else account) } else { + Log.d("vincent", "Not an accountType in MainAccountType or not unauthorizedException or NotfoundException") contentIntent = buildDebugInfoIntent(e, local, remote) if (local != null) viewItemAction = buildViewItemAction(local) @@ -917,10 +929,10 @@ abstract class SyncManager, out CollectionType: L channel = NotificationUtils.CHANNEL_SYNC_ERRORS priority = NotificationCompat.PRIORITY_DEFAULT } - + Log.d("vincent", "about to build the notification if possible") val builder = NotificationUtils.newBuilder(context, channel) builder .setSmallIcon(R.drawable.ic_sync_problem_notify) - .setContentTitle(localCollection.title) + .setContentTitle(title) .setContentText(message) .setStyle(NotificationCompat.BigTextStyle(builder).bigText(message)) .setSubText(mainAccount.name) @@ -930,6 +942,7 @@ abstract class SyncManager, out CollectionType: L .setCategory(NotificationCompat.CATEGORY_ERROR) viewItemAction?.let { builder.addAction(it) } + Log.d("vincent", "about to try to notify if possible") notificationManager.notifyIfPossible(notificationTag, NotificationUtils.NOTIFY_SYNC_ERROR, builder.build()) } diff --git a/app/src/main/kotlin/at/bitfire/davdroid/syncadapter/SyncWorker.kt b/app/src/main/kotlin/at/bitfire/davdroid/syncadapter/SyncWorker.kt index 50f1fd84282e60dc1a16aa3f143f08d51630d47a..e2bb52f7d1cd5b218366c68a7d37e6897713fe2b 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/syncadapter/SyncWorker.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/syncadapter/SyncWorker.kt @@ -11,6 +11,7 @@ import android.net.wifi.WifiManager import android.os.Build import android.provider.CalendarContract import android.provider.ContactsContract +import android.util.Log import androidx.annotation.IntDef import androidx.concurrent.futures.CallbackToFutureAdapter import androidx.core.app.NotificationCompat @@ -382,6 +383,7 @@ class SyncWorker @AssistedInject constructor( if (isCookiePresent && result.stats.numAuthExceptions > 0) { // probably the session is outDated. retry without the sessionCookie + Log.d("vincent", "SyncWorker. Cookie is present so clearCookies & retry") accountSettings.clearCookie() return Result.retry() } diff --git a/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/DetectConfigurationFragment.kt b/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/DetectConfigurationFragment.kt index 92114462c591cc8ef88f598159f127d8a15182a7..58dbe82abdf3ec8aa86f7c7fba1f37f7d6fff652 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/DetectConfigurationFragment.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/DetectConfigurationFragment.kt @@ -7,6 +7,7 @@ package at.bitfire.davdroid.ui.setup import android.app.Application import android.app.Dialog import android.os.Bundle +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -68,6 +69,7 @@ class DetectConfigurationFragment: Fragment() { } else if(requireActivity().intent.getBooleanExtra(LoginActivity.RETRY_ON_401, false) && loginModel.configuration?.encountered401 == true) { // murena account has encounters 401, most-probably user put wrong accountId (ex: abc@murena.io instead of abc@e.email) // do nothing, EeloAuthenticatorFragment will retry with another time with another user email + Log.d("DetectConfigurationFragment.onCreate()", "encountered error 401. L72") return@observe } else { requireActivity().intent.putExtra(LoginActivity.RETRY_ON_401, false) @@ -139,8 +141,10 @@ class DetectConfigurationFragment: Fragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { var message = getString(R.string.login_no_caldav_carddav) - if (model.configuration?.encountered401 == true) + if (model.configuration?.encountered401 == true) { message += "\n\n" + getString(R.string.login_username_password_wrong) + Log.d("DetectConfigurationFragment.NothingDetectedFragment.onCreateDialog()", "config encountered401") + } return MaterialAlertDialogBuilder(requireActivity(), R.style.CustomAlertDialogStyle) .setTitle(R.string.login_configuration_detection) diff --git a/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/EeloAuthenticatorFragment.kt b/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/EeloAuthenticatorFragment.kt index 77b0252c74c3991a0685e53b924bf7db4da990a0..1522b62eb23b535818dc6706b912d5cfcae7ed6b 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/EeloAuthenticatorFragment.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/EeloAuthenticatorFragment.kt @@ -21,6 +21,7 @@ import android.content.Context import android.content.Intent import android.net.ConnectivityManager import android.os.Bundle +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -130,6 +131,7 @@ class EeloAuthenticatorFragment : Fragment() { if (requireActivity().intent.getBooleanExtra(LoginActivity.RETRY_ON_401, false) && switchUserName()) { // user wants to login with murena account, but most probably provided wrong accountId as email. // switching email is done, retry login + Log.d("EeloAuthenticatorFragment.onResume()", "encountered error 401 L134.") login() requireActivity().intent.putExtra(LoginActivity.RETRY_ON_401, false) // disable retry option to mitigate infinite looping } @@ -231,6 +233,7 @@ class EeloAuthenticatorFragment : Fragment() { // if user in any case provide wrong accountId as email (ex: abc@murena.io instead of abc@e.email) private fun addSupportRetryOn401IfPossible(serverUrl: String) { if ("https://${Constants.EELO_SYNC_HOST}" == serverUrl) { + Log.d("EeloAuthenticatoFragment.addSupportRetryOn401IfPossible", "intent.putExtra (retryon on 401 = true) L236") requireActivity().intent.putExtra(LoginActivity.RETRY_ON_401, true) } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2f0de73467f5bceeec749e8b747d9f01bc84fb65..45aedfba8c2789284587987ccbded922bd5df26a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -283,7 +283,7 @@ Create new calendar No Webcal-capable app found Install ICSx⁵ - + Your login/password is incorrect, please login again. Add account Use your Murena ID to sign in (for example @e.email or @murena.io):