Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(app_check, mobile): add option to pass debugTokens in initialization #13101

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
@@ -102,6 +102,8 @@ private Task<Void> activate(Map<String, Object> arguments) {
case debugProvider:
{
FirebaseAppCheck firebaseAppCheck = getAppCheck(arguments);
FlutterFirebaseAppRegistrar.debugToken =
(String) arguments.get("androidDebugToken");
firebaseAppCheck.installAppCheckProviderFactory(
DebugAppCheckProviderFactory.getInstance());
break;
Original file line number Diff line number Diff line change
@@ -5,17 +5,38 @@
package io.flutter.plugins.firebase.appcheck;

import androidx.annotation.Keep;
import androidx.annotation.Nullable;
import com.google.firebase.appcheck.debug.InternalDebugSecretProvider;
import com.google.firebase.components.Component;
import com.google.firebase.components.ComponentRegistrar;
import com.google.firebase.platforminfo.LibraryVersionComponent;
import java.util.Collections;
import java.util.Arrays;
import java.util.List;

@Keep
public class FlutterFirebaseAppRegistrar implements ComponentRegistrar {
public class FlutterFirebaseAppRegistrar
implements ComponentRegistrar, InternalDebugSecretProvider {
private static final String DEBUG_SECRET_NAME = "fire-app-check-debug-secret";

public static String debugToken;

@Override
public List<Component<?>> getComponents() {
return Collections.<Component<?>>singletonList(
LibraryVersionComponent.create(BuildConfig.LIBRARY_NAME, BuildConfig.LIBRARY_VERSION));
Component<?> library =
LibraryVersionComponent.create(BuildConfig.LIBRARY_NAME, BuildConfig.LIBRARY_VERSION);

Component<InternalDebugSecretProvider> debugSecretProvider =
Component.builder(InternalDebugSecretProvider.class)
.name(DEBUG_SECRET_NAME)
.factory(container -> this)
.build();

return Arrays.<Component<?>>asList(library, debugSecretProvider);
}

@Nullable
@Override
public String getDebugSecret() {
return debugToken;
}
}
Original file line number Diff line number Diff line change
@@ -14,10 +14,19 @@ - (id)initWithApp:app {
return self;
}

- (void)configure:(FIRApp *)app providerName:(NSString *)providerName {
- (void)configure:(FIRApp *)app
providerName:(NSString *)providerName
debugToken:(NSString *)debugToken {
if ([providerName isEqualToString:@"debug"]) {
if (debugToken != nil) {
// We have a debug token, so just need to stuff it in the environment and it will hook up
char *key = "FIRAAppCheckDebugToken", *value = (char *)[debugToken UTF8String];
int overwrite = 1;
setenv(key, value, overwrite);
}

FIRAppCheckDebugProvider *provider = [[FIRAppCheckDebugProvider alloc] initWithApp:app];
NSLog(@"Firebase App Check Debug Token: %@", [provider localDebugToken]);
if (debugToken == nil) NSLog(@"Firebase App Check Debug Token: %@", [provider localDebugToken]);
self.delegateProvider = provider;
}

Original file line number Diff line number Diff line change
@@ -25,13 +25,15 @@ @implementation FLTAppCheckProviderFactory
self.providers[app.name] = [FLTAppCheckProvider new];
FLTAppCheckProvider *provider = self.providers[app.name];
// We set "deviceCheck" as this is currently what is default. Backward compatible.
[provider configure:app providerName:@"deviceCheck"];
[provider configure:app providerName:@"deviceCheck" debugToken:nil];
}

return self.providers[app.name];
}

- (void)configure:(FIRApp *)app providerName:(NSString *)providerName {
- (void)configure:(FIRApp *)app
providerName:(NSString *)providerName
debugToken:(NSString *)debugToken {
if (self.providers == nil) {
self.providers = [NSMutableDictionary new];
}
@@ -41,7 +43,7 @@ - (void)configure:(FIRApp *)app providerName:(NSString *)providerName {
}

FLTAppCheckProvider *provider = self.providers[app.name];
[provider configure:app providerName:providerName];
[provider configure:app providerName:providerName debugToken:debugToken];
}

@end
Original file line number Diff line number Diff line change
@@ -123,9 +123,10 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)flutter
- (void)activate:(id)arguments withMethodCallResult:(FLTFirebaseMethodCallResult *)result {
NSString *appNameDart = arguments[@"appName"];
NSString *providerName = arguments[@"appleProvider"];
NSString *debugToken = arguments[@"appleDebugToken"];

FIRApp *app = [FLTFirebasePlugin firebaseAppNamed:appNameDart];
[self->providerFactory configure:app providerName:providerName];
[self->providerFactory configure:app providerName:providerName debugToken:debugToken];
result.success(nil);
}

Original file line number Diff line number Diff line change
@@ -10,7 +10,9 @@

@property id<FIRAppCheckProvider> delegateProvider;

- (void)configure:(FIRApp *)app providerName:(NSString *)providerName;
- (void)configure:(FIRApp *)app
providerName:(NSString *)providerName
debugToken:(NSString *)debugToken;

- (id)initWithApp:(FIRApp *)app;

Original file line number Diff line number Diff line change
@@ -7,6 +7,8 @@

@property NSMutableDictionary *_Nullable providers;

- (void)configure:(FIRApp *_Nonnull)app providerName:(NSString *_Nonnull)providerName;
- (void)configure:(FIRApp *_Nonnull)app
providerName:(NSString *_Nonnull)providerName
debugToken:(NSString *)debugToken;

@end
Original file line number Diff line number Diff line change
@@ -55,16 +55,23 @@ class FirebaseAppCheck extends FirebasePluginPlatform {
/// On iOS or macOS, the default provider is "device check". If you wish to set the provider to "app attest", "debug" or "app attest with fallback to device check"
/// ("app attest" is only available on iOS 14.0+, macOS 14.0+), you may set the `appleProvider` property using the `AppleProvider` enum
///
/// `androidDebugToken` and `appleDebugToken` allow you to set a debug token for the "debug" provider on Android and Apple's systems, respectively.
/// On iOS, you must restart the app after changing the appleDebugToken.
///
/// For more information, see [the Firebase Documentation](https://firebase.google.com/docs/app-check)
Future<void> activate({
WebProvider? webProvider,
AndroidProvider androidProvider = AndroidProvider.playIntegrity,
AppleProvider appleProvider = AppleProvider.deviceCheck,
String? androidDebugToken,
String? appleDebugToken,
}) {
return _delegate.activate(
webProvider: webProvider,
androidProvider: androidProvider,
appleProvider: appleProvider,
androidDebugToken: androidDebugToken,
appleDebugToken: appleDebugToken,
);
}

Original file line number Diff line number Diff line change
@@ -78,17 +78,21 @@ class MethodChannelFirebaseAppCheck extends FirebaseAppCheckPlatform {
WebProvider? webProvider,
AndroidProvider? androidProvider,
AppleProvider? appleProvider,
String? androidDebugToken,
String? appleDebugToken,
}) async {
try {
await channel.invokeMethod<void>('FirebaseAppCheck#activate', {
'appName': app.name,
// Allow value to pass for debug mode for unit testing
if (defaultTargetPlatform == TargetPlatform.android || kDebugMode)
'androidProvider': getAndroidProviderString(androidProvider),
if (androidDebugToken != null) 'androidDebugToken': androidDebugToken,
if (defaultTargetPlatform == TargetPlatform.iOS ||
defaultTargetPlatform == TargetPlatform.macOS ||
kDebugMode)
'appleProvider': getAppleProviderString(appleProvider),
if (appleDebugToken != null) 'appleDebugToken': appleDebugToken,
});
} on PlatformException catch (e, s) {
convertPlatformException(e, s);
Original file line number Diff line number Diff line change
@@ -66,6 +66,8 @@ abstract class FirebaseAppCheckPlatform extends PlatformInterface {
WebProvider? webProvider,
AndroidProvider? androidProvider,
AppleProvider? appleProvider,
String? androidDebugToken,
String? appleDebugToken,
}) {
throw UnimplementedError('activate() is not implemented');
}
Original file line number Diff line number Diff line change
@@ -99,6 +99,8 @@ class FirebaseAppCheckWeb extends FirebaseAppCheckPlatform {
WebProvider? webProvider,
AndroidProvider? androidProvider,
AppleProvider? appleProvider,
String? androidDebugToken,
String? appleDebugToken,
}) async {
// save the recaptcha type and site key for future startups
if (webProvider != null) {
Original file line number Diff line number Diff line change
@@ -131,6 +131,8 @@ class MockFirebaseAppCheckWeb extends _i1.Mock
_i3.WebProvider? webProvider,
_i3.AndroidProvider? androidProvider,
_i3.AppleProvider? appleProvider,
String? androidDebugToken,
String? appleDebugToken,
}) =>
(super.noSuchMethod(
Invocation.method(
@@ -140,6 +142,8 @@ class MockFirebaseAppCheckWeb extends _i1.Mock
#webProvider: webProvider,
#androidProvider: androidProvider,
#appleProvider: appleProvider,
#androidDebugToken: androidDebugToken,
#appleDebugToken: appleDebugToken,
},
),
returnValue: _i5.Future<void>.value(),
Original file line number Diff line number Diff line change
@@ -781,6 +781,8 @@ class MockFirebaseAppCheck extends _i1.Mock implements _i10.FirebaseAppCheck {
_i11.WebProvider? webProvider,
_i11.AndroidProvider? androidProvider = _i11.AndroidProvider.playIntegrity,
_i11.AppleProvider? appleProvider = _i11.AppleProvider.deviceCheck,
String? androidDebugToken,
String? appleDebugToken,
}) =>
(super.noSuchMethod(
Invocation.method(
@@ -790,6 +792,8 @@ class MockFirebaseAppCheck extends _i1.Mock implements _i10.FirebaseAppCheck {
#webProvider: webProvider,
#androidProvider: androidProvider,
#appleProvider: appleProvider,
#androidDebugToken: androidDebugToken,
#appleDebugToken: appleDebugToken,
},
),
returnValue: _i6.Future<void>.value(),
Original file line number Diff line number Diff line change
@@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:io';

import 'package:firebase_app_check/firebase_app_check.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/foundation.dart';
@@ -77,6 +79,34 @@ void main() {
},
skip: kIsWeb,
);

test(
'debugToken on Android',
() async {
await expectLater(
FirebaseAppCheck.instance.activate(
androidProvider: AndroidProvider.debug,
androidDebugToken: 'debug_token',
),
completes,
);
},
skip: !Platform.isAndroid,
);

test(
'debugToken on iOS',
() async {
await expectLater(
FirebaseAppCheck.instance.activate(
appleDebugToken: 'debug_token',
appleProvider: AppleProvider.debug,
),
completes,
);
},
skip: !Platform.isIOS,
);
},
);
}