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
83 changes: 40 additions & 43 deletions GoogleSignIn/Sources/GIDGoogleUser.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,19 @@

NS_ASSUME_NONNULL_BEGIN

@interface GIDGoogleUser ()

@property(nonatomic, readwrite) GIDToken *accessToken;

@property(nonatomic, readwrite) GIDToken *refreshToken;

@property(nonatomic, readwrite, nullable) GIDToken *idToken;

@end

@implementation GIDGoogleUser {
OIDAuthState *_authState;
GIDConfiguration *_cachedConfiguration;
GIDToken *_cachedAccessToken;
GIDToken *_cachedRefreshToken;
GIDToken *_cachedIdToken;
}

- (nullable NSString *)userID {
Expand All @@ -59,7 +66,6 @@ - (nullable NSString *)userID {
return [idTokenDecoded.subject copy];
}
}

return nil;
}

Expand Down Expand Up @@ -97,44 +103,9 @@ - (GIDConfiguration *)configuration {
openIDRealm:openIDRealm];
};
}

return _cachedConfiguration;
}

- (GIDToken *)accessToken {
@synchronized(self) {
if (!_cachedAccessToken) {
_cachedAccessToken = [[GIDToken alloc] initWithTokenString:_authState.lastTokenResponse.accessToken
expirationDate:_authState.lastTokenResponse.
accessTokenExpirationDate];
}
}
return _cachedAccessToken;
}

- (GIDToken *)refreshToken {
@synchronized(self) {
if (!_cachedRefreshToken) {
_cachedRefreshToken = [[GIDToken alloc] initWithTokenString:_authState.refreshToken
expirationDate:nil];
}
}
return _cachedRefreshToken;
}

- (nullable GIDToken *)idToken {
@synchronized(self) {
NSString *idTokenString = _authState.lastTokenResponse.idToken;
if (!_cachedIdToken && idTokenString) {
NSDate *idTokenExpirationDate = [[[OIDIDToken alloc]
initWithIDTokenString:idTokenString] expiresAt];
_cachedIdToken = [[GIDToken alloc] initWithTokenString:idTokenString
expirationDate:idTokenExpirationDate];
}
}
return _cachedIdToken;
}

#pragma mark - Private Methods

- (instancetype)initWithAuthState:(OIDAuthState *)authState
Expand All @@ -153,10 +124,36 @@ - (void)updateAuthState:(OIDAuthState *)authState
_authentication = [[GIDAuthentication alloc] initWithAuthState:authState];
_profile = profileData;

// These three tokens will be generated in the getter and cached .
_cachedAccessToken = nil;
_cachedRefreshToken = nil;
_cachedIdToken = nil;
[self updateTokensWithAuthState:authState];
}
}

- (void)updateTokensWithAuthState:(OIDAuthState *)authState {
GIDToken *accessToken =
[[GIDToken alloc] initWithTokenString:authState.lastTokenResponse.accessToken
expirationDate:authState.lastTokenResponse.accessTokenExpirationDate];
if (![self.accessToken isEqualToToken:accessToken]) {
self.accessToken = accessToken;
}

GIDToken *refreshToken = [[GIDToken alloc] initWithTokenString:authState.refreshToken
expirationDate:nil];
if (![self.refreshToken isEqualToToken:refreshToken]) {
self.refreshToken = refreshToken;
}

GIDToken *idToken;
NSString *idTokenString = authState.lastTokenResponse.idToken;
if (idTokenString) {
NSDate *idTokenExpirationDate =
[[[OIDIDToken alloc] initWithIDTokenString:idTokenString] expiresAt];
idToken = [[GIDToken alloc] initWithTokenString:idTokenString
expirationDate:idTokenExpirationDate];
} else {
idToken = nil;
}
if ((self.idToken || idToken) && ![self.idToken isEqualToToken:idToken]) {
self.idToken = idToken;
}
}

