GIDAuthorizationUtilTest.m 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. // Copyright 2023 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #import <TargetConditionals.h>
  15. #import <XCTest/XCTest.h>
  16. #import "GoogleSignIn/Sources/GIDAuthorizationUtil.h"
  17. #import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDConfiguration.h"
  18. #import "GoogleSignIn/Sources/GIDSignInInternalOptions.h"
  19. #import "GoogleSignIn/Sources/GIDSignInPreferences.h"
  20. #import "GoogleSignIn/Tests/Unit/OIDAuthorizationResponse+Testing.h"
  21. #import "GoogleSignIn/Tests/Unit/OIDTokenResponse+Testing.h"
  22. #ifdef SWIFT_PACKAGE
  23. @import AppAuth;
  24. #else
  25. #import <AppAuth/AppAuth.h>
  26. #endif
  27. NS_ASSUME_NONNULL_BEGIN
  28. static NSString * const kClientId = @"FakeClientID";
  29. static NSString * const kUserEmail = @"FakeUserEmail";
  30. static NSString * const kServerClientId = @"FakeServerClientID";
  31. static NSString * const kOpenIDRealm = @"FakeRealm";
  32. static NSString * const kScopeBirthday = @"birthday";
  33. static NSString * const kScopeEmail = @"email";
  34. static NSString * const kScopeProfile = @"profile";
  35. @interface GIDAuthorizationUtilTest : XCTestCase
  36. @end
  37. @implementation GIDAuthorizationUtilTest {
  38. GIDConfiguration *_configuration;
  39. BOOL _isEligibleForEMM;
  40. }
  41. - (void)setUp {
  42. [super setUp];
  43. _configuration = [[GIDConfiguration alloc] initWithClientID:kClientId
  44. serverClientID:kServerClientId
  45. hostedDomain:kHostedDomain
  46. openIDRealm:nil];
  47. #if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
  48. _isEligibleForEMM = [UIDevice currentDevice].systemVersion.integerValue >= 9;
  49. #endif // TARGET_OS_IOS && !TARGET_OS_MACCATALYST
  50. }
  51. # pragma mark - test `authorizationRequestWithOptions:emmSupport:`.
  52. - (void)testCreateAuthorizationRequest_signInFlow {
  53. GIDSignInInternalOptions *options =
  54. [GIDSignInInternalOptions defaultOptionsWithConfiguration:_configuration
  55. #if TARGET_OS_IOS || TARGET_OS_MACCATALYST
  56. presentingViewController:nil
  57. #elif TARGET_OS_OSX
  58. presentingWindow:nil
  59. #endif // TARGET_OS_OSX
  60. loginHint:kUserEmail
  61. addScopesFlow:NO
  62. completion:nil];
  63. OIDAuthorizationRequest *request =
  64. [GIDAuthorizationUtil authorizationRequestWithOptions:options
  65. emmSupport:nil];
  66. NSDictionary<NSString *, NSObject *> *params = request.additionalParameters;
  67. XCTAssertEqualObjects(params[kIncludeGrantedScopesParameter], @"true");
  68. XCTAssertEqualObjects(params[kSDKVersionLoggingParameter], GIDVersion());
  69. XCTAssertEqualObjects(params[kEnvironmentLoggingParameter], GIDEnvironment());
  70. XCTAssertEqualObjects(params[kLoginHintParameter], kUserEmail, @"login hint should match");
  71. XCTAssertEqualObjects(params[kHostedDomainParameter], kHostedDomain,
  72. @"hosted domain should match");
  73. XCTAssertEqualObjects(params[kAudienceParameter], kServerClientId, @"client ID should match");
  74. NSArray<NSString *> *defaultScopes = @[kScopeEmail, kScopeProfile];
  75. NSString *expectedScopeString = [defaultScopes componentsJoinedByString:@" "];
  76. XCTAssertEqualObjects(request.scope, expectedScopeString);
  77. }
  78. - (void)testCreateAuthorizationRequest_additionalScopes {
  79. NSArray<NSString *> *addtionalScopes = @[kScopeBirthday];
  80. GIDSignInInternalOptions *options =
  81. [GIDSignInInternalOptions defaultOptionsWithConfiguration:_configuration
  82. #if TARGET_OS_IOS || TARGET_OS_MACCATALYST
  83. presentingViewController:nil
  84. #elif TARGET_OS_OSX
  85. presentingWindow:nil
  86. #endif // TARGET_OS_OSX
  87. loginHint:kUserEmail
  88. addScopesFlow:NO
  89. scopes:addtionalScopes
  90. completion:nil];
  91. OIDAuthorizationRequest *request =
  92. [GIDAuthorizationUtil authorizationRequestWithOptions:options
  93. emmSupport:nil];
  94. NSArray<NSString *> *expectedScopes = @[kScopeBirthday, kScopeEmail, kScopeProfile];
  95. NSString *expectedScopeString = [expectedScopes componentsJoinedByString:@" "];
  96. XCTAssertEqualObjects(request.scope, expectedScopeString);
  97. }
  98. - (void)testCreateAuthrizationRequest_addScopes {
  99. NSArray<NSString *> *scopes = @[kScopeEmail, kScopeProfile, kScopeBirthday];
  100. GIDSignInInternalOptions *options =
  101. [GIDSignInInternalOptions defaultOptionsWithConfiguration:_configuration
  102. #if TARGET_OS_IOS || TARGET_OS_MACCATALYST
  103. presentingViewController:nil
  104. #elif TARGET_OS_OSX
  105. presentingWindow:nil
  106. #endif // TARGET_OS_OSX
  107. loginHint:kUserEmail
  108. addScopesFlow:YES
  109. scopes:scopes
  110. completion:nil];
  111. OIDAuthorizationRequest *request =
  112. [GIDAuthorizationUtil authorizationRequestWithOptions:options
  113. emmSupport:nil];
  114. NSString *expectedScopeString = [scopes componentsJoinedByString:@" "];
  115. XCTAssertEqualObjects(request.scope, expectedScopeString);
  116. }
  117. #if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
  118. - (void)testCreateAuthorizationRequest_signInFlow_EMM {
  119. GIDSignInInternalOptions *options =
  120. [GIDSignInInternalOptions defaultOptionsWithConfiguration:_configuration
  121. presentingViewController:nil
  122. loginHint:kUserEmail
  123. addScopesFlow:NO
  124. completion:nil];
  125. OIDAuthorizationRequest *request =
  126. [GIDAuthorizationUtil authorizationRequestWithOptions:options
  127. emmSupport:kEMMVersion];
  128. NSString *systemName = [UIDevice currentDevice].systemName;
  129. if ([systemName isEqualToString:@"iPhone OS"]) {
  130. systemName = @"iOS";
  131. }
  132. NSString *expectedOSVersion = [NSString stringWithFormat:@"%@ %@",
  133. systemName, [UIDevice currentDevice].systemVersion];
  134. NSDictionary<NSString *, NSObject *> *authParams = request.additionalParameters;
  135. if (_isEligibleForEMM) {
  136. XCTAssertEqualObjects(authParams[@"emm_support"], kEMMVersion,
  137. @"EMM support should match in auth request");
  138. XCTAssertEqualObjects(authParams[@"device_os"], expectedOSVersion,
  139. @"OS version should match in auth request");
  140. } else {
  141. XCTAssertNil(authParams[@"emm_support"],
  142. @"EMM support should not be in auth request for unsupported OS");
  143. XCTAssertNil(authParams[@"device_os"],
  144. @"OS version should not be in auth request for unsupported OS");
  145. }
  146. }
  147. #endif // TARGET_OS_IOS && !TARGET_OS_MACCATALYST
  148. #pragma mark - test `accessTokenRequestWithAuthState:serverClientID:openIDRealm:emmSupport:`.
  149. - (void)testCreateAccessTokenRequest_NoAccessToken_hasAuthorizationCode {
  150. OIDAuthorizationResponse *authResponse =
  151. [OIDAuthorizationResponse testInstanceWithAdditionalParameters:nil
  152. errorString:nil];
  153. OIDAuthState *authState = [[OIDAuthState alloc] initWithAuthorizationResponse:authResponse
  154. tokenResponse:nil];
  155. OIDTokenRequest *tokenRequest =
  156. [GIDAuthorizationUtil accessTokenRequestWithAuthState:authState
  157. serverClientID:kServerClientId
  158. openIDRealm:kOpenIDRealm
  159. emmSupport:nil];
  160. NSDictionary<NSString *, NSString *> *params = tokenRequest.additionalParameters;
  161. XCTAssertEqual(params[kOpenIDRealmParameter], kOpenIDRealm, @"OpenID Realm should match.");
  162. XCTAssertEqual(params[kAudienceParameter], kServerClientId, @"Server Client ID should match.");
  163. }
  164. #if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
  165. - (void)testCreateAccessTokenRequest_EMMFlow {
  166. NSDictionary<NSString *, NSString *> *additionalParameters =
  167. @{ @"emm_passcode_info_required" : @"1" };
  168. OIDAuthorizationResponse *authResponse =
  169. [OIDAuthorizationResponse testInstanceWithAdditionalParameters:additionalParameters
  170. errorString:nil];
  171. OIDAuthState *authState = [[OIDAuthState alloc] initWithAuthorizationResponse:authResponse
  172. tokenResponse:nil];
  173. OIDTokenRequest *tokenRequest =
  174. [GIDAuthorizationUtil accessTokenRequestWithAuthState:authState
  175. serverClientID:nil
  176. openIDRealm:nil
  177. emmSupport:kEMMVersion];
  178. NSString *systemName = [UIDevice currentDevice].systemName;
  179. if ([systemName isEqualToString:@"iPhone OS"]) {
  180. systemName = @"iOS";
  181. }
  182. NSString *expectedOSVersion = [NSString stringWithFormat:@"%@ %@",
  183. systemName, [UIDevice currentDevice].systemVersion];
  184. NSDictionary<NSString *, NSString *> *tokenParams = tokenRequest.additionalParameters;
  185. if (_isEligibleForEMM) {
  186. XCTAssertEqualObjects(tokenParams[@"emm_support"], kEMMVersion,
  187. @"EMM support should match in token request");
  188. XCTAssertEqualObjects(tokenParams[@"device_os"],
  189. expectedOSVersion,
  190. @"OS version should match in token request");
  191. XCTAssertNotNil(tokenParams[@"emm_passcode_info"],
  192. @"passcode info should be in token request");
  193. } else {
  194. XCTAssertNil(tokenParams[@"emm_support"],
  195. @"EMM support should not be in token request for unsupported OS");
  196. XCTAssertNil(tokenParams[@"device_os"],
  197. @"OS version should not be in token request for unsupported OS");
  198. XCTAssertNil(tokenParams[@"emm_passcode_info"],
  199. @"passcode info should not be in token request for unsupported OS");
  200. }
  201. }
  202. #endif // TARGET_OS_IOS && !TARGET_OS_MACCATALYST
  203. #pragma mark - test `resolvedScopesFromGrantedScopes:ithNewScopes:error:`.
  204. - (void)testUnionScopes_success {
  205. NSArray<NSString *> *scopes = @[kScopeEmail, kScopeProfile];
  206. NSArray<NSString *> *newScopes = @[kScopeBirthday];
  207. NSError *error;
  208. NSArray<NSString *> *allScopes =
  209. [GIDAuthorizationUtil resolvedScopesFromGrantedScopes:scopes
  210. withNewScopes:newScopes
  211. error:&error];
  212. NSArray<NSString *> *expectedScopes = @[kScopeEmail, kScopeProfile, kScopeBirthday];
  213. XCTAssertEqualObjects(allScopes, expectedScopes);
  214. XCTAssertNil(error);
  215. }
  216. - (void)testUnionScopes_addExistingScopes_error {
  217. NSArray<NSString *> *scopes = @[kScopeEmail, kScopeProfile, kScopeBirthday];
  218. NSArray<NSString *> *newScopes = @[kScopeBirthday];
  219. NSError *error;
  220. NSArray<NSString *> *allScopes =
  221. [GIDAuthorizationUtil resolvedScopesFromGrantedScopes:scopes
  222. withNewScopes:newScopes
  223. error:&error];
  224. XCTAssertNil(allScopes);
  225. XCTAssertEqualObjects(error.domain, kGIDSignInErrorDomain);
  226. XCTAssertEqual(error.code, kGIDSignInErrorCodeScopesAlreadyGranted);
  227. }
  228. @end
  229. NS_ASSUME_NONNULL_END