providing a custom initial device display name

- Uses SmallTalk Android with a 4 character random
This commit is contained in:
Adam Brown 2022-10-02 16:58:59 +01:00 committed by Adam Brown
parent 011c7aebf9
commit 4a4fad3cc0
6 changed files with 31 additions and 13 deletions

View File

@ -23,6 +23,7 @@ import app.dapk.st.home.MainActivity
import app.dapk.st.imageloader.ImageLoaderModule
import app.dapk.st.login.LoginModule
import app.dapk.st.matrix.MatrixClient
import app.dapk.st.matrix.auth.DeviceDisplayNameGenerator
import app.dapk.st.matrix.auth.authService
import app.dapk.st.matrix.auth.installAuthService
import app.dapk.st.matrix.common.*
@ -259,7 +260,7 @@ internal class MatrixModules(
logger
).also {
it.install {
installAuthService(credentialsStore)
installAuthService(credentialsStore, SmallTalkDeviceNameGenerator())
installEncryptionService(store.knownDevicesStore())
val olmAccountStore = OlmPersistenceWrapper(store.olmStore(), base64)
@ -516,4 +517,12 @@ internal class AndroidImageContentReader(private val contentResolver: ContentRes
}
override fun inputStream(uri: String): InputStream = contentResolver.openInputStream(Uri.parse(uri))!!
}
internal class SmallTalkDeviceNameGenerator : DeviceDisplayNameGenerator {
override fun generate(): String {
val allowedChars = ('A'..'Z') + ('a'..'z') + ('0'..'9')
val randomIdentifier = (1..4).map { allowedChars.random() }.joinToString("")
return "SmallTalk Android ($randomIdentifier)"
}
}

View File

@ -26,16 +26,17 @@ interface AuthService : MatrixService {
fun MatrixServiceInstaller.installAuthService(
credentialsStore: CredentialsStore,
deviceDisplayNameGenerator: DeviceDisplayNameGenerator = DefaultDeviceDisplayNameGenerator,
): InstallExtender<AuthService> {
return this.install { (httpClient, json) ->
SERVICE_KEY to DefaultAuthService(httpClient, credentialsStore, json)
SERVICE_KEY to DefaultAuthService(httpClient, credentialsStore, json, deviceDisplayNameGenerator)
}
}
fun MatrixClient.authService(): AuthService = this.getService(key = SERVICE_KEY)
fun interface DeviceDisplayNameGenerator {
fun generate(): String?
}
data class AuthConfig(
val forceHttp: Boolean = false,
val forceHomeserver: String? = null
)
val DefaultDeviceDisplayNameGenerator = DeviceDisplayNameGenerator { null }

View File

@ -11,12 +11,12 @@ import app.dapk.st.matrix.http.jsonBody
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
fun loginRequest(userId: UserId, password: String, baseUrl: String) = httpRequest<ApiAuthResponse>(
fun loginRequest(userId: UserId, password: String, baseUrl: String, deviceDisplayName: String?) = httpRequest<ApiAuthResponse>(
path = "_matrix/client/r0/login",
method = MatrixHttpClient.Method.POST,
body = jsonBody(
PasswordLoginRequest.serializer(),
PasswordLoginRequest(PasswordLoginRequest.UserIdentifier(userId), password),
PasswordLoginRequest(PasswordLoginRequest.UserIdentifier(userId), password, deviceDisplayName),
MatrixHttpClient.jsonWithDefaults
),
authenticated = false,
@ -81,6 +81,7 @@ data class ApiWellKnown(
internal data class PasswordLoginRequest(
@SerialName("identifier") val userName: UserIdentifier,
@SerialName("password") val password: String,
@SerialName("initial_device_display_name") val deviceDisplayName: String?,
@SerialName("type") val type: String = "m.login.password",
) {

View File

@ -1,6 +1,7 @@
package app.dapk.st.matrix.auth.internal
import app.dapk.st.matrix.auth.AuthService
import app.dapk.st.matrix.auth.DeviceDisplayNameGenerator
import app.dapk.st.matrix.common.CredentialsStore
import app.dapk.st.matrix.common.HomeServerUrl
import app.dapk.st.matrix.common.UserCredentials
@ -13,11 +14,12 @@ internal class DefaultAuthService(
httpClient: MatrixHttpClient,
credentialsStore: CredentialsStore,
json: Json,
deviceDisplayNameGenerator: DeviceDisplayNameGenerator,
) : AuthService {
private val fetchWellKnownUseCase = FetchWellKnownUseCaseImpl(httpClient, json)
private val loginUseCase = LoginWithUserPasswordUseCase(httpClient, credentialsStore, fetchWellKnownUseCase)
private val loginServerUseCase = LoginWithUserPasswordServerUseCase(httpClient, credentialsStore)
private val loginUseCase = LoginWithUserPasswordUseCase(httpClient, credentialsStore, fetchWellKnownUseCase, deviceDisplayNameGenerator)
private val loginServerUseCase = LoginWithUserPasswordServerUseCase(httpClient, credentialsStore, deviceDisplayNameGenerator)
private val registerCase = RegisterUseCase(httpClient, credentialsStore, json, fetchWellKnownUseCase)
override suspend fun login(request: AuthService.LoginRequest): AuthService.LoginResult {

View File

@ -1,6 +1,7 @@
package app.dapk.st.matrix.auth.internal
import app.dapk.st.matrix.auth.AuthService
import app.dapk.st.matrix.auth.DeviceDisplayNameGenerator
import app.dapk.st.matrix.common.CredentialsStore
import app.dapk.st.matrix.common.HomeServerUrl
import app.dapk.st.matrix.common.UserCredentials
@ -10,6 +11,7 @@ import app.dapk.st.matrix.http.MatrixHttpClient
class LoginWithUserPasswordServerUseCase(
private val httpClient: MatrixHttpClient,
private val credentialsProvider: CredentialsStore,
private val deviceDisplayNameGenerator: DeviceDisplayNameGenerator,
) {
suspend fun login(userName: String, password: String, serverUrl: HomeServerUrl): AuthService.LoginResult {
@ -22,7 +24,7 @@ class LoginWithUserPasswordServerUseCase(
}
private suspend fun authenticate(baseUrl: HomeServerUrl, fullUserId: UserId, password: String): UserCredentials {
val authResponse = httpClient.execute(loginRequest(fullUserId, password, baseUrl.value))
val authResponse = httpClient.execute(loginRequest(fullUserId, password, baseUrl.value, deviceDisplayNameGenerator.generate()))
return UserCredentials(
authResponse.accessToken,
baseUrl,
@ -30,4 +32,4 @@ class LoginWithUserPasswordServerUseCase(
authResponse.deviceId,
).also { credentialsProvider.update(it) }
}
}
}

View File

@ -1,6 +1,7 @@
package app.dapk.st.matrix.auth.internal
import app.dapk.st.matrix.auth.AuthService
import app.dapk.st.matrix.auth.DeviceDisplayNameGenerator
import app.dapk.st.matrix.common.CredentialsStore
import app.dapk.st.matrix.common.HomeServerUrl
import app.dapk.st.matrix.common.UserCredentials
@ -14,6 +15,7 @@ class LoginWithUserPasswordUseCase(
private val httpClient: MatrixHttpClient,
private val credentialsProvider: CredentialsStore,
private val fetchWellKnownUseCase: FetchWellKnownUseCase,
private val deviceDisplayNameGenerator: DeviceDisplayNameGenerator,
) {
suspend fun login(userName: String, password: String): AuthService.LoginResult {
@ -27,6 +29,7 @@ class LoginWithUserPasswordUseCase(
onFailure = { AuthService.LoginResult.Error(it) }
)
}
WellKnownResult.InvalidWellKnown -> AuthService.LoginResult.MissingWellKnown
WellKnownResult.MissingWellKnown -> AuthService.LoginResult.MissingWellKnown
is WellKnownResult.Error -> AuthService.LoginResult.Error(wellKnownResult.cause)
@ -42,7 +45,7 @@ class LoginWithUserPasswordUseCase(
}
private suspend fun authenticate(baseUrl: HomeServerUrl, fullUserId: UserId, password: String): UserCredentials {
val authResponse = httpClient.execute(loginRequest(fullUserId, password, baseUrl.value))
val authResponse = httpClient.execute(loginRequest(fullUserId, password, baseUrl.value, deviceDisplayNameGenerator.generate()))
return UserCredentials(
authResponse.accessToken,
baseUrl,