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

Main #6645

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open

Main #6645

Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions firebase-installations/firebase-installations.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ dependencies {

implementation 'androidx.multidex:multidex:2.0.1'
implementation 'com.google.android.gms:play-services-tasks:17.0.0'
implementation 'com.google.re2j:re2j:1.0'


compileOnly "com.google.auto.value:auto-value-annotations:1.6.5"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,18 +143,19 @@ public Thread newThread(Runnable r) {
* or empty.
*/
private void preConditionChecks() {
Preconditions.checkNotEmpty(
getApplicationId(),
"Please set your Application ID. A valid Firebase App ID is required to communicate "
+ "with Firebase server APIs: It identifies your application with Firebase.");
Preconditions.checkNotEmpty(
getProjectIdentifier(),
"Please set your project ID. A valid Firebase project ID is required to communicate "
+ "with Firebase server APIs: It identifies your project with Google.");
Preconditions.checkNotEmpty(
getApiKey(),
"Please set a valid API key. A Firebase API key is required to communicate with "
+ "Firebase server APIs: It authenticates your project with Google.");
Preconditions.checkNotEmpty(getApplicationId());
Preconditions.checkNotEmpty(getProjectIdentifier());
Preconditions.checkNotEmpty(getApiKey());
Preconditions.checkArgument(
Utils.isValidAppIdFormat(getApplicationId()),
"Please set your Application ID. A valid Firebase App ID is required to communicate "
+ "with Firebase server APIs: It identifies your application with Firebase."
+ "Please refer to https://firebase.google.com/support/privacy/init-options.");
Preconditions.checkArgument(
Utils.isValidApiKeyFormat(getApiKey()),
"Please set a valid API key. A Firebase API key is required to communicate with "
+ "Firebase server APIs: It authenticates your project with Google."
+ "Please refer to https://firebase.google.com/support/privacy/init-options.");
}

/** Returns the Project Id or Project Number for the Firebase Project. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,21 @@
package com.google.firebase.installations;

import android.text.TextUtils;

import androidx.annotation.NonNull;

import com.google.firebase.installations.local.PersistedInstallationEntry;
import java.util.concurrent.TimeUnit;

import com.google.re2j.Pattern;

/** Util methods used for {@link FirebaseInstallations} */
class Utils {
public static final long AUTH_TOKEN_EXPIRATION_BUFFER_IN_SECS = TimeUnit.HOURS.toSeconds(1);

private static final String APP_ID_IDENTIFICATION_SUBSTRING = ":";
private static final Pattern API_KEY_FORMAT = Pattern.compile("\\AA[\\w-]{38}\\z");

/**
* Checks if the FIS Auth token is expired or going to expire in next 1 hour {@link
* #AUTH_TOKEN_EXPIRATION_BUFFER_IN_SECS}.
Expand All @@ -41,4 +49,12 @@ public boolean isAuthTokenExpired(PersistedInstallationEntry entry) {
public long currentTimeInSecs() {
return TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
}

static boolean isValidAppIdFormat(@NonNull String appId) {
return appId.contains(APP_ID_IDENTIFICATION_SUBSTRING);
}

static boolean isValidApiKeyFormat(@NonNull String apiKey) {
return API_KEY_FORMAT.matcher(apiKey).matches();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import static com.google.common.truth.Truth.assertWithMessage;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
Expand Down Expand Up @@ -82,7 +83,7 @@ public class FirebaseInstallationsTest {
public static final String TEST_AUTH_TOKEN_3 = "fis.auth.token3";
public static final String TEST_AUTH_TOKEN_4 = "fis.auth.token4";

public static final String TEST_API_KEY = "apiKey";
public static final String TEST_API_KEY = "AIzaSyabcdefghijklmnopqrstuvwxyz1234567";

public static final String TEST_REFRESH_TOKEN = "1:test-refresh-token";

Expand Down Expand Up @@ -965,4 +966,43 @@ public void testDelete_networkError() throws Exception {
entry.isRegistered());
}
}

@Test
public void testAppIdCheck() {
// valid appid
assertTrue(Utils.isValidAppIdFormat("1:123456789:android:abcdef"));
assertTrue(Utils.isValidAppIdFormat("1:515438998704:android:e78ec19738058349"));
assertTrue(Utils.isValidAppIdFormat("1:208472424340:android:a243f98a00873753"));
assertTrue(Utils.isValidAppIdFormat("1:755541669657:ios:4d6d5a5ce71e9d30"));
assertTrue(Utils.isValidAppIdFormat("1:1086610230652:ios:852c7f6ee799ff89"));
assertTrue(Utils.isValidAppIdFormat("1:35006771263:web:32b6f4a5b95acd2c"));
// invalid appid
assertFalse(Utils.isValidAppIdFormat("abc.abc.abc"));
assertFalse(
Utils.isValidAppIdFormat(
"com.google.firebase.samples.messaging.advanced")); // using pakage name as App ID
}

@Test
public void testApiKeyCheck() {
// valid ApiKey
assertTrue(Utils.isValidApiKeyFormat("AIzaSyabcdefghijklmnopqrstuvwxyz1234567"));
assertTrue(Utils.isValidApiKeyFormat("AIzaSyA4UrcGxgwQFTfaI3no3t7Lt1sjmdnP5sQ"));
assertTrue(Utils.isValidApiKeyFormat("AIzaSyA5_iVawFQ8ABuTZNUdcwERLJv_a_p4wtM"));
assertTrue(Utils.isValidApiKeyFormat("AIzaSyANUvH9H9BsUccjsu2pCmEkOPjjaXeDQgY"));
assertTrue(Utils.isValidApiKeyFormat("AIzaSyASWm6HmTMdYWpgMnjRBjxcQ9CKctWmLd4"));
assertTrue(Utils.isValidApiKeyFormat("AIzaSyAdOS2zB6NCsk1pCdZ4-P6GBdi_UUPwX7c"));
assertTrue(Utils.isValidApiKeyFormat("AIzaSyAnLA7NfeLquW1tJFpx_eQCxoX-oo6YyIs"));
// invalid ApiKey
assertFalse(
Utils.isValidApiKeyFormat("BIzaSyabcdefghijklmnopqrstuvwxyz1234567")); // wrong prefix
assertFalse(Utils.isValidApiKeyFormat("AIzaSyabcdefghijklmnopqrstuvwxyz")); // wrong length
assertFalse(Utils.isValidApiKeyFormat("AIzaSyabcdefghijklmno:qrstuvwxyzabcdefg")); // wrong char
assertFalse(Utils.isValidApiKeyFormat("AIzaSyabcdefghijklmno qrstuvwxyzabcdefg")); // wrong char
assertFalse(
Utils.isValidApiKeyFormat(
"AAAAdpB7anM:APA91bFFK03DIT8y3l5uymwbKcUDJdYqTRSP9Qcxg8SU5kKPalEpObdx0C0xv8gQttdWlL"
+ "W4hLvvHA0JoDKA6Lrvbi-edUjFCPY_WJkuvHxFwGWXjnj4yI4sPQ27mXuSVIyAbgX4aTK0QY"
+ "pIKq2j1NBi7ZU75gunQg")); // using FCM server key as API key.
}
}