Jitsi auth: clean after Benoits review

This commit is contained in:
ganfra 2021-05-20 20:16:37 +02:00
parent 2ca0397867
commit 03f81258c4
21 changed files with 106 additions and 113 deletions

View file

@ -39,6 +39,7 @@ import org.matrix.android.sdk.api.session.identity.IdentityService
import org.matrix.android.sdk.api.session.initsync.InitialSyncProgressService
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService
import org.matrix.android.sdk.api.session.media.MediaService
import org.matrix.android.sdk.api.session.openid.OpenIdService
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
import org.matrix.android.sdk.api.session.profile.ProfileService
import org.matrix.android.sdk.api.session.pushers.PushersService
@ -233,6 +234,11 @@ interface Session :
*/
fun spaceService(): SpaceService
/**
* Returns the open id service associated with the session
*/
fun openIdService(): OpenIdService
/**
* Add a listener to the session.
* @param listener the listener to add.

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2021 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.api.session.openid
interface OpenIdService {
/**
* Gets an OpenID token object that the requester may supply to another service to verify their identity in Matrix.
* The generated token is only valid for exchanging for user information from the federation API for OpenID.
*/
suspend fun getOpenIdToken(): OpenIdToken
}

View file

@ -14,32 +14,35 @@
* limitations under the License.
*/
package org.matrix.android.sdk.api.session.room.model.thirdparty
package org.matrix.android.sdk.api.session.openid
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
/**
* This class holds the response for openId request_token API
* See https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-user-userid-openid-request-token
*/
@JsonClass(generateAdapter = true)
data class OpenIdToken(
/**
* Required. An access token the consumer may use to verify the identity of the person who generated the token.
* This is given to the federation API GET /openid/userinfo to verify the user's identity.
*/
@Json(name = "access_token") val accessToken: String,
@Json(name = "access_token")
val accessToken: String,
/**
* Required. The string Bearer.
* Required. The string "Bearer".
*/
@Json(name = "token_type") val tokenType: String,
@Json(name = "token_type")
val tokenType: String,
/**
* Required. The homeserver domain the consumer should use when attempting to verify the user's identity.
*/
@Json(name = "matrix_server_name") val matrix_server_name: String,
@Json(name = "matrix_server_name")
val matrixServerName: String,
/**
* Required. The number of seconds before this token expires and a new one must be generated.
*/
@Json(name = "expires_in") val expires_in: Int
@Json(name = "expires_in")
val expiresIn: Int
)

View file

@ -16,7 +16,6 @@
package org.matrix.android.sdk.api.session.thirdparty
import org.matrix.android.sdk.api.session.room.model.thirdparty.OpenIdToken
import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
import org.matrix.android.sdk.api.session.thirdparty.model.ThirdPartyUser
@ -37,10 +36,4 @@ interface ThirdPartyService {
* @param fields One or more custom fields that are passed to the AS to help identify the user.
*/
suspend fun getThirdPartyUser(protocol: String, fields: Map<String, String> = emptyMap()): List<ThirdPartyUser>
/**
* Gets an OpenID token object that the requester may supply to another service to verify their identity in Matrix.
* The generated token is only valid for exchanging for user information from the federation API for OpenID.
*/
suspend fun getOpenIdToken(): OpenIdToken
}

View file

