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 15f27b7
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 16 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 @@ -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
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 15f27b7

Please sign in to comment.