diff --git a/.gitignore b/.gitignore index 538419c3..103cb405 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ Podfile.lock # Firebase App Check Example **/GoogleService-Info.plist +**/AppCheckSecrets.xcconfig diff --git a/GoogleSignIn.podspec b/GoogleSignIn.podspec index 8c7d93b7..3f1c9488 100644 --- a/GoogleSignIn.podspec +++ b/GoogleSignIn.podspec @@ -33,7 +33,7 @@ The Google Sign-In SDK allows users to sign in with their Google account from th ] s.ios.framework = 'UIKit' s.osx.framework = 'AppKit' - s.dependency 'AppCheckCore', '~> 0.1.0-alpha.4' + s.dependency 'AppCheckCore', '~> 0.1.0-alpha.9' s.dependency 'AppAuth', '~> 1.6' s.dependency 'GTMAppAuth', '~> 4.0' s.dependency 'GTMSessionFetcher/Core', '>= 1.1', '< 4.0' diff --git a/GoogleSignIn/Sources/GIDAppCheck/Implementations/Fake/GIDAppCheckProviderFake.h b/GoogleSignIn/Sources/GIDAppCheck/Implementations/Fake/GIDAppCheckProviderFake.h index 2f0d64b8..e294273f 100644 --- a/GoogleSignIn/Sources/GIDAppCheck/Implementations/Fake/GIDAppCheckProviderFake.h +++ b/GoogleSignIn/Sources/GIDAppCheck/Implementations/Fake/GIDAppCheckProviderFake.h @@ -31,7 +31,8 @@ NS_CLASS_AVAILABLE_IOS(14) /// error. /// /// @param token The `GACAppCheckToken` instance to pass into the completion called from -/// `getTokenWithCompletion:`. +/// `getTokenWithCompletion:`. Use `nil` if you would like a placeholder token from +/// AppCheckCore. /// @param error The `NSError` to pass into the completion called from /// `getTokenWithCompletion:`. - (instancetype)initWithAppCheckToken:(nullable GACAppCheckToken *)token diff --git a/GoogleSignIn/Sources/GIDAppCheck/Implementations/Fake/GIDAppCheckProviderFake.m b/GoogleSignIn/Sources/GIDAppCheck/Implementations/Fake/GIDAppCheckProviderFake.m index 0a3dfb1a..903fc3ff 100644 --- a/GoogleSignIn/Sources/GIDAppCheck/Implementations/Fake/GIDAppCheckProviderFake.m +++ b/GoogleSignIn/Sources/GIDAppCheck/Implementations/Fake/GIDAppCheckProviderFake.m @@ -22,14 +22,14 @@ @interface GIDAppCheckProviderFake () -@property(nonatomic, strong, nullable) id token; +@property(nonatomic, strong, nullable) GACAppCheckToken *token; @property(nonatomic, strong, nullable) NSError *error; @end @implementation GIDAppCheckProviderFake -- (instancetype)initWithAppCheckToken:(nullable id)token +- (instancetype)initWithAppCheckToken:(nullable GACAppCheckToken *)token error:(nullable NSError *)error { if (self = [super init]) { _token = token; @@ -38,14 +38,13 @@ - (instancetype)initWithAppCheckToken:(nullable id)tok return self; } -- (void)getTokenWithCompletion:(nonnull void (^)(id _Nullable, - NSError * _Nullable))handler { +- (void)getTokenWithCompletion:(void (^)(GACAppCheckToken *, NSError * _Nullable))handler { dispatch_async(dispatch_get_main_queue(), ^{ handler(self.token, self.error); }); } -- (void)getLimitedUseTokenWithCompletion:(void (^)(id _Nullable, +- (void)getLimitedUseTokenWithCompletion:(void (^)(GACAppCheckToken *, NSError * _Nullable))handler { dispatch_async(dispatch_get_main_queue(), ^{ handler(self.token, self.error); diff --git a/GoogleSignIn/Sources/GIDAppCheck/Implementations/GIDAppCheck.h b/GoogleSignIn/Sources/GIDAppCheck/Implementations/GIDAppCheck.h index 68d0a44e..6b7d1d92 100644 --- a/GoogleSignIn/Sources/GIDAppCheck/Implementations/GIDAppCheck.h +++ b/GoogleSignIn/Sources/GIDAppCheck/Implementations/GIDAppCheck.h @@ -23,20 +23,26 @@ NS_ASSUME_NONNULL_BEGIN @protocol GACAppCheckProvider; -@protocol GACAppCheckTokenProtocol; +@class GACAppCheckToken; extern NSString *const kGIDAppCheckPreparedKey; NS_CLASS_AVAILABLE_IOS(14) @interface GIDAppCheck : NSObject -/// Creates the instance of this App Check wrapper class. +- (instancetype)init NS_UNAVAILABLE; + +/// Creates the instance of this App Check wrapper class using `GACAppCheckDebugProvider`. /// -/// The instance is created using `+[NSUserDefaults standardUserDefaults]` and the standard App -/// Check provider. +/// @param APIKey The API Key to use when creating the debug App Check provider. +/// +/// The instance is created using `+[NSUserDefaults standardUserDefaults]`. ++ (instancetype)appCheckUsingDebugProviderWithAPIKey:(NSString *)APIKey; + +/// Creates the instance of this App Check wrapper class using `GACAppAttestProvider`. /// -/// @SeeAlso The App Check provider is constructed with `+[GIDAppCheck standardAppCheckProvider]`. -- (instancetype)init; +/// The instance is created using `+[NSUserDefaults standardUserDefaults]`. ++ (instancetype)appCheckUsingAppAttestProvider; /// Creates the instance of this App Check wrapper class. /// @@ -55,11 +61,9 @@ NS_CLASS_AVAILABLE_IOS(14) /// Fetches the limited use Firebase token. /// -/// @param completion A `nullable` callback with the `FIRAppCheckToken` if present, or an `NSError` -/// otherwise. +/// @param completion A `nullable` callback with the `FIRAppCheckToken`, or an `NSError` otherwise. - (void)getLimitedUseTokenWithCompletion: - (nullable void (^)(id _Nullable token, - NSError * _Nullable error))completion; + (nullable void (^)(GACAppCheckToken *token, NSError * _Nullable error))completion; /// Whether or not the App Attest key ID created and the attestation object has been fetched. - (BOOL)isPrepared; diff --git a/GoogleSignIn/Sources/GIDAppCheck/Implementations/GIDAppCheck.m b/GoogleSignIn/Sources/GIDAppCheck/Implementations/GIDAppCheck.m index 97a74241..7ac20947 100644 --- a/GoogleSignIn/Sources/GIDAppCheck/Implementations/GIDAppCheck.m +++ b/GoogleSignIn/Sources/GIDAppCheck/Implementations/GIDAppCheck.m @@ -20,8 +20,9 @@ #import #import -#import +#import #import +#import #import "GoogleSignIn/Sources/GIDAppCheck/Implementations/GIDAppCheck.h" #import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDAppCheckError.h" @@ -35,8 +36,7 @@ static NSString *const kGIDAppAttestBaseURL = @"https://firebaseappcheck.googleapis.com/v1beta"; typedef void (^GIDAppCheckPrepareCompletion)(NSError * _Nullable); -typedef void (^GIDAppCheckTokenCompletion)(id _Nullable, - NSError * _Nullable); +typedef void (^GIDAppCheckTokenCompletion)(GACAppCheckToken *,NSError * _Nullable); @interface GIDAppCheck () @@ -50,10 +50,14 @@ @interface GIDAppCheck () @implementation GIDAppCheck -- (instancetype)init { - id provider = [GIDAppCheck standardAppCheckProvider]; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - return [self initWithAppCheckProvider:provider userDefaults:userDefaults]; ++ (instancetype)appCheckUsingDebugProviderWithAPIKey:(NSString *)APIKey { + return [[self alloc] initWithAppCheckProvider:[GIDAppCheck debugAppCheckProviderWithAPIKey:APIKey] + userDefaults:[NSUserDefaults standardUserDefaults]]; +} + ++ (instancetype)appCheckUsingAppAttestProvider { + return [[self alloc] initWithAppCheckProvider:[GIDAppCheck appAttestProvider] + userDefaults:[NSUserDefaults standardUserDefaults]]; } - (instancetype)initWithAppCheckProvider:(id)appCheckProvider @@ -110,17 +114,16 @@ - (void)prepareForAppCheckWithCompletion:(nullable GIDAppCheckPrepareCompletion) return; } - [self.appCheck limitedUseTokenWithCompletion:^(id _Nullable token, - NSError * _Nullable error) { - NSError * __block maybeError = error; + [self.appCheck limitedUseTokenWithCompletion:^(GACAppCheckTokenResult * _Nonnull result) { + NSError * __block maybeError = result.error; @synchronized (self) { - if (!token && !error) { + if (!result.token && !result.error) { maybeError = [NSError errorWithDomain:kGIDAppCheckErrorDomain code:kGIDAppCheckUnexpectedError userInfo:nil]; } - if (token) { + if (result.token) { [self.userDefaults setBool:YES forKey:kGIDAppCheckPreparedKey]; } @@ -139,13 +142,12 @@ - (void)prepareForAppCheckWithCompletion:(nullable GIDAppCheckPrepareCompletion) - (void)getLimitedUseTokenWithCompletion:(nullable GIDAppCheckTokenCompletion)completion { dispatch_async(self.workerQueue, ^{ - [self.appCheck limitedUseTokenWithCompletion:^(id _Nullable token, - NSError * _Nullable error) { - if (token) { + [self.appCheck limitedUseTokenWithCompletion:^(GACAppCheckTokenResult * _Nonnull result) { + if (result.token) { [self.userDefaults setBool:YES forKey:kGIDAppCheckPreparedKey]; } if (completion) { - completion(token, error); + completion(result.token, result.error); } }]; }); @@ -156,7 +158,7 @@ + (NSString *)appAttestResourceName { return [NSString stringWithFormat:kGIDAppAttestResourceNameFormat, clientID]; } -+ (id)standardAppCheckProvider { ++ (id)appAttestProvider { return [[GACAppAttestProvider alloc] initWithServiceName:kGIDAppAttestServiceName resourceName:[GIDAppCheck appAttestResourceName] baseURL:kGIDAppAttestBaseURL @@ -165,6 +167,14 @@ + (NSString *)appAttestResourceName { requestHooks:nil]; } ++ (id)debugAppCheckProviderWithAPIKey:(NSString *)APIKey { + return [[GACAppCheckDebugProvider alloc] initWithServiceName:kGIDAppAttestServiceName + resourceName:[GIDAppCheck appAttestResourceName] + baseURL:kGIDAppAttestBaseURL + APIKey:APIKey + requestHooks:nil]; +} + @end #endif // TARGET_OS_IOS && !TARGET_OS_MACCATALYST diff --git a/GoogleSignIn/Sources/GIDSignIn.m b/GoogleSignIn/Sources/GIDSignIn.m index bf832d3c..48b9f368 100644 --- a/GoogleSignIn/Sources/GIDSignIn.m +++ b/GoogleSignIn/Sources/GIDSignIn.m @@ -464,7 +464,7 @@ + (GIDSignIn *)sharedInstance { [[GTMKeychainStore alloc] initWithItemName:kGTMAppAuthKeychainName]; #if TARGET_OS_IOS && !TARGET_OS_MACCATALYST if (@available(iOS 14.0, *)) { - GIDAppCheck *appCheck = [[GIDAppCheck alloc] init]; + GIDAppCheck *appCheck = [GIDAppCheck appCheckUsingAppAttestProvider]; sharedInstance = [[self alloc] initWithKeychainStore:keychainStore appCheck:appCheck]; } @@ -488,6 +488,18 @@ - (void)configureWithCompletion:(nullable void (^)(NSError * _Nullable))completi }]; } } + +- (void)configureDebugProviderWithAPIKey:(NSString *)APIKey + completion:(nullable void (^)(NSError * _Nullable))completion { + @synchronized(self) { + _appCheck = [GIDAppCheck appCheckUsingDebugProviderWithAPIKey:APIKey]; + [_appCheck prepareForAppCheckWithCompletion:^(NSError * _Nullable error) { + if (completion) { + completion(error); + } + }]; + } +} #endif // TARGET_OS_IOS && !TARGET_OS_MACCATALYST #pragma mark - Private methods @@ -646,8 +658,8 @@ - (void)authorizationRequestWithOptions:(GIDSignInInternalOptions *)options comp _timedLoader = [[GIDTimedLoader alloc] initWithPresentingViewController:presentingVC]; } [_timedLoader startTiming]; - [self->_appCheck getLimitedUseTokenWithCompletion: - ^(id _Nullable token, NSError * _Nullable error) { + [self->_appCheck getLimitedUseTokenWithCompletion:^(GACAppCheckToken * _Nullable token, + NSError * _Nullable error) { OIDAuthorizationRequest *request = nil; if (token) { additionalParameters[kClientAssertionTypeParameter] = kClientAssertionTypeParameterValue; diff --git a/GoogleSignIn/Sources/Public/GoogleSignIn/GIDSignIn.h b/GoogleSignIn/Sources/Public/GoogleSignIn/GIDSignIn.h index e6bd3407..82655ca8 100644 --- a/GoogleSignIn/Sources/Public/GoogleSignIn/GIDSignIn.h +++ b/GoogleSignIn/Sources/Public/GoogleSignIn/GIDSignIn.h @@ -71,14 +71,27 @@ typedef NS_ERROR_ENUM(kGIDSignInErrorDomain, GIDSignInErrorCode) { /// Configures `GIDSignIn` for use. /// /// @param completion A nullable callback block passing back any error arising from the -/// configuration process if any exists. +/// configuration process if any exists. /// /// Call this method on `GIDSignIn` prior to use and as early as possible. This method generates App /// Attest key IDs and the attestation object eagerly to minimize latency later on during the sign /// in or add scopes flows. - (void)configureWithCompletion:(nullable void (^)(NSError * _Nullable error))completion +NS_SWIFT_NAME(configure(completion:)); + +/// Configures `GIDSignIn` for use in debug or test environments. +/// +/// @param APIKey The API Key to use during configuration of the App Check debug provider. +/// @param completion A nullable callback block passing back any error arising from the +/// configuration process if any exists. +/// +/// Call this method on `GIDSignIn` prior to use and as early as possible. This method generates App +/// Attest key IDs and the attestation object eagerly to minimize latency later on during the sign +/// in or add scopes flows. +- (void)configureDebugProviderWithAPIKey:(NSString *)APIKey + completion:(nullable void (^)(NSError * _Nullable error))completion API_AVAILABLE(ios(14)) -NS_SWIFT_NAME(configureWithCompletion(completion:)); +NS_SWIFT_NAME(configureDebugProvider(withAPIKey:completion:)); #endif // TARGET_OS_IOS && !TARGET_OS_MACCATALYST diff --git a/GoogleSignIn/Tests/Unit/GIDAppCheckTest.m b/GoogleSignIn/Tests/Unit/GIDAppCheckTest.m index e84c9a84..7c0610ae 100644 --- a/GoogleSignIn/Tests/Unit/GIDAppCheckTest.m +++ b/GoogleSignIn/Tests/Unit/GIDAppCheckTest.m @@ -45,7 +45,7 @@ - (void)tearDown { [self.userDefaults removeSuiteNamed:kUserDefaultsTestSuiteName]; } -- (void)testGetLimitedUseTokenFailure { +- (void)testGetLimitedUseTokenFailureReturnsPlaceholder { XCTestExpectation *tokenFailExpectation = [self expectationWithDescription:@"App check token fail"]; NSError *expectedError = [NSError errorWithDomain:kGIDAppCheckErrorDomain @@ -57,10 +57,10 @@ - (void)testGetLimitedUseTokenFailure { GIDAppCheck *appCheck = [[GIDAppCheck alloc] initWithAppCheckProvider:fakeProvider userDefaults:self.userDefaults]; - [appCheck getLimitedUseTokenWithCompletion:^(id _Nullable token, + [appCheck getLimitedUseTokenWithCompletion:^(GACAppCheckToken *token, NSError * _Nullable error) { - XCTAssertNil(token); XCTAssertEqualObjects(expectedError, error); + XCTAssertNotNil(token); // If there is an error, we expect a placeholder token [tokenFailExpectation fulfill]; }]; @@ -126,7 +126,7 @@ - (void)testGetLimitedUseTokenSucceeds { XCTestExpectation *getLimitedUseTokenSucceedsExpectation = [self expectationWithDescription:@"getLimitedUseToken should succeed"]; - [appCheck getLimitedUseTokenWithCompletion:^(id _Nullable token, + [appCheck getLimitedUseTokenWithCompletion:^(GACAppCheckToken *token, NSError * _Nullable error) { XCTAssertNil(error); XCTAssertNotNil(token); diff --git a/GoogleSignIn/Tests/Unit/GIDSignInTest.m b/GoogleSignIn/Tests/Unit/GIDSignInTest.m index 400e09fb..0f35dc6b 100644 --- a/GoogleSignIn/Tests/Unit/GIDSignInTest.m +++ b/GoogleSignIn/Tests/Unit/GIDSignInTest.m @@ -422,7 +422,7 @@ - (void)testConfigureFailsNoTokenOrError { GIDSignIn *signIn = [[GIDSignIn alloc] initWithKeychainStore:_keychainStore appCheck:appCheck]; - // `configureWithCompletion:` should fail if neither a token or error is present + // Should fail if missing both token and error [signIn configureWithCompletion:^(NSError * _Nullable error) { XCTAssertNotNil(error); XCTAssertEqual(error.code, kGIDAppCheckUnexpectedError); diff --git a/Package.swift b/Package.swift index cd74c50d..be46e8bd 100644 --- a/Package.swift +++ b/Package.swift @@ -48,7 +48,7 @@ let package = Package( .package( name: "AppCheck", url: "https://github.com/google/app-check.git", - .branch("main")), + .branch("CocoaPods-0.1.0-alpha.6")), .package( name: "GTMAppAuth", url: "https://github.com/google/GTMAppAuth.git", diff --git a/Samples/Swift/AppAttestExample/AppAttestExample.xcodeproj/project.pbxproj b/Samples/Swift/AppAttestExample/AppAttestExample.xcodeproj/project.pbxproj index 15473767..e976444d 100644 --- a/Samples/Swift/AppAttestExample/AppAttestExample.xcodeproj/project.pbxproj +++ b/Samples/Swift/AppAttestExample/AppAttestExample.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 4D8DB53AAE2F7D0055DCEA7F /* Pods_AppAttestExample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 91F3A930BB86D9E0648046BC /* Pods_AppAttestExample.framework */; }; + 738B4A322AA8FE800056885D /* AppCheckSecretReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 738B4A312AA8FE800056885D /* AppCheckSecretReader.swift */; }; 738D5F732A26BC3B00A7F11B /* BirthdayLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 738D5F722A26BC3B00A7F11B /* BirthdayLoader.swift */; }; 73A464042A1C3B3400BA8528 /* AppAttestExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73A464032A1C3B3400BA8528 /* AppAttestExampleApp.swift */; }; 73A464062A1C3B3400BA8528 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73A464052A1C3B3400BA8528 /* ContentView.swift */; }; @@ -17,6 +18,8 @@ /* Begin PBXFileReference section */ 1C96B5B2B34E31F1A1CEE95E /* Pods-AppAttestExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppAttestExample.release.xcconfig"; path = "Target Support Files/Pods-AppAttestExample/Pods-AppAttestExample.release.xcconfig"; sourceTree = ""; }; 73443A232A55F56900A4932E /* AppAttestExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AppAttestExample.entitlements; sourceTree = ""; }; + 738B4A302AA7EB840056885D /* AppCheckSecrets.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppCheckSecrets.xcconfig; sourceTree = ""; }; + 738B4A312AA8FE800056885D /* AppCheckSecretReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCheckSecretReader.swift; sourceTree = ""; }; 738D5F722A26BC3B00A7F11B /* BirthdayLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BirthdayLoader.swift; sourceTree = ""; }; 73A065612A786D10007BC7FC /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 73A464002A1C3B3400BA8528 /* AppAttestExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AppAttestExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -73,6 +76,8 @@ 73A464032A1C3B3400BA8528 /* AppAttestExampleApp.swift */, 73A464052A1C3B3400BA8528 /* ContentView.swift */, 738D5F722A26BC3B00A7F11B /* BirthdayLoader.swift */, + 738B4A312AA8FE800056885D /* AppCheckSecretReader.swift */, + 738B4A302AA7EB840056885D /* AppCheckSecrets.xcconfig */, 73A065612A786D10007BC7FC /* Info.plist */, 73A464092A1C3B3500BA8528 /* Preview Content */, ); @@ -209,6 +214,7 @@ buildActionMask = 2147483647; files = ( 738D5F732A26BC3B00A7F11B /* BirthdayLoader.swift in Sources */, + 738B4A322AA8FE800056885D /* AppCheckSecretReader.swift in Sources */, 73A464062A1C3B3400BA8528 /* ContentView.swift in Sources */, 73A464042A1C3B3400BA8528 /* AppAttestExampleApp.swift in Sources */, ); @@ -219,6 +225,7 @@ /* Begin XCBuildConfiguration section */ 73A4640C2A1C3B3500BA8528 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 738B4A302AA7EB840056885D /* AppCheckSecrets.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; diff --git a/Samples/Swift/AppAttestExample/AppAttestExample.xcodeproj/xcshareddata/xcschemes/AppAttestExample.xcscheme b/Samples/Swift/AppAttestExample/AppAttestExample.xcodeproj/xcshareddata/xcschemes/AppAttestExample.xcscheme index 43e79198..f2c125f8 100644 --- a/Samples/Swift/AppAttestExample/AppAttestExample.xcodeproj/xcshareddata/xcschemes/AppAttestExample.xcscheme +++ b/Samples/Swift/AppAttestExample/AppAttestExample.xcodeproj/xcshareddata/xcschemes/AppAttestExample.xcscheme @@ -49,13 +49,6 @@ ReferencedContainer = "container:AppAttestExample.xcodeproj"> - - - - Bool { - GIDSignIn.sharedInstance.configureWithCompletion { error in + #if targetEnvironment(simulator) + let secretReader = AppCheckSecretReader() + guard let APIKey = secretReader.APIKey else { + print("Unable to read API key from bundle or environment") + return true + } + GIDSignIn.sharedInstance.configureDebugProvider(withAPIKey: APIKey) { error in + if let error { + print("Error configuring `GIDSignIn` for Firebase App Check: \(error)") + } + } + #else + GIDSignIn.sharedInstance.configure { error in if let error { print("Error configuring `GIDSignIn` for Firebase App Check: \(error)") } } + #endif return true } diff --git a/Samples/Swift/AppAttestExample/AppAttestExample/AppCheckSecretReader.swift b/Samples/Swift/AppAttestExample/AppAttestExample/AppCheckSecretReader.swift new file mode 100644 index 00000000..bdcab6f1 --- /dev/null +++ b/Samples/Swift/AppAttestExample/AppAttestExample/AppCheckSecretReader.swift @@ -0,0 +1,44 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Foundation + +struct AppCheckSecretReader { + private let APIKeyName = "APP_CHECK_WEB_API_KEY" + + var APIKey: String? { + return APIKeyFromBundle ?? APIKeyFromEnvironment + } + + /// Method for retrieving API key from environment variable used during CI tests + private var APIKeyFromEnvironment: String? { + guard let APIKey = ProcessInfo.processInfo.environment[APIKeyName], !APIKey.isEmpty else { + print("Failed to get \(APIKeyName) from environment.") + return nil + } + return APIKey + } + + /// Method for retrieving API key from the bundle during simulator or debug builds + private var APIKeyFromBundle: String? { + guard let APIKey = Bundle.main.infoDictionary?[APIKeyName] as? String, + !APIKey.isEmpty else { + print("Failed to get \(APIKeyName) from Bundle.") + return nil + } + return APIKey + } +} diff --git a/Samples/Swift/AppAttestExample/AppAttestExample/Info.plist b/Samples/Swift/AppAttestExample/AppAttestExample/Info.plist index b9179a51..e8f329f4 100644 --- a/Samples/Swift/AppAttestExample/AppAttestExample/Info.plist +++ b/Samples/Swift/AppAttestExample/AppAttestExample/Info.plist @@ -2,6 +2,8 @@ + APP_CHECK_WEB_API_KEY + $(APP_CHECK_WEB_API_KEY) CFBundleURLTypes diff --git a/Samples/Swift/AppAttestExample/Podfile b/Samples/Swift/AppAttestExample/Podfile index 2a5c41a5..9554395e 100644 --- a/Samples/Swift/AppAttestExample/Podfile +++ b/Samples/Swift/AppAttestExample/Podfile @@ -1,3 +1,6 @@ +source 'https://github.com/CocoaPods/Specs.git' +source 'https://github.com/firebase/SpecsDev.git' + pod 'GoogleSignIn', :path => '../../../', :testspecs => ['unit'] pod 'GoogleSignInSwiftSupport', :path => '../../../', :testspecs => ['unit'] project 'AppAttestExample.xcodeproj' @@ -5,6 +8,6 @@ project 'AppAttestExample.xcodeproj' use_frameworks! :linkage => :static target 'AppAttestExample' do - pod 'AppCheckCore', :git => 'https://github.com/google/app-check.git', :tag => 'CocoaPods-0.1.0-alpha.1' + pod 'AppCheckCore' platform :ios, '14.0' end