@ -43,6 +43,7 @@ import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesServi
import org.matrix.android.sdk.api.session.initsync.InitialSyncProgressService
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService
import org.matrix.android.sdk.api.session.media.MediaService
import org.matrix.android.sdk.api.session.openid.OpenIdService
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
import org.matrix.android.sdk.api.session.profile.ProfileService
import org.matrix.android.sdk.api.session.pushers.PushersService
@ -125,6 +126,7 @@ internal class DefaultSession @Inject constructor(
private val thirdPartyService: Lazy<ThirdPartyService>,
private val callSignalingService: Lazy<CallSignalingService>,
private val spaceService: Lazy<SpaceService>,
private val openIdService: Lazy<OpenIdService>,
@UnauthenticatedWithCertificate
private val unauthenticatedWithCertificateOkHttpClient: Lazy<OkHttpClient>
) : Session,
@ -289,6 +291,8 @@ internal class DefaultSession @Inject constructor(
override fun spaceService(): SpaceService = spaceService.get()
override fun openIdService(): OpenIdService = openIdService.get()
override fun getOkHttpClient(): OkHttpClient {
return unauthenticatedWithCertificateOkHttpClient.get()
}

View file

@ -38,6 +38,7 @@ import org.matrix.android.sdk.api.session.accountdata.AccountDataService
import org.matrix.android.sdk.api.session.events.EventService
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
import org.matrix.android.sdk.api.session.initsync.InitialSyncProgressService
import org.matrix.android.sdk.api.session.openid.OpenIdService
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
import org.matrix.android.sdk.api.session.securestorage.SecureStorageService
import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService
@ -82,6 +83,7 @@ import org.matrix.android.sdk.internal.session.homeserver.DefaultHomeServerCapab
import org.matrix.android.sdk.internal.session.identity.DefaultIdentityService
import org.matrix.android.sdk.internal.session.initsync.DefaultInitialSyncProgressService
import org.matrix.android.sdk.internal.session.integrationmanager.IntegrationManager
import org.matrix.android.sdk.internal.session.openid.DefaultOpenIdService
import org.matrix.android.sdk.internal.session.permalinks.DefaultPermalinkService
import org.matrix.android.sdk.internal.session.room.EventRelationsAggregationProcessor
import org.matrix.android.sdk.internal.session.room.create.RoomCreateEventProcessor
@ -373,6 +375,9 @@ internal abstract class SessionModule {
@Binds
abstract fun bindPermalinkService(service: DefaultPermalinkService): PermalinkService
@Binds
abstract fun bindOpenIdTokenService(service: DefaultOpenIdService): OpenIdService
@Binds
abstract fun bindTypingUsersTracker(tracker: DefaultTypingUsersTracker): TypingUsersTracker

View file

@ -16,9 +16,9 @@
package org.matrix.android.sdk.internal.session.identity
import org.matrix.android.sdk.api.session.openid.OpenIdToken
import org.matrix.android.sdk.internal.network.NetworkConstants
import org.matrix.android.sdk.internal.session.identity.model.IdentityRegisterResponse
import org.matrix.android.sdk.internal.session.openid.RequestOpenIdTokenResponse
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
@ -52,5 +52,5 @@ internal interface IdentityAuthAPI {
* The request body is the same as the values returned by /openid/request_token in the Client-Server API.
*/
@POST(NetworkConstants.URI_IDENTITY_PATH_V2 + "account/register")
suspend fun register(@Body openIdToken: RequestOpenIdTokenResponse): IdentityRegisterResponse
suspend fun register(@Body openIdToken: OpenIdToken): IdentityRegisterResponse
}

View file

@ -16,16 +16,16 @@
package org.matrix.android.sdk.internal.session.identity
import org.matrix.android.sdk.api.session.openid.OpenIdToken
import org.matrix.android.sdk.internal.network.executeRequest
import org.matrix.android.sdk.internal.session.identity.model.IdentityRegisterResponse
import org.matrix.android.sdk.internal.session.openid.RequestOpenIdTokenResponse
import org.matrix.android.sdk.internal.task.Task
import javax.inject.Inject
internal interface IdentityRegisterTask : Task<IdentityRegisterTask.Params, IdentityRegisterResponse> {
data class Params(
val identityAuthAPI: IdentityAuthAPI,
val openIdTokenResponse: RequestOpenIdTokenResponse
val openIdToken: OpenIdToken
)
}
@ -33,7 +33,7 @@ internal class DefaultIdentityRegisterTask @Inject constructor() : IdentityRegis
override suspend fun execute(params: IdentityRegisterTask.Params): IdentityRegisterResponse {
return executeRequest(null) {
params.identityAuthAPI.register(params.openIdTokenResponse)
params.identityAuthAPI.register(params.openIdToken)
}
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2021 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.session.openid
import org.matrix.android.sdk.api.session.openid.OpenIdService
import org.matrix.android.sdk.api.session.openid.OpenIdToken
import javax.inject.Inject
internal class DefaultOpenIdService @Inject constructor(private val getOpenIdTokenTask: GetOpenIdTokenTask): OpenIdService {
override suspend fun getOpenIdToken(): OpenIdToken {
return getOpenIdTokenTask.execute(Unit)
}
}

View file

@ -16,20 +16,21 @@
package org.matrix.android.sdk.internal.session.openid
import org.matrix.android.sdk.api.session.openid.OpenIdToken
import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
import org.matrix.android.sdk.internal.network.executeRequest
import org.matrix.android.sdk.internal.task.Task
import javax.inject.Inject
internal interface GetOpenIdTokenTask : Task<Unit, RequestOpenIdTokenResponse>
internal interface GetOpenIdTokenTask : Task<Unit, OpenIdToken>
internal class DefaultGetOpenIdTokenTask @Inject constructor(
@UserId private val userId: String,
private val openIdAPI: OpenIdAPI,
private val globalErrorReceiver: GlobalErrorReceiver) : GetOpenIdTokenTask {
override suspend fun execute(params: Unit): RequestOpenIdTokenResponse {
override suspend fun execute(params: Unit): OpenIdToken {
return executeRequest(globalErrorReceiver) {
openIdAPI.openIdToken(userId)
}

View file

@ -16,6 +16,7 @@
package org.matrix.android.sdk.internal.session.openid
import org.matrix.android.sdk.api.session.openid.OpenIdToken
import org.matrix.android.sdk.api.util.JsonDict
import org.matrix.android.sdk.internal.network.NetworkConstants
import retrofit2.http.Body
@ -34,5 +35,5 @@ internal interface OpenIdAPI {
*/
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "user/{userId}/openid/request_token")
suspend fun openIdToken(@Path("userId") userId: String,
@Body body: JsonDict = emptyMap()): RequestOpenIdTokenResponse
@Body body: JsonDict = emptyMap()): OpenIdToken
}

View file

@ -16,15 +16,13 @@
package org.matrix.android.sdk.internal.session.thirdparty
import org.matrix.android.sdk.api.session.room.model.thirdparty.OpenIdToken
import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
import org.matrix.android.sdk.api.session.thirdparty.ThirdPartyService
import org.matrix.android.sdk.api.session.thirdparty.model.ThirdPartyUser
import javax.inject.Inject
internal class DefaultThirdPartyService @Inject constructor(private val getThirdPartyProtocolTask: GetThirdPartyProtocolsTask,
private val getThirdPartyUserTask: GetThirdPartyUserTask,
private val getOpenIdTokenTask: GetOpenIdTokenTask)
private val getThirdPartyUserTask: GetThirdPartyUserTask)
: ThirdPartyService {
override suspend fun getThirdPartyProtocols(): Map<String, ThirdPartyProtocol> {
@ -38,8 +36,4 @@ internal class DefaultThirdPartyService @Inject constructor(private val getThird
)
return getThirdPartyUserTask.execute(taskParams)
}
override suspend fun getOpenIdToken(): OpenIdToken {
return getOpenIdTokenTask.execute(Unit)
}
}

View file

@ -1,39 +0,0 @@
/*
* Copyright 2020 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.session.thirdparty
import org.matrix.android.sdk.api.session.room.model.thirdparty.OpenIdToken
import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
import org.matrix.android.sdk.internal.network.executeRequest
import org.matrix.android.sdk.internal.task.Task
import javax.inject.Inject
internal interface GetOpenIdTokenTask : Task<Unit, OpenIdToken>
internal class DefaultGetOpenIdTokenTask @Inject constructor(
private val thirdPartyAPI: ThirdPartyAPI,
private val globalErrorReceiver: GlobalErrorReceiver,
@UserId private val userId: String
) : GetOpenIdTokenTask {
override suspend fun execute(params: Unit): OpenIdToken {
return executeRequest(globalErrorReceiver) {
thirdPartyAPI.requestOpenIdToken(userId)
}
}
}

View file

@ -16,14 +16,10 @@
package org.matrix.android.sdk.internal.session.thirdparty
import org.matrix.android.sdk.api.session.room.model.thirdparty.OpenIdToken
import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
import org.matrix.android.sdk.api.session.thirdparty.model.ThirdPartyUser
import org.matrix.android.sdk.api.util.JsonDict
import org.matrix.android.sdk.internal.network.NetworkConstants
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Path
import retrofit2.http.QueryMap
@ -45,16 +41,4 @@ internal interface ThirdPartyAPI {
@GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "thirdparty/protocols/user/{protocol}")
suspend fun getThirdPartyUser(@Path("protocol") protocol: String,
@QueryMap params: Map<String, String>?): List<ThirdPartyUser>
/**
* Gets an OpenID token object that the requester may supply to another service to verify their identity in Matrix.
* The generated token is only valid for exchanging for user information from the federation API for OpenID.
* The access token generated is only valid for the OpenID API. It cannot be used to request another OpenID access token or call /sync, for example.
*
* Ref: https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-user-userid-openid-request-token
*/
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "user/{userId}/openid/request_token")
suspend fun requestOpenIdToken(@Path("userId") userId: String,
// We should post an empty body
@Body body: JsonDict = HashMap()): OpenIdToken
}

View file

@ -44,7 +44,4 @@ internal abstract class ThirdPartyModule {
@Binds
abstract fun bindGetThirdPartyUserTask(task: DefaultGetThirdPartyUserTask): GetThirdPartyUserTask
@Binds
abstract fun bindGetOpenIdTokenTask(task: DefaultGetOpenIdTokenTask): GetOpenIdTokenTask
}

View file

@ -15,7 +15,7 @@
*/
package org.matrix.android.sdk.internal.session.widgets
import org.matrix.android.sdk.internal.session.openid.RequestOpenIdTokenResponse
import org.matrix.android.sdk.api.session.openid.OpenIdToken
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
@ -29,7 +29,7 @@ internal interface WidgetsAPI {
* @param body the body content (Ref: https://github.com/matrix-org/matrix-doc/pull/1961)
*/
@POST("register")
suspend fun register(@Body body: RequestOpenIdTokenResponse,
suspend fun register(@Body body: OpenIdToken,
@Query("v") version: String?): RegisterWidgetResponse
@GET("account")

View file

@ -22,6 +22,6 @@ fun String.toBase32String(padding: Boolean = true): String {
return if (padding) {
base32
} else {
base32.replace("=", "")
base32.trimEnd('=')
}
}

View file

@ -30,7 +30,7 @@ fun String.isValidUrl(): Boolean {
/**
* Ensure string starts with "http". If it is not the case, "https://" is added, only if the String is not empty
*/
internal fun String.ensureProtocol(): String {
fun String.ensureProtocol(): String {
return when {
isEmpty() -> this
!startsWith("http") -> "https://$this"
@ -38,14 +38,7 @@ internal fun String.ensureProtocol(): String {
}
}
/**
* Ensure string do not starts with "http" or "https" protocol.
*/
internal fun String.ensureNoProtocol(): String {
return removePrefix("https://").removePrefix("http://")
}
internal fun String.ensureTrailingSlash(): String {
fun String.ensureTrailingSlash(): String {
return when {
isEmpty() -> this
!endsWith("/") -> "$this/"

View file

@ -19,7 +19,6 @@ package im.vector.app.features.call.conference
import im.vector.app.R
import im.vector.app.core.network.await
import im.vector.app.core.resources.StringProvider
import im.vector.app.core.utils.ensureNoProtocol
import im.vector.app.core.utils.ensureProtocol
import im.vector.app.core.utils.toBase32String
import im.vector.app.features.call.conference.jwt.JitsiJWTFactory
@ -60,9 +59,8 @@ class JitsiService @Inject constructor(
rawService.getElementWellknown(session.myUserId)
?.jitsiServer
?.preferredDomain
?.ensureNoProtocol()
}
val jitsiDomain = (preferredJitsiDomain ?: stringProvider.getString(R.string.preferred_jitsi_domain))
val jitsiDomain = preferredJitsiDomain ?: stringProvider.getString(R.string.preferred_jitsi_domain)
val jitsiAuth = getJitsiAuth(jitsiDomain)
val confId = createConferenceId(roomId, jitsiAuth)
@ -133,11 +131,10 @@ class JitsiService @Inject constructor(
}
private suspend fun getOpenIdJWTToken(roomId: String, domain: String, userDisplayName: String, userAvatar: String): String {
val openIdToken = session.thirdPartyService().getOpenIdToken()
val openIdToken = session.openIdService().getOpenIdToken()
return jitsiJWTFactory.create(
homeServerName = session.sessionParams.homeServerUrl.ensureNoProtocol(),
openIdToken = openIdToken,
jitsiServerDomain = domain,
openIdAccessToken = openIdToken.accessToken,
roomId = roomId,
userAvatarUrl = userAvatar,
userDisplayName = userDisplayName

View file

@ -37,7 +37,7 @@ class JitsiWidgetPropertiesFactory @Inject constructor(
.orEmpty()
return JitsiWidgetProperties(
domain = (configs["conferenceDomain"] ?: stringProvider.getString(R.string.preferred_jitsi_domain)),
domain = configs["conferenceDomain"] ?: stringProvider.getString(R.string.preferred_jitsi_domain),
confId = configs["conferenceId"],
displayName = configs["displayName"],
avatarUrl = configs["avatarUrl"]

View file

@ -20,6 +20,7 @@ import im.vector.app.core.utils.ensureProtocol
import io.jsonwebtoken.Jwts
import io.jsonwebtoken.SignatureAlgorithm
import io.jsonwebtoken.security.Keys
import org.matrix.android.sdk.api.session.openid.OpenIdToken
import javax.inject.Inject
class JitsiJWTFactory @Inject constructor() {
@ -28,9 +29,8 @@ class JitsiJWTFactory @Inject constructor() {
* Create a JWT token for jitsi openidtoken-jwt authentication
* See https://github.com/matrix-org/prosody-mod-auth-matrix-user-verification
*/
fun create(homeServerName: String,
fun create(openIdToken: OpenIdToken,
jitsiServerDomain: String,
openIdAccessToken: String,
roomId: String,
userAvatarUrl: String,
userDisplayName: String): String {
@ -38,9 +38,9 @@ class JitsiJWTFactory @Inject constructor() {
val key = Keys.secretKeyFor(SignatureAlgorithm.HS256)
val context = mapOf(
"matrix" to mapOf(
"token" to openIdAccessToken,
"token" to openIdToken.accessToken,
"room_id" to roomId,
"server_name" to homeServerName
"server_name" to openIdToken.matrixServerName
),
"user" to mapOf(
"name" to userDisplayName,