Skip to content

Commit

Permalink
Add logout support
Browse files Browse the repository at this point in the history
  • Loading branch information
hb0 committed May 18, 2024
1 parent c9116c9 commit 2706d17
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,8 @@ public void makeAccountSyncable(@NonNull final Account account, boolean enabled)
* @return The only <code>Account</code> 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.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import net.openid.appauth.AuthorizationResponse
import net.openid.appauth.RegistrationResponse
import net.openid.appauth.TokenResponse
import org.json.JSONException
import java.io.File
import java.lang.ref.WeakReference
import java.util.concurrent.atomic.AtomicReference
import java.util.concurrent.locks.ReentrantLock
Expand All @@ -32,7 +33,7 @@ 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) {
class AuthStateManager private constructor(private val context: Context) {
private val mPrefs: SharedPreferences
private val mPrefsLock: ReentrantLock
private val mCurrentAuthState: AtomicReference<AuthState>
Expand Down Expand Up @@ -130,6 +131,38 @@ class AuthStateManager private constructor(context: Context) {
}
}

/**
* Removes the shared preferences file, as clearing the state did not work.
*
* This was added in [LEIP-233] to fix the bug where the shared preferences were not cleared
* and "credentials invalid" was shown after re-login during upload.
*/
/*@AnyThread
fun clearState() {
mPrefsLock.lock()
try {
val editor = mPrefs.edit()
editor.clear() // Clears all data in the SharedPreferences
check(editor.commit()) { "Failed to clear state from shared prefs" }
mCurrentAuthState.set(null) // Reset the current auth state reference
} finally {
mPrefsLock.unlock()
}
}*/
@AnyThread
fun deletePreferencesFile() {
mPrefsLock.lock()
try {
val file = File(context.filesDir.parentFile, "shared_prefs/$STORE_NAME.xml")
if (file.exists()) {
file.delete()
}
mCurrentAuthState.set(null)
} finally {
mPrefsLock.unlock()
}
}

companion object {
private val INSTANCE_REF = AtomicReference(WeakReference<AuthStateManager?>(null))
private const val TAG = "AuthStateManager"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ import kotlinx.coroutines.runBlocking
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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package de.cyface.synchronization

import android.app.Service
import android.content.Intent
import android.os.Binder
import android.os.IBinder
import android.util.Log

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@
package de.cyface.synchronization

import android.app.Service
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.IBinder
import de.cyface.uploader.DefaultUploader
import de.cyface.utils.Validate
Expand All @@ -46,7 +49,7 @@ class CyfaceSyncService : Service() {
syncAdapter = SyncAdapter(
applicationContext,
true,
OAuth2(applicationContext, CyfaceAuthenticator.settings),
OAuth2(applicationContext, CyfaceAuthenticator.settings, "CyfaceSyncService"),
DefaultUploader(collectorApi),
)
}
Expand Down
26 changes: 16 additions & 10 deletions synchronization/src/main/kotlin/de/cyface/synchronization/OAuth2.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -57,7 +55,7 @@ import org.json.JSONObject
* @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, private val caller: String) : Auth {

/**
* The service used for authorization.
Expand All @@ -84,6 +82,7 @@ class OAuth2(context: Context, settings: SynchronizationSettings) : Auth {
//Handler().postDelayed({signOut()}, 2000)
//return
}*/
Log.i(TAG, "OAuth2 init ($caller)")
authService = AuthorizationService(
context,
AppAuthConfiguration.Builder()
Expand Down Expand Up @@ -259,24 +258,31 @@ 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!!)
if (currentState.lastRegistrationResponse != null) {
clearedState.update(currentState.lastRegistrationResponse)
}
stateManager.replace(clearedState)
// FIXME: completely delete AuthState.xml in sharedPreferences to fix credentials
// incorrect bug after logout and login during upload
stateManager.deletePreferencesFile()//clearState()
} else {
Log.w(TAG, "No authorization service configuration to sign out")
}

// Invalidate all tokens to ensure they are no longer used
authService.dispose()
}

// Keep: login is currently just deactivated because it's buggy
// FIXME: Keep: login is currently just deactivated because it's buggy
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)
Expand Down Expand Up @@ -310,4 +316,4 @@ class OAuth2(context: Context, settings: SynchronizationSettings) : Auth {
.put("https_required", true)
}
}
}
}

0 comments on commit 2706d17

Please sign in to comment.