mirror of
https://github.com/bitwarden/android.git
synced 2025-02-16 11:59:57 +03:00
BIT-654: Adding generator disk source implementation (#245)
This commit is contained in:
parent
f52f4befba
commit
fa9401f2d2
10 changed files with 463 additions and 1 deletions
|
@ -0,0 +1,19 @@
|
|||
package com.x8bit.bitwarden.data.generator.datasource.disk
|
||||
|
||||
import com.x8bit.bitwarden.data.generator.repository.model.PasswordGenerationOptions
|
||||
|
||||
/**
|
||||
* Primary access point for disk information related to generation.
|
||||
*/
|
||||
interface GeneratorDiskSource {
|
||||
|
||||
/**
|
||||
* Retrieves a user's password generation options using a [userId].
|
||||
*/
|
||||
fun getPasswordGenerationOptions(userId: String): PasswordGenerationOptions?
|
||||
|
||||
/**
|
||||
* Stores a user's password generation options using a [userId].
|
||||
*/
|
||||
fun storePasswordGenerationOptions(userId: String, options: PasswordGenerationOptions?)
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package com.x8bit.bitwarden.data.generator.datasource.disk
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import com.x8bit.bitwarden.data.generator.repository.model.PasswordGenerationOptions
|
||||
import com.x8bit.bitwarden.data.platform.datasource.disk.BaseDiskSource
|
||||
import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
private const val PASSWORD_GENERATION_OPTIONS_KEY = "passwordGenerationOptions"
|
||||
|
||||
/**
|
||||
* Primary implementation of [GeneratorDiskSource].
|
||||
*/
|
||||
class GeneratorDiskSourceImpl(
|
||||
sharedPreferences: SharedPreferences,
|
||||
private val json: Json,
|
||||
) : BaseDiskSource(sharedPreferences),
|
||||
GeneratorDiskSource {
|
||||
|
||||
override fun getPasswordGenerationOptions(userId: String): PasswordGenerationOptions? {
|
||||
val key = getPasswordGenerationOptionsKey(userId)
|
||||
return getString(key)?.let { json.decodeFromString(it) }
|
||||
}
|
||||
|
||||
override fun storePasswordGenerationOptions(
|
||||
userId: String,
|
||||
options: PasswordGenerationOptions?,
|
||||
) {
|
||||
val key = getPasswordGenerationOptionsKey(userId)
|
||||
putString(
|
||||
key,
|
||||
options?.let { json.encodeToString(options) },
|
||||
)
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(
|
||||
sharedPreferences: SharedPreferences?,
|
||||
key: String?,
|
||||
) = Unit
|
||||
|
||||
private fun getPasswordGenerationOptionsKey(userId: String): String =
|
||||
"${BASE_KEY}_${PASSWORD_GENERATION_OPTIONS_KEY}_$userId"
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.x8bit.bitwarden.data.generator.datasource.disk.di
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import com.x8bit.bitwarden.data.generator.datasource.disk.GeneratorDiskSource
|
||||
import com.x8bit.bitwarden.data.generator.datasource.disk.GeneratorDiskSourceImpl
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import kotlinx.serialization.json.Json
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* Provides persistence-related dependencies for the generator package.
|
||||
*/
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
object GeneratorDiskModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGeneratorDiskSource(
|
||||
sharedPreferences: SharedPreferences,
|
||||
json: Json,
|
||||
): GeneratorDiskSource =
|
||||
GeneratorDiskSourceImpl(
|
||||
sharedPreferences = sharedPreferences,
|
||||
json = json,
|
||||
)
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.x8bit.bitwarden.data.generator.repository
|
|||
|
||||
import com.bitwarden.core.PasswordGeneratorRequest
|
||||
import com.x8bit.bitwarden.data.generator.repository.model.GeneratedPasswordResult
|
||||
import com.x8bit.bitwarden.data.generator.repository.model.PasswordGenerationOptions
|
||||
|
||||
/**
|
||||
* Responsible for managing generator data.
|
||||
|
@ -14,4 +15,14 @@ interface GeneratorRepository {
|
|||
suspend fun generatePassword(
|
||||
passwordGeneratorRequest: PasswordGeneratorRequest,
|
||||
): GeneratedPasswordResult
|
||||
|
||||
/**
|
||||
* Get the [PasswordGenerationOptions] for the current user.
|
||||
*/
|
||||
fun getPasswordGenerationOptions(): PasswordGenerationOptions?
|
||||
|
||||
/**
|
||||
* Save the [PasswordGenerationOptions] for the current user.
|
||||
*/
|
||||
fun savePasswordGenerationOptions(options: PasswordGenerationOptions)
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package com.x8bit.bitwarden.data.generator.repository
|
||||
|
||||
import com.bitwarden.core.PasswordGeneratorRequest
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
|
||||
import com.x8bit.bitwarden.data.generator.datasource.disk.GeneratorDiskSource
|
||||
import com.x8bit.bitwarden.data.generator.datasource.sdk.GeneratorSdkSource
|
||||
import com.x8bit.bitwarden.data.generator.repository.model.GeneratedPasswordResult
|
||||
import com.x8bit.bitwarden.data.generator.repository.model.PasswordGenerationOptions
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
|
@ -11,6 +14,8 @@ import javax.inject.Singleton
|
|||
@Singleton
|
||||
class GeneratorRepositoryImpl constructor(
|
||||
private val generatorSdkSource: GeneratorSdkSource,
|
||||
private val generatorDiskSource: GeneratorDiskSource,
|
||||
private val authDiskSource: AuthDiskSource,
|
||||
) : GeneratorRepository {
|
||||
|
||||
override suspend fun generatePassword(
|
||||
|
@ -22,4 +27,14 @@ class GeneratorRepositoryImpl constructor(
|
|||
onSuccess = { GeneratedPasswordResult.Success(it) },
|
||||
onFailure = { GeneratedPasswordResult.InvalidRequest },
|
||||
)
|
||||
|
||||
override fun getPasswordGenerationOptions(): PasswordGenerationOptions? {
|
||||
val userId = authDiskSource.userState?.activeUserId
|
||||
return userId?.let { generatorDiskSource.getPasswordGenerationOptions(it) }
|
||||
}
|
||||
|
||||
override fun savePasswordGenerationOptions(options: PasswordGenerationOptions) {
|
||||
val userId = authDiskSource.userState?.activeUserId
|
||||
userId?.let { generatorDiskSource.storePasswordGenerationOptions(it, options) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.x8bit.bitwarden.data.generator.repository.di
|
||||
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
|
||||
import com.x8bit.bitwarden.data.generator.datasource.disk.GeneratorDiskSource
|
||||
import com.x8bit.bitwarden.data.generator.datasource.sdk.GeneratorSdkSource
|
||||
import com.x8bit.bitwarden.data.generator.repository.GeneratorRepository
|
||||
import com.x8bit.bitwarden.data.generator.repository.GeneratorRepositoryImpl
|
||||
|
@ -20,5 +22,11 @@ object GeneratorRepositoryModule {
|
|||
@Singleton
|
||||
fun provideGeneratorRepository(
|
||||
generatorSdkSource: GeneratorSdkSource,
|
||||
): GeneratorRepository = GeneratorRepositoryImpl(generatorSdkSource)
|
||||
generatorDiskSource: GeneratorDiskSource,
|
||||
authDiskSource: AuthDiskSource,
|
||||
): GeneratorRepository = GeneratorRepositoryImpl(
|
||||
generatorSdkSource = generatorSdkSource,
|
||||
generatorDiskSource = generatorDiskSource,
|
||||
authDiskSource = authDiskSource,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package com.x8bit.bitwarden.data.generator.repository.model
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* A data class representing the configuration options for password generation.
|
||||
*
|
||||
* @property length The total length of the generated password.
|
||||
* @property allowAmbiguousChar Indicates whether ambiguous characters are allowed in the password.
|
||||
* @property hasNumbers Indicates whether the password should contain numbers.
|
||||
* @property minNumber The minimum number of numeric characters required in the password.
|
||||
* @property hasUppercase Indicates whether the password should contain uppercase characters.
|
||||
* @property minUppercase The minimum number of uppercase characters required in the password.
|
||||
* @property hasLowercase Indicates whether the password should contain lowercase characters.
|
||||
* @property minLowercase The minimum number of lowercase characters required in the password.
|
||||
* @property allowSpecial Indicates whether special characters are allowed in the password.
|
||||
* @property minSpecial The minimum number of special characters required in the password.
|
||||
*/
|
||||
@Serializable
|
||||
data class PasswordGenerationOptions(
|
||||
@SerialName("length")
|
||||
val length: Int,
|
||||
|
||||
@SerialName("allowAmbiguousChar")
|
||||
val allowAmbiguousChar: Boolean,
|
||||
|
||||
@SerialName("number")
|
||||
val hasNumbers: Boolean,
|
||||
|
||||
@SerialName("minNumber")
|
||||
val minNumber: Int,
|
||||
|
||||
@SerialName("uppercase")
|
||||
val hasUppercase: Boolean,
|
||||
|
||||
@SerialName("minUppercase")
|
||||
val minUppercase: Int?,
|
||||
|
||||
@SerialName("lowercase")
|
||||
val hasLowercase: Boolean,
|
||||
|
||||
@SerialName("minLowercase")
|
||||
val minLowercase: Int?,
|
||||
|
||||
@SerialName("special")
|
||||
val allowSpecial: Boolean,
|
||||
|
||||
@SerialName("minSpecial")
|
||||
val minSpecial: Int,
|
||||
)
|
|
@ -0,0 +1,84 @@
|
|||
package com.x8bit.bitwarden.data.generator.datasource.disk
|
||||
|
||||
import com.x8bit.bitwarden.data.generator.repository.model.PasswordGenerationOptions
|
||||
import com.x8bit.bitwarden.data.platform.base.FakeSharedPreferences
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertNotNull
|
||||
import org.junit.jupiter.api.Assertions.assertNull
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class GeneratorDiskSourceTest {
|
||||
private val fakeSharedPreferences = FakeSharedPreferences()
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
private val json = Json {
|
||||
ignoreUnknownKeys = true
|
||||
explicitNulls = false
|
||||
}
|
||||
|
||||
private val generatorDiskSource = GeneratorDiskSourceImpl(
|
||||
sharedPreferences = fakeSharedPreferences,
|
||||
json = json,
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `getPasswordGenerationOptions should return correct options when available`() {
|
||||
val userId = "user123"
|
||||
val options = PasswordGenerationOptions(
|
||||
length = 14,
|
||||
allowAmbiguousChar = false,
|
||||
hasNumbers = true,
|
||||
minNumber = 0,
|
||||
hasUppercase = true,
|
||||
minUppercase = null,
|
||||
hasLowercase = false,
|
||||
minLowercase = null,
|
||||
allowSpecial = false,
|
||||
minSpecial = 1,
|
||||
)
|
||||
|
||||
val key = "bwPreferencesStorage_passwordGenerationOptions_$userId"
|
||||
fakeSharedPreferences.edit().putString(key, json.encodeToString(options)).apply()
|
||||
|
||||
val result = generatorDiskSource.getPasswordGenerationOptions(userId)
|
||||
|
||||
assertEquals(options, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getPasswordGenerationOptions should return null when options are not available`() {
|
||||
val userId = "user123"
|
||||
|
||||
val result = generatorDiskSource.getPasswordGenerationOptions(userId)
|
||||
|
||||
assertNull(result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `storePasswordGenerationOptions should correctly store options`() {
|
||||
val userId = "user123"
|
||||
val options = PasswordGenerationOptions(
|
||||
length = 14,
|
||||
allowAmbiguousChar = false,
|
||||
hasNumbers = true,
|
||||
minNumber = 0,
|
||||
hasUppercase = true,
|
||||
minUppercase = null,
|
||||
hasLowercase = false,
|
||||
minLowercase = null,
|
||||
allowSpecial = false,
|
||||
minSpecial = 1,
|
||||
)
|
||||
|
||||
val key = "bwPreferencesStorage_passwordGenerationOptions_$userId"
|
||||
|
||||
generatorDiskSource.storePasswordGenerationOptions(userId, options)
|
||||
|
||||
val storedValue = fakeSharedPreferences.getString(key, null)
|
||||
assertNotNull(storedValue)
|
||||
assertEquals(json.encodeToString(options), storedValue)
|
||||
}
|
||||
}
|
|
@ -1,14 +1,28 @@
|
|||
package com.x8bit.bitwarden.data.generator.repository
|
||||
|
||||
import com.bitwarden.core.PasswordGeneratorRequest
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.AccountJson
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.EnvironmentUrlDataJson
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.ForcePasswordResetReason
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.UserStateJson
|
||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.KdfTypeJson
|
||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorUserDecryptionOptionsJson
|
||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.TrustedDeviceUserDecryptionOptionsJson
|
||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.UserDecryptionOptionsJson
|
||||
import com.x8bit.bitwarden.data.generator.datasource.disk.GeneratorDiskSource
|
||||
import com.x8bit.bitwarden.data.generator.datasource.sdk.GeneratorSdkSource
|
||||
import com.x8bit.bitwarden.data.generator.repository.model.GeneratedPasswordResult
|
||||
import com.x8bit.bitwarden.data.generator.repository.model.PasswordGenerationOptions
|
||||
import io.mockk.Runs
|
||||
import io.mockk.clearMocks
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertNull
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
|
@ -16,9 +30,13 @@ import org.junit.jupiter.api.Test
|
|||
class GeneratorRepositoryTest {
|
||||
|
||||
private val generatorSdkSource: GeneratorSdkSource = mockk()
|
||||
private val generatorDiskSource: GeneratorDiskSource = mockk()
|
||||
private val authDiskSource: AuthDiskSource = mockk()
|
||||
|
||||
private val repository = GeneratorRepositoryImpl(
|
||||
generatorSdkSource = generatorSdkSource,
|
||||
generatorDiskSource = generatorDiskSource,
|
||||
authDiskSource = authDiskSource,
|
||||
)
|
||||
|
||||
@BeforeEach
|
||||
|
@ -73,4 +91,156 @@ class GeneratorRepositoryTest {
|
|||
assertTrue(result is GeneratedPasswordResult.InvalidRequest)
|
||||
coVerify { generatorSdkSource.generatePassword(request) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getPasswordGenerationOptions should return options when available`() = runTest {
|
||||
val userId = "activeUserId"
|
||||
val expectedOptions = PasswordGenerationOptions(
|
||||
length = 14,
|
||||
allowAmbiguousChar = false,
|
||||
hasNumbers = true,
|
||||
minNumber = 0,
|
||||
hasUppercase = true,
|
||||
minUppercase = null,
|
||||
hasLowercase = false,
|
||||
minLowercase = null,
|
||||
allowSpecial = false,
|
||||
minSpecial = 1,
|
||||
)
|
||||
|
||||
coEvery { authDiskSource.userState } returns USER_STATE
|
||||
|
||||
coEvery {
|
||||
generatorDiskSource.getPasswordGenerationOptions(userId)
|
||||
} returns expectedOptions
|
||||
|
||||
val result = repository.getPasswordGenerationOptions()
|
||||
|
||||
assertEquals(expectedOptions, result)
|
||||
coVerify { generatorDiskSource.getPasswordGenerationOptions(userId) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getPasswordGenerationOptions should return null when there is no active user`() = runTest {
|
||||
coEvery { authDiskSource.userState } returns null
|
||||
|
||||
val result = repository.getPasswordGenerationOptions()
|
||||
|
||||
assertNull(result)
|
||||
coVerify(exactly = 0) { generatorDiskSource.getPasswordGenerationOptions(any()) }
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `getPasswordGenerationOptions should return null when no data is stored for active user`() = runTest {
|
||||
val userId = "activeUserId"
|
||||
coEvery { authDiskSource.userState } returns USER_STATE
|
||||
coEvery { generatorDiskSource.getPasswordGenerationOptions(userId) } returns null
|
||||
|
||||
val result = repository.getPasswordGenerationOptions()
|
||||
|
||||
assertNull(result)
|
||||
coVerify { generatorDiskSource.getPasswordGenerationOptions(userId) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `savePasswordGenerationOptions should store options correctly`() = runTest {
|
||||
val userId = "activeUserId"
|
||||
val optionsToSave = PasswordGenerationOptions(
|
||||
length = 14,
|
||||
allowAmbiguousChar = false,
|
||||
hasNumbers = true,
|
||||
minNumber = 0,
|
||||
hasUppercase = true,
|
||||
minUppercase = null,
|
||||
hasLowercase = false,
|
||||
minLowercase = null,
|
||||
allowSpecial = false,
|
||||
minSpecial = 1,
|
||||
)
|
||||
|
||||
coEvery { authDiskSource.userState } returns USER_STATE
|
||||
|
||||
coEvery {
|
||||
generatorDiskSource.storePasswordGenerationOptions(userId, optionsToSave)
|
||||
} just Runs
|
||||
|
||||
repository.savePasswordGenerationOptions(optionsToSave)
|
||||
|
||||
coVerify { generatorDiskSource.storePasswordGenerationOptions(userId, optionsToSave) }
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `savePasswordGenerationOptions should not store options when there is no active user`() = runTest {
|
||||
val optionsToSave = PasswordGenerationOptions(
|
||||
length = 14,
|
||||
allowAmbiguousChar = false,
|
||||
hasNumbers = true,
|
||||
minNumber = 0,
|
||||
hasUppercase = true,
|
||||
minUppercase = null,
|
||||
hasLowercase = false,
|
||||
minLowercase = null,
|
||||
allowSpecial = false,
|
||||
minSpecial = 1,
|
||||
)
|
||||
|
||||
coEvery { authDiskSource.userState } returns null
|
||||
|
||||
repository.savePasswordGenerationOptions(optionsToSave)
|
||||
|
||||
coVerify(exactly = 0) { generatorDiskSource.storePasswordGenerationOptions(any(), any()) }
|
||||
}
|
||||
|
||||
private val USER_STATE = UserStateJson(
|
||||
activeUserId = "activeUserId",
|
||||
accounts = mapOf(
|
||||
"activeUserId" to AccountJson(
|
||||
profile = AccountJson.Profile(
|
||||
userId = "activeUserId",
|
||||
email = "email",
|
||||
isEmailVerified = true,
|
||||
name = "name",
|
||||
stamp = "stamp",
|
||||
organizationId = "organizationId",
|
||||
avatarColorHex = "avatarColorHex",
|
||||
hasPremium = true,
|
||||
forcePasswordResetReason = ForcePasswordResetReason.ADMIN_FORCE_PASSWORD_RESET,
|
||||
kdfType = KdfTypeJson.ARGON2_ID,
|
||||
kdfIterations = 600000,
|
||||
kdfMemory = 16,
|
||||
kdfParallelism = 4,
|
||||
userDecryptionOptions = UserDecryptionOptionsJson(
|
||||
hasMasterPassword = true,
|
||||
trustedDeviceUserDecryptionOptions = TrustedDeviceUserDecryptionOptionsJson(
|
||||
encryptedPrivateKey = "encryptedPrivateKey",
|
||||
encryptedUserKey = "encryptedUserKey",
|
||||
hasAdminApproval = true,
|
||||
hasLoginApprovingDevice = true,
|
||||
hasManageResetPasswordPermission = true,
|
||||
),
|
||||
keyConnectorUserDecryptionOptions = KeyConnectorUserDecryptionOptionsJson(
|
||||
keyConnectorUrl = "keyConnectorUrl",
|
||||
),
|
||||
),
|
||||
),
|
||||
tokens = AccountJson.Tokens(
|
||||
accessToken = "accessToken",
|
||||
refreshToken = "refreshToken",
|
||||
),
|
||||
settings = AccountJson.Settings(
|
||||
environmentUrlData = EnvironmentUrlDataJson(
|
||||
base = "base",
|
||||
api = "api",
|
||||
identity = "identity",
|
||||
icon = "icon",
|
||||
notifications = "notifications",
|
||||
webVault = "webVault",
|
||||
events = "events",
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package com.x8bit.bitwarden.data.generator.repository.util
|
||||
|
||||
import com.bitwarden.core.PasswordGeneratorRequest
|
||||
import com.x8bit.bitwarden.data.generator.repository.GeneratorRepository
|
||||
import com.x8bit.bitwarden.data.generator.repository.model.GeneratedPasswordResult
|
||||
import com.x8bit.bitwarden.data.generator.repository.model.PasswordGenerationOptions
|
||||
|
||||
/**
|
||||
* A fake implementation of [GeneratorRepository] for testing purposes.
|
||||
* This class provides a simplified way to set up and control responses for repository methods.
|
||||
*/
|
||||
class FakeGeneratorRepository : GeneratorRepository {
|
||||
private var generatePasswordResult: GeneratedPasswordResult = GeneratedPasswordResult.Success(
|
||||
generatedString = "pa11w0rd",
|
||||
)
|
||||
private var passwordGenerationOptions: PasswordGenerationOptions? = null
|
||||
|
||||
override suspend fun generatePassword(
|
||||
passwordGeneratorRequest: PasswordGeneratorRequest,
|
||||
): GeneratedPasswordResult {
|
||||
return generatePasswordResult
|
||||
}
|
||||
|
||||
override fun getPasswordGenerationOptions(): PasswordGenerationOptions? {
|
||||
return passwordGenerationOptions
|
||||
}
|
||||
|
||||
override fun savePasswordGenerationOptions(options: PasswordGenerationOptions) {
|
||||
passwordGenerationOptions = options
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue