GACAppCheckDebugProvider.m 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*
  2. * Copyright 2020 Google LLC
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #import "AppCheckCore/Sources/Public/AppCheckCore/GACAppCheckDebugProvider.h"
  17. #if __has_include(<FBLPromises/FBLPromises.h>)
  18. #import <FBLPromises/FBLPromises.h>
  19. #else
  20. #import "FBLPromises.h"
  21. #endif
  22. #import "AppCheckCore/Sources/Core/APIService/GACAppCheckAPIService.h"
  23. #import "AppCheckCore/Sources/Core/GACAppCheckLogger+Internal.h"
  24. #import "AppCheckCore/Sources/DebugProvider/API/GACAppCheckDebugProviderAPIService.h"
  25. #import "AppCheckCore/Sources/Public/AppCheckCore/GACAppCheckErrors.h"
  26. #import "AppCheckCore/Sources/Public/AppCheckCore/GACAppCheckToken.h"
  27. NS_ASSUME_NONNULL_BEGIN
  28. // TODO(andrewheard): Parameterize the following Firebase-specific keys.
  29. // FIREBASE_APP_CHECK_ONLY_BEGIN
  30. static NSString *const kDebugTokenEnvKey = @"FIRAAppCheckDebugToken";
  31. static NSString *const kDebugTokenUserDefaultsKey = @"FIRAAppCheckDebugToken";
  32. // FIREBASE_APP_CHECK_ONLY_END
  33. @interface GACAppCheckDebugProvider ()
  34. @property(nonatomic, readonly) id<GACAppCheckDebugProviderAPIServiceProtocol> APIService;
  35. @end
  36. @implementation GACAppCheckDebugProvider
  37. - (instancetype)initWithAPIService:(id<GACAppCheckDebugProviderAPIServiceProtocol>)APIService {
  38. self = [super init];
  39. if (self) {
  40. _APIService = APIService;
  41. }
  42. return self;
  43. }
  44. - (instancetype)initWithServiceName:(NSString *)serviceName
  45. resourceName:(NSString *)resourceName
  46. APIKey:(nullable NSString *)APIKey
  47. requestHooks:(nullable NSArray<GACAppCheckAPIRequestHook> *)requestHooks {
  48. return [self initWithServiceName:serviceName
  49. resourceName:resourceName
  50. baseURL:nil
  51. APIKey:APIKey
  52. limitedUse:NO
  53. requestHooks:requestHooks];
  54. }
  55. - (instancetype)initWithServiceName:(NSString *)serviceName
  56. resourceName:(NSString *)resourceName
  57. baseURL:(nullable NSString *)baseURL
  58. APIKey:(nullable NSString *)APIKey
  59. limitedUse:(BOOL)limitedUse
  60. requestHooks:(nullable NSArray<GACAppCheckAPIRequestHook> *)requestHooks {
  61. NSURLSession *URLSession = [NSURLSession
  62. sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration]];
  63. GACAppCheckAPIService *APIService =
  64. [[GACAppCheckAPIService alloc] initWithURLSession:URLSession
  65. baseURL:baseURL
  66. APIKey:APIKey
  67. requestHooks:requestHooks];
  68. GACAppCheckDebugProviderAPIService *debugAPIService =
  69. [[GACAppCheckDebugProviderAPIService alloc] initWithAPIService:APIService
  70. resourceName:resourceName
  71. limitedUse:limitedUse];
  72. return [self initWithAPIService:debugAPIService];
  73. }
  74. - (NSString *)currentDebugToken {
  75. NSString *envVariableValue = [[NSProcessInfo processInfo] environment][kDebugTokenEnvKey];
  76. if (envVariableValue.length > 0) {
  77. return envVariableValue;
  78. } else {
  79. return [self localDebugToken];
  80. }
  81. }
  82. - (NSString *)localDebugToken {
  83. return [self storedDebugToken] ?: [self generateAndStoreDebugToken];
  84. }
  85. - (nullable NSString *)storedDebugToken {
  86. return [[NSUserDefaults standardUserDefaults] stringForKey:kDebugTokenUserDefaultsKey];
  87. }
  88. - (void)storeDebugToken:(nullable NSString *)token {
  89. [[NSUserDefaults standardUserDefaults] setObject:token forKey:kDebugTokenUserDefaultsKey];
  90. }
  91. - (NSString *)generateAndStoreDebugToken {
  92. NSString *token = [NSUUID UUID].UUIDString;
  93. [self storeDebugToken:token];
  94. return token;
  95. }
  96. #pragma mark - GACAppCheckProvider
  97. - (void)getTokenWithCompletion:(void (^)(GACAppCheckToken *_Nullable token,
  98. NSError *_Nullable error))handler {
  99. [FBLPromise do:^NSString * {
  100. return [self currentDebugToken];
  101. }]
  102. .then(^FBLPromise<GACAppCheckToken *> *(NSString *debugToken) {
  103. return [self.APIService appCheckTokenWithDebugToken:debugToken];
  104. })
  105. .then(^id(GACAppCheckToken *appCheckToken) {
  106. handler(appCheckToken, nil);
  107. return nil;
  108. })
  109. .catch(^void(NSError *error) {
  110. NSString *logMessage = [NSString
  111. stringWithFormat:@"Failed to exchange debug token to app check token: %@", error];
  112. GACAppCheckLogDebug(GACLoggerAppCheckMessageDebugProviderFailedExchange, logMessage);
  113. handler(nil, error);
  114. });
  115. }
  116. @end
  117. NS_ASSUME_NONNULL_END