Skip to content
This repository has been archived by the owner on Dec 12, 2022. It is now read-only.

Support identity server v2 API #597

Merged
merged 11 commits into from
Aug 30, 2019
Merged
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Improvements:
* Support soft logout (vector-im/riot-ios/issues/2540).
* MXKRoomBubbleCellData: Add method to get bubble component index from event id.
* MXKEmail: force in lowercase the email address.
* Use MXIdentityService to perform identity server requests (vector-im/riot-ios#2647).
* Support identity server v2 API (vector-im/riot-ios#2603 and /vector-im/riot-ios#2652).

Bug fix:
* APNS Push: fix logic when enabling APNS push. Avoid calling nil callback method.
Expand Down
24 changes: 20 additions & 4 deletions MatrixKit/Controllers/MXKAuthenticationViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ The timer used to postpone the registration when the authentication is pending (
NSTimer* registrationTimer;
}

/**
The identity service used to make identity server API requests.
*/
@property (nonatomic) MXIdentityService *identityService;

@end

@implementation MXKAuthenticationViewController
Expand Down Expand Up @@ -506,11 +511,17 @@ - (void)setIdentityServerTextFieldText:(NSString *)identityServerUrl
{
_identityServerTextField.text = identityServerUrl;

// Update REST client
if (![mxRestClient.identityServer isEqualToString:identityServerUrl])
[self updateIdentityServerURL:identityServerUrl];
}

- (void)updateIdentityServerURL:(NSString*)url
{
if (![self.identityService.identityServer isEqualToString:url])
{
[mxRestClient setIdentityServer:identityServerUrl];
self.identityService = [[MXIdentityService alloc] initWithIdentityServer:url andHomeserverRestClient:mxRestClient];
}

[mxRestClient setIdentityServer:url];
}

- (void)setUserInteractionEnabled:(BOOL)userInteractionEnabled
Expand Down Expand Up @@ -1469,7 +1480,7 @@ - (void)updateRESTClient

if (_identityServerTextField.text.length)
{
[mxRestClient setIdentityServer:_identityServerTextField.text];
[self updateIdentityServerURL:self.identityServerTextField.text];
}
}
}
Expand Down Expand Up @@ -1877,6 +1888,11 @@ - (MXRestClient *)authInputsViewThirdPartyIdValidationRestClient:(MXKAuthInputsV
return mxRestClient;
}

- (MXIdentityService *)authInputsViewThirdPartyIdValidationIdentityService:(MXIdentityService *)authInputsView
{
return self.identityService;
}

#pragma mark - Authentication Fallback

- (void)showAuthenticationFallBackView
Expand Down
40 changes: 39 additions & 1 deletion MatrixKit/Models/Account/MXKAccount.m
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ - (instancetype)initWithCredentials:(MXCredentials*)credentials

// Refresh device information
[self loadDeviceInformation:nil failure:nil];

[self registerIdentityServiceDidChangeAccessTokenNotification];
}
return self;
}
Expand Down Expand Up @@ -156,16 +158,20 @@ - (id)initWithCoder:(NSCoder *)coder
NSString *userId = [coder decodeObjectForKey:@"userid"];
NSString *accessToken = [coder decodeObjectForKey:@"accesstoken"];
_identityServerURL = [coder decodeObjectForKey:@"identityserverurl"];
NSString *identityServerAccessToken = [coder decodeObjectForKey:@"identityserveraccesstoken"];

mxCredentials = [[MXCredentials alloc] initWithHomeServer:homeServerURL
userId:userId
accessToken:accessToken];

mxCredentials.identityServer = _identityServerURL;
mxCredentials.identityServerAccessToken = identityServerAccessToken;
mxCredentials.deviceId = [coder decodeObjectForKey:@"deviceId"];
mxCredentials.allowedCertificate = [coder decodeObjectForKey:@"allowedCertificate"];

[self prepareRESTClient];

[self registerIdentityServiceDidChangeAccessTokenNotification];

if ([coder decodeObjectForKey:@"threePIDs"])
{
Expand Down Expand Up @@ -212,6 +218,7 @@ - (void)encodeWithCoder:(NSCoder *)coder
[coder encodeObject:mxCredentials.homeServer forKey:@"homeserverurl"];
[coder encodeObject:mxCredentials.userId forKey:@"userid"];
[coder encodeObject:mxCredentials.accessToken forKey:@"accesstoken"];
[coder encodeObject:mxCredentials.identityServerAccessToken forKey:@"identityserveraccesstoken"];

if (mxCredentials.deviceId)
{
Expand Down Expand Up @@ -269,11 +276,18 @@ - (void)setIdentityServerURL:(NSString *)identityServerURL
_identityServerURL = identityServerURL;
// Update the current restClient
[mxRestClient setIdentityServer:identityServerURL];

mxCredentials.identityServer = identityServerURL;

// Update identity service
MXIdentityService *identityService = [[MXIdentityService alloc] initWithCredentials:mxCredentials andHomeserverRestClient:mxRestClient];
mxSession.identityService = identityService;
}
else
{
_identityServerURL = nil;
_identityServerURL = nil;
[mxRestClient setIdentityServer:nil];
mxSession.identityService = nil;
}

// Archive updated field
Expand Down Expand Up @@ -1966,4 +1980,28 @@ - (void)checkSyncFilterCompatibility:(MXFilterJSONModel*)syncFilter completion:(
}
}

