package io.dropwizard.auth;
import com.codahale.metrics.MetricRegistry;
import com.google.common.cache.CacheBuilderSpec;
import com.google.common.collect.ImmutableSet;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InOrder;
import java.security.Principal;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class CachingAuthorizerTest {
@SuppressWarnings("unchecked")
private final Authorizer<Principal> underlying = mock(Authorizer.class);
private final CachingAuthorizer<Principal> cached = new CachingAuthorizer<>(
new MetricRegistry(),
underlying,
CacheBuilderSpec.parse("maximumSize=1")
);
private final Principal principal = new PrincipalImpl("principal");
private final Principal principal2 = new PrincipalImpl("principal2");
private final Principal principal3 = new PrincipalImpl("principal3");
private final String role = "popular_kids";
@Before
public void setUp() throws Exception {
when(underlying.authorize(any(), anyString())).thenReturn(true);
}
@Test
public void cachesTheFirstReturnedPrincipal() throws Exception {
assertThat(cached.authorize(principal, role)).isTrue();
assertThat(cached.authorize(principal, role)).isTrue();
verify(underlying, times(1)).authorize(principal, role);
}
@Test
public void respectsTheCacheConfiguration() throws Exception {
cached.authorize(principal, role);
cached.authorize(principal2, role);
cached.authorize(principal, role);
final InOrder inOrder = inOrder(underlying);
inOrder.verify(underlying, times(1)).authorize(principal, role);
inOrder.verify(underlying, times(1)).authorize(principal2, role);
inOrder.verify(underlying, times(1)).authorize(principal, role);
}
@Test
public void invalidatesPrincipalAndRole() throws Exception {
cached.authorize(principal, role);
cached.invalidate(principal, role);
cached.authorize(principal, role);
verify(underlying, times(2)).authorize(principal, role);
}
@Test
public void invalidatesSinglePrincipal() throws Exception {
cached.authorize(principal, role);
cached.invalidate(principal);
cached.authorize(principal, role);
verify(underlying, times(2)).authorize(principal, role);
}
@Test
public void invalidatesSetsofPrincipals() throws Exception {
cached.authorize(principal, role);
cached.authorize(principal2, role);
cached.invalidateAll(ImmutableSet.of(principal, principal2));
cached.authorize(principal, role);
cached.authorize(principal2, role);
verify(underlying, times(2)).authorize(principal, role);
verify(underlying, times(2)).authorize(principal2, role);
}
@Test
public void invalidatesPrincipalsMatchingGivenPredicate() throws Exception {
cached.authorize(principal, role);
cached.invalidateAll(principal::equals);
cached.authorize(principal, role);
verify(underlying, times(2)).authorize(principal, role);
}
@Test
public void invalidatesAllPrincipals() throws Exception {
cached.authorize(principal, role);
cached.authorize(principal2, role);
cached.invalidateAll();
cached.authorize(principal, role);
cached.authorize(principal2, role);
verify(underlying, times(2)).authorize(principal, role);
verify(underlying, times(2)).authorize(principal2, role);
}
@Test
public void calculatesTheSizeOfTheCache() throws Exception {
assertThat(cached.size()).isEqualTo(0);
cached.authorize(principal, role);
assertThat(cached.size()).isEqualTo(1);
cached.invalidateAll();
assertThat(cached.size()).isEqualTo(0);
}
@Test
public void calculatesCacheStats() throws Exception {
cached.authorize(principal, role);
assertThat(cached.stats().loadCount()).isEqualTo(0);
assertThat(cached.size()).isEqualTo(1);
}
}