Skip to content

Commit 66c7398

Browse files
authored
Integrate AppCheckProviders with Firebase Components. (#4436)
* Integrate `SafetyNetAppCheckProvider` with Firebase Components. * Suppress warning. * Integrate DebugAppCheckProvider with Firebase Components. * Add unit tests for the new registrars. * Integrate `PlayIntegrityAppCheckProvider` with Firebase Components.
1 parent 69ed2cb commit 66c7398

File tree

17 files changed

+316
-56
lines changed

17 files changed

+316
-56
lines changed

appcheck/firebase-appcheck-debug-testing/src/main/AndroidManifest.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,11 @@
1717
package="com.google.firebase.appcheck.debug.testing">
1818
<!--Although the *SdkVersion is captured in gradle build files, this is required for non gradle builds-->
1919
<!--<uses-sdk android:minSdkVersion="16"/>-->
20+
<application>
21+
<service android:name="com.google.firebase.components.ComponentDiscoveryService"
22+
android:exported="false">
23+
<meta-data android:name="com.google.firebase.components:com.google.firebase.appcheck.debug.testing.FirebaseAppCheckDebugTestingRegistrar"
24+
android:value="com.google.firebase.components.ComponentRegistrar" />
25+
</service>
26+
</application>
2027
</manifest>

appcheck/firebase-appcheck-debug-testing/src/main/java/com/google/firebase/appcheck/debug/testing/DebugAppCheckTestHelper.java

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,10 @@
1515
package com.google.firebase.appcheck.debug.testing;
1616

1717
import androidx.annotation.NonNull;
18-
import androidx.annotation.VisibleForTesting;
19-
import androidx.test.platform.app.InstrumentationRegistry;
2018
import com.google.firebase.FirebaseApp;
2119
import com.google.firebase.appcheck.AppCheckProviderFactory;
2220
import com.google.firebase.appcheck.FirebaseAppCheck;
2321
import com.google.firebase.appcheck.debug.DebugAppCheckProviderFactory;
24-
import com.google.firebase.appcheck.debug.DebugAppCheckProviderFactoryHelper;
2522
import com.google.firebase.appcheck.internal.DefaultFirebaseAppCheck;
2623

2724
/**
@@ -66,28 +63,16 @@
6663
* </pre>
6764
*/
6865
public final class DebugAppCheckTestHelper {
69-
private static final String DEBUG_SECRET_KEY = "firebaseAppCheckDebugSecret";
70-
71-
private final String debugSecret;
72-
7366
/**
74-
* Creates a {@link DebugAppCheckTestHelper} instance with the debug secret obtained from {@link
75-
* InstrumentationRegistry} arguments.
67+
* Creates a {@link DebugAppCheckTestHelper} instance with a debug secret obtained from {@link
68+
* androidx.test.platform.app.InstrumentationRegistry} arguments.
7669
*/
7770
@NonNull
7871
public static DebugAppCheckTestHelper fromInstrumentationArgs() {
79-
String debugSecret = InstrumentationRegistry.getArguments().getString(DEBUG_SECRET_KEY);
80-
return new DebugAppCheckTestHelper(debugSecret);
72+
return new DebugAppCheckTestHelper();
8173
}
8274

83-
@VisibleForTesting
84-
static DebugAppCheckTestHelper fromString(String debugSecret) {
85-
return new DebugAppCheckTestHelper(debugSecret);
86-
}
87-
88-
private DebugAppCheckTestHelper(String debugSecret) {
89-
this.debugSecret = debugSecret;
90-
}
75+
private DebugAppCheckTestHelper() {}
9176

9277
/**
9378
* Installs a {@link DebugAppCheckProviderFactory} to the default {@link FirebaseApp} and runs the
@@ -109,8 +94,7 @@ public <E extends Throwable> void withDebugProvider(
10994
(DefaultFirebaseAppCheck) FirebaseAppCheck.getInstance(firebaseApp);
11095
AppCheckProviderFactory currentAppCheckProviderFactory =
11196
firebaseAppCheck.getInstalledAppCheckProviderFactory();
112-
firebaseAppCheck.installAppCheckProviderFactory(
113-
DebugAppCheckProviderFactoryHelper.createDebugAppCheckProviderFactory(debugSecret));
97+
firebaseAppCheck.installAppCheckProviderFactory(DebugAppCheckProviderFactory.getInstance());
11498
try {
11599
runnable.run();
116100
} catch (Throwable throwable) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2022 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+
15+
package com.google.firebase.appcheck.debug.testing;
16+
17+
import androidx.test.platform.app.InstrumentationRegistry;
18+
import com.google.firebase.appcheck.debug.InternalDebugSecretProvider;
19+
20+
/** @hide */
21+
public class DebugSecretProvider implements InternalDebugSecretProvider {
22+
private static final String DEBUG_SECRET_KEY = "firebaseAppCheckDebugSecret";
23+
24+
DebugSecretProvider() {}
25+
26+
/**
27+
* Returns a debug secret from {@link InstrumentationRegistry} arguments to be used with the
28+
* {@link com.google.firebase.appcheck.debug.internal.DebugAppCheckProvider} in continuous
29+
* integration testing flows.
30+
*/
31+
@Override
32+
public String getDebugSecret() {
33+
return InstrumentationRegistry.getArguments().getString(DEBUG_SECRET_KEY);
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright 2022 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+
15+
package com.google.firebase.appcheck.debug.testing;
16+
17+
import com.google.android.gms.common.annotation.KeepForSdk;
18+
import com.google.firebase.appcheck.debug.BuildConfig;
19+
import com.google.firebase.appcheck.debug.InternalDebugSecretProvider;
20+
import com.google.firebase.components.Component;
21+
import com.google.firebase.components.ComponentRegistrar;
22+
import com.google.firebase.platforminfo.LibraryVersionComponent;
23+
import java.util.Arrays;
24+
import java.util.List;
25+
26+
/**
27+
* {@link ComponentRegistrar} for setting up FirebaseAppCheck debug testing's dependency injections
28+
* in Firebase Android Components.
29+
*
30+
* @hide
31+
*/
32+
@KeepForSdk
33+
public class FirebaseAppCheckDebugTestingRegistrar implements ComponentRegistrar {
34+
private static final String LIBRARY_NAME = "fire-app-check-debug-testing";
35+
36+
@Override
37+
public List<Component<?>> getComponents() {
38+
return Arrays.asList(
39+
Component.builder(DebugSecretProvider.class, (InternalDebugSecretProvider.class))
40+
.name(LIBRARY_NAME)
41+
.factory((container) -> new DebugSecretProvider())
42+
.build(),
43+
LibraryVersionComponent.create(LIBRARY_NAME, BuildConfig.VERSION_NAME));
44+
}
45+
}

appcheck/firebase-appcheck-debug-testing/src/test/java/com/google/firebase/appcheck/debug/testing/DebugAppCheckTestHelperTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,9 @@ public class DebugAppCheckTestHelperTest {
3535
private static final String PROJECT_ID = "projectId";
3636
private static final String APP_ID = "appId";
3737
private static final String OTHER_FIREBASE_APP_NAME = "otherFirebaseAppName";
38-
private static final String DEBUG_SECRET = "debugSecret";
3938

4039
private final DebugAppCheckTestHelper debugAppCheckTestHelper =
41-
DebugAppCheckTestHelper.fromString(DEBUG_SECRET);
40+
DebugAppCheckTestHelper.fromInstrumentationArgs();
4241

4342
@Before
4443
public void setUp() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2022 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+
15+
package com.google.firebase.appcheck.debug.testing;
16+
17+
import static com.google.common.truth.Truth.assertThat;
18+
19+
import com.google.firebase.components.Component;
20+
import java.util.List;
21+
import org.junit.Test;
22+
import org.junit.runner.RunWith;
23+
import org.robolectric.RobolectricTestRunner;
24+
25+
/** Tests for {@link FirebaseAppCheckDebugTestingRegistrar}. */
26+
@RunWith(RobolectricTestRunner.class)
27+
public class FirebaseAppCheckDebugTestingRegistrarTest {
28+
@Test
29+
public void testGetComponents() {
30+
FirebaseAppCheckDebugTestingRegistrar registrar = new FirebaseAppCheckDebugTestingRegistrar();
31+
List<Component<?>> components = registrar.getComponents();
32+
assertThat(components).isNotEmpty();
33+
assertThat(components).hasSize(2);
34+
Component<?> appCheckDebugTestingComponent = components.get(0);
35+
assertThat(appCheckDebugTestingComponent.getDependencies()).isEmpty();
36+
assertThat(appCheckDebugTestingComponent.isLazy()).isTrue();
37+
}
38+
}

appcheck/firebase-appcheck-debug/src/main/java/com/google/firebase/appcheck/debug/DebugAppCheckProviderFactory.java

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,7 @@ public class DebugAppCheckProviderFactory implements AppCheckProviderFactory {
2727

2828
private static final DebugAppCheckProviderFactory instance = new DebugAppCheckProviderFactory();
2929

30-
private String debugSecret;
31-
32-
private DebugAppCheckProviderFactory() {
33-
this.debugSecret = null;
34-
}
35-
36-
/**
37-
* This constructor is package-private in order to prevent debug secrets from being hard-coded in
38-
* application logic. This constructor is used by the firebase-appcheck-debug-testing SDK, to
39-
* inject debug secrets in integration tests.
40-
*/
41-
DebugAppCheckProviderFactory(String debugSecret) {
42-
this.debugSecret = debugSecret;
43-
}
30+
private DebugAppCheckProviderFactory() {}
4431

4532
/**
4633
* Gets an instance of this class for installation into a {@link
@@ -55,7 +42,8 @@ public static DebugAppCheckProviderFactory getInstance() {
5542

5643
@NonNull
5744
@Override
45+
@SuppressWarnings("FirebaseUseExplicitDependencies")
5846
public AppCheckProvider create(@NonNull FirebaseApp firebaseApp) {
59-
return new DebugAppCheckProvider(firebaseApp, debugSecret);
47+
return firebaseApp.get(DebugAppCheckProvider.class);
6048
}
6149
}

appcheck/firebase-appcheck-debug/src/main/java/com/google/firebase/appcheck/debug/FirebaseAppCheckDebugRegistrar.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@
1515
package com.google.firebase.appcheck.debug;
1616

1717
import com.google.android.gms.common.annotation.KeepForSdk;
18+
import com.google.firebase.FirebaseApp;
19+
import com.google.firebase.appcheck.debug.internal.DebugAppCheckProvider;
1820
import com.google.firebase.components.Component;
1921
import com.google.firebase.components.ComponentRegistrar;
22+
import com.google.firebase.components.Dependency;
2023
import com.google.firebase.platforminfo.LibraryVersionComponent;
2124
import java.util.Arrays;
2225
import java.util.List;
@@ -33,6 +36,17 @@ public class FirebaseAppCheckDebugRegistrar implements ComponentRegistrar {
3336

3437
@Override
3538
public List<Component<?>> getComponents() {
36-
return Arrays.asList(LibraryVersionComponent.create(LIBRARY_NAME, BuildConfig.VERSION_NAME));
39+
return Arrays.asList(
40+
Component.builder(DebugAppCheckProvider.class)
41+
.name(LIBRARY_NAME)
42+
.add(Dependency.required(FirebaseApp.class))
43+
.add(Dependency.optionalProvider(InternalDebugSecretProvider.class))
44+
.factory(
45+
(container) ->
46+
new DebugAppCheckProvider(
47+
container.get(FirebaseApp.class),
48+
container.getProvider(InternalDebugSecretProvider.class)))
49+
.build(),
50+
LibraryVersionComponent.create(LIBRARY_NAME, BuildConfig.VERSION_NAME));
3751
}
3852
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2021 Google LLC
1+
// Copyright 2022 Google LLC
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -14,19 +14,15 @@
1414

1515
package com.google.firebase.appcheck.debug;
1616

17-
import androidx.annotation.NonNull;
17+
import androidx.annotation.Nullable;
1818

1919
/**
20-
* Helper class used by {@link com.google.firebase.appcheck.debug.testing.DebugAppCheckTestHelper}
21-
* in order to access the package-private {@link DebugAppCheckProviderFactory} constructor that
22-
* takes in a debug secret.
20+
* An interface for obtaining a debug secret to be used with {@link
21+
* com.google.firebase.appcheck.debug.internal.DebugAppCheckProvider}.
2322
*
2423
* @hide
2524
*/
26-
public class DebugAppCheckProviderFactoryHelper {
27-
@NonNull
28-
public static DebugAppCheckProviderFactory createDebugAppCheckProviderFactory(
29-
@NonNull String debugSecret) {
30-
return new DebugAppCheckProviderFactory(debugSecret);
31-
}
25+
public interface InternalDebugSecretProvider {
26+
@Nullable
27+
String getDebugSecret();
3228
}

appcheck/firebase-appcheck-debug/src/main/java/com/google/firebase/appcheck/debug/internal/DebugAppCheckProvider.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,18 @@
1919
import android.annotation.SuppressLint;
2020
import android.util.Log;
2121
import androidx.annotation.NonNull;
22-
import androidx.annotation.Nullable;
2322
import androidx.annotation.VisibleForTesting;
2423
import com.google.android.gms.tasks.Task;
2524
import com.google.android.gms.tasks.TaskCompletionSource;
2625
import com.google.android.gms.tasks.Tasks;
2726
import com.google.firebase.FirebaseApp;
2827
import com.google.firebase.appcheck.AppCheckProvider;
2928
import com.google.firebase.appcheck.AppCheckToken;
29+
import com.google.firebase.appcheck.debug.InternalDebugSecretProvider;
3030
import com.google.firebase.appcheck.internal.DefaultAppCheckToken;
3131
import com.google.firebase.appcheck.internal.NetworkClient;
3232
import com.google.firebase.appcheck.internal.RetryManager;
33+
import com.google.firebase.inject.Provider;
3334
import java.util.UUID;
3435
import java.util.concurrent.ExecutorService;
3536
import java.util.concurrent.Executors;
@@ -46,11 +47,18 @@ public class DebugAppCheckProvider implements AppCheckProvider {
4647

4748
// TODO(b/258273630): Migrate to go/firebase-android-executors
4849
@SuppressLint("ThreadPoolCreation")
49-
public DebugAppCheckProvider(@NonNull FirebaseApp firebaseApp, @Nullable String debugSecret) {
50+
public DebugAppCheckProvider(
51+
@NonNull FirebaseApp firebaseApp,
52+
@NonNull Provider<InternalDebugSecretProvider> debugSecretProvider) {
5053
checkNotNull(firebaseApp);
5154
this.networkClient = new NetworkClient(firebaseApp);
5255
this.backgroundExecutor = Executors.newCachedThreadPool();
5356
this.retryManager = new RetryManager();
57+
58+
String debugSecret = null;
59+
if (debugSecretProvider.get() != null) {
60+
debugSecret = debugSecretProvider.get().getDebugSecret();
61+
}
5462
this.debugSecretTask =
5563
debugSecret == null
5664
? determineDebugSecret(firebaseApp, this.backgroundExecutor)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright 2022 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+
15+
package com.google.firebase.appcheck.debug;
16+
17+
import static com.google.common.truth.Truth.assertThat;
18+
19+
import com.google.firebase.FirebaseApp;
20+
import com.google.firebase.components.Component;
21+
import com.google.firebase.components.Dependency;
22+
import java.util.List;
23+
import org.junit.Test;
24+
import org.junit.runner.RunWith;
25+
import org.robolectric.RobolectricTestRunner;
26+
27+
/** Tests for {@link FirebaseAppCheckDebugRegistrar}. */
28+
@RunWith(RobolectricTestRunner.class)
29+
public class FirebaseAppCheckDebugRegistrarTest {
30+
@Test
31+
public void testGetComponents() {
32+
FirebaseAppCheckDebugRegistrar registrar = new FirebaseAppCheckDebugRegistrar();
33+
List<Component<?>> components = registrar.getComponents();
34+
assertThat(components).isNotEmpty();
35+
assertThat(components).hasSize(2);
36+
Component<?> appCheckDebugComponent = components.get(0);
37+
assertThat(appCheckDebugComponent.getDependencies())
38+
.containsExactly(
39+
Dependency.required(FirebaseApp.class),
40+
Dependency.optionalProvider(InternalDebugSecretProvider.class));
41+
assertThat(appCheckDebugComponent.isLazy()).isTrue();
42+
}
43+
}

0 commit comments

Comments
 (0)