Merge pull request #7358 from vector-im/feature/hughns/qr_code_login_task
This commit is contained in:
commit
626e3dbd10
|
@ -0,0 +1 @@
|
|||
Add support for `m.login.token` auth during QR code based sign in
|
|
@ -124,4 +124,18 @@ interface AuthenticationService {
|
|||
initialDeviceName: String,
|
||||
deviceId: String? = null
|
||||
): Session
|
||||
|
||||
/**
|
||||
* Authenticate using m.login.token method during sign in with QR code.
|
||||
* @param homeServerConnectionConfig the information about the homeserver and other configuration
|
||||
* @param loginToken the m.login.token
|
||||
* @param initialDeviceName the initial device name
|
||||
* @param deviceId the device id, optional. If not provided or null, the server will generate one.
|
||||
*/
|
||||
suspend fun loginUsingQrLoginToken(
|
||||
homeServerConnectionConfig: HomeServerConnectionConfig,
|
||||
loginToken: String,
|
||||
initialDeviceName: String? = null,
|
||||
deviceId: String? = null
|
||||
): Session
|
||||
}
|
||||
|
|
|
@ -22,7 +22,8 @@ enum class LoginType {
|
|||
UNSUPPORTED,
|
||||
CUSTOM,
|
||||
DIRECT,
|
||||
UNKNOWN;
|
||||
UNKNOWN,
|
||||
QR;
|
||||
|
||||
companion object {
|
||||
|
||||
|
@ -32,6 +33,7 @@ enum class LoginType {
|
|||
UNSUPPORTED.name -> UNSUPPORTED
|
||||
CUSTOM.name -> CUSTOM
|
||||
DIRECT.name -> DIRECT
|
||||
QR.name -> QR
|
||||
else -> UNKNOWN
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,9 @@ import org.matrix.android.sdk.internal.auth.db.AuthRealmModule
|
|||
import org.matrix.android.sdk.internal.auth.db.RealmPendingSessionStore
|
||||
import org.matrix.android.sdk.internal.auth.db.RealmSessionParamsStore
|
||||
import org.matrix.android.sdk.internal.auth.login.DefaultDirectLoginTask
|
||||
import org.matrix.android.sdk.internal.auth.login.DefaultQrLoginTokenTask
|
||||
import org.matrix.android.sdk.internal.auth.login.DirectLoginTask
|
||||
import org.matrix.android.sdk.internal.auth.login.QrLoginTokenTask
|
||||
import org.matrix.android.sdk.internal.database.RealmKeysUtils
|
||||
import org.matrix.android.sdk.internal.di.AuthDatabase
|
||||
import org.matrix.android.sdk.internal.legacy.DefaultLegacySessionImporter
|
||||
|
@ -94,4 +96,7 @@ internal abstract class AuthModule {
|
|||
|
||||
@Binds
|
||||
abstract fun bindHomeServerHistoryService(service: DefaultHomeServerHistoryService): HomeServerHistoryService
|
||||
|
||||
@Binds
|
||||
abstract fun bindQrLoginTokenTask(task: DefaultQrLoginTokenTask): QrLoginTokenTask
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.matrix.android.sdk.internal.auth.data.WebClientConfig
|
|||
import org.matrix.android.sdk.internal.auth.db.PendingSessionData
|
||||
import org.matrix.android.sdk.internal.auth.login.DefaultLoginWizard
|
||||
import org.matrix.android.sdk.internal.auth.login.DirectLoginTask
|
||||
import org.matrix.android.sdk.internal.auth.login.QrLoginTokenTask
|
||||
import org.matrix.android.sdk.internal.auth.registration.DefaultRegistrationWizard
|
||||
import org.matrix.android.sdk.internal.auth.version.Versions
|
||||
import org.matrix.android.sdk.internal.auth.version.doesServerSupportLogoutDevices
|
||||
|
@ -62,7 +63,8 @@ internal class DefaultAuthenticationService @Inject constructor(
|
|||
private val sessionCreator: SessionCreator,
|
||||
private val pendingSessionStore: PendingSessionStore,
|
||||
private val getWellknownTask: GetWellknownTask,
|
||||
private val directLoginTask: DirectLoginTask
|
||||
private val directLoginTask: DirectLoginTask,
|
||||
private val qrLoginTokenTask: QrLoginTokenTask
|
||||
) : AuthenticationService {
|
||||
|
||||
private var pendingSessionData: PendingSessionData? = pendingSessionStore.getPendingSessionData()
|
||||
|
@ -404,6 +406,22 @@ internal class DefaultAuthenticationService @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
override suspend fun loginUsingQrLoginToken(
|
||||
homeServerConnectionConfig: HomeServerConnectionConfig,
|
||||
loginToken: String,
|
||||
initialDeviceName: String?,
|
||||
deviceId: String?,
|
||||
): Session {
|
||||
return qrLoginTokenTask.execute(
|
||||
QrLoginTokenTask.Params(
|
||||
homeServerConnectionConfig = homeServerConnectionConfig,
|
||||
loginToken = loginToken,
|
||||
deviceName = initialDeviceName,
|
||||
deviceId = deviceId
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun buildAuthAPI(homeServerConnectionConfig: HomeServerConnectionConfig): AuthAPI {
|
||||
val retrofit = retrofitFactory.create(buildClient(homeServerConnectionConfig), homeServerConnectionConfig.homeServerUriBase.toString())
|
||||
return retrofit.create(AuthAPI::class.java)
|
||||
|
|
|
@ -18,4 +18,6 @@ package org.matrix.android.sdk.internal.auth.data
|
|||
|
||||
internal interface LoginParams {
|
||||
val type: String
|
||||
val deviceDisplayName: String?
|
||||
val deviceId: String?
|
||||
}
|
||||
|
|
|
@ -30,8 +30,8 @@ internal data class PasswordLoginParams(
|
|||
@Json(name = "identifier") val identifier: Map<String, String>,
|
||||
@Json(name = "password") val password: String,
|
||||
@Json(name = "type") override val type: String,
|
||||
@Json(name = "initial_device_display_name") val deviceDisplayName: String?,
|
||||
@Json(name = "device_id") val deviceId: String?
|
||||
@Json(name = "initial_device_display_name") override val deviceDisplayName: String?,
|
||||
@Json(name = "device_id") override val deviceId: String?
|
||||
) : LoginParams {
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -23,5 +23,7 @@ import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
|
|||
@JsonClass(generateAdapter = true)
|
||||
internal data class TokenLoginParams(
|
||||
@Json(name = "type") override val type: String = LoginFlowTypes.TOKEN,
|
||||
@Json(name = "token") val token: String
|
||||
@Json(name = "token") val token: String,
|
||||
@Json(name = "initial_device_display_name") override val deviceDisplayName: String? = null,
|
||||
@Json(name = "device_id") override val deviceId: String? = null
|
||||
) : LoginParams
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.auth.login
|
||||
|
||||
import dagger.Lazy
|
||||
import okhttp3.OkHttpClient
|
||||
import org.matrix.android.sdk.api.auth.LoginType
|
||||
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
|
||||
import org.matrix.android.sdk.api.failure.Failure
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.internal.auth.AuthAPI
|
||||
import org.matrix.android.sdk.internal.auth.SessionCreator
|
||||
import org.matrix.android.sdk.internal.auth.data.TokenLoginParams
|
||||
import org.matrix.android.sdk.internal.di.Unauthenticated
|
||||
import org.matrix.android.sdk.internal.network.RetrofitFactory
|
||||
import org.matrix.android.sdk.internal.network.executeRequest
|
||||
import org.matrix.android.sdk.internal.network.httpclient.addSocketFactory
|
||||
import org.matrix.android.sdk.internal.network.ssl.UnrecognizedCertificateException
|
||||
import org.matrix.android.sdk.internal.task.Task
|
||||
import javax.inject.Inject
|
||||
|
||||
internal interface QrLoginTokenTask : Task<QrLoginTokenTask.Params, Session> {
|
||||
data class Params(
|
||||
val homeServerConnectionConfig: HomeServerConnectionConfig,
|
||||
val loginToken: String,
|
||||
val deviceName: String?,
|
||||
val deviceId: String?
|
||||
)
|
||||
}
|
||||
|
||||
internal class DefaultQrLoginTokenTask @Inject constructor(
|
||||
@Unauthenticated
|
||||
private val okHttpClient: Lazy<OkHttpClient>,
|
||||
private val retrofitFactory: RetrofitFactory,
|
||||
private val sessionCreator: SessionCreator,
|
||||
) : QrLoginTokenTask {
|
||||
|
||||
override suspend fun execute(params: QrLoginTokenTask.Params): Session {
|
||||
val client = buildClient(params.homeServerConnectionConfig)
|
||||
val homeServerUrl = params.homeServerConnectionConfig.homeServerUriBase.toString()
|
||||
|
||||
val authAPI = retrofitFactory.create(client, homeServerUrl)
|
||||
.create(AuthAPI::class.java)
|
||||
|
||||
val loginParams = TokenLoginParams(
|
||||
token = params.loginToken,
|
||||
deviceDisplayName = params.deviceName,
|
||||
deviceId = params.deviceId
|
||||
)
|
||||
|
||||
val credentials = try {
|
||||
executeRequest(null) {
|
||||
authAPI.login(loginParams)
|
||||
}
|
||||
} catch (throwable: Throwable) {
|
||||
throw when (throwable) {
|
||||
is UnrecognizedCertificateException -> Failure.UnrecognizedCertificateFailure(
|
||||
homeServerUrl,
|
||||
throwable.fingerprint
|
||||
)
|
||||
else -> throwable
|
||||
}
|
||||
}
|
||||
|
||||
return sessionCreator.createSession(credentials, params.homeServerConnectionConfig, LoginType.QR)
|
||||
}
|
||||
|
||||
private fun buildClient(homeServerConnectionConfig: HomeServerConnectionConfig): OkHttpClient {
|
||||
return okHttpClient.get()
|
||||
.newBuilder()
|
||||
.addSocketFactory(homeServerConnectionConfig)
|
||||
.build()
|
||||
}
|
||||
}
|
|
@ -152,6 +152,7 @@ class SoftLogoutController @Inject constructor(
|
|||
LoginType.SSO -> buildLoginSSOForm()
|
||||
LoginType.DIRECT,
|
||||
LoginType.CUSTOM,
|
||||
LoginType.QR,
|
||||
LoginType.UNSUPPORTED -> buildLoginUnsupportedForm()
|
||||
LoginType.UNKNOWN -> Unit
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue