Skip to content

Move tenant-aware integration tests to separate class #405

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

Merged
merged 3 commits into from
May 5, 2020
Merged
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
363 changes: 0 additions & 363 deletions src/test/java/com/google/firebase/auth/FirebaseAuthIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,6 @@
import org.junit.BeforeClass;
import org.junit.Test;

// TODO(micahstairs): Move tenant-aware tests into a seperate class, so that we only need to
// create and destroy the tenant once.
public class FirebaseAuthIT {

private static final String VERIFY_CUSTOM_TOKEN_URL =
Expand Down Expand Up @@ -322,209 +320,6 @@ public void onSuccess(ListUsersPage result) {
}
}

@Test
public void testTenantAwareUserLifecycle() throws Exception {
// Create tenant to use.
TenantManager tenantManager = auth.getTenantManager();
Tenant.CreateRequest tenantCreateRequest =
new Tenant.CreateRequest().setDisplayName("DisplayName");
final String tenantId = tenantManager.createTenant(tenantCreateRequest).getTenantId();

TenantAwareFirebaseAuth tenantAwareAuth = auth.getTenantManager().getAuthForTenant(tenantId);

// Create user
UserRecord userRecord = tenantAwareAuth.createUserAsync(new UserRecord.CreateRequest()).get();
String uid = userRecord.getUid();

// Get user
userRecord = tenantAwareAuth.getUserAsync(userRecord.getUid()).get();
assertEquals(uid, userRecord.getUid());
assertEquals(tenantId, userRecord.getTenantId());
assertNull(userRecord.getDisplayName());
assertNull(userRecord.getEmail());
assertNull(userRecord.getPhoneNumber());
assertNull(userRecord.getPhotoUrl());
assertFalse(userRecord.isEmailVerified());
assertFalse(userRecord.isDisabled());
assertTrue(userRecord.getUserMetadata().getCreationTimestamp() > 0);
assertEquals(0, userRecord.getUserMetadata().getLastSignInTimestamp());
assertEquals(0, userRecord.getProviderData().length);
assertTrue(userRecord.getCustomClaims().isEmpty());

// Update user
RandomUser randomUser = RandomUser.create();
String phone = randomPhoneNumber();
UserRecord.UpdateRequest request = userRecord.updateRequest()
.setDisplayName("Updated Name")
.setEmail(randomUser.email)
.setPhoneNumber(phone)
.setPhotoUrl("https://example.com/photo.png")
.setEmailVerified(true)
.setPassword("secret");
userRecord = tenantAwareAuth.updateUserAsync(request).get();
assertEquals(uid, userRecord.getUid());
assertEquals(tenantId, userRecord.getTenantId());
assertEquals("Updated Name", userRecord.getDisplayName());
assertEquals(randomUser.email, userRecord.getEmail());
assertEquals(phone, userRecord.getPhoneNumber());
assertEquals("https://example.com/photo.png", userRecord.getPhotoUrl());
assertTrue(userRecord.isEmailVerified());
assertFalse(userRecord.isDisabled());
assertEquals(2, userRecord.getProviderData().length);
assertTrue(userRecord.getCustomClaims().isEmpty());

// Get user by email
userRecord = tenantAwareAuth.getUserByEmailAsync(userRecord.getEmail()).get();
assertEquals(uid, userRecord.getUid());

// Disable user and remove properties
request = userRecord.updateRequest()
.setPhotoUrl(null)
.setDisplayName(null)
.setPhoneNumber(null)
.setDisabled(true);
userRecord = tenantAwareAuth.updateUserAsync(request).get();
assertEquals(uid, userRecord.getUid());
assertEquals(tenantId, userRecord.getTenantId());
assertNull(userRecord.getDisplayName());
assertEquals(randomUser.email, userRecord.getEmail());
assertNull(userRecord.getPhoneNumber());
assertNull(userRecord.getPhotoUrl());
assertTrue(userRecord.isEmailVerified());
assertTrue(userRecord.isDisabled());
assertEquals(1, userRecord.getProviderData().length);
assertTrue(userRecord.getCustomClaims().isEmpty());

// Delete user and tenant
tenantAwareAuth.deleteUserAsync(userRecord.getUid()).get();
assertUserDoesNotExist(tenantAwareAuth, userRecord.getUid());
tenantManager.deleteTenant(tenantId);
}

