mirror of
https://github.com/bitwarden/android.git
synced 2026-06-05 22:15:09 -05:00
Setup for generator policy implementation (#888)
This commit is contained in:
committed by
Álison Fernandes
parent
d9d5eaeea2
commit
5ceec9b2f7
@@ -42,4 +42,60 @@ sealed class PolicyInformation {
|
||||
@SerialName("enforceOnLogin")
|
||||
val enforceOnLogin: Boolean?,
|
||||
) : PolicyInformation()
|
||||
|
||||
/**
|
||||
* Represents a policy enforcing rules on the password generator.
|
||||
*
|
||||
* @property defaultType The default type of password to be generated.
|
||||
* @property minLength The minimum length of the password.
|
||||
* @property useUpper Whether the password requires upper case letters.
|
||||
* @property useLower Whether the password requires lower case letters.
|
||||
* @property useNumbers Whether the password requires numbers.
|
||||
* @property useSpecial Whether the password requires special characters.
|
||||
* @property minNumbers The minimum number of digits in the password.
|
||||
* @property minSpecial The minimum number of special characters in the password.
|
||||
* @property minNumberWords The minimum number of words in a passphrase.
|
||||
* @property capitalize Whether to capitalize the first character of each word in a passphrase.
|
||||
* @property includeNumber Whether to include a number at the end of a passphrase.
|
||||
*/
|
||||
@Serializable
|
||||
data class PasswordGenerator(
|
||||
@SerialName("defaultType")
|
||||
val defaultType: String?,
|
||||
|
||||
@SerialName("minLength")
|
||||
val minLength: Int?,
|
||||
|
||||
@SerialName("useUpper")
|
||||
val useUpper: Boolean?,
|
||||
|
||||
@SerialName("useLower")
|
||||
val useLower: Boolean?,
|
||||
|
||||
@SerialName("useNumbers")
|
||||
val useNumbers: Boolean?,
|
||||
|
||||
@SerialName("useSpecial")
|
||||
val useSpecial: Boolean?,
|
||||
|
||||
@SerialName("minNumbers")
|
||||
val minNumbers: Int?,
|
||||
|
||||
@SerialName("minSpecial")
|
||||
val minSpecial: Int?,
|
||||
|
||||
@SerialName("minNumberWords")
|
||||
val minNumberWords: Int?,
|
||||
|
||||
@SerialName("capitalize")
|
||||
val capitalize: Boolean?,
|
||||
|
||||
@SerialName("includeNumber")
|
||||
val includeNumber: Boolean?,
|
||||
) : PolicyInformation() {
|
||||
companion object {
|
||||
const val TYPE_PASSWORD: String = "password"
|
||||
const val TYPE_PASSPHRASE: String = "passphrase"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,9 @@ val SyncResponseJson.Policy.policyInformation: PolicyInformation?
|
||||
PolicyTypeJson.MASTER_PASSWORD -> {
|
||||
Json.decodeFromString<PolicyInformation.MasterPassword>(it)
|
||||
}
|
||||
PolicyTypeJson.PASSWORD_GENERATOR -> {
|
||||
Json.decodeFromString<PolicyInformation.PasswordGenerator>(it)
|
||||
}
|
||||
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.bitwarden.core.PasswordHistoryView
|
||||
import com.bitwarden.generators.PassphraseGeneratorRequest
|
||||
import com.bitwarden.generators.PasswordGeneratorRequest
|
||||
import com.bitwarden.generators.UsernameGeneratorRequest
|
||||
import com.x8bit.bitwarden.data.auth.repository.model.PolicyInformation
|
||||
import com.x8bit.bitwarden.data.platform.repository.model.LocalDataState
|
||||
import com.x8bit.bitwarden.data.tools.generator.repository.model.GeneratedCatchAllUsernameResult
|
||||
import com.x8bit.bitwarden.data.tools.generator.repository.model.GeneratedForwardedServiceUsernameResult
|
||||
@@ -84,6 +85,11 @@ interface GeneratorRepository {
|
||||
forwardedServiceGeneratorRequest: UsernameGeneratorRequest.Forwarded,
|
||||
): GeneratedForwardedServiceUsernameResult
|
||||
|
||||
/**
|
||||
* Get the policy for password generation.
|
||||
*/
|
||||
fun getPasswordGeneratorPolicy(): PolicyInformation.PasswordGenerator?
|
||||
|
||||
/**
|
||||
* Get the [PasscodeGenerationOptions] for the current user.
|
||||
*/
|
||||
|
||||
@@ -7,6 +7,8 @@ import com.bitwarden.generators.PassphraseGeneratorRequest
|
||||
import com.bitwarden.generators.PasswordGeneratorRequest
|
||||
import com.bitwarden.generators.UsernameGeneratorRequest
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
|
||||
import com.x8bit.bitwarden.data.auth.repository.model.PolicyInformation
|
||||
import com.x8bit.bitwarden.data.auth.repository.util.policyInformation
|
||||
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
|
||||
import com.x8bit.bitwarden.data.platform.repository.model.LocalDataState
|
||||
import com.x8bit.bitwarden.data.platform.repository.util.observeWhenSubscribedAndLoggedIn
|
||||
@@ -24,6 +26,7 @@ import com.x8bit.bitwarden.data.tools.generator.repository.model.GeneratedRandom
|
||||
import com.x8bit.bitwarden.data.tools.generator.repository.model.GeneratorResult
|
||||
import com.x8bit.bitwarden.data.tools.generator.repository.model.PasscodeGenerationOptions
|
||||
import com.x8bit.bitwarden.data.tools.generator.repository.model.UsernameGenerationOptions
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.PolicyTypeJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
@@ -39,6 +42,7 @@ import kotlinx.coroutines.flow.receiveAsFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import java.time.Instant
|
||||
import javax.inject.Singleton
|
||||
import kotlin.math.max
|
||||
|
||||
/**
|
||||
* Default implementation of [GeneratorRepository].
|
||||
@@ -197,6 +201,75 @@ class GeneratorRepositoryImpl(
|
||||
},
|
||||
)
|
||||
|
||||
@Suppress("LongMethod", "ReturnCount", "CyclomaticComplexMethod")
|
||||
override fun getPasswordGeneratorPolicy(): PolicyInformation.PasswordGenerator? {
|
||||
val userId = authDiskSource.userState?.activeUserId ?: return null
|
||||
val policies = authDiskSource.getPolicies(userId) ?: return null
|
||||
|
||||
var minLength: Int? = null
|
||||
var useUpper = false
|
||||
var useLower = false
|
||||
var useNumbers = false
|
||||
var useSpecial = false
|
||||
var minNumbers: Int? = null
|
||||
var minSpecial: Int? = null
|
||||
var minNumberWords: Int? = null
|
||||
var capitalize = false
|
||||
var includeNumber = false
|
||||
|
||||
var isPassphrasePresent = false
|
||||
policies.filter { it.type == PolicyTypeJson.PASSWORD_GENERATOR && it.isEnabled }
|
||||
.mapNotNull { it.policyInformation as? PolicyInformation.PasswordGenerator }
|
||||
.forEach { policy ->
|
||||
if (policy.defaultType == PolicyInformation.PasswordGenerator.TYPE_PASSPHRASE) {
|
||||
isPassphrasePresent = true
|
||||
}
|
||||
minLength = max(minLength ?: 0, policy.minLength ?: 0)
|
||||
useUpper = useUpper || policy.useUpper == true
|
||||
useLower = useLower || policy.useLower == true
|
||||
useNumbers = useNumbers || policy.useNumbers == true
|
||||
useSpecial = useSpecial || policy.useSpecial == true
|
||||
minNumbers = max(minNumbers ?: 0, policy.minNumbers ?: 0)
|
||||
minSpecial = max(minSpecial ?: 0, policy.minSpecial ?: 0)
|
||||
minNumberWords = max(minNumberWords ?: 0, policy.minNumberWords ?: 0)
|
||||
capitalize = capitalize || policy.capitalize == true
|
||||
includeNumber = includeNumber || policy.includeNumber == true
|
||||
}
|
||||
|
||||
// Only return a new policy if any policy settings were actually provided
|
||||
return PolicyInformation.PasswordGenerator(
|
||||
defaultType = if (isPassphrasePresent) {
|
||||
PolicyInformation.PasswordGenerator.TYPE_PASSPHRASE
|
||||
} else {
|
||||
PolicyInformation.PasswordGenerator.TYPE_PASSWORD
|
||||
},
|
||||
minLength = minLength,
|
||||
useUpper = useUpper,
|
||||
useLower = useLower,
|
||||
useNumbers = useNumbers,
|
||||
useSpecial = useSpecial,
|
||||
minNumbers = minNumbers,
|
||||
minSpecial = minSpecial,
|
||||
minNumberWords = minNumberWords,
|
||||
capitalize = capitalize,
|
||||
includeNumber = includeNumber,
|
||||
).takeIf {
|
||||
listOf(
|
||||
minLength,
|
||||
useUpper,
|
||||
useLower,
|
||||
useNumbers,
|
||||
useSpecial,
|
||||
minNumbers,
|
||||
minSpecial,
|
||||
minNumberWords,
|
||||
capitalize,
|
||||
includeNumber,
|
||||
)
|
||||
.any { it != null }
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPasscodeGenerationOptions(): PasscodeGenerationOptions? {
|
||||
val userId = authDiskSource.userState?.activeUserId
|
||||
return userId?.let { generatorDiskSource.getPasscodeGenerationOptions(it) }
|
||||
|
||||
Reference in New Issue
Block a user