/*
* 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;
import java.util.Optional;
import javax.ws.rs.ForbiddenException;
import javax.ws.rs.NotFoundException;
import keywhiz.api.ApiDate;
import keywhiz.api.SecretDeliveryResponse;
import keywhiz.api.model.Client;
import keywhiz.api.model.SanitizedSecret;
import keywhiz.api.model.Secret;
import keywhiz.service.daos.AclDAO;
import keywhiz.service.daos.ClientDAO;
import keywhiz.service.daos.SecretController;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
public class SecretDeliveryResourceTest {
private static final ApiDate NOW = ApiDate.now();
@Rule public MockitoRule mockito = MockitoJUnit.rule();
@Mock SecretController secretController;
@Mock AclDAO aclDAO;
@Mock ClientDAO clientDAO;
SecretDeliveryResource secretDeliveryResource;
final Client client = new Client(0, "principal", null, null, null, null, null, null, false, false);
final Secret secret = new Secret(0, "secret_name", null, () -> "secret_value", "checksum", NOW, null, NOW, null,
null, null, null, 0, 1L);
final Secret secretBase64 = new Secret(1, "Base64With=", null, () -> "SGVsbG8=", "checksum", NOW, null, NOW,
null, null, null, null, 0, 1L);
@Before public void setUp() {
secretDeliveryResource = new SecretDeliveryResource(secretController, aclDAO, clientDAO);
}
@Test public void returnsSecretWhenAllowed() throws Exception {
Secret secret = new Secret(0, "secret_name", null, () -> "unused_secret", "checksum", NOW, null, NOW, null, null, null,
null, 0, 1L);
SanitizedSecret sanitizedSecret = SanitizedSecret.fromSecret(secret);
String name = sanitizedSecret.name();
when(aclDAO.getSanitizedSecretFor(client, name))
.thenReturn(Optional.of(sanitizedSecret));
when(secretController.getSecretByName(name))
.thenReturn(Optional.of(secret));
SecretDeliveryResponse response = secretDeliveryResource.getSecret(sanitizedSecret.name(), client);
assertThat(response).isEqualTo(SecretDeliveryResponse.fromSecret(secret));
}
@Test public void returnsVersionedSecretWhenAllowed() throws Exception {
String name = "secret_name";
Secret versionedSecret = new Secret(2, name, null, () -> "U3BpZGVybWFu", "checksum", NOW, null, NOW,
null, null, null, null, 0, 1L);
when(aclDAO.getSanitizedSecretFor(client, name))
.thenReturn(Optional.of(SanitizedSecret.fromSecret(versionedSecret)));
when(secretController.getSecretByName(name))
.thenReturn(Optional.of(versionedSecret));
String displayName = versionedSecret.getDisplayName();
SecretDeliveryResponse response = secretDeliveryResource.getSecret(displayName, client);
assertThat(response).isEqualTo(SecretDeliveryResponse.fromSecret(versionedSecret));
}
@Test(expected = NotFoundException.class)
public void returnsNotFoundWhenClientDoesNotExist() throws Exception {
when(aclDAO.getSanitizedSecretFor(client, secret.getName())).thenReturn(Optional.empty());
when(clientDAO.getClient(client.getName())).thenReturn(Optional.empty());
when(secretController.getSecretByName(secret.getName()))
.thenReturn(Optional.of(secret));
secretDeliveryResource.getSecret(secret.getName(), client);
}
@Test(expected = NotFoundException.class)
public void returnsNotFoundWhenSecretDoesNotExist() throws Exception {
when(aclDAO.getSanitizedSecretFor(client, "secret_name")).thenReturn(Optional.empty());
when(clientDAO.getClient(client.getName())).thenReturn(Optional.of(client));
when(secretController.getSecretByName("secret_name"))
.thenReturn(Optional.empty());
secretDeliveryResource.getSecret("secret_name", client);
}
@Test(expected = ForbiddenException.class)
public void returnsUnauthorizedWhenDenied() throws Exception {
when(aclDAO.getSanitizedSecretFor(client, secret.getName())).thenReturn(Optional.empty());
when(clientDAO.getClient(client.getName())).thenReturn(Optional.of(client));
when(secretController.getSecretByName(secret.getName()))
.thenReturn(Optional.of(secret));
secretDeliveryResource.getSecret(secret.getName(), client);
}
@Test public void doesNotEscapeBase64() throws Exception {
String name = secretBase64.getName();
when(aclDAO.getSanitizedSecretFor(client, name))
.thenReturn(Optional.of(SanitizedSecret.fromSecret(secretBase64)));
when(secretController.getSecretByName(name))
.thenReturn(Optional.of(secretBase64));
SecretDeliveryResponse response = secretDeliveryResource.getSecret(secretBase64.getName(), client);
assertThat(response.getSecret()).isEqualTo(secretBase64.getSecret());
}
}