Expand Down
2 changes: 2 additions & 0 deletions GoogleSignIn/Tests/Unit/GIDAuthenticationTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,7 @@ - (GIDAuthentication *)auth {
[OIDTokenResponse testInstanceWithIDToken:idToken
accessToken:kAccessToken
expiresIn:accessTokenExpiresIn
refreshToken:kRefreshToken
tokenRequest:tokenRequest];
return [[GIDAuthentication alloc]
initWithAuthState:[OIDAuthState testInstanceWithTokenResponse:tokenResponse]];
Expand Down Expand Up @@ -599,6 +600,7 @@ - (OIDTokenResponse *)tokenResponseWithNewTokens {
return [OIDTokenResponse testInstanceWithIDToken:(_hasIDToken ? [self idTokenNew] : nil)
accessToken:kNewAccessToken
expiresIn:expiresIn
refreshToken:kRefreshToken
tokenRequest:_tokenRequest ?: nil];
}

Expand Down
50 changes: 43 additions & 7 deletions GoogleSignIn/Tests/Unit/GIDGoogleUserTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
#endif

static NSString *const kNewAccessToken = @"new_access_token";
static NSString *const kNewRefreshToken = @"new_refresh_token";

static NSTimeInterval const kTimeAccuracy = 10;
// The difference between times.
// It should be larger than kTimeAccuracy which is used in the method `XCTAssertEqualWithAccuracy`.
Expand Down Expand Up @@ -102,19 +104,16 @@ - (void)testUpdateAuthState {
NSTimeInterval accessTokenExpireTime = [[NSDate date] timeIntervalSince1970];
NSTimeInterval idTokenExpireTime = accessTokenExpireTime + kTimeIncrement;

NSString *idToken = [self idTokenWithExpireTime:idTokenExpireTime];
OIDAuthState *authState = [OIDAuthState testInstanceWithIDToken:idToken
accessToken:kAccessToken
accessTokenExpireTime:accessTokenExpireTime];

GIDGoogleUser *user = [[GIDGoogleUser alloc] initWithAuthState:authState profileData:nil];
GIDGoogleUser *user = [self googleUserWithAccessTokenExpireTime:accessTokenExpireTime
idTokenExpireTime:idTokenExpireTime];

NSTimeInterval updatedAccessTokenExpireTime = idTokenExpireTime + kTimeIncrement;
NSTimeInterval updatedIDTokenExpireTime = updatedAccessTokenExpireTime + kTimeIncrement;
NSString *updatedIDToken = [self idTokenWithExpireTime:updatedIDTokenExpireTime];
OIDAuthState *updatedAuthState = [OIDAuthState testInstanceWithIDToken:updatedIDToken
accessToken:kNewAccessToken
accessTokenExpireTime:updatedAccessTokenExpireTime];
accessTokenExpireTime:updatedAccessTokenExpireTime
refreshToken:kNewRefreshToken];
GIDProfileData *updatedProfileData = [GIDProfileData testInstance];

[user updateAuthState:updatedAuthState profileData:updatedProfileData];
Expand All @@ -125,11 +124,48 @@ - (void)testUpdateAuthState {
XCTAssertEqualObjects(user.idToken.tokenString, updatedIDToken);
XCTAssertEqualWithAccuracy([user.idToken.expirationDate timeIntervalSince1970],
updatedIDTokenExpireTime, kTimeAccuracy);
XCTAssertEqualObjects(user.refreshToken.tokenString, kNewRefreshToken);
XCTAssertEqual(user.profile, updatedProfileData);
}

// When updating with a new OIDAuthState in which token information is not changed, the token objects
// should remain the same.
- (void)testUpdateAuthState_tokensAreNotChanged {
NSTimeInterval accessTokenExpireTime = [[NSDate date] timeIntervalSince1970];
NSTimeInterval idTokenExpireTime = [[NSDate date] timeIntervalSince1970];

NSString *idToken = [self idTokenWithExpireTime:idTokenExpireTime];
OIDAuthState *authState = [OIDAuthState testInstanceWithIDToken:idToken
accessToken:kAccessToken
accessTokenExpireTime:accessTokenExpireTime
refreshToken:kRefreshToken];

GIDGoogleUser *user = [[GIDGoogleUser alloc] initWithAuthState:authState profileData:nil];

GIDToken *accessTokenBeforeUpdate = user.accessToken;
GIDToken *refreshTokenBeforeUpdate = user.refreshToken;
GIDToken *idTokenBeforeUpdate = user.idToken;

[user updateAuthState:authState profileData:nil];

XCTAssertIdentical(user.accessToken, accessTokenBeforeUpdate);
XCTAssertIdentical(user.idToken, idTokenBeforeUpdate);
XCTAssertIdentical(user.refreshToken, refreshTokenBeforeUpdate);
}

#pragma mark - Helpers

- (GIDGoogleUser *)googleUserWithAccessTokenExpireTime:(NSTimeInterval)accessTokenExpireTime
idTokenExpireTime:(NSTimeInterval)idTokenExpireTime {
NSString *idToken = [self idTokenWithExpireTime:idTokenExpireTime];
OIDAuthState *authState = [OIDAuthState testInstanceWithIDToken:idToken
accessToken:kAccessToken
accessTokenExpireTime:accessTokenExpireTime
refreshToken:kRefreshToken];

return [[GIDGoogleUser alloc] initWithAuthState:authState profileData:nil];
}

// The expireTime should be based on 1970.
- (NSString *)idTokenWithExpireTime:(NSTimeInterval)expireTime {
return [OIDTokenResponse idTokenWithSub:kUserID exp:@(expireTime)];
Expand Down
1 change: 1 addition & 0 deletions GoogleSignIn/Tests/Unit/GIDSignInTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -1202,6 +1202,7 @@ - (void)OAuthLoginWithAddScopesFlow:(BOOL)addScopesFlow
[OIDTokenResponse testInstanceWithIDToken:[OIDTokenResponse fatIDToken]
accessToken:restoredSignIn ? kAccessToken : nil
expiresIn:oldAccessToken ? @(300) : nil
refreshToken:kRefreshToken
tokenRequest:nil];

OIDTokenRequest *tokenRequest = [[OIDTokenRequest alloc]
Expand Down
3 changes: 2 additions & 1 deletion GoogleSignIn/Tests/Unit/OIDAuthState+Testing.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

+ (instancetype)testInstanceWithIDToken:(NSString *)idToken
accessToken:(NSString *)accessToken
accessTokenExpireTime:(NSTimeInterval)accessTokenExpireTime;
accessTokenExpireTime:(NSTimeInterval)accessTokenExpireTime
refreshToken:(NSString *)refreshToken;

@end
4 changes: 3 additions & 1 deletion GoogleSignIn/Tests/Unit/OIDAuthState+Testing.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@ + (instancetype)testInstanceWithTokenResponse:(OIDTokenResponse *)tokenResponse

+ (instancetype)testInstanceWithIDToken:(NSString *)idToken
accessToken:(NSString *)accessToken
accessTokenExpireTime:(NSTimeInterval)accessTokenExpireTime {
accessTokenExpireTime:(NSTimeInterval)accessTokenExpireTime
refreshToken:(NSString *)refreshToken {
NSNumber *accessTokenExpiresIn =
@(accessTokenExpireTime - [[NSDate date] timeIntervalSince1970]);
OIDTokenResponse *newResponse =
[OIDTokenResponse testInstanceWithIDToken:idToken
accessToken:accessToken
expiresIn:accessTokenExpiresIn
refreshToken:refreshToken
tokenRequest:nil];
return [self testInstanceWithTokenResponse:newResponse];
}
Expand Down
1 change: 1 addition & 0 deletions GoogleSignIn/Tests/Unit/OIDTokenResponse+Testing.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ extern NSString * const kFatPictureURL;
+ (instancetype)testInstanceWithIDToken:(NSString *)idToken
accessToken:(NSString *)accessToken
expiresIn:(NSNumber *)expiresIn
refreshToken:(NSString *)refreshToken
tokenRequest:(OIDTokenRequest *)tokenRequest;

+ (NSString *)idToken;
Expand Down
4 changes: 3 additions & 1 deletion GoogleSignIn/Tests/Unit/OIDTokenResponse+Testing.m
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,21 @@ + (instancetype)testInstanceWithIDToken:(NSString *)idToken {
return [OIDTokenResponse testInstanceWithIDToken:idToken
accessToken:nil
expiresIn:nil
refreshToken:nil
tokenRequest:nil];
}

+ (instancetype)testInstanceWithIDToken:(NSString *)idToken
accessToken:(NSString *)accessToken
expiresIn:(NSNumber *)expiresIn
refreshToken:(NSString *)refreshToken
tokenRequest:(OIDTokenRequest *)tokenRequest {
NSMutableDictionary<NSString *, NSString *> *parameters;
parameters = [[NSMutableDictionary alloc] initWithDictionary:@{
@"access_token" : accessToken ?: kAccessToken,
@"expires_in" : expiresIn ?: @(kAccessTokenExpiresIn),
@"token_type" : @"example_token_type",
@"refresh_token" : kRefreshToken,
@"refresh_token" : refreshToken ?: kRefreshToken,
@"scope" : [OIDScopeUtilities scopesWithArray:@[ OIDAuthorizationRequestTestingScope2 ]],
@"server_code" : kServerAuthCode,
}];
Expand Down