Skip to content

Commit

Permalink
[LEIP-233] Explicitly dispose tokens on logout and add document logou…
Browse files Browse the repository at this point in the history
…t bug

Add logout support
  • Loading branch information
hb0 committed May 18, 2024
2 parents c9116c9 + 086bc42 commit e81ac27
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 44 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2021 Cyface GmbH
* Copyright 2017-2024 Cyface GmbH
*
* This file is part of the Cyface SDK for Android.
*
Expand Down Expand Up @@ -49,8 +49,6 @@
*
* @author Klemens Muthmann
* @author Armin Schnabel
* @version 7.2.1
* @since 2.0.0
*/
public class WiFiSurveyor extends BroadcastReceiver {

Expand Down Expand Up @@ -374,8 +372,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 @@ -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<AuthState>

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<AuthState> = AtomicReference()

@get:AnyThread
val current: AuthState
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2018-2023 Cyface GmbH
* Copyright 2018-2024 Cyface GmbH
*
* This file is part of the Cyface SDK for Android.
*
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,13 @@ 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
* [the Android documentation](https://developer.android.com/training/sync-adapters/creating-authenticator.html#CreateAuthenticatorService).
*
* @author Klemens Muthmann
* @author Armin Schnabel
* @version 1.0.7
* @since 2.0.0
*/
class CyfaceAuthenticatorService : Service() {
/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2023 Cyface GmbH
* Copyright 2017-2024 Cyface GmbH
*
* This file is part of the Cyface SDK for Android.
*
Expand Down Expand Up @@ -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() {

Expand All @@ -46,7 +44,7 @@ class CyfaceSyncService : Service() {
syncAdapter = SyncAdapter(
applicationContext,
true,
OAuth2(applicationContext, CyfaceAuthenticator.settings),
OAuth2(applicationContext, CyfaceAuthenticator.settings, "CyfaceSyncService"),
DefaultUploader(collectorApi),
)
}
Expand Down
40 changes: 22 additions & 18 deletions synchronization/src/main/kotlin/de/cyface/synchronization/OAuth2.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Cyface GmbH
* Copyright 2023-2024 Cyface GmbH
*
* This file is part of the Cyface SDK for Android.
*
Expand All @@ -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 @@ -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.
Expand All @@ -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()
Expand Down Expand Up @@ -259,24 +253,34 @@ 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)

// [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)
Expand Down Expand Up @@ -310,4 +314,4 @@ class OAuth2(context: Context, settings: SynchronizationSettings) : Auth {
.put("https_required", true)
}
}
}
}

0 comments on commit e81ac27

Please sign in to comment.