@Test
public void testTenantAwareListUsers() throws Exception {
// Create tenant to use.
TenantManager tenantManager = auth.getTenantManager();
Tenant.CreateRequest tenantCreateRequest =
new Tenant.CreateRequest().setDisplayName("DisplayName");
final String tenantId = tenantManager.createTenant(tenantCreateRequest).getTenantId();

TenantAwareFirebaseAuth tenantAwareAuth = tenantManager.getAuthForTenant(tenantId);
final List<String> uids = new ArrayList<>();

try {
for (int i = 0; i < 3; i++) {
UserRecord.CreateRequest createRequest =
new UserRecord.CreateRequest().setPassword("password");
uids.add(tenantAwareAuth.createUserAsync(createRequest).get().getUid());
}

// Test list by batches
final AtomicInteger collected = new AtomicInteger(0);
ListUsersPage page = tenantAwareAuth.listUsersAsync(null).get();
while (page != null) {
for (ExportedUserRecord user : page.getValues()) {
if (uids.contains(user.getUid())) {
collected.incrementAndGet();
assertNotNull("Missing passwordHash field. A common cause would be "
+ "forgetting to add the \"Firebase Authentication Admin\" permission. See "
+ "instructions in CONTRIBUTING.md", user.getPasswordHash());
assertNotNull(user.getPasswordSalt());
assertEquals(tenantId, user.getTenantId());
}
}
page = page.getNextPage();
}
assertEquals(uids.size(), collected.get());

// Test iterate all
collected.set(0);
page = tenantAwareAuth.listUsersAsync(null).get();
for (ExportedUserRecord user : page.iterateAll()) {
if (uids.contains(user.getUid())) {
collected.incrementAndGet();
assertNotNull(user.getPasswordHash());
assertNotNull(user.getPasswordSalt());
assertEquals(tenantId, user.getTenantId());
}
}
assertEquals(uids.size(), collected.get());

// Test iterate async
collected.set(0);
final Semaphore semaphore = new Semaphore(0);
final AtomicReference<Throwable> error = new AtomicReference<>();
ApiFuture<ListUsersPage> pageFuture = tenantAwareAuth.listUsersAsync(null);
ApiFutures.addCallback(pageFuture, new ApiFutureCallback<ListUsersPage>() {
@Override
public void onFailure(Throwable t) {
error.set(t);
semaphore.release();
}

@Override
public void onSuccess(ListUsersPage result) {
for (ExportedUserRecord user : result.iterateAll()) {
if (uids.contains(user.getUid())) {
collected.incrementAndGet();
assertNotNull(user.getPasswordHash());
assertNotNull(user.getPasswordSalt());
assertEquals(tenantId, user.getTenantId());
}
}
semaphore.release();
}
}, MoreExecutors.directExecutor());
semaphore.acquire();
assertEquals(uids.size(), collected.get());
assertNull(error.get());
} finally {
for (String uid : uids) {
tenantAwareAuth.deleteUserAsync(uid).get();
}
tenantManager.deleteTenant(tenantId);
}
}

@Test
public void testTenantAwareGetUserWithMultipleTenantIds() throws Exception {
// Create tenants to use.
TenantManager tenantManager = auth.getTenantManager();
Tenant.CreateRequest tenantCreateRequest1 =
new Tenant.CreateRequest().setDisplayName("DisplayName1");
String tenantId1 = tenantManager.createTenant(tenantCreateRequest1).getTenantId();
Tenant.CreateRequest tenantCreateRequest2 =
new Tenant.CreateRequest().setDisplayName("DisplayName2");
String tenantId2 = tenantManager.createTenant(tenantCreateRequest2).getTenantId();

// Create three users (one without a tenant ID, and two with different tenant IDs).
UserRecord.CreateRequest createRequest = new UserRecord.CreateRequest();
UserRecord nonTenantUserRecord = auth.createUser(createRequest);
TenantAwareFirebaseAuth tenantAwareAuth1 = auth.getTenantManager().getAuthForTenant(tenantId1);
UserRecord tenantUserRecord1 = tenantAwareAuth1.createUser(createRequest);
TenantAwareFirebaseAuth tenantAwareAuth2 = auth.getTenantManager().getAuthForTenant(tenantId2);
UserRecord tenantUserRecord2 = tenantAwareAuth2.createUser(createRequest);

// Make sure only non-tenant users can be fetched using the standard client.
assertNotNull(auth.getUser(nonTenantUserRecord.getUid()));
assertUserDoesNotExist(auth, tenantUserRecord1.getUid());
assertUserDoesNotExist(auth, tenantUserRecord2.getUid());

// Make sure tenant-aware client cannot fetch users outside that tenant.
assertUserDoesNotExist(tenantAwareAuth1, nonTenantUserRecord.getUid());
assertUserDoesNotExist(tenantAwareAuth1, tenantUserRecord2.getUid());
assertUserDoesNotExist(tenantAwareAuth2, nonTenantUserRecord.getUid());
assertUserDoesNotExist(tenantAwareAuth2, tenantUserRecord1.getUid());

// Make sure tenant-aware client can fetch users under that tenant.
assertNotNull(tenantAwareAuth1.getUser(tenantUserRecord1.getUid()));
assertNotNull(tenantAwareAuth2.getUser(tenantUserRecord2.getUid()));

// Delete tenants.
tenantManager.deleteTenant(tenantId1);
tenantManager.deleteTenant(tenantId2);
}

