diff --git a/synchronization/src/main/java/de/cyface/synchronization/WiFiSurveyor.java b/synchronization/src/main/java/de/cyface/synchronization/WiFiSurveyor.java
index de48aa980..559f9a8a8 100644
--- a/synchronization/src/main/java/de/cyface/synchronization/WiFiSurveyor.java
+++ b/synchronization/src/main/java/de/cyface/synchronization/WiFiSurveyor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 Cyface GmbH
+ * Copyright 2017-2024 Cyface GmbH
*
* This file is part of the Cyface SDK for Android.
*
@@ -49,8 +49,6 @@
*
* @author Klemens Muthmann
* @author Armin Schnabel
- * @version 7.2.1
- * @since 2.0.0
*/
public class WiFiSurveyor extends BroadcastReceiver {
@@ -374,8 +372,8 @@ public void makeAccountSyncable(@NonNull final Account account, boolean enabled)
* @return The only Account
existing
*/
public Account getAccount() {
- final AccountManager accountManager = AccountManager.get(context.get());
- final Account[] cyfaceAccounts = accountManager.getAccountsByType(accountType);
+ final var accountManager = AccountManager.get(context.get());
+ final var cyfaceAccounts = accountManager.getAccountsByType(accountType);
if (cyfaceAccounts.length == 0) {
throw new IllegalStateException("No cyface account exists.");
}
diff --git a/synchronization/src/main/kotlin/de/cyface/synchronization/AuthStateManager.kt b/synchronization/src/main/kotlin/de/cyface/synchronization/AuthStateManager.kt
index 79dad5c27..ee292566f 100644
--- a/synchronization/src/main/kotlin/de/cyface/synchronization/AuthStateManager.kt
+++ b/synchronization/src/main/kotlin/de/cyface/synchronization/AuthStateManager.kt
@@ -32,16 +32,10 @@ import java.util.concurrent.locks.ReentrantLock
* This stores the instance in a shared preferences file, and provides thread-safe access and
* mutation.
*/
-class AuthStateManager private constructor(context: Context) {
- private val mPrefs: SharedPreferences
- private val mPrefsLock: ReentrantLock
- private val mCurrentAuthState: AtomicReference
-
- init {
- mPrefs = context.getSharedPreferences(STORE_NAME, Context.MODE_PRIVATE)
- mPrefsLock = ReentrantLock()
- mCurrentAuthState = AtomicReference()
- }
+class AuthStateManager private constructor(private val context: Context) {
+ private val mPrefs: SharedPreferences = context.getSharedPreferences(STORE_NAME, Context.MODE_PRIVATE)
+ private val mPrefsLock: ReentrantLock = ReentrantLock()
+ private val mCurrentAuthState: AtomicReference = AtomicReference()
@get:AnyThread
val current: AuthState
diff --git a/synchronization/src/main/kotlin/de/cyface/synchronization/CyfaceAuthenticator.kt b/synchronization/src/main/kotlin/de/cyface/synchronization/CyfaceAuthenticator.kt
index 989a34ee6..c0b5c5fae 100644
--- a/synchronization/src/main/kotlin/de/cyface/synchronization/CyfaceAuthenticator.kt
+++ b/synchronization/src/main/kotlin/de/cyface/synchronization/CyfaceAuthenticator.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2023 Cyface GmbH
+ * Copyright 2018-2024 Cyface GmbH
*
* This file is part of the Cyface SDK for Android.
*
@@ -44,13 +44,11 @@ import kotlinx.coroutines.runBlocking
*
* @author Klemens Muthmann
* @author Armin Schnabel
- * @version 5.1.1
- * @since 2.0.0
*/
class CyfaceAuthenticator(private val context: Context) :
AbstractAccountAuthenticator(context), LoginActivityProvider {
- private var auth: OAuth2 = OAuth2(context, settings)
+ var auth: OAuth2 = OAuth2(context, settings, "CyfaceAuthenticator")
override fun editProperties(
response: AccountAuthenticatorResponse,
diff --git a/synchronization/src/main/kotlin/de/cyface/synchronization/CyfaceAuthenticatorService.kt b/synchronization/src/main/kotlin/de/cyface/synchronization/CyfaceAuthenticatorService.kt
index 24248d9f3..049a58d9b 100644
--- a/synchronization/src/main/kotlin/de/cyface/synchronization/CyfaceAuthenticatorService.kt
+++ b/synchronization/src/main/kotlin/de/cyface/synchronization/CyfaceAuthenticatorService.kt
@@ -21,7 +21,6 @@ package de.cyface.synchronization
import android.app.Service
import android.content.Intent
import android.os.IBinder
-import android.util.Log
/**
* The Android service used to communicate with the Stub Authenticator. This has been implemented as described in
@@ -29,8 +28,6 @@ import android.util.Log
*
* @author Klemens Muthmann
* @author Armin Schnabel
- * @version 1.0.7
- * @since 2.0.0
*/
class CyfaceAuthenticatorService : Service() {
/**
diff --git a/synchronization/src/main/kotlin/de/cyface/synchronization/CyfaceSyncService.kt b/synchronization/src/main/kotlin/de/cyface/synchronization/CyfaceSyncService.kt
index 50b485e8c..538efe679 100644
--- a/synchronization/src/main/kotlin/de/cyface/synchronization/CyfaceSyncService.kt
+++ b/synchronization/src/main/kotlin/de/cyface/synchronization/CyfaceSyncService.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2023 Cyface GmbH
+ * Copyright 2017-2024 Cyface GmbH
*
* This file is part of the Cyface SDK for Android.
*
@@ -34,8 +34,6 @@ import kotlinx.coroutines.runBlocking
*
* @author Armin Schnabel
* @author Klemens Muthmann
- * @version 1.0.9
- * @since 2.0.0
*/
class CyfaceSyncService : Service() {
@@ -46,7 +44,7 @@ class CyfaceSyncService : Service() {
syncAdapter = SyncAdapter(
applicationContext,
true,
- OAuth2(applicationContext, CyfaceAuthenticator.settings),
+ OAuth2(applicationContext, CyfaceAuthenticator.settings, "CyfaceSyncService"),
DefaultUploader(collectorApi),
)
}
diff --git a/synchronization/src/main/kotlin/de/cyface/synchronization/OAuth2.kt b/synchronization/src/main/kotlin/de/cyface/synchronization/OAuth2.kt
index 1acca884b..e584f5128 100644
--- a/synchronization/src/main/kotlin/de/cyface/synchronization/OAuth2.kt
+++ b/synchronization/src/main/kotlin/de/cyface/synchronization/OAuth2.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Cyface GmbH
+ * Copyright 2023-2024 Cyface GmbH
*
* This file is part of the Cyface SDK for Android.
*
@@ -22,7 +22,6 @@ import android.accounts.Account
import android.accounts.AccountManager
import android.content.ContentResolver
import android.content.Context
-import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.util.Log
@@ -38,7 +37,6 @@ import net.openid.appauth.AuthState
import net.openid.appauth.AuthorizationException
import net.openid.appauth.AuthorizationResponse
import net.openid.appauth.AuthorizationService
-import net.openid.appauth.AuthorizationServiceConfiguration
import net.openid.appauth.ClientAuthentication
import net.openid.appauth.EndSessionRequest
import net.openid.appauth.TokenRequest
@@ -52,12 +50,10 @@ import org.json.JSONObject
* accounts, and handling sessions.
*
* @author Armin Schnabel
- * @version 1.0.0
- * @since 7.9.0
* @param context The context to load settings and accounts from.
* @param settings The settings which store the user preferences.
*/
-class OAuth2(context: Context, settings: SynchronizationSettings) : Auth {
+class OAuth2(context: Context, settings: SynchronizationSettings, caller: String) : Auth {
/**
* The service used for authorization.
@@ -67,23 +63,21 @@ class OAuth2(context: Context, settings: SynchronizationSettings) : Auth {
/**
* The authorization state.
*/
- private var stateManager: AuthStateManager
+ private var stateManager: AuthStateManager = AuthStateManager.getInstance(context)
/**
* The configuration of the OAuth 2 endpoint to authorize against.
*/
- private var configuration: Configuration
+ private var configuration: Configuration = Configuration.getInstance(context, settings)
init {
- // Authorization
- stateManager = AuthStateManager.getInstance(context)
- configuration = Configuration.getInstance(context, settings)
/*if (config.hasConfigurationChanged()) {
//throw IllegalArgumentException("config changed (SyncAdapter)")
Toast.makeText(context, "Ignoring: config changed (SyncAdapter)", Toast.LENGTH_SHORT).show()
//Handler().postDelayed({signOut()}, 2000)
//return
}*/
+ Log.i(TAG, "OAuth2 init ($caller)")
authService = AuthorizationService(
context,
AppAuthConfiguration.Builder()
@@ -259,7 +253,7 @@ class OAuth2(context: Context, settings: SynchronizationSettings) : Auth {
fun signOut() {
// discard the authorization and token state, but retain the configuration and
// dynamic client registration (if applicable), to save from retrieving them again.
- val currentState: AuthState = stateManager.current
+ val currentState = stateManager.current
if (currentState.authorizationServiceConfiguration != null) {
// Replace the state with a fresh `AuthState`
val clearedState = AuthState(currentState.authorizationServiceConfiguration!!)
@@ -267,16 +261,26 @@ class OAuth2(context: Context, settings: SynchronizationSettings) : Auth {
clearedState.update(currentState.lastRegistrationResponse)
}
stateManager.replace(clearedState)
+
+ // [LEIP-233] Completely deleting the sharedPreferences/AuthState.xml file does not
+ // fix the `Credentials incorrect` error after re-login (app restart required)
+ //stateManager.deletePreferencesFile()
+ } else {
+ Log.w(TAG, "No authorization service configuration to sign out")
}
+
+ // Invalidate all tokens to ensure they are no longer used
+ dispose()
}
- // Keep: login is currently just deactivated because it's buggy
+ /**
+ * Sends the end session request to the auth service to sign out the user.
+ */
fun endSession(activity: FragmentActivity) {
- val currentState: AuthState = stateManager.current
- val config: AuthorizationServiceConfiguration =
- currentState.authorizationServiceConfiguration!!
+ val currentState = stateManager.current
+ val config = currentState.authorizationServiceConfiguration!!
if (config.endSessionEndpoint != null) {
- val endSessionIntent: Intent = authService.getEndSessionRequestIntent(
+ val endSessionIntent = authService.getEndSessionRequestIntent(
EndSessionRequest.Builder(config)
.setIdTokenHint(currentState.idToken)
.setPostLogoutRedirectUri(configuration.endSessionRedirectUri)
@@ -310,4 +314,4 @@ class OAuth2(context: Context, settings: SynchronizationSettings) : Auth {
.put("https_required", true)
}
}
-}
\ No newline at end of file
+}