diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6e519ba518bdcad01dc2f989d607a388654c6120..a06756be5d0fe7a460b76e16d71846e93e2b9c5c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,6 +6,7 @@ variables: UNSIGNED_APK: "davx5-ose-release-unsigned.apk" COMMUNITY_APK: "Account_manager_community.apk" OFFICIAL_APK: "Account_manager_official.apk" + TEST_APK: "Account_manager_test.apk" stages: - update-from-upstream @@ -15,7 +16,6 @@ stages: before_script: - echo email.key=$PEPPER >> local.properties - echo MURENA_CLIENT_ID=$MURENA_CLIENT_ID >> local.properties - - echo MURENA_CLIENT_SECRET=$MURENA_CLIENT_SECRET >> local.properties - echo MURENA_REDIRECT_URI=$MURENA_REDIRECT_URI >> local.properties - echo MURENA_LOGOUT_REDIRECT_URI=$MURENA_LOGOUT_REDIRECT_URI >> local.properties - echo MURENA_BASE_URL=$MURENA_BASE_URL >> local.properties @@ -75,12 +75,13 @@ generate-apks: script: - | ./systemAppsUpdateInfo/scripts/generate-apks.sh \ - "$APK_PATH" "$UNSIGNED_APK" "$COMMUNITY_APK" "$OFFICIAL_APK" + "$APK_PATH" "$UNSIGNED_APK" "$COMMUNITY_APK" "$OFFICIAL_APK" "$TEST_APK" artifacts: paths: - $APK_PATH/$UNSIGNED_APK - $APK_PATH/$COMMUNITY_APK - $APK_PATH/$OFFICIAL_APK + - $APK_PATH/$TEST_APK create-json-files: stage: gitlab_release @@ -92,17 +93,37 @@ create-json-files: - generate-apks rules: - if: '$CI_COMMIT_TAG && $CI_COMMIT_REF_PROTECTED == "true"' - when: manual + when: on_success before_script: - apt update && apt install jq aapt -y script: - | ./systemAppsUpdateInfo/scripts/create-json-files.sh \ - "$APK_PATH" "$UNSIGNED_APK" "$COMMUNITY_APK" "$OFFICIAL_APK" + "$APK_PATH" "$UNSIGNED_APK" "$COMMUNITY_APK" "$OFFICIAL_APK" "$TEST_APK" artifacts: paths: - community.json - official.json + - test.json + +create-test-release: + stage: gitlab_release + dependencies: + - init_submodules + needs: + - init_submodules + - create-json-files + - generate-apks + rules: + - if: '$CI_COMMIT_TAG && $CI_COMMIT_REF_PROTECTED == "true"' + when: manual + before_script: + - apt update && apt install jq -y + script: + - | + ./systemAppsUpdateInfo/scripts/create-test-release.sh \ + "$APK_PATH" "$TEST_APK" + allow_failure: true create-release: stage: gitlab_release @@ -114,13 +135,14 @@ create-release: - generate-apks rules: - if: '$CI_COMMIT_TAG && $CI_COMMIT_REF_PROTECTED == "true"' - when: on_success + when: manual before_script: - apt update && apt install jq -y script: - | ./systemAppsUpdateInfo/scripts/create-release.sh \ "$APK_PATH" "$UNSIGNED_APK" "$COMMUNITY_APK" "$OFFICIAL_APK" + allow_failure: true .update-from-upstream: stage: update-from-upstream diff --git a/app/build.gradle b/app/build.gradle index 0904d4364eacd09f6c8c0367d6eb9880d005981a..3214eb1b5c3917bc6f65e4dba52ab3809b03d333 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -30,7 +30,7 @@ android { setProperty "archivesBaseName", "davx5-ose-" + getVersionName() - minSdkVersion 24 // Android 7.0 + minSdkVersion 26 // Android 9.0 targetSdkVersion 33 // Android 13 buildConfigField "String", "userAgent", "\"AccountManager\"" @@ -113,7 +113,6 @@ android { defaultConfig { buildConfigField "String", "MURENA_CLIENT_ID", "\"${retrieveKey("MURENA_CLIENT_ID")}\"" - buildConfigField "String", "MURENA_CLIENT_SECRET", "\"${retrieveKey("MURENA_CLIENT_SECRET")}\"" buildConfigField "String", "MURENA_REDIRECT_URI", "\"${retrieveKey("MURENA_REDIRECT_URI")}\"" buildConfigField "String", "MURENA_LOGOUT_REDIRECT_URI", "\"${retrieveKey("MURENA_LOGOUT_REDIRECT_URI")}\"" buildConfigField "String", "MURENA_BASE_URL", "\"${retrieveKey("MURENA_BASE_URL")}\"" @@ -156,6 +155,7 @@ configurations { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:${versions.kotlin}" implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3' + implementation 'androidx.activity:activity:1.9.3' testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 30e04639bf227a9af7c83a4dbc1829bca94a65c0..98bccdcca2ebd48352910f89cd049b22b66ffe4f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,118 +1,170 @@ - + xmlns:tools="http://schemas.android.com/tools" + android:installLocation="internalOnly"> - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - + + + + - - - - + - fine location (Android 10) + --> + + + + + + - + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + android:supportsRtl="true" + android:theme="@style/AppTheme" + tools:ignore="UnusedAttribute"> + - + tools:node="remove"> - + - - - - - - + + + - + + + + + android:theme="@style/AppTheme.NoActionBar"> - - + + + - - + android:parentActivityName=".ui.AccountsActivity" + android:theme="@style/AppTheme.NoActionBar" /> + android:parentActivityName=".ui.AccountsActivity"> - + + + android:label="@string/debug_info_title" + android:parentActivityName=".ui.AppSettingsActivity"> - + + @@ -124,43 +176,43 @@ android:name=".ui.TasksActivity" android:label="@string/intro_tasks_title" android:parentActivityName=".ui.AppSettingsActivity" /> - + android:exported="true" + android:label="@string/login_title" + android:parentActivityName=".ui.AccountsActivity"> - + - - - - - - - - + + + + + + + + + + + - - - - + android:theme="@style/AppTheme.NoActionBar"> - + android:parentActivityName=".ui.AccountsActivity" /> - - - - + - + + + android:resource="@xml/account_authenticator" /> - + + + android:resource="@xml/sync_calendars" /> - + + + android:resource="@xml/sync_notes" /> - + + + android:resource="@xml/sync_opentasks" /> - + + + android:resource="@xml/sync_tasks_org" /> + - - - + + android:exported="true"> - + + android:resource="@xml/account_authenticator_address_book" /> + + android:label="@string/address_books_authority_title" /> + - + + android:resource="@xml/sync_address_books" /> - + + android:resource="@xml/sync_contacts" /> - - - + android:resource="@xml/contacts" /> + @@ -313,22 +366,20 @@ android:name="android.accounts.AccountAuthenticator" android:resource="@xml/eelo_account_authenticator" /> - - - + - - - - - - + - - - - - - + - - - - - + @@ -425,7 +468,6 @@ android:name="android.accounts.AccountAuthenticator" android:resource="@xml/account_authenticator_eelo_address_book" /> - - - + - - - + @@ -469,8 +508,7 @@ android:name="android.accounts.AccountAuthenticator" android:resource="@xml/google_account_authenticator" /> - - - - + - - - + @@ -510,7 +545,6 @@ android:name="android.accounts.AccountAuthenticator" android:resource="@xml/account_authenticator_google_address_book" /> - - - + - - - - - + @@ -568,7 +598,6 @@ android:name="android.accounts.AccountAuthenticator" android:resource="@xml/yahoo_account_authenticator" /> - - - - - - + @@ -623,7 +648,6 @@ android:name="android.accounts.AccountAuthenticator" android:resource="@xml/account_authenticator_yahoo_address_book" /> - - - - - - + + + android:exported="false" + android:grantUriPermissions="true"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/java/at/bitfire/davdroid/ReLoginWithOidcActivity.kt b/app/src/main/java/at/bitfire/davdroid/ReLoginWithOidcActivity.kt new file mode 100644 index 0000000000000000000000000000000000000000..f9fc6f7834795b5829e733c7a2ce8ecf29cf4eef --- /dev/null +++ b/app/src/main/java/at/bitfire/davdroid/ReLoginWithOidcActivity.kt @@ -0,0 +1,82 @@ +package at.bitfire.davdroid + +import android.accounts.AccountManager +import android.accounts.AccountManager.KEY_ACCOUNT_NAME +import android.accounts.AccountManager.KEY_ACCOUNT_TYPE +import android.accounts.AccountManager.KEY_BOOLEAN_RESULT +import android.accounts.AccountManagerFuture +import android.accounts.AuthenticatorException +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import at.bitfire.davdroid.log.Logger +import com.owncloud.android.lib.common.operations.OperationCancelledException +import java.io.IOException + +class ReLoginWithOidcActivity : AppCompatActivity() { + + override fun onStart() { + super.onStart() + + val accountName = intent?.extras?.getString(KEY_ACCOUNT_NAME, null) ?: run { + finish() + return + } + + logoutAccount(accountName) + } + + private fun logoutAccount(accountName: String) + { + val accountManager = AccountManager.get(this) + val eAccounts= accountManager.getAccountsByType(applicationContext.getString(R.string.eelo_account_type)) + val activity = this + + val accountRemovalCallback: (AliasFuture) -> Unit = { future -> + val success = future.result.getBoolean(KEY_BOOLEAN_RESULT) + + if (success) { + Logger.log.info("Vincent: $accountName removed") + loginAccount() + } else { + Logger.log.info("failed to remove account: $accountName ") + } + } + + + + eAccounts.firstOrNull() { it.name == accountName }?.run { + Logger.log.info("Vincent: try to remove account: ${this.name} ") //todo remove this before merge + accountManager.removeAccount(this, activity, accountRemovalCallback, null) + + } ?: finish() + } + + private fun loginAccount() { + val accountManager = AccountManager.get(this) + val eAccountType = applicationContext.getString(R.string.eelo_account_type) + + Logger.log.info("Vincent: Will start add Account Session for: $eAccountType account type") + + try { + + accountManager.addAccount(eAccountType, + null, + null, + null, + this, + null, + null + ) + } catch (exception: AuthenticatorException) { + Logger.log.info("Vincent: AuthenticatorException: can't add account: ${exception.message}") + } catch (exception: IOException) { + Logger.log.info("Vincent: IOException: can't add account: ${exception.message}") + } catch (exception: OperationCancelledException) { + Logger.log.info("Vincent: OperationCancelledException: can't add account: ${exception.message}") + } catch (exception: Exception) { + Logger.log.info("Vincent: catch unexpected exception: ${exception.message}") + } + } +} + +typealias AliasFuture = AccountManagerFuture diff --git a/app/src/main/kotlin/at/bitfire/davdroid/authorization/IdentityProvider.kt b/app/src/main/kotlin/at/bitfire/davdroid/authorization/IdentityProvider.kt index c7cdbf441ea4fa42e66ad27a567187019f1c48f7..02e8437946b2b9d60abed5d87197e535ce459acc 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/authorization/IdentityProvider.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/authorization/IdentityProvider.kt @@ -42,7 +42,7 @@ enum class IdentityProvider( authEndpoint = null, tokenEndpoint = null, clientId = BuildConfig.MURENA_CLIENT_ID, - clientSecret = BuildConfig.MURENA_CLIENT_SECRET, + clientSecret = null, redirectUri = BuildConfig.MURENA_REDIRECT_URI + ":/redirect", logoutRedirectUri = BuildConfig.MURENA_LOGOUT_REDIRECT_URI + ":/redirect", scope = "openid profile email offline_access", diff --git a/app/src/main/kotlin/at/bitfire/davdroid/network/HttpClient.kt b/app/src/main/kotlin/at/bitfire/davdroid/network/HttpClient.kt index b5fff9d5f4d9fb22c97e836c11e0bd55dbab44c1..d61ba172aaa8769b9f91b9414e5f20795a12bc7b 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/network/HttpClient.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/network/HttpClient.kt @@ -89,8 +89,12 @@ class HttpClient private constructor( } override fun close() { - authService?.dispose() - okHttpClient.cache?.close() + try { + okHttpClient.cache?.close() + authService?.dispose() + } catch (e: Exception) { + Logger.log.log(Level.INFO, "failed to clear resource on close httpClient", e) + } } diff --git a/app/src/main/kotlin/at/bitfire/davdroid/receiver/BootCompletedReceiver.kt b/app/src/main/kotlin/at/bitfire/davdroid/receiver/BootCompletedReceiver.kt index d769750815e6293becf5334a2a931129bcf60fb6..c79b544f15eeffbceab5c1fdd8ebb8db0f9fdfc9 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/receiver/BootCompletedReceiver.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/receiver/BootCompletedReceiver.kt @@ -4,12 +4,22 @@ package at.bitfire.davdroid.receiver +import android.accounts.Account +import android.accounts.AccountManager +import android.app.PendingIntent import android.content.BroadcastReceiver import android.content.Context import android.content.Intent +import androidx.core.app.NotificationManagerCompat +import at.bitfire.davdroid.R +import at.bitfire.davdroid.ReLoginWithOidcActivity import at.bitfire.davdroid.log.Logger import at.bitfire.davdroid.settings.AccountSettings import at.bitfire.davdroid.syncadapter.AccountUtils +import at.bitfire.davdroid.ui.NotificationUtils +import at.bitfire.davdroid.ui.NotificationUtils.CHANNEL_GENERAL +import at.bitfire.davdroid.ui.NotificationUtils.NOTIFY_SWITCH_TO_OPENID +import at.bitfire.davdroid.ui.NotificationUtils.notifyIfPossible /** * There are circumstances when Android drops automatic sync of accounts and resets them @@ -22,12 +32,57 @@ class BootCompletedReceiver: BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { Logger.log.info("Device has been rebooted; checking sync intervals etc.") + + val eAccountType = context.getString(R.string.eelo_account_type) + + val accountManager = AccountManager.get(context) + // sync intervals are checked in App.onCreate() AccountUtils.getMainAccounts(context) .forEach { - val accountSettings = AccountSettings(context, it) - accountSettings.initSync() + if (eAccountType == it.type && !isLoggedWithOpenId(it, accountManager)) { + Logger.log.info("Vincent: eAccountFound. Will notify") + notifySwitchToOpenId(it, context) + } else { + val accountSettings = AccountSettings(context, it) + accountSettings.initSync() + } } } -} \ No newline at end of file + private fun isLoggedWithOpenId(account: Account, accountManager: AccountManager): Boolean { + val hasAuthStateData = accountManager.getUserData(account, AccountSettings.KEY_AUTH_STATE) != null + val isPasswordNull = accountManager.getPassword(account).isNullOrEmpty() + return isPasswordNull && hasAuthStateData + } + + private fun notifySwitchToOpenId(account: Account, context: Context) { + val notifTag = "Switch to openID" + val notifTitle = context.getString(R.string.notification_account_title, account.name) + val notifText = context.getString(R.string.notification_switch_to_openId_text) + val notifIntent = generateLogoutIntent(account.name, context) + + val notification = NotificationUtils.newBuilder(context, CHANNEL_GENERAL) + .setContentTitle(notifTitle) + .setContentText(notifText) + .setSmallIcon(R.drawable.ic_info) + .setContentIntent(notifIntent) + .setAutoCancel(true) + .build() + + val notificationManager = NotificationManagerCompat.from(context) + notificationManager.notifyIfPossible(notifTag, NOTIFY_SWITCH_TO_OPENID, notification) + } + + private fun generateLogoutIntent(accountName: String, context: Context): PendingIntent { + val reLoginIntent = Intent(context, ReLoginWithOidcActivity::class.java).apply { + flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + putExtra(AccountManager.KEY_ACCOUNT_NAME, accountName) + } + + return PendingIntent.getActivity(context, + 0, + reLoginIntent, + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE) + } +} diff --git a/app/src/main/kotlin/at/bitfire/davdroid/syncadapter/DefaultAccountAuthenticatorService.kt b/app/src/main/kotlin/at/bitfire/davdroid/syncadapter/DefaultAccountAuthenticatorService.kt index da635b072b8bed3064dbdc3864a779fbbe13d8fd..16adca03594c599a969c3e46ec26cd7ab4df36f9 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/syncadapter/DefaultAccountAuthenticatorService.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/syncadapter/DefaultAccountAuthenticatorService.kt @@ -232,7 +232,11 @@ abstract class DefaultAccountAuthenticatorService : Service(), OnAccountsUpdateL result.putString(AccountManager.KEY_AUTHTOKEN, authState.accessToken) response?.onResult(result) - authorizationService.dispose() + try { + authorizationService.dispose() + } catch (e: Exception) { + Logger.log.log(Level.INFO, "failed to dispose oidc authorizationService", e) + } } val result = Bundle() 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 eb36c64150b60b7474b7012d4cfbffce1fff6e64..ae3b479bb536e8fb19ad9d56f7d7aa04cee9baa8 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/syncadapter/SyncManager.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/syncadapter/SyncManager.kt @@ -211,7 +211,11 @@ abstract class SyncManager, out CollectionType: L performSync(DEFAULT_RETRY_AFTER, DEFAULT_SECOND_RETRY_AFTER, DEFAULT_MAX_RETRY_TIME) } - authorizationService.dispose() + try { + authorizationService.dispose() + } catch (e: Exception) { + Logger.log.log(Level.INFO, "failed to dispose oidc authorizationService", e) + } } } diff --git a/app/src/main/kotlin/at/bitfire/davdroid/ui/NotificationUtils.kt b/app/src/main/kotlin/at/bitfire/davdroid/ui/NotificationUtils.kt index e41544d538bb2a6f08bda820781ad4d7361c0c77..4e6f04fe5598b3aafe9c1bf16b487d5bb33f4405 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/ui/NotificationUtils.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/ui/NotificationUtils.kt @@ -34,6 +34,7 @@ object NotificationUtils { const val NOTIFY_SYNC_EXPEDITED = 14 const val NOTIFY_TASKS_PROVIDER_TOO_OLD = 20 const val NOTIFY_PERMISSIONS = 21 + const val NOTIFY_SWITCH_TO_OPENID = 22 const val NOTIFY_LICENSE = 100 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..be7d2750ebfd1a313d2f533a49030241b5e9de35 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 @@ -10,7 +10,6 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.core.content.ContextCompat import androidx.fragment.app.DialogFragment import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels @@ -18,14 +17,13 @@ import androidx.fragment.app.viewModels import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import at.bitfire.davdroid.Constants +import at.bitfire.davdroid.ECloudAccountHelper import at.bitfire.davdroid.R import at.bitfire.davdroid.db.Credentials import at.bitfire.davdroid.log.Logger import at.bitfire.davdroid.servicedetection.DavResourceFinder import at.bitfire.davdroid.ui.DebugInfoActivity import com.google.android.material.dialog.MaterialAlertDialogBuilder -import at.bitfire.davdroid.ECloudAccountHelper import java.lang.ref.WeakReference import java.net.URI import java.util.logging.Level @@ -47,7 +45,7 @@ class DetectConfigurationFragment: Fragment() { return } - val blockOnUnauthorizedException = (accountType == getString(R.string.eelo_account_type)) && !EeloAuthenticatorModel.enableOpenIdSupport + val blockOnUnauthorizedException = (accountType == getString(R.string.eelo_account_type)) && !EeloAuthenticatorModel.ENABLE_OIDC_SUPPORT val baseURI = loginModel.baseURI ?: return 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..47bbafcf0a99699cb6dd64f25363688010eca628 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 @@ -79,7 +79,7 @@ class EeloAuthenticatorFragment : Fragment() { passwordEditText = v.root.findViewById(R.id.urlpwd_password) passwordHolder = v.root.findViewById(R.id.password_holder) - passwordHolder.isVisible = !EeloAuthenticatorModel.enableOpenIdSupport + passwordHolder.isVisible = !EeloAuthenticatorModel.ENABLE_OIDC_SUPPORT serverToggleButton.setOnClickListener { expandCollapse() } @@ -87,7 +87,7 @@ class EeloAuthenticatorFragment : Fragment() { val tfaButton = v.root.findViewById(R.id.twofa_info_button) tfaButton.setOnClickListener { show2FAInfoDialog() } - tfaButton.isVisible = !EeloAuthenticatorModel.enableOpenIdSupport + tfaButton.isVisible = !EeloAuthenticatorModel.ENABLE_OIDC_SUPPORT userIdEditText.doOnTextChanged { text, _, _, _ -> val domain = computeDomain(text) @@ -205,7 +205,7 @@ class EeloAuthenticatorFragment : Fragment() { private fun login() { handleNoNetworkAvailable() - val handleOpenIdAuth = EeloAuthenticatorModel.enableOpenIdSupport && !toggleButtonState + val handleOpenIdAuth = EeloAuthenticatorModel.ENABLE_OIDC_SUPPORT && !toggleButtonState val userId = userIdEditText.text.toString() val password = passwordEditText.text.toString() @@ -306,7 +306,7 @@ class EeloAuthenticatorFragment : Fragment() { serverUrlEditText.isEnabled = false toggleButtonState = false - if(!EeloAuthenticatorModel.enableOpenIdSupport) { + if(!EeloAuthenticatorModel.ENABLE_OIDC_SUPPORT) { return } diff --git a/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/EeloAuthenticatorModel.kt b/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/EeloAuthenticatorModel.kt index c65296df1a15c71d505ded1a55fa11ec712ec70f..9b05b2e607c7b685007da8fa8d3b8e480db0fa75 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/EeloAuthenticatorModel.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/EeloAuthenticatorModel.kt @@ -27,7 +27,7 @@ class EeloAuthenticatorModel(application: Application) : AndroidViewModel(applic companion object { // as https://gitlab.e.foundation/e/backlog/-/issues/6287 is blocked, the openId implementation is not ready yet. // But we want to push the changes so later we won't face any conflict. So we are disabling the openId feature for now. - const val enableOpenIdSupport = false + const val ENABLE_OIDC_SUPPORT = true } private var initialized = false diff --git a/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/GoogleLoginFragment.kt b/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/GoogleLoginFragment.kt index 6ef6e097182ba92726b5ec4a011675ce909c0478..21c91f48856e1ac3b3f92c63008b572288584f31 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/GoogleLoginFragment.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/GoogleLoginFragment.kt @@ -209,7 +209,11 @@ class GoogleLoginFragment(private val defaultEmail: String? = null): Fragment() } override fun onCleared() { - authService.dispose() + try { + authService.dispose() + } catch (e: Exception) { + Logger.log.log(Level.INFO, "failed to dispose oidc authorizationService", e) + } } } diff --git a/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/OpenIdAuthenticationViewModel.kt b/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/OpenIdAuthenticationViewModel.kt index 175872dc535f3ca318c76db71bfc31a20cc6ccd3..f777a8d805919302b1940b0e8164318cbfa33988 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/OpenIdAuthenticationViewModel.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/OpenIdAuthenticationViewModel.kt @@ -62,8 +62,13 @@ class OpenIdAuthenticationViewModel(application: Application) : AndroidViewModel } override fun onCleared() { - authorizationService.dispose() super.onCleared() + try { + authorizationService.dispose() + } catch (e: Exception) { + Logger.log.log(Level.INFO, "failed to dispose oidc authorizationService", e) + } + } fun getAuthState(): AuthState { diff --git a/app/src/main/kotlin/at/bitfire/davdroid/ui/signout/OpenIdEndSessionActivity.kt b/app/src/main/kotlin/at/bitfire/davdroid/ui/signout/OpenIdEndSessionActivity.kt index 631e4b8f75200e1bb1bec926f08d20d32bc70e00..5001315b45ea2301eda19a1f7cfa39f6f6207e73 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/ui/signout/OpenIdEndSessionActivity.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/ui/signout/OpenIdEndSessionActivity.kt @@ -20,11 +20,13 @@ import android.accounts.AccountManager import android.app.Activity import android.os.Bundle import at.bitfire.davdroid.authorization.IdentityProvider +import at.bitfire.davdroid.log.Logger import at.bitfire.davdroid.settings.AccountSettings import net.openid.appauth.AuthState import net.openid.appauth.AuthorizationService import net.openid.appauth.AuthorizationServiceConfiguration import net.openid.appauth.EndSessionRequest +import java.util.logging.Level class OpenIdEndSessionActivity : Activity() { @@ -79,7 +81,12 @@ class OpenIdEndSessionActivity : Activity() { } override fun onDestroy() { - authorizationService?.dispose() super.onDestroy() + + try { + authorizationService?.dispose() + } catch (e: Exception) { + Logger.log.log(Level.INFO, "failed to dispose oidc authorizationService", e) + } } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 47579443b9ea55469724ce5d64711d1afbc71c1f..e08b3c0048f040376e776c642aadedb5b5867229 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -43,6 +43,7 @@ Database corrupted All accounts have been removed locally. + Debugging Other important messages Low-priority status messages @@ -53,6 +54,8 @@ Non-fatal synchronization problems like certain invalid files Network and I/O errors Timeouts, connection problems, etc. (often temporary) + Your account %1$s + A new login service for a better experience is available. Tap the notification to start using it. Your data. Your choice. diff --git a/build.gradle b/build.gradle index e969706ab4a9dd19c37b22e1bac029d0e9bb1092..22f24469ede8926b369f1d9947eb4ee50da827a9 100644 --- a/build.gradle +++ b/build.gradle @@ -43,6 +43,7 @@ buildscript { plugins { // see https://github.com/google/ksp/releases for version numbers id 'com.google.devtools.ksp' version '1.9.10-1.0.13' apply false + id 'org.jetbrains.kotlin.android' version '1.9.10' apply false } allprojects {