@Test
public void testTenantLifecycle() throws Exception {
TenantManager tenantManager = auth.getTenantManager();
Expand Down Expand Up @@ -708,58 +503,6 @@ public void testCustomTokenWithIAM() throws Exception {
}
}

@Test
public void testTenantAwareCustomToken() throws Exception {
// Create tenant to use.
TenantManager tenantManager = auth.getTenantManager();
Tenant.CreateRequest tenantCreateRequest =
new Tenant.CreateRequest().setDisplayName("DisplayName");
String tenantId = tenantManager.createTenant(tenantCreateRequest).getTenantId();

try {
// Create and decode a token with a tenant-aware client.
TenantAwareFirebaseAuth tenantAwareAuth = auth.getTenantManager().getAuthForTenant(tenantId);
String customToken = tenantAwareAuth.createCustomTokenAsync("user1").get();
String idToken = signInWithCustomToken(customToken, tenantId);
FirebaseToken decoded = tenantAwareAuth.verifyIdTokenAsync(idToken).get();
assertEquals("user1", decoded.getUid());
assertEquals(tenantId, decoded.getTenantId());
} finally {
// Delete tenant.
tenantManager.deleteTenantAsync(tenantId).get();
}
}

@Test
public void testVerifyTokenWithWrongTenantAwareClient() throws Exception {
// Create tenant to use.
TenantManager tenantManager = auth.getTenantManager();
Tenant.CreateRequest tenantCreateRequest =
new Tenant.CreateRequest().setDisplayName("DisplayName");
String tenantId = tenantManager.createTenant(tenantCreateRequest).getTenantId();

// Create tenant-aware clients.
TenantAwareFirebaseAuth tenantAwareAuth1 = auth.getTenantManager().getAuthForTenant(tenantId);
TenantAwareFirebaseAuth tenantAwareAuth2 = auth.getTenantManager().getAuthForTenant("OTHER");

try {
// Create a token with one client and decode with the other.
String customToken = tenantAwareAuth1.createCustomTokenAsync("user").get();
String idToken = signInWithCustomToken(customToken, tenantId);
try {
tenantAwareAuth2.verifyIdTokenAsync(idToken).get();
fail("No error thrown for verifying a token with the wrong tenant-aware client");
} catch (ExecutionException e) {
assertTrue(e.getCause() instanceof FirebaseAuthException);
assertEquals(FirebaseUserManager.TENANT_ID_MISMATCH_ERROR,
((FirebaseAuthException) e.getCause()).getErrorCode());
}
} finally {
// Delete tenant.
tenantManager.deleteTenantAsync(tenantId).get();
}
}

