Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion mfa/auth-migration/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
/*
* Copyright (c) 2026 Ping Identity Corporation. All rights reserved.
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/

description = "Legacy Authentication Migration"

plugins {
Expand Down Expand Up @@ -41,5 +48,10 @@ dependencies {
testImplementation(libs.mockk)
testImplementation(libs.robolectric)
testImplementation(project(":foundation:android"))
testImplementation(libs.forgerock.authenticator)

androidTestImplementation(libs.mockwebserver)
androidTestImplementation(libs.kotlinx.coroutines.test)
androidTestImplementation(libs.kotlin.test)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.test.runner)
}
19 changes: 19 additions & 0 deletions mfa/auth-migration/src/androidTest/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2026 Ping Identity Corporation. All rights reserved.
~
~ This software may be modified and distributed under the terms
~ of the MIT license. See the LICENSE file for details.
-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<application
Comment thread
witrisna marked this conversation as resolved.
android:allowBackup="false"
android:label="Test"
android:supportsRtl="true"
android:usesCleartextTraffic="true">

</application>

</manifest>

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
/*
* Copyright (c) 2026 Ping Identity Corporation. All rights reserved.
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/

package com.pingidentity.auth.migration

import android.content.Context
import com.pingidentity.auth.migration.AuthMigration.logger
import com.pingidentity.auth.migration.AuthMigration.start
import com.pingidentity.logger.Logger
import com.pingidentity.logger.STANDARD
import com.pingidentity.migration.Migration
import com.pingidentity.migration.MigrationProgress
import kotlinx.coroutines.flow.FlowCollector
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock

Expand Down Expand Up @@ -112,7 +116,7 @@ object AuthMigration {
step(cleanupLegacyDataStep(config.legacyStorageProvider, config.backup))
}

migration.migrate(context).collect { progress ->
val collector = config.progress ?: FlowCollector { progress ->
when (progress) {
is MigrationProgress.Started -> {
logger.i("Migration started")
Expand All @@ -134,6 +138,8 @@ object AuthMigration {
}
}
}

migration.migrate(context).collect(collector)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2026 Ping Identity Corporation. All rights reserved.
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/

package com.pingidentity.auth.migration

import android.content.Context
import org.forgerock.android.auth.DefaultStorageClient
import org.forgerock.android.auth.StorageClient

/** SharedPreferences file name for storing account data from the ForgeRock Authenticator. */
private const val AUTH_DATA_ACCOUNT = "org.forgerock.android.authenticator.DATA.ACCOUNT"

/** SharedPreferences file name for storing mechanism data from the ForgeRock Authenticator. */
private const val AUTH_DATA_MECHANISM = "org.forgerock.android.authenticator.DATA.MECHANISM"

/** SharedPreferences file name for storing push notification data from the ForgeRock Authenticator. */
private const val AUTH_DATA_NOTIFICATIONS = "org.forgerock.android.authenticator.DATA.NOTIFICATIONS"

/** SharedPreferences file name for storing the device token from the ForgeRock Authenticator. */
private const val AUTH_DATA_DEVICE_TOKEN = "org.forgerock.android.authenticator.DATA.DEVICE_TOKEN"

/**
* A [StorageClientProvider] that reads data from the default [DefaultStorageClient] used by the
* ForgeRock Authenticator SDK.
*
* This provider is intended for migration scenarios where authenticator data needs to be
* transferred from the legacy ForgeRock Authenticator storage into the unified SDK storage.
*
* @param context The Android [Context] used to access shared preferences.
* @param storageClient The [StorageClient] to read legacy authenticator data from.
* Defaults to a new [DefaultStorageClient] instance.
*/
class DefaultStorageClientProvider(
Comment thread
witrisna marked this conversation as resolved.
context: Context,
storageClient: StorageClient = DefaultStorageClient(context),
) : StorageClientProvider(context, storageClient) {

/**
* Cleans up all legacy ForgeRock Authenticator SharedPreferences files after migration.
*
* This override deletes the SharedPreferences files directly (rather than clearing individual
* entries) to improve performance during cleanup.
*
* @param context The Android [Context] used to delete shared preferences.
* @param backup A callback invoked before deletion, allowing the caller to back up data prior
* to removal.
*/
override suspend fun cleanUp(context: Context, backup: (context: Context) -> Unit) {

backup(context)
context.deleteSharedPreferences(AUTH_DATA_ACCOUNT)
context.deleteSharedPreferences(AUTH_DATA_MECHANISM)
context.deleteSharedPreferences(AUTH_DATA_NOTIFICATIONS)
context.deleteSharedPreferences(AUTH_DATA_DEVICE_TOKEN)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2026 Ping Identity Corporation. All rights reserved.
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
Expand All @@ -9,6 +10,8 @@ package com.pingidentity.auth.migration
import android.content.Context
import com.pingidentity.logger.Logger
import com.pingidentity.logger.STANDARD
import com.pingidentity.migration.MigrationProgress
import kotlinx.coroutines.flow.FlowCollector
import org.forgerock.android.auth.StorageClient

/**
Expand All @@ -29,6 +32,7 @@ import org.forgerock.android.auth.StorageClient
* invoked by [StorageClientProvider.cleanUp] unconditionally — pass a no-op (the default) to
* skip backup. For custom [LegacyStorageProvider] implementations, the callback is forwarded
* via [LegacyStorageProvider.cleanUp] and it is the implementation's responsibility to invoke it.
* @property progress An optional [FlowCollector] that receives migration pipeline events.
*
* ## Example — default migration (no block needed)
* ```kotlin
Expand Down Expand Up @@ -69,7 +73,8 @@ import org.forgerock.android.auth.StorageClient
* @see StorageClientProvider
*/
class LegacyAuthenticationConfig(context: Context) {
var legacyStorageProvider: LegacyStorageProvider = StorageClientProvider(context)
var legacyStorageProvider: LegacyStorageProvider = DefaultStorageClientProvider(context)
var logger: Logger = Logger.STANDARD
var backup: (context: Context) -> Unit = {}
var progress: FlowCollector<MigrationProgress>? = null
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2026 Ping Identity Corporation. All rights reserved.
* Copyright (c) 2026 - 2026 Ping Identity Corporation. All rights reserved.
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
Expand Down Expand Up @@ -59,7 +60,7 @@ import org.forgerock.android.auth.StorageClient
* @see LegacyAuthenticationConfig
* @see DefaultStorageClient
*/
class StorageClientProvider(
open class StorageClientProvider(
context: Context,
private val storageClient: StorageClient = DefaultStorageClient(context),
) : LegacyStorageProvider {
Expand Down
18 changes: 17 additions & 1 deletion mfa/binding-migration/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2025 Ping Identity Corporation. All rights reserved.
* Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved.
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
Expand All @@ -18,6 +18,13 @@ plugins {

android {
namespace = "com.pingidentity.device.binding.migration"

packaging {
resources.excludes += setOf(
"META-INF/LICENSE.md",
"META-INF/LICENSE-notice.md",
)
}
}

dependencies {
Expand All @@ -37,4 +44,13 @@ dependencies {
testImplementation(libs.mockk)
testImplementation(libs.robolectric)

androidTestImplementation(project(":foundation:journey-plugin"))
androidTestImplementation(libs.mockk)
androidTestImplementation(libs.mockk.android)
androidTestImplementation(libs.kotlinx.coroutines.test)
androidTestImplementation(libs.forgerock.auth)
androidTestImplementation(libs.kotlin.test)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.test.runner)

}
Loading
Loading