Skip to content

Commit bd48ccb

Browse files
authored
Add unit tests for AMR claim (#575)
1 parent 234580e commit bd48ccb

File tree

3 files changed

+116
-41
lines changed

3 files changed

+116
-41
lines changed

GoogleSignIn/Tests/Unit/GIDSignInTest.m

Lines changed: 102 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,18 @@
160160
static NSString *const kGrantedScope = @"grantedScope";
161161
static NSString *const kNewScope = @"newScope";
162162

163-
static NSString *const kEssentialAuthTimeClaimsJsonString =
163+
static NSString *const kEssentialAuthTimeClaimJsonString =
164164
@"{\"id_token\":{\"auth_time\":{\"essential\":true}}}";
165-
static NSString *const kNonEssentialAuthTimeClaimsJsonString =
165+
static NSString *const kNonEssentialAuthTimeClaimJsonString =
166166
@"{\"id_token\":{\"auth_time\":{\"essential\":false}}}";
167167

168+
static NSString *const kEssentialAMRClaimJsonString =
169+
@"{\"id_token\":{\"amr\":{\"essential\":true}}}";
170+
static NSString *const kNonEssentialAMRClaimJsonString =
171+
@"{\"id_token\":{\"amr\":{\"essential\":false}}}";
172+
173+
static NSString *const kMultipleClaimsJsonString =
174+
@"{\"id_token\":{\"amr\":{\"essential\":false},\"auth_time\":{\"essential\":false}}}";
168175

169176
#if TARGET_OS_IOS || TARGET_OS_MACCATALYST
170177
// This category is used to allow the test to swizzle a private method.
@@ -751,7 +758,7 @@ - (void)testOAuthLogin_AdditionalScopes {
751758
XCTAssertEqualObjects(_savedAuthorizationRequest.scope, expectedScopeString);
752759
}
753760

754-
- (void)testOAuthLogin_WithClaims_FormatsParametersCorrectly {
761+
- (void)testOAuthLogin_WithAuthTimeClaim_FormatsParametersCorrectly {
755762
GIDClaim *authTimeClaim = [GIDClaim authTimeClaim];
756763
GIDClaim *essentialAuthTimeClaim = [GIDClaim essentialAuthTimeClaim];
757764

@@ -776,7 +783,7 @@ - (void)testOAuthLogin_WithClaims_FormatsParametersCorrectly {
776783
claims:[NSSet setWithObject:essentialAuthTimeClaim]];
777784

778785
XCTAssertEqualObjects(_savedAuthorizationRequest.additionalParameters[@"claims"],
779-
kEssentialAuthTimeClaimsJsonString,
786+
kEssentialAuthTimeClaimJsonString,
780787
@"Claims JSON should be correctly formatted");
781788

782789
[self OAuthLoginWithAddScopesFlow:NO
@@ -795,12 +802,62 @@ - (void)testOAuthLogin_WithClaims_FormatsParametersCorrectly {
795802
claims:[NSSet setWithObject:authTimeClaim]];
796803

797804
XCTAssertEqualObjects(_savedAuthorizationRequest.additionalParameters[@"claims"],
798-
kNonEssentialAuthTimeClaimsJsonString,
805+
kNonEssentialAuthTimeClaimJsonString,
806+
@"Claims JSON should be correctly formatted");
807+
}
808+
809+
- (void)testOAuthLogin_WithAMRClaim_FormatsParametersCorrectly {
810+
GIDClaim *AMRClaim = [GIDClaim AMRClaim];
811+
GIDClaim *essentialAMRClaim = [GIDClaim essentialAMRClaim];
812+
813+
OCMStub([_keychainStore saveAuthSession:OCMOCK_ANY error:OCMArg.anyObjectRef]
814+
).andDo(^(NSInvocation *invocation){
815+
self->_keychainSaved = self->_saveAuthorizationReturnValue;
816+
});
817+
818+
[self OAuthLoginWithAddScopesFlow:NO
819+
authError:nil
820+
tokenError:nil
821+
emmPasscodeInfoRequired:NO
822+
claimsAsJSONRequired:NO
823+
keychainError:NO
824+
claimsError:NO
825+
restoredSignIn:NO
826+
oldAccessToken:NO
827+
modalCancel:NO
828+
useAdditionalScopes:NO
829+
additionalScopes:nil
830+
manualNonce:nil
831+
claims:[NSSet setWithObject:essentialAMRClaim]];
832+
833+
XCTAssertEqualObjects(_savedAuthorizationRequest.additionalParameters[@"claims"],
834+
kEssentialAMRClaimJsonString,
835+
@"Claims JSON should be correctly formatted");
836+
837+
[self OAuthLoginWithAddScopesFlow:NO
838+
authError:nil
839+
tokenError:nil
840+
emmPasscodeInfoRequired:NO
841+
claimsAsJSONRequired:NO
842+
keychainError:NO
843+
claimsError:NO
844+
restoredSignIn:NO
845+
oldAccessToken:NO
846+
modalCancel:NO
847+
useAdditionalScopes:NO
848+
additionalScopes:nil
849+
manualNonce:nil
850+
claims:[NSSet setWithObject:AMRClaim]];
851+
852+
XCTAssertEqualObjects(_savedAuthorizationRequest.additionalParameters[@"claims"],
853+
kNonEssentialAMRClaimJsonString,
799854
@"Claims JSON should be correctly formatted");
800855
}
801856

802-
- (void)testOAuthLogin_WithClaims_ReturnsIdTokenWithCorrectClaims {
857+
- (void)testOAuthLogin_WithMultipleClaims_FormatsParametersCorrectly {
803858
GIDClaim *authTimeClaim = [GIDClaim authTimeClaim];
859+
GIDClaim *AMRClaim = [GIDClaim AMRClaim];
860+
NSSet *claims = [NSSet setWithArray:@[authTimeClaim, AMRClaim]];
804861

805862
OCMStub([_keychainStore saveAuthSession:OCMOCK_ANY error:OCMArg.anyObjectRef]
806863
).andDo(^(NSInvocation *invocation){
@@ -820,7 +877,37 @@ - (void)testOAuthLogin_WithClaims_ReturnsIdTokenWithCorrectClaims {
820877
useAdditionalScopes:NO
821878
additionalScopes:nil
822879
manualNonce:nil
823-
claims:[NSSet setWithObject:authTimeClaim]];
880+
claims:claims];
881+
882+
XCTAssertEqualObjects(_savedAuthorizationRequest.additionalParameters[@"claims"],
883+
kMultipleClaimsJsonString,
884+
@"Claims JSON should be correctly formatted");
885+
}
886+
887+
- (void)testOAuthLogin_WithMultipleClaims_ReturnsIdTokenWithCorrectClaims {
888+
GIDClaim *authTimeClaim = [GIDClaim authTimeClaim];
889+
GIDClaim *AMRClaim = [GIDClaim AMRClaim];
890+
NSSet *claims = [NSSet setWithArray:@[authTimeClaim, AMRClaim]];
891+
892+
OCMStub([_keychainStore saveAuthSession:OCMOCK_ANY error:OCMArg.anyObjectRef]
893+
).andDo(^(NSInvocation *invocation){
894+
self->_keychainSaved = self->_saveAuthorizationReturnValue;
895+
});
896+
897+
[self OAuthLoginWithAddScopesFlow:NO
898+
authError:nil
899+
tokenError:nil
900+
emmPasscodeInfoRequired:NO
901+
claimsAsJSONRequired:NO
902+
keychainError:NO
903+
claimsError:NO
904+
restoredSignIn:NO
905+
oldAccessToken:NO
906+
modalCancel:NO
907+
useAdditionalScopes:NO
908+
additionalScopes:nil
909+
manualNonce:nil
910+
claims:claims];
824911

825912
XCTAssertNotNil(_signIn.currentUser, @"The currentUser should not be nil after a successful sign-in.");
826913
NSString *idTokenString = _signIn.currentUser.idToken.tokenString;
@@ -830,10 +917,13 @@ - (void)testOAuthLogin_WithClaims_ReturnsIdTokenWithCorrectClaims {
830917
NSData *payloadData = [[NSData alloc]
831918
initWithBase64EncodedString:components[1]
832919
options:NSDataBase64DecodingIgnoreUnknownCharacters];
833-
NSDictionary *claims = [NSJSONSerialization JSONObjectWithData:payloadData options:0 error:nil];
834-
XCTAssertEqualObjects(claims[@"auth_time"],
920+
NSDictionary *receivedClaims = [NSJSONSerialization JSONObjectWithData:payloadData options:0 error:nil];
921+
XCTAssertEqualObjects(receivedClaims[@"auth_time"],
835922
kAuthTime,
836923
@"The 'auth_time' claim should be present and correct.");
924+
XCTAssertEqualObjects(receivedClaims[@"amr"],
925+
[OIDTokenResponse stubbedAMRValues],
926+
@"The 'amr' claim should be present and correct.");
837927
}
838928

839929
- (void)testAddScopes {
@@ -963,7 +1053,7 @@ - (void)testAddScopes_WithPreviouslyRequestedClaims {
9631053
NSArray<NSString *> *expectedScopes = @[kNewScope, kGrantedScope];
9641054
XCTAssertEqualObjects(grantedScopes, expectedScopes);
9651055
XCTAssertEqualObjects(_savedAuthorizationRequest.additionalParameters[@"claims"],
966-
kNonEssentialAuthTimeClaimsJsonString,
1056+
kNonEssentialAuthTimeClaimJsonString,
9671057
@"Claims JSON should be correctly formatted");
9681058

9691059
[_user verify];
@@ -1688,7 +1778,7 @@ - (void)OAuthLoginWithAddScopesFlow:(BOOL)addScopesFlow
16881778
nonce:nonce
16891779
errorString:authError];
16901780

1691-
NSString *idToken = claims ? [OIDTokenResponse fatIDTokenWithAuthTime] : [OIDTokenResponse fatIDToken];
1781+
NSString *idToken = claims ? [OIDTokenResponse fatIDTokenWithClaims] : [OIDTokenResponse fatIDToken];
16921782
OIDTokenResponse *tokenResponse =
16931783
[OIDTokenResponse testInstanceWithIDToken:idToken
16941784
accessToken:restoredSignIn ? kAccessToken : nil
@@ -1958,7 +2048,7 @@ - (void)OAuthLoginWithAddScopesFlow:(BOOL)addScopesFlow
19582048
additionalParameters[@"emm_passcode_info_required"] = @"1";
19592049
}
19602050
if (claimsAsJSONRequired) {
1961-
additionalParameters[@"claims"] = kNonEssentialAuthTimeClaimsJsonString;
2051+
additionalParameters[@"claims"] = kNonEssentialAuthTimeClaimJsonString;
19622052
}
19632053

19642054
return [additionalParameters copy];

GoogleSignIn/Tests/Unit/OIDTokenResponse+Testing.h

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,13 @@ extern NSString * const kFatPictureURL;
6060
refreshToken:(NSString *)refreshToken
6161
tokenRequest:(OIDTokenRequest *)tokenRequest;
6262

63-
+ (instancetype)testInstanceWithIDToken:(NSString *)idToken
64-
accessToken:(NSString *)accessToken
65-
expiresIn:(NSNumber *)expiresIn
66-
refreshToken:(NSString *)refreshToken
67-
authTime:(NSString *)authTime
68-
tokenRequest:(OIDTokenRequest *)tokenRequest;
69-
7063
+ (NSString *)idToken;
7164

7265
+ (NSString *)fatIDToken;
7366

74-
+ (NSString *)fatIDTokenWithAuthTime;
67+
+ (NSString *)fatIDTokenWithClaims;
68+
69+
+ (NSArray<NSString *> *)stubbedAMRValues;
7570

7671
/**
7772
* @sub The subject of the ID token.
@@ -81,6 +76,6 @@ extern NSString * const kFatPictureURL;
8176

8277
+ (NSString *)idTokenWithSub:(NSString *)sub exp:(NSNumber *)exp fat:(BOOL)fat;
8378

84-
+ (NSString *)idTokenWithSub:(NSString *)sub exp:(NSNumber *)exp fat:(BOOL)fat authTime:(NSString *)authTime;
79+
+ (NSString *)idTokenWithSub:(NSString *)sub exp:(NSNumber *)exp fat:(BOOL)fat claims:(BOOL)claims;
8580

8681
@end

GoogleSignIn/Tests/Unit/OIDTokenResponse+Testing.m

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -71,21 +71,6 @@ + (instancetype)testInstanceWithIDToken:(NSString *)idToken
7171
expiresIn:(NSNumber *)expiresIn
7272
refreshToken:(NSString *)refreshToken
7373
tokenRequest:(OIDTokenRequest *)tokenRequest {
74-
return [OIDTokenResponse testInstanceWithIDToken:idToken
75-
accessToken:accessToken
76-
expiresIn:expiresIn
77-
refreshToken:refreshToken
78-
authTime:nil
79-
tokenRequest:tokenRequest];
80-
}
81-
82-
+ (instancetype)testInstanceWithIDToken:(NSString *)idToken
83-
accessToken:(NSString *)accessToken
84-
expiresIn:(NSNumber *)expiresIn
85-
refreshToken:(NSString *)refreshToken
86-
authTime:(NSString *)authTime
87-
tokenRequest:(OIDTokenRequest *)tokenRequest {
88-
8974
NSMutableDictionary<NSString *, NSString *> *parameters = [[NSMutableDictionary alloc] initWithDictionary:@{
9075
@"access_token" : accessToken ?: kAccessToken,
9176
@"expires_in" : expiresIn ?: @(kAccessTokenExpiresIn),
@@ -109,8 +94,12 @@ + (NSString *)fatIDToken {
10994
return [self idTokenWithSub:kUserID exp:@(kIDTokenExpires) fat:YES];
11095
}
11196

112-
+ (NSString *)fatIDTokenWithAuthTime {
113-
return [self idTokenWithSub:kUserID exp:@(kIDTokenExpires) fat:YES authTime:kAuthTime];
97+
+ (NSString *)fatIDTokenWithClaims {
98+
return [self idTokenWithSub:kUserID exp:@(kIDTokenExpires) fat:YES claims:YES];
99+
}
100+
101+
+ (NSArray<NSString *> *)stubbedAMRValues {
102+
return @[ @"pwd", @"mfa", @"otp" ];
114103
}
115104

116105
+ (NSString *)idTokenWithSub:(NSString *)sub exp:(NSNumber *)exp {
@@ -120,13 +109,13 @@ + (NSString *)idTokenWithSub:(NSString *)sub exp:(NSNumber *)exp {
120109
+ (NSString *)idTokenWithSub:(NSString *)sub
121110
exp:(NSNumber *)exp
122111
fat:(BOOL)fat {
123-
return [self idTokenWithSub:kUserID exp:exp fat:fat authTime:nil];
112+
return [self idTokenWithSub:kUserID exp:exp fat:fat claims:NO];
124113
}
125114

126115
+ (NSString *)idTokenWithSub:(NSString *)sub
127116
exp:(NSNumber *)exp
128117
fat:(BOOL)fat
129-
authTime:(NSString *)authTime{
118+
claims:(BOOL)claims {
130119
NSError *error;
131120
NSDictionary *headerContents = @{
132121
@"alg" : kAlg,
@@ -156,9 +145,10 @@ + (NSString *)idTokenWithSub:(NSString *)sub
156145
kFatPictureURLKey : kFatPictureURL,
157146
}];
158147
}
159-
if (authTime) {
148+
if (claims) {
160149
[payloadContents addEntriesFromDictionary:@{
161150
@"auth_time": kAuthTime,
151+
@"amr": [OIDTokenResponse stubbedAMRValues],
162152
}];
163153
}
164154
NSData *payloadJson = [NSJSONSerialization dataWithJSONObject:payloadContents

0 commit comments

Comments
 (0)