Skip to content

Commit 9580d16

Browse files
hughnspixlwave
andauthored
Support for stable version of MSC3824 OAuth 2.0 aware (#1917)
* Support for stable `oauth_aware_preferred` from MSC3824 * Support for stable OAuth 2.0 API discovery with fallback to unstable MSC2965 .well-known Uses the /_matrix/client/v1/auth_metadata endpoint if available. Uses discovery to choose the MSC4191 action parameter. * Add missing return * Workspace * Feedback from PR review * Typo * Restore the well-known's authentication object serialisation. --------- Co-authored-by: Doug <douglase@element.io>
1 parent b0f967c commit 9580d16

File tree

18 files changed

+396
-5
lines changed

18 files changed

+396
-5
lines changed

MatrixSDK.xcodeproj/project.pbxproj

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@
5959
18C26C54273C16C800805154 /* MXEventContentPollStart.h in Headers */ = {isa = PBXBuildFile; fileRef = 18C26C51273C16C700805154 /* MXEventContentPollStart.h */; settings = {ATTRIBUTES = (Public, ); }; };
6060
18C26C55273C16C800805154 /* MXEventContentPollStart.m in Sources */ = {isa = PBXBuildFile; fileRef = 18C26C52273C16C700805154 /* MXEventContentPollStart.m */; };
6161
18C26C56273C16C800805154 /* MXEventContentPollStart.m in Sources */ = {isa = PBXBuildFile; fileRef = 18C26C52273C16C700805154 /* MXEventContentPollStart.m */; };
62+
1E6C553B2EF071B4001C9EF5 /* MXAuthMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E6C55392EF071B4001C9EF5 /* MXAuthMetadata.h */; settings = {ATTRIBUTES = (Public, ); }; };
63+
1E6C553C2EF071B4001C9EF5 /* MXAuthMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E6C553A2EF071B4001C9EF5 /* MXAuthMetadata.m */; };
64+
1E6C553D2EF071B4001C9EF5 /* MXAuthMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E6C553A2EF071B4001C9EF5 /* MXAuthMetadata.m */; };
65+
1E6C553E2EF071B4001C9EF5 /* MXAuthMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E6C55392EF071B4001C9EF5 /* MXAuthMetadata.h */; settings = {ATTRIBUTES = (Public, ); }; };
66+
1E6C55402EF5C105001C9EF5 /* MXWellKnown_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E6C553F2EF5C0FA001C9EF5 /* MXWellKnown_Private.h */; };
67+
1E6C55412EF5C105001C9EF5 /* MXWellKnown_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E6C553F2EF5C0FA001C9EF5 /* MXWellKnown_Private.h */; };
6268
3209683126396385005D64ED /* AllTestsWithSanitizers.xctestplan in Resources */ = {isa = PBXBuildFile; fileRef = 3209682F26396385005D64ED /* AllTestsWithSanitizers.xctestplan */; };
6369
3209683226396385005D64ED /* AllTestsWithSanitizers.xctestplan in Resources */ = {isa = PBXBuildFile; fileRef = 3209682F26396385005D64ED /* AllTestsWithSanitizers.xctestplan */; };
6470
3209683326396385005D64ED /* UnitTestsWithSanitizers.xctestplan in Resources */ = {isa = PBXBuildFile; fileRef = 3209683026396385005D64ED /* UnitTestsWithSanitizers.xctestplan */; };
@@ -2024,6 +2030,9 @@
20242030
18C26C51273C16C700805154 /* MXEventContentPollStart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXEventContentPollStart.h; sourceTree = "<group>"; };
20252031
18C26C52273C16C700805154 /* MXEventContentPollStart.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXEventContentPollStart.m; sourceTree = "<group>"; };
20262032
1D18B4F281A93ADB785B4800 /* Pods-MatrixSDKTests-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MatrixSDKTests-iOS.release.xcconfig"; path = "Target Support Files/Pods-MatrixSDKTests-iOS/Pods-MatrixSDKTests-iOS.release.xcconfig"; sourceTree = "<group>"; };
2033+
1E6C55392EF071B4001C9EF5 /* MXAuthMetadata.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MXAuthMetadata.h; sourceTree = "<group>"; };
2034+
1E6C553A2EF071B4001C9EF5 /* MXAuthMetadata.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MXAuthMetadata.m; sourceTree = "<group>"; };
2035+
1E6C553F2EF5C0FA001C9EF5 /* MXWellKnown_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MXWellKnown_Private.h; sourceTree = "<group>"; };
20272036
2D8EE909E54EE5334E1FD271 /* Pods-MatrixSDKTests-macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MatrixSDKTests-macOS.release.xcconfig"; path = "Target Support Files/Pods-MatrixSDKTests-macOS/Pods-MatrixSDKTests-macOS.release.xcconfig"; sourceTree = "<group>"; };
20282037
3209682F26396385005D64ED /* AllTestsWithSanitizers.xctestplan */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AllTestsWithSanitizers.xctestplan; sourceTree = "<group>"; };
20292038
3209683026396385005D64ED /* UnitTestsWithSanitizers.xctestplan */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = UnitTestsWithSanitizers.xctestplan; sourceTree = "<group>"; };
@@ -3364,6 +3373,7 @@
33643373
323547D12226D3F500F15F94 /* AutoDiscovery */ = {
33653374
isa = PBXGroup;
33663375
children = (
3376+
1E6C553F2EF5C0FA001C9EF5 /* MXWellKnown_Private.h */,
33673377
323547D32226D3F500F15F94 /* MXWellKnown.h */,
33683378
323547D22226D3F500F15F94 /* MXWellKnown.m */,
33693379
323547D62226D5D600F15F94 /* MXWellKnownBaseConfig.h */,
@@ -3640,6 +3650,8 @@
36403650
3275FD9121A6B46600B9C13D /* Authentication */ = {
36413651
isa = PBXGroup;
36423652
children = (
3653+
1E6C55392EF071B4001C9EF5 /* MXAuthMetadata.h */,
3654+
1E6C553A2EF071B4001C9EF5 /* MXAuthMetadata.m */,
36433655
3275FD9321A6B46600B9C13D /* MXLoginTerms.h */,
36443656
3275FD9221A6B46600B9C13D /* MXLoginTerms.m */,
36453657
3275FD9A21A6B60B00B9C13D /* MXLoginPolicy.h */,
@@ -5615,6 +5627,7 @@
56155627
B14EECE52577F76100448735 /* MXLoginSSOFlow.h in Headers */,
56165628
EC8A53E025B1BCC6004E0802 /* MXThirdPartyProtocolInstance.h in Headers */,
56175629
91F0685D2767CA420079F8FA /* MXTaskProfileName.h in Headers */,
5630+
1E6C55402EF5C105001C9EF5 /* MXWellKnown_Private.h in Headers */,
56185631
B1798D0624091A0100308A8F /* MXBase64Tools.h in Headers */,
56195632
32133015228AF4EF0070BA9B /* MXRealmAggregationsStore.h in Headers */,
56205633
ED1AE92A2881AC7500D3432A /* MXWarnings.h in Headers */,
@@ -5719,6 +5732,7 @@
57195732
1838927E2702F553003F0C4F /* MXSendReplyEventDefaultStringLocalizer.h in Headers */,
57205733
F08B8D5C1E014711006171A8 /* NSData+MatrixSDK.h in Headers */,
57215734
C60165381E3AA57900B92CFA /* MXSDKOptions.h in Headers */,
5735+
1E6C553B2EF071B4001C9EF5 /* MXAuthMetadata.h in Headers */,
57225736
32CEEF4F23B0AB030039BA98 /* MXCrossSigning.h in Headers */,
57235737
EC6D007928E1F15400152144 /* MXDevice.h in Headers */,
57245738
EC619D9324DD834B00663A80 /* MXPushGatewayRestClient.h in Headers */,
@@ -6117,6 +6131,7 @@
61176131
EC60ED9B265CFE1700B39A4E /* MXRoomSyncState.h in Headers */,
61186132
B14EF30D2397E90400758AF0 /* MXEventRelations.h in Headers */,
61196133
32261B8B23C74A230018F1E2 /* MXDeviceTrustLevel.h in Headers */,
6134+
1E6C553E2EF071B4001C9EF5 /* MXAuthMetadata.h in Headers */,
61206135
324DD2B7246C21C700377005 /* MXSecretStorageKeyCreationInfo.h in Headers */,
61216136
B14EF3102397E90400758AF0 /* MXEmojiRepresentation.h in Headers */,
61226137
ED5C754928B3E80300D24E85 /* MXLogObjcWrapper.h in Headers */,
@@ -6176,6 +6191,7 @@
61766191
B14EF32F2397E90400758AF0 /* MXAccountData.h in Headers */,
61776192
EDE70DC928DA22F800099736 /* MXKeyBackupEngine.h in Headers */,
61786193
B135066C27EA1F5E00BD3276 /* MXEventAssetType.h in Headers */,
6194+
1E6C55412EF5C105001C9EF5 /* MXWellKnown_Private.h in Headers */,
61796195
B14EF3302397E90400758AF0 /* MXEnumConstants.h in Headers */,
61806196
ECBF658626DE3DF800AA3A99 /* MXFileRoomOutgoingMessagesStore.h in Headers */,
61816197
ECD289BA26FCD25600F268CF /* MXPushGatewayRestClient.h in Headers */,
@@ -6706,6 +6722,7 @@
67066722
32D2CC0623422462002BD8CA /* MX3PidAddManager.m in Sources */,
67076723
92634B831EF2E3C400DB9F60 /* MXCallKitConfiguration.m in Sources */,
67086724
3265CB391A14C43E00E24B2F /* MXRoomState.m in Sources */,
6725+
1E6C553C2EF071B4001C9EF5 /* MXAuthMetadata.m in Sources */,
67096726
EC619D9224DD834B00663A80 /* MXPushGatewayRestClient.m in Sources */,
67106727
EDD578EC2881C38C006739DD /* MXCrossSigningV2.swift in Sources */,
67116728
3281E8B819E42DFE00976E1A /* MXJSONModel.m in Sources */,
@@ -7334,6 +7351,7 @@
73347351
B14EF2102397E90400758AF0 /* MXReplyEventBodyParts.m in Sources */,
73357352
B14EF2112397E90400758AF0 /* MXIncomingRoomKeyRequestCancellation.m in Sources */,
73367353
B14EF2122397E90400758AF0 /* MXMemoryRoomStore.m in Sources */,
7354+
1E6C553D2EF071B4001C9EF5 /* MXAuthMetadata.m in Sources */,
73377355
B14EF2132397E90400758AF0 /* MXUIKitBackgroundTask.m in Sources */,
73387356
EC60EDFF265CFFD200B39A4E /* MXInvitedGroupSync.m in Sources */,
73397357
B14EF2142397E90400758AF0 /* MXPeekingRoomSummary.m in Sources */,

MatrixSDK/Background/MXBackgroundStore.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,10 @@ class MXBackgroundStore: NSObject, MXStore {
253253
func storeHomeserverCapabilities(_ homeserverCapabilities: MXCapabilities) {
254254
}
255255

256+
var authMetadata: MXAuthMetadata?
257+
func store(_ authMetadata: MXAuthMetadata) {
258+
}
259+
256260
var supportedMatrixVersions: MXMatrixVersions?
257261
func storeSupportedMatrixVersions(_ supportedMatrixVersions: MXMatrixVersions) {
258262
}

MatrixSDK/Data/Store/MXFileStore/MXFileStore.m

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,20 @@ - (void)storeHomeserverCapabilities:(MXCapabilities *)capabilities
493493
}
494494
}
495495

496+
- (MXAuthMetadata *)authMetadata
497+
{
498+
return metaData.authMetadata;
499+
}
500+
501+
- (void)storeAuthMetadata:(MXAuthMetadata *)authMetadata
502+
{
503+
if (metaData)
504+
{
505+
metaData.authMetadata = authMetadata;
506+
metaDataHasChanged = YES;
507+
}
508+
}
509+
496510
- (MXMatrixVersions *)supportedMatrixVersions
497511
{
498512
return metaData.supportedMatrixVersions;

MatrixSDK/Data/Store/MXFileStore/MXFileStoreMetaData.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#import "MXWellKnown.h"
2020
#import "MXCapabilities.h"
2121
#import "MXMatrixVersions.h"
22+
#import "MXAuthMetadata.h"
2223

2324
@interface MXFileStoreMetaData : NSObject <NSCoding, NSCopying>
2425

@@ -78,4 +79,9 @@
7879
*/
7980
@property (nonatomic) NSInteger maxUploadSize;
8081

82+
/**
83+
OAuth 2.0 server metadata.
84+
*/
85+
@property (nonatomic) MXAuthMetadata *authMetadata;
86+
8187
@end

MatrixSDK/Data/Store/MXMemoryStore/MXMemoryStore.m

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ @implementation MXMemoryStore
4141
@synthesize storeService, eventStreamToken, userAccountData, syncFilterId, homeserverWellknown, areAllIdentityServerTermsAgreed;
4242
@synthesize homeserverCapabilities;
4343
@synthesize supportedMatrixVersions;
44+
@synthesize authMetadata;
4445

4546
- (instancetype)init
4647
{
@@ -410,6 +411,11 @@ - (void)storeSupportedMatrixVersions:(MXMatrixVersions *)supportedMatrixVersions
410411
supportedMatrixVersions = supportedMatrixVersions;
411412
}
412413

414+
- (void)storeAuthMetadata:(MXAuthMetadata *)authMetadata
415+
{
416+
authMetadata = authMetadata;
417+
}
418+
413419
- (NSInteger)maxUploadSize
414420
{
415421
return self->maxUploadSize;

MatrixSDK/Data/Store/MXNoStore/MXNoStore.m

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,14 @@ - (void)storeHomeserverCapabilities:(MXCapabilities *)homeserverCapabilities
480480
{
481481
}
482482

483+
- (MXAuthMetadata *)authMetadata
484+
{
485+
return nil;
486+
}
487+
- (void)storeAuthMetadata:(MXAuthMetadata *)authMetadata
488+
{
489+
}
490+
483491
- (MXMatrixVersions *)supportedMatrixVersions
484492
{
485493
return nil;

MatrixSDK/Data/Store/MXStore.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
@class MXStoreService;
3535
@class MXCapabilities;
3636
@class MXMatrixVersions;
37+
@class MXAuthMetadata;
3738

3839
/**
3940
The `MXStore` protocol defines an interface that must be implemented in order to store
@@ -407,6 +408,18 @@
407408
*/
408409
- (void)storeSupportedMatrixVersions:(nonnull MXMatrixVersions*)supportedMatrixVersions;
409410

411+
/**
412+
The homeserver OAuth 2.0 server metadata.
413+
*/
414+
@property (nonatomic, readonly) MXAuthMetadata * _Nullable authMetadata;
415+
416+
/**
417+
Store the homeserver OAuth 2.0 server metadata.
418+
419+
@param authMetadata the homeserver OAuth 2.0 server metadata to store.
420+
*/
421+
- (void)storeAuthMetadata:(nonnull MXAuthMetadata*)authMetadata;
422+
410423
#pragma mark - Room Messages
411424

412425
/**
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//
2+
// Copyright 2025 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+
#import <Foundation/Foundation.h>
18+
19+
#import "MXJSONModel.h"
20+
21+
NS_ASSUME_NONNULL_BEGIN
22+
23+
/**
24+
Subset of OAuth 2.0 API Server metadata: https://spec.matrix.org/v1.16/client-server-api/#server-metadata-discovery
25+
{
26+
"issuer": "https://example.com/",
27+
"account_management_uri": "https://example.com/account",
28+
"account_management_actions_supported": ["org.matrix.profile", "org.matrix.device_delete"]
29+
}
30+
*/
31+
32+
@interface MXAuthMetadata : MXJSONModel<NSCoding>
33+
34+
@property (nonatomic, readonly) NSString *issuer;
35+
@property (nonatomic, readonly, nullable) NSString *accountManagementURI;
36+
@property (nonatomic, readonly, nullable) NSArray<NSString*> *accountManagementActionsSupported;
37+
38+
-(NSURL * _Nullable) getLogoutDeviceURLFromID: (NSString * ) deviceID;
39+
40+
@end
41+
42+
NS_ASSUME_NONNULL_END
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
//
2+
// Copyright 2025 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+
#import "MXAuthMetadata.h"
18+
19+
static NSString *const kMXIssuerJSONKey = @"issuer";
20+
static NSString *const kMXAccountManagementUriJSONKey = @"account_management_uri";
21+
static NSString *const kMXAccountManagementActionsSupportedJSONKey = @"account_management_actions_supported";
22+
23+
@interface MXAuthMetadata ()
24+
25+
@property (nonatomic, readwrite) NSString *issuer;
26+
@property (nonatomic, readwrite, nullable) NSString *accountManagementURI;
27+
@property (nonatomic, readwrite, nullable) NSArray<NSString*> *accountManagementActionsSupported;
28+
29+
@end
30+
31+
@implementation MXAuthMetadata
32+
33+
+ (instancetype)modelFromJSON:(NSDictionary *)JSONDictionary
34+
{
35+
MXAuthMetadata *oauthMetadata;
36+
37+
NSString *issuer;
38+
MXJSONModelSetString(issuer, JSONDictionary[kMXIssuerJSONKey]);
39+
40+
if (issuer)
41+
{
42+
oauthMetadata = [[MXAuthMetadata alloc] init];
43+
oauthMetadata.issuer = issuer;
44+
MXJSONModelSetString(oauthMetadata.accountManagementURI, JSONDictionary[kMXAccountManagementUriJSONKey])
45+
MXJSONModelSetArray(oauthMetadata.accountManagementActionsSupported, JSONDictionary[kMXAccountManagementActionsSupportedJSONKey])
46+
}
47+
48+
return oauthMetadata;
49+
}
50+
51+
-(NSURL * _Nullable) getLogoutDeviceURLFromID: (NSString * ) deviceID
52+
{
53+
if (!_accountManagementURI)
54+
{
55+
return nil;
56+
}
57+
NSURLComponents *components = [NSURLComponents componentsWithString:_accountManagementURI];
58+
// default to the stable value
59+
NSString *actionParam = @"org.matrix.device_delete";
60+
if ([_accountManagementActionsSupported containsObject: @"org.matrix.delete_device"])
61+
{
62+
// use the stable value
63+
}
64+
else if ([_accountManagementActionsSupported containsObject: @"org.matrix.session_end"])
65+
{
66+
// earlier version of MSC4191
67+
actionParam = @"org.matrix.session_end";
68+
}
69+
else if ([_accountManagementActionsSupported containsObject: @"session_end"])
70+
{
71+
// previous unspecced version
72+
actionParam = @"session_end";
73+
}
74+
75+
components.queryItems = @[
76+
[NSURLQueryItem queryItemWithName:@"device_id" value:deviceID],
77+
[NSURLQueryItem queryItemWithName:@"action" value:actionParam]
78+
];
79+
return components.URL;
80+
}
81+
82+
83+
#pragma mark - NSCoding
84+
85+
- (id)initWithCoder:(NSCoder *)aDecoder
86+
{
87+
self = [super init];
88+
if (self)
89+
{
90+
_issuer = [aDecoder decodeObjectForKey:kMXIssuerJSONKey];
91+
_accountManagementURI = [aDecoder decodeObjectForKey: kMXAccountManagementUriJSONKey];
92+
_accountManagementActionsSupported = [aDecoder decodeObjectForKey: kMXAccountManagementActionsSupportedJSONKey];
93+
}
94+
return self;
95+
}
96+
97+
- (void)encodeWithCoder:(NSCoder *)aCoder
98+
{
99+
[aCoder encodeObject:_issuer forKey:kMXIssuerJSONKey];
100+
[aCoder encodeObject:_accountManagementURI forKey:kMXAccountManagementUriJSONKey];
101+
[aCoder encodeObject:_accountManagementActionsSupported forKey:kMXAccountManagementActionsSupportedJSONKey];
102+
}
103+
104+
@end

MatrixSDK/JSONModels/AutoDiscovery/MXWellKnown.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
#import "MXWellKnownBaseConfig.h"
2121
#import "MXWellknownIntegrations.h"
2222
#import "MXWellKnownTileServerConfig.h"
23-
#import "MXWellKnownAuthentication.h"
2423

2524
NS_ASSUME_NONNULL_BEGIN
2625

@@ -46,8 +45,6 @@ NS_ASSUME_NONNULL_BEGIN
4645

4746
@property (nonatomic, nullable) MXWellKnownTileServerConfig *tileServer;
4847

49-
@property (nonatomic, nullable) MXWellKnownAuthentication *authentication;
50-
5148
@end
5249

5350
NS_ASSUME_NONNULL_END

0 commit comments

Comments
 (0)