Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 102 additions & 12 deletions GoogleSignIn/Tests/Unit/GIDSignInTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,18 @@
static NSString *const kGrantedScope = @"grantedScope";
static NSString *const kNewScope = @"newScope";

static NSString *const kEssentialAuthTimeClaimsJsonString =
static NSString *const kEssentialAuthTimeClaimJsonString =
@"{\"id_token\":{\"auth_time\":{\"essential\":true}}}";
static NSString *const kNonEssentialAuthTimeClaimsJsonString =
static NSString *const kNonEssentialAuthTimeClaimJsonString =
@"{\"id_token\":{\"auth_time\":{\"essential\":false}}}";

static NSString *const kEssentialAMRClaimJsonString =
@"{\"id_token\":{\"amr\":{\"essential\":true}}}";
static NSString *const kNonEssentialAMRClaimJsonString =
@"{\"id_token\":{\"amr\":{\"essential\":false}}}";

static NSString *const kMultipleClaimsJsonString =
@"{\"id_token\":{\"amr\":{\"essential\":false},\"auth_time\":{\"essential\":false}}}";

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

- (void)testOAuthLogin_WithClaims_FormatsParametersCorrectly {
- (void)testOAuthLogin_WithAuthTimeClaim_FormatsParametersCorrectly {
GIDClaim *authTimeClaim = [GIDClaim authTimeClaim];
GIDClaim *essentialAuthTimeClaim = [GIDClaim essentialAuthTimeClaim];

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

XCTAssertEqualObjects(_savedAuthorizationRequest.additionalParameters[@"claims"],
kEssentialAuthTimeClaimsJsonString,
kEssentialAuthTimeClaimJsonString,
@"Claims JSON should be correctly formatted");

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

XCTAssertEqualObjects(_savedAuthorizationRequest.additionalParameters[@"claims"],
kNonEssentialAuthTimeClaimsJsonString,
kNonEssentialAuthTimeClaimJsonString,
@"Claims JSON should be correctly formatted");
}

- (void)testOAuthLogin_WithAMRClaim_FormatsParametersCorrectly {
GIDClaim *AMRClaim = [GIDClaim AMRClaim];
GIDClaim *essentialAMRClaim = [GIDClaim essentialAMRClaim];

OCMStub([_keychainStore saveAuthSession:OCMOCK_ANY error:OCMArg.anyObjectRef]
).andDo(^(NSInvocation *invocation){
self->_keychainSaved = self->_saveAuthorizationReturnValue;
});

[self OAuthLoginWithAddScopesFlow:NO
authError:nil
tokenError:nil
emmPasscodeInfoRequired:NO
claimsAsJSONRequired:NO
keychainError:NO
claimsError:NO
restoredSignIn:NO
oldAccessToken:NO
modalCancel:NO
useAdditionalScopes:NO
additionalScopes:nil
manualNonce:nil
claims:[NSSet setWithObject:essentialAMRClaim]];

XCTAssertEqualObjects(_savedAuthorizationRequest.additionalParameters[@"claims"],
kEssentialAMRClaimJsonString,
@"Claims JSON should be correctly formatted");

[self OAuthLoginWithAddScopesFlow:NO
authError:nil
tokenError:nil
emmPasscodeInfoRequired:NO
claimsAsJSONRequired:NO
keychainError:NO
claimsError:NO
restoredSignIn:NO
oldAccessToken:NO
modalCancel:NO
useAdditionalScopes:NO
additionalScopes:nil
manualNonce:nil
claims:[NSSet setWithObject:AMRClaim]];

XCTAssertEqualObjects(_savedAuthorizationRequest.additionalParameters[@"claims"],
kNonEssentialAMRClaimJsonString,
@"Claims JSON should be correctly formatted");
}

- (void)testOAuthLogin_WithClaims_ReturnsIdTokenWithCorrectClaims {
- (void)testOAuthLogin_WithMultipleClaims_FormatsParametersCorrectly {
GIDClaim *authTimeClaim = [GIDClaim authTimeClaim];
GIDClaim *AMRClaim = [GIDClaim AMRClaim];
NSSet *claims = [NSSet setWithArray:@[authTimeClaim, AMRClaim]];

OCMStub([_keychainStore saveAuthSession:OCMOCK_ANY error:OCMArg.anyObjectRef]
).andDo(^(NSInvocation *invocation){
Expand All @@ -820,7 +877,37 @@ - (void)testOAuthLogin_WithClaims_ReturnsIdTokenWithCorrectClaims {
useAdditionalScopes:NO
additionalScopes:nil
manualNonce:nil
claims:[NSSet setWithObject:authTimeClaim]];
claims:claims];

XCTAssertEqualObjects(_savedAuthorizationRequest.additionalParameters[@"claims"],
kMultipleClaimsJsonString,
@"Claims JSON should be correctly formatted");
}

- (void)testOAuthLogin_WithMultipleClaims_ReturnsIdTokenWithCorrectClaims {
GIDClaim *authTimeClaim = [GIDClaim authTimeClaim];
GIDClaim *AMRClaim = [GIDClaim AMRClaim];
NSSet *claims = [NSSet setWithArray:@[authTimeClaim, AMRClaim]];

OCMStub([_keychainStore saveAuthSession:OCMOCK_ANY error:OCMArg.anyObjectRef]
).andDo(^(NSInvocation *invocation){
self->_keychainSaved = self->_saveAuthorizationReturnValue;
});

[self OAuthLoginWithAddScopesFlow:NO
authError:nil
tokenError:nil
emmPasscodeInfoRequired:NO
claimsAsJSONRequired:NO
keychainError:NO
claimsError:NO
restoredSignIn:NO
oldAccessToken:NO
modalCancel:NO
useAdditionalScopes:NO
additionalScopes:nil
manualNonce:nil
claims:claims];

XCTAssertNotNil(_signIn.currentUser, @"The currentUser should not be nil after a successful sign-in.");
NSString *idTokenString = _signIn.currentUser.idToken.tokenString;
Expand All @@ -830,10 +917,13 @@ - (void)testOAuthLogin_WithClaims_ReturnsIdTokenWithCorrectClaims {
NSData *payloadData = [[NSData alloc]
initWithBase64EncodedString:components[1]
options:NSDataBase64DecodingIgnoreUnknownCharacters];
NSDictionary *claims = [NSJSONSerialization JSONObjectWithData:payloadData options:0 error:nil];
XCTAssertEqualObjects(claims[@"auth_time"],
NSDictionary *receivedClaims = [NSJSONSerialization JSONObjectWithData:payloadData options:0 error:nil];
XCTAssertEqualObjects(receivedClaims[@"auth_time"],
kAuthTime,
@"The 'auth_time' claim should be present and correct.");
XCTAssertEqualObjects(receivedClaims[@"amr"],
[OIDTokenResponse stubbedAMRValues],
@"The 'amr' claim should be present and correct.");
}

- (void)testAddScopes {
Expand Down Expand Up @@ -963,7 +1053,7 @@ - (void)testAddScopes_WithPreviouslyRequestedClaims {
NSArray<NSString *> *expectedScopes = @[kNewScope, kGrantedScope];
XCTAssertEqualObjects(grantedScopes, expectedScopes);
XCTAssertEqualObjects(_savedAuthorizationRequest.additionalParameters[@"claims"],
kNonEssentialAuthTimeClaimsJsonString,
kNonEssentialAuthTimeClaimJsonString,
@"Claims JSON should be correctly formatted");

[_user verify];
Expand Down Expand Up @@ -1688,7 +1778,7 @@ - (void)OAuthLoginWithAddScopesFlow:(BOOL)addScopesFlow
nonce:nonce
errorString:authError];

NSString *idToken = claims ? [OIDTokenResponse fatIDTokenWithAuthTime] : [OIDTokenResponse fatIDToken];
NSString *idToken = claims ? [OIDTokenResponse fatIDTokenWithClaims] : [OIDTokenResponse fatIDToken];
OIDTokenResponse *tokenResponse =
[OIDTokenResponse testInstanceWithIDToken:idToken
accessToken:restoredSignIn ? kAccessToken : nil
Expand Down Expand Up @@ -1958,7 +2048,7 @@ - (void)OAuthLoginWithAddScopesFlow:(BOOL)addScopesFlow
additionalParameters[@"emm_passcode_info_required"] = @"1";
}
if (claimsAsJSONRequired) {
additionalParameters[@"claims"] = kNonEssentialAuthTimeClaimsJsonString;
additionalParameters[@"claims"] = kNonEssentialAuthTimeClaimJsonString;
}

return [additionalParameters copy];
Expand Down
13 changes: 4 additions & 9 deletions GoogleSignIn/Tests/Unit/OIDTokenResponse+Testing.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,13 @@ extern NSString * const kFatPictureURL;
refreshToken:(NSString *)refreshToken
tokenRequest:(OIDTokenRequest *)tokenRequest;

+ (instancetype)testInstanceWithIDToken:(NSString *)idToken
accessToken:(NSString *)accessToken
expiresIn:(NSNumber *)expiresIn
refreshToken:(NSString *)refreshToken
authTime:(NSString *)authTime
tokenRequest:(OIDTokenRequest *)tokenRequest;

+ (NSString *)idToken;

+ (NSString *)fatIDToken;

+ (NSString *)fatIDTokenWithAuthTime;
+ (NSString *)fatIDTokenWithClaims;

+ (NSArray<NSString *> *)stubbedAMRValues;

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

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

+ (NSString *)idTokenWithSub:(NSString *)sub exp:(NSNumber *)exp fat:(BOOL)fat authTime:(NSString *)authTime;
+ (NSString *)idTokenWithSub:(NSString *)sub exp:(NSNumber *)exp fat:(BOOL)fat claims:(BOOL)claims;

@end
30 changes: 10 additions & 20 deletions GoogleSignIn/Tests/Unit/OIDTokenResponse+Testing.m
Original file line number Diff line number Diff line change
Expand Up @@ -71,21 +71,6 @@ + (instancetype)testInstanceWithIDToken:(NSString *)idToken
expiresIn:(NSNumber *)expiresIn
refreshToken:(NSString *)refreshToken
tokenRequest:(OIDTokenRequest *)tokenRequest {
return [OIDTokenResponse testInstanceWithIDToken:idToken
accessToken:accessToken
expiresIn:expiresIn
refreshToken:refreshToken
authTime:nil
tokenRequest:tokenRequest];
}

+ (instancetype)testInstanceWithIDToken:(NSString *)idToken
accessToken:(NSString *)accessToken
expiresIn:(NSNumber *)expiresIn
refreshToken:(NSString *)refreshToken
authTime:(NSString *)authTime
tokenRequest:(OIDTokenRequest *)tokenRequest {

NSMutableDictionary<NSString *, NSString *> *parameters = [[NSMutableDictionary alloc] initWithDictionary:@{
@"access_token" : accessToken ?: kAccessToken,
@"expires_in" : expiresIn ?: @(kAccessTokenExpiresIn),
Expand All @@ -109,8 +94,12 @@ + (NSString *)fatIDToken {
return [self idTokenWithSub:kUserID exp:@(kIDTokenExpires) fat:YES];
}

+ (NSString *)fatIDTokenWithAuthTime {
return [self idTokenWithSub:kUserID exp:@(kIDTokenExpires) fat:YES authTime:kAuthTime];
+ (NSString *)fatIDTokenWithClaims {
return [self idTokenWithSub:kUserID exp:@(kIDTokenExpires) fat:YES claims:YES];
}

+ (NSArray<NSString *> *)stubbedAMRValues {
return @[ @"pwd", @"mfa", @"otp" ];
}

+ (NSString *)idTokenWithSub:(NSString *)sub exp:(NSNumber *)exp {
Expand All @@ -120,13 +109,13 @@ + (NSString *)idTokenWithSub:(NSString *)sub exp:(NSNumber *)exp {
+ (NSString *)idTokenWithSub:(NSString *)sub
exp:(NSNumber *)exp
fat:(BOOL)fat {
return [self idTokenWithSub:kUserID exp:exp fat:fat authTime:nil];
return [self idTokenWithSub:kUserID exp:exp fat:fat claims:NO];
}

+ (NSString *)idTokenWithSub:(NSString *)sub
exp:(NSNumber *)exp
fat:(BOOL)fat
authTime:(NSString *)authTime{
claims:(BOOL)claims {
NSError *error;
NSDictionary *headerContents = @{
@"alg" : kAlg,
Expand Down Expand Up @@ -156,9 +145,10 @@ + (NSString *)idTokenWithSub:(NSString *)sub
kFatPictureURLKey : kFatPictureURL,
}];
}
if (authTime) {
if (claims) {
[payloadContents addEntriesFromDictionary:@{
@"auth_time": kAuthTime,
@"amr": [OIDTokenResponse stubbedAMRValues],
}];
}
NSData *payloadJson = [NSJSONSerialization dataWithJSONObject:payloadContents
Expand Down