@Test
public void testVerifyIdToken() throws Exception {
String customToken = auth.createCustomTokenAsync("user2").get();
Expand Down Expand Up @@ -1009,65 +752,6 @@ public void testOidcProviderConfigLifecycle() throws Exception {
assertOidcProviderConfigDoesNotExist(auth, providerId);
}

@Test
public void testTenantAwareOidcProviderConfigLifecycle() throws Exception {
// Create tenant to use
TenantManager tenantManager = auth.getTenantManager();
Tenant.CreateRequest tenantCreateRequest =
new Tenant.CreateRequest().setDisplayName("DisplayName");
String tenantId = tenantManager.createTenant(tenantCreateRequest).getTenantId();

try {
// Create config provider
TenantAwareFirebaseAuth tenantAwareAuth = auth.getTenantManager().getAuthForTenant(tenantId);
String providerId = "oidc.provider-id";
OidcProviderConfig.CreateRequest createRequest =
new OidcProviderConfig.CreateRequest()
.setProviderId(providerId)
.setDisplayName("DisplayName")
.setEnabled(true)
.setClientId("ClientId")
.setIssuer("https://oidc.com/issuer");
OidcProviderConfig config =
tenantAwareAuth.createOidcProviderConfigAsync(createRequest).get();
assertEquals(providerId, config.getProviderId());
assertEquals("DisplayName", config.getDisplayName());
assertEquals("ClientId", config.getClientId());
assertEquals("https://oidc.com/issuer", config.getIssuer());

try {
// Get config provider
config = tenantAwareAuth.getOidcProviderConfigAsync(providerId).get();
assertEquals(providerId, config.getProviderId());
assertEquals("DisplayName", config.getDisplayName());
assertEquals("ClientId", config.getClientId());
assertEquals("https://oidc.com/issuer", config.getIssuer());

// Update config provider
OidcProviderConfig.UpdateRequest updateRequest =
new OidcProviderConfig.UpdateRequest(providerId)
.setDisplayName("NewDisplayName")
.setEnabled(false)
.setClientId("NewClientId")
.setIssuer("https://oidc.com/new-issuer");
config = tenantAwareAuth.updateOidcProviderConfigAsync(updateRequest).get();
assertEquals(providerId, config.getProviderId());
assertEquals("NewDisplayName", config.getDisplayName());
assertFalse(config.isEnabled());
assertEquals("NewClientId", config.getClientId());
assertEquals("https://oidc.com/new-issuer", config.getIssuer());
} finally {
// Delete config provider
tenantAwareAuth.deleteProviderConfigAsync(providerId).get();
}

assertOidcProviderConfigDoesNotExist(tenantAwareAuth, providerId);
} finally {
// Delete tenant.
tenantManager.deleteTenantAsync(tenantId).get();
}
}

@Test
public void testListOidcProviderConfigs() throws Exception {
final List<String> providerIds = new ArrayList<>();
Expand Down Expand Up @@ -1144,53 +828,6 @@ public void onSuccess(ListProviderConfigsPage<OidcProviderConfig> result) {
}
}

@Test
public void testTenantAwareListOidcProviderConfigs() throws Exception {
// Create tenant to use
TenantManager tenantManager = auth.getTenantManager();
Tenant.CreateRequest tenantCreateRequest =
new Tenant.CreateRequest().setDisplayName("DisplayName");
String tenantId = tenantManager.createTenant(tenantCreateRequest).getTenantId();
TenantAwareFirebaseAuth tenantAwareAuth = auth.getTenantManager().getAuthForTenant(tenantId);

try {
final List<String> providerIds = new ArrayList<>();
try {

// Create provider configs
for (int i = 0; i < 3; i++) {
String providerId = "oidc.provider-id" + i;
providerIds.add(providerId);
OidcProviderConfig.CreateRequest createRequest = new OidcProviderConfig.CreateRequest()
.setProviderId(providerId)
.setClientId("CLIENT_ID")
.setIssuer("https://oidc.com/issuer");
tenantAwareAuth.createOidcProviderConfig(createRequest);
}

// List provider configs
final AtomicInteger collected = new AtomicInteger(0);
ListProviderConfigsPage<OidcProviderConfig> page =
tenantAwareAuth.listOidcProviderConfigsAsync(null).get();
for (OidcProviderConfig providerConfig : page.iterateAll()) {
if (checkProviderConfig(providerIds, providerConfig)) {
collected.incrementAndGet();
}
}
assertEquals(providerIds.size(), collected.get());

} finally {
// Delete provider configs
for (String providerId : providerIds) {
tenantAwareAuth.deleteProviderConfigAsync(providerId).get();
}
}
} finally {
// Delete tenant
tenantManager.deleteTenantAsync(tenantId).get();
}
}

private Map<String, String> parseLinkParameters(String link) throws Exception {
Map<String, String> result = new HashMap<>();
int queryBegin = link.indexOf('?');
Expand Down
Loading