mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-21 10:17:56 +00:00
Update username validation to use libsignal.
This commit is contained in:
@@ -182,7 +182,7 @@ public class UsernameEditFragment extends LoggingFragment {
|
||||
case DISCRIMINATOR_TOO_LONG -> getString(R.string.UsernameEditFragment__invalid_username_enter_a_maximum_of_d_digits, UsernameUtil.MAX_DISCRIMINATOR_LENGTH);
|
||||
case DISCRIMINATOR_TOO_SHORT -> getString(R.string.UsernameEditFragment__invalid_username_enter_a_minimum_of_d_digits, UsernameUtil.MIN_DISCRIMINATOR_LENGTH);
|
||||
case DISCRIMINATOR_CANNOT_BE_00 -> getString(R.string.UsernameEditFragment__this_number_cant_be_00);
|
||||
case DISCRIMINATOR_CANNOT_START_WITH_00 -> getString(R.string.UsernameEditFragment__this_number_cant_start_with_00);
|
||||
case DISCRIMINATOR_CANNOT_START_WITH_0 -> getString(R.string.UsernameEditFragment__this_number_cant_start_with_0);
|
||||
};
|
||||
|
||||
int colorRes = error != null ? R.color.signal_colorError : R.color.signal_colorPrimary;
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.thoughtcrime.securesms.profiles.manage.UsernameRepository.UsernameSet
|
||||
import org.thoughtcrime.securesms.util.NetworkUtil
|
||||
import org.thoughtcrime.securesms.util.UsernameUtil.InvalidReason
|
||||
import org.thoughtcrime.securesms.util.UsernameUtil.checkDiscriminator
|
||||
import org.thoughtcrime.securesms.util.UsernameUtil.checkUsername
|
||||
import org.thoughtcrime.securesms.util.UsernameUtil.checkNickname
|
||||
import org.thoughtcrime.securesms.util.rx.RxStore
|
||||
import org.whispersystems.signalservice.api.util.Usernames
|
||||
import java.util.concurrent.TimeUnit
|
||||
@@ -159,7 +159,7 @@ internal class UsernameEditViewModel private constructor(private val mode: Usern
|
||||
return
|
||||
}
|
||||
|
||||
val invalidReason: InvalidReason? = checkUsername(usernameState.getNickname())
|
||||
val invalidReason: InvalidReason? = checkNickname(usernameState.getNickname())
|
||||
if (invalidReason != null) {
|
||||
Log.w(TAG, "Username was submitted, but did not pass validity checks. Reason: $invalidReason")
|
||||
uiState.update { it.copy(buttonState = ButtonState.SUBMIT_DISABLED, usernameStatus = mapNicknameError(invalidReason)) }
|
||||
@@ -257,7 +257,7 @@ internal class UsernameEditViewModel private constructor(private val mode: Usern
|
||||
return
|
||||
}
|
||||
|
||||
val invalidReason: InvalidReason? = checkUsername(nickname)
|
||||
val invalidReason: InvalidReason? = checkNickname(nickname)
|
||||
if (invalidReason != null) {
|
||||
uiState.update { uiState ->
|
||||
uiState.copy(
|
||||
@@ -366,7 +366,7 @@ internal class UsernameEditViewModel private constructor(private val mode: Usern
|
||||
DISCRIMINATOR_TOO_LONG,
|
||||
DISCRIMINATOR_HAS_INVALID_CHARACTERS,
|
||||
DISCRIMINATOR_CANNOT_BE_00,
|
||||
DISCRIMINATOR_CANNOT_START_WITH_00
|
||||
DISCRIMINATOR_CANNOT_START_WITH_0
|
||||
}
|
||||
|
||||
enum class ButtonState {
|
||||
@@ -394,7 +394,9 @@ internal class UsernameEditViewModel private constructor(private val mode: Usern
|
||||
InvalidReason.TOO_LONG -> UsernameStatus.TOO_LONG
|
||||
InvalidReason.STARTS_WITH_NUMBER -> UsernameStatus.CANNOT_START_WITH_NUMBER
|
||||
InvalidReason.INVALID_CHARACTERS -> UsernameStatus.INVALID_CHARACTERS
|
||||
InvalidReason.INVALID_NUMBER, InvalidReason.INVALID_NUMBER_PREFIX -> error("Unexpected reason $invalidReason")
|
||||
InvalidReason.INVALID_NUMBER,
|
||||
InvalidReason.INVALID_NUMBER_00,
|
||||
InvalidReason.INVALID_NUMBER_PREFIX_0 -> error("Unexpected reason $invalidReason")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,8 +405,8 @@ internal class UsernameEditViewModel private constructor(private val mode: Usern
|
||||
InvalidReason.TOO_SHORT -> UsernameStatus.DISCRIMINATOR_TOO_SHORT
|
||||
InvalidReason.TOO_LONG -> UsernameStatus.DISCRIMINATOR_TOO_LONG
|
||||
InvalidReason.INVALID_CHARACTERS -> UsernameStatus.DISCRIMINATOR_HAS_INVALID_CHARACTERS
|
||||
InvalidReason.INVALID_NUMBER -> UsernameStatus.DISCRIMINATOR_CANNOT_BE_00
|
||||
InvalidReason.INVALID_NUMBER_PREFIX -> UsernameStatus.DISCRIMINATOR_CANNOT_START_WITH_00
|
||||
InvalidReason.INVALID_NUMBER_00 -> UsernameStatus.DISCRIMINATOR_CANNOT_BE_00
|
||||
InvalidReason.INVALID_NUMBER_PREFIX_0 -> UsernameStatus.DISCRIMINATOR_CANNOT_START_WITH_0
|
||||
else -> UsernameStatus.INVALID_GENERIC
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
package org.thoughtcrime.securesms.util
|
||||
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.libsignal.usernames.BadDiscriminatorCharacterException
|
||||
import org.signal.libsignal.usernames.BadNicknameCharacterException
|
||||
import org.signal.libsignal.usernames.BaseUsernameException
|
||||
import org.signal.libsignal.usernames.CannotBeEmptyException
|
||||
import org.signal.libsignal.usernames.CannotStartWithDigitException
|
||||
import org.signal.libsignal.usernames.DiscriminatorCannotBeEmptyException
|
||||
import org.signal.libsignal.usernames.DiscriminatorCannotBeSingleDigitException
|
||||
import org.signal.libsignal.usernames.DiscriminatorCannotBeZeroException
|
||||
import org.signal.libsignal.usernames.DiscriminatorCannotHaveLeadingZerosException
|
||||
import org.signal.libsignal.usernames.DiscriminatorTooLargeException
|
||||
import org.signal.libsignal.usernames.NicknameTooLongException
|
||||
import org.signal.libsignal.usernames.NicknameTooShortException
|
||||
import org.signal.libsignal.usernames.Username
|
||||
import java.util.Locale
|
||||
import java.util.regex.Pattern
|
||||
|
||||
@@ -36,52 +49,75 @@ object UsernameUtil {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun checkUsername(value: String?): InvalidReason? {
|
||||
return when {
|
||||
value == null -> {
|
||||
InvalidReason.TOO_SHORT
|
||||
}
|
||||
value.length < MIN_NICKNAME_LENGTH -> {
|
||||
InvalidReason.TOO_SHORT
|
||||
}
|
||||
value.length > MAX_NICKNAME_LENGTH -> {
|
||||
InvalidReason.TOO_LONG
|
||||
}
|
||||
DIGIT_START_PATTERN.matcher(value).matches() -> {
|
||||
InvalidReason.STARTS_WITH_NUMBER
|
||||
}
|
||||
!FULL_PATTERN.matcher(value).matches() -> {
|
||||
InvalidReason.INVALID_CHARACTERS
|
||||
}
|
||||
else -> {
|
||||
null
|
||||
}
|
||||
fun checkNickname(value: String?): InvalidReason? {
|
||||
if (value == null) {
|
||||
return InvalidReason.TOO_SHORT
|
||||
}
|
||||
|
||||
return try {
|
||||
// We only want to check the nickname, so we pass in a known-valid discriminator
|
||||
Username.fromParts(value, "01", MIN_NICKNAME_LENGTH, MAX_NICKNAME_LENGTH)
|
||||
null
|
||||
} catch (e: BadNicknameCharacterException) {
|
||||
InvalidReason.INVALID_CHARACTERS
|
||||
} catch (e: CannotBeEmptyException) {
|
||||
InvalidReason.TOO_SHORT
|
||||
} catch (e: CannotStartWithDigitException) {
|
||||
InvalidReason.STARTS_WITH_NUMBER
|
||||
} catch (e: NicknameTooLongException) {
|
||||
InvalidReason.TOO_LONG
|
||||
} catch (e: NicknameTooShortException) {
|
||||
InvalidReason.TOO_SHORT
|
||||
} catch (e: BaseUsernameException) {
|
||||
Log.w(TAG, "Unhandled verification exception!", e)
|
||||
InvalidReason.INVALID_CHARACTERS
|
||||
}
|
||||
}
|
||||
|
||||
fun checkDiscriminator(value: String?): InvalidReason? {
|
||||
return when {
|
||||
value == null -> {
|
||||
null
|
||||
}
|
||||
value == "00" -> {
|
||||
InvalidReason.INVALID_NUMBER
|
||||
}
|
||||
value.startsWith("00") -> {
|
||||
InvalidReason.INVALID_NUMBER_PREFIX
|
||||
}
|
||||
value.length < MIN_DISCRIMINATOR_LENGTH -> {
|
||||
if (value == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (value.length < MIN_DISCRIMINATOR_LENGTH) {
|
||||
return InvalidReason.TOO_SHORT
|
||||
}
|
||||
|
||||
if (value.length > MAX_DISCRIMINATOR_LENGTH) {
|
||||
return InvalidReason.TOO_LONG
|
||||
}
|
||||
|
||||
return try {
|
||||
// We only want to check the discriminator, so we pass in a known-valid nickname
|
||||
Username.fromParts("spiderman", value, MIN_NICKNAME_LENGTH, MAX_NICKNAME_LENGTH)
|
||||
null
|
||||
} catch (e: BadDiscriminatorCharacterException) {
|
||||
InvalidReason.INVALID_CHARACTERS
|
||||
} catch (e: DiscriminatorCannotBeEmptyException) {
|
||||
InvalidReason.TOO_SHORT
|
||||
} catch (e: DiscriminatorCannotBeSingleDigitException) {
|
||||
InvalidReason.TOO_SHORT
|
||||
} catch (e: DiscriminatorCannotBeZeroException) {
|
||||
if (value.length < 2) {
|
||||
InvalidReason.TOO_SHORT
|
||||
} else if (value == "00") {
|
||||
InvalidReason.INVALID_NUMBER_00
|
||||
} else {
|
||||
InvalidReason.INVALID_NUMBER_PREFIX_0
|
||||
}
|
||||
value.length > MAX_DISCRIMINATOR_LENGTH -> {
|
||||
InvalidReason.TOO_LONG
|
||||
}
|
||||
value.toIntOrNull() == null -> {
|
||||
InvalidReason.INVALID_CHARACTERS
|
||||
}
|
||||
else -> {
|
||||
null
|
||||
} catch (e: DiscriminatorCannotHaveLeadingZerosException) {
|
||||
if (value.length < 2) {
|
||||
InvalidReason.TOO_SHORT
|
||||
} else if (value == "00") {
|
||||
InvalidReason.INVALID_NUMBER_00
|
||||
} else {
|
||||
InvalidReason.INVALID_NUMBER_PREFIX_0
|
||||
}
|
||||
} catch (e: DiscriminatorTooLargeException) {
|
||||
InvalidReason.TOO_LONG
|
||||
} catch (e: BaseUsernameException) {
|
||||
Log.w(TAG, "Unhandled verification exception!", e)
|
||||
InvalidReason.INVALID_CHARACTERS
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +127,7 @@ object UsernameUtil {
|
||||
INVALID_CHARACTERS,
|
||||
STARTS_WITH_NUMBER,
|
||||
INVALID_NUMBER,
|
||||
INVALID_NUMBER_PREFIX
|
||||
INVALID_NUMBER_00,
|
||||
INVALID_NUMBER_PREFIX_0
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user