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
66 changes: 42 additions & 24 deletions GoogleSignIn/Sources/GIDGoogleUser.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDGoogleUser.h"

#import "GoogleSignIn/Sources/GIDGoogleUser_Private.h"

#import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDConfiguration.h"

#import "GoogleSignIn/Sources/GIDAuthentication_Private.h"
#import "GoogleSignIn/Sources/GIDProfileData_Private.h"

Expand All @@ -39,6 +43,7 @@

@implementation GIDGoogleUser {
OIDAuthState *_authState;
GIDConfiguration *_cachedConfiguration;
}

- (nullable NSString *)userID {
Expand All @@ -53,30 +58,6 @@ - (nullable NSString *)userID {
return nil;
}

- (nullable NSString *)hostedDomain {
NSString *idToken = [self idToken];
if (idToken) {
OIDIDToken *idTokenDecoded = [[OIDIDToken alloc] initWithIDTokenString:idToken];
if (idTokenDecoded && idTokenDecoded.claims[kHostedDomainIDTokenClaimKey]) {
return [idTokenDecoded.claims[kHostedDomainIDTokenClaimKey] copy];
}
}

return nil;
}

- (nullable NSString *)serverAuthCode {
return [_authState.lastTokenResponse.additionalParameters[@"server_code"] copy];
}

- (nullable NSString *)serverClientID {
return [_authState.lastTokenResponse.request.additionalParameters[kAudienceParameter] copy];
}

- (nullable NSString *)openIDRealm {
return [_authState.lastTokenResponse.request.additionalParameters[kOpenIDRealmParameter] copy];
}

- (nullable NSArray<NSString *> *)grantedScopes {
NSArray<NSString *> *grantedScopes;
NSString *grantedScopeString = _authState.lastTokenResponse.scope;
Expand All @@ -95,6 +76,20 @@ - (nullable NSString *)openIDRealm {
return grantedScopes;
}

- (GIDConfiguration *)configuration {
@synchronized(self) {
// Caches the configuration since it would not change for one GIDGoogleUser instance.
if (!_cachedConfiguration) {
_cachedConfiguration = [[GIDConfiguration alloc] initWithClientID:[self clientID]
serverClientID:[self serverClientID]
hostedDomain:[self hostedDomain]
openIDRealm:[self openIDRealm]];
};
}

return _cachedConfiguration;
}

#pragma mark - Private Methods

- (instancetype)initWithAuthState:(OIDAuthState *)authState
Expand All @@ -115,10 +110,33 @@ - (void)updateAuthState:(OIDAuthState *)authState

#pragma mark - Helpers

- (NSString *)clientID {
return _authState.lastAuthorizationResponse.request.clientID;
}

- (nullable NSString *)hostedDomain {
NSString *idToken = [self idToken];
if (idToken) {
OIDIDToken *idTokenDecoded = [[OIDIDToken alloc] initWithIDTokenString:idToken];
if (idTokenDecoded && idTokenDecoded.claims[kHostedDomainIDTokenClaimKey]) {
return [idTokenDecoded.claims[kHostedDomainIDTokenClaimKey] copy];
}
}
return nil;
}

- (NSString *)idToken {
return _authState ? _authState.lastTokenResponse.idToken : nil;
}

- (nullable NSString *)serverClientID {
return [_authState.lastTokenResponse.request.additionalParameters[kAudienceParameter] copy];
}

- (nullable NSString *)openIDRealm {
return [_authState.lastTokenResponse.request.additionalParameters[kOpenIDRealmParameter] copy];
}

#pragma mark - NSSecureCoding

+ (BOOL)supportsSecureCoding {
Expand Down
12 changes: 2 additions & 10 deletions GoogleSignIn/Sources/GIDSignIn.m
Original file line number Diff line number Diff line change
Expand Up @@ -278,11 +278,7 @@ - (void)addScopes:(NSArray<NSString *> *)scopes
return;
}

GIDConfiguration *configuration =
[[GIDConfiguration alloc] initWithClientID:self.currentUser.authentication.clientID
serverClientID:self.currentUser.serverClientID
hostedDomain:self.currentUser.hostedDomain
openIDRealm:self.currentUser.openIDRealm];
GIDConfiguration *configuration = self.currentUser.configuration;
GIDSignInInternalOptions *options =
[GIDSignInInternalOptions defaultOptionsWithConfiguration:configuration
presentingViewController:presentingViewController
Expand Down Expand Up @@ -371,11 +367,7 @@ - (void)addScopes:(NSArray<NSString *> *)scopes
return;
}

GIDConfiguration *configuration =
[[GIDConfiguration alloc] initWithClientID:self.currentUser.authentication.clientID
serverClientID:self.currentUser.serverClientID
hostedDomain:self.currentUser.hostedDomain
openIDRealm:self.currentUser.openIDRealm];
GIDConfiguration *configuration = self.currentUser.configuration;
GIDSignInInternalOptions *options =
[GIDSignInInternalOptions defaultOptionsWithConfiguration:configuration
presentingWindow:presentingWindow
Expand Down
15 changes: 3 additions & 12 deletions GoogleSignIn/Sources/Public/GoogleSignIn/GIDGoogleUser.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
NS_ASSUME_NONNULL_BEGIN

@class GIDAuthentication;
@class GIDConfiguration;
@class GIDProfileData;

/// This class represents a user account.
Expand All @@ -36,18 +37,8 @@ NS_ASSUME_NONNULL_BEGIN
/// The API scopes granted to the app in an array of `NSString`.
@property(nonatomic, readonly, nullable) NSArray<NSString *> *grantedScopes;

/// For Google Apps hosted accounts, the domain of the user.
@property(nonatomic, readonly, nullable) NSString *hostedDomain;

/// The client ID of the home server.
@property(nonatomic, readonly, nullable) NSString *serverClientID;

/// An OAuth2 authorization code for the home server.
@property(nonatomic, readonly, nullable) NSString *serverAuthCode;

/// The OpenID2 realm of the home server.
@property(nonatomic, readonly, nullable) NSString *openIDRealm;

/// The configuration that was used to sign in this user.
@property(nonatomic, readonly) GIDConfiguration *configuration;

@end

Expand Down
6 changes: 6 additions & 0 deletions GoogleSignIn/Tests/Unit/GIDConfiguration+Testing.m
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ - (BOOL)isEqualToConfiguration:(GIDConfiguration *)other {
self.openIDRealm == other.openIDRealm);
}

// Not the hash implemention you want to use on prod, but just to match |isEqual:| here.
- (NSUInteger)hash {
return [self.clientID hash] ^ [self.serverClientID hash] ^ [self.hostedDomain hash] ^
[self.openIDRealm hash];
}

+ (instancetype)testInstance {
return [[GIDConfiguration alloc] initWithClientID:OIDAuthorizationRequestTestingClientID
serverClientID:kServerClientID
Expand Down
9 changes: 5 additions & 4 deletions GoogleSignIn/Tests/Unit/GIDGoogleUser+Testing.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@

#import "GoogleSignIn/Tests/Unit/GIDGoogleUser+Testing.h"

#import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDConfiguration.h"
#import "GoogleSignIn/Tests/Unit/GIDAuthentication+Testing.h"
#import "GoogleSignIn/Tests/Unit/GIDConfiguration+Testing.h"
#import "GoogleSignIn/Tests/Unit/GIDProfileData+Testing.h"

@implementation GIDGoogleUser (Testing)
Expand All @@ -32,15 +34,14 @@ - (BOOL)isEqual:(id)object {
- (BOOL)isEqualToGoogleUser:(GIDGoogleUser *)other {
return [self.authentication isEqual:other.authentication] &&
[self.userID isEqual:other.userID] &&
[self.serverAuthCode isEqual:other.serverAuthCode] &&
[self.profile isEqual:other.profile] &&
[self.hostedDomain isEqual:other.hostedDomain];
[self.configuration isEqual:other.configuration];
}

// Not the hash implemention you want to use on prod, but just to match |isEqual:| here.
- (NSUInteger)hash {
return [self.authentication hash] ^ [self.userID hash] ^ [self.serverAuthCode hash] ^
[self.profile hash] ^ [self.hostedDomain hash];
return [self.authentication hash] ^ [self.userID hash] ^ [self.configuration hash] ^
[self.profile hash] ;
}

@end
5 changes: 3 additions & 2 deletions GoogleSignIn/Tests/Unit/GIDGoogleUserTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#import <XCTest/XCTest.h>

#import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDAuthentication.h"
#import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDConfiguration.h"
#import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDProfileData.h"

#import "GoogleSignIn/Sources/GIDAuthentication_Private.h"
Expand Down Expand Up @@ -49,8 +50,8 @@ - (void)testInitWithAuthState {
XCTAssertEqualObjects(user.authentication, authentication);
XCTAssertEqualObjects(user.grantedScopes, @[ OIDAuthorizationRequestTestingScope2 ]);
XCTAssertEqualObjects(user.userID, kUserID);
XCTAssertEqualObjects(user.hostedDomain, kHostedDomain);
XCTAssertEqualObjects(user.serverAuthCode, kServerAuthCode);
XCTAssertEqualObjects(user.configuration.hostedDomain, kHostedDomain);
XCTAssertEqualObjects(user.configuration.clientID, OIDAuthorizationRequestTestingClientID);
XCTAssertEqualObjects(user.profile, [GIDProfileData testInstance]);
}

Expand Down
27 changes: 17 additions & 10 deletions GoogleSignIn/Tests/Unit/GIDSignInTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -397,22 +397,29 @@ - (void)testShareInstance {
- (void)testRestorePreviousSignInNoRefresh_hasPreviousUser {
[[[_authorization expect] andReturn:_authState] authState];
OCMStub([_authState lastTokenResponse]).andReturn(_tokenResponse);
OCMStub([_tokenResponse scope]).andReturn(nil);
OCMStub([_tokenResponse additionalParameters]).andReturn(nil);
OCMStub([_tokenResponse idToken]).andReturn(kFakeIDToken);
OCMStub([_tokenResponse request]).andReturn(_tokenRequest);
OCMStub([_tokenRequest additionalParameters]).andReturn(nil);

id idTokenDecoded = OCMClassMock([OIDIDToken class]);
OCMStub([idTokenDecoded alloc]).andReturn(idTokenDecoded);
OCMStub([idTokenDecoded initWithIDTokenString:OCMOCK_ANY]).andReturn(idTokenDecoded);
OCMStub([idTokenDecoded subject]).andReturn(kFakeGaiaID);

// Mock generating a GIDConfiguration when initializing GIDGoogleUser.
OIDAuthorizationResponse *authResponse =
[OIDAuthorizationResponse testInstanceWithAdditionalParameters:nil
errorString:nil];

OCMStub([_authState lastAuthorizationResponse]).andReturn(authResponse);
OCMStub([_tokenResponse idToken]).andReturn(kFakeIDToken);
OCMStub([_tokenResponse request]).andReturn(_tokenRequest);
OCMStub([_tokenRequest additionalParameters]).andReturn(nil);

[_signIn restorePreviousSignInNoRefresh];

[_authorization verify];
[_authState verify];
[_tokenResponse verify];
[_tokenRequest verify];
[idTokenDecoded verify];
XCTAssertEqual(_signIn.currentUser.userID, kFakeGaiaID);

[idTokenDecoded stopMocking];
Expand Down Expand Up @@ -569,11 +576,9 @@ - (void)testAddScopes {
OCMStub([profile email]).andReturn(kUserEmail);

OCMStub([_user authentication]).andReturn(_authentication);
OCMStub([_authentication clientID]).andReturn(kClientId);
OCMStub([_user serverClientID]).andReturn(nil);
OCMStub([_user hostedDomain]).andReturn(nil);

OCMStub([_user openIDRealm]).andReturn(kOpenIDRealm);

// Mock for the method `addScopes`.
OCMStub([_user configuration]).andReturn(_configuration);
OCMStub([_user profile]).andReturn(profile);
OCMStub([_user grantedScopes]).andReturn(@[kGrantedScope]);

Expand Down Expand Up @@ -603,6 +608,8 @@ - (void)testAddScopes {
NSArray<NSString *> *expectedScopes = @[kNewScope, kGrantedScope];
XCTAssertEqualObjects(grantedScopes, expectedScopes);

[_user verify];
[profile verify];
[profile stopMocking];
}

Expand Down
2 changes: 1 addition & 1 deletion GoogleSignIn/Tests/Unit/OIDTokenResponse+Testing.m
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ + (NSString *)idTokenWithSub:(NSString *)sub exp:(NSNumber *)exp fat:(BOOL)fat {
NSMutableDictionary<NSString *, NSString *> *payloadContents =
[NSMutableDictionary dictionaryWithDictionary:@{
@"sub" : sub,
@"hd" : kHostedDomain,
@"hd" : kHostedDomain,
@"iss" : kIssuer,
@"aud" : kAudience,
@"exp" : exp,
Expand Down