Skip to content

Commit 4cc2daa

Browse files
authored
Merge pull request #7920 from vector-im/hughns/msc3824-oidc-aware
Implementation of MSC3824 to make the client OIDC-aware
2 parents f4367a0 + b1d7831 commit 4cc2daa

40 files changed

+303
-64
lines changed

changelog.d/6367.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Adds MSC3824 OIDC-awareness when talking to an OIDC-enabled homeservers

library/ui-strings/src/main/res/values/strings.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,6 +1063,9 @@
10631063
<string name="settings_discovery_category">Discovery</string>
10641064
<string name="settings_discovery_manage">Manage your discovery settings.</string>
10651065

1066+
<string name="settings_external_account_management_title">Account</string>
1067+
<string name="settings_external_account_management">Your account details are managed separately at %1$s.</string>
1068+
10661069
<!-- analytics -->
10671070
<string name="settings_analytics">Analytics</string>
10681071
<string name="settings_opt_in_of_analytics">Send analytics data</string>

matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ interface AuthenticationService {
4444
/**
4545
* Get a SSO url.
4646
*/
47-
fun getSsoUrl(redirectUrl: String, deviceId: String?, providerId: String?): String?
47+
fun getSsoUrl(redirectUrl: String, deviceId: String?, providerId: String?, action: SSOAction): String?
4848

4949
/**
5050
* Get the sign in or sign up fallback URL.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright 2022 The Matrix.org Foundation C.I.C.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.matrix.android.sdk.api.auth
18+
19+
/**
20+
* See https://github.com/matrix-org/matrix-spec-proposals/pull/3824
21+
*/
22+
enum class SSOAction {
23+
LOGIN,
24+
REGISTER;
25+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2023 The Matrix.org Foundation C.I.C.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.matrix.android.sdk.api.auth.data
18+
19+
import com.squareup.moshi.Json
20+
import com.squareup.moshi.JsonClass
21+
22+
/**
23+
* https://github.com/matrix-org/matrix-spec-proposals/pull/2965
24+
* <pre>
25+
* {
26+
* "issuer": "https://id.server.org",
27+
* "account": "https://id.server.org/my-account",
28+
* }
29+
* </pre>
30+
* .
31+
*/
32+
33+
@JsonClass(generateAdapter = true)
34+
data class DelegatedAuthConfig(
35+
@Json(name = "issuer")
36+
val issuer: String,
37+
38+
@Json(name = "account")
39+
val accountManagementUrl: String,
40+
)

matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/LoginFlowResult.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ data class LoginFlowResult(
2222
val isLoginAndRegistrationSupported: Boolean,
2323
val homeServerUrl: String,
2424
val isOutdatedHomeserver: Boolean,
25+
val hasOidcCompatibilityFlow: Boolean,
2526
val isLogoutDevicesSupported: Boolean,
2627
val isLoginWithQrSupported: Boolean,
2728
)

matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/WellKnown.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,11 @@ data class WellKnown(
5454
val identityServer: WellKnownBaseConfig? = null,
5555

5656
@Json(name = "m.integrations")
57-
val integrations: JsonDict? = null
57+
val integrations: JsonDict? = null,
58+
59+
/**
60+
* For delegation of auth via OIDC as per [MSC2965](https://github.com/matrix-org/matrix-spec-proposals/pull/2965).
61+
*/
62+
@Json(name = "org.matrix.msc2965.authentication")
63+
val unstableDelegatedAuthConfig: DelegatedAuthConfig? = null,
5864
)

matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ data class HomeServerCapabilities(
8080
* True if the home server supports event redaction with relations.
8181
*/
8282
var canRedactEventWithRelations: Boolean = false,
83+
84+
/**
85+
* External account management url for use with MSC3824 delegated OIDC, provided in Wellknown.
86+
*/
87+
val externalAccountManagementUrl: String? = null,
8388
) {
8489

8590
enum class RoomCapabilitySupport {

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import org.matrix.android.sdk.api.MatrixPatterns
2323
import org.matrix.android.sdk.api.MatrixPatterns.getServerName
2424
import org.matrix.android.sdk.api.auth.AuthenticationService
2525
import org.matrix.android.sdk.api.auth.LoginType
26+
import org.matrix.android.sdk.api.auth.SSOAction
2627
import org.matrix.android.sdk.api.auth.data.Credentials
2728
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
2829
import org.matrix.android.sdk.api.auth.data.LoginFlowResult
@@ -88,7 +89,7 @@ internal class DefaultAuthenticationService @Inject constructor(
8889
return getLoginFlow(homeServerConnectionConfig)
8990
}
9091

91-
override fun getSsoUrl(redirectUrl: String, deviceId: String?, providerId: String?): String? {
92+
override fun getSsoUrl(redirectUrl: String, deviceId: String?, providerId: String?, action: SSOAction): String? {
9293
val homeServerUrlBase = getHomeServerUrlBase() ?: return null
9394

9495
return buildString {
@@ -103,6 +104,9 @@ internal class DefaultAuthenticationService @Inject constructor(
103104
// But https://github.com/matrix-org/synapse/issues/5755
104105
appendParamToUrl("device_id", it)
105106
}
107+
108+
// unstable MSC3824 action param
109+
appendParamToUrl("org.matrix.msc3824.action", action.toString())
106110
}
107111
}
108112

@@ -292,12 +296,18 @@ internal class DefaultAuthenticationService @Inject constructor(
292296
val loginFlowResponse = executeRequest(null) {
293297
authAPI.getLoginFlows()
294298
}
299+
300+
// If an m.login.sso flow is present that is flagged as being for MSC3824 OIDC compatibility then we only return that flow
301+
val oidcCompatibilityFlow = loginFlowResponse.flows.orEmpty().firstOrNull { it.type == "m.login.sso" && it.delegatedOidcCompatibilty == true }
302+
val flows = if (oidcCompatibilityFlow != null) listOf(oidcCompatibilityFlow) else loginFlowResponse.flows
303+
295304
return LoginFlowResult(
296-
supportedLoginTypes = loginFlowResponse.flows.orEmpty().mapNotNull { it.type },
297-
ssoIdentityProviders = loginFlowResponse.flows.orEmpty().firstOrNull { it.type == LoginFlowTypes.SSO }?.ssoIdentityProvider,
305+
supportedLoginTypes = flows.orEmpty().mapNotNull { it.type },
306+
ssoIdentityProviders = flows.orEmpty().firstOrNull { it.type == LoginFlowTypes.SSO }?.ssoIdentityProvider,
298307
isLoginAndRegistrationSupported = versions.isLoginAndRegistrationSupportedBySdk(),
299308
homeServerUrl = homeServerUrl,
300309
isOutdatedHomeserver = !versions.isSupportedBySdk(),
310+
hasOidcCompatibilityFlow = oidcCompatibilityFlow != null,
301311
isLogoutDevicesSupported = versions.doesServerSupportLogoutDevices(),
302312
isLoginWithQrSupported = versions.doesServerSupportQrCodeLogin(),
303313
)

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/LoginFlowResponse.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ internal data class LoginFlow(
4343
* See MSC #2858
4444
*/
4545
@Json(name = "identity_providers")
46-
val ssoIdentityProvider: List<SsoIdentityProvider>? = null
46+
val ssoIdentityProvider: List<SsoIdentityProvider>? = null,
4747

48+
/**
49+
* Whether this login flow is preferred for OIDC-aware clients.
50+
*
51+
* See [MSC3824](https://github.com/matrix-org/matrix-spec-proposals/pull/3824)
52+
*/
53+
@Json(name = "org.matrix.msc3824.delegated_oidc_compatibility")
54+
val delegatedOidcCompatibilty: Boolean? = null
4855
)

0 commit comments

Comments
 (0)