Skip to content

Commit 9f15838

Browse files
fix(auth): Set emulator credentials when using the Auth emulator (#734)
If `FIREBASE_AUTH_EMULATOR_HOST` env var is set the SDK shouldn't connect to Auth servers for OAuth2 handshake. This PR sets the emulator credentials when emulator mode is set.
1 parent 51a0f27 commit 9f15838

File tree

5 files changed

+85
-26
lines changed

5 files changed

+85
-26
lines changed

Diff for: src/main/java/com/google/firebase/ImplFirebaseTrampolines.java

+5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import com.google.api.core.ApiFutures;
2323
import com.google.auth.oauth2.GoogleCredentials;
2424
import com.google.cloud.firestore.FirestoreOptions;
25+
import com.google.firebase.auth.internal.Utils;
26+
import com.google.firebase.internal.EmulatorCredentials;
2527
import com.google.firebase.internal.FirebaseService;
2628
import com.google.firebase.internal.NonNull;
2729

@@ -41,6 +43,9 @@ public final class ImplFirebaseTrampolines {
4143
private ImplFirebaseTrampolines() {}
4244

4345
public static GoogleCredentials getCredentials(@NonNull FirebaseApp app) {
46+
if (Utils.isEmulatorMode()) {
47+
return new EmulatorCredentials();
48+
}
4449
return app.getOptions().getCredentials();
4550
}
4651

Diff for: src/main/java/com/google/firebase/database/FirebaseDatabase.java

+1-22
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import com.google.firebase.database.utilities.ParsedUrl;
3636
import com.google.firebase.database.utilities.Utilities;
3737
import com.google.firebase.database.utilities.Validation;
38+
import com.google.firebase.internal.EmulatorCredentials;
3839
import com.google.firebase.internal.FirebaseService;
3940

4041
import com.google.firebase.internal.SdkUtils;
@@ -406,26 +407,4 @@ public void destroy() {
406407
instance.destroy();
407408
}
408409
}
409-
410-
private static class EmulatorCredentials extends GoogleCredentials {
411-
412-
EmulatorCredentials() {
413-
super(newToken());
414-
}
415-
416-
private static AccessToken newToken() {
417-
return new AccessToken("owner",
418-
new Date(System.currentTimeMillis() + TimeUnit.HOURS.toMillis(1)));
419-
}
420-
421-
@Override
422-
public AccessToken refreshAccessToken() {
423-
return newToken();
424-
}
425-
426-
@Override
427-
public Map<String, List<String>> getRequestMetadata() throws IOException {
428-
return ImmutableMap.of();
429-
}
430-
}
431410
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright 2022 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.firebase.internal;
18+
19+
import com.google.auth.oauth2.AccessToken;
20+
import com.google.auth.oauth2.GoogleCredentials;
21+
import com.google.common.collect.ImmutableMap;
22+
23+
import java.io.IOException;
24+
import java.util.Date;
25+
import java.util.List;
26+
import java.util.Map;
27+
import java.util.concurrent.TimeUnit;
28+
29+
/**
30+
* A Mock Credentials implementation that can be used with the Emulator Suite
31+
*/
32+
public final class EmulatorCredentials extends GoogleCredentials {
33+
34+
public EmulatorCredentials() {
35+
super(newToken());
36+
}
37+
38+
private static AccessToken newToken() {
39+
return new AccessToken("owner",
40+
new Date(System.currentTimeMillis() + TimeUnit.HOURS.toMillis(1)));
41+
}
42+
43+
@Override
44+
public AccessToken refreshAccessToken() {
45+
return newToken();
46+
}
47+
48+
@Override
49+
public Map<String, List<String>> getRequestMetadata() throws IOException {
50+
return ImmutableMap.of();
51+
}
52+
}

Diff for: src/test/java/com/google/firebase/auth/FirebaseUserManagerTest.java

+13-2
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,13 @@ public class FirebaseUserManagerTest {
7171

7272
private static final String TEST_TOKEN = "token";
7373

74+
private static final String TEST_EMULATOR_TOKEN = "owner";
75+
7476
private static final GoogleCredentials credentials = new MockGoogleCredentials(TEST_TOKEN);
7577

78+
private static final GoogleCredentials emulator_credentials =
79+
new MockGoogleCredentials(TEST_EMULATOR_TOKEN);
80+
7681
private static final ActionCodeSettings ACTION_CODE_SETTINGS = ActionCodeSettings.builder()
7782
.setUrl("https://example.dynamic.link")
7883
.setHandleCodeInApp(true)
@@ -2916,7 +2921,7 @@ private static void initializeAppWithResponses(String... responses) {
29162921
}
29172922
MockHttpTransport transport = new MultiRequestMockHttpTransport(mocks);
29182923
FirebaseApp.initializeApp(FirebaseOptions.builder()
2919-
.setCredentials(credentials)
2924+
.setCredentials(isEmulatorMode() ? emulator_credentials : credentials)
29202925
.setHttpTransport(transport)
29212926
.setProjectId("test-project-id")
29222927
.build());
@@ -3014,7 +3019,7 @@ private static void checkSamlProviderConfig(SamlProviderConfig config, String pr
30143019

30153020
private static void checkRequestHeaders(TestResponseInterceptor interceptor) {
30163021
HttpHeaders headers = interceptor.getResponse().getRequest().getHeaders();
3017-
String auth = "Bearer " + TEST_TOKEN;
3022+
String auth = "Bearer " + (isEmulatorMode() ? TEST_EMULATOR_TOKEN : TEST_TOKEN);
30183023
assertEquals(auth, headers.getFirstHeaderStringValue("Authorization"));
30193024

30203025
String clientVersion = "Java/Admin/" + SdkUtils.getVersion();
@@ -3027,6 +3032,12 @@ private static void checkUrl(TestResponseInterceptor interceptor, String method,
30273032
assertEquals(url, request.getUrl().toString().split("\\?")[0]);
30283033
}
30293034

3035+
private static boolean isEmulatorMode() {
3036+
return !Strings.isNullOrEmpty(
3037+
FirebaseProcessEnvironment.getenv("FIREBASE_AUTH_EMULATOR_HOST")
3038+
);
3039+
}
3040+
30303041
private interface UserManagerOp {
30313042
void call(FirebaseAuth auth) throws Exception;
30323043
}

Diff for: src/test/java/com/google/firebase/auth/multitenancy/FirebaseTenantClientTest.java

+14-2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import com.google.api.client.testing.http.MockHttpTransport;
3434
import com.google.api.client.testing.http.MockLowLevelHttpResponse;
3535
import com.google.auth.oauth2.GoogleCredentials;
36+
import com.google.common.base.Strings;
3637
import com.google.common.collect.ImmutableList;
3738
import com.google.common.collect.Iterables;
3839
import com.google.firebase.ErrorCode;
@@ -63,8 +64,13 @@ public class FirebaseTenantClientTest {
6364

6465
private static final String TEST_TOKEN = "token";
6566

67+
private static final String TEST_EMULATOR_TOKEN = "owner";
68+
6669
private static final GoogleCredentials credentials = new MockGoogleCredentials(TEST_TOKEN);
6770

71+
private static final GoogleCredentials emulator_credentials =
72+
new MockGoogleCredentials(TEST_EMULATOR_TOKEN);
73+
6874
private static final String PROJECT_BASE_URL =
6975
"https://identitytoolkit.googleapis.com/v2/projects/test-project-id";
7076

@@ -342,7 +348,7 @@ private static void checkTenant(Tenant tenant, String tenantId) {
342348

343349
private static void checkRequestHeaders(TestResponseInterceptor interceptor) {
344350
HttpHeaders headers = interceptor.getResponse().getRequest().getHeaders();
345-
String auth = "Bearer " + TEST_TOKEN;
351+
String auth = "Bearer " + (isEmulatorMode() ? TEST_EMULATOR_TOKEN : TEST_TOKEN);
346352
assertEquals(auth, headers.getFirstHeaderStringValue("Authorization"));
347353

348354
String clientVersion = "Java/Admin/" + SdkUtils.getVersion();
@@ -362,7 +368,7 @@ private static TestResponseInterceptor initializeAppForTenantManagement(String..
362368
}
363369
MockHttpTransport transport = new MultiRequestMockHttpTransport(mocks);
364370
FirebaseApp.initializeApp(FirebaseOptions.builder()
365-
.setCredentials(credentials)
371+
.setCredentials(isEmulatorMode() ? emulator_credentials : credentials)
366372
.setHttpTransport(transport)
367373
.setProjectId("test-project-id")
368374
.build());
@@ -408,4 +414,10 @@ private static GenericJson parseRequestContent(TestResponseInterceptor intercept
408414
interceptor.getResponse().getRequest().getContent().writeTo(out);
409415
return JSON_FACTORY.fromString(new String(out.toByteArray()), GenericJson.class);
410416
}
417+
418+
private static boolean isEmulatorMode() {
419+
return !Strings.isNullOrEmpty(
420+
FirebaseProcessEnvironment.getenv("FIREBASE_AUTH_EMULATOR_HOST")
421+
);
422+
}
411423
}

0 commit comments

Comments
 (0)