Skip to content

Commit

Permalink
NEVISACCESSAPP-5283: Delete local data
Browse files Browse the repository at this point in the history
  • Loading branch information
tamas-toth committed Nov 14, 2023
1 parent ed9acf8 commit b521435
Show file tree
Hide file tree
Showing 11 changed files with 136 additions and 11 deletions.
9 changes: 3 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ Clone the example application GitHub repository and open it with Android Studio.
The example applications support two kinds of configuration: `authenticationCloud` and `identitySuite`. The following chapters describes how to change the base configuration to match your environment.
The configuration could be changed by modifying the [ApplicationModule](app/src/main/java/ch/nevis/exampleapp/coroutines/dagger/ApplicationModule.kt) file which describes the dependency injection related configuration using the [Dagger Hilt](https://dagger.dev/hilt/) library and the [AndroidManifest.xml](app/src/main/AndroidManifest.xml).

> **_NOTE_**
>
> [!NOTE]
> Only _build-time_ configuration change is supported.
#### Authentication Cloud Configuration
Expand Down Expand Up @@ -126,8 +125,7 @@ Change the `myaccessapp` scheme value in the following `intent-filter` with the
</intent-filter>
```

> **_NOTE_**:
>
> [!NOTE]
> For more information about deep links, web links visit the official [Android guide](https://developer.android.com/training/app-links).
#### Facet ID
Expand All @@ -154,8 +152,7 @@ object FacetIdCalculator {
}
```

> **_NOTE_:**
>
> [!NOTE]
> An alternative way to set a constant Facet ID is to call `facetId(String facetId)` method of `ch.nevis.mobile.sdk.api.Configuration.Builder` in methods `provideAuthenticationCloudConfiguration` and `provideIdentitySuiteConfiguration` in [ApplicationModule](app/src/main/java/ch/nevis/exampleapp/coroutines/dagger/ApplicationModule.kt) file.
>
> The value of the facet ID depends on the certificate used to build the application, which can change during the development, that is why this method has been introduced: by providing a constant facet ID and having
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,10 @@ class ApplicationModule {
fun provideGetAuthenticatorsUseCase(clientProvider: ClientProvider): GetAuthenticatorsUseCase =
GetAuthenticatorsUseCaseImpl(clientProvider)

@Provides
fun provideDeleteAuthenticatorsUseCase(clientProvider: ClientProvider): DeleteAuthenticatorsUseCase =
DeleteAuthenticatorsUseCaseImpl(clientProvider)

@Provides
fun provideCreateDeviceInformationUseCase(@ApplicationContext context: Context): CreateDeviceInformationUseCase =
CreateDeviceInformationUseCaseImpl(context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,11 @@ enum class Operation(
/**
* Process out-of-band payload
*/
PROCESS_OUT_OF_BAND_PAYLOAD(R.string.operation_process_oob_payload)
PROCESS_OUT_OF_BAND_PAYLOAD(R.string.operation_process_oob_payload),

/**
* Local Data
*/
LOCAL_DATA(R.string.operation_local_data)

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class SelectAccountResponse(
val operation: Operation,

/**
* The set of available authenticators the user has to choose from.
* The set of enrolled accounts the user has to choose from.
*/
val accounts: Set<Account>,

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Nevis Mobile Authentication SDK Example App
*
* Copyright © 2023. Nevis Security AG. All rights reserved.
*/

package ch.nevis.exampleapp.coroutines.domain.usecase

import ch.nevis.exampleapp.coroutines.domain.model.response.Response
import ch.nevis.mobile.sdk.api.localdata.Account

/**
* Interface declaration of delete local authenticators use-case.
*/
interface DeleteAuthenticatorsUseCase {

/**
* Executes use-case.
*
* @param accounts The set of enrolled accounts.
* @return A [Response] object, the result of the use-case execution.
*/
suspend fun execute(
accounts: Set<Account>
): Response
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* Nevis Mobile Authentication SDK Example App
*
* Copyright © 2023. Nevis Security AG. All rights reserved.
*/

package ch.nevis.exampleapp.coroutines.domain.usecase

import ch.nevis.exampleapp.coroutines.domain.client.ClientProvider
import ch.nevis.exampleapp.coroutines.domain.model.error.BusinessException
import ch.nevis.exampleapp.coroutines.domain.model.operation.Operation
import ch.nevis.exampleapp.coroutines.domain.model.response.CompletedResponse
import ch.nevis.exampleapp.coroutines.domain.model.response.Response
import ch.nevis.mobile.sdk.api.localdata.Account
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlin.coroutines.resume

class DeleteAuthenticatorsUseCaseImpl(
/**
* An instance of a [ClientProvider] implementation.
*/
private val clientProvider: ClientProvider
) : DeleteAuthenticatorsUseCase {
//region DeleteAuthenticatorsUseCase
override suspend fun execute(accounts: Set<Account>): Response {
for (account in accounts) {
deleteAuthenticators(account.username())
}

return CompletedResponse(Operation.LOCAL_DATA)
}
//endregion

//region Private Interface
/**
* Deletes all local authenticators of an enrolled account.
*
* @param username The username that identifies the account whose authenticators must be deleted locally.
*/
private suspend fun deleteAuthenticators(username: String) {
return suspendCancellableCoroutine { cancellableContinuation ->
val client = clientProvider.get() ?: throw BusinessException.clientNotInitialized()
client.localData().deleteAuthenticator(username)
cancellableContinuation.resume(Unit)
}
}
//endregion
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ class HomeFragment : ResponseObserverFragment() {
navController.navigate(action)
}

binding.deleteAuthenticatorsButton.setOnClickListener {
viewModel.deleteAuthenticators()
}

binding.inBandRegistrationButton.setOnClickListener {
val action = NavigationGraphDirections.actionGlobalLegacyLoginFragment()
navController.navigate(action)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,17 @@ import ch.nevis.exampleapp.coroutines.common.configuration.Environment
import ch.nevis.exampleapp.coroutines.domain.model.error.BusinessException
import ch.nevis.exampleapp.coroutines.domain.model.operation.Operation
import ch.nevis.exampleapp.coroutines.domain.model.response.*
import ch.nevis.exampleapp.coroutines.domain.usecase.DeleteAuthenticatorsUseCase
import ch.nevis.exampleapp.coroutines.domain.usecase.GetAccountsUseCase
import ch.nevis.exampleapp.coroutines.domain.usecase.GetAuthenticatorsUseCase
import ch.nevis.exampleapp.coroutines.domain.usecase.InitializeClientUseCase
import ch.nevis.exampleapp.coroutines.ui.base.OutOfBandOperationViewModel
import ch.nevis.mobile.sdk.api.localdata.Account
import ch.nevis.mobile.sdk.api.localdata.Authenticator
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject

/**
Expand All @@ -46,6 +49,11 @@ class HomeViewModel @Inject constructor(
* An instance of a [GetAuthenticatorsUseCase] implementation.
*/
private val getAuthenticatorsUseCase: GetAuthenticatorsUseCase,

/**
* An instance of a [DeleteAuthenticatorsUseCase] implementation.
*/
private val deleteAuthenticatorsUseCase: DeleteAuthenticatorsUseCase,
) : OutOfBandOperationViewModel() {

//region Public Interface
Expand Down Expand Up @@ -152,5 +160,25 @@ class HomeViewModel @Inject constructor(
}
}
}

/**
* Starts deleting local authenticators of all registered users.
*/
fun deleteAuthenticators() {
viewModelScope.launch(errorHandler) {
var response = getAccountsUseCase.execute()
if (response is GetAccountsResponse) {
val accounts = response.accounts
response = if (accounts.isNotEmpty()) {
withContext(Dispatchers.IO) {
deleteAuthenticatorsUseCase.execute(accounts)
}
} else {
ErrorResponse(BusinessException.accountsNotFound())
}
}
mutableResponseLiveData.postValue(response)
}
}
//endregion
}
10 changes: 10 additions & 0 deletions app/src/main/res/layout/fragment_home.xml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,16 @@
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="@string/home_auth_cloud_registration_button_title"
app:layout_constraintBottom_toTopOf="@id/deleteAuthenticatorsButton"
app:layout_constraintEnd_toEndOf="@id/rightVerticalGuideline"
app:layout_constraintStart_toStartOf="@id/leftVerticalGuideline" />

<Button
android:id="@+id/deleteAuthenticatorsButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="@string/home_delete_authenticators_button_title"
app:layout_constraintBottom_toTopOf="@id/softwareDeliveredOnlyLabel"
app:layout_constraintEnd_toEndOf="@id/rightVerticalGuideline"
app:layout_constraintStart_toStartOf="@id/leftVerticalGuideline" />
Expand Down
6 changes: 4 additions & 2 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
<string name="home_change_pin_button_title">PIN Change</string>
<string name="home_change_device_information_button_title">Change Device Information</string>
<string name="home_auth_cloud_registration_button_title">Auth Cloud API Registration</string>
<string name="home_delete_authenticators_button_title">Delete Authenticators</string>
<string name="home_in_band_registration_button_title">In-band Registration</string>

<string name="operation_authentication">Authentication</string>
Expand All @@ -102,6 +103,7 @@
<string name="operation_general">Operation</string>
<string name="operation_process_oob_payload">Payload Processing</string>
<string name="operation_registration">Registration</string>
<string name="operation_local_data">Local Data operation</string>

<string name="pin_confirm_button_title">OK</string>
<string name="pin_hint_old_pin">Old PIN</string>
Expand All @@ -121,8 +123,8 @@
<string name="rational_dialog_cancel_button_title">Cancel</string>

<string name="result_confirm_button_title">OK</string>
<string name="result_title_success">%s Success</string>
<string name="result_title_cancelled">%s Cancelled</string>
<string name="result_title_success">%s succeeded</string>
<string name="result_title_cancelled">%s cancelled</string>

<string name="select_account_title">Select an account</string>

Expand Down
2 changes: 1 addition & 1 deletion fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ platform :android do
add_git_tag(tag: "release/#{version_name}/#{build_number}", message: "[Fastlane] #{display_name} #{version_name} (#{build_number})")
push_git_tags

report_on_success("#{display_name} build is completed: #{version_name} (#{build_number}) ✅")
report_on_success("#{display_name} build completed: #{version_name} (#{build_number}) ✅")
rescue => exception
report_on_error("#{display_name} build failed ❌", exception)
end
Expand Down

0 comments on commit b521435

Please sign in to comment.