Login: check login flow - step 1
This commit is contained in:
parent
a47a3ead1f
commit
db8ea0f5e8
@ -21,12 +21,18 @@ import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
|
|||||||
import im.vector.matrix.android.api.auth.data.SessionParams
|
import im.vector.matrix.android.api.auth.data.SessionParams
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.api.util.Cancelable
|
import im.vector.matrix.android.api.util.Cancelable
|
||||||
|
import im.vector.matrix.android.internal.auth.data.LoginFlowResponse
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface defines methods to authenticate to a matrix server.
|
* This interface defines methods to authenticate to a matrix server.
|
||||||
*/
|
*/
|
||||||
interface Authenticator {
|
interface Authenticator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request the supported login flows for this homeserver
|
||||||
|
*/
|
||||||
|
fun getLoginFlow(homeServerConnectionConfig: HomeServerConnectionConfig, callback: MatrixCallback<LoginFlowResponse>): Cancelable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param homeServerConnectionConfig this param is used to configure the Homeserver
|
* @param homeServerConnectionConfig this param is used to configure the Homeserver
|
||||||
* @param login the login field
|
* @param login the login field
|
||||||
|
@ -17,10 +17,12 @@
|
|||||||
package im.vector.matrix.android.internal.auth
|
package im.vector.matrix.android.internal.auth
|
||||||
|
|
||||||
import im.vector.matrix.android.api.auth.data.Credentials
|
import im.vector.matrix.android.api.auth.data.Credentials
|
||||||
|
import im.vector.matrix.android.internal.auth.data.LoginFlowResponse
|
||||||
import im.vector.matrix.android.internal.auth.data.PasswordLoginParams
|
import im.vector.matrix.android.internal.auth.data.PasswordLoginParams
|
||||||
import im.vector.matrix.android.internal.network.NetworkConstants
|
import im.vector.matrix.android.internal.network.NetworkConstants
|
||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.http.Body
|
import retrofit2.http.Body
|
||||||
|
import retrofit2.http.GET
|
||||||
import retrofit2.http.Headers
|
import retrofit2.http.Headers
|
||||||
import retrofit2.http.POST
|
import retrofit2.http.POST
|
||||||
|
|
||||||
@ -29,6 +31,13 @@ import retrofit2.http.POST
|
|||||||
*/
|
*/
|
||||||
internal interface AuthAPI {
|
internal interface AuthAPI {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the supported login flow
|
||||||
|
* Ref: https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-login
|
||||||
|
*/
|
||||||
|
@GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "login")
|
||||||
|
fun getLoginFlows(): Call<LoginFlowResponse>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pass params to the server for the current login phase.
|
* Pass params to the server for the current login phase.
|
||||||
* Set all the timeouts to 1 minute
|
* Set all the timeouts to 1 minute
|
||||||
|
@ -25,6 +25,7 @@ import im.vector.matrix.android.api.auth.data.SessionParams
|
|||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.api.util.Cancelable
|
import im.vector.matrix.android.api.util.Cancelable
|
||||||
import im.vector.matrix.android.internal.SessionManager
|
import im.vector.matrix.android.internal.SessionManager
|
||||||
|
import im.vector.matrix.android.internal.auth.data.LoginFlowResponse
|
||||||
import im.vector.matrix.android.internal.auth.data.PasswordLoginParams
|
import im.vector.matrix.android.internal.auth.data.PasswordLoginParams
|
||||||
import im.vector.matrix.android.internal.auth.data.ThreePidMedium
|
import im.vector.matrix.android.internal.auth.data.ThreePidMedium
|
||||||
import im.vector.matrix.android.internal.di.Unauthenticated
|
import im.vector.matrix.android.internal.di.Unauthenticated
|
||||||
@ -62,11 +63,20 @@ internal class DefaultAuthenticator @Inject constructor(@Unauthenticated
|
|||||||
return sessionManager.getOrCreateSession(sessionParams)
|
return sessionManager.getOrCreateSession(sessionParams)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getLoginFlow(homeServerConnectionConfig: HomeServerConnectionConfig, callback: MatrixCallback<LoginFlowResponse>): Cancelable {
|
||||||
|
val job = GlobalScope.launch(coroutineDispatchers.main) {
|
||||||
|
val result = runCatching {
|
||||||
|
getLoginFlowInternal(homeServerConnectionConfig)
|
||||||
|
}
|
||||||
|
result.foldToCallback(callback)
|
||||||
|
}
|
||||||
|
return CancelableCoroutine(job)
|
||||||
|
}
|
||||||
|
|
||||||
override fun authenticate(homeServerConnectionConfig: HomeServerConnectionConfig,
|
override fun authenticate(homeServerConnectionConfig: HomeServerConnectionConfig,
|
||||||
login: String,
|
login: String,
|
||||||
password: String,
|
password: String,
|
||||||
callback: MatrixCallback<Session>): Cancelable {
|
callback: MatrixCallback<Session>): Cancelable {
|
||||||
|
|
||||||
val job = GlobalScope.launch(coroutineDispatchers.main) {
|
val job = GlobalScope.launch(coroutineDispatchers.main) {
|
||||||
val sessionOrFailure = runCatching {
|
val sessionOrFailure = runCatching {
|
||||||
authenticate(homeServerConnectionConfig, login, password)
|
authenticate(homeServerConnectionConfig, login, password)
|
||||||
@ -74,7 +84,14 @@ internal class DefaultAuthenticator @Inject constructor(@Unauthenticated
|
|||||||
sessionOrFailure.foldToCallback(callback)
|
sessionOrFailure.foldToCallback(callback)
|
||||||
}
|
}
|
||||||
return CancelableCoroutine(job)
|
return CancelableCoroutine(job)
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun getLoginFlowInternal(homeServerConnectionConfig: HomeServerConnectionConfig) = withContext(coroutineDispatchers.io) {
|
||||||
|
val authAPI = buildAuthAPI(homeServerConnectionConfig)
|
||||||
|
|
||||||
|
executeRequest<LoginFlowResponse> {
|
||||||
|
apiCall = authAPI.getLoginFlows()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun authenticate(homeServerConnectionConfig: HomeServerConnectionConfig,
|
private suspend fun authenticate(homeServerConnectionConfig: HomeServerConnectionConfig,
|
||||||
|
@ -20,7 +20,7 @@ import com.squareup.moshi.Json
|
|||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
internal data class LoginFlowResponse(
|
data class LoginFlowResponse(
|
||||||
@Json(name = "flows")
|
@Json(name = "flows")
|
||||||
val flows: List<InteractiveAuthenticationFlow>
|
val flows: List<InteractiveAuthenticationFlow>
|
||||||
)
|
)
|
@ -35,7 +35,7 @@ internal object NetworkModule {
|
|||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun providesHttpLogingInterceptor(): HttpLoggingInterceptor {
|
fun providesHttpLoggingInterceptor(): HttpLoggingInterceptor {
|
||||||
val logger = FormattedJsonHttpLogger()
|
val logger = FormattedJsonHttpLogger()
|
||||||
val interceptor = HttpLoggingInterceptor(logger)
|
val interceptor = HttpLoggingInterceptor(logger)
|
||||||
interceptor.level = BuildConfig.OKHTTP_LOGGING_LEVEL
|
interceptor.level = BuildConfig.OKHTTP_LOGGING_LEVEL
|
||||||
|
@ -128,6 +128,28 @@ class LoginFragment : VectorBaseFragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun invalidate() = withState(viewModel) { state ->
|
override fun invalidate() = withState(viewModel) { state ->
|
||||||
|
when (state.asyncHomeServerLoginFlowRequest) {
|
||||||
|
is Loading -> {
|
||||||
|
progressBar.isVisible = true
|
||||||
|
touchArea.isVisible = true
|
||||||
|
|
||||||
|
passwordShown = false
|
||||||
|
renderPasswordField()
|
||||||
|
}
|
||||||
|
is Fail -> {
|
||||||
|
progressBar.isVisible = false
|
||||||
|
touchArea.isVisible = false
|
||||||
|
Toast.makeText(requireActivity(), "Authenticate failure: ${state.asyncHomeServerLoginFlowRequest.error}", Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
is Success -> {
|
||||||
|
progressBar.isVisible = false
|
||||||
|
touchArea.isVisible = false
|
||||||
|
|
||||||
|
// Check login flow
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
when (state.asyncLoginAction) {
|
when (state.asyncLoginAction) {
|
||||||
is Loading -> {
|
is Loading -> {
|
||||||
progressBar.isVisible = true
|
progressBar.isVisible = true
|
||||||
|
@ -25,6 +25,7 @@ import im.vector.matrix.android.api.auth.Authenticator
|
|||||||
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
|
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.api.util.Cancelable
|
import im.vector.matrix.android.api.util.Cancelable
|
||||||
|
import im.vector.matrix.android.internal.auth.data.LoginFlowResponse
|
||||||
import im.vector.riotx.core.di.ActiveSessionHolder
|
import im.vector.riotx.core.di.ActiveSessionHolder
|
||||||
import im.vector.riotx.core.extensions.configureAndStart
|
import im.vector.riotx.core.extensions.configureAndStart
|
||||||
import im.vector.riotx.core.platform.VectorViewModel
|
import im.vector.riotx.core.platform.VectorViewModel
|
||||||
@ -104,6 +105,8 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleUpdateHomeserver(action: LoginActions.UpdateHomeServer) {
|
private fun handleUpdateHomeserver(action: LoginActions.UpdateHomeServer) {
|
||||||
|
currentTask?.cancel()
|
||||||
|
|
||||||
Try {
|
Try {
|
||||||
val homeServerUri = action.homeServerUrl
|
val homeServerUri = action.homeServerUrl
|
||||||
homeServerConnectionConfig = HomeServerConnectionConfig.Builder()
|
homeServerConnectionConfig = HomeServerConnectionConfig.Builder()
|
||||||
@ -111,11 +114,16 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi
|
|||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val homeServerConnectionConfigFinal = homeServerConnectionConfig
|
||||||
|
|
||||||
// TODO Do request
|
if (homeServerConnectionConfigFinal == null) {
|
||||||
|
// This is invalid
|
||||||
/*
|
setState {
|
||||||
currentTask?.cancel()
|
copy(
|
||||||
|
asyncHomeServerLoginFlowRequest = Fail(Throwable("Baf format"))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
@ -124,9 +132,31 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO currentTask =
|
currentTask = authenticator.getLoginFlow(homeServerConnectionConfigFinal, object : MatrixCallback<LoginFlowResponse> {
|
||||||
|
override fun onFailure(failure: Throwable) {
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
asyncHomeServerLoginFlowRequest = Fail(failure)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSuccess(data: LoginFlowResponse) {
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
asyncHomeServerLoginFlowRequest = Success(data)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleLoginFlowResponse(data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleLoginFlowResponse(loginFlowResponse: LoginFlowResponse) {
|
||||||
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,12 +19,9 @@ package im.vector.riotx.features.login
|
|||||||
import com.airbnb.mvrx.Async
|
import com.airbnb.mvrx.Async
|
||||||
import com.airbnb.mvrx.MvRxState
|
import com.airbnb.mvrx.MvRxState
|
||||||
import com.airbnb.mvrx.Uninitialized
|
import com.airbnb.mvrx.Uninitialized
|
||||||
|
import im.vector.matrix.android.internal.auth.data.LoginFlowResponse
|
||||||
|
|
||||||
data class LoginViewState(
|
data class LoginViewState(
|
||||||
val asyncLoginAction: Async<Unit> = Uninitialized,
|
val asyncLoginAction: Async<Unit> = Uninitialized,
|
||||||
val asyncHomeServerLoginFlowRequest: Async<LoginFlowResult> = Uninitialized
|
val asyncHomeServerLoginFlowRequest: Async<LoginFlowResponse> = Uninitialized
|
||||||
) : MvRxState
|
) : MvRxState
|
||||||
|
|
||||||
|
|
||||||
// TODO Remove
|
|
||||||
data class LoginFlowResult(val remover: Boolean)
|
|
Loading…
x
Reference in New Issue
Block a user