-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(app-check): add custom factory/provider; supports all providers
On Android this allows use of Play Integrity provider. On iOS this allows use of AppAttest provider. On all platforms, things should be dynamically reconfigurable if you use our custom provider, and it should be easier to specify debug tokens for CI etc
- Loading branch information
Showing
17 changed files
with
795 additions
and
99 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
85 changes: 85 additions & 0 deletions
85
...oid/src/main/java/io/invertase/firebase/appcheck/ReactNativeFirebaseAppCheckProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package io.invertase.firebase.appcheck; | ||
|
||
/* | ||
* Copyright (c) 2023-present Invertase Limited & Contributors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this library 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 android.util.Log; | ||
import com.google.android.gms.tasks.Task; | ||
import com.google.firebase.FirebaseApp; | ||
import com.google.firebase.appcheck.AppCheckProvider; | ||
import com.google.firebase.appcheck.AppCheckProviderFactory; | ||
import com.google.firebase.appcheck.AppCheckToken; | ||
import com.google.firebase.appcheck.debug.DebugAppCheckProviderFactory; | ||
import com.google.firebase.appcheck.playintegrity.PlayIntegrityAppCheckProviderFactory; | ||
import com.google.firebase.appcheck.safetynet.SafetyNetAppCheckProviderFactory; | ||
import java.lang.reflect.Constructor; | ||
|
||
// Facade for all possible provider factory delegates, | ||
// configurable dynamically instead of at startup | ||
public class ReactNativeFirebaseAppCheckProvider implements AppCheckProvider { | ||
private static final String LOGTAG = "RNFBAppCheck"; | ||
|
||
AppCheckProvider delegateProvider; | ||
|
||
@Override | ||
public Task<AppCheckToken> getToken() { | ||
Log.d(LOGTAG, "Provider::getToken - delegating to native provider"); | ||
return delegateProvider.getToken(); | ||
} | ||
|
||
public void configure(String appName, String providerName, String debugToken) { | ||
Log.d( | ||
LOGTAG, | ||
"Provider::configure with appName/providerName/debugToken: " | ||
+ appName | ||
+ "/" | ||
+ providerName | ||
+ "/" | ||
+ (debugToken != null ? "(not shown)" : "null")); | ||
|
||
try { | ||
FirebaseApp app = FirebaseApp.getInstance(appName); | ||
|
||
if ("debug".equals(providerName)) { | ||
|
||
// the debug configuration may have a token, or may not | ||
if (debugToken != null) { | ||
// Create a debug provider using hidden factory constructor and our debug token | ||
Class<DebugAppCheckProviderFactory> debugACFactoryClass = | ||
DebugAppCheckProviderFactory.class; | ||
Class<?>[] argType = {String.class}; | ||
Constructor c = debugACFactoryClass.getDeclaredConstructor(argType); | ||
Object[] cArgs = {debugToken}; | ||
delegateProvider = ((AppCheckProviderFactory) c.newInstance(cArgs)).create(app); | ||
} else { | ||
delegateProvider = DebugAppCheckProviderFactory.getInstance().create(app); | ||
} | ||
} | ||
|
||
if ("safetyNet".equals(providerName)) { | ||
delegateProvider = SafetyNetAppCheckProviderFactory.getInstance().create(app); | ||
} | ||
|
||
if ("playIntegrity".equals(providerName)) { | ||
delegateProvider = PlayIntegrityAppCheckProviderFactory.getInstance().create(app); | ||
} | ||
} catch (Exception e) { | ||
// This will bubble up and result in a rejected promise with the underlying message | ||
throw new RuntimeException(e.getMessage()); | ||
} | ||
} | ||
} |
66 changes: 66 additions & 0 deletions
66
.../main/java/io/invertase/firebase/appcheck/ReactNativeFirebaseAppCheckProviderFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package io.invertase.firebase.appcheck; | ||
|
||
/* | ||
* Copyright (c) 2023-present Invertase Limited & Contributors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this library 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 android.util.Log; | ||
import com.google.firebase.FirebaseApp; | ||
import com.google.firebase.appcheck.AppCheckProvider; | ||
import com.google.firebase.appcheck.AppCheckProviderFactory; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
public class ReactNativeFirebaseAppCheckProviderFactory implements AppCheckProviderFactory { | ||
private static final String LOGTAG = "RNFBAppCheck"; | ||
|
||
// This object has one job - create + maintain control over one provider per app | ||
public Map<String, ReactNativeFirebaseAppCheckProvider> providers = new HashMap(); | ||
|
||
// Our provider will serve as a facade to all the supported native providers, | ||
// we will just pass through configuration calls to it | ||
public void configure(String appName, String providerName, String debugToken) { | ||
Log.d( | ||
LOGTAG, | ||
"ProviderFactory::configure - appName/providerName/debugToken: " | ||
+ appName | ||
+ "/" | ||
+ providerName | ||
+ (debugToken != null ? "/(not shown)" : "/null")); | ||
|
||
ReactNativeFirebaseAppCheckProvider provider = null; | ||
|
||
// Look up the correct provider for the given appName, create it if not created | ||
provider = providers.get(appName); | ||
if (provider == null) { | ||
provider = new ReactNativeFirebaseAppCheckProvider(); | ||
providers.put(appName, provider); | ||
} | ||
provider.configure(appName, providerName, debugToken); | ||
} | ||
|
||
public AppCheckProvider create(FirebaseApp firebaseApp) { | ||
String appName = firebaseApp.getName(); | ||
Log.d(LOGTAG, "ProviderFactory::create - fetching provider for app " + appName); | ||
ReactNativeFirebaseAppCheckProvider provider = providers.get(appName); | ||
if (provider == null) { | ||
Log.d(LOGTAG, "ProviderFactory::create - provider not configured for this app."); | ||
throw new RuntimeException( | ||
"ReactNativeFirebaseAppCheckProvider not configured for app " + appName); | ||
} | ||
return provider; | ||
} | ||
} |
Oops, something went wrong.