Skip to content

Commit

Permalink
Merge pull request #20 from nevissecurity/feature/NEVISACCESSAPP-5666-…
Browse files Browse the repository at this point in the history
…Password-authenticator
  • Loading branch information
tamas-toth authored Aug 1, 2024
2 parents ffb0048 + 93f4e2e commit 9ca6555
Show file tree
Hide file tree
Showing 44 changed files with 1,766 additions and 704 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,11 @@ The [HomeViewModel](app/src/main/java/ch/nevis/exampleapp/ui/home/HomeViewModel.

#### Change PIN

The change PIN operation is implemented in the [HomeViewModel](app/src/main/java/ch/nevis/exampleapp/ui/home/HomeViewModel.kt), [SelectAccountViewModel](app/src/main/java/ch/nevis/exampleapp/ui/selectAccount/SelectAccountViewModel.kt) and [PinViewModel](app/src/main/java/ch/nevis/exampleapp/ui/pin/PinViewModel.kt) classes with which you can modify the PIN of a registered PIN authenticator for a given user.
The change PIN operation is implemented in the [HomeViewModel](app/src/main/java/ch/nevis/exampleapp/ui/home/HomeViewModel.kt), [SelectAccountViewModel](app/src/main/java/ch/nevis/exampleapp/ui/selectAccount/SelectAccountViewModel.kt) and [CredentialViewModel](app/src/main/java/ch/nevis/exampleapp/ui/credential/CredentialViewModel.kt) classes with which you can modify the PIN of a registered PIN authenticator for a given user.

#### Change Password

The change Password operation is implemented in the [HomeViewModel](app/src/main/java/ch/nevis/exampleapp/ui/home/HomeViewModel.kt), [SelectAccountViewModel](app/src/main/java/ch/nevis/exampleapp/ui/selectAccount/SelectAccountViewModel.kt) and [CredentialViewModel](app/src/main/java/ch/nevis/exampleapp/ui/credential/CredentialViewModel.kt) classes with which you can modify the password of a registered Password authenticator for a given user.

#### Change device information

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ class ExampleApplication : Application() {
Timber.plant(ExampleAppTimberDebugTree(sdkLogger))
}
//endregion
}
}
31 changes: 31 additions & 0 deletions app/src/main/java/ch/nevis/exampleapp/dagger/ApplicationModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,32 @@ import ch.nevis.exampleapp.domain.client.ClientProviderImpl
import ch.nevis.exampleapp.domain.deviceInformation.DeviceInformationFactory
import ch.nevis.exampleapp.domain.deviceInformation.DeviceInformationFactoryImpl
import ch.nevis.exampleapp.domain.interaction.*
import ch.nevis.exampleapp.domain.interaction.password.*
import ch.nevis.exampleapp.domain.interaction.pin.*
import ch.nevis.exampleapp.domain.log.SdkLogger
import ch.nevis.exampleapp.domain.log.SdkLoggerImpl
import ch.nevis.exampleapp.domain.validation.AuthenticatorValidator
import ch.nevis.exampleapp.domain.validation.AuthenticatorValidatorImpl
import ch.nevis.exampleapp.domain.validation.PasswordPolicyImpl
import ch.nevis.exampleapp.ui.navigation.NavigationDispatcher
import ch.nevis.exampleapp.ui.navigation.NavigationDispatcherImpl
import ch.nevis.mobile.sdk.api.Configuration
import ch.nevis.mobile.sdk.api.localdata.Authenticator.BIOMETRIC_AUTHENTICATOR_AAID
import ch.nevis.mobile.sdk.api.localdata.Authenticator.DEVICE_PASSCODE_AUTHENTICATOR_AAID
import ch.nevis.mobile.sdk.api.localdata.Authenticator.FINGERPRINT_AUTHENTICATOR_AAID
import ch.nevis.mobile.sdk.api.localdata.Authenticator.PASSWORD_AUTHENTICATOR_AAID
import ch.nevis.mobile.sdk.api.localdata.Authenticator.PIN_AUTHENTICATOR_AAID
import ch.nevis.mobile.sdk.api.operation.password.PasswordChanger
import ch.nevis.mobile.sdk.api.operation.password.PasswordEnroller
import ch.nevis.mobile.sdk.api.operation.password.PasswordPolicy
import ch.nevis.mobile.sdk.api.operation.pin.PinChanger
import ch.nevis.mobile.sdk.api.operation.pin.PinEnroller
import ch.nevis.mobile.sdk.api.operation.selection.AccountSelector
import ch.nevis.mobile.sdk.api.operation.selection.AuthenticatorSelector
import ch.nevis.mobile.sdk.api.operation.userverification.BiometricUserVerifier
import ch.nevis.mobile.sdk.api.operation.userverification.DevicePasscodeUserVerifier
import ch.nevis.mobile.sdk.api.operation.userverification.FingerprintUserVerifier
import ch.nevis.mobile.sdk.api.operation.userverification.PasswordUserVerifier
import ch.nevis.mobile.sdk.api.operation.userverification.PinUserVerifier
import dagger.Module
import dagger.Provides
Expand Down Expand Up @@ -115,6 +123,7 @@ class ApplicationModule {
@Provides
fun provideAuthenticatorAllowlist(): List<String> = listOf(
PIN_AUTHENTICATOR_AAID,
PASSWORD_AUTHENTICATOR_AAID,
FINGERPRINT_AUTHENTICATOR_AAID,
BIOMETRIC_AUTHENTICATOR_AAID,
DEVICE_PASSCODE_AUTHENTICATOR_AAID
Expand Down Expand Up @@ -231,6 +240,28 @@ class ApplicationModule {
@Provides
fun providePinUserVerifier(navigationDispatcher: NavigationDispatcher): PinUserVerifier =
PinUserVerifierImpl(navigationDispatcher)

@Provides
fun providePasswordChanger(
passwordPolicy: PasswordPolicy,
navigationDispatcher: NavigationDispatcher
): PasswordChanger =
PasswordChangerImpl(passwordPolicy, navigationDispatcher)

@Provides
fun providePasswordEnroller(
passwordPolicy: PasswordPolicy,
navigationDispatcher: NavigationDispatcher
): PasswordEnroller =
PasswordEnrollerImpl(passwordPolicy, navigationDispatcher)

@Provides
fun providePasswordUserVerifier(navigationDispatcher: NavigationDispatcher): PasswordUserVerifier =
PasswordUserVerifierImpl(navigationDispatcher)

@Provides
fun providePasswordPolicy(@ApplicationContext context: Context): PasswordPolicy =
PasswordPolicyImpl(context)
//endregion

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

package ch.nevis.exampleapp.domain.interaction.password

import ch.nevis.exampleapp.NavigationGraphDirections
import ch.nevis.exampleapp.logging.sdk
import ch.nevis.exampleapp.ui.credential.model.CredentialViewMode
import ch.nevis.exampleapp.ui.credential.parameter.PasswordNavigationParameter
import ch.nevis.exampleapp.ui.navigation.NavigationDispatcher
import ch.nevis.mobile.sdk.api.operation.password.PasswordChangeContext
import ch.nevis.mobile.sdk.api.operation.password.PasswordChangeHandler
import ch.nevis.mobile.sdk.api.operation.password.PasswordChanger
import ch.nevis.mobile.sdk.api.operation.password.PasswordPolicy
import timber.log.Timber

/**
* Default implementation of [PasswordChanger] interface. Navigates to Credential view with the received
* [PasswordChangeHandler], [ch.nevis.mobile.sdk.api.operation.password.PasswordAuthenticatorProtectionStatus]
* and [ch.nevis.mobile.sdk.api.operation.password.PasswordChangeRecoverableError] objects.
*/
class PasswordChangerImpl(
/**
* An instance of a [PasswordPolicy] interface implementation.
*/
private val policy: PasswordPolicy,

/**
* An instance of a [NavigationDispatcher] interface implementation.
*/
private val navigationDispatcher: NavigationDispatcher
) : PasswordChanger {

//region PasswordChanger
override fun changePassword(
context: PasswordChangeContext,
handler: PasswordChangeHandler
) {
if (context.lastRecoverableError().isPresent) {
Timber.asTree().sdk("Password change failed. Please try again.")
} else {
Timber.asTree().sdk("Please start Password change.")
}

navigationDispatcher.requestNavigation(
NavigationGraphDirections.actionGlobalCredentialFragment(
PasswordNavigationParameter(
CredentialViewMode.CHANGE,
lastRecoverableError = context.lastRecoverableError().orElse(null),
passwordAuthenticatorProtectionStatus = context.authenticatorProtectionStatus(),
passwordChangeHandler = handler
)
)
)
}

// You can add custom password policy by overriding the `passwordPolicy` getter
override fun passwordPolicy(): PasswordPolicy = policy
//endregion
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* Nevis Mobile Authentication SDK Example App
*
* Copyright © 2024. Nevis Security AG. All rights reserved.
*/

package ch.nevis.exampleapp.domain.interaction.password

import ch.nevis.exampleapp.NavigationGraphDirections
import ch.nevis.exampleapp.logging.sdk
import ch.nevis.exampleapp.ui.credential.model.CredentialViewMode
import ch.nevis.exampleapp.ui.credential.parameter.PasswordNavigationParameter
import ch.nevis.exampleapp.ui.navigation.NavigationDispatcher
import ch.nevis.mobile.sdk.api.operation.password.PasswordEnroller
import ch.nevis.mobile.sdk.api.operation.password.PasswordEnrollmentContext
import ch.nevis.mobile.sdk.api.operation.password.PasswordEnrollmentHandler
import ch.nevis.mobile.sdk.api.operation.password.PasswordPolicy
import timber.log.Timber

/**
* Default implementation of [PasswordEnroller] interface. Navigates to Credential view with the
* received [PasswordEnrollmentHandler] and [ch.nevis.mobile.sdk.api.operation.password.PasswordEnrollmentError]
* objects.
*/
class PasswordEnrollerImpl(
/**
* An instance of a [PasswordPolicy] interface implementation.
*/
private val policy: PasswordPolicy,

/**
* An instance of a [NavigationDispatcher] interface implementation.
*/
private val navigationDispatcher: NavigationDispatcher
) : PasswordEnroller {

//region PasswordEnroller
override fun enrollPassword(
context: PasswordEnrollmentContext,
handler: PasswordEnrollmentHandler
) {
if (context.lastRecoverableError().isPresent) {
Timber.asTree().sdk("Password enrollment failed. Please try again.")
} else {
Timber.asTree().sdk("Please start Password enrollment.")
}

navigationDispatcher.requestNavigation(
NavigationGraphDirections.actionGlobalCredentialFragment(
PasswordNavigationParameter(
CredentialViewMode.ENROLLMENT,
lastRecoverableError = context.lastRecoverableError().orElse(null),
passwordEnrollmentHandler = handler
)
)
)
}

override fun onValidCredentialsProvided() {
Timber.asTree().sdk("Valid credentials provided during Password enrollment.")
}

// You can add custom password policy by overriding the `passwordPolicy` getter
override fun passwordPolicy(): PasswordPolicy = policy
//endregion
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* Nevis Mobile Authentication SDK Example App
*
* Copyright © 2024. Nevis Security AG. All rights reserved.
*/

package ch.nevis.exampleapp.domain.interaction.password

import ch.nevis.exampleapp.NavigationGraphDirections
import ch.nevis.exampleapp.logging.sdk
import ch.nevis.exampleapp.ui.credential.model.CredentialViewMode
import ch.nevis.exampleapp.ui.credential.parameter.PasswordNavigationParameter
import ch.nevis.exampleapp.ui.navigation.NavigationDispatcher
import ch.nevis.mobile.sdk.api.operation.userverification.PasswordUserVerificationContext
import ch.nevis.mobile.sdk.api.operation.userverification.PasswordUserVerificationHandler
import ch.nevis.mobile.sdk.api.operation.userverification.PasswordUserVerifier
import timber.log.Timber

/**
* Default implementation of [PasswordUserVerifier] interface. Navigates to Credential view with the
* received [PasswordUserVerificationHandler], [ch.nevis.mobile.sdk.api.operation.password.PasswordAuthenticatorProtectionStatus]
* and [ch.nevis.mobile.sdk.api.operation.userverification.PasswordUserVerificationError] objects.
*/
class PasswordUserVerifierImpl(

/**
* An instance of a [NavigationDispatcher] interface implementation.
*/
private val navigationDispatcher: NavigationDispatcher
) : PasswordUserVerifier {

//region PasswordUserVerifier
override fun verifyPassword(
context: PasswordUserVerificationContext,
handler: PasswordUserVerificationHandler
) {
if (context.lastRecoverableError().isPresent) {
Timber.asTree().sdk("Password user verification failed. Please try again.")
} else {
Timber.asTree().sdk("Please start Password user verification.")
}

navigationDispatcher.requestNavigation(
NavigationGraphDirections.actionGlobalCredentialFragment(
PasswordNavigationParameter(
CredentialViewMode.VERIFICATION,
lastRecoverableError = context.lastRecoverableError().orElse(null),
passwordAuthenticatorProtectionStatus = context.authenticatorProtectionStatus(),
passwordUserVerificationHandler = handler
)
)
)
}

override fun onValidCredentialsProvided() {
Timber.asTree().sdk("Valid credentials provided during Password verification.")
}
//endregion
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@
* Copyright © 2023. Nevis Security AG. All rights reserved.
*/

package ch.nevis.exampleapp.domain.interaction
package ch.nevis.exampleapp.domain.interaction.pin

import ch.nevis.exampleapp.NavigationGraphDirections
import ch.nevis.exampleapp.logging.sdk
import ch.nevis.exampleapp.ui.navigation.NavigationDispatcher
import ch.nevis.exampleapp.ui.pin.model.PinViewMode
import ch.nevis.exampleapp.ui.pin.parameter.PinNavigationParameter
import ch.nevis.exampleapp.ui.credential.model.CredentialViewMode
import ch.nevis.exampleapp.ui.credential.parameter.PinNavigationParameter
import ch.nevis.mobile.sdk.api.operation.pin.PinChangeContext
import ch.nevis.mobile.sdk.api.operation.pin.PinChangeHandler
import ch.nevis.mobile.sdk.api.operation.pin.PinChanger
import timber.log.Timber

/**
* Default implementation of [PinChanger] interface. It navigates to PIN view with the received
* Default implementation of [PinChanger] interface. Navigates to Credential view with the received
* [PinChangeHandler], [ch.nevis.mobile.sdk.api.operation.pin.PinAuthenticatorProtectionStatus] and
* [ch.nevis.mobile.sdk.api.operation.pin.PinChangeRecoverableError] objects.
*/
Expand All @@ -39,11 +39,11 @@ class PinChangerImpl(
}

navigationDispatcher.requestNavigation(
NavigationGraphDirections.actionGlobalPinFragment(
NavigationGraphDirections.actionGlobalCredentialFragment(
PinNavigationParameter(
PinViewMode.CHANGE_PIN,
context.authenticatorProtectionStatus(),
CredentialViewMode.CHANGE,
lastRecoverableError = context.lastRecoverableError().orElse(null),
pinAuthenticatorProtectionStatus = context.authenticatorProtectionStatus(),
pinChangeHandler = handler
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@
* Copyright © 2023. Nevis Security AG. All rights reserved.
*/

package ch.nevis.exampleapp.domain.interaction
package ch.nevis.exampleapp.domain.interaction.pin

import ch.nevis.exampleapp.NavigationGraphDirections
import ch.nevis.exampleapp.logging.sdk
import ch.nevis.exampleapp.ui.navigation.NavigationDispatcher
import ch.nevis.exampleapp.ui.pin.model.PinViewMode
import ch.nevis.exampleapp.ui.pin.parameter.PinNavigationParameter
import ch.nevis.exampleapp.ui.credential.model.CredentialViewMode
import ch.nevis.exampleapp.ui.credential.parameter.PinNavigationParameter
import ch.nevis.mobile.sdk.api.operation.pin.PinEnroller
import ch.nevis.mobile.sdk.api.operation.pin.PinEnrollmentContext
import ch.nevis.mobile.sdk.api.operation.pin.PinEnrollmentHandler
import timber.log.Timber

/**
* Default implementation of [PinEnroller] interface. It navigates to PIN view with the received
* Default implementation of [PinEnroller] interface. Navigates to Credential view with the received
* [PinEnrollmentHandler] and [ch.nevis.mobile.sdk.api.operation.pin.PinEnrollmentError] objects.
*/
class PinEnrollerImpl(
Expand All @@ -40,9 +40,9 @@ class PinEnrollerImpl(
}

navigationDispatcher.requestNavigation(
NavigationGraphDirections.actionGlobalPinFragment(
NavigationGraphDirections.actionGlobalCredentialFragment(
PinNavigationParameter(
PinViewMode.ENROLL_PIN,
CredentialViewMode.ENROLLMENT,
lastRecoverableError = context.lastRecoverableError().orElse(null),
pinEnrollmentHandler = handler
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@
* Copyright © 2023. Nevis Security AG. All rights reserved.
*/

package ch.nevis.exampleapp.domain.interaction
package ch.nevis.exampleapp.domain.interaction.pin

import ch.nevis.exampleapp.NavigationGraphDirections
import ch.nevis.exampleapp.logging.sdk
import ch.nevis.exampleapp.ui.navigation.NavigationDispatcher
import ch.nevis.exampleapp.ui.pin.model.PinViewMode
import ch.nevis.exampleapp.ui.pin.parameter.PinNavigationParameter
import ch.nevis.exampleapp.ui.credential.model.CredentialViewMode
import ch.nevis.exampleapp.ui.credential.parameter.PinNavigationParameter
import ch.nevis.mobile.sdk.api.operation.userverification.PinUserVerificationContext
import ch.nevis.mobile.sdk.api.operation.userverification.PinUserVerificationHandler
import ch.nevis.mobile.sdk.api.operation.userverification.PinUserVerifier
import timber.log.Timber

/**
* Default implementation of [PinUserVerifier] interface. It navigates to PIN view with the received
* Default implementation of [PinUserVerifier] interface. Navigates to Credential view with the received
* [PinUserVerificationHandler], [ch.nevis.mobile.sdk.api.operation.pin.PinAuthenticatorProtectionStatus] and
* [ch.nevis.mobile.sdk.api.operation.userverification.PinUserVerificationError] objects.
*/
Expand All @@ -41,11 +41,11 @@ class PinUserVerifierImpl(
}

navigationDispatcher.requestNavigation(
NavigationGraphDirections.actionGlobalPinFragment(
NavigationGraphDirections.actionGlobalCredentialFragment(
PinNavigationParameter(
PinViewMode.VERIFY_PIN,
pinAuthenticatorProtectionStatus = context.authenticatorProtectionStatus(),
CredentialViewMode.VERIFICATION,
lastRecoverableError = context.lastRecoverableError().orElse(null),
pinAuthenticatorProtectionStatus = context.authenticatorProtectionStatus(),
pinUserVerificationHandler = handler
)
)
Expand Down
Loading

0 comments on commit 9ca6555

Please sign in to comment.