|
|
@@ -30,61 +30,91 @@ static NSString *const kHostedDomainIDTokenClaimKey = @"hd";
|
|
|
|
|
|
// Key constants used for encode and decode.
|
|
|
static NSString *const kAuthenticationKey = @"authentication";
|
|
|
-static NSString *const kGrantedScopesKey = @"grantedScopes";
|
|
|
-static NSString *const kUserIDKey = @"userID";
|
|
|
-static NSString *const kServerAuthCodeKey = @"serverAuthCode";
|
|
|
static NSString *const kProfileDataKey = @"profileData";
|
|
|
-static NSString *const kHostedDomainKey = @"hostedDomain";
|
|
|
+static NSString *const kAuthState = @"authState";
|
|
|
|
|
|
// Parameters for the token exchange endpoint.
|
|
|
static NSString *const kAudienceParameter = @"audience";
|
|
|
static NSString *const kOpenIDRealmParameter = @"openid.realm";
|
|
|
|
|
|
-
|
|
|
-@implementation GIDGoogleUser
|
|
|
+@implementation GIDGoogleUser {
|
|
|
+ OIDAuthState *_authState;
|
|
|
+}
|
|
|
|
|
|
- (instancetype)initWithAuthState:(OIDAuthState *)authState
|
|
|
profileData:(nullable GIDProfileData *)profileData {
|
|
|
self = [super init];
|
|
|
if (self) {
|
|
|
- _authentication = [[GIDAuthentication alloc] initWithAuthState:authState];
|
|
|
-
|
|
|
- NSArray<NSString *> *grantedScopes;
|
|
|
- NSString *grantedScopeString = authState.lastTokenResponse.scope;
|
|
|
- if (grantedScopeString) {
|
|
|
- // If we have a 'scope' parameter from the backend, this is authoritative.
|
|
|
- // Remove leading and trailing whitespace.
|
|
|
- grantedScopeString = [grantedScopeString stringByTrimmingCharactersInSet:
|
|
|
- [NSCharacterSet whitespaceCharacterSet]];
|
|
|
- // Tokenize with space as a delimiter.
|
|
|
- NSMutableArray<NSString *> *parsedScopes =
|
|
|
- [[grantedScopeString componentsSeparatedByString:@" "] mutableCopy];
|
|
|
- // Remove empty strings.
|
|
|
- [parsedScopes removeObject:@""];
|
|
|
- grantedScopes = [parsedScopes copy];
|
|
|
+ [self updateAuthState:authState profileData:profileData];
|
|
|
+ }
|
|
|
+ return self;
|
|
|
+}
|
|
|
+
|
|
|
+- (nullable NSString *)userID {
|
|
|
+ NSString *idToken = [self idToken];
|
|
|
+ if (idToken) {
|
|
|
+ OIDIDToken *idTokenDecoded = [[OIDIDToken alloc] initWithIDTokenString:idToken];
|
|
|
+ if (idTokenDecoded && idTokenDecoded.subject) {
|
|
|
+ return [idTokenDecoded.subject copy];
|
|
|
}
|
|
|
- _grantedScopes = grantedScopes;
|
|
|
-
|
|
|
- _serverAuthCode = [authState.lastTokenResponse.additionalParameters[@"server_code"] copy];
|
|
|
- _profile = [profileData copy];
|
|
|
-
|
|
|
- NSString *idToken = authState.lastTokenResponse.idToken;
|
|
|
- if (idToken) {
|
|
|
- OIDIDToken *idTokenDecoded = [[OIDIDToken alloc] initWithIDTokenString:idToken];
|
|
|
- if (idTokenDecoded.subject) {
|
|
|
- _userID = [idTokenDecoded.subject copy];
|
|
|
- }
|
|
|
- if (idTokenDecoded.claims[kHostedDomainIDTokenClaimKey]) {
|
|
|
- _hostedDomain = [idTokenDecoded.claims[kHostedDomainIDTokenClaimKey] copy];
|
|
|
- }
|
|
|
+ }
|
|
|
+
|
|
|
+ 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;
|
|
|
+}
|
|
|
|
|
|
- _serverClientID =
|
|
|
- [authState.lastTokenResponse.request.additionalParameters[kAudienceParameter] copy];
|
|
|
- _openIDRealm =
|
|
|
- [authState.lastTokenResponse.request.additionalParameters[kOpenIDRealmParameter] copy];
|
|
|
+- (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;
|
|
|
+ if (grantedScopeString) {
|
|
|
+ // If we have a 'scope' parameter from the backend, this is authoritative.
|
|
|
+ // Remove leading and trailing whitespace.
|
|
|
+ grantedScopeString = [grantedScopeString stringByTrimmingCharactersInSet:
|
|
|
+ [NSCharacterSet whitespaceCharacterSet]];
|
|
|
+ // Tokenize with space as a delimiter.
|
|
|
+ NSMutableArray<NSString *> *parsedScopes =
|
|
|
+ [[grantedScopeString componentsSeparatedByString:@" "] mutableCopy];
|
|
|
+ // Remove empty strings.
|
|
|
+ [parsedScopes removeObject:@""];
|
|
|
+ grantedScopes = [parsedScopes copy];
|
|
|
}
|
|
|
- return self;
|
|
|
+ return grantedScopes;
|
|
|
+}
|
|
|
+
|
|
|
+#pragma mark - Private Methods
|
|
|
+
|
|
|
+- (void)updateAuthState:(OIDAuthState *)authState
|
|
|
+ profileData:(nullable GIDProfileData *)profileData {
|
|
|
+ _authState = authState;
|
|
|
+ _authentication = [[GIDAuthentication alloc] initWithAuthState:authState];
|
|
|
+ _profile = profileData;
|
|
|
+}
|
|
|
+
|
|
|
+- (NSString *)idToken {
|
|
|
+ return _authState ? _authState.lastTokenResponse.idToken : nil;
|
|
|
}
|
|
|
|
|
|
#pragma mark - NSSecureCoding
|
|
|
@@ -98,22 +128,16 @@ static NSString *const kOpenIDRealmParameter = @"openid.realm";
|
|
|
if (self) {
|
|
|
_authentication = [decoder decodeObjectOfClass:[GIDAuthentication class]
|
|
|
forKey:kAuthenticationKey];
|
|
|
- _grantedScopes = [decoder decodeObjectOfClass:[NSArray class] forKey:kGrantedScopesKey];
|
|
|
- _userID = [decoder decodeObjectOfClass:[NSString class] forKey:kUserIDKey];
|
|
|
- _serverAuthCode = [decoder decodeObjectOfClass:[NSString class] forKey:kServerAuthCodeKey];
|
|
|
_profile = [decoder decodeObjectOfClass:[GIDProfileData class] forKey:kProfileDataKey];
|
|
|
- _hostedDomain = [decoder decodeObjectOfClass:[NSString class] forKey:kHostedDomainKey];
|
|
|
+ _authState = [decoder decodeObjectOfClass:[OIDAuthState class] forKey:kAuthState];
|
|
|
}
|
|
|
return self;
|
|
|
}
|
|
|
|
|
|
- (void)encodeWithCoder:(NSCoder *)encoder {
|
|
|
[encoder encodeObject:_authentication forKey:kAuthenticationKey];
|
|
|
- [encoder encodeObject:_grantedScopes forKey:kGrantedScopesKey];
|
|
|
- [encoder encodeObject:_userID forKey:kUserIDKey];
|
|
|
- [encoder encodeObject:_serverAuthCode forKey:kServerAuthCodeKey];
|
|
|
[encoder encodeObject:_profile forKey:kProfileDataKey];
|
|
|
- [encoder encodeObject:_hostedDomain forKey:kHostedDomainKey];
|
|
|
+ [encoder encodeObject:_authState forKey:kAuthState];
|
|
|
}
|
|
|
|
|
|
@end
|