mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-26 19:56:02 +01:00
Add mostly-working SVR3 implementation behind flag.
This commit is contained in:
committed by
Alex Hart
parent
143a61e312
commit
664c22d8f1
@@ -233,7 +233,7 @@ public final class RegistrationRepository {
|
||||
.map(BackupAuthCheckProcessor::new)
|
||||
.doOnSuccess(processor -> {
|
||||
Log.d(TAG, "Received SVR backup auth credential response.");
|
||||
if (SignalStore.svr().removeAuthTokens(processor.getInvalid())) {
|
||||
if (SignalStore.svr().removeSvr2AuthTokens(processor.getInvalid())) {
|
||||
new BackupManager(context).dataChanged();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -21,7 +21,7 @@ sealed class VerifyResponseProcessor(response: ServiceResponse<VerifyResponse>)
|
||||
get() {
|
||||
return error?.let {
|
||||
if (it is LockedException) {
|
||||
SvrAuthCredentialSet(it.svr1Credentials, it.svr2Credentials)
|
||||
SvrAuthCredentialSet(svr2Credentials = it.svr2Credentials, svr3Credentials = it.svr3Credentials)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
@@ -65,7 +65,7 @@ sealed class VerifyResponseProcessor(response: ServiceResponse<VerifyResponse>)
|
||||
*/
|
||||
class VerifyResponseWithoutKbs(response: ServiceResponse<VerifyResponse>) : VerifyResponseProcessor(response) {
|
||||
override fun isRegistrationLockPresentAndSvrExhausted(): Boolean {
|
||||
return registrationLock() && getLockedException().svr1Credentials == null && getLockedException().svr2Credentials == null
|
||||
return registrationLock() && getLockedException().svr2Credentials == null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import android.content.Context
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import com.google.android.gms.auth.api.phone.SmsRetriever
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.tasks.await
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.coroutines.withTimeoutOrNull
|
||||
@@ -37,6 +36,7 @@ import org.thoughtcrime.securesms.jobs.RotateCertificateJob
|
||||
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.notifications.NotificationIds
|
||||
import org.thoughtcrime.securesms.pin.Svr3Migration
|
||||
import org.thoughtcrime.securesms.pin.SvrRepository
|
||||
import org.thoughtcrime.securesms.pin.SvrWrongPinException
|
||||
import org.thoughtcrime.securesms.push.AccountManagerFactory
|
||||
@@ -67,6 +67,7 @@ import org.whispersystems.signalservice.api.push.ServiceId.ACI
|
||||
import org.whispersystems.signalservice.api.push.ServiceId.PNI
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress
|
||||
import org.whispersystems.signalservice.api.registration.RegistrationApi
|
||||
import org.whispersystems.signalservice.api.svr.Svr3Credentials
|
||||
import org.whispersystems.signalservice.internal.push.AuthCredentials
|
||||
import org.whispersystems.signalservice.internal.push.PushServiceSocket
|
||||
import org.whispersystems.signalservice.internal.push.RegistrationSessionMetadataHeaders
|
||||
@@ -259,9 +260,10 @@ object RegistrationRepository {
|
||||
return PinHashUtil.verifyLocalPinHash(pinHash, pin)
|
||||
}
|
||||
|
||||
suspend fun fetchMasterKeyFromSvrRemote(pin: String, authCredentials: AuthCredentials): MasterKey =
|
||||
suspend fun fetchMasterKeyFromSvrRemote(pin: String, svr2Credentials: AuthCredentials?, svr3Credentials: Svr3Credentials?): MasterKey =
|
||||
withContext(Dispatchers.IO) {
|
||||
val masterKey = SvrRepository.restoreMasterKeyPreRegistration(SvrAuthCredentialSet(null, authCredentials), pin)
|
||||
val credentialSet = SvrAuthCredentialSet(svr2Credentials = svr2Credentials, svr3Credentials = svr3Credentials)
|
||||
val masterKey = SvrRepository.restoreMasterKeyPreRegistration(credentialSet, pin)
|
||||
SignalStore.svr().setMasterKey(masterKey, pin)
|
||||
return@withContext masterKey
|
||||
}
|
||||
@@ -488,36 +490,55 @@ object RegistrationRepository {
|
||||
|
||||
suspend fun hasValidSvrAuthCredentials(context: Context, e164: String, password: String): BackupAuthCheckResult =
|
||||
withContext(Dispatchers.IO) {
|
||||
val usernamePasswords = async { retrieveLocalSvrCredentials() }
|
||||
val api: RegistrationApi = AccountManagerFactory.getInstance().createUnauthenticated(context, e164, SignalServiceAddress.DEFAULT_DEVICE_ID, password).registrationApi
|
||||
|
||||
val authTokens = usernamePasswords.await()
|
||||
|
||||
if (authTokens.isEmpty()) {
|
||||
return@withContext BackupAuthCheckResult.SuccessWithoutCredentials()
|
||||
}
|
||||
|
||||
val result = api.getSvrAuthCredential(e164, authTokens)
|
||||
.runIfSuccessful {
|
||||
val removedInvalidTokens = SignalStore.svr().removeAuthTokens(it.invalid)
|
||||
if (removedInvalidTokens) {
|
||||
BackupManager(context).dataChanged()
|
||||
}
|
||||
val svr3Result = SignalStore.svr().svr3AuthTokens
|
||||
?.takeIf { Svr3Migration.shouldReadFromSvr3 }
|
||||
?.takeIf { it.isNotEmpty() }
|
||||
?.toSvrCredentials()
|
||||
?.let { authTokens ->
|
||||
api
|
||||
.validateSvr3AuthCredential(e164, authTokens)
|
||||
.runIfSuccessful {
|
||||
val removedInvalidTokens = SignalStore.svr().removeSvr3AuthTokens(it.invalid)
|
||||
if (removedInvalidTokens) {
|
||||
BackupManager(context).dataChanged()
|
||||
}
|
||||
}
|
||||
.let { BackupAuthCheckResult.fromV3(it) }
|
||||
}
|
||||
|
||||
return@withContext BackupAuthCheckResult.from(result)
|
||||
if (svr3Result is BackupAuthCheckResult.SuccessWithCredentials) {
|
||||
Log.d(TAG, "Found valid SVR3 credentials.")
|
||||
return@withContext svr3Result
|
||||
}
|
||||
|
||||
Log.d(TAG, "No valid SVR3 credentials, looking for SVR2.")
|
||||
|
||||
return@withContext SignalStore.svr().svr2AuthTokens
|
||||
?.takeIf { it.isNotEmpty() }
|
||||
?.toSvrCredentials()
|
||||
?.let { authTokens ->
|
||||
api
|
||||
.validateSvr2AuthCredential(e164, authTokens)
|
||||
.runIfSuccessful {
|
||||
val removedInvalidTokens = SignalStore.svr().removeSvr2AuthTokens(it.invalid)
|
||||
if (removedInvalidTokens) {
|
||||
BackupManager(context).dataChanged()
|
||||
}
|
||||
}
|
||||
.let { BackupAuthCheckResult.fromV2(it) }
|
||||
} ?: BackupAuthCheckResult.SuccessWithoutCredentials()
|
||||
}
|
||||
|
||||
private suspend fun retrieveLocalSvrCredentials(): List<String> = withContext(Dispatchers.IO) {
|
||||
return@withContext SignalStore.svr()
|
||||
.authTokenList
|
||||
/** Converts the basic-auth creds we have locally into username:password pairs that are suitable for handing off to the service. */
|
||||
private fun List<String?>.toSvrCredentials(): List<String> {
|
||||
return this
|
||||
.asSequence()
|
||||
.filterNotNull()
|
||||
.take<String>(10)
|
||||
.map<String, String> {
|
||||
it.replace("Basic ", "").trim()
|
||||
}
|
||||
.mapNotNull<String, ByteArray> {
|
||||
.take(10)
|
||||
.map { it.replace("Basic ", "").trim() }
|
||||
.mapNotNull {
|
||||
try {
|
||||
Base64.decode(it)
|
||||
} catch (e: IOException) {
|
||||
@@ -525,9 +546,7 @@ object RegistrationRepository {
|
||||
null
|
||||
}
|
||||
}
|
||||
.map<ByteArray, String> {
|
||||
String(it, StandardCharsets.ISO_8859_1)
|
||||
}
|
||||
.map { String(it, StandardCharsets.ISO_8859_1) }
|
||||
.toList()
|
||||
}
|
||||
|
||||
|
||||
@@ -6,21 +6,41 @@
|
||||
package org.thoughtcrime.securesms.registration.v2.data.network
|
||||
|
||||
import org.whispersystems.signalservice.api.NetworkResult
|
||||
import org.whispersystems.signalservice.api.svr.Svr3Credentials
|
||||
import org.whispersystems.signalservice.internal.push.AuthCredentials
|
||||
import org.whispersystems.signalservice.internal.push.BackupAuthCheckResponse
|
||||
import org.whispersystems.signalservice.internal.push.BackupV2AuthCheckResponse
|
||||
import org.whispersystems.signalservice.internal.push.BackupV3AuthCheckResponse
|
||||
|
||||
/**
|
||||
* This is a processor to map a [BackupAuthCheckResponse] to all the known outcomes.
|
||||
* This is a processor to map a [BackupV2AuthCheckResponse] to all the known outcomes.
|
||||
*/
|
||||
sealed class BackupAuthCheckResult(cause: Throwable?) : RegistrationResult(cause) {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun from(networkResult: NetworkResult<BackupAuthCheckResponse>): BackupAuthCheckResult {
|
||||
fun fromV2(networkResult: NetworkResult<BackupV2AuthCheckResponse>): BackupAuthCheckResult {
|
||||
return when (networkResult) {
|
||||
is NetworkResult.Success -> {
|
||||
val match = networkResult.result.match
|
||||
if (match != null) {
|
||||
SuccessWithCredentials(match)
|
||||
SuccessWithCredentials(svr2Credentials = match, svr3Credentials = null)
|
||||
} else {
|
||||
SuccessWithoutCredentials()
|
||||
}
|
||||
}
|
||||
|
||||
is NetworkResult.ApplicationError -> UnknownError(networkResult.throwable)
|
||||
is NetworkResult.NetworkError -> UnknownError(networkResult.exception)
|
||||
is NetworkResult.StatusCodeError -> UnknownError(networkResult.exception)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun fromV3(networkResult: NetworkResult<BackupV3AuthCheckResponse>): BackupAuthCheckResult {
|
||||
return when (networkResult) {
|
||||
is NetworkResult.Success -> {
|
||||
val match = networkResult.result.match
|
||||
if (match != null) {
|
||||
SuccessWithCredentials(svr2Credentials = null, svr3Credentials = match)
|
||||
} else {
|
||||
SuccessWithoutCredentials()
|
||||
}
|
||||
@@ -33,7 +53,7 @@ sealed class BackupAuthCheckResult(cause: Throwable?) : RegistrationResult(cause
|
||||
}
|
||||
}
|
||||
|
||||
class SuccessWithCredentials(val authCredentials: AuthCredentials) : BackupAuthCheckResult(null)
|
||||
class SuccessWithCredentials(val svr2Credentials: AuthCredentials?, val svr3Credentials: Svr3Credentials?) : BackupAuthCheckResult(null)
|
||||
|
||||
class SuccessWithoutCredentials : BackupAuthCheckResult(null)
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedE
|
||||
import org.whispersystems.signalservice.api.push.exceptions.IncorrectRegistrationRecoveryPasswordException
|
||||
import org.whispersystems.signalservice.api.push.exceptions.MalformedRequestException
|
||||
import org.whispersystems.signalservice.api.push.exceptions.RateLimitException
|
||||
import org.whispersystems.signalservice.api.svr.Svr3Credentials
|
||||
import org.whispersystems.signalservice.internal.push.AuthCredentials
|
||||
import org.whispersystems.signalservice.internal.push.LockedException
|
||||
import org.whispersystems.signalservice.internal.push.VerifyAccountResponse
|
||||
@@ -33,7 +34,7 @@ sealed class RegisterAccountResult(cause: Throwable?) : RegistrationResult(cause
|
||||
is AuthorizationFailedException -> AuthorizationFailed(cause)
|
||||
is MalformedRequestException -> MalformedRequest(cause)
|
||||
is RateLimitException -> createRateLimitProcessor(cause)
|
||||
is LockedException -> RegistrationLocked(cause = cause, timeRemaining = cause.timeRemaining, svr2Credentials = cause.svr2Credentials)
|
||||
is LockedException -> RegistrationLocked(cause = cause, timeRemaining = cause.timeRemaining, svr2Credentials = cause.svr2Credentials, svr3Credentials = cause.svr3Credentials)
|
||||
else -> {
|
||||
if (networkResult.code == 422) {
|
||||
ValidationError(cause)
|
||||
@@ -61,7 +62,7 @@ sealed class RegisterAccountResult(cause: Throwable?) : RegistrationResult(cause
|
||||
class ValidationError(cause: Throwable) : RegisterAccountResult(cause)
|
||||
class RateLimited(cause: Throwable, val timeRemaining: Long) : RegisterAccountResult(cause)
|
||||
class AttemptsExhausted(cause: Throwable) : RegisterAccountResult(cause)
|
||||
class RegistrationLocked(cause: Throwable, val timeRemaining: Long, val svr2Credentials: AuthCredentials?) : RegisterAccountResult(cause)
|
||||
class RegistrationLocked(cause: Throwable, val timeRemaining: Long, val svr2Credentials: AuthCredentials?, val svr3Credentials: Svr3Credentials?) : RegisterAccountResult(cause)
|
||||
class UnknownError(cause: Throwable) : RegisterAccountResult(cause)
|
||||
|
||||
class SvrNoData(cause: SvrNoDataException) : RegisterAccountResult(cause)
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.whispersystems.signalservice.api.push.exceptions.PushChallengeRequire
|
||||
import org.whispersystems.signalservice.api.push.exceptions.RateLimitException
|
||||
import org.whispersystems.signalservice.api.push.exceptions.RegistrationRetryException
|
||||
import org.whispersystems.signalservice.api.push.exceptions.TokenNotAcceptedException
|
||||
import org.whispersystems.signalservice.api.svr.Svr3Credentials
|
||||
import org.whispersystems.signalservice.internal.push.AuthCredentials
|
||||
import org.whispersystems.signalservice.internal.push.LockedException
|
||||
import org.whispersystems.signalservice.internal.push.RegistrationSessionMetadataJson
|
||||
@@ -70,7 +71,7 @@ sealed class VerificationCodeRequestResult(cause: Throwable?) : RegistrationResu
|
||||
is InvalidTransportModeException -> InvalidTransportModeFailure(cause)
|
||||
is MalformedRequestException -> MalformedRequest(cause)
|
||||
is RegistrationRetryException -> MustRetry(cause)
|
||||
is LockedException -> RegistrationLocked(cause = cause, timeRemaining = cause.timeRemaining, svr2Credentials = cause.svr2Credentials)
|
||||
is LockedException -> RegistrationLocked(cause = cause, timeRemaining = cause.timeRemaining, svr2Credentials = cause.svr2Credentials, svr3Credentials = cause.svr3Credentials)
|
||||
is NoSuchSessionException -> NoSuchSession(cause)
|
||||
is AlreadyVerifiedException -> AlreadyVerified(cause)
|
||||
else -> UnknownError(cause)
|
||||
@@ -125,7 +126,7 @@ sealed class VerificationCodeRequestResult(cause: Throwable?) : RegistrationResu
|
||||
|
||||
class MustRetry(cause: Throwable) : VerificationCodeRequestResult(cause)
|
||||
|
||||
class RegistrationLocked(cause: Throwable, val timeRemaining: Long, val svr2Credentials: AuthCredentials) : VerificationCodeRequestResult(cause)
|
||||
class RegistrationLocked(cause: Throwable, val timeRemaining: Long, val svr2Credentials: AuthCredentials, val svr3Credentials: Svr3Credentials) : VerificationCodeRequestResult(cause)
|
||||
|
||||
class NoSuchSession(cause: Throwable) : VerificationCodeRequestResult(cause)
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.google.i18n.phonenumbers.Phonenumber
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.registration.v2.data.network.Challenge
|
||||
import org.whispersystems.signalservice.api.svr.Svr3Credentials
|
||||
import org.whispersystems.signalservice.internal.push.AuthCredentials
|
||||
|
||||
/**
|
||||
@@ -24,7 +25,8 @@ data class RegistrationV2State(
|
||||
val isReRegister: Boolean = false,
|
||||
val recoveryPassword: String? = SignalStore.svr().getRecoveryPassword(),
|
||||
val canSkipSms: Boolean = false,
|
||||
val svrAuthCredentials: AuthCredentials? = null,
|
||||
val svr2AuthCredentials: AuthCredentials? = null,
|
||||
val svr3AuthCredentials: Svr3Credentials? = null,
|
||||
val svrTriesRemaining: Int = 10,
|
||||
val incorrectCodeAttempts: Int = 0,
|
||||
val isRegistrationLockEnabled: Boolean = false,
|
||||
|
||||
@@ -229,7 +229,13 @@ class RegistrationV2ViewModel : ViewModel() {
|
||||
is BackupAuthCheckResult.SuccessWithCredentials -> {
|
||||
Log.d(TAG, "Found local valid SVR auth credentials.")
|
||||
store.update {
|
||||
it.copy(isReRegister = true, canSkipSms = true, svrAuthCredentials = svrCredentialsResult.authCredentials, inProgress = false)
|
||||
it.copy(
|
||||
isReRegister = true,
|
||||
canSkipSms = true,
|
||||
svr2AuthCredentials = svrCredentialsResult.svr2Credentials,
|
||||
svr3AuthCredentials = svrCredentialsResult.svr3Credentials,
|
||||
inProgress = false
|
||||
)
|
||||
}
|
||||
return@launch
|
||||
}
|
||||
@@ -571,12 +577,14 @@ class RegistrationV2ViewModel : ViewModel() {
|
||||
}
|
||||
|
||||
// remote recovery password
|
||||
val authCredentials = store.value.svrAuthCredentials
|
||||
if (authCredentials != null) {
|
||||
Log.d(TAG, "Found SVR auth credentials, fetching recovery password from SVR.")
|
||||
val svr2Credentials = store.value.svr2AuthCredentials
|
||||
val svr3Credentials = store.value.svr3AuthCredentials
|
||||
|
||||
if (svr2Credentials != null || svr3Credentials != null) {
|
||||
Log.d(TAG, "Found SVR auth credentials, fetching recovery password from SVR (svr2: ${svr2Credentials != null}, svr3: ${svr3Credentials != null}).")
|
||||
viewModelScope.launch(context = coroutineExceptionHandler) {
|
||||
try {
|
||||
val masterKey = RegistrationRepository.fetchMasterKeyFromSvrRemote(pin, authCredentials)
|
||||
val masterKey = RegistrationRepository.fetchMasterKeyFromSvrRemote(pin, svr2Credentials, svr3Credentials)
|
||||
setRecoveryPassword(masterKey.deriveRegistrationRecoveryPassword())
|
||||
updateSvrTriesRemaining(10)
|
||||
verifyReRegisterInternal(context, pin, masterKey, registrationErrorHandler)
|
||||
@@ -628,7 +636,10 @@ class RegistrationV2ViewModel : ViewModel() {
|
||||
|
||||
Log.i(TAG, "Received a registration lock response when trying to register an account. Retrying with master key.")
|
||||
store.update {
|
||||
it.copy(svrAuthCredentials = registrationResult.svr2Credentials)
|
||||
it.copy(
|
||||
svr2AuthCredentials = registrationResult.svr2Credentials,
|
||||
svr3AuthCredentials = registrationResult.svr3Credentials
|
||||
)
|
||||
}
|
||||
|
||||
return Pair(RegistrationRepository.registerAccount(context = context, sessionId = sessionId, registrationData = registrationData, pin = pin) { masterKey }, true)
|
||||
@@ -716,19 +727,26 @@ class RegistrationV2ViewModel : ViewModel() {
|
||||
if (pin == null && SignalStore.svr().registrationLockToken != null) {
|
||||
Log.d(TAG, "Retrying registration with stored credentials.")
|
||||
result = RegistrationRepository.registerAccount(context, sessionId, registrationData, SignalStore.svr().pin) { SignalStore.svr().getOrCreateMasterKey() }
|
||||
} else if (result.svr2Credentials != null) {
|
||||
Log.d(TAG, "Retrying registration with received credentials.")
|
||||
val credentials = result.svr2Credentials
|
||||
} else if (result.svr2Credentials != null || result.svr3Credentials != null) {
|
||||
Log.d(TAG, "Retrying registration with received credentials (svr2: ${result.svr2Credentials != null}, svr3: ${result.svr3Credentials != null}).")
|
||||
val svr2Credentials = result.svr2Credentials
|
||||
val svr3Credentials = result.svr3Credentials
|
||||
state = store.updateAndGet {
|
||||
it.copy(svrAuthCredentials = credentials)
|
||||
it.copy(svr2AuthCredentials = svr2Credentials, svr3AuthCredentials = svr3Credentials)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reglock && pin.isNotNullOrBlank()) {
|
||||
Log.d(TAG, "Registration lock enabled, attempting to register account restore master key from SVR.")
|
||||
Log.d(TAG, "Registration lock enabled, attempting to register account restore master key from SVR (svr2: ${state.svr2AuthCredentials != null}, svr3: ${state.svr3AuthCredentials != null})")
|
||||
result = RegistrationRepository.registerAccount(context, sessionId, registrationData, pin) {
|
||||
SvrRepository.restoreMasterKeyPreRegistration(SvrAuthCredentialSet(null, state.svrAuthCredentials), pin)
|
||||
SvrRepository.restoreMasterKeyPreRegistration(
|
||||
credentials = SvrAuthCredentialSet(
|
||||
svr2Credentials = state.svr2AuthCredentials,
|
||||
svr3Credentials = state.svr3AuthCredentials
|
||||
),
|
||||
userPin = pin
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -353,7 +353,7 @@ public final class RegistrationViewModel extends BaseRegistrationViewModel {
|
||||
}
|
||||
|
||||
private Single<Boolean> checkForValidSvrAuthCredentials() {
|
||||
final List<String> svrAuthTokenList = SignalStore.svr().getAuthTokenList();
|
||||
final List<String> svrAuthTokenList = SignalStore.svr().getSvr2AuthTokens();
|
||||
List<String> usernamePasswords = svrAuthTokenList
|
||||
.stream()
|
||||
.limit(10)
|
||||
@@ -376,7 +376,7 @@ public final class RegistrationViewModel extends BaseRegistrationViewModel {
|
||||
.flatMap(p -> {
|
||||
if (p.hasValidSvr2AuthCredential()) {
|
||||
Log.d(TAG, "Saving valid SVR2 auth credential.");
|
||||
setSvrAuthCredentials(new SvrAuthCredentialSet(null, p.requireSvr2AuthCredential()));
|
||||
setSvrAuthCredentials(new SvrAuthCredentialSet(p.requireSvr2AuthCredential(), null));
|
||||
return Single.just(true);
|
||||
} else {
|
||||
Log.d(TAG, "SVR2 response contained no valid SVR2 auth credentials.");
|
||||
|
||||
@@ -7,20 +7,24 @@ package org.thoughtcrime.securesms.registration.viewmodel
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import org.whispersystems.signalservice.api.svr.Svr3Credentials
|
||||
import org.whispersystems.signalservice.internal.push.AuthCredentials
|
||||
|
||||
@Parcelize
|
||||
data class SvrAuthCredentialSet(
|
||||
private val svr1Credentials: ParcelableAuthCredentials?,
|
||||
private val svr2Credentials: ParcelableAuthCredentials?
|
||||
private val svr2Credentials: ParcelableAuthCredentials?,
|
||||
private val svr3Credentials: ParcelableSvr3AuthCredentials?
|
||||
) : Parcelable {
|
||||
constructor(
|
||||
svr1Credentials: AuthCredentials?,
|
||||
svr2Credentials: AuthCredentials?
|
||||
) : this(ParcelableAuthCredentials.createOrNull(svr1Credentials), ParcelableAuthCredentials.createOrNull(svr2Credentials))
|
||||
svr2Credentials: AuthCredentials?,
|
||||
svr3Credentials: Svr3Credentials?
|
||||
) : this(
|
||||
ParcelableAuthCredentials.createOrNull(svr2Credentials),
|
||||
ParcelableSvr3AuthCredentials.createOrNull(svr3Credentials)
|
||||
)
|
||||
|
||||
val svr1: AuthCredentials? = svr1Credentials?.credentials()
|
||||
val svr2: AuthCredentials? = svr2Credentials?.credentials()
|
||||
val svr3: Svr3Credentials? = svr3Credentials?.credentials()
|
||||
|
||||
@Parcelize
|
||||
data class ParcelableAuthCredentials(private val username: String, private val password: String) : Parcelable {
|
||||
@@ -39,4 +43,22 @@ data class SvrAuthCredentialSet(
|
||||
return AuthCredentials.create(username, password)
|
||||
}
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
data class ParcelableSvr3AuthCredentials(private val username: String, private val password: String, private val shareSet: ByteArray?) : Parcelable {
|
||||
|
||||
companion object {
|
||||
fun createOrNull(creds: Svr3Credentials?): ParcelableSvr3AuthCredentials? {
|
||||
return if (creds != null) {
|
||||
ParcelableSvr3AuthCredentials(creds.username, creds.password, creds.shareSet)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun credentials(): Svr3Credentials {
|
||||
return Svr3Credentials(username, password, shareSet)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user