From 3804aa2933b898fbbbb8397a3c63ccb546992d40 Mon Sep 17 00:00:00 2001 From: James Go Date: Thu, 26 Oct 2017 10:12:02 -0700 Subject: [PATCH 01/30] DE324462 : [iOS][MASFoundation] MASAuthCredentialsJWT should not be re-used for registration and authentication --- .../Classes/models/AuthCredentials/MASAuthCredentialsJWT.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MASFoundation/Classes/models/AuthCredentials/MASAuthCredentialsJWT.m b/MASFoundation/Classes/models/AuthCredentials/MASAuthCredentialsJWT.m index 54d45503..5c07a31b 100644 --- a/MASFoundation/Classes/models/AuthCredentials/MASAuthCredentialsJWT.m +++ b/MASFoundation/Classes/models/AuthCredentials/MASAuthCredentialsJWT.m @@ -49,7 +49,7 @@ - (instancetype)initPrivateWithJWT:(NSString *)jwt tokenType:(NSString *)tokenTy } _canRegisterDevice = YES; - _isReuseable = YES; + _isReuseable = NO; } return self; From 4d7d72f14154836703054f49007b731ecbfde4ed Mon Sep 17 00:00:00 2001 From: James Go Date: Mon, 6 Nov 2017 16:42:52 -0800 Subject: [PATCH 02/30] US416558 : [iOS] SharedStorage API --- MASFoundation/Classes/MAS.m | 4 +- MASFoundation/Classes/MQTT/MASMQTTHelper.m | 2 +- .../MASAuthCredentials+MASPrivate.m | 6 +- .../MASAuthCredentialsClientCredentials.m | 4 +- .../Classes/_private_/models/MASAccess.m | 108 ++-- .../models/MASApplication+MASPrivate.m | 29 +- .../_private_/models/MASClaims+MASPrivate.m | 4 +- .../_private_/models/MASDevice+MASPrivate.m | 18 +- .../_private_/models/MASUser+MASPrivate.m | 10 +- .../services/access/MASAccessService.h | 128 ++-- .../services/access/MASAccessService.m | 545 +++++++----------- .../services/model/MASModelService.m | 30 +- .../services/network/MASNetworkingService.m | 6 +- .../internal/MASSessionDataTaskOperation.m | 4 +- .../services/security/MASSecurityService.m | 12 +- .../MASAuthCredentialsAuthorizationCode.m | 4 +- .../AuthCredentials/MASAuthCredentialsJWT.m | 4 +- MASFoundation/Classes/models/MASApplication.m | 6 +- MASFoundation/Classes/models/MASClaims.m | 4 +- .../Classes/models/MASConfiguration.m | 4 +- MASFoundation/Classes/models/MASDevice.m | 6 +- MASFoundation/Classes/models/MASUser.m | 10 +- 22 files changed, 412 insertions(+), 536 deletions(-) diff --git a/MASFoundation/Classes/MAS.m b/MASFoundation/Classes/MAS.m index db17fbab..6f470ced 100644 --- a/MASFoundation/Classes/MAS.m +++ b/MASFoundation/Classes/MAS.m @@ -206,7 +206,7 @@ + (void)start:(MASCompletionErrorBlock)completion // // If the device is registered, and id_token exists, which means MSSO can be used for this application // - else if ([MASDevice currentDevice].isRegistered && [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeIdToken]) + else if ([MASDevice currentDevice].isRegistered && [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyIdToken]) { // // Make sure to register the client (application) @@ -1641,7 +1641,7 @@ + (NSString * _Nullable)signWithClaims:(MASClaims *_Nonnull)claims error:(NSErro // // Retrieve private key from registered device's client certificate // - SecKeyRef pemPrivateRef = [[MASAccessService sharedService] getAccessValueCryptoKeyWithType:MASAccessValueTypePrivateKey]; + SecKeyRef pemPrivateRef = [[MASAccessService sharedService] getAccessValueCryptoKeyWithStorageKey:MASKeychainStorageKeyPrivateKey]; NSData *privateKeyData = [NSData converKeyRefToNSData:pemPrivateRef]; return [self signWithClaims:claims privateKey:privateKeyData error:error]; diff --git a/MASFoundation/Classes/MQTT/MASMQTTHelper.m b/MASFoundation/Classes/MQTT/MASMQTTHelper.m index cbe88579..56a5acb1 100644 --- a/MASFoundation/Classes/MQTT/MASMQTTHelper.m +++ b/MASFoundation/Classes/MQTT/MASMQTTHelper.m @@ -29,7 +29,7 @@ + (void)showLogMessage:(NSString *)message debugMode:(BOOL)debugMode + (NSString *)mqttClientId { - NSString *magIdentifier = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeMAGIdentifier]; + NSString *magIdentifier = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyMAGIdentifier]; //MQTT ClientId is: :::: NSString *clientId = [NSString stringWithFormat:@"%@::%@::%@",magIdentifier,[MASApplication currentApplication].identifier,[MASUser currentUser].objectId]; diff --git a/MASFoundation/Classes/_private_/models/AuthCredentials/MASAuthCredentials+MASPrivate.m b/MASFoundation/Classes/_private_/models/AuthCredentials/MASAuthCredentials+MASPrivate.m index 8673246c..79067d7f 100644 --- a/MASFoundation/Classes/_private_/models/AuthCredentials/MASAuthCredentials+MASPrivate.m +++ b/MASFoundation/Classes/_private_/models/AuthCredentials/MASAuthCredentials+MASPrivate.m @@ -333,7 +333,7 @@ - (void)loginWithCredential:(MASCompletionErrorBlock)completion { NSError *idTokenValidationError = nil; BOOL isIdTokenValid = [MASAccessService validateIdToken:[bodyInfo objectForKey:MASIdTokenBodyRequestResponseKey] - magIdentifier:[[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeMAGIdentifier] + magIdentifier:[[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyMAGIdentifier] error:&idTokenValidationError]; if (!isIdTokenValid && idTokenValidationError) @@ -355,7 +355,7 @@ - (void)loginWithCredential:(MASCompletionErrorBlock)completion // // Persist current authCredentials type // - [[MASAccessService sharedService] setAccessValueString:self.credentialsType withAccessValueType:MASAccessValueTypeCurrentAuthCredentialsGrantType]; + [[MASAccessService sharedService] setAccessValueString:self.credentialsType storageKey:MASKeychainStorageKeyCurrentAuthCredentialsGrantType]; // // Create a new instance of MASUser if not client credentials @@ -371,7 +371,7 @@ - (void)loginWithCredential:(MASCompletionErrorBlock)completion // set authenticated timestamp // NSNumber *authenticatedTimestamp = [NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]]; - [[MASAccessService sharedService] setAccessValueNumber:authenticatedTimestamp withAccessValueType:MASAccessValueTypeAuthenticatedTimestamp]; + [[MASAccessService sharedService] setAccessValueNumber:authenticatedTimestamp storageKey:MASKeychainStorageKeyAuthenticatedTimestamp]; // // Store credential information into keychain diff --git a/MASFoundation/Classes/_private_/models/AuthCredentials/MASAuthCredentialsClientCredentials.m b/MASFoundation/Classes/_private_/models/AuthCredentials/MASAuthCredentialsClientCredentials.m index 305ce1e2..b6d85197 100644 --- a/MASFoundation/Classes/_private_/models/AuthCredentials/MASAuthCredentialsClientCredentials.m +++ b/MASFoundation/Classes/_private_/models/AuthCredentials/MASAuthCredentialsClientCredentials.m @@ -109,14 +109,14 @@ - (NSDictionary *)getParameters else { // ClientId - NSString *clientId = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeClientId]; + NSString *clientId = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyClientId]; if (clientId) { parameterInfo[MASClientIdentifierRequestResponseKey] = clientId; } // ClientSecret - NSString *clientSecret = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeClientSecret]; + NSString *clientSecret = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyClientSecret]; if (clientSecret) { parameterInfo[MASClientSecretRequestResponseKey] = clientSecret; diff --git a/MASFoundation/Classes/_private_/models/MASAccess.m b/MASFoundation/Classes/_private_/models/MASAccess.m index 3401a4e9..a3b7457b 100644 --- a/MASFoundation/Classes/_private_/models/MASAccess.m +++ b/MASFoundation/Classes/_private_/models/MASAccess.m @@ -60,14 +60,14 @@ + (MASAccess *)instanceFromStorage // // retrieve all values from keychain and initialize with dictionary as those values shouold be read only. // - NSString *accessToken = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeAccessToken]; - NSString *tokenType = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeTokenType]; - NSString *refreshToken = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeRefreshToken]; - NSString *idToken = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeIdToken]; - NSString *idTokenType = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeIdTokenType]; - NSNumber *expiresIn = [[MASAccessService sharedService] getAccessValueNumberWithType:MASAccessValueTypeExpiresIn]; - NSString *scopeAsString = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeScope]; - NSString *authCredentialsType = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeCurrentAuthCredentialsGrantType]; + NSString *accessToken = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyAccessToken]; + NSString *tokenType = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyTokenType]; + NSString *refreshToken = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyRefreshToken]; + NSString *idToken = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyIdToken]; + NSString *idTokenType = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyIdTokenType]; + NSNumber *expiresIn = [[MASAccessService sharedService] getAccessValueNumberWithStorageKey:MASKeychainStorageKeyExpiresIn]; + NSString *scopeAsString = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyScope]; + NSString *authCredentialsType = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyCurrentAuthCredentialsGrantType]; NSMutableDictionary *accessDictionary = [NSMutableDictionary dictionary]; @@ -149,14 +149,14 @@ - (void)saveToStorage // // Save to the keychain // - [[MASAccessService sharedService] setAccessValueString:self.accessToken withAccessValueType:MASAccessValueTypeAccessToken]; - [[MASAccessService sharedService] setAccessValueString:self.tokenType withAccessValueType:MASAccessValueTypeTokenType]; - [[MASAccessService sharedService] setAccessValueString:self.refreshToken withAccessValueType:MASAccessValueTypeRefreshToken]; - [[MASAccessService sharedService] setAccessValueString:self.idToken withAccessValueType:MASAccessValueTypeIdToken]; - [[MASAccessService sharedService] setAccessValueString:self.idTokenType withAccessValueType:MASAccessValueTypeIdTokenType]; - [[MASAccessService sharedService] setAccessValueNumber:self.expiresIn withAccessValueType:MASAccessValueTypeExpiresIn]; - [[MASAccessService sharedService] setAccessValueString:self.scopeAsString withAccessValueType:MASAccessValueTypeScope]; - [[MASAccessService sharedService] setAccessValueString:self.authCredentialsType withAccessValueType:MASAccessValueTypeCurrentAuthCredentialsGrantType]; + [[MASAccessService sharedService] setAccessValueString:self.accessToken storageKey:MASKeychainStorageKeyAccessToken]; + [[MASAccessService sharedService] setAccessValueString:self.tokenType storageKey:MASKeychainStorageKeyTokenType]; + [[MASAccessService sharedService] setAccessValueString:self.refreshToken storageKey:MASKeychainStorageKeyRefreshToken]; + [[MASAccessService sharedService] setAccessValueString:self.idToken storageKey:MASKeychainStorageKeyIdToken]; + [[MASAccessService sharedService] setAccessValueString:self.idTokenType storageKey:MASKeychainStorageKeyIdTokenType]; + [[MASAccessService sharedService] setAccessValueNumber:self.expiresIn storageKey:MASKeychainStorageKeyExpiresIn]; + [[MASAccessService sharedService] setAccessValueString:self.scopeAsString storageKey:MASKeychainStorageKeyScope]; + [[MASAccessService sharedService] setAccessValueString:self.authCredentialsType storageKey:MASKeychainStorageKeyCurrentAuthCredentialsGrantType]; } @@ -262,7 +262,7 @@ - (void)saveWithUpdatedInfo:(NSDictionary *)info // // authCredentialsType // - NSString *authCredentialsType = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeCurrentAuthCredentialsGrantType]; + NSString *authCredentialsType = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyCurrentAuthCredentialsGrantType]; if (authCredentialsType) { _authCredentialsType = authCredentialsType; @@ -278,29 +278,29 @@ - (void)saveWithUpdatedInfo:(NSDictionary *)info - (void)refresh { _accessToken = nil; - _accessToken = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeAccessToken]; + _accessToken = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyAccessToken]; _tokenType = nil; - _tokenType = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeTokenType]; + _tokenType = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyTokenType]; _refreshToken = nil; - _refreshToken = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeRefreshToken]; + _refreshToken = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyRefreshToken]; _idToken = nil; - _idToken = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeIdToken]; + _idToken = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyIdToken]; _idTokenType = nil; - _idTokenType = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeIdTokenType]; + _idTokenType = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyIdTokenType]; _expiresIn = nil; - _expiresIn = [[MASAccessService sharedService] getAccessValueNumberWithType:MASAccessValueTypeExpiresIn]; + _expiresIn = [[MASAccessService sharedService] getAccessValueNumberWithStorageKey:MASKeychainStorageKeyExpiresIn]; _scope = nil; _scopeAsString = nil; - _scopeAsString = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeScope]; + _scopeAsString = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyScope]; _authCredentialsType = nil; - _authCredentialsType = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeCurrentAuthCredentialsGrantType]; + _authCredentialsType = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyCurrentAuthCredentialsGrantType]; } @@ -328,7 +328,6 @@ - (void)reset } - - (void)deleteAll { @@ -336,40 +335,39 @@ - (void)deleteAll // remove all data from the keychain // _accessToken = nil; - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeAccessToken]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyAccessToken]; - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeAuthenticatedUserObjectId]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyAuthenticatedUserObjectId]; - [[MASAccessService sharedService] setAccessValueNumber:nil withAccessValueType:MASAccessValueTypeAuthenticatedTimestamp]; + [[MASAccessService sharedService] setAccessValueNumber:nil storageKey:MASKeychainStorageKeyAuthenticatedTimestamp]; _tokenType = nil; - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeTokenType]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyTokenType]; _refreshToken = nil; - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeRefreshToken]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyRefreshToken]; _idToken = nil; - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeIdToken]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyIdToken]; _idTokenType = nil; - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeIdTokenType]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyIdTokenType]; _expiresIn = nil; - [[MASAccessService sharedService] setAccessValueNumber:nil withAccessValueType:MASAccessValueTypeExpiresIn]; + [[MASAccessService sharedService] setAccessValueNumber:nil storageKey:MASKeychainStorageKeyExpiresIn]; _scope = nil; _scopeAsString = nil; - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeScope]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyScope]; // // Clena up the tokens from Local Authentication protected keychain storage // - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeSecuredIdToken]; - [[MASAccessService sharedService] setAccessValueNumber:nil withAccessValueType:MASAccessValueTypeIsDeviceLocked]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeySecuredIdToken]; + [[MASAccessService sharedService] setAccessValueNumber:nil storageKey:MASKeychainStorageKeyIsDeviceLocked]; } - - (void)deleteForLogOff { @@ -377,24 +375,24 @@ - (void)deleteForLogOff // remove all data from the keychain // _accessToken = nil; - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeAccessToken]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyAccessToken]; - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeAuthenticatedUserObjectId]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyAuthenticatedUserObjectId]; - [[MASAccessService sharedService] setAccessValueNumber:nil withAccessValueType:MASAccessValueTypeAuthenticatedTimestamp]; + [[MASAccessService sharedService] setAccessValueNumber:nil storageKey:MASKeychainStorageKeyAuthenticatedTimestamp]; _tokenType = nil; - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeTokenType]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyTokenType]; _refreshToken = nil; - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeRefreshToken]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyRefreshToken]; _expiresIn = nil; - [[MASAccessService sharedService] setAccessValueNumber:nil withAccessValueType:MASAccessValueTypeExpiresIn]; + [[MASAccessService sharedService] setAccessValueNumber:nil storageKey:MASKeychainStorageKeyExpiresIn]; _scope = nil; _scopeAsString = nil; - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeScope]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyScope]; } @@ -404,19 +402,19 @@ - (void)deleteForTokenExpiration // remove all data from the keychain // _accessToken = nil; - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeAccessToken]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyAccessToken]; - [[MASAccessService sharedService] setAccessValueNumber:nil withAccessValueType:MASAccessValueTypeAuthenticatedTimestamp]; + [[MASAccessService sharedService] setAccessValueNumber:nil storageKey:MASKeychainStorageKeyAuthenticatedTimestamp]; _tokenType = nil; - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeTokenType]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyTokenType]; _expiresIn = nil; - [[MASAccessService sharedService] setAccessValueNumber:nil withAccessValueType:MASAccessValueTypeExpiresIn]; + [[MASAccessService sharedService] setAccessValueNumber:nil storageKey:MASKeychainStorageKeyExpiresIn]; _scope = nil; _scopeAsString = nil; - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeScope]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyScope]; } @@ -491,7 +489,7 @@ - (BOOL)isSessionLocked // MASAccessService *accessService = [MASAccessService sharedService]; - NSNumber *isLocked = [accessService getAccessValueNumberWithType:MASAccessValueTypeIsDeviceLocked]; + NSNumber *isLocked = [accessService getAccessValueNumberWithStorageKey:MASKeychainStorageKeyIsDeviceLocked]; return [isLocked boolValue]; } @@ -576,7 +574,7 @@ - (NSDate *)expiresInDate } // Authentication timestamp - NSNumber *authenticatedTimestamp = [[MASAccessService sharedService] getAccessValueNumberWithType:MASAccessValueTypeAuthenticatedTimestamp]; + NSNumber *authenticatedTimestamp = [[MASAccessService sharedService] getAccessValueNumberWithStorageKey:MASKeychainStorageKeyAuthenticatedTimestamp]; double expiresInDateNumber = [authenticatedTimestamp doubleValue] + [_expiresIn doubleValue]; NSDate *expiresInDate = [NSDate dateWithTimeIntervalSince1970:expiresInDateNumber]; @@ -589,7 +587,7 @@ - (NSDate *)clientCertificateExpirationDate { if (!_clientCertificateExpirationDate) { - NSNumber *clientCertExpTimestamp = [[MASAccessService sharedService] getAccessValueNumberWithType:MASAccessValueTypeSignedPublicCertificateExpirationDate]; + NSNumber *clientCertExpTimestamp = [[MASAccessService sharedService] getAccessValueNumberWithStorageKey:MASKeychainStorageKeyPublicCertificateExpirationDate]; if (clientCertExpTimestamp) { @@ -600,7 +598,7 @@ - (NSDate *)clientCertificateExpirationDate // // Extracting signed client certificate expiration date // - NSArray * cert = [[MASAccessService sharedService] getAccessValueCertificateWithType:MASAccessValueTypeSignedPublicCertificate]; + NSArray * cert = [[MASAccessService sharedService] getAccessValueCertificateWithStorageKey:MASKeychainStorageKeySignedPublicCertificate]; SecCertificateRef certificate = (__bridge SecCertificateRef)([cert objectAtIndex:0]); // @@ -608,7 +606,7 @@ - (NSDate *)clientCertificateExpirationDate // _clientCertificateExpirationDate = [[MASAccessService sharedService] extractExpirationDateFromCertificate:certificate]; [[MASAccessService sharedService] setAccessValueNumber:[NSNumber numberWithDouble:[_clientCertificateExpirationDate timeIntervalSince1970]] - withAccessValueType:MASAccessValueTypeSignedPublicCertificateExpirationDate]; + storageKey:MASKeychainStorageKeyPublicCertificateExpirationDate]; } } diff --git a/MASFoundation/Classes/_private_/models/MASApplication+MASPrivate.m b/MASFoundation/Classes/_private_/models/MASApplication+MASPrivate.m index 2c2291d3..d112574e 100644 --- a/MASFoundation/Classes/_private_/models/MASApplication+MASPrivate.m +++ b/MASFoundation/Classes/_private_/models/MASApplication+MASPrivate.m @@ -56,8 +56,7 @@ - (id)initWithConfiguration nil) forKey:@"redirectUri"]; MASAccessService *accessService = [MASAccessService sharedService]; - - NSData *trustedServerCertificate = [accessService getAccessValueDataWithType:MASAccessValueTypeTrustedServerCertificate]; + NSData *trustedServerCertificate = [accessService getAccessValueDataWithStorageKey:MASKeychainStorageKeyTrustedServerCertificate]; if(!trustedServerCertificate) { // @@ -67,7 +66,7 @@ - (id)initWithConfiguration if(certificates && certificates.count > 0) { trustedServerCertificate = certificates[0]; - [accessService setAccessValueData:trustedServerCertificate withAccessValueType:MASAccessValueTypeTrustedServerCertificate]; + [accessService setAccessValueData:trustedServerCertificate storageKey:MASKeychainStorageKeyTrustedServerCertificate]; } } @@ -200,7 +199,7 @@ - (void)saveWithUpdatedInfo:(NSDictionary *)info NSNumber *clientExpiration = bodyInfo[MASClientExpirationRequestResponseKey]; if(clientExpiration) { - [accessService setAccessValueNumber:clientExpiration withAccessValueType:MASAccessValueTypeClientExpiration]; + [accessService setAccessValueNumber:clientExpiration storageKey:MASKeychainStorageKeyClientExpiration]; } // @@ -209,7 +208,7 @@ - (void)saveWithUpdatedInfo:(NSDictionary *)info NSString *clientId = bodyInfo[MASClientKeyRequestResponseKey]; if(clientId) { - [accessService setAccessValueString:clientId withAccessValueType:MASAccessValueTypeClientId]; + [accessService setAccessValueString:clientId storageKey:MASKeychainStorageKeyClientId]; } // @@ -218,7 +217,7 @@ - (void)saveWithUpdatedInfo:(NSDictionary *)info NSString *clientSecret = bodyInfo[MASClientSecretRequestResponseKey]; if(clientSecret) { - [accessService setAccessValueString:clientSecret withAccessValueType:MASAccessValueTypeClientSecret]; + [accessService setAccessValueString:clientSecret storageKey:MASKeychainStorageKeyClientSecret]; } // @@ -232,9 +231,9 @@ - (void)reset { MASAccessService *accessService = [MASAccessService sharedService]; - [accessService setAccessValueString:nil withAccessValueType:MASAccessValueTypeClientId]; - [accessService setAccessValueString:nil withAccessValueType:MASAccessValueTypeClientSecret]; - [accessService setAccessValueNumber:nil withAccessValueType:MASAccessValueTypeClientExpiration]; + [accessService setAccessValueString:nil storageKey:MASKeychainStorageKeyClientId]; + [accessService setAccessValueString:nil storageKey:MASKeychainStorageKeyClientSecret]; + [accessService setAccessValueNumber:nil storageKey:MASKeychainStorageKeyClientExpiration]; [[MASIKeyChainStore keyChainStoreWithService:[MASConfiguration currentConfiguration].gatewayUrl.absoluteString] removeItemForKey:[MASApplication.class description]]; } @@ -268,7 +267,7 @@ + (NSDate *)expirationAsDate // MASAccessService *accessService = [MASAccessService sharedService]; - NSNumber *clientExpiration = [accessService getAccessValueNumberWithType:MASAccessValueTypeClientExpiration]; + NSNumber *clientExpiration = [accessService getAccessValueNumberWithStorageKey:MASKeychainStorageKeyClientExpiration]; if(!clientExpiration) { return nil; @@ -291,8 +290,8 @@ - (NSString *)clientAuthorizationBasicHeaderValue // MASAccessService *accessService = [MASAccessService sharedService]; - NSString *clientId = [accessService getAccessValueStringWithType:MASAccessValueTypeClientId]; - NSString *clientSecret = [accessService getAccessValueStringWithType:MASAccessValueTypeClientSecret]; + NSString *clientId = [accessService getAccessValueStringWithStorageKey:MASKeychainStorageKeyClientId]; + NSString *clientSecret = [accessService getAccessValueStringWithStorageKey:MASKeychainStorageKeyClientSecret]; NSString *clientAuthStr = [NSString stringWithFormat:@"%@:%@", clientId, clientSecret]; NSData *clientAuthData = [clientAuthStr dataUsingEncoding:NSUTF8StringEncoding]; @@ -310,9 +309,9 @@ - (BOOL)isExpired // MASAccessService *accessService = [MASAccessService sharedService]; - NSNumber *clientExpiration = [accessService getAccessValueNumberWithType:MASAccessValueTypeClientExpiration]; - NSString *clientId = [accessService getAccessValueStringWithType:MASAccessValueTypeClientId]; - NSString *clientSecret = [accessService getAccessValueStringWithType:MASAccessValueTypeClientSecret]; + NSNumber *clientExpiration = [accessService getAccessValueNumberWithStorageKey:MASKeychainStorageKeyClientExpiration]; + NSString *clientId = [accessService getAccessValueStringWithStorageKey:MASKeychainStorageKeyClientId]; + NSString *clientSecret = [accessService getAccessValueStringWithStorageKey:MASKeychainStorageKeyClientSecret]; // // Expiration is nil, then it is considered expired diff --git a/MASFoundation/Classes/_private_/models/MASClaims+MASPrivate.m b/MASFoundation/Classes/_private_/models/MASClaims+MASPrivate.m index da45ebad..ccb5e2c8 100644 --- a/MASFoundation/Classes/_private_/models/MASClaims+MASPrivate.m +++ b/MASFoundation/Classes/_private_/models/MASClaims+MASPrivate.m @@ -48,8 +48,8 @@ - (NSString * __nullable)buildWithPrivateKey:(NSData * __nonnull)privateKey erro // If iss was not prepare upon MASClaims object construction which most likley happened due to registration status of the client, // re-prepare iss with registered client id // - NSString *magIdentifier = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeMAGIdentifier]; - NSString *clientId = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeClientId]; + NSString *magIdentifier = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyMAGIdentifier]; + NSString *clientId = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyClientId]; if (magIdentifier && clientId) { diff --git a/MASFoundation/Classes/_private_/models/MASDevice+MASPrivate.m b/MASFoundation/Classes/_private_/models/MASDevice+MASPrivate.m index 48dab8cf..5972031a 100644 --- a/MASFoundation/Classes/_private_/models/MASDevice+MASPrivate.m +++ b/MASFoundation/Classes/_private_/models/MASDevice+MASPrivate.m @@ -96,28 +96,28 @@ - (void)saveWithUpdatedInfo:(NSDictionary *)info NSString *jwt = headerInfo[MASJwtRequestResponseKey]; if (jwt) { - [accessService setAccessValueString:jwt withAccessValueType:MASAccessValueTypeJWT]; + [accessService setAccessValueString:jwt storageKey:MASKeychainStorageKeyJWT]; } // Mag Identifier NSString *magIdentifier = headerInfo[MASMagIdentifierRequestResponseKey]; if (magIdentifier) { - [accessService setAccessValueString:magIdentifier withAccessValueType:MASAccessValueTypeMAGIdentifier]; + [accessService setAccessValueString:magIdentifier storageKey:MASKeychainStorageKeyMAGIdentifier]; } // Id token NSString *idToken = headerInfo[MASIdTokenHeaderRequestResponseKey]; if (idToken) { - [accessService setAccessValueString:idToken withAccessValueType:MASAccessValueTypeIdToken]; + [accessService setAccessValueString:idToken storageKey:MASKeychainStorageKeyIdToken]; } // Id token type NSString *idTokenType = headerInfo[MASIdTokenTypeHeaderRequestResponseKey]; if (idTokenType) { - [accessService setAccessValueString:idTokenType withAccessValueType:MASAccessValueTypeIdTokenType]; + [accessService setAccessValueString:idTokenType storageKey:MASKeychainStorageKeyIdTokenType]; } // @@ -129,20 +129,20 @@ - (void)saveWithUpdatedInfo:(NSDictionary *)info if (certificateData) { - [accessService setAccessValueCertificate:certificateData withAccessValueType:MASAccessValueTypeSignedPublicCertificate]; - [accessService setAccessValueData:certificateData withAccessValueType:MASAccessValueTypeSignedPublicCertificateData]; + [accessService setAccessValueCertificate:certificateData storageKey:MASKeychainStorageKeySignedPublicCertificate]; + [accessService setAccessValueData:certificateData storageKey:MASKeychainStorageKeyPublicCertificateData]; // // Extracting signed client certificate expiration date // - NSArray * cert = [accessService getAccessValueCertificateWithType:MASAccessValueTypeSignedPublicCertificate]; + NSArray * cert = [accessService getAccessValueCertificateWithStorageKey:MASKeychainStorageKeySignedPublicCertificate]; SecCertificateRef certificate = (__bridge SecCertificateRef)([cert objectAtIndex:0]); // // Store client certificate expiration date into shared keychain storage // NSDate *expirationDate = [accessService extractExpirationDateFromCertificate:certificate]; - [accessService setAccessValueNumber:[NSNumber numberWithDouble:[expirationDate timeIntervalSince1970]] withAccessValueType:MASAccessValueTypeSignedPublicCertificateExpirationDate]; + [accessService setAccessValueNumber:[NSNumber numberWithDouble:[expirationDate timeIntervalSince1970]] storageKey:MASKeychainStorageKeyPublicCertificateExpirationDate]; } // @@ -151,7 +151,7 @@ - (void)saveWithUpdatedInfo:(NSDictionary *)info NSString *deviceVendorId = [MASDevice deviceVendorId]; if (deviceVendorId) { - [accessService setAccessValueString:deviceVendorId withAccessValueType:MASAccessValueTypeDeviceVendorId]; + [accessService setAccessValueString:deviceVendorId storageKey:MASKeychainStorageKeyDeviceVendorId]; } // diff --git a/MASFoundation/Classes/_private_/models/MASUser+MASPrivate.m b/MASFoundation/Classes/_private_/models/MASUser+MASPrivate.m index 630acfcd..131b9a33 100644 --- a/MASFoundation/Classes/_private_/models/MASUser+MASPrivate.m +++ b/MASFoundation/Classes/_private_/models/MASUser+MASPrivate.m @@ -46,7 +46,7 @@ + (MASUser *)instanceFromStorage // Attempt to retrieve from keychain // - NSData *data = [[MASAccessService sharedService] getAccessValueDataWithType:MASAccessValueTypeMASUserObjectData]; + NSData *data = [[MASAccessService sharedService] getAccessValueDataWithStorageKey:MASKeychainStorageKeyMASUserObjectData]; if(data) { @@ -65,7 +65,7 @@ - (void)saveToStorage NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self]; if(data) { - [[MASAccessService sharedService] setAccessValueData:data withAccessValueType:MASAccessValueTypeMASUserObjectData]; + [[MASAccessService sharedService] setAccessValueData:data storageKey:MASKeychainStorageKeyMASUserObjectData]; } } @@ -172,12 +172,12 @@ - (void)saveWithUpdatedInfo:(NSDictionary *)info // set authenticated timestamp // NSNumber *authenticatedTimestamp = [NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]]; - [accessService setAccessValueNumber:authenticatedTimestamp withAccessValueType:MASAccessValueTypeAuthenticatedTimestamp]; + [accessService setAccessValueNumber:authenticatedTimestamp storageKey:MASKeychainStorageKeyAuthenticatedTimestamp]; // // set authenticated user's objectId // - [accessService setAccessValueString:self.objectId withAccessValueType:MASAccessValueTypeAuthenticatedUserObjectId]; + [accessService setAccessValueString:self.objectId storageKey:MASKeychainStorageKeyAuthenticatedUserObjectId]; // // storing access information into keychain @@ -203,7 +203,7 @@ - (void)reset { [self resetPartial]; - [[MASAccessService sharedService] setAccessValueData:nil withAccessValueType:MASAccessValueTypeMASUserObjectData]; + [[MASAccessService sharedService] setAccessValueData:nil storageKey:MASKeychainStorageKeyMASUserObjectData]; } - (void)resetPartial diff --git a/MASFoundation/Classes/_private_/services/access/MASAccessService.h b/MASFoundation/Classes/_private_/services/access/MASAccessService.h index 077e6038..cfa4abc5 100644 --- a/MASFoundation/Classes/_private_/services/access/MASAccessService.h +++ b/MASFoundation/Classes/_private_/services/access/MASAccessService.h @@ -16,43 +16,38 @@ @class MASIKeyChainStore; - -/** - * The enumerated MASAccessValueType - */ -typedef NS_ENUM(NSInteger, MASAccessValueType) -{ - MASAccessValueTypeUknonw = -1, - MASAccessValueTypeAccessToken, - MASAccessValueTypeAuthenticatedTimestamp, - MASAccessValueTypeAuthenticatedUserObjectId, - MASAccessValueTypeConfiguration, - MASAccessValueTypeClientExpiration, - MASAccessValueTypeClientId, - MASAccessValueTypeClientSecret, - MASAccessValueTypeExpiresIn, - MASAccessValueTypeIdToken, - MASAccessValueTypeIdTokenType, - MASAccessValueTypeIsDeviceLocked, - MASAccessValueTypeJWT, - MASAccessValueTypeMAGIdentifier, - MASAccessValueTypeMSSOEnabled, - MASAccessValueTypePrivateKey, - MASAccessValueTypePrivateKeyBits, - MASAccessValueTypePublicKey, - MASAccessValueTypeRefreshToken, - MASAccessValueTypeScope, - MASAccessValueTypeSecuredIdToken, - MASAccessValueTypeSignedPublicCertificate, - MASAccessValueTypeSignedPublicCertificateData, - MASAccessValueTypeSignedPublicCertificateExpirationDate, - MASAccessValueTypeTokenExpiration, - MASAccessValueTypeTokenType, - MASAccessValueTypeTrustedServerCertificate, - MASAccessValueTypeCurrentAuthCredentialsGrantType, - MASAccessValueTypeMASUserObjectData, - MASAccessValueTypeDeviceVendorId, -}; +// +// List of constant NSString values for reserved storage keys +// +extern NSString * const MASKeychainStorageKeyConfiguration; +extern NSString * const MASKeychainStorageKeyAccessToken; +extern NSString * const MASKeychainStorageKeyAuthenticatedUserObjectId; +extern NSString * const MASKeychainStorageKeyRefreshToken; +extern NSString * const MASKeychainStorageKeyScope; +extern NSString * const MASKeychainStorageKeyTokenType; +extern NSString * const MASKeychainStorageKeyExpiresIn; +extern NSString * const MASKeychainStorageKeyTokenExpiration; +extern NSString * const MASKeychainStorageKeySecuredIdToken; +extern NSString * const MASKeychainStorageKeyIdToken; +extern NSString * const MASKeychainStorageKeyIdTokenType; +extern NSString * const MASKeychainStorageKeyClientExpiration; +extern NSString * const MASKeychainStorageKeyClientId; +extern NSString * const MASKeychainStorageKeyClientSecret; +extern NSString * const MASKeychainStorageKeyJWT; +extern NSString * const MASKeychainStorageKeyMAGIdentifier; +extern NSString * const MASKeychainStorageKeyMSSOEnabled; +extern NSString * const MASKeychainStorageKeyPrivateKey; +extern NSString * const MASKeychainStorageKeyPrivateKeyBits; +extern NSString * const MASKeychainStorageKeyPublicKey; +extern NSString * const MASKeychainStorageKeyTrustedServerCertificate; +extern NSString * const MASKeychainStorageKeySignedPublicCertificate; +extern NSString * const MASKeychainStorageKeyPublicCertificateData; +extern NSString * const MASKeychainStorageKeyPublicCertificateExpirationDate; +extern NSString * const MASKeychainStorageKeyAuthenticatedTimestamp; +extern NSString * const MASKeychainStorageKeyIsDeviceLocked; +extern NSString * const MASKeychainStorageKeyCurrentAuthCredentialsGrantType; +extern NSString * const MASKeychainStorageKeyMASUserObjectData; +extern NSString * const MASKeychainStorageKeyDeviceVendorId; /** @@ -133,6 +128,10 @@ typedef NS_ENUM(NSInteger, MASAccessValueType) +///-------------------------------------- +/// @name MASAccess object +///-------------------------------------- + # pragma mark - MASAccess object /** @@ -145,9 +144,11 @@ typedef NS_ENUM(NSInteger, MASAccessValueType) -# pragma mark - Storage methods - +///-------------------------------------- +/// @name Storage methods +///-------------------------------------- +# pragma mark - Storage methods /** * Retrieve list of identities in keychain @@ -164,7 +165,7 @@ typedef NS_ENUM(NSInteger, MASAccessValueType) * @param certificate NSData form of certificate * @param type MASAccessValueType enum specifying the value key */ -- (void)setAccessValueCertificate:(NSData *)certificate withAccessValueType:(MASAccessValueType)type; +- (void)setAccessValueCertificate:(NSData *)certificate storageKey:(NSString *)storageKey; @@ -175,7 +176,7 @@ typedef NS_ENUM(NSInteger, MASAccessValueType) * * @return Certificate value by the specified value key */ -- (id)getAccessValueCertificateWithType:(MASAccessValueType)type; +- (id)getAccessValueCertificateWithStorageKey:(NSString *)storageKey; @@ -185,7 +186,7 @@ typedef NS_ENUM(NSInteger, MASAccessValueType) * @param data NSData to store into keychain * @param type MASAccessValueType enum value for the value key */ -- (void)setAccessValueData:(NSData *)data withAccessValueType:(MASAccessValueType)type; +- (void)setAccessValueData:(NSData *)data storageKey:(NSString *)storageKey; @@ -196,7 +197,7 @@ typedef NS_ENUM(NSInteger, MASAccessValueType) * * @return NSData of the access data by the specified value key */ -- (NSData *)getAccessValueDataWithType:(MASAccessValueType)type; +- (NSData *)getAccessValueDataWithStorageKey:(NSString *)storageKey; @@ -206,7 +207,7 @@ typedef NS_ENUM(NSInteger, MASAccessValueType) * @param string NSString to store into keychain * @param type MASAccessValueType enum value for the value key */ -- (void)setAccessValueString:(NSString *)string withAccessValueType:(MASAccessValueType)type; +- (void)setAccessValueString:(NSString *)string storageKey:(NSString *)storageKey; @@ -217,7 +218,7 @@ typedef NS_ENUM(NSInteger, MASAccessValueType) * * @return NSString of the access data by the specified value key */ -- (NSString *)getAccessValueStringWithType:(MASAccessValueType)type; +- (NSString *)getAccessValueStringWithStorageKey:(NSString *)storageKey; @@ -227,7 +228,7 @@ typedef NS_ENUM(NSInteger, MASAccessValueType) * @param dictionary NSDictionary to store into keychain * @param type MASAccessValueType enum value for the value key */ -- (void)setAccessValueDictionary:(NSDictionary *)dictionary withAccessValueType:(MASAccessValueType)type; +- (void)setAccessValueDictionary:(NSDictionary *)dictionary storageKey:(NSString *)storageKey; @@ -238,7 +239,7 @@ typedef NS_ENUM(NSInteger, MASAccessValueType) * * @return NSDictionary of the access data by the specified value key */ -- (NSDictionary *)getAccessValueDictionaryWithType:(MASAccessValueType)type; +- (NSDictionary *)getAccessValueDictionaryWithStorageKey:(NSString *)storageKey; @@ -248,7 +249,7 @@ typedef NS_ENUM(NSInteger, MASAccessValueType) * @param number NSNumber to store into keychain * @param type MASAccessValueType enum value for the value key */ -- (void)setAccessValueNumber:(NSNumber *)number withAccessValueType:(MASAccessValueType)type; +- (void)setAccessValueNumber:(NSNumber *)number storageKey:(NSString *)storageKey; @@ -259,7 +260,7 @@ typedef NS_ENUM(NSInteger, MASAccessValueType) * * @return NSNumber of the access data by the specified value key */ -- (NSNumber *)getAccessValueNumberWithType:(MASAccessValueType)type; +- (NSNumber *)getAccessValueNumberWithStorageKey:(NSString *)storageKey; @@ -273,7 +274,7 @@ typedef NS_ENUM(NSInteger, MASAccessValueType) * @param cryptoKey SecKeyRef to store into keychain * @param type MASAccessValueType enum value for the value key */ -- (void)setAccessValueCryptoKey:(SecKeyRef)cryptoKey withAccessValueType:(MASAccessValueType)type; +- (void)setAccessValueCryptoKey:(SecKeyRef)cryptoKey storageKey:(NSString *)storageKey; @@ -288,8 +289,13 @@ typedef NS_ENUM(NSInteger, MASAccessValueType) * * @return SecKeyRef of the access data by the specified value key */ -- (SecKeyRef)getAccessValueCryptoKeyWithType:(MASAccessValueType)type; +- (SecKeyRef)getAccessValueCryptoKeyWithStorageKey:(NSString *)storageKey; + + +///-------------------------------------- +/// @name Public +///-------------------------------------- # pragma mark - Public @@ -303,6 +309,8 @@ typedef NS_ENUM(NSInteger, MASAccessValueType) */ + (BOOL)validateIdToken:(NSString *)idToken magIdentifier:(NSString *)magIdentifier error:(NSError *__autoreleasing *)error; + + /** * Validate the expiration date in id_token * @@ -313,6 +321,13 @@ typedef NS_ENUM(NSInteger, MASAccessValueType) + (BOOL)isIdTokenExpired:(NSString *)idToken error:(NSError *__autoreleasing *)error; + +/** + Extracts the expiration date from the SecCertificateRef + + @param certificate SecCertificateRef of the certificate + @return NSDate of the expiration date from SecCertificateRef + */ - (NSDate *)extractExpirationDateFromCertificate:(SecCertificateRef)certificate; @@ -328,7 +343,6 @@ typedef NS_ENUM(NSInteger, MASAccessValueType) - /** Unlock id_token, access_token, and refresh_token from secure keychain storage protected by device's local authentication (passcode and/or fingerprint) @@ -348,6 +362,16 @@ typedef NS_ENUM(NSInteger, MASAccessValueType) +/** + Internal method to determine whether the key is reserved for internal system data or not + + @param storageKey NSString of key to be stored + @return BOOL result of whether the key is reserved or not by internal system data + */ +- (BOOL)isInternalDataForStorageKey:(NSString *)storageKey; + + + # pragma mark - Debug only - (void)clearLocal; diff --git a/MASFoundation/Classes/_private_/services/access/MASAccessService.m b/MASFoundation/Classes/_private_/services/access/MASAccessService.m index a03e0d4b..468ae48a 100644 --- a/MASFoundation/Classes/_private_/services/access/MASAccessService.m +++ b/MASFoundation/Classes/_private_/services/access/MASAccessService.m @@ -28,6 +28,39 @@ static NSString *const kMASAccessIsNotFreshInstallFlag = @"isNotFreshInstall"; +# pragma mark - Keychain Storage Key + +NSString * const MASKeychainStorageKeyConfiguration = @"kMASKeyChainConfiguration"; +NSString * const MASKeychainStorageKeyAccessToken = @"kMASKeyChainAccessToken"; +NSString * const MASKeychainStorageKeyAuthenticatedUserObjectId = @"MASAccessValueTypeAuthenticatedUserObjectId"; +NSString * const MASKeychainStorageKeyRefreshToken = @"kMASKeyChainRefreshToken"; +NSString * const MASKeychainStorageKeyScope = @"kMASKeyChainScope"; +NSString * const MASKeychainStorageKeyTokenType = @"kMASKeyChainTokenType"; +NSString * const MASKeychainStorageKeyExpiresIn = @"kMASKeyChainExpiresIn"; +NSString * const MASKeychainStorageKeyTokenExpiration = @"kMASKeyChainTokenExpiration"; +NSString * const MASKeychainStorageKeySecuredIdToken = @"kMASKeyChainSecuredIdToken"; +NSString * const MASKeychainStorageKeyIdToken = @"kMASKeyChainIdToken"; +NSString * const MASKeychainStorageKeyIdTokenType = @"kMASKeyChainIdTokenType"; +NSString * const MASKeychainStorageKeyClientExpiration = @"kMASKeyChainClientExpiration"; +NSString * const MASKeychainStorageKeyClientId = @"kMASKeyChainClientId"; +NSString * const MASKeychainStorageKeyClientSecret = @"kMASKeyChainClientSecret"; +NSString * const MASKeychainStorageKeyJWT = @"kMASKeyChainJwt"; +NSString * const MASKeychainStorageKeyMAGIdentifier = @"kMASKeyChainMagIdentifier"; +NSString * const MASKeychainStorageKeyMSSOEnabled = @"kMASAccessValueTypeMSSOEnabled"; +NSString * const MASKeychainStorageKeyPrivateKey = @"kMASKeyChainPrivateKey"; +NSString * const MASKeychainStorageKeyPrivateKeyBits = @"kMASKeyChainPrivateKeyBits"; +NSString * const MASKeychainStorageKeyPublicKey = @"kMASKeyChainPublicKey"; +NSString * const MASKeychainStorageKeyTrustedServerCertificate = @"kMASKeyChainTrustedServerCertificate"; +NSString * const MASKeychainStorageKeySignedPublicCertificate = @"kMASKeyChainSignedPublicCertificate"; +NSString * const MASKeychainStorageKeyPublicCertificateData = @"kMASKeyChainSignedPublicCertificateData"; +NSString * const MASKeychainStorageKeyPublicCertificateExpirationDate = @"kMASAccessValueTypeSignedPublicCertificateExpirationDate"; +NSString * const MASKeychainStorageKeyAuthenticatedTimestamp = @"kMASAccessValueTypeAuthenticatedTimestamp"; +NSString * const MASKeychainStorageKeyIsDeviceLocked = @"kMASAccessValueTypeIsDeviceLocked"; +NSString * const MASKeychainStorageKeyCurrentAuthCredentialsGrantType = @"kMASAccessValueTypeCurrentAuthCredentialsGrantType"; +NSString * const MASKeychainStorageKeyMASUserObjectData = @"kMASAccessValueTypeMASUserObjectData"; +NSString * const MASKeychainStorageKeyDeviceVendorId = @"kMASKeyChainDeviceVendorId"; + + @interface MASAccessService () # pragma mark - Properties @@ -42,6 +75,10 @@ @interface MASAccessService () @property (assign) BOOL isSharedKeychainEnabled; +@property (strong, nonatomic, readwrite) NSArray *sharedStorageKeys; +@property (strong, nonatomic, readwrite) NSArray *localStorageKeys; +@property (strong, nonatomic, readwrite) NSArray *secureStorageKeys; + @end @@ -102,13 +139,54 @@ + (NSString *)serviceUUID - (void)serviceDidLoad { - [super serviceDidLoad]; } - (void)serviceWillStart { + // + // Define a list of keys for secured storage + // + _secureStorageKeys = @[MASKeychainStorageKeySecuredIdToken]; + + // + // Define a list of keys to be stored in local keychain storage + // + _localStorageKeys = @[MASKeychainStorageKeyConfiguration, + MASKeychainStorageKeyAccessToken, + MASKeychainStorageKeyRefreshToken, + MASKeychainStorageKeyScope, + MASKeychainStorageKeyTokenType, + MASKeychainStorageKeyExpiresIn, + MASKeychainStorageKeyTokenExpiration, + MASKeychainStorageKeyClientExpiration, + MASKeychainStorageKeyClientId, + MASKeychainStorageKeyClientSecret, + MASKeychainStorageKeyAuthenticatedTimestamp]; + + // + // Define a list of keys to be stored in shared keychain storage + // + _sharedStorageKeys = @[MASKeychainStorageKeyAuthenticatedUserObjectId, + MASKeychainStorageKeySecuredIdToken, + MASKeychainStorageKeyIdToken, + MASKeychainStorageKeyIdTokenType, + MASKeychainStorageKeyJWT, + MASKeychainStorageKeyMAGIdentifier, + MASKeychainStorageKeyMSSOEnabled, + MASKeychainStorageKeyPrivateKey, + MASKeychainStorageKeyPrivateKeyBits, + MASKeychainStorageKeyPublicKey, + MASKeychainStorageKeyTrustedServerCertificate, + MASKeychainStorageKeySignedPublicCertificate, + MASKeychainStorageKeyPublicCertificateData, + MASKeychainStorageKeyPublicCertificateExpirationDate, + MASKeychainStorageKeyCurrentAuthCredentialsGrantType, + MASKeychainStorageKeyIsDeviceLocked, + MASKeychainStorageKeyMASUserObjectData, + MASKeychainStorageKeyDeviceVendorId]; + // // Retrieve gatewayUrl which is combination of hostname, port number, and prefix of the gateway. // The gatewayUrl can be unique identifier for each server. @@ -240,11 +318,22 @@ - (void)saveAccessValuesWithDictionary:(NSDictionary *)dictionary forceToOverwri # pragma mark - Storage methods -- (void)setAccessValueCertificate:(NSData *)certificate withAccessValueType:(MASAccessValueType)type +- (id)getAccessValueIdentities { - NSString *storageKey = [self getStorageKeyWithAccessValueType:type]; - NSString *accessValueAsString = [self convertAccessTypeToString:type]; - MASIKeyChainStore *destinationStorage = _storages[storageKey]; + //DLog(@"\n\ncalled\n\n"); + + MASIKeyChainStore *keychainStore = [MASIKeyChainStore keyChainStore]; + NSArray *identities = [keychainStore identitiesWithCertificateLabel:[self convertKeyString:MASKeychainStorageKeySignedPublicCertificate]]; + + return identities; +} + + +- (void)setAccessValueCertificate:(NSData *)certificate storageKey:(NSString *)storageKey +{ + NSString *storageType = [self getStorageTypeWithKey:storageKey]; + NSString *accessValueAsString = [self convertKeyString:storageKey]; + MASIKeyChainStore *destinationStorage = _storages[storageType]; NSData * certData = nil; @@ -269,35 +358,24 @@ - (void)setAccessValueCertificate:(NSData *)certificate withAccessValueType:(MAS } -- (id)getAccessValueCertificateWithType:(MASAccessValueType)type +- (id)getAccessValueCertificateWithStorageKey:(NSString *)storageKey { - NSString *storageKey = [self getStorageKeyWithAccessValueType:type]; - NSString *accessValueAsString = [self convertAccessTypeToString:type]; - MASIKeyChainStore *destinationStorage = _storages[storageKey]; + NSString *storageType = [self getStorageTypeWithKey:storageKey]; + NSString *accessValueAsString = [self convertKeyString:storageKey]; + MASIKeyChainStore *destinationStorage = _storages[storageType]; return [destinationStorage certificateForKey:accessValueAsString]; } -- (id)getAccessValueIdentities +- (void)setAccessValueData:(NSData *)data storageKey:(NSString *)storageKey { - //DLog(@"\n\ncalled\n\n"); - MASIKeyChainStore *keychainStore = [MASIKeyChainStore keyChainStore]; - NSArray *identities = [keychainStore identitiesWithCertificateLabel:[self convertAccessTypeToString:MASAccessValueTypeSignedPublicCertificate]]; + NSString *storageType = [self getStorageTypeWithKey:storageKey]; + NSString *accessValueAsString = [self convertKeyString:storageKey]; + MASIKeyChainStore *destinationStorage = _storages[storageType]; - return identities; -} - - -- (void)setAccessValueData:(NSData *)data withAccessValueType:(MASAccessValueType)type -{ - - NSString *storageKey = [self getStorageKeyWithAccessValueType:type]; - NSString *accessValueAsString = [self convertAccessTypeToString:type]; - MASIKeyChainStore *destinationStorage = _storages[storageKey]; - - BOOL isSecuredData = [self isSecuredData:type]; + BOOL isSecuredData = [self isSecureData:storageKey]; if (isSecuredData) { @@ -326,12 +404,12 @@ - (void)setAccessValueData:(NSData *)data withAccessValueType:(MASAccessValueTyp } -- (NSData *)getAccessValueDataWithType:(MASAccessValueType)type +- (NSData *)getAccessValueDataWithStorageKey:(NSString *)storageKey { - NSString *storageKey = [self getStorageKeyWithAccessValueType:type]; - NSString *accessValueAsString = [self convertAccessTypeToString:type]; - MASIKeyChainStore *destinationStorage = _storages[storageKey]; + NSString *storageType = [self getStorageTypeWithKey:storageKey]; + NSString *accessValueAsString = [self convertKeyString:storageKey]; + MASIKeyChainStore *destinationStorage = _storages[storageType]; NSData *keychainData = [destinationStorage dataForKey:accessValueAsString]; @@ -339,20 +417,20 @@ - (NSData *)getAccessValueDataWithType:(MASAccessValueType)type } -- (void)setAccessValueString:(NSString *)string withAccessValueType:(MASAccessValueType)type +- (void)setAccessValueString:(NSString *)string storageKey:(NSString *)storageKey { - [self setAccessValueString:string withAccessValueType:type error:nil]; + [self setAccessValueString:string storageKey:storageKey error:nil]; } -- (BOOL)setAccessValueString:(NSString *)string withAccessValueType:(MASAccessValueType)type error:(NSError * __nullable __autoreleasing * __nullable)error +- (BOOL)setAccessValueString:(NSString *)string storageKey:(NSString *)storageKey error:(NSError * __nullable __autoreleasing * __nullable)error { - NSString *storageKey = [self getStorageKeyWithAccessValueType:type]; - NSString *accessValueAsString = [self convertAccessTypeToString:type]; - MASIKeyChainStore *destinationStorage = _storages[storageKey]; + NSString *storageType = [self getStorageTypeWithKey:storageKey]; + NSString *accessValueAsString = [self convertKeyString:storageKey]; + MASIKeyChainStore *destinationStorage = _storages[storageType]; - BOOL isSecuredData = [self isSecuredData:type]; + BOOL isSecuredData = [self isSecureData:storageKey]; if (isSecuredData) { @@ -389,18 +467,18 @@ - (BOOL)setAccessValueString:(NSString *)string withAccessValueType:(MASAccessVa } -- (NSString *)getAccessValueStringWithType:(MASAccessValueType)type +- (NSString *)getAccessValueStringWithStorageKey:(NSString *)storageKey { - return [self getAccessValueStringWithType:type error:nil]; + return [self getAccessValueStringWithStorageKey:storageKey error:nil]; } -- (NSString *)getAccessValueStringWithType:(MASAccessValueType)type userOperationPrompt:(NSString *)userOperationPrompt error:(NSError * __nullable __autoreleasing * __nullable)error +- (NSString *)getAccessValueStringWithStorageKey:(NSString *)storageKey userOperationPrompt:(NSString *)userOperationPrompt error:(NSError * __nullable __autoreleasing * __nullable)error { - NSString *storageKey = [self getStorageKeyWithAccessValueType:type]; - NSString *accessValueAsString = [self convertAccessTypeToString:type]; - MASIKeyChainStore *destinationStorage = _storages[storageKey]; + NSString *storageType = [self getStorageTypeWithKey:storageKey]; + NSString *accessValueAsString = [self convertKeyString:storageKey]; + MASIKeyChainStore *destinationStorage = _storages[storageType]; NSString *securedString = [destinationStorage stringForKey:accessValueAsString userOperationPrompt:userOperationPrompt error:error]; @@ -408,12 +486,12 @@ - (NSString *)getAccessValueStringWithType:(MASAccessValueType)type userOperatio } -- (NSString *)getAccessValueStringWithType:(MASAccessValueType)type error:(NSError * __nullable __autoreleasing * __nullable)error +- (NSString *)getAccessValueStringWithStorageKey:(NSString *)storageKey error:(NSError * __nullable __autoreleasing * __nullable)error { - NSString *storageKey = [self getStorageKeyWithAccessValueType:type]; - NSString *accessValueAsString = [self convertAccessTypeToString:type]; - MASIKeyChainStore *destinationStorage = _storages[storageKey]; + NSString *storageType = [self getStorageTypeWithKey:storageKey]; + NSString *accessValueAsString = [self convertKeyString:storageKey]; + MASIKeyChainStore *destinationStorage = _storages[storageType]; NSString *securedString = [destinationStorage stringForKey:accessValueAsString error:error]; @@ -421,7 +499,7 @@ - (NSString *)getAccessValueStringWithType:(MASAccessValueType)type error:(NSErr } -- (void)setAccessValueDictionary:(NSDictionary *)dictionary withAccessValueType:(MASAccessValueType)type +- (void)setAccessValueDictionary:(NSDictionary *)dictionary storageKey:(NSString *)storageKey { // @@ -434,17 +512,17 @@ - (void)setAccessValueDictionary:(NSDictionary *)dictionary withAccessValueType: // if(thisData) { - [self setAccessValueData:thisData withAccessValueType:type]; + [self setAccessValueData:thisData storageKey:storageKey]; } } -- (NSDictionary *)getAccessValueDictionaryWithType:(MASAccessValueType)type +- (NSDictionary *)getAccessValueDictionaryWithStorageKey:(NSString *)storageKey { // // get data from keychain as NSData first // - NSData *thisData = [self getAccessValueDataWithType:type]; + NSData *thisData = [self getAccessValueDataWithStorageKey:storageKey]; // // return nil if NSData is nil @@ -453,7 +531,7 @@ - (NSDictionary *)getAccessValueDictionaryWithType:(MASAccessValueType)type } -- (void)setAccessValueNumber:(NSNumber *)number withAccessValueType:(MASAccessValueType)type +- (void)setAccessValueNumber:(NSNumber *)number storageKey:(NSString *)storageKey { // convert dictionary to data // @@ -464,17 +542,17 @@ - (void)setAccessValueNumber:(NSNumber *)number withAccessValueType:(MASAccessVa // if(thisData) { - [self setAccessValueData:thisData withAccessValueType:type]; + [self setAccessValueData:thisData storageKey:storageKey]; } } -- (NSNumber *)getAccessValueNumberWithType:(MASAccessValueType)type +- (NSNumber *)getAccessValueNumberWithStorageKey:(NSString *)storageKey { // // get data from keychain as NSData first // - NSData *thisData = [self getAccessValueDataWithType:type]; + NSData *thisData = [self getAccessValueDataWithStorageKey:storageKey]; // // return nil if NSData is nil @@ -483,19 +561,20 @@ - (NSNumber *)getAccessValueNumberWithType:(MASAccessValueType)type } -- (void)setAccessValueCryptoKey:(SecKeyRef)cryptoKey withAccessValueType:(MASAccessValueType)type +- (void)setAccessValueCryptoKey:(SecKeyRef)cryptoKey storageKey:(NSString *)storageKey { - NSString *storageKey = [self getStorageKeyWithAccessValueType:type]; + NSString *storageType = [self getStorageTypeWithKey:storageKey]; - MASIKeyChainStore *destinationStorage = _storages[storageKey]; + MASIKeyChainStore *destinationStorage = _storages[storageType]; NSString *keyIdentifierStr = nil; - if (type == MASAccessValueTypePublicKey) + + if ([storageType isEqualToString:MASKeychainStorageKeyPublicKey]) { keyIdentifierStr = [NSString stringWithFormat:@"%@.%@", [MASConfiguration currentConfiguration].gatewayUrl.absoluteString, @"publicKey"]; } - else if (type == MASAccessValueTypePrivateKey) + else if ([storageType isEqualToString:MASKeychainStorageKeyPrivateKey]) { keyIdentifierStr = [NSString stringWithFormat:@"%@.%@", [MASConfiguration currentConfiguration].gatewayUrl.absoluteString, @"privateKey"]; } @@ -510,20 +589,20 @@ - (void)setAccessValueCryptoKey:(SecKeyRef)cryptoKey withAccessValueType:(MASAcc } -- (SecKeyRef)getAccessValueCryptoKeyWithType:(MASAccessValueType)type +- (SecKeyRef)getAccessValueCryptoKeyWithStorageKey:(NSString *)storageKey { - NSString *storageKey = [self getStorageKeyWithAccessValueType:type]; - MASIKeyChainStore *destinationStorage = _storages[storageKey]; + NSString *storageType = [self getStorageTypeWithKey:storageKey]; + MASIKeyChainStore *destinationStorage = _storages[storageType]; NSString *keyIdentifierStr = nil; - if (type == MASAccessValueTypePublicKey) + if ([storageType isEqualToString:MASKeychainStorageKeyPublicKey]) { keyIdentifierStr = [NSString stringWithFormat:@"%@.%@", [MASConfiguration currentConfiguration].gatewayUrl.absoluteString, @"publicKey"]; } - else if (type == MASAccessValueTypePrivateKey) + else if ([storageType isEqualToString:MASKeychainStorageKeyPrivateKey]) { keyIdentifierStr = [NSString stringWithFormat:@"%@.%@", [MASConfiguration currentConfiguration].gatewayUrl.absoluteString, @"privateKey"]; } @@ -544,7 +623,7 @@ - (SecKeyRef)getAccessValueCryptoKeyWithType:(MASAccessValueType)type #pragma mark - Private -+ (NSString *)padding: (NSString *) encodedString{ ++ (NSString *)padding:(NSString *)encodedString{ unsigned long lengthtRequired = (int)(4 * ceil((float)[encodedString length] / 4.0)); long numPaddings = lengthtRequired - [encodedString length]; @@ -562,6 +641,7 @@ + (NSString *)padding: (NSString *) encodedString{ return encodedString; } + + (NSDictionary *)getIdTokenSegments:(NSString *)idToken error:(NSError *__autoreleasing *)error { NSDictionary *segmentsDict = nil; @@ -598,6 +678,7 @@ + (NSDictionary *)getIdTokenSegments:(NSString *)idToken error:(NSError *__autor return segmentsDict; } + + (NSDictionary *)unwrap:(NSString *)data { NSDictionary *dictionary = nil; @@ -615,284 +696,45 @@ + (NSDictionary *)unwrap:(NSString *)data return dictionary; } -- (BOOL)isSecuredData:(MASAccessValueType)type + +- (NSString *)convertKeyString:(NSString *)key { - BOOL isSecuredData = NO; + NSString *accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, key]; - switch (type) { - case MASAccessValueTypeSecuredIdToken: - isSecuredData = YES; - break; - - default: - isSecuredData = NO; - break; + // + // When access gruop is not accessiable, differentiate the key to make sure there is no conflict of device registration record in the future + // + if (![self isAccessGroupAccessible]) + { + accessTypeToString = [NSString stringWithFormat:@"_%@", accessTypeToString]; } - return isSecuredData; + return accessTypeToString; } -- (NSString *)getStorageKeyWithAccessValueType:(MASAccessValueType)type +- (BOOL)isSecureData:(NSString *)key { - NSString *storageKey = @""; - - switch (type) { - //Configuration - case MASAccessValueTypeConfiguration: - storageKey = kMASAccessLocalStorageKey; - break; - //AccessToken - case MASAccessValueTypeAccessToken: - storageKey = kMASAccessLocalStorageKey; - break; - //Authenticated username - case MASAccessValueTypeAuthenticatedUserObjectId: - storageKey = kMASAccessSharedStorageKey; - break; - //RefreshToken - case MASAccessValueTypeRefreshToken: - storageKey = kMASAccessLocalStorageKey; - break; - //Scope - case MASAccessValueTypeScope: - storageKey = kMASAccessLocalStorageKey; - break; - //TokenType - case MASAccessValueTypeTokenType: - storageKey = kMASAccessLocalStorageKey; - break; - //ExpiresIn - case MASAccessValueTypeExpiresIn: - storageKey = kMASAccessLocalStorageKey; - break; - //TokenExpiration - case MASAccessValueTypeTokenExpiration: - storageKey = kMASAccessLocalStorageKey; - break; - //IdToken with secured local authentication - case MASAccessValueTypeSecuredIdToken: - storageKey = kMASAccessSharedStorageKey; - break; - //IdToken - case MASAccessValueTypeIdToken: - storageKey = kMASAccessSharedStorageKey; - break; - //IdTokenType - case MASAccessValueTypeIdTokenType: - storageKey = kMASAccessSharedStorageKey; - break; - //ClientExpiration - case MASAccessValueTypeClientExpiration: - storageKey = kMASAccessLocalStorageKey; - break; - //ClientId - case MASAccessValueTypeClientId: - storageKey = kMASAccessLocalStorageKey; - break; - //ClientSecret - case MASAccessValueTypeClientSecret: - storageKey = kMASAccessLocalStorageKey; - break; - //JWT - case MASAccessValueTypeJWT: - storageKey = kMASAccessSharedStorageKey; - break; - //MAGIdentifier - case MASAccessValueTypeMAGIdentifier: - storageKey = kMASAccessSharedStorageKey; - break; - case MASAccessValueTypeMSSOEnabled: - storageKey = kMASAccessSharedStorageKey; - break; - //PrivateKey - case MASAccessValueTypePrivateKey: - storageKey = kMASAccessSharedStorageKey; - break; - case MASAccessValueTypePrivateKeyBits: - storageKey = kMASAccessSharedStorageKey; - break; - //PublicKey - case MASAccessValueTypePublicKey: - storageKey = kMASAccessSharedStorageKey; - break; - //TrustedServerCertificate - case MASAccessValueTypeTrustedServerCertificate: - storageKey = kMASAccessSharedStorageKey; - break; - //PublicCertificate - case MASAccessValueTypeSignedPublicCertificate: - storageKey = kMASAccessSharedStorageKey; - break; - //PublicCertificate as NSData - case MASAccessValueTypeSignedPublicCertificateData: - storageKey = kMASAccessSharedStorageKey; - break; - //PublicCertificate Expiration Date - case MASAccessValueTypeSignedPublicCertificateExpirationDate: - storageKey = kMASAccessSharedStorageKey; - break; - //authentication timestamp - case MASAccessValueTypeAuthenticatedTimestamp: - storageKey = kMASAccessLocalStorageKey; - break; - case MASAccessValueTypeCurrentAuthCredentialsGrantType: - storageKey = kMASAccessSharedStorageKey; - break; - case MASAccessValueTypeIsDeviceLocked: - storageKey = kMASAccessSharedStorageKey; - break; - case MASAccessValueTypeMASUserObjectData: - storageKey = kMASAccessSharedStorageKey; - break; - case MASAccessValueTypeDeviceVendorId: - storageKey = kMASAccessSharedStorageKey; - break; - default: - // - // MASAccessValueTypeUknonw - // - break; - } - - return storageKey; + return [_secureStorageKeys containsObject:key]; } -- (NSString *)convertAccessTypeToString:(MASAccessValueType)type +- (NSString *)getStorageTypeWithKey:(NSString *)key { - - NSString *accessTypeToString = @""; - - switch (type) { - //Configuration - case MASAccessValueTypeConfiguration: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASKeyChainConfiguration"]; - break; - //AccessToken - case MASAccessValueTypeAccessToken: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASKeyChainAccessToken"]; - break; - //Authenticated username - case MASAccessValueTypeAuthenticatedUserObjectId: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"MASAccessValueTypeAuthenticatedUserObjectId"]; - break; - //RefreshToken - case MASAccessValueTypeRefreshToken: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASKeyChainRefreshToken"]; - break; - //Scope - case MASAccessValueTypeScope: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASKeyChainScope"]; - break; - //TokenType - case MASAccessValueTypeTokenType: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASKeyChainTokenType"]; - break; - //ExpiresIn - case MASAccessValueTypeExpiresIn: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASKeyChainExpiresIn"]; - break; - //TokenExpiration - case MASAccessValueTypeTokenExpiration: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASKeyChainTokenExpiration"]; - break; - //IdToken with secured local authentication - case MASAccessValueTypeSecuredIdToken: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASKeyChainSecuredIdToken"]; - break; - //IdToken - case MASAccessValueTypeIdToken: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASKeyChainIdToken"]; - break; - //IdTokenType - case MASAccessValueTypeIdTokenType: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASKeyChainIdTokenType"]; - break; - //ClientExpiration - case MASAccessValueTypeClientExpiration: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASKeyChainClientExpiration"]; - break; - //ClientId - case MASAccessValueTypeClientId: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASKeyChainClientId"]; - break; - //ClientSecret - case MASAccessValueTypeClientSecret: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASKeyChainClientSecret"]; - break; - //JWT - case MASAccessValueTypeJWT: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASKeyChainJwt"]; - break; - //MAGIdentifier - case MASAccessValueTypeMAGIdentifier: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASKeyChainMagIdentifier"]; - break; - case MASAccessValueTypeMSSOEnabled: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASAccessValueTypeMSSOEnabled"]; - break; - //PrivateKey - case MASAccessValueTypePrivateKey: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASKeyChainPrivateKey"]; - break; - //PrivateKeyBits - case MASAccessValueTypePrivateKeyBits: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASKeyChainPrivateKeyBits"]; - break; - //PublicKey - case MASAccessValueTypePublicKey: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASKeyChainPublicKey"]; - break; - //TrustedServerCertificate - case MASAccessValueTypeTrustedServerCertificate: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASKeyChainTrustedServerCertificate"]; - break; - //PublicCertificate - case MASAccessValueTypeSignedPublicCertificate: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASKeyChainSignedPublicCertificate"]; - break; - //PublicCertificate as NSData - case MASAccessValueTypeSignedPublicCertificateData: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASKeyChainSignedPublicCertificateData"]; - break; - //PublicCertificate Expiration Date - case MASAccessValueTypeSignedPublicCertificateExpirationDate: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASAccessValueTypeSignedPublicCertificateExpirationDate"]; - break; - //AuthenticatedTimestamp - case MASAccessValueTypeAuthenticatedTimestamp: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASAccessValueTypeAuthenticatedTimestamp"]; - break; - //IsDeviceLocked: - case MASAccessValueTypeIsDeviceLocked: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASAccessValueTypeIsDeviceLocked"]; - break; - //CurrentAuthCredentialsGrantType - case MASAccessValueTypeCurrentAuthCredentialsGrantType: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, @"kMASAccessValueTypeCurrentAuthCredentialsGrantType"]; - break; - //MASUserObjectData - case MASAccessValueTypeMASUserObjectData: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayHostName, @"kMASAccessValueTypeMASUserObjectData"]; - break; - //DeviceVendorId - case MASAccessValueTypeDeviceVendorId: - accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayHostName, @"kMASKeyChainDeviceVendorId"]; - break; - default: - // - // MASAccessValueTypeUknonw - // - break; + if ([_sharedStorageKeys containsObject:key]) + { + return kMASAccessSharedStorageKey; } - - if (![self isAccessGroupAccessible]) + else if([_localStorageKeys containsObject:key]) { - accessTypeToString = [NSString stringWithFormat:@"_%@", accessTypeToString]; + return kMASAccessLocalStorageKey; + } + // + // If the key is not defined in either of shared nor local storage, the key must be custom data which will always be stored in shared + // + else { + return kMASAccessSharedStorageKey; } - - return accessTypeToString; } @@ -1034,7 +876,7 @@ - (BOOL)lockSession:(NSError * __nullable __autoreleasing * __nullable)error // if (!localError) { - [self setAccessValueString:idToken withAccessValueType:MASAccessValueTypeSecuredIdToken error:&localError]; + [self setAccessValueString:idToken storageKey:MASKeychainStorageKeySecuredIdToken error:&localError]; } } @@ -1048,7 +890,7 @@ - (BOOL)lockSession:(NSError * __nullable __autoreleasing * __nullable)error // if (![MASUser currentUser].isSessionLocked) { - [self setAccessValueString:nil withAccessValueType:MASAccessValueTypeSecuredIdToken]; + [self setAccessValueString:nil storageKey:MASKeychainStorageKeySecuredIdToken]; } if (error != NULL) @@ -1061,10 +903,10 @@ - (BOOL)lockSession:(NSError * __nullable __autoreleasing * __nullable)error // else { - [self setAccessValueString:nil withAccessValueType:MASAccessValueTypeAccessToken]; - [self setAccessValueString:nil withAccessValueType:MASAccessValueTypeRefreshToken]; - [self setAccessValueString:nil withAccessValueType:MASAccessValueTypeIdToken]; - [self setAccessValueNumber:[NSNumber numberWithBool:YES] withAccessValueType:MASAccessValueTypeIsDeviceLocked]; + [self setAccessValueString:nil storageKey:MASKeychainStorageKeyAccessToken]; + [self setAccessValueString:nil storageKey:MASKeychainStorageKeyRefreshToken]; + [self setAccessValueString:nil storageKey:MASKeychainStorageKeyIdToken]; + [self setAccessValueNumber:[NSNumber numberWithBool:YES] storageKey:MASKeychainStorageKeyIsDeviceLocked]; // // Refresh the currentAccessObj to reflect the current status @@ -1120,7 +962,7 @@ - (BOOL)unlockSessionWithUserOperationPromptMessage:(NSString *)userOperationPro // if (!localError) { - idToken = [self getAccessValueStringWithType:MASAccessValueTypeSecuredIdToken userOperationPrompt:userOperationPrompt error:&localError]; + idToken = [self getAccessValueStringWithStorageKey:MASKeychainStorageKeySecuredIdToken userOperationPrompt:userOperationPrompt error:&localError]; } if (idToken) @@ -1129,7 +971,7 @@ - (BOOL)unlockSessionWithUserOperationPromptMessage:(NSString *)userOperationPro // Validate id_token whether it is valid or not // BOOL isIdTokenValid = [MASAccessService validateIdToken:idToken - magIdentifier:[[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeMAGIdentifier] + magIdentifier:[[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyMAGIdentifier] error:&localError]; if (localError && localError.code != MASFoundationErrorCodeTokenIdTokenExpired) @@ -1151,9 +993,9 @@ - (BOOL)unlockSessionWithUserOperationPromptMessage:(NSString *)userOperationPro // if (!localError) { - [self setAccessValueString:idToken withAccessValueType:MASAccessValueTypeIdToken]; - [self setAccessValueString:nil withAccessValueType:MASAccessValueTypeSecuredIdToken]; - [self setAccessValueNumber:[NSNumber numberWithBool:NO] withAccessValueType:MASAccessValueTypeIsDeviceLocked]; + [self setAccessValueString:idToken storageKey:MASKeychainStorageKeyIdToken]; + [self setAccessValueString:nil storageKey:MASKeychainStorageKeySecuredIdToken]; + [self setAccessValueNumber:[NSNumber numberWithBool:NO] storageKey:MASKeychainStorageKeyIsDeviceLocked]; // // Refresh the currentAccessObj to reflect the current status @@ -1175,8 +1017,8 @@ - (BOOL)unlockSessionWithUserOperationPromptMessage:(NSString *)userOperationPro - (void)removeSessionLock { - [self setAccessValueString:nil withAccessValueType:MASAccessValueTypeSecuredIdToken]; - [self setAccessValueNumber:[NSNumber numberWithBool:NO] withAccessValueType:MASAccessValueTypeIsDeviceLocked]; + [self setAccessValueString:nil storageKey:MASKeychainStorageKeySecuredIdToken]; + [self setAccessValueNumber:[NSNumber numberWithBool:NO] storageKey:MASKeychainStorageKeyIsDeviceLocked]; // // Refresh the currentAccessObj to reflect the current status @@ -1223,7 +1065,7 @@ + (BOOL)validateIdToken:(NSString *)idToken magIdentifier:(NSString *)magIdentif [signatureSegments addObject:payload]; NSString *signingInput = [signatureSegments componentsJoinedByString:@"."]; - NSString *clientSecret = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeClientSecret]; + NSString *clientSecret = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyClientSecret]; NSData *signedInput = [NSData sign:signingInput key:clientSecret]; NSString *encodedSignedInput = [signedInput base64Encoding]; @@ -1261,7 +1103,7 @@ + (BOOL)validateIdToken:(NSString *)idToken magIdentifier:(NSString *)magIdentif // // case 2: aud doesn't match with clientId // - if (![aud isEqualToString:[[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeClientId]]){ + if (![aud isEqualToString:[[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyClientId]]){ if (error) { @@ -1393,6 +1235,19 @@ - (NSDate *)extractExpirationDateFromCertificate:(SecCertificateRef)certificate } +- (BOOL)isInternalDataForStorageKey:(NSString *)storageKey +{ + BOOL isInternalData = NO; + + if ([_localStorageKeys containsObject:storageKey] || [_sharedStorageKeys containsObject:storageKey]) + { + isInternalData = YES; + } + + return isInternalData; +} + + # pragma mark - Debug only - (void)clearLocal @@ -1405,13 +1260,13 @@ - (void)clearLocal - (void)clearShared; { - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeMAGIdentifier]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyMAGIdentifier]; [_storages[kMASAccessSharedStorageKey] removeAllItems]; // // Retrieve the key for certificate // - NSString *certificateKey = [self convertAccessTypeToString:MASAccessValueTypeSignedPublicCertificate]; + NSString *certificateKey = [self convertKeyString:MASKeychainStorageKeySignedPublicCertificate]; [[MASIKeyChainStore keyChainStore] clearCertificatesAndIdentitiesWithCertificateLabelKey:certificateKey]; // diff --git a/MASFoundation/Classes/_private_/services/model/MASModelService.m b/MASFoundation/Classes/_private_/services/model/MASModelService.m index 0aa71154..e89189f2 100644 --- a/MASFoundation/Classes/_private_/services/model/MASModelService.m +++ b/MASFoundation/Classes/_private_/services/model/MASModelService.m @@ -155,9 +155,9 @@ - (void)serviceWillStart // if (![keychainApplication.identifier isEqualToString:_currentApplication.identifier]) { - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeClientId]; - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeClientSecret]; - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeClientExpiration]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyClientId]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyClientSecret]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyClientExpiration]; [[MASModelService sharedService] clearCurrentUserForLogout]; } @@ -396,7 +396,7 @@ - (void)retrieveAuthenticationProviders:(MASObjectResponseErrorBlock)completion MASIMutableOrderedDictionary *parameterInfo = [MASIMutableOrderedDictionary new]; // ClientId - parameterInfo[MASClientKeyRequestResponseKey] = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeClientId]; + parameterInfo[MASClientKeyRequestResponseKey] = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyClientId]; // RedirectUri parameterInfo[MASRedirectUriRequestResponseKey] = [[MASApplication currentApplication].redirectUri absoluteString]; @@ -1308,9 +1308,9 @@ - (void)renewClientCertificateWithCompletion:(MASCompletionErrorBlock)completion // // Remove signed client certificate from the keychain storage // - [[MASAccessService sharedService] setAccessValueData:nil withAccessValueType:MASAccessValueTypeSignedPublicCertificateData]; - [[MASAccessService sharedService] setAccessValueCertificate:nil withAccessValueType:MASAccessValueTypeSignedPublicCertificate]; - [[MASAccessService sharedService] setAccessValueNumber:[NSNumber numberWithInt:0] withAccessValueType:MASAccessValueTypeSignedPublicCertificateExpirationDate]; + [[MASAccessService sharedService] setAccessValueData:nil storageKey:MASKeychainStorageKeyPublicCertificateData]; + [[MASAccessService sharedService] setAccessValueCertificate:nil storageKey:MASKeychainStorageKeySignedPublicCertificate]; + [[MASAccessService sharedService] setAccessValueNumber:[NSNumber numberWithInt:0] storageKey:MASKeychainStorageKeyPublicCertificateExpirationDate]; // // Remove device's client MASFile for re-generation @@ -1406,7 +1406,7 @@ - (void)logOutDeviceAndClearLocalAccessToken:(BOOL)clearLocal completion:(MASCom // // Detect if device is already logged out (which is basically checking if id_token exists), if so stop here // - if(![accessService getAccessValueStringWithType:MASAccessValueTypeIdToken]) + if(![accessService getAccessValueStringWithStorageKey:MASKeychainStorageKeyIdToken]) { // // Notify @@ -1444,14 +1444,14 @@ - (void)logOutDeviceAndClearLocalAccessToken:(BOOL)clearLocal completion:(MASCom parameterInfo[MASDeviceLogoutAppRequestResponseKey] = [MASConfiguration currentConfiguration].ssoEnabled ? @"true" : @"false"; // IdToken - NSString *idToken = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeIdToken]; + NSString *idToken = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyIdToken]; if (idToken) { parameterInfo[MASIdTokenBodyRequestResponseKey] = idToken; } // IdTokenType - NSString *idTokenType = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeIdTokenType]; + NSString *idTokenType = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyIdTokenType]; if (idTokenType) { parameterInfo[MASIdTokenTypeBodyRequestResponseKey]= idTokenType; @@ -1508,8 +1508,8 @@ - (void)logOutDeviceAndClearLocalAccessToken:(BOOL)clearLocal completion:(MASCom // // Set id_token and id_token_type to nil // - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeIdToken]; - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeIdTokenType]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyIdToken]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyIdTokenType]; [[MASAccessService sharedService].currentAccessObj refresh]; // @@ -1946,7 +1946,7 @@ - (void)loginAsRefreshTokenWithCompletion:(MASCompletionErrorBlock)completion if(clientAuthorization) headerInfo[MASAuthorizationRequestResponseKey] = clientAuthorization; // MAG Identifier - NSString *magIdentifier = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeMAGIdentifier]; + NSString *magIdentifier = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyMAGIdentifier]; if(magIdentifier) headerInfo[MASMagIdentifierRequestResponseKey] = magIdentifier; // @@ -2015,7 +2015,7 @@ - (void)loginAsRefreshTokenWithCompletion:(MASCompletionErrorBlock)completion // // If authenticate user with refresh_token, we should invalidate local refresh_token, and re-validate the user's session with alternative method. // - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeRefreshToken]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyRefreshToken]; [[MASAccessService sharedService].currentAccessObj refresh]; [blockSelf validateCurrentUserSession:completion]; @@ -2039,7 +2039,7 @@ - (void)loginAsRefreshTokenWithCompletion:(MASCompletionErrorBlock)completion { NSError *idTokenValidationError = nil; BOOL isIdTokenValid = [MASAccessService validateIdToken:[bodayInfo objectForKey:MASIdTokenBodyRequestResponseKey] - magIdentifier:[[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeMAGIdentifier] + magIdentifier:[[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyMAGIdentifier] error:&idTokenValidationError]; if (!isIdTokenValid && idTokenValidationError) diff --git a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m index 209a8a61..c4415cac 100644 --- a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m +++ b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m @@ -603,9 +603,9 @@ - (MASSessionDataTaskCompletionBlock)sessionDataTaskCompletionBlockWithEndPoint: // // Remove slave client_id and client_secret from keychain // - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeClientId]; - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeClientSecret]; - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeClientExpiration]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyClientId]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyClientSecret]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyClientExpiration]; // // Remove access_token from keychain diff --git a/MASFoundation/Classes/_private_/services/network/internal/MASSessionDataTaskOperation.m b/MASFoundation/Classes/_private_/services/network/internal/MASSessionDataTaskOperation.m index 371b3e13..0329c917 100644 --- a/MASFoundation/Classes/_private_/services/network/internal/MASSessionDataTaskOperation.m +++ b/MASFoundation/Classes/_private_/services/network/internal/MASSessionDataTaskOperation.m @@ -75,9 +75,9 @@ - (void)start { NSMutableDictionary *mutableHeader = [self.request.headerInfo mutableCopy]; - if (![[self.request.headerInfo allKeys] containsObject:MASMagIdentifierRequestResponseKey] && [MASDevice currentDevice].isRegistered && [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeMAGIdentifier]) + if (![[self.request.headerInfo allKeys] containsObject:MASMagIdentifierRequestResponseKey] && [MASDevice currentDevice].isRegistered && [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyMAGIdentifier]) { - [mutableHeader setObject:[[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeMAGIdentifier] forKey:MASMagIdentifierRequestResponseKey]; + [mutableHeader setObject:[[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyMAGIdentifier] forKey:MASMagIdentifierRequestResponseKey]; } if (![[self.request.headerInfo allKeys] containsObject:MASAuthorizationRequestResponseKey] && [MASAccessService sharedService].currentAccessObj.accessToken) diff --git a/MASFoundation/Classes/_private_/services/security/MASSecurityService.m b/MASFoundation/Classes/_private_/services/security/MASSecurityService.m index c3d46a1d..56239924 100644 --- a/MASFoundation/Classes/_private_/services/security/MASSecurityService.m +++ b/MASFoundation/Classes/_private_/services/security/MASSecurityService.m @@ -102,7 +102,7 @@ - (void)serviceDidReset - (NSURLCredential *)createUrlCredential { NSArray *identities = [[MASAccessService sharedService] getAccessValueIdentities]; - NSArray *certificates = [[MASAccessService sharedService] getAccessValueCertificateWithType:MASAccessValueTypeSignedPublicCertificate]; + NSArray *certificates = [[MASAccessService sharedService] getAccessValueCertificateWithStorageKey:MASKeychainStorageKeySignedPublicCertificate]; //DLog(@"\n\ncalled and identities is: %@ and certificates is: %@", identities, certificates); @@ -235,7 +235,7 @@ - (NSString *)generateCSRWithUsername:(NSString *)userName // // Store private key bits into keychain // - [[MASAccessService sharedService] setAccessValueString:keyContents withAccessValueType:MASAccessValueTypePrivateKeyBits]; + [[MASAccessService sharedService] setAccessValueString:keyContents storageKey:MASKeychainStorageKeyPrivateKeyBits]; } if (!X509_REQ_sign(req, privatekey, EVP_sha1())) @@ -337,12 +337,12 @@ - (void)generateKeypair // if(privateKeyRef) { - [[MASAccessService sharedService] setAccessValueCryptoKey:privateKeyRef withAccessValueType:MASAccessValueTypePrivateKey]; + [[MASAccessService sharedService] setAccessValueCryptoKey:privateKeyRef storageKey:MASKeychainStorageKeyPrivateKey]; } if(publicKeyRef) { - [[MASAccessService sharedService] setAccessValueCryptoKey:publicKeyRef withAccessValueType:MASAccessValueTypePublicKey]; + [[MASAccessService sharedService] setAccessValueCryptoKey:publicKeyRef storageKey:MASKeychainStorageKeyPublicKey]; } privateKeyRef = NULL; @@ -422,7 +422,7 @@ - (MASFile *)getDeviceClientCertificate if (!signedCert) { - NSData *signedCertificateData = [[MASAccessService sharedService] getAccessValueDataWithType:MASAccessValueTypeSignedPublicCertificateData]; + NSData *signedCertificateData = [[MASAccessService sharedService] getAccessValueDataWithStorageKey:MASKeychainStorageKeyPublicCertificateData]; if (signedCertificateData) { @@ -478,7 +478,7 @@ - (MASFile *)getPrivateKey // // Retrieve privateKeyBits from keychain. // - NSString *privateKeyBits = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypePrivateKeyBits]; + NSString *privateKeyBits = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyPrivateKeyBits]; if (privateKeyBits) { diff --git a/MASFoundation/Classes/models/AuthCredentials/MASAuthCredentialsAuthorizationCode.m b/MASFoundation/Classes/models/AuthCredentials/MASAuthCredentialsAuthorizationCode.m index bc75b7f9..277d3cf1 100644 --- a/MASFoundation/Classes/models/AuthCredentials/MASAuthCredentialsAuthorizationCode.m +++ b/MASFoundation/Classes/models/AuthCredentials/MASAuthCredentialsAuthorizationCode.m @@ -142,13 +142,13 @@ - (NSDictionary *)getParameters MASAccessService *accessService = [MASAccessService sharedService]; // ClientId - NSString *clientId = [accessService getAccessValueStringWithType:MASAccessValueTypeClientId]; + NSString *clientId = [accessService getAccessValueStringWithStorageKey:MASKeychainStorageKeyClientId]; if (clientId) { parameterInfo[MASClientIdentifierRequestResponseKey] = clientId; } - NSString *clientSecret = [accessService getAccessValueStringWithType:MASAccessValueTypeClientSecret]; + NSString *clientSecret = [accessService getAccessValueStringWithStorageKey:MASKeychainStorageKeyClientSecret]; if (clientSecret) { parameterInfo[MASClientSecretRequestResponseKey] = clientSecret; diff --git a/MASFoundation/Classes/models/AuthCredentials/MASAuthCredentialsJWT.m b/MASFoundation/Classes/models/AuthCredentials/MASAuthCredentialsJWT.m index 5c07a31b..93777227 100644 --- a/MASFoundation/Classes/models/AuthCredentials/MASAuthCredentialsJWT.m +++ b/MASFoundation/Classes/models/AuthCredentials/MASAuthCredentialsJWT.m @@ -79,8 +79,8 @@ - (void)loginWithCredential:(MASCompletionErrorBlock)completion // If there is an error from the server complaining about invalid token, // invalidate local id_token and id_token_type and revalidate the user's session. // - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeIdToken]; - [[MASAccessService sharedService] setAccessValueString:nil withAccessValueType:MASAccessValueTypeIdTokenType]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyIdToken]; + [[MASAccessService sharedService] setAccessValueString:nil storageKey:MASKeychainStorageKeyIdTokenType]; [[MASAccessService sharedService].currentAccessObj refresh]; } diff --git a/MASFoundation/Classes/models/MASApplication.m b/MASFoundation/Classes/models/MASApplication.m index 15d7d480..43923b77 100644 --- a/MASFoundation/Classes/models/MASApplication.m +++ b/MASFoundation/Classes/models/MASApplication.m @@ -108,9 +108,9 @@ - (BOOL)isRegistered // MASAccessService *accessService = [MASAccessService sharedService]; - NSNumber *clientExpiration = [accessService getAccessValueNumberWithType:MASAccessValueTypeClientExpiration]; - NSString *clientId = [accessService getAccessValueStringWithType:MASAccessValueTypeClientId]; - NSString *clientSecret = [accessService getAccessValueStringWithType:MASAccessValueTypeClientSecret]; + NSNumber *clientExpiration = [accessService getAccessValueNumberWithStorageKey:MASKeychainStorageKeyClientExpiration]; + NSString *clientId = [accessService getAccessValueStringWithStorageKey:MASKeychainStorageKeyClientId]; + NSString *clientSecret = [accessService getAccessValueStringWithStorageKey:MASKeychainStorageKeyClientSecret]; _isRegistered = (clientExpiration && clientId && clientSecret && !self.isExpired); return _isRegistered; diff --git a/MASFoundation/Classes/models/MASClaims.m b/MASFoundation/Classes/models/MASClaims.m index 2b5d550b..54557475 100644 --- a/MASFoundation/Classes/models/MASClaims.m +++ b/MASFoundation/Classes/models/MASClaims.m @@ -68,8 +68,8 @@ - (id)initPrivate // // Prepare iss // - NSString *magIdentifier = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeMAGIdentifier]; - NSString *clientId = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeClientId]; + NSString *magIdentifier = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyMAGIdentifier]; + NSString *clientId = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyClientId]; if (magIdentifier && clientId) { diff --git a/MASFoundation/Classes/models/MASConfiguration.m b/MASFoundation/Classes/models/MASConfiguration.m index 29cea4b4..268b55d7 100644 --- a/MASFoundation/Classes/models/MASConfiguration.m +++ b/MASFoundation/Classes/models/MASConfiguration.m @@ -774,7 +774,7 @@ - (BOOL)enabledTrustedPublicPKI - (BOOL)ssoEnabled { MASAccessService *accessService = [MASAccessService sharedService]; - NSString *ssoEnabledString = [accessService getAccessValueStringWithType:MASAccessValueTypeMSSOEnabled]; + NSString *ssoEnabledString = [accessService getAccessValueStringWithStorageKey:MASKeychainStorageKeyMSSOEnabled]; if (ssoEnabledString) { @@ -793,7 +793,7 @@ - (void)setSsoEnabled:(BOOL)ssoEnabled { MASAccessService *accessService = [MASAccessService sharedService]; - [accessService setAccessValueString:(ssoEnabled ? @"true":@"false") withAccessValueType:MASAccessValueTypeMSSOEnabled]; + [accessService setAccessValueString:(ssoEnabled ? @"true":@"false") storageKey:MASKeychainStorageKeyMSSOEnabled]; } diff --git a/MASFoundation/Classes/models/MASDevice.m b/MASFoundation/Classes/models/MASDevice.m index ab9e1aee..76cfbb19 100644 --- a/MASFoundation/Classes/models/MASDevice.m +++ b/MASFoundation/Classes/models/MASDevice.m @@ -57,7 +57,7 @@ - (BOOL)isRegistered // MASAccessService *accessService = [MASAccessService sharedService]; - NSString *vendorIdFromKeychain = [accessService getAccessValueStringWithType:MASAccessValueTypeDeviceVendorId]; + NSString *vendorIdFromKeychain = [accessService getAccessValueStringWithStorageKey:MASKeychainStorageKeyDeviceVendorId]; NSString *vendorIdCurrent = [MASDevice deviceVendorId]; // @@ -65,8 +65,8 @@ - (BOOL)isRegistered // if([vendorIdCurrent isEqualToString:vendorIdFromKeychain]) { - NSString *magIdentifier = [accessService getAccessValueStringWithType:MASAccessValueTypeMAGIdentifier]; - NSData *certificateData = [accessService getAccessValueCertificateWithType:MASAccessValueTypeSignedPublicCertificate]; + NSString *magIdentifier = [accessService getAccessValueStringWithStorageKey:MASKeychainStorageKeyMAGIdentifier]; + NSData *certificateData = [accessService getAccessValueCertificateWithStorageKey:MASKeychainStorageKeySignedPublicCertificate]; _isRegistered = (magIdentifier && certificateData); } diff --git a/MASFoundation/Classes/models/MASUser.m b/MASFoundation/Classes/models/MASUser.m index da2b3d3b..f0645db8 100644 --- a/MASFoundation/Classes/models/MASUser.m +++ b/MASFoundation/Classes/models/MASUser.m @@ -42,7 +42,7 @@ + (MASUser *)currentUser + (NSString *_Nullable)authCredentialsType { - NSString *authCredentialsType = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeCurrentAuthCredentialsGrantType]; + NSString *authCredentialsType = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyCurrentAuthCredentialsGrantType]; return authCredentialsType; } @@ -142,7 +142,7 @@ - (BOOL)isCurrentUser // // Get currently authenticated user's object id to make sure that isCurrentUser flag can be determined properly for other users // - NSString *currentlyAuthenticatedUserObjectId = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeAuthenticatedUserObjectId]; + NSString *currentlyAuthenticatedUserObjectId = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyAuthenticatedUserObjectId]; return [self.objectId isEqualToString:currentlyAuthenticatedUserObjectId]; } @@ -154,7 +154,7 @@ - (BOOL)isAuthenticated // // Get currently authenticated user's object id to make sure that isAuthenticated flag can be determined properly for other users // - NSString *currentlyAuthenticatedUserObjectId = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeAuthenticatedUserObjectId]; + NSString *currentlyAuthenticatedUserObjectId = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyAuthenticatedUserObjectId]; // // if the user status is not MASUserStatusNotLoggedIn, @@ -169,7 +169,7 @@ - (BOOL)isSessionLocked // // Get currently authenticated user's object id to make sure that isAuthenticated flag can be determined properly for other users // - NSString *currentlyAuthenticatedUserObjectId = [[MASAccessService sharedService] getAccessValueStringWithType:MASAccessValueTypeAuthenticatedUserObjectId]; + NSString *currentlyAuthenticatedUserObjectId = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyAuthenticatedUserObjectId]; if ([self.objectId isEqualToString:currentlyAuthenticatedUserObjectId]) { @@ -287,7 +287,7 @@ - (void)logoutWithCompletion:(MASCompletionErrorBlock)completion // // Detect if there is id_token // - if([accessService getAccessValueStringWithType:MASAccessValueTypeIdToken]) + if([accessService getAccessValueStringWithStorageKey:MASKeychainStorageKeyIdToken]) { [[MASModelService sharedService] logOutDeviceAndClearLocalAccessToken:YES completion:completion]; } From 940df22db465eeddb99476edf786f439a44200a6 Mon Sep 17 00:00:00 2001 From: James Go Date: Tue, 7 Nov 2017 15:49:27 -0800 Subject: [PATCH 03/30] US416558 : [iOS] SharedStorage API --- MASFoundation.xcodeproj/project.pbxproj | 8 + MASFoundation/Classes/MASConstants.h | 5 + .../_private_/categories/NSError+MASPrivate.m | 5 + .../services/access/MASAccessService.h | 86 +++++-- .../services/access/MASAccessService.m | 132 ++++++++--- .../Classes/models/MASSharedStorage.h | 76 ++++++ .../Classes/models/MASSharedStorage.m | 217 ++++++++++++++++++ MASFoundation/MASFoundation.h | 5 +- 8 files changed, 479 insertions(+), 55 deletions(-) create mode 100644 MASFoundation/Classes/models/MASSharedStorage.h create mode 100644 MASFoundation/Classes/models/MASSharedStorage.m diff --git a/MASFoundation.xcodeproj/project.pbxproj b/MASFoundation.xcodeproj/project.pbxproj index aab8da93..cac3bf9e 100644 --- a/MASFoundation.xcodeproj/project.pbxproj +++ b/MASFoundation.xcodeproj/project.pbxproj @@ -310,6 +310,8 @@ CB1907F91C17950700A5EF16 /* MASAccessService.m in Sources */ = {isa = PBXBuildFile; fileRef = CB1907F71C17950700A5EF16 /* MASAccessService.m */; }; CB1C151E1E450109002B31A5 /* NSURL+MASPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = CB1C151C1E450109002B31A5 /* NSURL+MASPrivate.h */; }; CB1C151F1E450109002B31A5 /* NSURL+MASPrivate.m in Sources */ = {isa = PBXBuildFile; fileRef = CB1C151D1E450109002B31A5 /* NSURL+MASPrivate.m */; }; + CB1FD14B1FB23701000AFA25 /* MASSharedStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = CB1FD1491FB23701000AFA25 /* MASSharedStorage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CB1FD14C1FB23701000AFA25 /* MASSharedStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = CB1FD14A1FB23701000AFA25 /* MASSharedStorage.m */; }; CB2357921F0EF53600D4C420 /* MASURLSessionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = CB2357901F0EF53600D4C420 /* MASURLSessionManager.h */; }; CB2357931F0EF53600D4C420 /* MASURLSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CB2357911F0EF53600D4C420 /* MASURLSessionManager.m */; }; CB2357961F0EFDEA00D4C420 /* MASSessionTaskOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = CB2357941F0EFDEA00D4C420 /* MASSessionTaskOperation.h */; }; @@ -735,6 +737,8 @@ CB1907F71C17950700A5EF16 /* MASAccessService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASAccessService.m; sourceTree = ""; }; CB1C151C1E450109002B31A5 /* NSURL+MASPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURL+MASPrivate.h"; sourceTree = ""; }; CB1C151D1E450109002B31A5 /* NSURL+MASPrivate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURL+MASPrivate.m"; sourceTree = ""; }; + CB1FD1491FB23701000AFA25 /* MASSharedStorage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MASSharedStorage.h; sourceTree = ""; }; + CB1FD14A1FB23701000AFA25 /* MASSharedStorage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MASSharedStorage.m; sourceTree = ""; }; CB2357901F0EF53600D4C420 /* MASURLSessionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASURLSessionManager.h; sourceTree = ""; }; CB2357911F0EF53600D4C420 /* MASURLSessionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASURLSessionManager.m; sourceTree = ""; }; CB2357941F0EFDEA00D4C420 /* MASSessionTaskOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASSessionTaskOperation.h; sourceTree = ""; }; @@ -1342,6 +1346,8 @@ CB14D2181D02266D004F772E /* MASProximityLoginQRCode.m */, CBA3EB2C1E945F2400E64D9D /* MASClaims.h */, CBA3EB2D1E945F2400E64D9D /* MASClaims.m */, + CB1FD1491FB23701000AFA25 /* MASSharedStorage.h */, + CB1FD14A1FB23701000AFA25 /* MASSharedStorage.m */, ); path = models; sourceTree = ""; @@ -1677,6 +1683,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + CB1FD14B1FB23701000AFA25 /* MASSharedStorage.h in Headers */, 69B7DF6A1F9675600056DD3A /* MASRequestBuilder.h in Headers */, 69B7DF681F9675600056DD3A /* MASRequest.h in Headers */, CBAFD24C1F2BD46C0034DF02 /* MASSecurityConfiguration.h in Headers */, @@ -2091,6 +2098,7 @@ CBA3EB2F1E945F2400E64D9D /* MASClaims.m in Sources */, CBD25B151E7A0A9200DFB47F /* MF_Base64Additions.m in Sources */, 10738A3B1C711C2F00B7E87E /* util_mosq.c in Sources */, + CB1FD14C1FB23701000AFA25 /* MASSharedStorage.m in Sources */, 10E027A71F72B10100EAB103 /* RNEncryptor.m in Sources */, 10738A2F1C711C2F00B7E87E /* read_handle.c in Sources */, CB9975571EDF5986006CEBB1 /* MASAuthCredentialsClientCredentials.m in Sources */, diff --git a/MASFoundation/Classes/MASConstants.h b/MASFoundation/Classes/MASConstants.h index 003e0284..963db9f9 100644 --- a/MASFoundation/Classes/MASConstants.h +++ b/MASFoundation/Classes/MASConstants.h @@ -459,6 +459,11 @@ typedef NS_ENUM(NSInteger, MASFoundationErrorCode) MASFoundationErrorCodeJWTUnexpectedClassType = 170002, MASFoundationErrorCodeJWTSerializationError = 170003, + // + // Shared Keychain Storage + // + MASFoundationErrorCodeSharedStorageNotAllowedDataKey = 180001, + MASFoundationErrorCodeCount = -999999 }; diff --git a/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m b/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m index cfd4c0e4..75fc749a 100644 --- a/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m +++ b/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m @@ -1103,6 +1103,11 @@ + (NSString *)descriptionForFoundationErrorCode:(MASFoundationErrorCode)errorCod case MASFoundationErrorCodeJWTUnexpectedClassType: return @"Mis-match of reserved JWT claim value's type (%@)"; case MASFoundationErrorCodeJWTSerializationError: return @"Claim value (%@) cannot be serialized"; + // + // Custom shared keychain storage + // + case MASFoundationErrorCodeSharedStorageNotAllowedDataKey: return @"Data key is reserved, and not allowed to read and/or modify."; + // // Default // diff --git a/MASFoundation/Classes/_private_/services/access/MASAccessService.h b/MASFoundation/Classes/_private_/services/access/MASAccessService.h index cfa4abc5..a498a5e2 100644 --- a/MASFoundation/Classes/_private_/services/access/MASAccessService.h +++ b/MASFoundation/Classes/_private_/services/access/MASAccessService.h @@ -163,7 +163,7 @@ extern NSString * const MASKeychainStorageKeyDeviceVendorId; * Store the certificate as data format into keychain * * @param certificate NSData form of certificate - * @param type MASAccessValueType enum specifying the value key + * @param storageKey NSString value for the data key */ - (void)setAccessValueCertificate:(NSData *)certificate storageKey:(NSString *)storageKey; @@ -172,7 +172,7 @@ extern NSString * const MASKeychainStorageKeyDeviceVendorId; /** * Retrieve the certificate data by the value key * - * @param type MASAccessValueType enum value for key + * @param storageKey NSString value for the data key * * @return Certificate value by the specified value key */ @@ -181,19 +181,32 @@ extern NSString * const MASKeychainStorageKeyDeviceVendorId; /** - * Store NSData of access value into keychain - * - * @param data NSData to store into keychain - * @param type MASAccessValueType enum value for the value key + Store NSData of access value into keychain + + @param data NSData to be stored into keychain + @param storageKey NSString value for the data key + @return BOOL result of operation */ -- (void)setAccessValueData:(NSData *)data storageKey:(NSString *)storageKey; +- (BOOL)setAccessValueData:(NSData *)data storageKey:(NSString *)storageKey; + + + +/** + Store NSData of access value into keychain + + @param data NSData to be stored into keychain + @param storageKey NSString value for the data key + @param error NSError reference object to notify if there is any error while keychain operation + @return BOOL result of operation + */ +- (BOOL)setAccessValueData:(NSData *)data storageKey:(NSString *)storageKey error:(NSError **)error; /** * Retrieve NSData of access value from keychain * - * @param type MASAccessValueType enum value for the value key + * @param storageKey NSString value for the data key * * @return NSData of the access data by the specified value key */ @@ -201,20 +214,44 @@ extern NSString * const MASKeychainStorageKeyDeviceVendorId; +/** + Retrieve NSData of access value from keychain + + @param storageKey NSString value for the data key + @param error NSError reference object to notify if there is any error while keychain operation + @return NSData of the access data by the specified value key + */ +- (NSData *)getAccessValueDataWithStorageKey:(NSString *)storageKey error:(NSError **)error; + + + /** * Store NSString of access value into keychain * * @param string NSString to store into keychain - * @param type MASAccessValueType enum value for the value key + * @param storageKey NSString value for the data key + * @return BOOL result of operation + */ +- (BOOL)setAccessValueString:(NSString *)string storageKey:(NSString *)storageKey; + + + +/** + Store NSString of access value into keychain + + @param string NSString to store into keychain + @param storageKey NSString value for the data key + @param error NSError reference object to notify if there is any error while keychain operation + @return BOOL result of operation */ -- (void)setAccessValueString:(NSString *)string storageKey:(NSString *)storageKey; +- (BOOL)setAccessValueString:(NSString *)string storageKey:(NSString *)storageKey error:(NSError **)error; /** * Retrieve NSString of access value from keychain * - * @param type MASAccessValueType enum value for the value key + * @param storageKey NSString value for the data key * * @return NSString of the access data by the specified value key */ @@ -222,20 +259,31 @@ extern NSString * const MASKeychainStorageKeyDeviceVendorId; +/** + Retrieve NSString of access value from keychain + + @param storageKey NSString value for the data key + @param error NSError reference object to notify if there is any error while keychain operation + @return NSString of the access data by the specified value key + */ +- (NSString *)getAccessValueStringWithStorageKey:(NSString *)storageKey error:(NSError **)error; + + + /** * Store NSDictionary of access value into keychain * * @param dictionary NSDictionary to store into keychain - * @param type MASAccessValueType enum value for the value key + * @param storageKey NSString value for the data key */ -- (void)setAccessValueDictionary:(NSDictionary *)dictionary storageKey:(NSString *)storageKey; +- (BOOL)setAccessValueDictionary:(NSDictionary *)dictionary storageKey:(NSString *)storageKey; /** * Retrieve NSDictionary of access value from keychain * - * @param type MASAccessValueType enum value for the value key + * @param storageKey NSString value for the data key * * @return NSDictionary of the access data by the specified value key */ @@ -247,16 +295,16 @@ extern NSString * const MASKeychainStorageKeyDeviceVendorId; * Store NSNumber of access value into keychain * * @param number NSNumber to store into keychain - * @param type MASAccessValueType enum value for the value key + * @param storageKey NSString value for the data key */ -- (void)setAccessValueNumber:(NSNumber *)number storageKey:(NSString *)storageKey; +- (BOOL)setAccessValueNumber:(NSNumber *)number storageKey:(NSString *)storageKey; /** * Retrieve NSNumber of access value from keychain * - * @param type MASAccessValueType enum value for the value key + * @param storageKey NSString value for the data key * * @return NSNumber of the access data by the specified value key */ @@ -272,7 +320,7 @@ extern NSString * const MASKeychainStorageKeyDeviceVendorId; * Other access type value will not be stored. * * @param cryptoKey SecKeyRef to store into keychain - * @param type MASAccessValueType enum value for the value key + * @param storageKey NSString value for the data key */ - (void)setAccessValueCryptoKey:(SecKeyRef)cryptoKey storageKey:(NSString *)storageKey; @@ -285,7 +333,7 @@ extern NSString * const MASKeychainStorageKeyDeviceVendorId; * MASAccessValueTypePublicKey and MASAccessValueTypePrivateKey. * Other access type value will not be retrieved. * - * @param type MASAccessValueType enum value for the value key + * @param storageKey NSString value for the data key * * @return SecKeyRef of the access data by the specified value key */ diff --git a/MASFoundation/Classes/_private_/services/access/MASAccessService.m b/MASFoundation/Classes/_private_/services/access/MASAccessService.m index 468ae48a..184c560d 100644 --- a/MASFoundation/Classes/_private_/services/access/MASAccessService.m +++ b/MASFoundation/Classes/_private_/services/access/MASAccessService.m @@ -25,6 +25,7 @@ static NSString *const kMASAccessSharedStorageKey = @"sharedStorage"; static NSString *const kMASAccessLocalStorageKey = @"localStorage"; +static NSString *const kMASAccessCustomSharedStorageKey = @"customSharedStorage"; static NSString *const kMASAccessIsNotFreshInstallFlag = @"isNotFreshInstall"; @@ -69,6 +70,7 @@ @interface MASAccessService () @property (strong, nonatomic, readwrite) NSString *sharedStorageServiceName; @property (strong, nonatomic, readwrite) NSString *localStorageServiceName; +@property (strong, nonatomic, readwrite) NSString *customSharedStorageServiceName; @property (strong, nonatomic, readwrite) NSString *gatewayHostName; @property (strong, nonatomic, readwrite) NSString *gatewayIdentifier; @@ -194,8 +196,14 @@ - (void)serviceWillStart _gatewayIdentifier = [MASConfiguration currentConfiguration].gatewayUrl.absoluteString; _localStorageServiceName = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, kMASAccessLocalStorageServiceName]; - _sharedStorageServiceName = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, kMASAccessSharedStorageServiceName]; + _customSharedStorageServiceName = [NSString stringWithFormat:@"MAS.%@", kMASAccessCustomSharedStorageKey]; + + // + // Custom shared storage + // + MASIKeyChainStore *customSharedStorage = [MASIKeyChainStore keyChainStoreWithService:_customSharedStorageServiceName]; + customSharedStorage.synchronizable = _isKeychainSynchronizable_; // // Local storage @@ -214,13 +222,13 @@ - (void)serviceWillStart // // storage dictionary property // - _storages = [NSDictionary dictionaryWithObjectsAndKeys:localStorage, kMASAccessLocalStorageKey, sharedStorage, kMASAccessSharedStorageKey, nil]; + _storages = [NSDictionary dictionaryWithObjectsAndKeys:localStorage, kMASAccessLocalStorageKey, sharedStorage, kMASAccessSharedStorageKey, customSharedStorage, kMASAccessCustomSharedStorageKey, nil]; } else { // // storage dictionary property // - _storages = [NSDictionary dictionaryWithObjectsAndKeys:localStorage, kMASAccessLocalStorageKey, localStorage, kMASAccessSharedStorageKey, nil]; + _storages = [NSDictionary dictionaryWithObjectsAndKeys:localStorage, kMASAccessLocalStorageKey, localStorage, kMASAccessSharedStorageKey, customSharedStorage, kMASAccessCustomSharedStorageKey, nil]; } @@ -368,14 +376,21 @@ - (id)getAccessValueCertificateWithStorageKey:(NSString *)storageKey } -- (void)setAccessValueData:(NSData *)data storageKey:(NSString *)storageKey +- (BOOL)setAccessValueData:(NSData *)data storageKey:(NSString *)storageKey +{ + return [self setAccessValueData:data storageKey:storageKey error:nil]; +} + + +- (BOOL)setAccessValueData:(NSData *)data storageKey:(NSString *)storageKey error:(NSError **)error { - NSString *storageType = [self getStorageTypeWithKey:storageKey]; NSString *accessValueAsString = [self convertKeyString:storageKey]; MASIKeyChainStore *destinationStorage = _storages[storageType]; + NSError *operationError = nil; BOOL isSecuredData = [self isSecureData:storageKey]; + BOOL result = NO; if (isSecuredData) { @@ -387,49 +402,69 @@ - (void)setAccessValueData:(NSData *)data storageKey:(NSString *)storageKey // if (data) { - [destinationStorage setData:data forKey:accessValueAsString]; + result = [destinationStorage setData:data forKey:accessValueAsString error:&operationError]; } // // Removal // else { - [destinationStorage removeItemForKey:accessValueAsString]; + result = [destinationStorage removeItemForKey:accessValueAsString error:&operationError]; } if (isSecuredData) { [destinationStorage setAccessibility:MASIKeyChainStoreAccessibilityAfterFirstUnlock authenticationPolicy:0]; } + + if (error) + { + *error = operationError; + } + + return result; } - (NSData *)getAccessValueDataWithStorageKey:(NSString *)storageKey { - + return [self getAccessValueDataWithStorageKey:storageKey error:nil]; +} + + +- (NSData *)getAccessValueDataWithStorageKey:(NSString *)storageKey error:(NSError **)error +{ NSString *storageType = [self getStorageTypeWithKey:storageKey]; NSString *accessValueAsString = [self convertKeyString:storageKey]; MASIKeyChainStore *destinationStorage = _storages[storageType]; + NSError *operationError = nil; + + NSData *keychainData = [destinationStorage dataForKey:accessValueAsString error:&operationError]; + + if (error) + { + *error = operationError; + } - NSData *keychainData = [destinationStorage dataForKey:accessValueAsString]; - return keychainData; } -- (void)setAccessValueString:(NSString *)string storageKey:(NSString *)storageKey +- (BOOL)setAccessValueString:(NSString *)string storageKey:(NSString *)storageKey { - [self setAccessValueString:string storageKey:storageKey error:nil]; + return [self setAccessValueString:string storageKey:storageKey error:nil]; } -- (BOOL)setAccessValueString:(NSString *)string storageKey:(NSString *)storageKey error:(NSError * __nullable __autoreleasing * __nullable)error +- (BOOL)setAccessValueString:(NSString *)string storageKey:(NSString *)storageKey error:(NSError **)error { NSString *storageType = [self getStorageTypeWithKey:storageKey]; NSString *accessValueAsString = [self convertKeyString:storageKey]; MASIKeyChainStore *destinationStorage = _storages[storageType]; + NSError *operationError = nil; + BOOL result = NO; BOOL isSecuredData = [self isSecureData:storageKey]; if (isSecuredData) @@ -442,14 +477,14 @@ - (BOOL)setAccessValueString:(NSString *)string storageKey:(NSString *)storageKe // if (string) { - [destinationStorage setString:string forKey:accessValueAsString error:error]; + result = [destinationStorage setString:string forKey:accessValueAsString error:&operationError]; } // // Removal // else { - [destinationStorage removeItemForKey:accessValueAsString error:error]; + result = [destinationStorage removeItemForKey:accessValueAsString error:&operationError]; } if (isSecuredData) @@ -459,61 +494,73 @@ - (BOOL)setAccessValueString:(NSString *)string storageKey:(NSString *)storageKe if (error) { - return NO; - } - else { - return YES; + *error = operationError; } + + return result; } - (NSString *)getAccessValueStringWithStorageKey:(NSString *)storageKey { - return [self getAccessValueStringWithStorageKey:storageKey error:nil]; } -- (NSString *)getAccessValueStringWithStorageKey:(NSString *)storageKey userOperationPrompt:(NSString *)userOperationPrompt error:(NSError * __nullable __autoreleasing * __nullable)error +- (NSString *)getAccessValueStringWithStorageKey:(NSString *)storageKey userOperationPrompt:(NSString *)userOperationPrompt error:(NSError **)error { NSString *storageType = [self getStorageTypeWithKey:storageKey]; NSString *accessValueAsString = [self convertKeyString:storageKey]; MASIKeyChainStore *destinationStorage = _storages[storageType]; + NSError *operationError = nil; - NSString *securedString = [destinationStorage stringForKey:accessValueAsString userOperationPrompt:userOperationPrompt error:error]; + NSString *securedString = [destinationStorage stringForKey:accessValueAsString userOperationPrompt:userOperationPrompt error:&operationError]; + + if (error) + { + *error = operationError; + } return securedString; } -- (NSString *)getAccessValueStringWithStorageKey:(NSString *)storageKey error:(NSError * __nullable __autoreleasing * __nullable)error +- (NSString *)getAccessValueStringWithStorageKey:(NSString *)storageKey error:(NSError **)error { - NSString *storageType = [self getStorageTypeWithKey:storageKey]; NSString *accessValueAsString = [self convertKeyString:storageKey]; MASIKeyChainStore *destinationStorage = _storages[storageType]; + NSError *operationError = nil; - NSString *securedString = [destinationStorage stringForKey:accessValueAsString error:error]; + NSString *securedString = [destinationStorage stringForKey:accessValueAsString error:&operationError]; + + if (error) + { + *error = operationError; + } return securedString; } -- (void)setAccessValueDictionary:(NSDictionary *)dictionary storageKey:(NSString *)storageKey +- (BOOL)setAccessValueDictionary:(NSDictionary *)dictionary storageKey:(NSString *)storageKey { // // convert dictionary to data // NSData *thisData = [NSKeyedArchiver archivedDataWithRootObject:dictionary]; + BOOL result = NO; // // make sure the data exists // if(thisData) { - [self setAccessValueData:thisData storageKey:storageKey]; + result = [self setAccessValueData:thisData storageKey:storageKey]; } + + return result; } @@ -531,19 +578,22 @@ - (NSDictionary *)getAccessValueDictionaryWithStorageKey:(NSString *)storageKey } -- (void)setAccessValueNumber:(NSNumber *)number storageKey:(NSString *)storageKey +- (BOOL)setAccessValueNumber:(NSNumber *)number storageKey:(NSString *)storageKey { // convert dictionary to data // NSData *thisData = [NSKeyedArchiver archivedDataWithRootObject:number]; + BOOL result = NO; // // make sure the data exists // if(thisData) { - [self setAccessValueData:thisData storageKey:storageKey]; + result = [self setAccessValueData:thisData storageKey:storageKey]; } + + return result; } @@ -699,14 +749,28 @@ + (NSDictionary *)unwrap:(NSString *)data - (NSString *)convertKeyString:(NSString *)key { - NSString *accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, key]; + NSString *accessTypeToString = nil; // - // When access gruop is not accessiable, differentiate the key to make sure there is no conflict of device registration record in the future + // Internal system data // - if (![self isAccessGroupAccessible]) + if ([_sharedStorageKeys containsObject:key] || [_localStorageKeys containsObject:key]) { - accessTypeToString = [NSString stringWithFormat:@"_%@", accessTypeToString]; + accessTypeToString = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, key]; + + // + // When access gruop is not accessiable, differentiate the key to make sure there is no conflict of device registration record in the future + // + if (![self isAccessGroupAccessible]) + { + accessTypeToString = [NSString stringWithFormat:@"_%@", accessTypeToString]; + } + } + // + // External custom data in shared keychain storage + // + else { + accessTypeToString = [NSString stringWithFormat:@"%@.%@", kMASAccessCustomSharedStorageKey, key]; } return accessTypeToString; @@ -733,7 +797,7 @@ - (NSString *)getStorageTypeWithKey:(NSString *)key // If the key is not defined in either of shared nor local storage, the key must be custom data which will always be stored in shared // else { - return kMASAccessSharedStorageKey; + return kMASAccessCustomSharedStorageKey; } } diff --git a/MASFoundation/Classes/models/MASSharedStorage.h b/MASFoundation/Classes/models/MASSharedStorage.h new file mode 100644 index 00000000..dccf4fe1 --- /dev/null +++ b/MASFoundation/Classes/models/MASSharedStorage.h @@ -0,0 +1,76 @@ +// +// MASSharedStorage.h +// MASFoundation +// +// Copyright (c) 2017 CA. All rights reserved. +// +// This software may be modified and distributed under the terms +// of the MIT license. See the LICENSE file for details. +// + +#import + + +/** + MASSharedStorage class is designed for developers to store, and retrieve NSString or NSData data into shared keychain storage, + so that multiple applications with same keychain sharing group in the same device can share data between applications. + + @warning *Important:* there are some of the keys that are reserved by MASFoundation framework which will not store, or retrieve value with the same key. + Key should be generic to its use-case, and any internal system data reserved by MASFoundation framework will not be readable through this class. + */ +@interface MASSharedStorage : MASObject + + + +///-------------------------------------- +/// @name Public +///-------------------------------------- + +# pragma mark - Public + + +/** + Finds NSString data stored with the key from shared keychain storage. + + @param key NSString of the key used to store the NSString data + @param error NSError object reference that would notify if there was any error while retrieving the data + @return NSString of data found with the key + */ ++ (NSString *_Nullable)findStringUsingKey:(NSString *_Nonnull)key error:(NSError * __nullable __autoreleasing * __nullable)error; + + + +/** + Finds NSData object stored with the key from shared keychain storage. + + @param key NSString of the key used to store the NSData object + @param error NSError object reference that would notify if there was any error while retrieving the data + @return NSData of data found with the key + */ ++ (NSData *_Nullable)findDataUsingKey:(NSString *_Nonnull)key error:(NSError * __nullable __autoreleasing * __nullable)error; + + + +/** + Saves NSString data with the specified key into shared keychain storage. + + @param string NSString data to be stored + @param key NSString of the key used to store the NSString data + @param error NSError object reference that would notify if there was any error while storing the data + @return BOOL result of saving operation + */ ++ (BOOL)saveString:(NSString *_Nonnull)string key:(NSString *_Nonnull)key error:(NSError * __nullable __autoreleasing * __nullable)error; + + + +/** + Saves NSData object with the specified key into shared keychain storage. + + @param data NSData object to be stored + @param key NSString of the key used to store the NSData object + @param error NSError object reference that would notify if there was any error while storing the data + @return BOOL result of saving operation + */ ++ (BOOL)saveData:(NSData *_Nonnull)data key:(NSString *_Nonnull)key error:(NSError * __nullable __autoreleasing * __nullable)error; + +@end diff --git a/MASFoundation/Classes/models/MASSharedStorage.m b/MASFoundation/Classes/models/MASSharedStorage.m new file mode 100644 index 00000000..d73bfe83 --- /dev/null +++ b/MASFoundation/Classes/models/MASSharedStorage.m @@ -0,0 +1,217 @@ +// +// MASSharedStorage.m +// MASFoundation +// +// Copyright (c) 2017 CA. All rights reserved. +// +// This software may be modified and distributed under the terms +// of the MIT license. See the LICENSE file for details. +// + +#import "MASSharedStorage.h" + +#import "MASAccessService.h" + +@implementation MASSharedStorage + ++ (NSString *)findStringUsingKey:(NSString *)key error:(NSError **)error +{ + // + // Check if SDK was initialized + // + if ([MAS MASState] != MASStateDidStart) + { + if (error) + { + *error = [NSError errorMASIsNotStarted]; + } + + return nil; + } + + // + // Check if key is reserved for internal system data or not + // + if ([[MASAccessService sharedService] isInternalDataForStorageKey:key]) + { + if (error) + { + *error = [NSError errorForFoundationCode:MASFoundationErrorCodeSharedStorageNotAllowedDataKey errorDomain:MASFoundationErrorDomainLocal]; + } + + return nil; + } + + // + // Retrieve NSString from shared keychain storage + // + NSError *operationError = nil; + NSString *resultString = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:key error:&operationError]; + + // + // If an error occurred while keychain operation, convert it into MASFoundationErrorDomainLocal error object + // + if (operationError) + { + NSError *thisError = [NSError errorWithDomain:MASFoundationErrorDomainLocal code:operationError.code userInfo:@{NSLocalizedDescriptionKey : operationError.localizedDescription}]; + + if (error) + { + *error = thisError; + } + } + + return resultString; +} + + ++ (NSData *)findDataUsingKey:(NSString *)key error:(NSError **)error +{ + // + // Check if SDK was initialized + // + if ([MAS MASState] != MASStateDidStart) + { + if (error) + { + *error = [NSError errorMASIsNotStarted]; + } + + return nil; + } + + // + // Check if key is reserved for internal system data or not + // + if ([[MASAccessService sharedService] isInternalDataForStorageKey:key]) + { + if (error) + { + *error = [NSError errorForFoundationCode:MASFoundationErrorCodeSharedStorageNotAllowedDataKey errorDomain:MASFoundationErrorDomainLocal]; + } + + return nil; + } + + // + // Retrieve NSData from shared keychain storage + // + NSError *operationError = nil; + NSData *resultData = [[MASAccessService sharedService] getAccessValueDataWithStorageKey:key error:&operationError]; + + // + // If an error occurred while keychain operation, convert it into MASFoundationErrorDomainLocal error object + // + if (operationError) + { + NSError *thisError = [NSError errorWithDomain:MASFoundationErrorDomainLocal code:operationError.code userInfo:@{NSLocalizedDescriptionKey : operationError.localizedDescription}]; + + if (error) + { + *error = thisError; + } + } + + return resultData; +} + + ++ (BOOL)saveString:(NSString *)string key:(NSString *)key error:(NSError **)error +{ + // + // Check if SDK was initialized + // + if ([MAS MASState] != MASStateDidStart) + { + if (error) + { + *error = [NSError errorMASIsNotStarted]; + } + + return NO; + } + + // + // Check if key is reserved for internal system data or not + // + if ([[MASAccessService sharedService] isInternalDataForStorageKey:key]) + { + if (error) + { + *error = [NSError errorForFoundationCode:MASFoundationErrorCodeSharedStorageNotAllowedDataKey errorDomain:MASFoundationErrorDomainLocal]; + } + + return NO; + } + + // + // Store NSString into shared keychain storage + // + NSError *operationError = nil; + BOOL result = [[MASAccessService sharedService] setAccessValueString:string storageKey:key error:&operationError]; + + // + // If an error occurred while keychain operation, convert it into MASFoundationErrorDomainLocal error object + // + if (operationError) + { + NSError *thisError = [NSError errorWithDomain:MASFoundationErrorDomainLocal code:operationError.code userInfo:@{NSLocalizedDescriptionKey : operationError.localizedDescription}]; + + if (error) + { + *error = thisError; + } + } + + return result; +} + + ++ (BOOL)saveData:(NSData *)data key:(NSString *)key error:(NSError **)error +{ + // + // Check if SDK was initialized + // + if ([MAS MASState] != MASStateDidStart) + { + if (error) + { + *error = [NSError errorMASIsNotStarted]; + } + + return NO; + } + + // + // Check if key is reserved for internal system data or not + // + if ([[MASAccessService sharedService] isInternalDataForStorageKey:key]) + { + if (error) + { + *error = [NSError errorForFoundationCode:MASFoundationErrorCodeSharedStorageNotAllowedDataKey errorDomain:MASFoundationErrorDomainLocal]; + } + + return NO; + } + + NSError *operationError = nil; + BOOL result = [[MASAccessService sharedService] setAccessValueData:data storageKey:key error:&operationError]; + + // + // If an error occurred while keychain operation, convert it into MASFoundationErrorDomainLocal error object + // + if (operationError) + { + NSError *thisError = [NSError errorWithDomain:MASFoundationErrorDomainLocal code:operationError.code userInfo:@{NSLocalizedDescriptionKey : operationError.localizedDescription}]; + + if (error) + { + *error = thisError; + } + } + + return result; +} + +@end diff --git a/MASFoundation/MASFoundation.h b/MASFoundation/MASFoundation.h index 268dec54..10a69f8c 100644 --- a/MASFoundation/MASFoundation.h +++ b/MASFoundation/MASFoundation.h @@ -47,12 +47,13 @@ FOUNDATION_EXPORT const unsigned char MASFoundationVersionString[]; #import #import #import -#import -#import #import #import #import #import +#import +#import +#import // // AuthCredentials Models From 891ab3d476304e4ead919e301d06332b7929235e Mon Sep 17 00:00:00 2001 From: James Go Date: Tue, 7 Nov 2017 16:07:02 -0800 Subject: [PATCH 04/30] US416558 : [iOS] SharedStorage API --- MASFoundation/Classes/MASConstants.h | 5 -- .../_private_/categories/NSError+MASPrivate.m | 5 -- .../Classes/models/MASSharedStorage.h | 7 +-- .../Classes/models/MASSharedStorage.m | 52 ------------------- 4 files changed, 4 insertions(+), 65 deletions(-) diff --git a/MASFoundation/Classes/MASConstants.h b/MASFoundation/Classes/MASConstants.h index 963db9f9..003e0284 100644 --- a/MASFoundation/Classes/MASConstants.h +++ b/MASFoundation/Classes/MASConstants.h @@ -459,11 +459,6 @@ typedef NS_ENUM(NSInteger, MASFoundationErrorCode) MASFoundationErrorCodeJWTUnexpectedClassType = 170002, MASFoundationErrorCodeJWTSerializationError = 170003, - // - // Shared Keychain Storage - // - MASFoundationErrorCodeSharedStorageNotAllowedDataKey = 180001, - MASFoundationErrorCodeCount = -999999 }; diff --git a/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m b/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m index 75fc749a..cfd4c0e4 100644 --- a/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m +++ b/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m @@ -1103,11 +1103,6 @@ + (NSString *)descriptionForFoundationErrorCode:(MASFoundationErrorCode)errorCod case MASFoundationErrorCodeJWTUnexpectedClassType: return @"Mis-match of reserved JWT claim value's type (%@)"; case MASFoundationErrorCodeJWTSerializationError: return @"Claim value (%@) cannot be serialized"; - // - // Custom shared keychain storage - // - case MASFoundationErrorCodeSharedStorageNotAllowedDataKey: return @"Data key is reserved, and not allowed to read and/or modify."; - // // Default // diff --git a/MASFoundation/Classes/models/MASSharedStorage.h b/MASFoundation/Classes/models/MASSharedStorage.h index dccf4fe1..69867a73 100644 --- a/MASFoundation/Classes/models/MASSharedStorage.h +++ b/MASFoundation/Classes/models/MASSharedStorage.h @@ -12,11 +12,10 @@ /** - MASSharedStorage class is designed for developers to store, and retrieve NSString or NSData data into shared keychain storage, + MASSharedStorage class is designed for developers to write, read, and delete NSString or NSData data into shared keychain storage, so that multiple applications with same keychain sharing group in the same device can share data between applications. - @warning *Important:* there are some of the keys that are reserved by MASFoundation framework which will not store, or retrieve value with the same key. - Key should be generic to its use-case, and any internal system data reserved by MASFoundation framework will not be readable through this class. + @warning *Important:* MASSharedStorage will not be available if MASFoundation framework is not initialized; the framework should be initialized prior to write/read/delete any data into MASSharedStorage. */ @interface MASSharedStorage : MASObject @@ -53,6 +52,7 @@ /** Saves NSString data with the specified key into shared keychain storage. + Save method can also be used to delete the data from the shared keychain storage by passing nil in string parameter with the key. @param string NSString data to be stored @param key NSString of the key used to store the NSString data @@ -65,6 +65,7 @@ /** Saves NSData object with the specified key into shared keychain storage. + Save method can also be used to delete the data from the shared keychain storage by passing nil in data parameter with the key. @param data NSData object to be stored @param key NSString of the key used to store the NSData object diff --git a/MASFoundation/Classes/models/MASSharedStorage.m b/MASFoundation/Classes/models/MASSharedStorage.m index d73bfe83..4f3bdce3 100644 --- a/MASFoundation/Classes/models/MASSharedStorage.m +++ b/MASFoundation/Classes/models/MASSharedStorage.m @@ -29,19 +29,6 @@ + (NSString *)findStringUsingKey:(NSString *)key error:(NSError **)error return nil; } - // - // Check if key is reserved for internal system data or not - // - if ([[MASAccessService sharedService] isInternalDataForStorageKey:key]) - { - if (error) - { - *error = [NSError errorForFoundationCode:MASFoundationErrorCodeSharedStorageNotAllowedDataKey errorDomain:MASFoundationErrorDomainLocal]; - } - - return nil; - } - // // Retrieve NSString from shared keychain storage // @@ -80,19 +67,6 @@ + (NSData *)findDataUsingKey:(NSString *)key error:(NSError **)error return nil; } - // - // Check if key is reserved for internal system data or not - // - if ([[MASAccessService sharedService] isInternalDataForStorageKey:key]) - { - if (error) - { - *error = [NSError errorForFoundationCode:MASFoundationErrorCodeSharedStorageNotAllowedDataKey errorDomain:MASFoundationErrorDomainLocal]; - } - - return nil; - } - // // Retrieve NSData from shared keychain storage // @@ -131,19 +105,6 @@ + (BOOL)saveString:(NSString *)string key:(NSString *)key error:(NSError **)erro return NO; } - // - // Check if key is reserved for internal system data or not - // - if ([[MASAccessService sharedService] isInternalDataForStorageKey:key]) - { - if (error) - { - *error = [NSError errorForFoundationCode:MASFoundationErrorCodeSharedStorageNotAllowedDataKey errorDomain:MASFoundationErrorDomainLocal]; - } - - return NO; - } - // // Store NSString into shared keychain storage // @@ -182,19 +143,6 @@ + (BOOL)saveData:(NSData *)data key:(NSString *)key error:(NSError **)error return NO; } - // - // Check if key is reserved for internal system data or not - // - if ([[MASAccessService sharedService] isInternalDataForStorageKey:key]) - { - if (error) - { - *error = [NSError errorForFoundationCode:MASFoundationErrorCodeSharedStorageNotAllowedDataKey errorDomain:MASFoundationErrorDomainLocal]; - } - - return NO; - } - NSError *operationError = nil; BOOL result = [[MASAccessService sharedService] setAccessValueData:data storageKey:key error:&operationError]; From e09cee9683fcfeb4e3d5717c8c2a6f9cd9158183 Mon Sep 17 00:00:00 2001 From: James Go Date: Thu, 9 Nov 2017 10:40:40 -0800 Subject: [PATCH 05/30] US416558 : [iOS] SharedStorage API --- .../Classes/_private_/services/access/MASAccessService.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MASFoundation/Classes/_private_/services/access/MASAccessService.m b/MASFoundation/Classes/_private_/services/access/MASAccessService.m index 184c560d..343a4c12 100644 --- a/MASFoundation/Classes/_private_/services/access/MASAccessService.m +++ b/MASFoundation/Classes/_private_/services/access/MASAccessService.m @@ -620,11 +620,11 @@ - (void)setAccessValueCryptoKey:(SecKeyRef)cryptoKey storageKey:(NSString *)stor NSString *keyIdentifierStr = nil; - if ([storageType isEqualToString:MASKeychainStorageKeyPublicKey]) + if ([storageKey isEqualToString:MASKeychainStorageKeyPublicKey]) { keyIdentifierStr = [NSString stringWithFormat:@"%@.%@", [MASConfiguration currentConfiguration].gatewayUrl.absoluteString, @"publicKey"]; } - else if ([storageType isEqualToString:MASKeychainStorageKeyPrivateKey]) + else if ([storageKey isEqualToString:MASKeychainStorageKeyPrivateKey]) { keyIdentifierStr = [NSString stringWithFormat:@"%@.%@", [MASConfiguration currentConfiguration].gatewayUrl.absoluteString, @"privateKey"]; } From d932fc96245d55cc825c4d163d22acb7c8c2687f Mon Sep 17 00:00:00 2001 From: James Go Date: Thu, 9 Nov 2017 10:55:48 -0800 Subject: [PATCH 06/30] US416558 : [iOS] SharedStorage API --- MASFoundation/Classes/MASConstants.h | 5 ++ .../_private_/categories/NSError+MASPrivate.m | 5 ++ .../Classes/models/MASSharedStorage.m | 52 +++++++++++++++++++ 3 files changed, 62 insertions(+) diff --git a/MASFoundation/Classes/MASConstants.h b/MASFoundation/Classes/MASConstants.h index 003e0284..2505b83e 100644 --- a/MASFoundation/Classes/MASConstants.h +++ b/MASFoundation/Classes/MASConstants.h @@ -459,6 +459,11 @@ typedef NS_ENUM(NSInteger, MASFoundationErrorCode) MASFoundationErrorCodeJWTUnexpectedClassType = 170002, MASFoundationErrorCodeJWTSerializationError = 170003, + // + // SharedStorage + // + MASFoundationErrorCodeSharedStorageNotNilKey = 180001, + MASFoundationErrorCodeCount = -999999 }; diff --git a/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m b/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m index cfd4c0e4..51ecb6bc 100644 --- a/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m +++ b/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m @@ -1102,6 +1102,11 @@ + (NSString *)descriptionForFoundationErrorCode:(MASFoundationErrorCode)errorCod case MASFoundationErrorCodeJWTInvalidClaims: return @"MASClaims cannot be nil."; case MASFoundationErrorCodeJWTUnexpectedClassType: return @"Mis-match of reserved JWT claim value's type (%@)"; case MASFoundationErrorCodeJWTSerializationError: return @"Claim value (%@) cannot be serialized"; + + // + // Shared Storage + // + case MASFoundationErrorCodeSharedStorageNotNilKey: return @"Data key cannot be nil or empty string."; // // Default diff --git a/MASFoundation/Classes/models/MASSharedStorage.m b/MASFoundation/Classes/models/MASSharedStorage.m index 4f3bdce3..3f1dda9f 100644 --- a/MASFoundation/Classes/models/MASSharedStorage.m +++ b/MASFoundation/Classes/models/MASSharedStorage.m @@ -29,6 +29,19 @@ + (NSString *)findStringUsingKey:(NSString *)key error:(NSError **)error return nil; } + // + // Check for data key + // + if (key == nil || [key length] <= 0) + { + if (error) + { + *error = [NSError errorForFoundationCode:MASFoundationErrorCodeSharedStorageNotNilKey errorDomain:MASFoundationErrorDomainLocal]; + } + + return nil; + } + // // Retrieve NSString from shared keychain storage // @@ -67,6 +80,19 @@ + (NSData *)findDataUsingKey:(NSString *)key error:(NSError **)error return nil; } + // + // Check for data key + // + if (key == nil || [key length] <= 0) + { + if (error) + { + *error = [NSError errorForFoundationCode:MASFoundationErrorCodeSharedStorageNotNilKey errorDomain:MASFoundationErrorDomainLocal]; + } + + return nil; + } + // // Retrieve NSData from shared keychain storage // @@ -105,6 +131,19 @@ + (BOOL)saveString:(NSString *)string key:(NSString *)key error:(NSError **)erro return NO; } + // + // Check for data key + // + if (key == nil || [key length] <= 0) + { + if (error) + { + *error = [NSError errorForFoundationCode:MASFoundationErrorCodeSharedStorageNotNilKey errorDomain:MASFoundationErrorDomainLocal]; + } + + return NO; + } + // // Store NSString into shared keychain storage // @@ -143,6 +182,19 @@ + (BOOL)saveData:(NSData *)data key:(NSString *)key error:(NSError **)error return NO; } + // + // Check for data key + // + if (key == nil || [key length] <= 0) + { + if (error) + { + *error = [NSError errorForFoundationCode:MASFoundationErrorCodeSharedStorageNotNilKey errorDomain:MASFoundationErrorDomainLocal]; + } + + return NO; + } + NSError *operationError = nil; BOOL result = [[MASAccessService sharedService] setAccessValueData:data storageKey:key error:&operationError]; From 7f653ddd3e1da0ae8a358b81114fb01846960ede Mon Sep 17 00:00:00 2001 From: James Go Date: Thu, 9 Nov 2017 13:57:10 -0800 Subject: [PATCH 07/30] US416558 : [iOS] SharedStorage API --- .../_private_/services/access/MASAccessService.m | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/MASFoundation/Classes/_private_/services/access/MASAccessService.m b/MASFoundation/Classes/_private_/services/access/MASAccessService.m index 343a4c12..d7baf115 100644 --- a/MASFoundation/Classes/_private_/services/access/MASAccessService.m +++ b/MASFoundation/Classes/_private_/services/access/MASAccessService.m @@ -202,7 +202,7 @@ - (void)serviceWillStart // // Custom shared storage // - MASIKeyChainStore *customSharedStorage = [MASIKeyChainStore keyChainStoreWithService:_customSharedStorageServiceName]; + MASIKeyChainStore *customSharedStorage = [MASIKeyChainStore keyChainStoreWithService:_customSharedStorageServiceName accessGroup:self.accessGroup]; customSharedStorage.synchronizable = _isKeychainSynchronizable_; // @@ -1366,6 +1366,17 @@ - (NSString *)debugSecuredDescription [keychainDescription appendString:[NSString stringWithFormat:@"\n key: %@", key]]; } + // + // Custom + // + value = [NSString stringWithFormat:@"\n\n Custom (%@):\n", kMASAccessCustomSharedStorageKey]; + [keychainDescription appendString:value]; + + for(NSString *key in [_storages[kMASAccessCustomSharedStorageKey] allKeys]) + { + [keychainDescription appendString:[NSString stringWithFormat:@"\n key: %@", key]]; + } + [keychainDescription appendString:@"\n\n*********************\n\n"]; return keychainDescription; From ac61efffa059701c83cff588784e8b28a77a1b4c Mon Sep 17 00:00:00 2001 From: James Go Date: Thu, 9 Nov 2017 14:13:28 -0800 Subject: [PATCH 08/30] US416558 : [iOS] SharedStorage API --- .../Classes/_private_/services/access/MASAccessService.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MASFoundation/Classes/_private_/services/access/MASAccessService.m b/MASFoundation/Classes/_private_/services/access/MASAccessService.m index d7baf115..1d83c3a4 100644 --- a/MASFoundation/Classes/_private_/services/access/MASAccessService.m +++ b/MASFoundation/Classes/_private_/services/access/MASAccessService.m @@ -648,11 +648,11 @@ - (SecKeyRef)getAccessValueCryptoKeyWithStorageKey:(NSString *)storageKey NSString *keyIdentifierStr = nil; - if ([storageType isEqualToString:MASKeychainStorageKeyPublicKey]) + if ([storageKey isEqualToString:MASKeychainStorageKeyPublicKey]) { keyIdentifierStr = [NSString stringWithFormat:@"%@.%@", [MASConfiguration currentConfiguration].gatewayUrl.absoluteString, @"publicKey"]; } - else if ([storageType isEqualToString:MASKeychainStorageKeyPrivateKey]) + else if ([storageKey isEqualToString:MASKeychainStorageKeyPrivateKey]) { keyIdentifierStr = [NSString stringWithFormat:@"%@.%@", [MASConfiguration currentConfiguration].gatewayUrl.absoluteString, @"privateKey"]; } From 545d1b729aa37971a8859fb65cb86b8eea8d1c21 Mon Sep 17 00:00:00 2001 From: James Go Date: Fri, 10 Nov 2017 13:41:41 -0800 Subject: [PATCH 09/30] US416558 : [iOS] SharedStorage API --- MASFoundation/Classes/_private_/MASConstantsPrivate.h | 5 +++++ .../Classes/_private_/services/access/MASAccessService.m | 2 +- MASFoundation/Classes/models/MASSharedStorage.m | 9 +++++---- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/MASFoundation/Classes/_private_/MASConstantsPrivate.h b/MASFoundation/Classes/_private_/MASConstantsPrivate.h index 3e0ff215..b0c98fe9 100644 --- a/MASFoundation/Classes/_private_/MASConstantsPrivate.h +++ b/MASFoundation/Classes/_private_/MASConstantsPrivate.h @@ -212,6 +212,11 @@ static NSString *_Nonnull const MASGrantTypeRefreshToken = @"refresh_token"; // static int const MASExceptionErrorCodeInvalidCertificate = 9999; // integer +# pragma mark - MASSharedStorage custom prefix + +static NSString *_Nonnull const MASSharedStorageCustomPrefix = @"MAS.customSharedStorage"; + + ///-------------------------------------- /// @name Location Monitoring Constants ///-------------------------------------- diff --git a/MASFoundation/Classes/_private_/services/access/MASAccessService.m b/MASFoundation/Classes/_private_/services/access/MASAccessService.m index 1d83c3a4..26e6d290 100644 --- a/MASFoundation/Classes/_private_/services/access/MASAccessService.m +++ b/MASFoundation/Classes/_private_/services/access/MASAccessService.m @@ -770,7 +770,7 @@ - (NSString *)convertKeyString:(NSString *)key // External custom data in shared keychain storage // else { - accessTypeToString = [NSString stringWithFormat:@"%@.%@", kMASAccessCustomSharedStorageKey, key]; + accessTypeToString = key; } return accessTypeToString; diff --git a/MASFoundation/Classes/models/MASSharedStorage.m b/MASFoundation/Classes/models/MASSharedStorage.m index 3f1dda9f..c7d0916d 100644 --- a/MASFoundation/Classes/models/MASSharedStorage.m +++ b/MASFoundation/Classes/models/MASSharedStorage.m @@ -11,6 +11,7 @@ #import "MASSharedStorage.h" #import "MASAccessService.h" +#import "MASConstantsPrivate.h" @implementation MASSharedStorage @@ -46,7 +47,7 @@ + (NSString *)findStringUsingKey:(NSString *)key error:(NSError **)error // Retrieve NSString from shared keychain storage // NSError *operationError = nil; - NSString *resultString = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:key error:&operationError]; + NSString *resultString = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:[NSString stringWithFormat:@"%@.%@", MASSharedStorageCustomPrefix, key] error:&operationError]; // // If an error occurred while keychain operation, convert it into MASFoundationErrorDomainLocal error object @@ -97,7 +98,7 @@ + (NSData *)findDataUsingKey:(NSString *)key error:(NSError **)error // Retrieve NSData from shared keychain storage // NSError *operationError = nil; - NSData *resultData = [[MASAccessService sharedService] getAccessValueDataWithStorageKey:key error:&operationError]; + NSData *resultData = [[MASAccessService sharedService] getAccessValueDataWithStorageKey:[NSString stringWithFormat:@"%@.%@", MASSharedStorageCustomPrefix, key] error:&operationError]; // // If an error occurred while keychain operation, convert it into MASFoundationErrorDomainLocal error object @@ -148,7 +149,7 @@ + (BOOL)saveString:(NSString *)string key:(NSString *)key error:(NSError **)erro // Store NSString into shared keychain storage // NSError *operationError = nil; - BOOL result = [[MASAccessService sharedService] setAccessValueString:string storageKey:key error:&operationError]; + BOOL result = [[MASAccessService sharedService] setAccessValueString:string storageKey:[NSString stringWithFormat:@"%@.%@", MASSharedStorageCustomPrefix, key] error:&operationError]; // // If an error occurred while keychain operation, convert it into MASFoundationErrorDomainLocal error object @@ -196,7 +197,7 @@ + (BOOL)saveData:(NSData *)data key:(NSString *)key error:(NSError **)error } NSError *operationError = nil; - BOOL result = [[MASAccessService sharedService] setAccessValueData:data storageKey:key error:&operationError]; + BOOL result = [[MASAccessService sharedService] setAccessValueData:data storageKey:[NSString stringWithFormat:@"%@.%@", MASSharedStorageCustomPrefix, key] error:&operationError]; // // If an error occurred while keychain operation, convert it into MASFoundationErrorDomainLocal error object From a0d4bd6fb8a1c7a51bc3c1efc06301a6fd6bc5a3 Mon Sep 17 00:00:00 2001 From: Kaylie Son Date: Tue, 14 Nov 2017 12:56:31 -0800 Subject: [PATCH 10/30] US416558 : [iOS] SharedStorage API --- .../models/MASApplication+MASPrivate.m | 32 ++++++------- .../_private_/models/MASUser+MASPrivate.m | 46 +++++++++++++------ .../services/access/MASAccessService.m | 37 +++++++++------ .../services/security/MASSecurityService.m | 12 ++--- MASFoundation/Classes/models/MASDevice.m | 4 +- MASFoundation/Classes/models/MASUser.m | 2 +- 6 files changed, 79 insertions(+), 54 deletions(-) diff --git a/MASFoundation/Classes/_private_/models/MASApplication+MASPrivate.m b/MASFoundation/Classes/_private_/models/MASApplication+MASPrivate.m index d112574e..8c4a9d2f 100644 --- a/MASFoundation/Classes/_private_/models/MASApplication+MASPrivate.m +++ b/MASFoundation/Classes/_private_/models/MASApplication+MASPrivate.m @@ -57,13 +57,13 @@ - (id)initWithConfiguration MASAccessService *accessService = [MASAccessService sharedService]; NSData *trustedServerCertificate = [accessService getAccessValueDataWithStorageKey:MASKeychainStorageKeyTrustedServerCertificate]; - if(!trustedServerCertificate) + if (!trustedServerCertificate) { // // Trusted Server Certificate (not sure if this really belongs here, think about that) // NSArray *certificates = [MASConfiguration currentConfiguration].gatewayCertificatesAsPEMData; - if(certificates && certificates.count > 0) + if (certificates && certificates.count > 0) { trustedServerCertificate = certificates[0]; [accessService setAccessValueData:trustedServerCertificate storageKey:MASKeychainStorageKeyTrustedServerCertificate]; @@ -73,7 +73,7 @@ - (id)initWithConfiguration // // If the credentials are NOT dynamic set them here // - if(!configuration.applicationCredentialsAreDynamic) + if (!configuration.applicationCredentialsAreDynamic) { NSDictionary *credentialsFromConfiguration = @ { @@ -107,7 +107,7 @@ + (MASApplication *)instanceFromStorage // Attempt to retrieve from keychain // NSData *data = [[MASIKeyChainStore keyChainStoreWithService:[MASConfiguration currentConfiguration].gatewayUrl.absoluteString] dataForKey:[MASApplication.class description]]; - if(data) + if (data) { application = (MASApplication *)[NSKeyedUnarchiver unarchiveObjectWithData:data]; } @@ -159,14 +159,14 @@ - (void)saveToStorage // Save to the keychain // NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self]; - if(data) + if (data) { NSError *error; [[MASIKeyChainStore keyChainStoreWithService:[MASConfiguration currentConfiguration].gatewayUrl.absoluteString] setData:data forKey:[MASApplication.class description] error:&error]; - if(error) + if (error) { DLog(@"Error attempting to save data: %@", [error localizedDescription]); return; @@ -197,7 +197,7 @@ - (void)saveWithUpdatedInfo:(NSDictionary *)info // Client Expiration // NSNumber *clientExpiration = bodyInfo[MASClientExpirationRequestResponseKey]; - if(clientExpiration) + if (clientExpiration) { [accessService setAccessValueNumber:clientExpiration storageKey:MASKeychainStorageKeyClientExpiration]; } @@ -206,7 +206,7 @@ - (void)saveWithUpdatedInfo:(NSDictionary *)info // Client Key // NSString *clientId = bodyInfo[MASClientKeyRequestResponseKey]; - if(clientId) + if (clientId) { [accessService setAccessValueString:clientId storageKey:MASKeychainStorageKeyClientId]; } @@ -215,7 +215,7 @@ - (void)saveWithUpdatedInfo:(NSDictionary *)info // Client Secret // NSString *clientSecret = bodyInfo[MASClientSecretRequestResponseKey]; - if(clientSecret) + if (clientSecret) { [accessService setAccessValueString:clientSecret storageKey:MASKeychainStorageKeyClientSecret]; } @@ -244,7 +244,7 @@ - (id)initWithEnterpriseInfo:(NSDictionary *)info //DLog(@"\n\ncalled with info: %@\n\n", info); self = [super init]; - if(self) + if (self) { [self setValue:info[MASApplicationIdRequestResponseKey] forKey:@"identifier"]; [self setValue:info[MASApplicationNameRequestResponseKey] forKey:@"name"]; @@ -268,7 +268,7 @@ + (NSDate *)expirationAsDate MASAccessService *accessService = [MASAccessService sharedService]; NSNumber *clientExpiration = [accessService getAccessValueNumberWithStorageKey:MASKeychainStorageKeyClientExpiration]; - if(!clientExpiration) + if (!clientExpiration) { return nil; } @@ -316,7 +316,7 @@ - (BOOL)isExpired // // Expiration is nil, then it is considered expired // - if(!clientExpiration) + if (!clientExpiration) { isExpired = YES; } @@ -325,7 +325,7 @@ - (BOOL)isExpired // If the value is zero AND both the client id and secret are set then it is not expired and // the expiry is actually infinite // - else if([clientExpiration doubleValue] == 0 && clientId && clientSecret) + else if ([clientExpiration doubleValue] == 0 && clientId && clientSecret) { isExpired = NO; } @@ -333,7 +333,7 @@ - (BOOL)isExpired // // If a positive time interval remains compared to the current time and date then it is not expired // - else if([[MASApplication expirationAsDate] timeIntervalSinceNow] > 0) + else if ([[MASApplication expirationAsDate] timeIntervalSinceNow] > 0) { isExpired = NO; } @@ -348,7 +348,7 @@ - (NSString *)authenticationStatusAsString // // Detect status and respond appropriately // - switch([self authenticationStatus]) + switch ([self authenticationStatus]) { // // Not Logged In @@ -381,7 +381,7 @@ - (NSString *)scopeTypeToString:(MASScopeType)scopeType // // Detect type and respond appropriately // - switch(scopeType) + switch (scopeType) { // // OpenId diff --git a/MASFoundation/Classes/_private_/models/MASUser+MASPrivate.m b/MASFoundation/Classes/_private_/models/MASUser+MASPrivate.m index 131b9a33..567efc1f 100644 --- a/MASFoundation/Classes/_private_/models/MASUser+MASPrivate.m +++ b/MASFoundation/Classes/_private_/models/MASUser+MASPrivate.m @@ -29,7 +29,7 @@ @implementation MASUser (MASPrivate) - (id)initWithInfo:(NSDictionary *)info { self = [super init]; - if(self) + if (self) { [self saveWithUpdatedInfo:info]; } @@ -48,7 +48,7 @@ + (MASUser *)instanceFromStorage NSData *data = [[MASAccessService sharedService] getAccessValueDataWithStorageKey:MASKeychainStorageKeyMASUserObjectData]; - if(data) + if (data) { user = (MASUser *)[NSKeyedUnarchiver unarchiveObjectWithData:data]; } @@ -63,7 +63,7 @@ - (void)saveToStorage // Save to the keychain // NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self]; - if(data) + if (data) { [[MASAccessService sharedService] setAccessValueData:data storageKey:MASKeychainStorageKeyMASUserObjectData]; } @@ -88,13 +88,19 @@ - (void)saveWithUpdatedInfo:(NSDictionary *)info // Uid --> ObjectId // NSString *uid = bodyInfo[MASUserPreferredNameRequestResponseKey]; - if(uid && ![uid isKindOfClass:[NSNull class]]) [self setValue:uid forKey:@"objectId"]; + if (uid && ![uid isKindOfClass:[NSNull class]]) + { + [self setValue:uid forKey:@"objectId"]; + } // // Preferred UserName // NSString *userName = bodyInfo[MASUserPreferredNameRequestResponseKey]; - if(userName && ![userName isKindOfClass:[NSNull class]]) [self setValue:userName forKey:@"userName"]; + if (userName && ![userName isKindOfClass:[NSNull class]]) + { + [self setValue:userName forKey:@"userName"]; + } // // Family Name @@ -116,24 +122,33 @@ - (void)saveWithUpdatedInfo:(NSDictionary *)info NSMutableString *mutableCopy = [NSMutableString new]; // Given name, if any - if(self.givenName && ![self.givenName isKindOfClass:[NSNull class]]) [mutableCopy appendString:self.givenName]; + if (self.givenName && ![self.givenName isKindOfClass:[NSNull class]]) + { + [mutableCopy appendString:self.givenName]; + } // Family name, if any - if(self.familyName && ![self.familyName isKindOfClass:[NSNull class]]) + if (self.familyName && ![self.familyName isKindOfClass:[NSNull class]]) { // Check if there was a given name first, if so add a space - if(mutableCopy.length > 0) [mutableCopy appendString:MASDefaultEmptySpace]; + if (mutableCopy.length > 0) + { + [mutableCopy appendString:MASDefaultEmptySpace]; + } [mutableCopy appendString:self.familyName]; } - if(mutableCopy.length > 0) [self setValue:mutableCopy forKey:@"formattedName"]; + if (mutableCopy.length > 0) + { + [self setValue:mutableCopy forKey:@"formattedName"]; + } // // Email Addresses // NSString *emailValue = bodyInfo[MASUserEmailRequestResponseKey]; - if(emailValue && ![emailValue isKindOfClass:[NSNull class]]) + if (emailValue && ![emailValue isKindOfClass:[NSNull class]]) { [self setValue:@{ MASInfoTypeWork : emailValue } forKey:@"emailAddresses"]; } @@ -142,7 +157,7 @@ - (void)saveWithUpdatedInfo:(NSDictionary *)info // Phone Numbers // NSString *phoneValue = bodyInfo[MASUserPhoneRequestResponseKey]; - if(phoneValue && ![phoneValue isKindOfClass:[NSNull class]]) + if (phoneValue && ![phoneValue isKindOfClass:[NSNull class]]) { [self setValue:@{ MASInfoTypeWork : phoneValue } forKey:@"phoneNumbers"]; } @@ -151,7 +166,7 @@ - (void)saveWithUpdatedInfo:(NSDictionary *)info // Addresses // NSDictionary *addressInfo = bodyInfo[MASUserAddressRequestResponseKey]; - if(addressInfo && ![addressInfo isKindOfClass:[NSNull class]]) + if (addressInfo && ![addressInfo isKindOfClass:[NSNull class]]) { [self setValue:@{ MASInfoTypeWork : addressInfo } forKey:@"addresses"]; } @@ -160,7 +175,7 @@ - (void)saveWithUpdatedInfo:(NSDictionary *)info // Picture // NSString *imageUriAsString = bodyInfo[MASUserPictureRequestResponseKey]; - if(imageUriAsString && ![imageUriAsString isKindOfClass:[NSNull class]]) + if (imageUriAsString && ![imageUriAsString isKindOfClass:[NSNull class]]) { NSURL *imageUrl = [NSURL URLWithString:imageUriAsString]; NSData *imageData = [NSData dataWithContentsOfURL:imageUrl]; @@ -223,7 +238,10 @@ - (void)setWasLoggedOffAndSave:(BOOL)wasLoggedOff // // If was logged off remove the keychain stored values // - if(wasLoggedOff) [self resetPartial]; + if (wasLoggedOff) + { + [self resetPartial]; + } // // Save diff --git a/MASFoundation/Classes/_private_/services/access/MASAccessService.m b/MASFoundation/Classes/_private_/services/access/MASAccessService.m index 26e6d290..503b067b 100644 --- a/MASFoundation/Classes/_private_/services/access/MASAccessService.m +++ b/MASFoundation/Classes/_private_/services/access/MASAccessService.m @@ -301,7 +301,7 @@ - (void)saveAccessValuesWithDictionary:(NSDictionary *)dictionary forceToOverwri // // if the user chooses to overwite whatever SDK contains with the provided dictionary, reset the object // - if(forceToOverwrite) + if (forceToOverwrite) { [_currentAccessObj reset]; _currentAccessObj = nil; @@ -555,7 +555,7 @@ - (BOOL)setAccessValueDictionary:(NSDictionary *)dictionary storageKey:(NSString // // make sure the data exists // - if(thisData) + if (thisData) { result = [self setAccessValueData:thisData storageKey:storageKey]; } @@ -588,7 +588,7 @@ - (BOOL)setAccessValueNumber:(NSNumber *)number storageKey:(NSString *)storageKe // // make sure the data exists // - if(thisData) + if (thisData) { result = [self setAccessValueData:thisData storageKey:storageKey]; } @@ -789,7 +789,7 @@ - (NSString *)getStorageTypeWithKey:(NSString *)key { return kMASAccessSharedStorageKey; } - else if([_localStorageKeys containsObject:key]) + else if ([_localStorageKeys containsObject:key]) { return kMASAccessLocalStorageKey; } @@ -837,7 +837,7 @@ - (NSString *)accessGroup // // if accessGroup is not defined // - if(!_accessGroup) + if (!_accessGroup) { NSString *groupSuffix = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"MSSOSDKKeychainGroup"]; @@ -1119,7 +1119,8 @@ + (BOOL)validateIdToken:(NSString *)idToken magIdentifier:(NSString *)magIdentif // NSDictionary *headerDisctionary = [MASAccessService unwrap:headerString]; - if ([[headerDisctionary objectForKey:@"alg"] isEqualToString:@"HS256"]){ + if ([[headerDisctionary objectForKey:@"alg"] isEqualToString:@"HS256"]) + { // // check signature @@ -1155,7 +1156,8 @@ + (BOOL)validateIdToken:(NSString *)idToken magIdentifier:(NSString *)magIdentif NSString *azp = [payloadDictionary valueForKey:@"azp"]; NSDate *exp = [NSDate dateWithTimeIntervalSince1970:[[payloadDictionary valueForKey:@"exp"] floatValue]]; - if (!aud || !azp || !exp){ + if (!aud || !azp || !exp) + { if (error) { @@ -1167,7 +1169,8 @@ + (BOOL)validateIdToken:(NSString *)idToken magIdentifier:(NSString *)magIdentif // // case 2: aud doesn't match with clientId // - if (![aud isEqualToString:[[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyClientId]]){ + if (![aud isEqualToString:[[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyClientId]]) + { if (error) { @@ -1179,7 +1182,8 @@ + (BOOL)validateIdToken:(NSString *)idToken magIdentifier:(NSString *)magIdentif // // case 3: azp doesn't match with mag-identifier // - if (![azp isEqualToString:magIdentifier]){ + if (![azp isEqualToString:magIdentifier]) + { if (error) { @@ -1191,7 +1195,8 @@ + (BOOL)validateIdToken:(NSString *)idToken magIdentifier:(NSString *)magIdentif // // case 4: JWT expired // - if ([exp timeIntervalSinceNow] < 0){ + if ([exp timeIntervalSinceNow] < 0) + { if (error) { @@ -1264,9 +1269,11 @@ - (NSDate *)extractExpirationDateFromCertificate:(SecCertificateRef)certificate if (certificateX509 != NULL) { ASN1_TIME *certificateExpiryASN1 = X509_get_notAfter(certificateX509); - if (certificateExpiryASN1 != NULL) { + if (certificateExpiryASN1 != NULL) + { ASN1_GENERALIZEDTIME *certificateExpiryASN1Generalized = ASN1_TIME_to_generalizedtime(certificateExpiryASN1, NULL); - if (certificateExpiryASN1Generalized != NULL) { + if (certificateExpiryASN1Generalized != NULL) + { unsigned char *certificateExpiryData = ASN1_STRING_data(certificateExpiryASN1Generalized); // ASN1 generalized times look like this: "20131114230046Z" @@ -1350,7 +1357,7 @@ - (NSString *)debugSecuredDescription NSString *value = [NSString stringWithFormat:@"\n\n(MASAccessService)\n\n Local (%@):\n", kMASAccessLocalStorageServiceName]; NSMutableString *keychainDescription = [[NSMutableString alloc] initWithString:value]; - for(NSString *key in [_storages[kMASAccessLocalStorageKey] allKeys]) + for (NSString *key in [_storages[kMASAccessLocalStorageKey] allKeys]) { [keychainDescription appendString:[NSString stringWithFormat:@"\n key: %@", key]]; } @@ -1361,7 +1368,7 @@ - (NSString *)debugSecuredDescription value = [NSString stringWithFormat:@"\n\n Shared (%@):\n", kMASAccessSharedStorageServiceName]; [keychainDescription appendString:value]; - for(NSString *key in [_storages[kMASAccessSharedStorageKey] allKeys]) + for (NSString *key in [_storages[kMASAccessSharedStorageKey] allKeys]) { [keychainDescription appendString:[NSString stringWithFormat:@"\n key: %@", key]]; } @@ -1372,7 +1379,7 @@ - (NSString *)debugSecuredDescription value = [NSString stringWithFormat:@"\n\n Custom (%@):\n", kMASAccessCustomSharedStorageKey]; [keychainDescription appendString:value]; - for(NSString *key in [_storages[kMASAccessCustomSharedStorageKey] allKeys]) + for (NSString *key in [_storages[kMASAccessCustomSharedStorageKey] allKeys]) { [keychainDescription appendString:[NSString stringWithFormat:@"\n key: %@", key]]; } diff --git a/MASFoundation/Classes/_private_/services/security/MASSecurityService.m b/MASFoundation/Classes/_private_/services/security/MASSecurityService.m index 56239924..465c5404 100644 --- a/MASFoundation/Classes/_private_/services/security/MASSecurityService.m +++ b/MASFoundation/Classes/_private_/services/security/MASSecurityService.m @@ -140,7 +140,7 @@ - (void)deleteAsymmetricKeys // Delete the private key // sanityCheck = SecItemDelete((__bridge CFDictionaryRef)queryPrivateKey); - if(!(sanityCheck == noErr || sanityCheck == errSecItemNotFound)) + if (!(sanityCheck == noErr || sanityCheck == errSecItemNotFound)) { DLog(@"Error removing private key, OSStatus == %d.", (int)sanityCheck ); } @@ -149,7 +149,7 @@ - (void)deleteAsymmetricKeys // Delete the public key // sanityCheck = SecItemDelete((__bridge CFDictionaryRef)queryPublicKey); - if(!(sanityCheck == noErr || sanityCheck == errSecItemNotFound)) + if (!(sanityCheck == noErr || sanityCheck == errSecItemNotFound)) { DLog(@"Error removing public key, OSStatus == %d.", (int)sanityCheck ); } @@ -226,7 +226,7 @@ - (NSString *)generateCSRWithUsername:(NSString *)userName // // Store new value in keychain // - if(privateKeyBits) + if (privateKeyBits) { NSString *keyContents = [self evpKeyToString:privatekey]; @@ -327,7 +327,7 @@ - (void)generateKeypair [keyPairAttr setObject:publicKeyAttr forKey:(__bridge id)kSecPublicKeyAttrs]; sanityCheck = SecKeyGeneratePair((__bridge CFDictionaryRef)keyPairAttr, &publicKeyRef, &privateKeyRef); - if(!( sanityCheck == noErr && publicKeyRef != NULL && privateKeyRef != NULL)) + if (!( sanityCheck == noErr && publicKeyRef != NULL && privateKeyRef != NULL)) { DLog(@"Error with something really bad went wrong with generating the key pair"); } @@ -335,12 +335,12 @@ - (void)generateKeypair // // Storing privateKey and publicKey into keychain // - if(privateKeyRef) + if (privateKeyRef) { [[MASAccessService sharedService] setAccessValueCryptoKey:privateKeyRef storageKey:MASKeychainStorageKeyPrivateKey]; } - if(publicKeyRef) + if (publicKeyRef) { [[MASAccessService sharedService] setAccessValueCryptoKey:publicKeyRef storageKey:MASKeychainStorageKeyPublicKey]; } diff --git a/MASFoundation/Classes/models/MASDevice.m b/MASFoundation/Classes/models/MASDevice.m index 76cfbb19..2c1c1414 100644 --- a/MASFoundation/Classes/models/MASDevice.m +++ b/MASFoundation/Classes/models/MASDevice.m @@ -63,7 +63,7 @@ - (BOOL)isRegistered // // Check if the vendorId in Keychain macth with current vendorId // - if([vendorIdCurrent isEqualToString:vendorIdFromKeychain]) + if ([vendorIdCurrent isEqualToString:vendorIdFromKeychain]) { NSString *magIdentifier = [accessService getAccessValueStringWithStorageKey:MASKeychainStorageKeyMAGIdentifier]; NSData *certificateData = [accessService getAccessValueCertificateWithStorageKey:MASKeychainStorageKeySignedPublicCertificate]; @@ -215,7 +215,7 @@ - (void)encodeWithCoder:(NSCoder *)aCoder - (id)initWithCoder:(NSCoder *)aDecoder { - if(self = [super initWithCoder:aDecoder]) + if (self = [super initWithCoder:aDecoder]) { [self setValue:[aDecoder decodeObjectForKey:MASDeviceIdentifierPropertyKey] forKey:@"identifier"]; [self setValue:[aDecoder decodeObjectForKey:MASDeviceNamePropertyKey] forKey:@"name"]; diff --git a/MASFoundation/Classes/models/MASUser.m b/MASFoundation/Classes/models/MASUser.m index f0645db8..9cc8fc67 100644 --- a/MASFoundation/Classes/models/MASUser.m +++ b/MASFoundation/Classes/models/MASUser.m @@ -287,7 +287,7 @@ - (void)logoutWithCompletion:(MASCompletionErrorBlock)completion // // Detect if there is id_token // - if([accessService getAccessValueStringWithStorageKey:MASKeychainStorageKeyIdToken]) + if ([accessService getAccessValueStringWithStorageKey:MASKeychainStorageKeyIdToken]) { [[MASModelService sharedService] logOutDeviceAndClearLocalAccessToken:YES completion:completion]; } From 572f9623d1577baf22cd4a31b2c1ba8dd1bce774 Mon Sep 17 00:00:00 2001 From: Mahendra Nimishakavi Date: Mon, 20 Nov 2017 18:14:03 +0530 Subject: [PATCH 11/30] initial code related to browser based authentication --- MASFoundation.xcodeproj/project.pbxproj | 16 ++ MASFoundation/Classes/MAS.h | 9 + MASFoundation/Classes/MAS.m | 6 + .../categories/UIAlertController+MAS.h | 69 ++++++ .../categories/UIAlertController+MAS.m | 172 ++++++++++++++ .../_private_/services/MASServiceRegistry.h | 11 + .../_private_/services/MASServiceRegistry.m | 15 ++ .../services/model/MASModelService.h | 17 ++ .../services/model/MASModelService.m | 30 ++- .../models/MASBrowserBasedAuthentication.h | 34 +++ .../models/MASBrowserBasedAuthentication.m | 218 ++++++++++++++++++ 11 files changed, 594 insertions(+), 3 deletions(-) create mode 100644 MASFoundation/Classes/_private_/categories/UIAlertController+MAS.h create mode 100644 MASFoundation/Classes/_private_/categories/UIAlertController+MAS.m create mode 100644 MASFoundation/Classes/models/MASBrowserBasedAuthentication.h create mode 100644 MASFoundation/Classes/models/MASBrowserBasedAuthentication.m diff --git a/MASFoundation.xcodeproj/project.pbxproj b/MASFoundation.xcodeproj/project.pbxproj index cac3bf9e..237e62ba 100644 --- a/MASFoundation.xcodeproj/project.pbxproj +++ b/MASFoundation.xcodeproj/project.pbxproj @@ -293,6 +293,10 @@ A4F671331BAFC345000E2223 /* NSString+MASPrivate.m in Sources */ = {isa = PBXBuildFile; fileRef = A4F671311BAFC345000E2223 /* NSString+MASPrivate.m */; }; A858C6651D0978A6001FB9AD /* MASOTPService.h in Headers */ = {isa = PBXBuildFile; fileRef = A858C6631D0978A6001FB9AD /* MASOTPService.h */; }; A858C6661D0978A6001FB9AD /* MASOTPService.m in Sources */ = {isa = PBXBuildFile; fileRef = A858C6641D0978A6001FB9AD /* MASOTPService.m */; }; + C81CC3CC1FC2EA190058718E /* MASBrowserBasedAuthentication.h in Headers */ = {isa = PBXBuildFile; fileRef = C81CC3CA1FC2EA190058718E /* MASBrowserBasedAuthentication.h */; }; + C81CC3CD1FC2EA190058718E /* MASBrowserBasedAuthentication.m in Sources */ = {isa = PBXBuildFile; fileRef = C81CC3CB1FC2EA190058718E /* MASBrowserBasedAuthentication.m */; }; + C81CC3D01FC2EFBB0058718E /* UIAlertController+MAS.h in Headers */ = {isa = PBXBuildFile; fileRef = C81CC3CE1FC2EFBB0058718E /* UIAlertController+MAS.h */; }; + C81CC3D11FC2EFBB0058718E /* UIAlertController+MAS.m in Sources */ = {isa = PBXBuildFile; fileRef = C81CC3CF1FC2EFBB0058718E /* UIAlertController+MAS.m */; }; CB0A8ADF1D01F64F00B1DCCC /* MASProximityLogin.h in Headers */ = {isa = PBXBuildFile; fileRef = CB0A8ADD1D01F64F00B1DCCC /* MASProximityLogin.h */; settings = {ATTRIBUTES = (Public, ); }; }; CB0A8AE01D01F64F00B1DCCC /* MASProximityLogin.m in Sources */ = {isa = PBXBuildFile; fileRef = CB0A8ADE1D01F64F00B1DCCC /* MASProximityLogin.m */; }; CB0B58591E258C2A00BC0163 /* MASAuthorizationResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = CB0B58571E258C2A00BC0163 /* MASAuthorizationResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -720,6 +724,10 @@ A4F671311BAFC345000E2223 /* NSString+MASPrivate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+MASPrivate.m"; sourceTree = ""; }; A858C6631D0978A6001FB9AD /* MASOTPService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASOTPService.h; sourceTree = ""; }; A858C6641D0978A6001FB9AD /* MASOTPService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASOTPService.m; sourceTree = ""; }; + C81CC3CA1FC2EA190058718E /* MASBrowserBasedAuthentication.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MASBrowserBasedAuthentication.h; sourceTree = ""; }; + C81CC3CB1FC2EA190058718E /* MASBrowserBasedAuthentication.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MASBrowserBasedAuthentication.m; sourceTree = ""; }; + C81CC3CE1FC2EFBB0058718E /* UIAlertController+MAS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIAlertController+MAS.h"; sourceTree = ""; }; + C81CC3CF1FC2EFBB0058718E /* UIAlertController+MAS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIAlertController+MAS.m"; sourceTree = ""; }; CB0A8ADD1D01F64F00B1DCCC /* MASProximityLogin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASProximityLogin.h; sourceTree = ""; }; CB0A8ADE1D01F64F00B1DCCC /* MASProximityLogin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASProximityLogin.m; sourceTree = ""; }; CB0B58571E258C2A00BC0163 /* MASAuthorizationResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASAuthorizationResponse.h; sourceTree = ""; }; @@ -1348,6 +1356,8 @@ CBA3EB2D1E945F2400E64D9D /* MASClaims.m */, CB1FD1491FB23701000AFA25 /* MASSharedStorage.h */, CB1FD14A1FB23701000AFA25 /* MASSharedStorage.m */, + C81CC3CA1FC2EA190058718E /* MASBrowserBasedAuthentication.h */, + C81CC3CB1FC2EA190058718E /* MASBrowserBasedAuthentication.m */, ); path = models; sourceTree = ""; @@ -1402,6 +1412,8 @@ A4F6712F1BAFC321000E2223 /* categories */ = { isa = PBXGroup; children = ( + C81CC3CE1FC2EFBB0058718E /* UIAlertController+MAS.h */, + C81CC3CF1FC2EFBB0058718E /* UIAlertController+MAS.m */, CB1907ED1C1794F400A5EF16 /* MASIKeyChainStore+MASPrivate.h */, CB1907EE1C1794F400A5EF16 /* MASIKeyChainStore+MASPrivate.m */, A483C1FF1BE6D0C5007572CE /* CBCentralManager+MASPrivate.h */, @@ -1724,9 +1736,11 @@ 105B2F4B1CA6B3EA0005A2D0 /* ripemd.h in Headers */, A46F49F11C2F5FC500A4C370 /* MASINTULocationRequestDefines.h in Headers */, CB5E4C641C1D1B56001B3B8A /* MASGetURLRequest.h in Headers */, + C81CC3CC1FC2EA190058718E /* MASBrowserBasedAuthentication.h in Headers */, 105B2F471CA6B3EA0005A2D0 /* pqueue.h in Headers */, 105B2F371CA6B3EA0005A2D0 /* kssl.h in Headers */, 105B2F511CA6B3EA0005A2D0 /* srtp.h in Headers */, + C81CC3D01FC2EFBB0058718E /* UIAlertController+MAS.h in Headers */, CBFA70F41F1ED5D6006D025D /* MASSecurityPolicy.h in Headers */, CBD25AF51E78C47C00DFB47F /* JWTCryptoKeyExtractor.h in Headers */, 105B2F5F1CA6B3EA0005A2D0 /* x509_vfy.h in Headers */, @@ -2092,6 +2106,7 @@ A4150EFC1BF16EE200037E27 /* MASKeyChainService.m in Sources */, A47F12811C1D73530008E3F2 /* MASBluetoothPeripheral.m in Sources */, CBD25B061E78C47C00DFB47F /* JWTCoding+VersionThree.m in Sources */, + C81CC3D11FC2EFBB0058718E /* UIAlertController+MAS.m in Sources */, CBD25AED1E78C47C00DFB47F /* JWTAlgorithmDataHolderChain.m in Sources */, A46F49DA1C2F5FC500A4C370 /* MASINetworkActivityIndicatorManager.m in Sources */, A4831AAE1BD1A551007B4AE6 /* MASConfiguration.m in Sources */, @@ -2152,6 +2167,7 @@ A46F49C51C2F5FC500A4C370 /* MASIHTTPRequestOperation.m in Sources */, A4150E701BF1643900037E27 /* MASIJSONResponseSerializer+MASPrivate.m in Sources */, A417BA521BF033C300EC9BCB /* CLLocation+MASPrivate.m in Sources */, + C81CC3CD1FC2EA190058718E /* MASBrowserBasedAuthentication.m in Sources */, 69B7DF6D1F96756B0056DD3A /* MASRequest+MASPrivate.m in Sources */, A4831AB21BD1A551007B4AE6 /* MASFile.m in Sources */, CB0B585A1E258C2A00BC0163 /* MASAuthorizationResponse.m in Sources */, diff --git a/MASFoundation/Classes/MAS.h b/MASFoundation/Classes/MAS.h index 8d290576..1e10044a 100644 --- a/MASFoundation/Classes/MAS.h +++ b/MASFoundation/Classes/MAS.h @@ -110,6 +110,15 @@ + (void)setOTPCredentialsBlock:(MASOTPCredentialsBlock _Nullable)oneTimePassword; +/** + * Sets Bool indicator of Browser Based Authentication (templatized login) enabled or not for authorization process. + * By default, it is disabled. + + @param enable BOOL value indicating whether Browser Based Authentication is enabled or not. + */ ++(void)enableBrowserBasedAuthentication:(BOOL)enable; + + /** * Sets the gateway monitoring block defined by the GatewayMonitorStatusBlock type. diff --git a/MASFoundation/Classes/MAS.m b/MASFoundation/Classes/MAS.m index 6f470ced..98787fd9 100644 --- a/MASFoundation/Classes/MAS.m +++ b/MASFoundation/Classes/MAS.m @@ -92,6 +92,12 @@ + (void)setOTPCredentialsBlock:(MASOTPCredentialsBlock)oneTimePassword } ++(void)enableBrowserBasedAuthentication:(BOOL)enable +{ + [[MASModelService sharedService] setBrowserBasedLogin:enable]; +} + + + (void)setGatewayMonitor:(MASGatewayMonitorStatusBlock)monitor { [MASNetworkingService setGatewayMonitor:monitor]; diff --git a/MASFoundation/Classes/_private_/categories/UIAlertController+MAS.h b/MASFoundation/Classes/_private_/categories/UIAlertController+MAS.h new file mode 100644 index 00000000..7b158d89 --- /dev/null +++ b/MASFoundation/Classes/_private_/categories/UIAlertController+MAS.h @@ -0,0 +1,69 @@ +// +// UIAlertController+MAS.h +// MASFoundation +// +// Created by nimma01 on 11/10/17. +// Copyright © 2017 CA Technologies. All rights reserved. +// + +#import + +@interface UIAlertController (MAS) +///-------------------------------------- +/// @name Authentication Alerts +///------------------------------------- + +# pragma mark - Authentication Alerts + +/** + * Displays on screen an authentication UIAlertController modally in the currently + * visible UIViewController. + */ ++ (void)popupAuthenticationAlert; + + +/** + * Displays on screen an authentication UIAlertController modally in the selected + * UIViewController modally. + * + * @param viewController The UIViewController in which to present the modal UIAlertController. + */ ++ (void)popupAuthenticationAlertInViewController:(UIViewController *)viewController; + + + +///-------------------------------------- +/// @name Error Alerts +///------------------------------------- + +# pragma mark - Error Alerts + +/** + * Displays on screen an error UIAlertController modally in the currently + * visible UIViewController. + */ ++ (void)popupErrorAlert:(NSError *)error; + + +/** + * Displays on screen an error UIAlertController modally in the selected + * UIViewController modally. + * + * @param error The NSError contents to show in the UIAlertController. + * @param viewController The UIViewController in which to present the modal UIAlertController. + */ ++ (void)popupErrorAlert:(NSError *)error inViewController:(UIViewController *)viewController; + + + +///-------------------------------------- +/// @name Public +///------------------------------------- + +# pragma mark - Public + +/** + * Retrieve the currently visible UIViewController. + */ ++ (UIViewController *)rootViewController; +@end diff --git a/MASFoundation/Classes/_private_/categories/UIAlertController+MAS.m b/MASFoundation/Classes/_private_/categories/UIAlertController+MAS.m new file mode 100644 index 00000000..a34df9a5 --- /dev/null +++ b/MASFoundation/Classes/_private_/categories/UIAlertController+MAS.m @@ -0,0 +1,172 @@ +// +// UIAlertController+MAS.m +// MASFoundation +// +// Created by nimma01 on 11/10/17. +// Copyright © 2017 CA Technologies. All rights reserved. +// + +#import "UIAlertController+MAS.h" +#import "MASUser.h" +@implementation UIAlertController (MAS) +# pragma mark - Authentication Alerts + ++ (void)popupAuthenticationAlert +{ + [self popupAuthenticationAlertInViewController:[self rootViewController]]; +} + + ++ (void)popupAuthenticationAlertInViewController:(UIViewController *)viewController +{ + // + // Ensure this is done in the main UI thread. We don't know where the call is coming from + // + dispatch_async(dispatch_get_main_queue(), ^ + { + // + // Create alert controller + // + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Sign In (MASUI)" + message:@"You need to sign in with your user credentials" + preferredStyle:UIAlertControllerStyleAlert]; + + // + // Username text field + // + [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) + { + textField.placeholder = NSLocalizedString(@"username", nil); + }]; + + // + // Password text field + // + [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) + { + textField.placeholder = NSLocalizedString(@"password", nil); + textField.secureTextEntry = YES; + }]; + + // + // OK Action + // + UIAlertAction *okAction = [UIAlertAction + actionWithTitle:NSLocalizedString(@"OK", @"OK action") + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action) + { + UITextField *usernameTextField = alertController.textFields.firstObject; + UITextField *passwordTextField = alertController.textFields.lastObject; + + // + // Attempt to authenticate + // + [MASUser loginWithUserName:usernameTextField.text password:passwordTextField.text completion:^(BOOL completed, NSError *error) { + + DLog(@"viewController received authentication response completed: %@ or error: %@", + (completed ? @"Yes" : @"No"), [error debugDescription]); + + if(error) + { + [UIAlertController popupErrorAlert:error]; + return; + } + }]; + }]; + + [alertController addAction:okAction]; + + // + // Cancel Action + // + UIAlertAction *cancelAction = [UIAlertAction + actionWithTitle:NSLocalizedString(@"Cancel", @"Cancel action") + style:UIAlertActionStyleDefault + handler:nil]; + + [alertController addAction:cancelAction]; + + [viewController presentViewController:alertController animated:YES completion:nil]; + }); +} + + +# pragma mark - Error Alert + ++ (void)popupErrorAlert:(NSError *)error +{ + [self popupErrorAlert:error inViewController:[self rootViewController]]; +} + + ++ (void)popupErrorAlert:(NSError *)error inViewController:(UIViewController *)viewController +{ + // + // Ensure this is done in the main UI thread. We don't know where the call is coming from + // + dispatch_async(dispatch_get_main_queue(), ^ + { + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Error" + message:[error localizedDescription] + preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction *ok = [UIAlertAction actionWithTitle:@"OK" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) + { + [alertController dismissViewControllerAnimated:YES completion:nil]; + }]; + + [alertController addAction:ok]; + + [viewController presentViewController:alertController animated:NO completion:nil]; + }); +} + + ++ (UIViewController *) presentedViewController:(id)viewController +{ + if ([viewController isKindOfClass:[UINavigationController class]]) + { + UINavigationController *navigationController = (UINavigationController *)viewController; + return [self presentedViewController:navigationController.topViewController]; + } + if ([viewController isKindOfClass:[UIViewController class]]) + { + if ([viewController presentedViewController]) + { + if ([[viewController presentedViewController] isKindOfClass:[UINavigationController class]]) + { + UINavigationController *navigationController = (UINavigationController *)[viewController presentedViewController]; + + if (navigationController.isBeingDismissed) + { + return viewController; + } + } + + return [self presentedViewController:[viewController presentedViewController]]; + } + else { + return viewController; + } + } + else if ([viewController isKindOfClass:[UITabBarController class]]) + { + UITabBarController *tabBarController = (UITabBarController *)viewController; + return [self presentedViewController:tabBarController.presentedViewController]; + } + else { + return nil; + } +} + + +# pragma mark - Public + ++ (UIViewController *)rootViewController +{ + return [self presentedViewController:[UIApplication sharedApplication].keyWindow.rootViewController]; +} +@end diff --git a/MASFoundation/Classes/_private_/services/MASServiceRegistry.h b/MASFoundation/Classes/_private_/services/MASServiceRegistry.h index 694f9508..34b5ec54 100644 --- a/MASFoundation/Classes/_private_/services/MASServiceRegistry.h +++ b/MASFoundation/Classes/_private_/services/MASServiceRegistry.h @@ -187,4 +187,15 @@ typedef NS_ENUM(NSInteger, MASRegistryState) - (BOOL)uiServiceWillHandleOTPChannelSelection:(NSArray *)supportedChannels otpGenerationBlock:(MASOTPGenerationBlock)generationBlock; + +/** + * Calling this method will attempt to launch a browser which handles the user authentication steps. + * For this method to handle authentication it requires browser based login to be enabled. + * @see enableBrowserBasedAuthentication + * + * @param bbaLoginBlock The MASCompletionErrorBlock to receive login result. + * @return Return YES if handled, NO if not. + */ +-(BOOL)browserBasedLoginWillHandleAuthentication : (MASCompletionErrorBlock)bbaLoginBlock; + @end diff --git a/MASFoundation/Classes/_private_/services/MASServiceRegistry.m b/MASFoundation/Classes/_private_/services/MASServiceRegistry.m index 9c375214..b0788eeb 100644 --- a/MASFoundation/Classes/_private_/services/MASServiceRegistry.m +++ b/MASFoundation/Classes/_private_/services/MASServiceRegistry.m @@ -15,6 +15,8 @@ #import "MASConfigurationService.h" #import "MASModelService.h" #import "MASService.h" +#import "MASServiceRegistry.h" +#import "MASBrowserBasedAuthentication.h" // @@ -932,4 +934,17 @@ - (BOOL)uiServiceWillHandleOTPChannelSelection:(NSArray *)supportedChannels return YES; } + +-(BOOL)browserBasedLoginWillHandleAuthentication : (MASCompletionErrorBlock)bbaLoginBlock +{ + if(![[MASModelService sharedService] browserBasedLogin]) + { + return NO; + } + + [[MASBrowserBasedAuthentication sharedInstance] loadWebLoginTemplate:bbaLoginBlock]; + return YES; + +} + @end diff --git a/MASFoundation/Classes/_private_/services/model/MASModelService.h b/MASFoundation/Classes/_private_/services/model/MASModelService.h index 50b63377..4155579d 100644 --- a/MASFoundation/Classes/_private_/services/model/MASModelService.h +++ b/MASFoundation/Classes/_private_/services/model/MASModelService.h @@ -82,6 +82,23 @@ - (void)setUserObject:(MASUser *)user; +/** + * Sets the browser based authentication property. Default is NO. + * + * @param browserBasedLogin The state of browser based authentication. + * If this is set to true, a URL which has a templatized login is launched in a browser and this would disable the Social Login, Proximity Login and also prevents the launch of MASUI. + */ +-(void)setBrowserBasedLogin : (BOOL)browserBasedLogin; + + +/** + * The current state of browser based login. + * + * @return BOOL value is returned. + */ +-(BOOL)browserBasedLogin; + + ///-------------------------------------- /// @name Application ///-------------------------------------- diff --git a/MASFoundation/Classes/_private_/services/model/MASModelService.m b/MASFoundation/Classes/_private_/services/model/MASModelService.m index e89189f2..ce60366d 100644 --- a/MASFoundation/Classes/_private_/services/model/MASModelService.m +++ b/MASFoundation/Classes/_private_/services/model/MASModelService.m @@ -29,6 +29,7 @@ @interface MASModelService () @property (nonatomic, strong, readwrite) MASAuthenticationProviders *currentProviders; +@property (nonatomic) BOOL isBrowserBasedLogin; @end @@ -39,7 +40,6 @@ @implementation MASModelService static MASUserLoginWithUserCredentialsBlock _userLoginBlock_ = nil; static MASUserAuthCredentialsBlock _userAuthCredentialsBlock_ = nil; - # pragma mark - Properties @@ -71,6 +71,19 @@ - (void)setUserObject:(MASUser *)user _currentUser = user; } + +-(void)setBrowserBasedLogin : (BOOL)browserBasedLogin +{ + self.isBrowserBasedLogin = browserBasedLogin; +} + + +-(BOOL)browserBasedLogin +{ + return self.isBrowserBasedLogin; +} + + # pragma mark - Shared Service + (instancetype)sharedService @@ -367,7 +380,7 @@ - (void)retrieveAuthenticationProviders:(MASObjectResponseErrorBlock)completion // // If the user was already authenticated, we don't have to retrieve the authentication provider // - if (([MASApplication currentApplication].isAuthenticated && [MASApplication currentApplication].authenticationStatus == MASAuthenticationStatusLoginWithUser) || [MASAccess currentAccess].isSessionLocked) + if (([MASApplication currentApplication].isAuthenticated && [MASApplication currentApplication].authenticationStatus == MASAuthenticationStatusLoginWithUser) || [MASAccess currentAccess].isSessionLocked || self.isBrowserBasedLogin) { // @@ -906,9 +919,15 @@ - (void)registerDeviceWithCompletion:(MASCompletionErrorBlock)completion @"\n\n********************************************************\n\n\n"); // - // If the UI handling framework is present and will handle this stop here + // If the UI handling framework or browser based login is present and will handle this stop here // MASServiceRegistry *serviceRegistry = [MASServiceRegistry sharedRegistry]; + + if([serviceRegistry browserBasedLoginWillHandleAuthentication:completion]) + { + return; + } + if([serviceRegistry uiServiceWillHandleWithAuthCredentialsBlock:authCredentialsBlock]) { return; @@ -1712,6 +1731,11 @@ - (void)loginUsingUserCredentials:(MASCompletionErrorBlock)completion // If the UI handling framework is present and will handle this stop here // MASServiceRegistry *serviceRegistry = [MASServiceRegistry sharedRegistry]; + if([serviceRegistry browserBasedLoginWillHandleAuthentication:completion]) + { + return; + } + if([serviceRegistry uiServiceWillHandleWithAuthCredentialsBlock:authCredentialsBlock]) { return; diff --git a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.h b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.h new file mode 100644 index 00000000..e0b79d3c --- /dev/null +++ b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.h @@ -0,0 +1,34 @@ +// +// MASBrowserBasedAuthentication.h +// MASFoundation +// +// Created by nimma01 on 20/11/17. +// Copyright © 2017 CA Technologies. All rights reserved. +// + +#import +#import "MASConstants.h" + +@interface MASBrowserBasedAuthentication : NSObject +{ + +} + + +/** + * Retrieve the shared MASBrowserBasedAuthentication singleton. + * + * @return Returns the shared MASBrowserBasedAuthentication singleton. + */ ++ (instancetype)sharedInstance; + + + +/** + * Method to load the browser with a URL that loads a templatized login page. + * + * @param webLoginBlock completion MASCompletionErrorBlock that receives the results. + */ +-(void)loadWebLoginTemplate : (MASCompletionErrorBlock)webLoginBlock; + +@end diff --git a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m new file mode 100644 index 00000000..a303bf7b --- /dev/null +++ b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m @@ -0,0 +1,218 @@ +// +// MASBrowserBasedAuthentication.m +// MASFoundation +// +// Created by nimma01 on 20/11/17. +// Copyright © 2017 CA Technologies. All rights reserved. +// + +#import "MASBrowserBasedAuthentication.h" +#import +#import "MASAuthorizationResponse.h" +#import "UIAlertController+MAS.h" +#import "MASConfigurationService.h" +#import "MASAccessService.h" +#import "MASGetURLRequest.h" +#import "MASModelService.h" + +@interface MASBrowserBasedAuthentication () +{ + +} + +@property (nonatomic) SFSafariViewController* safariViewController; +@property (nonatomic) MASCompletionErrorBlock webLoginCallBack; + +@end + +@implementation MASBrowserBasedAuthentication + + +# pragma mark - Shared Service + ++ (instancetype)sharedInstance +{ + static id sharedInstance = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^ + { + sharedInstance = [[MASBrowserBasedAuthentication alloc] init]; + }); + + return sharedInstance; +} + + +-(void)loadWebLoginTemplate : (MASCompletionErrorBlock)webLoginBlock +{ + self.webLoginCallBack = webLoginBlock; + MASModelService* service = [MASModelService sharedService]; + [[MASAuthorizationResponse sharedInstance] setDelegate:self]; + __block MASBrowserBasedAuthentication *blockSelf = self; + + // + // Try to register so that all the essential things are set up in that API call and we get a valid URL. If Application is already registered the API returns without doing any work. + // + [service registerApplication:^(BOOL completed, NSError *error) { + + NSURL* url = [blockSelf getURLForWebLogin]; + DLog(@"url used for browser based authentication is %@",url.absoluteString); + blockSelf.safariViewController = [[SFSafariViewController alloc] initWithURL:url]; + __block UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:blockSelf.safariViewController]; + + dispatch_async(dispatch_get_main_queue(), ^ + { + [UIAlertController rootViewController].modalTransitionStyle = UIModalTransitionStyleCoverVertical; + + [[UIAlertController rootViewController] presentViewController:navigationController animated:YES + completion:^{ + + navigationController = nil; + }]; + + return; + }); + }]; +} + + +- (NSURL*)getURLForWebLogin +{ + // + // Endpoint + // + NSString *endPoint = [MASConfiguration currentConfiguration].authorizationEndpointPath; + + // + // Headers + // + MASIMutableOrderedDictionary *headerInfo = [MASIMutableOrderedDictionary new]; + + // + // Parameters + // + MASIMutableOrderedDictionary *parameterInfo = [MASIMutableOrderedDictionary new]; + + // ClientId + parameterInfo[MASClientKeyRequestResponseKey] = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyClientId]; + + // RedirectUri + parameterInfo[MASRedirectUriRequestResponseKey] = [[MASApplication currentApplication].redirectUri absoluteString]; + + // Scope + NSString *scope = [MASApplication currentApplication].scopeAsString; + + //Remove register scopes if device is already registered (required for BBA to work) + /* if([[MASDevice currentDevice] isRegistered]) + { + scope = [scope stringByReplacingOccurrencesOfString:@"msso_client_register" withString:@""]; + scope = [scope stringByReplacingOccurrencesOfString:@"msso_register" withString:@""]; + + }*/ + + // + // Workaround - msso_register scope should NOT be used to retrieve authenticationProviders when it is going to be used to "authenticate" + // msso_register scope should only contain for device registration with authorizationCode. + // When the authroizationCode was granted with msso_register scope and used to retrieve the tokens, it will FAIL with unknown error from the server. + // + if (scope && [[MASDevice currentDevice] isRegistered]) + { + scope = [scope replaceStringWithRegexPattern:@"\\bmsso_register\\b" withString:@""]; + } + + // + // If sso is disabled, manually remove msso scope, as it will create id_token with msso scope + // + if (scope && ![MASConfiguration currentConfiguration].ssoEnabled) + { + scope = [scope replaceStringWithRegexPattern:@"\\bmsso\\b" withString:@""]; + } + + parameterInfo[MASScopeRequestResponseKey] = scope; + + // ResponseType + parameterInfo[MASRequestResponseTypeRequestResponseKey] = @"code"; + + // Display + parameterInfo[MASDisplayRequestResponseKey] = @"template"; + + // PKCE Support - generate code verifier + [[MASAccessService sharedService].currentAccessObj generateCodeVerifier]; + + // PKCE Support - generate state + [[MASAccessService sharedService].currentAccessObj generatePKCEState]; + + // Retrieve code verifier + NSString *codeVerifier = [[MASAccessService sharedService].currentAccessObj retrieveCodeVerifier]; + + // Retrieve state + NSString *pkceState = [[MASAccessService sharedService].currentAccessObj retrievePKCEState]; + + if (codeVerifier) + { + // SHA256 the code verifier and encode it with base64url + NSString *codeChallenge = [NSString base64URLWithNSData:[codeVerifier sha256Data]]; + + if (codeChallenge) + { + parameterInfo[MASPKCECodeChallengeRequestResponseKey] = codeChallenge; + // + // code_challenge_method should be S256 if the code challenge is hashed; + // + // Otherwise, make code_challenge = code_verifier, and send code_challenge_method as plan, MASPKCECodeChallengeMethodPlainKey + // + parameterInfo[MASPKCECodeChallengeMethodRequestResponseKey] = MASPKCECodeChallengeMethodSHA256Key; + + parameterInfo[MASPKCEStateRequestResponseKey] = pkceState; + } + } + + //Put the mag-identifier in the url as query parameter for the device to be identified + NSString* magIdentifier = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyMAGIdentifier]; + //DLog(@"mag-identifier is %@",magIdentifier); + if(magIdentifier && magIdentifier.length > 0) + { + parameterInfo[MASMagIdentifierRequestResponseKey] = magIdentifier; + } + + return [MASGetURLRequest requestForEndpoint:endPoint withParameters:parameterInfo andHeaders:headerInfo requestType:MASRequestResponseTypeUnknown responseType:MASRequestResponseTypeUnknown isPublic:YES].URL; +} + + +#pragma mark - Authorization Response delegate + +-(void)didReceiveAuthorizationCode:(NSString *)code +{ + __block MASBrowserBasedAuthentication *blockSelf = self; + [MASUser loginWithAuthorizationCode:code completion:^(BOOL completed,NSError* error){ + [blockSelf dismissBrowser]; + if(error) + { + DLog(@"error occured %@",error.localizedDescription); + blockSelf.webLoginCallBack(completed, error); + return; + } + + DLog(@"Browser Based Login Successful"); + blockSelf.webLoginCallBack(completed, error); + + + }]; +} + + +-(void)didReceiveError:(NSError *)error +{ + self.webLoginCallBack(NO, error); +} + +#pragma mark - UI + +-(void)dismissBrowser +{ + dispatch_async(dispatch_get_main_queue(), ^{ + [[UIAlertController rootViewController] dismissViewControllerAnimated:YES completion:nil]; + }); +} + +@end From db7ccbb8193c94dac532750d6bacc05d39b62b83 Mon Sep 17 00:00:00 2001 From: Mahendra Nimishakavi Date: Tue, 21 Nov 2017 14:16:40 +0530 Subject: [PATCH 12/30] added code for explicit login in MASUser class --- .../Classes/models/MASBrowserBasedAuthentication.m | 13 +++++++++++-- MASFoundation/Classes/models/MASUser.h | 10 ++++++++++ MASFoundation/Classes/models/MASUser.m | 12 ++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m index a303bf7b..e1826078 100644 --- a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m +++ b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m @@ -15,7 +15,7 @@ #import "MASGetURLRequest.h" #import "MASModelService.h" -@interface MASBrowserBasedAuthentication () +@interface MASBrowserBasedAuthentication () { } @@ -49,7 +49,7 @@ -(void)loadWebLoginTemplate : (MASCompletionErrorBlock)webLoginBlock MASModelService* service = [MASModelService sharedService]; [[MASAuthorizationResponse sharedInstance] setDelegate:self]; __block MASBrowserBasedAuthentication *blockSelf = self; - + __weak __typeof__(self) weakSelf = self; // // Try to register so that all the essential things are set up in that API call and we get a valid URL. If Application is already registered the API returns without doing any work. // @@ -58,6 +58,7 @@ -(void)loadWebLoginTemplate : (MASCompletionErrorBlock)webLoginBlock NSURL* url = [blockSelf getURLForWebLogin]; DLog(@"url used for browser based authentication is %@",url.absoluteString); blockSelf.safariViewController = [[SFSafariViewController alloc] initWithURL:url]; + blockSelf.safariViewController.delegate = weakSelf; __block UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:blockSelf.safariViewController]; dispatch_async(dispatch_get_main_queue(), ^ @@ -179,6 +180,14 @@ - (NSURL*)getURLForWebLogin } +#pragma mark - SafariViewController Delegates + +-(void)safariViewControllerDidFinish:(SFSafariViewController *)controller +{ + self.webLoginCallBack(NO, nil); +} + + #pragma mark - Authorization Response delegate -(void)didReceiveAuthorizationCode:(NSString *)code diff --git a/MASFoundation/Classes/models/MASUser.h b/MASFoundation/Classes/models/MASUser.h index ff7c6507..d79c09a6 100644 --- a/MASFoundation/Classes/models/MASUser.h +++ b/MASFoundation/Classes/models/MASUser.h @@ -261,6 +261,16 @@ +/** + Authenticate a user by launching a Browser which in turn loads a URL (templatized). + + @param completion The MASCompletionErrorBlock block that receives the results. On a successful completion, the user + available via [MASUser currentUser] has been updated with the new information. + */ ++(void)initializeBrowserBasedLoginWithCompletion : (MASCompletionErrorBlock _Nullable)completion; + + + /** * Requesting userInfo for the MASUser object. * This method will retrieve additional information on the MASUser object. diff --git a/MASFoundation/Classes/models/MASUser.m b/MASFoundation/Classes/models/MASUser.m index 9cc8fc67..9c751916 100644 --- a/MASFoundation/Classes/models/MASUser.m +++ b/MASFoundation/Classes/models/MASUser.m @@ -250,6 +250,18 @@ + (void)loginWithAuthCredentials:(MASAuthCredentials *_Nonnull)authCredentials c } ++(void)initializeBrowserBasedLoginWithCompletion : (MASCompletionErrorBlock _Nullable)completion +{ + if ([MASUser currentUser] && [MASUser currentUser].isAuthenticated) + { + if(completion) completion(NO, [NSError errorUserAlreadyAuthenticated]); + + return; + } + + [[MASModelService sharedService] validateCurrentUserSession:completion]; +} + - (void)requestUserInfoWithCompletion:(MASUserResponseErrorBlock)completion { [[MASModelService sharedService] requestUserInfoWithCompletion:completion]; From a06367b2f8c946892b9406ebafaba1ffd3992fb9 Mon Sep 17 00:00:00 2001 From: Kaylie Son Date: Tue, 21 Nov 2017 11:22:24 -0800 Subject: [PATCH 13/30] DE328373 : [iOS][Multi-Server] MAS Set Security Configuration call gets success though setting Public Server and Trust Public PKI value set as 'False' --- MASFoundation/Classes/MASConstants.h | 6 + .../_private_/categories/NSError+MASPrivate.m | 6 + .../Classes/models/MASConfiguration.h | 27 ++++- .../Classes/models/MASConfiguration.m | 105 ++++++++++++++---- 4 files changed, 116 insertions(+), 28 deletions(-) diff --git a/MASFoundation/Classes/MASConstants.h b/MASFoundation/Classes/MASConstants.h index 2505b83e..2a4a86c6 100644 --- a/MASFoundation/Classes/MASConstants.h +++ b/MASFoundation/Classes/MASConstants.h @@ -329,6 +329,12 @@ typedef NS_ENUM(NSInteger, MASFoundationErrorCode) MASFoundationErrorCodeConfigurationLoadingFailedJsonValidation = 100203, MASFoundationErrorCodeConfigurationInvalidEndpoint = 100204, + // + // Security Configuration + // + MASFoundationErrorCodeConfigurationInvalidHostForSecurityConfiguration = 100211, + MASFoundationErrorCodeConfigurationInvalidPinningInfoForSecurityConfiguration = 100212, + // // Geolocation // diff --git a/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m b/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m index 51ecb6bc..1a3c0c90 100644 --- a/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m +++ b/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m @@ -984,6 +984,12 @@ + (NSString *)descriptionForFoundationErrorCode:(MASFoundationErrorCode)errorCod case MASFoundationErrorCodeConfigurationLoadingFailedJsonValidation: return @"The configuration was successfully loaded, but the configuration is invalid for the following reason\n\n'%@'"; case MASFoundationErrorCodeConfigurationInvalidEndpoint: return @"Invalid endpoint"; + // + // Security Configuration + // + case MASFoundationErrorCodeConfigurationInvalidHostForSecurityConfiguration: return @"Invalid host information for security configuration. NSURL host or port cannot be nil."; + case MASFoundationErrorCodeConfigurationInvalidPinningInfoForSecurityConfiguration: return @"Invalid pinning information for security configuration. At least one pinning information should be provided or public PKI should be trusted."; + // // Device // diff --git a/MASFoundation/Classes/models/MASConfiguration.h b/MASFoundation/Classes/models/MASConfiguration.h index 51d544be..8d4eafd8 100644 --- a/MASFoundation/Classes/models/MASConfiguration.h +++ b/MASFoundation/Classes/models/MASConfiguration.h @@ -174,13 +174,17 @@ # pragma mark - Security Configuration /** - Sets security measure for SSL pinning, and SSL validation for specified host in MASSecurityConfiguration object + Sets security measure for SSL pinning, and SSL validation for specified host in MASSecurityConfiguration object. + + @remark MASSecurityConfiguration must have valid host in NSURL object with port number (port number is mandatory), at least one pinning information (either certificates, or public key hashes), or trust public PKI. If public PKI is not trusted, and no pinning information is provided, it will fail to store the security configuration object, and eventually fail on evaluating SSL for requests. @warning Upon SDK initialization, [MASConfiguration currentConfiguration].gatewayUrl's MASSecurityConfiguration object will be overwritten. If primary gateway's security configuration has to be modified, ensure to set security configuration after SDK initialization. - @param securityConfiguration MASSecurityConfiguration object with host, and security measure configuration values. - */ -+ (void)setSecurityConfiguration:(MASSecurityConfiguration *_Nonnull)securityConfiguration; + @param securityConfiguration MASSecurityConfiguration object with host, and security measure configuration values + @param error NSError object reference to notify any error occurred while validating MASSecurityConfiguration + @return YES if security configuration was successfully set + */ ++ (BOOL)setSecurityConfiguration:(MASSecurityConfiguration *_Nonnull)securityConfiguration error:(NSError *__nullable __autoreleasing *__nullable)error; @@ -352,4 +356,19 @@ + (NSError *_Nullable)validateJSONConfiguration:(NSDictionary *_Nonnull)configuration; + +///-------------------------------------- +/// @name Deprecated +///-------------------------------------- + +# pragma mark - Deprecated + +/** + Sets security measure for SSL pinning, and SSL validation for specified host in MASSecurityConfiguration object + + @warning Upon SDK initialization, [MASConfiguration currentConfiguration].gatewayUrl's MASSecurityConfiguration object will be overwritten. If primary gateway's security configuration has to be modified, ensure to set security configuration after SDK initialization. + @param securityConfiguration MASSecurityConfiguration object with host, and security measure configuration values. + */ ++ (void)setSecurityConfiguration:(MASSecurityConfiguration *_Nonnull)securityConfiguration DEPRECATED_MSG_ATTRIBUTE("[MASConfiguration setSecurityConfiguration:] is deprecated. Use [MASConfiguration setSecurityConfiguration:error:] instead for better handling of error cases."); + @end diff --git a/MASFoundation/Classes/models/MASConfiguration.m b/MASFoundation/Classes/models/MASConfiguration.m index 268b55d7..d9705c15 100644 --- a/MASFoundation/Classes/models/MASConfiguration.m +++ b/MASFoundation/Classes/models/MASConfiguration.m @@ -201,7 +201,7 @@ - (id)init - (id)initPrivate { self = [super init]; - if(self) + if (self) { } @@ -212,7 +212,7 @@ - (id)initPrivate - (id)initWithConfigurationInfo:(NSDictionary *)info { - if(self = [super init]) + if (self = [super init]) { _configurationInfo_ = info; @@ -232,7 +232,10 @@ - (void)initializeEndpointsFromInfo:(NSDictionary *)info // // If the dictionary already exists ignore the call // - if(_endpointKeysToPaths) return; + if (_endpointKeysToPaths) + { + return; + } // // Create the dictionary @@ -243,15 +246,21 @@ - (void)initializeEndpointsFromInfo:(NSDictionary *)info // OAuth Endpoints // NSDictionary *oauthInfo = _configurationInfo_[MASOAuthConfigurationKey]; - if(oauthInfo) + if (oauthInfo) { // System Endpoints NSDictionary *endpointsInfo = oauthInfo[MASSystemEndpointsConfigurationKey]; - if(endpointsInfo) [_endpointKeysToPaths addEntriesFromDictionary:endpointsInfo]; + if (endpointsInfo) + { + [_endpointKeysToPaths addEntriesFromDictionary:endpointsInfo]; + } // Protected Endpoints endpointsInfo = oauthInfo[MASProtectedEndpointsConfigurationKey]; - if(endpointsInfo) [_endpointKeysToPaths addEntriesFromDictionary:endpointsInfo]; + if (endpointsInfo) + { + [_endpointKeysToPaths addEntriesFromDictionary:endpointsInfo]; + } } @@ -259,22 +268,28 @@ - (void)initializeEndpointsFromInfo:(NSDictionary *)info // MAG Endpoints // NSDictionary *magInfo = _configurationInfo_[MASMAGConfigurationKey]; - if(magInfo) + if (magInfo) { // System Endpoints NSDictionary *endpointsInfo = magInfo[MASSystemEndpointsConfigurationKey]; - if(endpointsInfo) [_endpointKeysToPaths addEntriesFromDictionary:endpointsInfo]; + if (endpointsInfo) + { + [_endpointKeysToPaths addEntriesFromDictionary:endpointsInfo]; + } // Protected Endpoints endpointsInfo = magInfo[MASProtectedEndpointsConfigurationKey]; - if(endpointsInfo) [_endpointKeysToPaths addEntriesFromDictionary:endpointsInfo]; + if (endpointsInfo) + { + [_endpointKeysToPaths addEntriesFromDictionary:endpointsInfo]; + } } // // MAS Endpoints // NSDictionary *masInfo = _configurationInfo_[MASConfigurationKey]; - if(masInfo) + if (masInfo) { // // currently scim-path is configured as String, maybe later when it comes as dictionary change it @@ -282,14 +297,14 @@ - (void)initializeEndpointsFromInfo:(NSDictionary *)info //scim-path NSString *scimPathInfo = masInfo[MASScimPathEndpoint]; - if(scimPathInfo) + if (scimPathInfo) { [_endpointKeysToPaths addEntriesFromDictionary:@{MASScimPathEndpoint : scimPathInfo}]; } //storage-path NSString *storagePathInfo = masInfo[MASStoragePathEndpoint]; - if(scimPathInfo) + if (scimPathInfo) { [_endpointKeysToPaths addEntriesFromDictionary:@{MASStoragePathEndpoint : storagePathInfo}]; } @@ -299,8 +314,10 @@ - (void)initializeEndpointsFromInfo:(NSDictionary *)info // Custom Endpoints // NSDictionary *customInfo = _configurationInfo_[MASCustomConfigurationKey]; - if(customInfo) [_endpointKeysToPaths addEntriesFromDictionary:customInfo]; - + if (customInfo) + { + [_endpointKeysToPaths addEntriesFromDictionary:customInfo]; + } // // Temporary Hardcoded Endpoints @@ -322,7 +339,7 @@ + (MASConfiguration *)instanceFromStorage // Attempt to retrieve from keychain // NSData *data = [[MASIKeyChainStore keyChainStoreWithService:[MASConfiguration currentConfiguration].gatewayUrl.absoluteString] dataForKey:[MASConfiguration.class description]]; - if(data) + if (data) { configuration = (MASConfiguration *)[NSKeyedUnarchiver unarchiveObjectWithData:data]; } @@ -337,11 +354,11 @@ - (void)saveToStorage // Save to the keychain // NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self]; - if(data) + if (data) { NSError *error; [[MASIKeyChainStore keyChainStoreWithService:[MASConfiguration currentConfiguration].gatewayUrl.absoluteString] setData:data forKey:[MASConfiguration.class description] error:&error]; - if(error) + if (error) { DLog(@"Error attempting to save data: %@", [error localizedDescription]); } @@ -365,13 +382,16 @@ - (void)encodeWithCoder:(NSCoder *)aCoder MASKeyChainService *keyChainService = [MASKeyChainService keyChainService]; // Configuration - if(_configurationInfo_) [keyChainService setConfiguration:_configurationInfo_]; + if (_configurationInfo_) + { + [keyChainService setConfiguration:_configurationInfo_]; + } } - (id)initWithCoder:(NSCoder *)aDecoder { - if(self = [super init]) + if (self = [super init]) { MASKeyChainService *keyChainService = [MASKeyChainService keyChainService]; @@ -386,9 +406,38 @@ - (id)initWithCoder:(NSCoder *)aDecoder } -+ (void)setSecurityConfiguration:(MASSecurityConfiguration *)securityConfiguration ++ (BOOL)setSecurityConfiguration:(MASSecurityConfiguration *)securityConfiguration error:(NSError **)error { + // + // Validate the NSURL host for security configuration. + // + if (!securityConfiguration.host || !securityConfiguration.host.port) + { + if (error) + { + *error = [NSError errorForFoundationCode:MASFoundationErrorCodeConfigurationInvalidHostForSecurityConfiguration errorDomain:MASFoundationErrorDomainLocal]; + } + + return NO; + } + + // + // Validate pinning information for the security configuration. + // At least one pinning information (certificates or public key hashes) should be defined, or public PKI should be trusted. + // + if (!securityConfiguration.trustPublicPKI && (!securityConfiguration.certificates || [securityConfiguration.certificates count]== 0) && (!securityConfiguration.publicKeyHashes || [securityConfiguration.publicKeyHashes count] == 0)) + { + if (error) + { + *error = [NSError errorForFoundationCode:MASFoundationErrorCodeConfigurationInvalidPinningInfoForSecurityConfiguration errorDomain:MASFoundationErrorDomainLocal]; + } + + return NO; + } + [MASConfigurationService setSecurityConfiguration:securityConfiguration]; + + return YES; } @@ -553,7 +602,7 @@ - (NSString *)gatewayHostName error:nil]; NSUInteger numberOfMatches = [regexToValidateIP numberOfMatchesInString:gatewayInfo[MASGatewayHostNameKey] options:0 range:NSMakeRange(0, [gatewayInfo[MASGatewayHostNameKey] length])]; - if(_systemVersionNumber_ < 9.0 && numberOfMatches != 1) + if (_systemVersionNumber_ < 9.0 && numberOfMatches != 1) { if (![MASDevice currentDevice].isRegistered) { @@ -882,7 +931,7 @@ - (NSString *)debugDescription NSMutableString *endpoints = [[NSMutableString alloc] initWithString:@"\n\n {\n"]; NSString *keyToEndpoint; - for(NSString *endpointKey in _endpointKeysToPaths) + for (NSString *endpointKey in _endpointKeysToPaths) { keyToEndpoint = [NSString stringWithFormat:@" %@ = %@\n", endpointKey, _endpointKeysToPaths[endpointKey]]; [endpoints appendString:keyToEndpoint]; @@ -904,13 +953,13 @@ - (NSString *)debugDescription - (NSDictionary *)defaultApplicationClientInfo { NSMutableArray *applicationClientInfoFound = [NSMutableArray new]; - for(NSDictionary *info in self.applicationClients) + for (NSDictionary *info in self.applicationClients) { [applicationClientInfoFound addObject:info]; } // Should there be two or more allowed in the list that meet that criteria? Can it happen? - if(applicationClientInfoFound.count > 1) + if (applicationClientInfoFound.count > 1) { DLog(@"Warning: found %ld iOS clients that are enabled, just choosing first in the list", (long)applicationClientInfoFound.count); @@ -981,4 +1030,12 @@ - (NSArray *)generateCertificatesFromPEM:(NSArray *)certificatesAsPEM return certificatesAsDER; } + +# pragma mark - Deprecated + ++ (void)setSecurityConfiguration:(MASSecurityConfiguration *)securityConfiguration +{ + [self setSecurityConfiguration:securityConfiguration error:nil]; +} + @end From 7bc04ed6ba10dbd21c0a82feaacb166028f3dcf1 Mon Sep 17 00:00:00 2001 From: Kaylie Son Date: Tue, 21 Nov 2017 12:38:38 -0800 Subject: [PATCH 14/30] US416558 : [iOS] SharedStorage API --- .../services/access/MASAccessService.h | 10 ++++ .../services/access/MASAccessService.m | 17 +++++++ .../Classes/models/MASSharedStorage.h | 10 ++++ .../Classes/models/MASSharedStorage.m | 46 +++++++++++++++++++ 4 files changed, 83 insertions(+) diff --git a/MASFoundation/Classes/_private_/services/access/MASAccessService.h b/MASFoundation/Classes/_private_/services/access/MASAccessService.h index a498a5e2..dfb9c3f0 100644 --- a/MASFoundation/Classes/_private_/services/access/MASAccessService.h +++ b/MASFoundation/Classes/_private_/services/access/MASAccessService.h @@ -341,6 +341,16 @@ extern NSString * const MASKeychainStorageKeyDeviceVendorId; +/** + Deletes keychain storage item based on storage key + + @param storageKey NSString of storage key. + @param error NSError object reference. + */ +- (void)deleteForStorageKey:(NSString *)storageKey error:(NSError **)error; + + + ///-------------------------------------- /// @name Public ///-------------------------------------- diff --git a/MASFoundation/Classes/_private_/services/access/MASAccessService.m b/MASFoundation/Classes/_private_/services/access/MASAccessService.m index 503b067b..38c86a4f 100644 --- a/MASFoundation/Classes/_private_/services/access/MASAccessService.m +++ b/MASFoundation/Classes/_private_/services/access/MASAccessService.m @@ -671,6 +671,23 @@ - (SecKeyRef)getAccessValueCryptoKeyWithStorageKey:(NSString *)storageKey } +- (void)deleteForStorageKey:(NSString *)storageKey error:(NSError **)error +{ + NSString *storageType = [self getStorageTypeWithKey:storageKey]; + NSString *accessValueAsString = [self convertKeyString:storageKey]; + MASIKeyChainStore *destinationStorage = _storages[storageType]; + + NSError *operationError = nil; + + [destinationStorage removeItemForKey:storageKey error:&operationError]; + + if (operationError && error) + { + *error = operationError; + } +} + + #pragma mark - Private + (NSString *)padding:(NSString *)encodedString{ diff --git a/MASFoundation/Classes/models/MASSharedStorage.h b/MASFoundation/Classes/models/MASSharedStorage.h index 69867a73..7b68d72c 100644 --- a/MASFoundation/Classes/models/MASSharedStorage.h +++ b/MASFoundation/Classes/models/MASSharedStorage.h @@ -74,4 +74,14 @@ */ + (BOOL)saveData:(NSData *_Nonnull)data key:(NSString *_Nonnull)key error:(NSError * __nullable __autoreleasing * __nullable)error; + + +/** + Deletes any data type with the specified key from shared keychain storage. + + @param key NSString of the key used to store the data + @param error NSError object reference that would notify if there was any error while deleting the data + */ ++ (void)deleteForKey:(NSString *_Nonnull)key error:(NSError * __nullable __autoreleasing * __nullable)error; + @end diff --git a/MASFoundation/Classes/models/MASSharedStorage.m b/MASFoundation/Classes/models/MASSharedStorage.m index c7d0916d..84a652e8 100644 --- a/MASFoundation/Classes/models/MASSharedStorage.m +++ b/MASFoundation/Classes/models/MASSharedStorage.m @@ -215,4 +215,50 @@ + (BOOL)saveData:(NSData *)data key:(NSString *)key error:(NSError **)error return result; } + ++ (void)deleteForKey:(NSString *_Nonnull)key error:(NSError * __nullable __autoreleasing * __nullable)error +{ + // + // Check if SDK was initialized + // + if ([MAS MASState] != MASStateDidStart) + { + if (error) + { + *error = [NSError errorMASIsNotStarted]; + } + + return; + } + + // + // Check for data key + // + if (key == nil || [key length] <= 0) + { + if (error) + { + *error = [NSError errorForFoundationCode:MASFoundationErrorCodeSharedStorageNotNilKey errorDomain:MASFoundationErrorDomainLocal]; + } + + return; + } + + NSError *operationError = nil; + [[MASAccessService sharedService] deleteForStorageKey:[NSString stringWithFormat:@"%@.%@", MASSharedStorageCustomPrefix, key] error:&operationError]; + + // + // If an error occurred while keychain operation, convert it into MASFoundationErrorDomainLocal error object + // + if (operationError) + { + NSError *thisError = [NSError errorWithDomain:MASFoundationErrorDomainLocal code:operationError.code userInfo:@{NSLocalizedDescriptionKey : operationError.localizedDescription}]; + + if (error) + { + *error = thisError; + } + } +} + @end From e5a886063b91a268fd468b56f47438de62a64df2 Mon Sep 17 00:00:00 2001 From: Kaylie Son Date: Tue, 21 Nov 2017 12:40:33 -0800 Subject: [PATCH 15/30] US416558 : [iOS] SharedStorage API --- .../Classes/_private_/services/access/MASAccessService.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MASFoundation/Classes/_private_/services/access/MASAccessService.m b/MASFoundation/Classes/_private_/services/access/MASAccessService.m index 38c86a4f..cedf6246 100644 --- a/MASFoundation/Classes/_private_/services/access/MASAccessService.m +++ b/MASFoundation/Classes/_private_/services/access/MASAccessService.m @@ -679,7 +679,7 @@ - (void)deleteForStorageKey:(NSString *)storageKey error:(NSError **)error NSError *operationError = nil; - [destinationStorage removeItemForKey:storageKey error:&operationError]; + [destinationStorage removeItemForKey:accessValueAsString error:&operationError]; if (operationError && error) { From bb0a2a5c0136a4f9abbdb901c604b6b6d1caa6a1 Mon Sep 17 00:00:00 2001 From: Mahendra Nimishakavi Date: Wed, 22 Nov 2017 19:08:28 +0530 Subject: [PATCH 16/30] added some code to handle the redirection and load the template --- .../_private_/services/MASServiceRegistry.h | 4 +- .../_private_/services/MASServiceRegistry.m | 2 +- .../services/model/MASModelService.m | 4 +- .../services/network/MASNetworkingService.h | 7 +- .../services/network/MASNetworkingService.m | 8 +- .../network/internal/MASURLSessionManager.h | 1 + .../network/internal/MASURLSessionManager.m | 8 ++ .../models/MASBrowserBasedAuthentication.h | 2 +- .../models/MASBrowserBasedAuthentication.m | 88 +++++++++++++++---- 9 files changed, 97 insertions(+), 27 deletions(-) diff --git a/MASFoundation/Classes/_private_/services/MASServiceRegistry.h b/MASFoundation/Classes/_private_/services/MASServiceRegistry.h index 34b5ec54..781e5f37 100644 --- a/MASFoundation/Classes/_private_/services/MASServiceRegistry.h +++ b/MASFoundation/Classes/_private_/services/MASServiceRegistry.h @@ -193,9 +193,9 @@ typedef NS_ENUM(NSInteger, MASRegistryState) * For this method to handle authentication it requires browser based login to be enabled. * @see enableBrowserBasedAuthentication * - * @param bbaLoginBlock The MASCompletionErrorBlock to receive login result. + * @param bbaLoginBlock The MASAuthCredentialsBlock to receive login result. * @return Return YES if handled, NO if not. */ --(BOOL)browserBasedLoginWillHandleAuthentication : (MASCompletionErrorBlock)bbaLoginBlock; +-(BOOL)browserBasedLoginWillHandleAuthentication : (MASAuthCredentialsBlock)bbaLoginBlock; @end diff --git a/MASFoundation/Classes/_private_/services/MASServiceRegistry.m b/MASFoundation/Classes/_private_/services/MASServiceRegistry.m index b0788eeb..5f759f10 100644 --- a/MASFoundation/Classes/_private_/services/MASServiceRegistry.m +++ b/MASFoundation/Classes/_private_/services/MASServiceRegistry.m @@ -935,7 +935,7 @@ - (BOOL)uiServiceWillHandleOTPChannelSelection:(NSArray *)supportedChannels } --(BOOL)browserBasedLoginWillHandleAuthentication : (MASCompletionErrorBlock)bbaLoginBlock +-(BOOL)browserBasedLoginWillHandleAuthentication : (MASAuthCredentialsBlock)bbaLoginBlock { if(![[MASModelService sharedService] browserBasedLogin]) { diff --git a/MASFoundation/Classes/_private_/services/model/MASModelService.m b/MASFoundation/Classes/_private_/services/model/MASModelService.m index ce60366d..c4b2ad8e 100644 --- a/MASFoundation/Classes/_private_/services/model/MASModelService.m +++ b/MASFoundation/Classes/_private_/services/model/MASModelService.m @@ -923,7 +923,7 @@ - (void)registerDeviceWithCompletion:(MASCompletionErrorBlock)completion // MASServiceRegistry *serviceRegistry = [MASServiceRegistry sharedRegistry]; - if([serviceRegistry browserBasedLoginWillHandleAuthentication:completion]) + if([serviceRegistry browserBasedLoginWillHandleAuthentication:authCredentialsBlock]) { return; } @@ -1731,7 +1731,7 @@ - (void)loginUsingUserCredentials:(MASCompletionErrorBlock)completion // If the UI handling framework is present and will handle this stop here // MASServiceRegistry *serviceRegistry = [MASServiceRegistry sharedRegistry]; - if([serviceRegistry browserBasedLoginWillHandleAuthentication:completion]) + if([serviceRegistry browserBasedLoginWillHandleAuthentication:authCredentialsBlock]) { return; } diff --git a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h index 6653a47c..ca85efab 100644 --- a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h +++ b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h @@ -9,10 +9,11 @@ // #import "MASService.h" - #import "MASConstantsPrivate.h" + #import "MASAuthValidationOperation.h" +typedef NSURLRequest* (^MASSessionDataTaskHTTPRedirectBlock)(NSURLSession *_Nonnull session, NSURLSessionTask *_Nonnull task, NSURLResponse * _Nonnull response, NSURLRequest *_Nonnull request); @interface MASNetworkingService : MASService @@ -26,6 +27,10 @@ @property (nonatomic, assign, readonly) MASGatewayMonitoringStatus monitoringStatus; +@property (nonatomic) MASSessionDataTaskHTTPRedirectBlock httpRedirectionBlock; + +//@property (nonatomic, copy) MASSessionDataTask1CompletionBlock httpBlock; + /** Constructs, if not exist, the shared operation that validates current session's registration and authentication status diff --git a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m index c4415cac..d016e392 100644 --- a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m +++ b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m @@ -11,7 +11,6 @@ #import "MASNetworkingService.h" #import "MASAccessService.h" -#import "MASConstantsPrivate.h" #import "MASConfigurationService.h" #import "MASLocationService.h" #import "MASModelService.h" @@ -657,6 +656,7 @@ - (MASSessionDataTaskCompletionBlock)sessionDataTaskCompletionBlockWithEndPoint: } + - (BOOL)isMAGEndpoint:(NSString *)endpoint { BOOL isMAGEndpoint = NO; @@ -1273,6 +1273,11 @@ - (void)httpRequest:(NSString *)httpMethod endPoint:(NSString *)endPoint paramet // // Construct MASSessionDataTaskOperation with request, and completion block to handle any responsive re-authentication or re-registration. // + if(self.httpRedirectionBlock) + { + [_sessionManager setSessionDidReceiveHTTPRedirectBlock:self.httpRedirectionBlock]; + } + MASSessionDataTaskOperation *operation = [_sessionManager dataOperationWithRequest:request completionHandler:[self sessionDataTaskCompletionBlockWithEndPoint:endPoint parameters:parameterInfo @@ -1283,6 +1288,7 @@ - (void)httpRequest:(NSString *)httpMethod endPoint:(NSString *)endPoint paramet isPublic:isPublic completionBlock:blockCompletion]]; + if (![self isMAGEndpoint:endPoint]) { // diff --git a/MASFoundation/Classes/_private_/services/network/internal/MASURLSessionManager.h b/MASFoundation/Classes/_private_/services/network/internal/MASURLSessionManager.h index ad42a64c..a2c67eb5 100644 --- a/MASFoundation/Classes/_private_/services/network/internal/MASURLSessionManager.h +++ b/MASFoundation/Classes/_private_/services/network/internal/MASURLSessionManager.h @@ -149,5 +149,6 @@ typedef void (^MASNetworkSessionDidFinishEventsForBackgroundURLSessionBlock)(NSU */ - (void)setSessionDidReceiveAuthenticationChallengeBlock:(NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential **credential))block; +-(void)setSessionDidReceiveHTTPRedirectBlock : (NSURLRequest* (^)(NSURLSession *session,NSURLSessionTask *task, NSURLResponse* response,NSURLRequest *request))block; @end diff --git a/MASFoundation/Classes/_private_/services/network/internal/MASURLSessionManager.m b/MASFoundation/Classes/_private_/services/network/internal/MASURLSessionManager.m index 52f37c81..f35e4139 100644 --- a/MASFoundation/Classes/_private_/services/network/internal/MASURLSessionManager.m +++ b/MASFoundation/Classes/_private_/services/network/internal/MASURLSessionManager.m @@ -17,6 +17,7 @@ @interface MASURLSessionManager () Date: Thu, 23 Nov 2017 13:04:45 +0530 Subject: [PATCH 17/30] [ADD] Adding new blocks for handling Biometric Registration and Deregistration UI --- MASFoundation/Classes/MASConstants.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/MASFoundation/Classes/MASConstants.h b/MASFoundation/Classes/MASConstants.h index 2a4a86c6..1a9de06a 100644 --- a/MASFoundation/Classes/MASConstants.h +++ b/MASFoundation/Classes/MASConstants.h @@ -91,6 +91,27 @@ typedef void (^MASOTPChannelSelectionBlock)(NSArray *_Nonnull supportedOTPChanne typedef void (^MASOTPCredentialsBlock)(MASOTPFetchCredentialsBlock _Nonnull otpBlock, NSError *_Nullable otpError); +/** + * The Selected Biometric modalities (NSArray *_Nullable biometricModalities, BOOL cancel, MASCompletionErrorBlock _Nullable) + * block. + */ +typedef void (^MASBiometricModalitiesBlock)(NSArray *_Nullable biometricModalities, BOOL cancel, MASCompletionErrorBlock _Nullable); + + +/** + * The Biometric registration with available modalities (NSArray *_Nonnull availableModalities, MASBiometricModalitiesBlock + * _Nonnull biometricModalitiesBlock) block. + */ +typedef void (^MASBiometricRegistrationModalitiesSelectionBlock)(NSArray *_Nonnull availableModalities, MASBiometricModalitiesBlock _Nonnull biometricModalitiesBlock); + + +/** + * The Biometric deregistration with available modalities (NSArray *_Nonnull availableModalities, MASBiometricModalitiesBlock + * _Nonnull biometricModalitiesBlock) block. + */ +typedef void (^MASBiometricDeregistrationModalitiesSelectionBlock)(NSArray *_Nonnull availableModalities, MASBiometricModalitiesBlock _Nonnull biometricModalitiesBlock); + + ///-------------------------------------- /// @name MAS Constants ///-------------------------------------- From 9e1cd5730c328614a4968ea47b545584359e2740 Mon Sep 17 00:00:00 2001 From: Mahendra Nimishakavi Date: Thu, 23 Nov 2017 18:35:06 +0530 Subject: [PATCH 18/30] included review comments - filter the redirection only to BBA , made Static properties on MASModelService and fixed other comments. --- MASFoundation/Classes/MAS.m | 2 +- MASFoundation/Classes/MASConstants.h | 4 + .../_private_/categories/NSError+MASPrivate.h | 10 +- .../_private_/categories/NSError+MASPrivate.m | 11 +- .../categories/UIAlertController+MAS.h | 46 ------- .../categories/UIAlertController+MAS.m | 113 ------------------ .../_private_/services/MASServiceRegistry.m | 2 +- .../services/model/MASModelService.h | 4 +- .../services/model/MASModelService.m | 14 +-- .../network/requests/MASGetURLRequest.m | 2 +- .../models/MASBrowserBasedAuthentication.h | 8 +- .../models/MASBrowserBasedAuthentication.m | 74 ++++++------ MASFoundation/Classes/models/MASUser.h | 2 +- MASFoundation/Classes/models/MASUser.m | 8 +- 14 files changed, 82 insertions(+), 218 deletions(-) diff --git a/MASFoundation/Classes/MAS.m b/MASFoundation/Classes/MAS.m index 98787fd9..ef590fcd 100644 --- a/MASFoundation/Classes/MAS.m +++ b/MASFoundation/Classes/MAS.m @@ -94,7 +94,7 @@ + (void)setOTPCredentialsBlock:(MASOTPCredentialsBlock)oneTimePassword +(void)enableBrowserBasedAuthentication:(BOOL)enable { - [[MASModelService sharedService] setBrowserBasedLogin:enable]; + [MASModelService setBrowserBasedAuthentication:enable]; } diff --git a/MASFoundation/Classes/MASConstants.h b/MASFoundation/Classes/MASConstants.h index 2505b83e..bfaa6848 100644 --- a/MASFoundation/Classes/MASConstants.h +++ b/MASFoundation/Classes/MASConstants.h @@ -459,6 +459,10 @@ typedef NS_ENUM(NSInteger, MASFoundationErrorCode) MASFoundationErrorCodeJWTUnexpectedClassType = 170002, MASFoundationErrorCodeJWTSerializationError = 170003, + // + // Browser Based Login + // + MASFoundationErrorCodeBBANotEnabled = 180000, // // SharedStorage // diff --git a/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.h b/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.h index b20b0bb4..a41079e6 100644 --- a/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.h +++ b/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.h @@ -644,9 +644,17 @@ /** * Create MASFoundationErrorDomainLocal NSError for MASFoundationErrorCodeProximityLoginInvalidAuthorizeURL. * - * @return REturns an NSError instance with the domain MASFoundationErrorDomainLocal and + * @return Returns an NSError instance with the domain MASFoundationErrorDomainLocal and * error MASFoundationErrorCodeProximityLoginInvalidAuthorizeURL */ + (NSError *)errorProximityLoginInvalidAuthroizeURL; + +/** + * Create MASFoundationErrorDomainLocal NSError for MASFoundationErrorCodeBBANotEnabled. + * + * @return Returns an NSError instance with the domain MASFoundationErrorDomainLocal and + * error MASFoundationErrorCodeBBANotEnabled + */ ++ (NSError *)errorBrowserBasedAuthenticaionNotEnabled; @end diff --git a/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m b/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m index 51ecb6bc..43e31a42 100644 --- a/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m +++ b/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m @@ -835,6 +835,11 @@ + (NSError *)errorProximityLoginInvalidAuthroizeURL } ++ (NSError *)errorBrowserBasedAuthenticaionNotEnabled +{ + return [self errorForFoundationCode:MASFoundationErrorCodeBBANotEnabled errorDomain:MASFoundationErrorDomainLocal]; +} + # pragma mark - Foundation Errors Private + (MASFoundationErrorCode)foundationErrorCodeForApiCode:(MASApiErrorCode)apiCode @@ -1107,7 +1112,11 @@ + (NSString *)descriptionForFoundationErrorCode:(MASFoundationErrorCode)errorCod // Shared Storage // case MASFoundationErrorCodeSharedStorageNotNilKey: return @"Data key cannot be nil or empty string."; - + + // + // Browser Based Authentication + // + case MASFoundationErrorCodeBBANotEnabled : return @"MAS Browser Based Authentication is Not Enabled"; // // Default // diff --git a/MASFoundation/Classes/_private_/categories/UIAlertController+MAS.h b/MASFoundation/Classes/_private_/categories/UIAlertController+MAS.h index 7b158d89..ec8de498 100644 --- a/MASFoundation/Classes/_private_/categories/UIAlertController+MAS.h +++ b/MASFoundation/Classes/_private_/categories/UIAlertController+MAS.h @@ -9,52 +9,6 @@ #import @interface UIAlertController (MAS) -///-------------------------------------- -/// @name Authentication Alerts -///------------------------------------- - -# pragma mark - Authentication Alerts - -/** - * Displays on screen an authentication UIAlertController modally in the currently - * visible UIViewController. - */ -+ (void)popupAuthenticationAlert; - - -/** - * Displays on screen an authentication UIAlertController modally in the selected - * UIViewController modally. - * - * @param viewController The UIViewController in which to present the modal UIAlertController. - */ -+ (void)popupAuthenticationAlertInViewController:(UIViewController *)viewController; - - - -///-------------------------------------- -/// @name Error Alerts -///------------------------------------- - -# pragma mark - Error Alerts - -/** - * Displays on screen an error UIAlertController modally in the currently - * visible UIViewController. - */ -+ (void)popupErrorAlert:(NSError *)error; - - -/** - * Displays on screen an error UIAlertController modally in the selected - * UIViewController modally. - * - * @param error The NSError contents to show in the UIAlertController. - * @param viewController The UIViewController in which to present the modal UIAlertController. - */ -+ (void)popupErrorAlert:(NSError *)error inViewController:(UIViewController *)viewController; - - ///-------------------------------------- /// @name Public diff --git a/MASFoundation/Classes/_private_/categories/UIAlertController+MAS.m b/MASFoundation/Classes/_private_/categories/UIAlertController+MAS.m index a34df9a5..cbd86f3e 100644 --- a/MASFoundation/Classes/_private_/categories/UIAlertController+MAS.m +++ b/MASFoundation/Classes/_private_/categories/UIAlertController+MAS.m @@ -9,122 +9,9 @@ #import "UIAlertController+MAS.h" #import "MASUser.h" @implementation UIAlertController (MAS) -# pragma mark - Authentication Alerts - -+ (void)popupAuthenticationAlert -{ - [self popupAuthenticationAlertInViewController:[self rootViewController]]; -} - - -+ (void)popupAuthenticationAlertInViewController:(UIViewController *)viewController -{ - // - // Ensure this is done in the main UI thread. We don't know where the call is coming from - // - dispatch_async(dispatch_get_main_queue(), ^ - { - // - // Create alert controller - // - UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Sign In (MASUI)" - message:@"You need to sign in with your user credentials" - preferredStyle:UIAlertControllerStyleAlert]; - - // - // Username text field - // - [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) - { - textField.placeholder = NSLocalizedString(@"username", nil); - }]; - - // - // Password text field - // - [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) - { - textField.placeholder = NSLocalizedString(@"password", nil); - textField.secureTextEntry = YES; - }]; - - // - // OK Action - // - UIAlertAction *okAction = [UIAlertAction - actionWithTitle:NSLocalizedString(@"OK", @"OK action") - style:UIAlertActionStyleDefault - handler:^(UIAlertAction *action) - { - UITextField *usernameTextField = alertController.textFields.firstObject; - UITextField *passwordTextField = alertController.textFields.lastObject; - - // - // Attempt to authenticate - // - [MASUser loginWithUserName:usernameTextField.text password:passwordTextField.text completion:^(BOOL completed, NSError *error) { - - DLog(@"viewController received authentication response completed: %@ or error: %@", - (completed ? @"Yes" : @"No"), [error debugDescription]); - - if(error) - { - [UIAlertController popupErrorAlert:error]; - return; - } - }]; - }]; - - [alertController addAction:okAction]; - - // - // Cancel Action - // - UIAlertAction *cancelAction = [UIAlertAction - actionWithTitle:NSLocalizedString(@"Cancel", @"Cancel action") - style:UIAlertActionStyleDefault - handler:nil]; - - [alertController addAction:cancelAction]; - - [viewController presentViewController:alertController animated:YES completion:nil]; - }); -} - # pragma mark - Error Alert -+ (void)popupErrorAlert:(NSError *)error -{ - [self popupErrorAlert:error inViewController:[self rootViewController]]; -} - - -+ (void)popupErrorAlert:(NSError *)error inViewController:(UIViewController *)viewController -{ - // - // Ensure this is done in the main UI thread. We don't know where the call is coming from - // - dispatch_async(dispatch_get_main_queue(), ^ - { - UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Error" - message:[error localizedDescription] - preferredStyle:UIAlertControllerStyleAlert]; - - UIAlertAction *ok = [UIAlertAction actionWithTitle:@"OK" - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) - { - [alertController dismissViewControllerAnimated:YES completion:nil]; - }]; - - [alertController addAction:ok]; - - [viewController presentViewController:alertController animated:NO completion:nil]; - }); -} - - + (UIViewController *) presentedViewController:(id)viewController { if ([viewController isKindOfClass:[UINavigationController class]]) diff --git a/MASFoundation/Classes/_private_/services/MASServiceRegistry.m b/MASFoundation/Classes/_private_/services/MASServiceRegistry.m index 5f759f10..d7148fc4 100644 --- a/MASFoundation/Classes/_private_/services/MASServiceRegistry.m +++ b/MASFoundation/Classes/_private_/services/MASServiceRegistry.m @@ -937,7 +937,7 @@ - (BOOL)uiServiceWillHandleOTPChannelSelection:(NSArray *)supportedChannels -(BOOL)browserBasedLoginWillHandleAuthentication : (MASAuthCredentialsBlock)bbaLoginBlock { - if(![[MASModelService sharedService] browserBasedLogin]) + if(![MASModelService browserBasedAuthentication]) { return NO; } diff --git a/MASFoundation/Classes/_private_/services/model/MASModelService.h b/MASFoundation/Classes/_private_/services/model/MASModelService.h index 4155579d..f7b6b2bc 100644 --- a/MASFoundation/Classes/_private_/services/model/MASModelService.h +++ b/MASFoundation/Classes/_private_/services/model/MASModelService.h @@ -88,7 +88,7 @@ * @param browserBasedLogin The state of browser based authentication. * If this is set to true, a URL which has a templatized login is launched in a browser and this would disable the Social Login, Proximity Login and also prevents the launch of MASUI. */ --(void)setBrowserBasedLogin : (BOOL)browserBasedLogin; ++(void)setBrowserBasedAuthentication : (BOOL)browserBasedAuthentication; /** @@ -96,7 +96,7 @@ * * @return BOOL value is returned. */ --(BOOL)browserBasedLogin; ++(BOOL)browserBasedAuthentication; ///-------------------------------------- diff --git a/MASFoundation/Classes/_private_/services/model/MASModelService.m b/MASFoundation/Classes/_private_/services/model/MASModelService.m index c4b2ad8e..6026fde9 100644 --- a/MASFoundation/Classes/_private_/services/model/MASModelService.m +++ b/MASFoundation/Classes/_private_/services/model/MASModelService.m @@ -29,7 +29,7 @@ @interface MASModelService () @property (nonatomic, strong, readwrite) MASAuthenticationProviders *currentProviders; -@property (nonatomic) BOOL isBrowserBasedLogin; + @end @@ -39,7 +39,7 @@ @implementation MASModelService static MASGrantFlow _grantFlow_ = MASGrantFlowClientCredentials; static MASUserLoginWithUserCredentialsBlock _userLoginBlock_ = nil; static MASUserAuthCredentialsBlock _userAuthCredentialsBlock_ = nil; - +static BOOL _isBrowserBasedAuthentication_; # pragma mark - Properties @@ -72,15 +72,15 @@ - (void)setUserObject:(MASUser *)user } --(void)setBrowserBasedLogin : (BOOL)browserBasedLogin ++(void)setBrowserBasedAuthentication : (BOOL)browserBasedAuthentication { - self.isBrowserBasedLogin = browserBasedLogin; + _isBrowserBasedAuthentication_ = browserBasedAuthentication; } --(BOOL)browserBasedLogin ++(BOOL)browserBasedAuthentication { - return self.isBrowserBasedLogin; + return _isBrowserBasedAuthentication_; } @@ -380,7 +380,7 @@ - (void)retrieveAuthenticationProviders:(MASObjectResponseErrorBlock)completion // // If the user was already authenticated, we don't have to retrieve the authentication provider // - if (([MASApplication currentApplication].isAuthenticated && [MASApplication currentApplication].authenticationStatus == MASAuthenticationStatusLoginWithUser) || [MASAccess currentAccess].isSessionLocked || self.isBrowserBasedLogin) + if (([MASApplication currentApplication].isAuthenticated && [MASApplication currentApplication].authenticationStatus == MASAuthenticationStatusLoginWithUser) || [MASAccess currentAccess].isSessionLocked || _isBrowserBasedAuthentication_) { // diff --git a/MASFoundation/Classes/_private_/services/network/requests/MASGetURLRequest.m b/MASFoundation/Classes/_private_/services/network/requests/MASGetURLRequest.m index 74b1d3fb..f17f61d8 100644 --- a/MASFoundation/Classes/_private_/services/network/requests/MASGetURLRequest.m +++ b/MASFoundation/Classes/_private_/services/network/requests/MASGetURLRequest.m @@ -46,7 +46,7 @@ + (MASGetURLRequest *)requestForEndpoint:(NSString *)endPoint NSURL *url = [NSURL URLWithString:endPointWithQueryParameters relativeToURL:[MASConfiguration currentConfiguration].gatewayUrl]; NSAssert(url, @"URL cannot be nil"); - + NSLog(@"url in sdk is %@",url.absoluteString); // // Create the request // diff --git a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.h b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.h index 2cafa95f..0994c69b 100644 --- a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.h +++ b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.h @@ -2,8 +2,10 @@ // MASBrowserBasedAuthentication.h // MASFoundation // -// Created by nimma01 on 20/11/17. -// Copyright © 2017 CA Technologies. All rights reserved. +// Copyright (c) 2017 CA. All rights reserved. +// +// This software may be modified and distributed under the terms +// of the MIT license. See the LICENSE file for details. // #import @@ -29,6 +31,6 @@ * * @param webLoginBlock completion MASCompletionErrorBlock that receives the results. */ --(void)loadWebLoginTemplate : (MASAuthCredentialsBlock)webLoginBlock; +-(void)loadWebLoginTemplate:(MASAuthCredentialsBlock)webLoginBlock; @end diff --git a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m index 891bb8bc..1eca7f30 100644 --- a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m +++ b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m @@ -2,8 +2,10 @@ // MASBrowserBasedAuthentication.m // MASFoundation // -// Created by nimma01 on 20/11/17. -// Copyright © 2017 CA Technologies. All rights reserved. +// Copyright (c) 2017 CA. All rights reserved. +// +// This software may be modified and distributed under the terms +// of the MIT license. See the LICENSE file for details. // #import "MASBrowserBasedAuthentication.h" @@ -43,7 +45,7 @@ + (instancetype)sharedInstance } --(void)loadWebLoginTemplate : (MASAuthCredentialsBlock)webLoginBlock +-(void)loadWebLoginTemplate:(MASAuthCredentialsBlock)webLoginBlock { self.webLoginCallBack = webLoginBlock; MASModelService* service = [MASModelService sharedService]; @@ -54,36 +56,14 @@ -(void)loadWebLoginTemplate : (MASAuthCredentialsBlock)webLoginBlock // Try to register so that all the essential things are set up in that API call and we get a valid URL. If Application is already registered the API returns without doing any work. // [service registerApplication:^(BOOL completed, NSError *error) { - - NSURL* url = [blockSelf getURLForWebLogin]; + [blockSelf getURLForWebLogin]; DLog(@"url used for browser based authentication is %@",url.absoluteString); - /* blockSelf.safariViewController = [[SFSafariViewController alloc] initWithURL:url]; - blockSelf.safariViewController.delegate = weakSelf; - __block UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:blockSelf.safariViewController]; - - dispatch_async(dispatch_get_main_queue(), ^ - { - [UIAlertController rootViewController].modalTransitionStyle = UIModalTransitionStyleCoverVertical; - - [[UIAlertController rootViewController] presentViewController:navigationController animated:YES - completion:^{ - - navigationController = nil; - }]; - - return; - });*/ - }]; + }]; } -- (NSURL*)getURLForWebLogin +- (void)getURLForWebLogin { - // - // Endpoint - // - NSString *endPoint = [MASConfiguration currentConfiguration].authorizationEndpointPath; - // // Headers // @@ -176,42 +156,51 @@ - (NSURL*)getURLForWebLogin parameterInfo[MASMagIdentifierRequestResponseKey] = magIdentifier; } + // + // Endpoint + // + NSString *endPoint = [MASConfiguration currentConfiguration].authorizationEndpointPath; + [[MASNetworkingService sharedService] setHttpRedirectionBlock:[self getRedirectionBlock]]; - [[MASNetworkingService sharedService] getFrom:@"/auth/oauth/v2/authorize" withParameters:parameterInfo andHeaders:headerInfo requestType:MASRequestResponseTypeWwwFormUrlEncoded responseType:MASRequestResponseTypeWwwFormUrlEncoded isPublic:YES completion:^(NSDictionary* response, NSError* error){ + [[MASNetworkingService sharedService] getFrom:endPoint withParameters:parameterInfo andHeaders:headerInfo requestType:MASRequestResponseTypeWwwFormUrlEncoded responseType:MASRequestResponseTypeWwwFormUrlEncoded completion:^(NSDictionary* response, NSError* error){ if(error) { - NSLog(@"error is %@",error.localizedDescription); + DLog(@"error is %@",error.localizedDescription); } - NSLog(@"response is %@",response); + DLog(@"response is %@",response); }]; - - - - return [MASGetURLRequest requestForEndpoint:endPoint withParameters:parameterInfo andHeaders:headerInfo requestType:MASRequestResponseTypeUnknown responseType:MASRequestResponseTypeUnknown isPublic:YES].URL; } -(MASSessionDataTaskHTTPRedirectBlock)getRedirectionBlock { MASSessionDataTaskHTTPRedirectBlock redirectionBlock = ^(NSURLSession *session, NSURLSessionTask *task, NSURLResponse * response, NSURLRequest *request){ NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; - if(httpResponse.statusCode == 302) + if(httpResponse.statusCode == 302 && [self isBBARedirection:task.originalRequest]) { - NSLog(@"all headers %@",httpResponse.allHeaderFields); + DLog(@"all headers %@",httpResponse.allHeaderFields); NSString* locationURL = [httpResponse.allHeaderFields objectForKey:@"Location"]; NSURL* redirectURL = [NSURL URLWithString:locationURL]; [task cancel]; [self launchBrowserWithURL:redirectURL]; } - return request; }; return redirectionBlock; } +-(BOOL)isBBARedirection : (NSURLRequest*)request +{ + if([request.URL.absoluteString containsString:[MASConfiguration currentConfiguration].authorizationEndpointPath] && [request.URL.absoluteString containsString:@"display=template"]) + { + return YES; + } + return NO; +} + -(void)launchBrowserWithURL : (NSURL*)templatizedURL { __block MASBrowserBasedAuthentication *blockSelf = self; @@ -239,7 +228,12 @@ -(void)launchBrowserWithURL : (NSURL*)templatizedURL -(void)safariViewControllerDidFinish:(SFSafariViewController *)controller { - //self.webLoginCallBack(NO, nil); + self.webLoginCallBack(nil, YES, ^(BOOL completed, NSError* error){ + if(error) + { + DLog(@"Browser dismissed"); + } + }); } @@ -254,7 +248,7 @@ -(void)didReceiveAuthorizationCode:(NSString *)code { //error } - NSLog(@"successfully logged in"); + DLog(@"successfully logged in"); [self dismissBrowser]; }); } diff --git a/MASFoundation/Classes/models/MASUser.h b/MASFoundation/Classes/models/MASUser.h index d79c09a6..78f5c497 100644 --- a/MASFoundation/Classes/models/MASUser.h +++ b/MASFoundation/Classes/models/MASUser.h @@ -267,7 +267,7 @@ @param completion The MASCompletionErrorBlock block that receives the results. On a successful completion, the user available via [MASUser currentUser] has been updated with the new information. */ -+(void)initializeBrowserBasedLoginWithCompletion : (MASCompletionErrorBlock _Nullable)completion; ++(void)initializeBrowserBasedAuthenticationWithCompletion:(MASCompletionErrorBlock _Nullable)completion; diff --git a/MASFoundation/Classes/models/MASUser.m b/MASFoundation/Classes/models/MASUser.m index 9c751916..34eaded7 100644 --- a/MASFoundation/Classes/models/MASUser.m +++ b/MASFoundation/Classes/models/MASUser.m @@ -250,8 +250,14 @@ + (void)loginWithAuthCredentials:(MASAuthCredentials *_Nonnull)authCredentials c } -+(void)initializeBrowserBasedLoginWithCompletion : (MASCompletionErrorBlock _Nullable)completion ++(void)initializeBrowserBasedAuthenticationWithCompletion:(MASCompletionErrorBlock _Nullable)completion { + if(![MASModelService browserBasedAuthentication]) + { + if(completion) completion(NO, [NSError errorBrowserBasedAuthenticaionNotEnabled]); + return; + } + if ([MASUser currentUser] && [MASUser currentUser].isAuthenticated) { if(completion) completion(NO, [NSError errorUserAlreadyAuthenticated]); From 4e7e1850d0d95c7ea2a6d6e3714d51fbc89a62b8 Mon Sep 17 00:00:00 2001 From: Mahendra Nimishakavi Date: Fri, 24 Nov 2017 14:31:55 +0530 Subject: [PATCH 19/30] saved older redirection block if any and set it back after BBA --- .../Classes/models/MASBrowserBasedAuthentication.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m index 1eca7f30..7a9479af 100644 --- a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m +++ b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m @@ -57,7 +57,7 @@ -(void)loadWebLoginTemplate:(MASAuthCredentialsBlock)webLoginBlock // [service registerApplication:^(BOOL completed, NSError *error) { [blockSelf getURLForWebLogin]; - DLog(@"url used for browser based authentication is %@",url.absoluteString); + //DLog(@"url used for browser based authentication is %@",url.absoluteString); }]; } @@ -161,16 +161,16 @@ - (void)getURLForWebLogin // NSString *endPoint = [MASConfiguration currentConfiguration].authorizationEndpointPath; + MASSessionDataTaskHTTPRedirectBlock oldRedirectionBlock = [[MASNetworkingService sharedService] httpRedirectionBlock]; [[MASNetworkingService sharedService] setHttpRedirectionBlock:[self getRedirectionBlock]]; [[MASNetworkingService sharedService] getFrom:endPoint withParameters:parameterInfo andHeaders:headerInfo requestType:MASRequestResponseTypeWwwFormUrlEncoded responseType:MASRequestResponseTypeWwwFormUrlEncoded completion:^(NSDictionary* response, NSError* error){ if(error) { - DLog(@"error is %@",error.localizedDescription); - + DLog(@"original request to get the url cancelled"); } - - DLog(@"response is %@",response); + [[MASNetworkingService sharedService] setHttpRedirectionBlock:oldRedirectionBlock]; + //DLog(@"response is %@",response); }]; } From 92a60c9d8a7fdcf53b2f3c587619e9794525bd7c Mon Sep 17 00:00:00 2001 From: Mahendra Nimishakavi Date: Fri, 24 Nov 2017 14:39:07 +0530 Subject: [PATCH 20/30] handled error case when authorization code is not received --- .../Classes/models/MASBrowserBasedAuthentication.m | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m index 7a9479af..e4dcb265 100644 --- a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m +++ b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m @@ -256,7 +256,12 @@ -(void)didReceiveAuthorizationCode:(NSString *)code -(void)didReceiveError:(NSError *)error { - //self.webLoginCallBack(NO, error); + self.webLoginCallBack(nil, YES, ^(BOOL completed, NSError* error){ + if(error) + { + DLog(@"Did not receive Authorization code"); + } + }); } #pragma mark - UI From c48f6c4f1b166739c38bd635127046025b4ec303 Mon Sep 17 00:00:00 2001 From: Mahendra Nimishakavi Date: Fri, 24 Nov 2017 20:20:07 +0530 Subject: [PATCH 21/30] improvements and error handling across --- .../services/model/MASModelService.m | 2 +- .../models/MASBrowserBasedAuthentication.h | 5 ++ .../models/MASBrowserBasedAuthentication.m | 63 +++++++++++-------- 3 files changed, 42 insertions(+), 28 deletions(-) diff --git a/MASFoundation/Classes/_private_/services/model/MASModelService.m b/MASFoundation/Classes/_private_/services/model/MASModelService.m index 6026fde9..71b6213c 100644 --- a/MASFoundation/Classes/_private_/services/model/MASModelService.m +++ b/MASFoundation/Classes/_private_/services/model/MASModelService.m @@ -39,7 +39,7 @@ @implementation MASModelService static MASGrantFlow _grantFlow_ = MASGrantFlowClientCredentials; static MASUserLoginWithUserCredentialsBlock _userLoginBlock_ = nil; static MASUserAuthCredentialsBlock _userAuthCredentialsBlock_ = nil; -static BOOL _isBrowserBasedAuthentication_; +static BOOL _isBrowserBasedAuthentication_ = NO; # pragma mark - Properties diff --git a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.h b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.h index 0994c69b..12d7f7ae 100644 --- a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.h +++ b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.h @@ -16,6 +16,11 @@ } +///-------------------------------------- +/// @name Public +///-------------------------------------- + +# pragma mark - Browser Based Authentication /** * Retrieve the shared MASBrowserBasedAuthentication singleton. diff --git a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m index e4dcb265..99d9f23b 100644 --- a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m +++ b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m @@ -51,13 +51,12 @@ -(void)loadWebLoginTemplate:(MASAuthCredentialsBlock)webLoginBlock MASModelService* service = [MASModelService sharedService]; [[MASAuthorizationResponse sharedInstance] setDelegate:self]; __block MASBrowserBasedAuthentication *blockSelf = self; - __weak __typeof__(self) weakSelf = self; + // // Try to register so that all the essential things are set up in that API call and we get a valid URL. If Application is already registered the API returns without doing any work. // [service registerApplication:^(BOOL completed, NSError *error) { [blockSelf getURLForWebLogin]; - //DLog(@"url used for browser based authentication is %@",url.absoluteString); }]; } @@ -83,14 +82,6 @@ - (void)getURLForWebLogin // Scope NSString *scope = [MASApplication currentApplication].scopeAsString; - //Remove register scopes if device is already registered (required for BBA to work) - /* if([[MASDevice currentDevice] isRegistered]) - { - scope = [scope stringByReplacingOccurrencesOfString:@"msso_client_register" withString:@""]; - scope = [scope stringByReplacingOccurrencesOfString:@"msso_register" withString:@""]; - - }*/ - // // Workaround - msso_register scope should NOT be used to retrieve authenticationProviders when it is going to be used to "authenticate" // msso_register scope should only contain for device registration with authorizationCode. @@ -161,15 +152,24 @@ - (void)getURLForWebLogin // NSString *endPoint = [MASConfiguration currentConfiguration].authorizationEndpointPath; - MASSessionDataTaskHTTPRedirectBlock oldRedirectionBlock = [[MASNetworkingService sharedService] httpRedirectionBlock]; + // + // preserve the redirection block that was set earlier + // + MASSessionDataTaskHTTPRedirectBlock previousRedirectionBlock = [[MASNetworkingService sharedService] httpRedirectionBlock]; [[MASNetworkingService sharedService] setHttpRedirectionBlock:[self getRedirectionBlock]]; + // + // This get request would result in a redirection which contains the actual URL to be loaded into browser and hence this would be canceled after the redirection + // [[MASNetworkingService sharedService] getFrom:endPoint withParameters:parameterInfo andHeaders:headerInfo requestType:MASRequestResponseTypeWwwFormUrlEncoded responseType:MASRequestResponseTypeWwwFormUrlEncoded completion:^(NSDictionary* response, NSError* error){ if(error) { + // + // This error is expected as we cancel the Get request after the redirection + // DLog(@"original request to get the url cancelled"); } - [[MASNetworkingService sharedService] setHttpRedirectionBlock:oldRedirectionBlock]; + [[MASNetworkingService sharedService] setHttpRedirectionBlock:previousRedirectionBlock]; //DLog(@"response is %@",response); }]; } @@ -192,7 +192,7 @@ -(MASSessionDataTaskHTTPRedirectBlock)getRedirectionBlock return redirectionBlock; } --(BOOL)isBBARedirection : (NSURLRequest*)request +-(BOOL)isBBARedirection:(NSURLRequest*)request { if([request.URL.absoluteString containsString:[MASConfiguration currentConfiguration].authorizationEndpointPath] && [request.URL.absoluteString containsString:@"display=template"]) { @@ -201,25 +201,31 @@ -(BOOL)isBBARedirection : (NSURLRequest*)request return NO; } --(void)launchBrowserWithURL : (NSURL*)templatizedURL +-(void)launchBrowserWithURL:(NSURL*)templatizedURL { __block MASBrowserBasedAuthentication *blockSelf = self; __weak __typeof__(self) weakSelf = self; blockSelf.safariViewController = [[SFSafariViewController alloc] initWithURL:templatizedURL]; + + if (@available(iOS 11.0, *)) { + blockSelf.safariViewController.dismissButtonStyle = SFSafariViewControllerDismissButtonStyleCancel; + } else { + // Fallback on earlier versions + } blockSelf.safariViewController.delegate = weakSelf; + __block UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:blockSelf.safariViewController]; - dispatch_async(dispatch_get_main_queue(), ^ - { - [UIAlertController rootViewController].modalTransitionStyle = UIModalTransitionStyleCoverVertical; - - [[UIAlertController rootViewController] presentViewController:navigationController animated:YES - completion:^{ - - navigationController = nil; - }]; - - return; + dispatch_async(dispatch_get_main_queue(), ^{ + [UIAlertController rootViewController].modalTransitionStyle = UIModalTransitionStyleCoverVertical; + + [[UIAlertController rootViewController] presentViewController:navigationController animated:YES + completion:^{ + + navigationController = nil; + }]; + + return; }); } @@ -231,7 +237,7 @@ -(void)safariViewControllerDidFinish:(SFSafariViewController *)controller self.webLoginCallBack(nil, YES, ^(BOOL completed, NSError* error){ if(error) { - DLog(@"Browser dismissed"); + DLog(@"Browser cancel clicked"); } }); } @@ -244,9 +250,12 @@ -(void)didReceiveAuthorizationCode:(NSString *)code MASAuthCredentialsAuthorizationCode *authCredentials = [MASAuthCredentialsAuthorizationCode initWithAuthorizationCode:code]; [[MASNetworkingService sharedService] setHttpRedirectionBlock:nil]; self.webLoginCallBack(authCredentials, NO, ^(BOOL completed, NSError* error){ + // + // In either success or error case dismiss the browser and just log the status. The caller would pass the error state/success back to user. + // if(error) { - //error + DLog(@"successfully logged in"); } DLog(@"successfully logged in"); [self dismissBrowser]; From 6a086c5c23b4bfdc32ddf15b92c037f02b8036ab Mon Sep 17 00:00:00 2001 From: Mahendra Nimishakavi Date: Mon, 27 Nov 2017 12:58:14 +0530 Subject: [PATCH 22/30] Taken care of all the indentation and spacing and complied to code guidelines of MAS --- MASFoundation/Classes/MAS.h | 3 +- MASFoundation/Classes/MAS.m | 2 +- .../services/model/MASModelService.h | 6 +- .../services/model/MASModelService.m | 4 +- .../services/network/MASNetworkingService.h | 4 +- .../network/internal/MASURLSessionManager.h | 9 ++- .../models/MASBrowserBasedAuthentication.h | 13 ++-- .../models/MASBrowserBasedAuthentication.m | 59 ++++++++++--------- 8 files changed, 56 insertions(+), 44 deletions(-) diff --git a/MASFoundation/Classes/MAS.h b/MASFoundation/Classes/MAS.h index 1e10044a..65d8de1c 100644 --- a/MASFoundation/Classes/MAS.h +++ b/MASFoundation/Classes/MAS.h @@ -110,13 +110,14 @@ + (void)setOTPCredentialsBlock:(MASOTPCredentialsBlock _Nullable)oneTimePassword; + /** * Sets Bool indicator of Browser Based Authentication (templatized login) enabled or not for authorization process. * By default, it is disabled. @param enable BOOL value indicating whether Browser Based Authentication is enabled or not. */ -+(void)enableBrowserBasedAuthentication:(BOOL)enable; ++ (void)enableBrowserBasedAuthentication:(BOOL)enable; diff --git a/MASFoundation/Classes/MAS.m b/MASFoundation/Classes/MAS.m index ef590fcd..ddda9014 100644 --- a/MASFoundation/Classes/MAS.m +++ b/MASFoundation/Classes/MAS.m @@ -92,7 +92,7 @@ + (void)setOTPCredentialsBlock:(MASOTPCredentialsBlock)oneTimePassword } -+(void)enableBrowserBasedAuthentication:(BOOL)enable ++ (void)enableBrowserBasedAuthentication:(BOOL)enable { [MASModelService setBrowserBasedAuthentication:enable]; } diff --git a/MASFoundation/Classes/_private_/services/model/MASModelService.h b/MASFoundation/Classes/_private_/services/model/MASModelService.h index f7b6b2bc..d2c356cd 100644 --- a/MASFoundation/Classes/_private_/services/model/MASModelService.h +++ b/MASFoundation/Classes/_private_/services/model/MASModelService.h @@ -82,13 +82,15 @@ - (void)setUserObject:(MASUser *)user; + /** * Sets the browser based authentication property. Default is NO. * * @param browserBasedLogin The state of browser based authentication. * If this is set to true, a URL which has a templatized login is launched in a browser and this would disable the Social Login, Proximity Login and also prevents the launch of MASUI. */ -+(void)setBrowserBasedAuthentication : (BOOL)browserBasedAuthentication; ++ (void)setBrowserBasedAuthentication:(BOOL)browserBasedAuthentication; + /** @@ -96,7 +98,7 @@ * * @return BOOL value is returned. */ -+(BOOL)browserBasedAuthentication; ++ (BOOL)browserBasedAuthentication; ///-------------------------------------- diff --git a/MASFoundation/Classes/_private_/services/model/MASModelService.m b/MASFoundation/Classes/_private_/services/model/MASModelService.m index 71b6213c..205ce5e3 100644 --- a/MASFoundation/Classes/_private_/services/model/MASModelService.m +++ b/MASFoundation/Classes/_private_/services/model/MASModelService.m @@ -72,13 +72,13 @@ - (void)setUserObject:(MASUser *)user } -+(void)setBrowserBasedAuthentication : (BOOL)browserBasedAuthentication ++ (void)setBrowserBasedAuthentication : (BOOL)browserBasedAuthentication { _isBrowserBasedAuthentication_ = browserBasedAuthentication; } -+(BOOL)browserBasedAuthentication ++ (BOOL)browserBasedAuthentication { return _isBrowserBasedAuthentication_; } diff --git a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h index ca85efab..69fc55c1 100644 --- a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h +++ b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h @@ -27,9 +27,11 @@ typedef NSURLRequest* (^MASSessionDataTaskHTTPRedirectBlock)(NSURLSession *_Nonn @property (nonatomic, assign, readonly) MASGatewayMonitoringStatus monitoringStatus; +/** + Http redirection block. Set this block only if you want to handle the redirection coming from the original NSURLRequest. + */ @property (nonatomic) MASSessionDataTaskHTTPRedirectBlock httpRedirectionBlock; -//@property (nonatomic, copy) MASSessionDataTask1CompletionBlock httpBlock; /** diff --git a/MASFoundation/Classes/_private_/services/network/internal/MASURLSessionManager.h b/MASFoundation/Classes/_private_/services/network/internal/MASURLSessionManager.h index a2c67eb5..139d8155 100644 --- a/MASFoundation/Classes/_private_/services/network/internal/MASURLSessionManager.h +++ b/MASFoundation/Classes/_private_/services/network/internal/MASURLSessionManager.h @@ -149,6 +149,13 @@ typedef void (^MASNetworkSessionDidFinishEventsForBackgroundURLSessionBlock)(NSU */ - (void)setSessionDidReceiveAuthenticationChallengeBlock:(NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential **credential))block; --(void)setSessionDidReceiveHTTPRedirectBlock : (NSURLRequest* (^)(NSURLSession *session,NSURLSessionTask *task, NSURLResponse* response,NSURLRequest *request))block; + + +/** + Set code block of session level redirection for the current NSURLRequest object. + + @param block http redirection code block. + */ +- (void)setSessionDidReceiveHTTPRedirectBlock:(NSURLRequest* (^)(NSURLSession *session,NSURLSessionTask *task, NSURLResponse* response,NSURLRequest *request))block; @end diff --git a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.h b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.h index 12d7f7ae..235634cf 100644 --- a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.h +++ b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.h @@ -11,14 +11,11 @@ #import #import "MASConstants.h" +/** + MASBrowserBasedAuthentication class is a helper class to utilize SFSafariViewController to launch a customized login template. + * This class will get the redirection to receive the authorization code to perform login. + */ @interface MASBrowserBasedAuthentication : NSObject -{ - -} - -///-------------------------------------- -/// @name Public -///-------------------------------------- # pragma mark - Browser Based Authentication @@ -36,6 +33,6 @@ * * @param webLoginBlock completion MASCompletionErrorBlock that receives the results. */ --(void)loadWebLoginTemplate:(MASAuthCredentialsBlock)webLoginBlock; +- (void)loadWebLoginTemplate:(MASAuthCredentialsBlock)webLoginBlock; @end diff --git a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m index 99d9f23b..56efa02a 100644 --- a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m +++ b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m @@ -8,28 +8,27 @@ // of the MIT license. See the LICENSE file for details. // -#import "MASBrowserBasedAuthentication.h" -#import +#import "MASAccessService.h" #import "MASAuthorizationResponse.h" -#import "UIAlertController+MAS.h" +#import "MASBrowserBasedAuthentication.h" #import "MASConfigurationService.h" -#import "MASAccessService.h" #import "MASGetURLRequest.h" #import "MASModelService.h" +#import "UIAlertController+MAS.h" +#import @interface MASBrowserBasedAuthentication () { } -@property (nonatomic) SFSafariViewController* safariViewController; +@property (nonatomic) SFSafariViewController *safariViewController; @property (nonatomic) MASAuthCredentialsBlock webLoginCallBack; @end @implementation MASBrowserBasedAuthentication - # pragma mark - Shared Service + (instancetype)sharedInstance @@ -141,7 +140,7 @@ - (void)getURLForWebLogin //Put the mag-identifier in the url as query parameter for the device to be identified NSString* magIdentifier = [[MASAccessService sharedService] getAccessValueStringWithStorageKey:MASKeychainStorageKeyMAGIdentifier]; - //DLog(@"mag-identifier is %@",magIdentifier); + if(magIdentifier && magIdentifier.length > 0) { parameterInfo[MASMagIdentifierRequestResponseKey] = magIdentifier; @@ -157,36 +156,37 @@ - (void)getURLForWebLogin // MASSessionDataTaskHTTPRedirectBlock previousRedirectionBlock = [[MASNetworkingService sharedService] httpRedirectionBlock]; [[MASNetworkingService sharedService] setHttpRedirectionBlock:[self getRedirectionBlock]]; + // // This get request would result in a redirection which contains the actual URL to be loaded into browser and hence this would be canceled after the redirection // [[MASNetworkingService sharedService] getFrom:endPoint withParameters:parameterInfo andHeaders:headerInfo requestType:MASRequestResponseTypeWwwFormUrlEncoded responseType:MASRequestResponseTypeWwwFormUrlEncoded completion:^(NSDictionary* response, NSError* error){ - if(error) - { - // - // This error is expected as we cancel the Get request after the redirection - // - DLog(@"original request to get the url cancelled"); - } - [[MASNetworkingService sharedService] setHttpRedirectionBlock:previousRedirectionBlock]; - //DLog(@"response is %@",response); + if(error) + { + // + // This error is expected as we cancel the Get request after the redirection + // + DLog(@"original request to get the url cancelled"); + } + + [[MASNetworkingService sharedService] setHttpRedirectionBlock:previousRedirectionBlock]; }]; } -(MASSessionDataTaskHTTPRedirectBlock)getRedirectionBlock { MASSessionDataTaskHTTPRedirectBlock redirectionBlock = ^(NSURLSession *session, NSURLSessionTask *task, NSURLResponse * response, NSURLRequest *request){ - NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; - if(httpResponse.statusCode == 302 && [self isBBARedirection:task.originalRequest]) - { - DLog(@"all headers %@",httpResponse.allHeaderFields); - NSString* locationURL = [httpResponse.allHeaderFields objectForKey:@"Location"]; - NSURL* redirectURL = [NSURL URLWithString:locationURL]; - [task cancel]; - [self launchBrowserWithURL:redirectURL]; - } - return request; + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; + if(httpResponse.statusCode == 302 && [self isBBARedirection:task.originalRequest]) + { + DLog(@"all headers %@",httpResponse.allHeaderFields); + NSString* locationURL = [httpResponse.allHeaderFields objectForKey:@"Location"]; + NSURL* redirectURL = [NSURL URLWithString:locationURL]; + [task cancel]; + [self launchBrowserWithURL:redirectURL]; + } + return request; }; return redirectionBlock; @@ -198,6 +198,7 @@ -(BOOL)isBBARedirection:(NSURLRequest*)request { return YES; } + return NO; } @@ -209,7 +210,8 @@ -(void)launchBrowserWithURL:(NSURL*)templatizedURL if (@available(iOS 11.0, *)) { blockSelf.safariViewController.dismissButtonStyle = SFSafariViewControllerDismissButtonStyleCancel; - } else { + } + else { // Fallback on earlier versions } blockSelf.safariViewController.delegate = weakSelf; @@ -222,7 +224,7 @@ -(void)launchBrowserWithURL:(NSURL*)templatizedURL [[UIAlertController rootViewController] presentViewController:navigationController animated:YES completion:^{ - navigationController = nil; + navigationController = nil; }]; return; @@ -249,6 +251,7 @@ -(void)didReceiveAuthorizationCode:(NSString *)code { MASAuthCredentialsAuthorizationCode *authCredentials = [MASAuthCredentialsAuthorizationCode initWithAuthorizationCode:code]; [[MASNetworkingService sharedService] setHttpRedirectionBlock:nil]; + self.webLoginCallBack(authCredentials, NO, ^(BOOL completed, NSError* error){ // // In either success or error case dismiss the browser and just log the status. The caller would pass the error state/success back to user. From a1a55ab47d1830574470f073fb7374c9b0d8f3c5 Mon Sep 17 00:00:00 2001 From: James Go Date: Mon, 27 Nov 2017 13:02:08 -0800 Subject: [PATCH 23/30] US427126 : [iOS] Update SDK Version, and ChangeLog --- CHANGELOG.md | 24 ++++++++++++++++++++++-- MASFoundation.xcodeproj/project.pbxproj | 4 ++-- MASFoundation/Info.plist | 2 +- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5508e73e..18e1cf7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,23 @@ +# Version 1.6.00 + +### Bug fixes +- `MASAuthCredentialsJWT` credentials was marked as re-usable, so that Mobile SDK tried to consume same credentials for a certian period of time. It is fixed that JWT credentials can only be consumed one time, and not re-usable. [DE324462] +- Device de-registration was removing all credentials from Mobile SDK regardless of the result of de-registration request. It is fixed that Mobile SDK will only remove credentials when de-registration request succeeds. +- Mobile SDK was changing `MASGrantFlow` to client credentials in certain scenario with Cordova SDK. It is fixed that Mobile SDK will not switch the `MASGrantFlow` by itself. +- Mobile SDK enhances device registration flow, so that it can handle the device registration record more smoothly. This will remove hassle for developers seeing "This device has already been registered and has not been configured to accept updates" error message while development phase. [US406920] +- `MASConfiguration` was not properly updating the updated endpoint values when switching to a different configuration. It is now fixed. [DE321925] +- `MASConfiguration` had some hard-coded values for client credentials device registration endpoint. `MASConfiguration` will now always read the value from the configuration. [DE321921] +- `MASMQTTClient` was not able to re-establish MQTT connection when the user session is logged-out, and logs-in with different account. Mobile SDK will now properly handle session change for MQTT connection. [US408725] +- Mobile SDK now only stores all credentials to the device only. All data will not be backed-up or transferred with iCloud unless otherwise `[MAS setKeychainSynchroizable:]` is explicitly set to `YES`. [US388853] +- Mobile SDK's MQTT connection was not able to establish mutual SSL connection with public CA certificate. It is fixed now that Mobile SDK can establish mutual SSL with public CA certificate when **entire certificate chain** is exported in JSON configuration. [US399506] + +### New features +- Mobile SDK introduces a secure way of storing and sharing data across multiple applications using same keychain sharing group with MASFoundation's `MASSharedStorage` class. [US416558] +- Mobile SDK introduces a new way of building API CRUD request with `MASRequestBuilder` and `MASRequest` classes to provide seamless developer experience Android SDK. [US374082] + +### Deprecated methods +- `[MASConfiguration setSecurityConfiguration:]` is deperecated. Please use `[MASSecurityConfiguration setSecurityConfiguration:error:]` for better handling of error cases while setting security configuration object. [DE328373] + # Version 1.5.00 NOTE: From this version on the frameworks changed to Dynamic instead of Static library @@ -12,14 +32,14 @@ NOTE: From this version on the frameworks changed to Dynamic instead of Static l - The SDK no longer requires Keychain Sharing to be enabled in Xcode. However, to establish SSO across multiple applications, Keychain Sharing must be enabled. [US320771] - Mobile SDK now only validates against the leaf certificate for SSL pinning validation by default. The configuration can be changed to validate against entire certificate chain through `MASSecurityConfiguration`. [US374086] -### New Features +### New features - Mobile SDK introduces an ability to configure security configuration for external APIs (such as SSL pinning), so that Mobile SDK can securely connect to external API (other than primary Gateway). [US344780] - The SDK handles multiple concurrent API requests with proper authentication processes. [US362800] - The SDK supports dynamic framework. All you need to do is update your Xcode settings. [US367604] - The SDK introduces more flexible and extensible authentication with different types of credentials. For details, see `MASAuthCredentials`. [US349497] - The SDK introduces the ability to digitally sign the request as JWT. See `MASClaims` to sign the request. [US313137] -### Deprecated Methods +### Deprecated methods - `[MAS setUserLoginBlock:]` is deprecated. Please use `[MAS setAuthCredentials:]` block to perform implicit authentication with `MASAuthCredentials` object. diff --git a/MASFoundation.xcodeproj/project.pbxproj b/MASFoundation.xcodeproj/project.pbxproj index cac3bf9e..7589be77 100644 --- a/MASFoundation.xcodeproj/project.pbxproj +++ b/MASFoundation.xcodeproj/project.pbxproj @@ -2318,7 +2318,7 @@ buildSettings = { CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - CURRENT_PROJECT_VERSION = 1.5.00; + CURRENT_PROJECT_VERSION = 1.6.00; DEAD_CODE_STRIPPING = YES; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; @@ -2363,7 +2363,7 @@ buildSettings = { CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - CURRENT_PROJECT_VERSION = 1.5.00; + CURRENT_PROJECT_VERSION = 1.6.00; DEAD_CODE_STRIPPING = YES; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; diff --git a/MASFoundation/Info.plist b/MASFoundation/Info.plist index 033da143..6c0ca926 100644 --- a/MASFoundation/Info.plist +++ b/MASFoundation/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.5 + 1.6 CFBundleSignature ???? CFBundleVersion From 56f4ea532fcc41bf30f259046fa029af76d72b73 Mon Sep 17 00:00:00 2001 From: bmckercher Date: Mon, 27 Nov 2017 14:19:08 -0800 Subject: [PATCH 24/30] Minor edits --- CHANGELOG.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18e1cf7f..d396e8db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,22 +1,22 @@ # Version 1.6.00 ### Bug fixes -- `MASAuthCredentialsJWT` credentials was marked as re-usable, so that Mobile SDK tried to consume same credentials for a certian period of time. It is fixed that JWT credentials can only be consumed one time, and not re-usable. [DE324462] -- Device de-registration was removing all credentials from Mobile SDK regardless of the result of de-registration request. It is fixed that Mobile SDK will only remove credentials when de-registration request succeeds. -- Mobile SDK was changing `MASGrantFlow` to client credentials in certain scenario with Cordova SDK. It is fixed that Mobile SDK will not switch the `MASGrantFlow` by itself. -- Mobile SDK enhances device registration flow, so that it can handle the device registration record more smoothly. This will remove hassle for developers seeing "This device has already been registered and has not been configured to accept updates" error message while development phase. [US406920] -- `MASConfiguration` was not properly updating the updated endpoint values when switching to a different configuration. It is now fixed. [DE321925] -- `MASConfiguration` had some hard-coded values for client credentials device registration endpoint. `MASConfiguration` will now always read the value from the configuration. [DE321921] -- `MASMQTTClient` was not able to re-establish MQTT connection when the user session is logged-out, and logs-in with different account. Mobile SDK will now properly handle session change for MQTT connection. [US408725] -- Mobile SDK now only stores all credentials to the device only. All data will not be backed-up or transferred with iCloud unless otherwise `[MAS setKeychainSynchroizable:]` is explicitly set to `YES`. [US388853] -- Mobile SDK's MQTT connection was not able to establish mutual SSL connection with public CA certificate. It is fixed now that Mobile SDK can establish mutual SSL with public CA certificate when **entire certificate chain** is exported in JSON configuration. [US399506] +- `MASAuthCredentialsJWT` credentials was marked as re-usable, so the Mobile SDK tried to consume the same credentials for a certain period of time. JWT credentials can now be consumed only one time, and is not reusable. [DE324462] +- Device deregistration was removing all credentials from the Mobile SDK regardless of the result of deregistration request. Now, the Mobile SDK removes credentials only when the deregistration request succeeds. +- Mobile SDK was changing `MASGrantFlow` to client credentials in a specific scenario with Cordova SDK. The Mobile SDK no longer switches the `MASGrantFlow` by itself. +- Mobile SDK enhances the device registration flow so it handles the device registration record more smoothly. This removes the hassle of developers seeing "This device has already been registered and has not been configured to accept updates" error message in development phase. [US406920] +- `MASConfiguration` was not properly updating the updated endpoint values when switching to a different configuration. It is fixed. [DE321925] +- `MASConfiguration` had some hard-coded values for client credentials device registration endpoint. `MASConfiguration` now reads the value from the configuration. [DE321921] +- `MASMQTTClient` was unable to reestablish MQTT connection when the user session was logged out, and logged in with a different account. Mobile SDK now properly handles session changes for MQTT connection. [US408725] +- Mobile SDK now stores all credentials only to the device. Data will not be backed-up or transferred with iCloud unless `[MAS setKeychainSynchroizable:]` is explicitly set to `YES`. [US388853] +- Mobile SDK's MQTT connection was unable to establish mutual SSL connection with public CA certificate. The Mobile SDK now establishes mutual SSL with public CA certificate when **entire certificate chain** is exported in JSON configuration. [US399506] ### New features - Mobile SDK introduces a secure way of storing and sharing data across multiple applications using same keychain sharing group with MASFoundation's `MASSharedStorage` class. [US416558] - Mobile SDK introduces a new way of building API CRUD request with `MASRequestBuilder` and `MASRequest` classes to provide seamless developer experience Android SDK. [US374082] ### Deprecated methods -- `[MASConfiguration setSecurityConfiguration:]` is deperecated. Please use `[MASSecurityConfiguration setSecurityConfiguration:error:]` for better handling of error cases while setting security configuration object. [DE328373] +- `[MASConfiguration setSecurityConfiguration:]` is deperecated. Please use `[MASSecurityConfiguration setSecurityConfiguration:error:]` for better handling of error cases when setting the security configuration object. [DE328373] # Version 1.5.00 From d2e6374d9c6d627b7db2a2fcbfad016cfa8bc980 Mon Sep 17 00:00:00 2001 From: bmckercher Date: Mon, 27 Nov 2017 15:44:14 -0800 Subject: [PATCH 25/30] Updated link Link to delete Start the SDK video. --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index abc786b3..81fc427a 100644 --- a/README.md +++ b/README.md @@ -72,9 +72,7 @@ For manual install, you add the Mobile SDK to your Xcode project. Note that you ## Set Up Project and Start the SDK -The following ***video*** describes how to set up the project and start the Mobile SDK. - -[![IMAGE ALT TEXT](http://img.youtube.com/vi/h95MF55Uuuw/0.jpg)](http://www.youtube.com/watch?v=h95MF55Uuuw "Starting the SDK") +To start your project, see [developer site](https://mas.ca.com/docs) After your project is properly configured, you must start the SDK to establish a secure connection with the backend services. The startup process includes: initialize necessary services for library (such as geo-location, BLE, and network services), and load configuration. From d7e950a3d16ce86da9cb499092056fc4343b098a Mon Sep 17 00:00:00 2001 From: Mahendra Nimishakavi Date: Wed, 29 Nov 2017 12:55:43 +0530 Subject: [PATCH 26/30] remove code related to iOS 11 and changed navigation for Safariviewcontroller to show done button for all versions of iOS --- .../models/MASBrowserBasedAuthentication.m | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m index 56efa02a..1b759628 100644 --- a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m +++ b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m @@ -207,24 +207,15 @@ -(void)launchBrowserWithURL:(NSURL*)templatizedURL __block MASBrowserBasedAuthentication *blockSelf = self; __weak __typeof__(self) weakSelf = self; blockSelf.safariViewController = [[SFSafariViewController alloc] initWithURL:templatizedURL]; - - if (@available(iOS 11.0, *)) { - blockSelf.safariViewController.dismissButtonStyle = SFSafariViewControllerDismissButtonStyleCancel; - } - else { - // Fallback on earlier versions - } - blockSelf.safariViewController.delegate = weakSelf; - - __block UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:blockSelf.safariViewController]; + blockSelf.safariViewController.delegate = weakSelf; dispatch_async(dispatch_get_main_queue(), ^{ [UIAlertController rootViewController].modalTransitionStyle = UIModalTransitionStyleCoverVertical; - [[UIAlertController rootViewController] presentViewController:navigationController animated:YES + [[UIAlertController rootViewController] presentViewController:blockSelf.safariViewController animated:YES completion:^{ - navigationController = nil; + DLog(@"Successfully displayed login template"); }]; return; From 75f7746e6050216e56e381532e95a6ac45151ccf Mon Sep 17 00:00:00 2001 From: Mahendra Nimishakavi Date: Fri, 1 Dec 2017 17:20:02 +0530 Subject: [PATCH 27/30] checking if the redirect url is good and taking necessary action --- .../_private_/services/MASServiceRegistry.h | 2 +- .../_private_/services/MASServiceRegistry.m | 2 +- .../models/MASBrowserBasedAuthentication.m | 38 ++++++++++++++----- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/MASFoundation/Classes/_private_/services/MASServiceRegistry.h b/MASFoundation/Classes/_private_/services/MASServiceRegistry.h index 781e5f37..d2c18078 100644 --- a/MASFoundation/Classes/_private_/services/MASServiceRegistry.h +++ b/MASFoundation/Classes/_private_/services/MASServiceRegistry.h @@ -196,6 +196,6 @@ typedef NS_ENUM(NSInteger, MASRegistryState) * @param bbaLoginBlock The MASAuthCredentialsBlock to receive login result. * @return Return YES if handled, NO if not. */ --(BOOL)browserBasedLoginWillHandleAuthentication : (MASAuthCredentialsBlock)bbaLoginBlock; +- (BOOL)browserBasedLoginWillHandleAuthentication : (MASAuthCredentialsBlock)bbaLoginBlock; @end diff --git a/MASFoundation/Classes/_private_/services/MASServiceRegistry.m b/MASFoundation/Classes/_private_/services/MASServiceRegistry.m index d7148fc4..f0b11b73 100644 --- a/MASFoundation/Classes/_private_/services/MASServiceRegistry.m +++ b/MASFoundation/Classes/_private_/services/MASServiceRegistry.m @@ -935,7 +935,7 @@ - (BOOL)uiServiceWillHandleOTPChannelSelection:(NSArray *)supportedChannels } --(BOOL)browserBasedLoginWillHandleAuthentication : (MASAuthCredentialsBlock)bbaLoginBlock +- (BOOL)browserBasedLoginWillHandleAuthentication : (MASAuthCredentialsBlock)bbaLoginBlock { if(![MASModelService browserBasedAuthentication]) { diff --git a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m index 1b759628..a605b165 100644 --- a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m +++ b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m @@ -44,7 +44,7 @@ + (instancetype)sharedInstance } --(void)loadWebLoginTemplate:(MASAuthCredentialsBlock)webLoginBlock +- (void)loadWebLoginTemplate:(MASAuthCredentialsBlock)webLoginBlock { self.webLoginCallBack = webLoginBlock; MASModelService* service = [MASModelService sharedService]; @@ -174,8 +174,9 @@ - (void)getURLForWebLogin }]; } --(MASSessionDataTaskHTTPRedirectBlock)getRedirectionBlock +- (MASSessionDataTaskHTTPRedirectBlock)getRedirectionBlock { + __block MASBrowserBasedAuthentication *blockSelf = self; MASSessionDataTaskHTTPRedirectBlock redirectionBlock = ^(NSURLSession *session, NSURLSessionTask *task, NSURLResponse * response, NSURLRequest *request){ NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; if(httpResponse.statusCode == 302 && [self isBBARedirection:task.originalRequest]) @@ -184,7 +185,14 @@ -(MASSessionDataTaskHTTPRedirectBlock)getRedirectionBlock NSString* locationURL = [httpResponse.allHeaderFields objectForKey:@"Location"]; NSURL* redirectURL = [NSURL URLWithString:locationURL]; [task cancel]; - [self launchBrowserWithURL:redirectURL]; + + if(![blockSelf redirectURLHasErrors:redirectURL]) + { + [blockSelf launchBrowserWithURL:redirectURL]; + } + else{ + blockSelf.webLoginCallBack(nil, YES, nil); + } } return request; }; @@ -192,7 +200,7 @@ -(MASSessionDataTaskHTTPRedirectBlock)getRedirectionBlock return redirectionBlock; } --(BOOL)isBBARedirection:(NSURLRequest*)request +- (BOOL)isBBARedirection:(NSURLRequest*)request { if([request.URL.absoluteString containsString:[MASConfiguration currentConfiguration].authorizationEndpointPath] && [request.URL.absoluteString containsString:@"display=template"]) { @@ -202,7 +210,19 @@ -(BOOL)isBBARedirection:(NSURLRequest*)request return NO; } --(void)launchBrowserWithURL:(NSURL*)templatizedURL + +- (BOOL)redirectURLHasErrors :(NSURL*)redirectURL +{ + NSString* redirectURLString = redirectURL.absoluteString; + if([redirectURLString containsString:@"x-ca-err"] && [redirectURLString containsString:@"error"] && [redirectURLString containsString:@"error_description"]) + { + return YES; + } + return NO; +} + + +- (void)launchBrowserWithURL:(NSURL*)templatizedURL { __block MASBrowserBasedAuthentication *blockSelf = self; __weak __typeof__(self) weakSelf = self; @@ -225,7 +245,7 @@ -(void)launchBrowserWithURL:(NSURL*)templatizedURL #pragma mark - SafariViewController Delegates --(void)safariViewControllerDidFinish:(SFSafariViewController *)controller +- (void)safariViewControllerDidFinish:(SFSafariViewController *)controller { self.webLoginCallBack(nil, YES, ^(BOOL completed, NSError* error){ if(error) @@ -238,7 +258,7 @@ -(void)safariViewControllerDidFinish:(SFSafariViewController *)controller #pragma mark - Authorization Response delegate --(void)didReceiveAuthorizationCode:(NSString *)code +- (void)didReceiveAuthorizationCode:(NSString *)code { MASAuthCredentialsAuthorizationCode *authCredentials = [MASAuthCredentialsAuthorizationCode initWithAuthorizationCode:code]; [[MASNetworkingService sharedService] setHttpRedirectionBlock:nil]; @@ -257,7 +277,7 @@ -(void)didReceiveAuthorizationCode:(NSString *)code } --(void)didReceiveError:(NSError *)error +- (void)didReceiveError:(NSError *)error { self.webLoginCallBack(nil, YES, ^(BOOL completed, NSError* error){ if(error) @@ -269,7 +289,7 @@ -(void)didReceiveError:(NSError *)error #pragma mark - UI --(void)dismissBrowser +- (void)dismissBrowser { dispatch_async(dispatch_get_main_queue(), ^{ [[UIAlertController rootViewController] dismissViewControllerAnimated:YES completion:nil]; From eab6edb24f0e9748de24e93b83515008b90cdab7 Mon Sep 17 00:00:00 2001 From: Mahendra Nimishakavi Date: Wed, 6 Dec 2017 14:46:02 +0530 Subject: [PATCH 28/30] resolving defect where a server does not respond to the authorize call or there is a invalid redirect URI --- .../Classes/models/MASBrowserBasedAuthentication.m | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m index a605b165..8a9b792b 100644 --- a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m +++ b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m @@ -156,18 +156,21 @@ - (void)getURLForWebLogin // MASSessionDataTaskHTTPRedirectBlock previousRedirectionBlock = [[MASNetworkingService sharedService] httpRedirectionBlock]; [[MASNetworkingService sharedService] setHttpRedirectionBlock:[self getRedirectionBlock]]; + __block MASBrowserBasedAuthentication *blockSelf = self; // // This get request would result in a redirection which contains the actual URL to be loaded into browser and hence this would be canceled after the redirection // [[MASNetworkingService sharedService] getFrom:endPoint withParameters:parameterInfo andHeaders:headerInfo requestType:MASRequestResponseTypeWwwFormUrlEncoded responseType:MASRequestResponseTypeWwwFormUrlEncoded completion:^(NSDictionary* response, NSError* error){ - if(error) + // + // We expect this API to be cancelled in the redirection and hence the only acceptable error here is cancel.Any other error could mean an error for authenticaion itself. Hence cancel authorization. + // + if(error.code != NSURLErrorCancelled) { - // - // This error is expected as we cancel the Get request after the redirection - // - DLog(@"original request to get the url cancelled"); + DLog(@"error occured in BBA error info: %@",error); + blockSelf.webLoginCallBack(nil, YES, nil); + return; } [[MASNetworkingService sharedService] setHttpRedirectionBlock:previousRedirectionBlock]; From c26af70abf44af063e9bfe0628459b44f06987ae Mon Sep 17 00:00:00 2001 From: James Go Date: Tue, 12 Dec 2017 09:26:26 -0800 Subject: [PATCH 29/30] US427126 : Updating ChangeLog.md with reference --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d396e8db..75b2c53e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,8 @@ ### Bug fixes - `MASAuthCredentialsJWT` credentials was marked as re-usable, so the Mobile SDK tried to consume the same credentials for a certain period of time. JWT credentials can now be consumed only one time, and is not reusable. [DE324462] -- Device deregistration was removing all credentials from the Mobile SDK regardless of the result of deregistration request. Now, the Mobile SDK removes credentials only when the deregistration request succeeds. -- Mobile SDK was changing `MASGrantFlow` to client credentials in a specific scenario with Cordova SDK. The Mobile SDK no longer switches the `MASGrantFlow` by itself. +- Device deregistration was removing all credentials from the Mobile SDK regardless of the result of deregistration request. Now, the Mobile SDK removes credentials only when the deregistration request succeeds. [DE324142] +- Mobile SDK was changing `MASGrantFlow` to client credentials in a specific scenario with Cordova SDK. The Mobile SDK no longer switches the `MASGrantFlow` by itself. [DE311841] - Mobile SDK enhances the device registration flow so it handles the device registration record more smoothly. This removes the hassle of developers seeing "This device has already been registered and has not been configured to accept updates" error message in development phase. [US406920] - `MASConfiguration` was not properly updating the updated endpoint values when switching to a different configuration. It is fixed. [DE321925] - `MASConfiguration` had some hard-coded values for client credentials device registration endpoint. `MASConfiguration` now reads the value from the configuration. [DE321921] From e13a83a4046ef98d7977393ab9fdca1bc1c22df4 Mon Sep 17 00:00:00 2001 From: James Go Date: Tue, 12 Dec 2017 09:47:12 -0800 Subject: [PATCH 30/30] US427126 : Updating ChangeLog.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75b2c53e..e68e92fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,7 @@ - Mobile SDK introduces a new way of building API CRUD request with `MASRequestBuilder` and `MASRequest` classes to provide seamless developer experience Android SDK. [US374082] ### Deprecated methods -- `[MASConfiguration setSecurityConfiguration:]` is deperecated. Please use `[MASSecurityConfiguration setSecurityConfiguration:error:]` for better handling of error cases when setting the security configuration object. [DE328373] +- `[MASConfiguration setSecurityConfiguration:]` is deprecated. Please use `[MASSecurityConfiguration setSecurityConfiguration:error:]` for better handling of error cases when setting the security configuration object. [DE328373] # Version 1.5.00