/* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file 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. */ package keywhiz.service.resources.admin; import com.google.common.collect.ImmutableMap; import java.io.IOException; import java.util.Base64; import java.util.List; import keywhiz.IntegrationTestRule; import keywhiz.TestClients; import keywhiz.api.SecretDetailResponse; import keywhiz.api.model.SanitizedSecret; import keywhiz.client.KeywhizClient; import keywhiz.commands.DbSeedCommand; import org.junit.Before; import org.junit.ClassRule; import org.junit.Test; import org.junit.rules.RuleChain; import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown; public class SecretsResourceIntegrationTest { KeywhizClient keywhizClient; @ClassRule public static final RuleChain chain = IntegrationTestRule.rule(); @Before public void setUp() { keywhizClient = TestClients.keywhizClient(); } @Test public void listsSecrets() throws IOException { keywhizClient.login(DbSeedCommand.defaultUser, DbSeedCommand.defaultPassword.toCharArray()); assertThat(keywhizClient.allSecrets().stream().map(SanitizedSecret::name).toArray()) .contains("Nobody_PgPass", "Hacking_Password", "General_Password", "NonexistentOwner_Pass", "Versioned_Password"); } @Test public void listingExcludesSecretContent() throws IOException { // This is checking that the response body doesn't contain the secret information anywhere, not // just that the resulting Java objects parsed by gson don't. keywhizClient.login(DbSeedCommand.defaultUser, DbSeedCommand.defaultPassword.toCharArray()); List<SanitizedSecret> sanitizedSecrets = keywhizClient.allSecrets(); assertThat(sanitizedSecrets.toString()) .doesNotContain("MTMzNw==") .doesNotContain(new String(Base64.getDecoder().decode("MTMzNw=="), UTF_8)); } @Test(expected = KeywhizClient.UnauthorizedException.class) public void adminRejectsNonKeywhizUsers() throws IOException { keywhizClient.login("username", "password".toCharArray()); keywhizClient.allSecrets(); } @Test(expected = KeywhizClient.UnauthorizedException.class) public void adminRejectsWithoutCookie() throws IOException { keywhizClient.allSecrets(); } @Test public void createsSecret() throws IOException { keywhizClient.login(DbSeedCommand.defaultUser, DbSeedCommand.defaultPassword.toCharArray()); SecretDetailResponse secretDetails = keywhizClient.createSecret("newSecret", "", "content".getBytes(UTF_8), ImmutableMap.of(), 0); assertThat(secretDetails.name).isEqualTo("newSecret"); assertThat(keywhizClient.allSecrets().stream().map(SanitizedSecret::name).toArray()) .contains("newSecret"); } @Test(expected = KeywhizClient.ConflictException.class) public void rejectsCreatingDuplicateSecretWithoutVersion() throws IOException { keywhizClient.login(DbSeedCommand.defaultUser, DbSeedCommand.defaultPassword.toCharArray()); keywhizClient.createSecret("passage", "v1", "content".getBytes(UTF_8), ImmutableMap.of(), 0); keywhizClient.createSecret("passage", "v2", "content".getBytes(UTF_8), ImmutableMap.of(), 0); } @Test public void deletesSecret() throws IOException { keywhizClient.login(DbSeedCommand.defaultUser, DbSeedCommand.defaultPassword.toCharArray()); keywhizClient.deleteSecretWithId(739); try { keywhizClient.secretDetailsForId(739); failBecauseExceptionWasNotThrown(KeywhizClient.NotFoundException.class); } catch (KeywhizClient.NotFoundException e) { // Secret was successfully deleted } } @Test public void listsSpecificSecret() throws IOException { keywhizClient.login(DbSeedCommand.defaultUser, DbSeedCommand.defaultPassword.toCharArray()); SecretDetailResponse response = keywhizClient.secretDetailsForId(737); assertThat(response.name).isEqualTo("Nobody_PgPass"); } @Test public void listSpecificNonVersionedSecretByName() throws IOException { keywhizClient.login(DbSeedCommand.defaultUser, DbSeedCommand.defaultPassword.toCharArray()); SanitizedSecret sanitizedSecret = keywhizClient.getSanitizedSecretByName("Nobody_PgPass"); assertThat(sanitizedSecret.id()).isEqualTo(737); } @Test(expected = KeywhizClient.NotFoundException.class) public void notFoundOnBadSecretId() throws IOException { keywhizClient.login(DbSeedCommand.defaultUser, DbSeedCommand.defaultPassword.toCharArray()); keywhizClient.secretDetailsForId(283092384); } @Test(expected = KeywhizClient.NotFoundException.class) public void notFoundOnBadSecretName() throws IOException { keywhizClient.login(DbSeedCommand.defaultUser, DbSeedCommand.defaultPassword.toCharArray()); keywhizClient.getSanitizedSecretByName("non-existent-secret"); } @Test public void doesNotRetrieveDeletedSecretVersions() throws IOException { keywhizClient.login(DbSeedCommand.defaultUser, DbSeedCommand.defaultPassword.toCharArray()); String name = "versionSecret"; // Create a secret SecretDetailResponse secretDetails = keywhizClient.createSecret(name, "first secret", "content".getBytes(UTF_8), ImmutableMap.of(), 0); assertThat(secretDetails.name).isEqualTo(name); assertThat(keywhizClient.allSecrets().stream().map(SanitizedSecret::name).toArray()) .contains(name); // Retrieve versions for the first secret List<SanitizedSecret> versions = keywhizClient.listSecretVersions(name, 0, 10); assertThat(versions.size()).isEqualTo(1); assertThat(versions.get(0).description()).isEqualTo("first secret"); // Delete this first secret keywhizClient.deleteSecretWithId(secretDetails.id); assertThat(keywhizClient.allSecrets().stream().map(SanitizedSecret::name).toArray()) .doesNotContain(name); // Create a second secret with the same name secretDetails = keywhizClient.createSecret(name, "second secret", "content".getBytes(UTF_8), ImmutableMap.of(), 0); assertThat(secretDetails.name).isEqualTo(name); // Retrieve versions for the second secret and check that the first secret's version is not included versions = keywhizClient.listSecretVersions(name, 0, 10); assertThat(versions.size()).isEqualTo(1); assertThat(versions.get(0).description()).isEqualTo("second secret"); } }