- (void)identityService:(MXIdentityService *)identityService didUpdateAccessToken:(NSString *)accessToken
{
mxCredentials.identityServerAccessToken = accessToken;
}

- (void)registerIdentityServiceDidChangeAccessTokenNotification
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleIdentityServiceDidChangeAccessTokenNotification:) name:MXIdentityServiceDidChangeAccessTokenNotification object:nil];
}

- (void)handleIdentityServiceDidChangeAccessTokenNotification:(NSNotification*)notification
{
NSDictionary *userInfo = notification.userInfo;

NSString *userId = userInfo[MXIdentityServiceNotificationUserIdKey];
NSString *identityServer = userInfo[MXIdentityServiceNotificationIdentityServerKey];
NSString *accessToken = userInfo[MXIdentityServiceNotificationAccessTokenKey];

if (userId && identityServer && accessToken && [mxCredentials.identityServer isEqualToString:identityServer])
{
mxCredentials.identityServerAccessToken = accessToken;
}
}

@end
70 changes: 39 additions & 31 deletions MatrixKit/Models/Contact/MXKContactManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,10 @@ Listeners registered on matrix presence and membership events (one by matrix ses
}

/**
The current REST client defined with the identity server.
The current identity service defined with the identity server.
*/
@property (nonatomic) MXRestClient *identityRESTClient;
@property (nonatomic) MXIdentityService *identityService;

@end

@implementation MXKContactManager
Expand Down Expand Up @@ -135,7 +136,6 @@ -(void)dealloc
mxSessionArray = nil;
mxEventListeners = nil;
_identityServer = nil;
_identityRESTClient = nil;

[[MXKAppSettings standardAppSettings] removeObserver:self forKeyPath:@"syncLocalContacts"];
[[MXKAppSettings standardAppSettings] removeObserver:self forKeyPath:@"phonebookCountryCode"];
Expand Down Expand Up @@ -274,8 +274,8 @@ - (void)removeMatrixSession:(MXSession*)mxSession
[mxEventListeners removeObjectAtIndex:index];
[mxSessionArray removeObjectAtIndex:index];

// Reset the current rest client (It will be rebuild if need)
_identityRESTClient = nil;
// Reset the current identity service (It will be rebuild if need)
self.identityService = nil;

if (!mxSessionArray.count) {
if (mxSessionStateObserver) {
Expand Down Expand Up @@ -489,49 +489,57 @@ - (void)setIdentityServer:(NSString *)identityServer

if (identityServer)
{
MXCredentials *credentials = [MXCredentials new];
credentials.identityServer = identityServer;

_identityRESTClient = [[MXRestClient alloc] initWithCredentials:credentials andOnUnrecognizedCertificateBlock:nil];
MXSession *mxSession = self.mxSessions.firstObject;

self.identityService = [[MXIdentityService alloc] initWithIdentityServer:identityServer andHomeserverRestClient:mxSession.matrixRestClient];

// Lookup the matrix users in all the local contacts.
[self updateMatrixIDsForAllLocalContacts];
}
else
{
_identityRESTClient = nil;
self.identityService = nil;
}
}

- (MXRestClient*)identityRESTClient
- (MXIdentityService*)identityService
{
if (!_identityRESTClient)
if (!_identityService)
{
NSString *identityServer;
MXSession *mxSession = [mxSessionArray firstObject];

if (self.identityServer)
{
MXCredentials *credentials = [MXCredentials new];
credentials.identityServer = self.identityServer;

_identityRESTClient = [[MXRestClient alloc] initWithCredentials:credentials andOnUnrecognizedCertificateBlock:nil];
identityServer = self.identityServer;
}
else if (mxSessionArray.count)
{
MXSession *mxSession = [mxSessionArray firstObject];

MXCredentials *credentials = [MXCredentials new];
credentials.identityServer = mxSession.matrixRestClient.identityServer;

_identityRESTClient = [[MXRestClient alloc] initWithCredentials:credentials andOnUnrecognizedCertificateBlock:nil];
identityServer = mxSession.identityService.identityServer;

if (!identityServer)
{
identityServer = mxSession.matrixRestClient.identityServer;
}
}

if (identityServer)
{
_identityService = [[MXIdentityService alloc] initWithIdentityServer:identityServer andHomeserverRestClient:mxSession.matrixRestClient];
}
else
{
_identityService = nil;
}
}

return _identityRESTClient;
return _identityService;
}

- (BOOL)isUsersDiscoveringEnabled
{
// Check whether the 3pid lookup is available
return (self.discoverUsersBoundTo3PIDsBlock || self.identityRESTClient);
return (self.discoverUsersBoundTo3PIDsBlock || self.identityService);
}

#pragma mark -
Expand Down Expand Up @@ -815,9 +823,9 @@ - (void)updateMatrixIDsForLocalContact:(MXKContact *)contact
else
{
// Consider the potential identity server url by default
[self.identityRESTClient lookup3pids:lookup3pidsArray
success:success
failure:failure];
[self.identityService lookup3pids:lookup3pidsArray
success:success
failure:failure];
}
}
}
Expand Down Expand Up @@ -928,9 +936,9 @@ - (void)updateMatrixIDsForAllLocalContacts
}
else
{
[self.identityRESTClient lookup3pids:lookup3pidsArray
success:success
failure:failure];
[self.identityService lookup3pids:lookup3pidsArray
success:success
failure:failure];
}
}
else
Expand Down Expand Up @@ -965,7 +973,7 @@ - (void)reset
mxSessionArray = nil;
mxEventListeners = nil;
_identityServer = nil;
_identityRESTClient = nil;
self.identityService = nil;

// warn of the contacts list update
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKContactManagerDidUpdateMatrixContactsNotification object:nil userInfo:nil];
Expand Down
65 changes: 46 additions & 19 deletions MatrixKit/Models/MXK3PID.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ @interface MXK3PID ()
@property (nonatomic) NSString *clientSecret;
@property (nonatomic) NSUInteger sendAttempt;
@property (nonatomic) NSString *sid;
@property (nonatomic) MXIdentityService *identityService;

@end

@implementation MXK3PID
Expand All @@ -50,6 +52,7 @@ - (void)cancelCurrentRequest
[currentRequest cancel];
currentRequest = nil;
mxRestClient = nil;
self.identityService = nil;

self.sendAttempt = 1;
self.sid = nil;
Expand Down Expand Up @@ -77,6 +80,13 @@ - (void)requestValidationTokenWithMatrixRestClient:(MXRestClient*)restClient
_validationState = MXK3PIDAuthStateTokenRequested;
mxRestClient = restClient;

NSString *identityServer = restClient.credentials.identityServer;
if (identityServer)
{
// Use same identity server as REST client for validation token submission
self.identityService = [[MXIdentityService alloc] initWithIdentityServer:identityServer andHomeserverRestClient:mxRestClient];
}

currentRequest = [mxRestClient requestTokenForEmail:self.address isDuringRegistration:isDuringRegistration clientSecret:self.clientSecret sendAttempt:self.sendAttempt nextLink:nextLink success:^(NSString *sid) {

self->_validationState = MXK3PIDAuthStateTokenReceived;
Expand Down Expand Up @@ -154,34 +164,51 @@ - (void)submitValidationToken:(NSString *)token
// Sanity Check
if (_validationState == MXK3PIDAuthStateTokenReceived)
{
_validationState = MXK3PIDAuthStateTokenSubmitted;

currentRequest = [mxRestClient submit3PIDValidationToken:token medium:self.medium clientSecret:self.clientSecret sid:self.sid success:^{

self->_validationState = MXK3PIDAuthStateAuthenticated;
self->currentRequest = nil;

if (success)
{
success();
}

} failure:^(NSError *error) {
if (self.identityService)
{
_validationState = MXK3PIDAuthStateTokenSubmitted;

// Return in previous state
self->_validationState = MXK3PIDAuthStateTokenReceived;
self->currentRequest = nil;
currentRequest = [self.identityService submit3PIDValidationToken:token medium:self.medium clientSecret:self.clientSecret sid:self.sid success:^{

self->_validationState = MXK3PIDAuthStateAuthenticated;
self->currentRequest = nil;

if (success)
{
success();
}

} failure:^(NSError *error) {

// Return in previous state
self->_validationState = MXK3PIDAuthStateTokenReceived;
self->currentRequest = nil;

if (failure)
{
failure (error);
}

}];
}
else
{
NSLog(@"[MXK3PID] Failed to submit validation token for 3PID: %@ (%@), identity service is not set", self.address, self.medium);

if (failure)
{
failure (error);
failure(nil);
}

}];
}
}
else
{
NSLog(@"[MXK3PID] Failed to submit validation token for 3PID: %@ (%@), state: %lu", self.address, self.medium, (unsigned long)_validationState);

if (failure)
{
failure(nil);
}
}
}

Expand Down
Loading