Clean up concepts of enabled account state

1) Rename "active" methods to be "enabled," since they aren't
   really about "activity."

2) Make authentication fail if a device or account is in dissabled
   state.

3) Let some controllers authenticate accounts that are in a
   disabled state.
This commit is contained in:
Moxie Marlinspike
2019-05-04 12:31:50 -07:00
parent fe66a59618
commit 35116f9229
36 changed files with 570 additions and 231 deletions

View File

@@ -29,7 +29,7 @@ public class OptionalAccessTest {
@Test
public void testUnidentifiedMissingTargetDevice() {
Account account = mock(Account.class);
when(account.isActive()).thenReturn(true);
when(account.isEnabled()).thenReturn(true);
when(account.getDevice(eq(10))).thenReturn(Optional.empty());
when(account.getUnidentifiedAccessKey()).thenReturn(Optional.of("1234".getBytes()));
@@ -43,7 +43,7 @@ public class OptionalAccessTest {
@Test
public void testUnidentifiedBadTargetDevice() {
Account account = mock(Account.class);
when(account.isActive()).thenReturn(true);
when(account.isEnabled()).thenReturn(true);
when(account.getDevice(eq(10))).thenReturn(Optional.empty());
when(account.getUnidentifiedAccessKey()).thenReturn(Optional.of("1234".getBytes()));
@@ -58,7 +58,7 @@ public class OptionalAccessTest {
@Test
public void testUnidentifiedBadCode() {
Account account = mock(Account.class);
when(account.isActive()).thenReturn(true);
when(account.isEnabled()).thenReturn(true);
when(account.getUnidentifiedAccessKey()).thenReturn(Optional.of("1234".getBytes()));
try {
@@ -72,7 +72,7 @@ public class OptionalAccessTest {
@Test
public void testIdentifiedMissingTarget() {
Account account = mock(Account.class);
when(account.isActive()).thenReturn(true);
when(account.isEnabled()).thenReturn(true);
try {
OptionalAccess.verify(Optional.of(account), Optional.empty(), Optional.empty());
@@ -86,7 +86,7 @@ public class OptionalAccessTest {
public void testUnsolicitedBadTarget() {
Account account = mock(Account.class);
when(account.isUnrestrictedUnidentifiedAccess()).thenReturn(false);
when(account.isActive()).thenReturn(true);
when(account.isEnabled()).thenReturn(true);
try {
OptionalAccess.verify(Optional.empty(), Optional.empty(), Optional.of(account));
@@ -101,7 +101,7 @@ public class OptionalAccessTest {
Account account = mock(Account.class);
Anonymous random = mock(Anonymous.class);
when(account.isUnrestrictedUnidentifiedAccess()).thenReturn(true);
when(account.isActive()).thenReturn(true);
when(account.isEnabled()).thenReturn(true);
OptionalAccess.verify(Optional.empty(), Optional.of(random), Optional.of(account));
}
@@ -109,7 +109,7 @@ public class OptionalAccessTest {
public void testUnidentifiedGoodTarget() {
Account account = mock(Account.class);
when(account.getUnidentifiedAccessKey()).thenReturn(Optional.of("1234".getBytes()));
when(account.isActive()).thenReturn(true);
when(account.isEnabled()).thenReturn(true);
OptionalAccess.verify(Optional.empty(), Optional.of(new Anonymous(Base64.encodeBytes("1234".getBytes()))), Optional.of(account));
}
@@ -117,7 +117,7 @@ public class OptionalAccessTest {
public void testUnidentifiedInactive() {
Account account = mock(Account.class);
when(account.getUnidentifiedAccessKey()).thenReturn(Optional.of("1234".getBytes()));
when(account.isActive()).thenReturn(false);
when(account.isEnabled()).thenReturn(false);
try {
OptionalAccess.verify(Optional.empty(), Optional.of(new Anonymous(Base64.encodeBytes("1234".getBytes()))), Optional.of(account));
@@ -131,7 +131,7 @@ public class OptionalAccessTest {
public void testIdentifiedGoodTarget() {
Account source = mock(Account.class);
Account target = mock(Account.class);
when(target.isActive()).thenReturn(true);
when(target.isEnabled()).thenReturn(true);
OptionalAccess.verify(Optional.of(source), Optional.empty(), Optional.of(target));;
}
}

View File

@@ -1,14 +1,18 @@
package org.whispersystems.textsecuregcm.tests.controllers;
import com.google.common.collect.ImmutableSet;
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAccount;
import org.whispersystems.textsecuregcm.auth.StoredVerificationCode;
import org.whispersystems.textsecuregcm.auth.TurnTokenGenerator;
import org.whispersystems.textsecuregcm.controllers.AccountController;
import org.whispersystems.textsecuregcm.controllers.RateLimitExceededException;
import org.whispersystems.textsecuregcm.entities.AccountAttributes;
import org.whispersystems.textsecuregcm.entities.ApnRegistrationId;
import org.whispersystems.textsecuregcm.entities.GcmRegistrationId;
import org.whispersystems.textsecuregcm.entities.RegistrationLock;
import org.whispersystems.textsecuregcm.entities.RegistrationLockFailure;
import org.whispersystems.textsecuregcm.limits.RateLimiter;
@@ -36,7 +40,7 @@ import java.util.HashMap;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import io.dropwizard.auth.AuthValueFactoryProvider;
import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider;
import io.dropwizard.testing.junit.ResourceTestRule;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.anyString;
@@ -80,7 +84,7 @@ public class AccountControllerTest {
@Rule
public final ResourceTestRule resources = ResourceTestRule.builder()
.addProvider(AuthHelper.getAuthFilter())
.addProvider(new AuthValueFactoryProvider.Binder<>(Account.class))
.addProvider(new PolymorphicAuthValueFactoryProvider.Binder<>(ImmutableSet.of(Account.class, DisabledPermittedAccount.class)))
.addProvider(new RateLimitExceededExceptionMapper())
.setMapper(SystemMapper.getMapper())
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
@@ -505,6 +509,51 @@ public class AccountControllerTest {
verify(AuthHelper.VALID_ACCOUNT, never()).setPin(anyString());
}
@Test
public void testSetPinDisabled() throws Exception {
Response response =
resources.getJerseyTest()
.target("/v1/accounts/pin/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.put(Entity.json(new RegistrationLock("31337")));
assertThat(response.getStatus()).isEqualTo(401);
verify(AuthHelper.VALID_ACCOUNT, never()).setPin(anyString());
}
@Test
public void testSetGcmId() throws Exception {
Response response =
resources.getJerseyTest()
.target("/v1/accounts/gcm/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.put(Entity.json(new GcmRegistrationId("c00lz0rz")));
assertThat(response.getStatus()).isEqualTo(204);
verify(AuthHelper.DISABLED_DEVICE, times(1)).setGcmId(eq("c00lz0rz"));
verify(accountsManager, times(1)).update(eq(AuthHelper.DISABLED_ACCOUNT));
}
@Test
public void testSetApnId() throws Exception {
Response response =
resources.getJerseyTest()
.target("/v1/accounts/apn/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.put(Entity.json(new ApnRegistrationId("first", "second")));
assertThat(response.getStatus()).isEqualTo(204);
verify(AuthHelper.DISABLED_DEVICE, times(1)).setApnId(eq("first"));
verify(AuthHelper.DISABLED_DEVICE, times(1)).setVoipApnId(eq("second"));
verify(accountsManager, times(1)).update(eq(AuthHelper.DISABLED_ACCOUNT));
}
}

View File

@@ -1,8 +1,10 @@
package org.whispersystems.textsecuregcm.tests.controllers;
import com.google.common.collect.ImmutableSet;
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
import org.junit.ClassRule;
import org.junit.Test;
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAccount;
import org.whispersystems.textsecuregcm.controllers.AttachmentControllerV1;
import org.whispersystems.textsecuregcm.controllers.AttachmentControllerV2;
import org.whispersystems.textsecuregcm.entities.AttachmentDescriptorV1;
@@ -14,9 +16,10 @@ import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
import org.whispersystems.textsecuregcm.util.SystemMapper;
import javax.ws.rs.core.Response;
import java.net.MalformedURLException;
import io.dropwizard.auth.AuthValueFactoryProvider;
import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider;
import io.dropwizard.testing.junit.ResourceTestRule;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@@ -34,7 +37,7 @@ public class AttachmentControllerTest {
@ClassRule
public static final ResourceTestRule resources = ResourceTestRule.builder()
.addProvider(AuthHelper.getAuthFilter())
.addProvider(new AuthValueFactoryProvider.Binder<>(Account.class))
.addProvider(new PolymorphicAuthValueFactoryProvider.Binder<>(ImmutableSet.of(Account.class, DisabledPermittedAccount.class)))
.setMapper(SystemMapper.getMapper())
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
.addResource(new AttachmentControllerV1(rateLimiters, "accessKey", "accessSecret", "attachment-bucket"))
@@ -67,6 +70,18 @@ public class AttachmentControllerTest {
assertThat(descriptor.getSignature()).isNotBlank();
}
@Test
public void testV2FormDisabled() {
Response response = resources.getJerseyTest()
.target("/v2/attachments/form/upload")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.get();
assertThat(response.getStatus()).isEqualTo(401);
}
@Test
public void testAcceleratedPut() {
AttachmentDescriptorV1 descriptor = resources.getJerseyTest()

View File

@@ -1,9 +1,11 @@
package org.whispersystems.textsecuregcm.tests.controllers;
import com.google.common.collect.ImmutableSet;
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
import org.junit.ClassRule;
import org.junit.Test;
import org.whispersystems.textsecuregcm.auth.CertificateGenerator;
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAccount;
import org.whispersystems.textsecuregcm.auth.OptionalAccess;
import org.whispersystems.textsecuregcm.controllers.CertificateController;
import org.whispersystems.textsecuregcm.crypto.Curve;
@@ -19,7 +21,7 @@ import javax.ws.rs.core.Response;
import java.io.IOException;
import java.util.Arrays;
import io.dropwizard.auth.AuthValueFactoryProvider;
import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider;
import io.dropwizard.testing.junit.ResourceTestRule;
import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertEquals;
@@ -46,7 +48,7 @@ public class CertificateControllerTest {
@ClassRule
public static final ResourceTestRule resources = ResourceTestRule.builder()
.addProvider(AuthHelper.getAuthFilter())
.addProvider(new AuthValueFactoryProvider.Binder<>(Account.class))
.addProvider(new PolymorphicAuthValueFactoryProvider.Binder<>(ImmutableSet.of(Account.class, DisabledPermittedAccount.class)))
.setMapper(SystemMapper.getMapper())
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
.addResource(new CertificateController(certificateGenerator))
@@ -110,4 +112,16 @@ public class CertificateControllerTest {
assertEquals(response.getStatus(), 401);
}
@Test
public void testDisabledAuthentication() throws Exception {
Response response = resources.getJerseyTest()
.target("/v1/certificate/delivery")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.get();
assertEquals(response.getStatus(), 401);
}
}

View File

@@ -16,10 +16,12 @@
*/
package org.whispersystems.textsecuregcm.tests.controllers;
import com.google.common.collect.ImmutableSet;
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAccount;
import org.whispersystems.textsecuregcm.auth.StoredVerificationCode;
import org.whispersystems.textsecuregcm.controllers.DeviceController;
import org.whispersystems.textsecuregcm.entities.AccountAttributes;
@@ -28,7 +30,11 @@ import org.whispersystems.textsecuregcm.limits.RateLimiter;
import org.whispersystems.textsecuregcm.limits.RateLimiters;
import org.whispersystems.textsecuregcm.mappers.DeviceLimitExceededExceptionMapper;
import org.whispersystems.textsecuregcm.sqs.DirectoryQueue;
import org.whispersystems.textsecuregcm.storage.*;
import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.storage.MessagesManager;
import org.whispersystems.textsecuregcm.storage.PendingDevicesManager;
import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
import org.whispersystems.textsecuregcm.util.VerificationCode;
@@ -41,7 +47,7 @@ import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import io.dropwizard.auth.AuthValueFactoryProvider;
import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider;
import io.dropwizard.testing.junit.ResourceTestRule;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
@@ -83,7 +89,7 @@ public class DeviceControllerTest {
@Rule
public final ResourceTestRule resources = ResourceTestRule.builder()
.addProvider(AuthHelper.getAuthFilter())
.addProvider(new AuthValueFactoryProvider.Binder<>(Account.class))
.addProvider(new PolymorphicAuthValueFactoryProvider.Binder<>(ImmutableSet.of(Account.class, DisabledPermittedAccount.class)))
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
.addProvider(new DeviceLimitExceededExceptionMapper())
.addResource(new DumbVerificationDeviceController(pendingDevicesManager,
@@ -109,7 +115,7 @@ public class DeviceControllerTest {
when(account.getNumber()).thenReturn(AuthHelper.VALID_NUMBER);
// when(maxedAccount.getActiveDeviceCount()).thenReturn(6);
when(account.getAuthenticatedDevice()).thenReturn(Optional.of(masterDevice));
when(account.isActive()).thenReturn(false);
when(account.isEnabled()).thenReturn(false);
when(pendingDevicesManager.getCodeForNumber(AuthHelper.VALID_NUMBER)).thenReturn(Optional.of(new StoredVerificationCode("5678901", System.currentTimeMillis())));
when(pendingDevicesManager.getCodeForNumber(AuthHelper.VALID_NUMBER_TWO)).thenReturn(Optional.of(new StoredVerificationCode("1112223", System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(31))));
@@ -141,6 +147,17 @@ public class DeviceControllerTest {
verify(messagesManager).clear(eq(AuthHelper.VALID_NUMBER), eq(42L));
}
@Test
public void disabledDeviceRegisterTest() throws Exception {
Response response = resources.getJerseyTest()
.target("/v1/devices/provisioning/code")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.get();
assertThat(response.getStatus()).isEqualTo(401);
}
@Test
public void invalidDeviceRegisterTest() throws Exception {
VerificationCode deviceCode = resources.getJerseyTest()

View File

@@ -1,5 +1,6 @@
package org.whispersystems.textsecuregcm.tests.controllers;
import com.google.common.collect.ImmutableSet;
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
import org.junit.Before;
import org.junit.Rule;
@@ -8,6 +9,7 @@ import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.whispersystems.textsecuregcm.auth.DirectoryCredentials;
import org.whispersystems.textsecuregcm.auth.DirectoryCredentialsGenerator;
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAccount;
import org.whispersystems.textsecuregcm.controllers.DirectoryController;
import org.whispersystems.textsecuregcm.entities.ClientContactTokens;
import org.whispersystems.textsecuregcm.entities.DirectoryFeedbackRequest;
@@ -27,7 +29,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import io.dropwizard.auth.AuthValueFactoryProvider;
import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider;
import io.dropwizard.testing.junit.ResourceTestRule;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyListOf;
@@ -47,7 +49,7 @@ public class DirectoryControllerTest {
@Rule
public final ResourceTestRule resources = ResourceTestRule.builder()
.addProvider(AuthHelper.getAuthFilter())
.addProvider(new AuthValueFactoryProvider.Binder<>(Account.class))
.addProvider(new PolymorphicAuthValueFactoryProvider.Binder<>(ImmutableSet.of(Account.class, DisabledPermittedAccount.class)))
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
.addResource(new DirectoryController(rateLimiters,
directoryManager,
@@ -148,6 +150,18 @@ public class DirectoryControllerTest {
assertThat(token.getPassword()).isEqualTo(validCredentials.getPassword());
}
@Test
public void testDisabledGetAuthToken() {
Response response =
resources.getJerseyTest()
.target("/v1/directory/auth")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.get();
assertThat(response.getStatus()).isEqualTo(401);
}
@Test
public void testContactIntersection() throws Exception {
List<String> tokens = new LinkedList<String>() {{

View File

@@ -1,10 +1,12 @@
package org.whispersystems.textsecuregcm.tests.controllers;
import com.google.common.collect.ImmutableSet;
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAccount;
import org.whispersystems.textsecuregcm.auth.OptionalAccess;
import org.whispersystems.textsecuregcm.controllers.KeysController;
import org.whispersystems.textsecuregcm.entities.PreKey;
@@ -31,7 +33,7 @@ import java.util.List;
import java.util.Optional;
import java.util.Set;
import io.dropwizard.auth.AuthValueFactoryProvider;
import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider;
import io.dropwizard.testing.junit.ResourceTestRule;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.*;
@@ -67,7 +69,7 @@ public class KeyControllerTest {
@Rule
public final ResourceTestRule resources = ResourceTestRule.builder()
.addProvider(AuthHelper.getAuthFilter())
.addProvider(new AuthValueFactoryProvider.Binder<>(Account.class))
.addProvider(new PolymorphicAuthValueFactoryProvider.Binder<>(ImmutableSet.of(Account.class, DisabledPermittedAccount.class)))
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
.addResource(new KeysController(rateLimiters, keys, accounts, directoryQueue))
.build();
@@ -90,10 +92,10 @@ public class KeyControllerTest {
when(sampleDevice2.getRegistrationId()).thenReturn(SAMPLE_REGISTRATION_ID2);
when(sampleDevice3.getRegistrationId()).thenReturn(SAMPLE_REGISTRATION_ID2);
when(sampleDevice4.getRegistrationId()).thenReturn(SAMPLE_REGISTRATION_ID4);
when(sampleDevice.isActive()).thenReturn(true);
when(sampleDevice2.isActive()).thenReturn(true);
when(sampleDevice3.isActive()).thenReturn(false);
when(sampleDevice4.isActive()).thenReturn(true);
when(sampleDevice.isEnabled()).thenReturn(true);
when(sampleDevice2.isEnabled()).thenReturn(true);
when(sampleDevice3.isEnabled()).thenReturn(false);
when(sampleDevice4.isEnabled()).thenReturn(true);
when(sampleDevice.getSignedPreKey()).thenReturn(SAMPLE_SIGNED_KEY);
when(sampleDevice2.getSignedPreKey()).thenReturn(SAMPLE_SIGNED_KEY2);
when(sampleDevice3.getSignedPreKey()).thenReturn(SAMPLE_SIGNED_KEY3);
@@ -109,7 +111,7 @@ public class KeyControllerTest {
when(existsAccount.getDevice(4L)).thenReturn(Optional.of(sampleDevice4));
when(existsAccount.getDevice(22L)).thenReturn(Optional.<Device>empty());
when(existsAccount.getDevices()).thenReturn(allDevices);
when(existsAccount.isActive()).thenReturn(true);
when(existsAccount.isEnabled()).thenReturn(true);
when(existsAccount.getIdentityKey()).thenReturn("existsidentitykey");
when(existsAccount.getNumber()).thenReturn(EXISTS_NUMBER);
when(existsAccount.getUnidentifiedAccessKey()).thenReturn(Optional.of("1337".getBytes()));
@@ -180,6 +182,21 @@ public class KeyControllerTest {
verify(accounts).update(eq(AuthHelper.VALID_ACCOUNT));
}
@Test
public void disabledPutSignedPreKeyV2() throws Exception {
SignedPreKey test = new SignedPreKey(9999, "fooozzz", "baaarzzz");
Response response = resources.getJerseyTest()
.target("/v2/keys/signed")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.put(Entity.entity(test, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(204);
verify(AuthHelper.DISABLED_DEVICE).setSignedPreKey(eq(test));
verify(accounts).update(eq(AuthHelper.DISABLED_ACCOUNT));
}
@Test
public void validSingleRequestTestV2() throws Exception {
PreKeyResponse result = resources.getJerseyTest()
@@ -367,5 +384,39 @@ public class KeyControllerTest {
verify(accounts).update(AuthHelper.VALID_ACCOUNT);
}
@Test
public void disabledPutKeysTestV2() throws Exception {
final PreKey preKey = new PreKey(31337, "foobar");
final SignedPreKey signedPreKey = new SignedPreKey(31338, "foobaz", "myvalidsig");
final String identityKey = "barbar";
List<PreKey> preKeys = new LinkedList<PreKey>() {{
add(preKey);
}};
PreKeyState preKeyState = new PreKeyState(identityKey, signedPreKey, preKeys);
Response response =
resources.getJerseyTest()
.target("/v2/keys")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.put(Entity.entity(preKeyState, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(204);
ArgumentCaptor<List> listCaptor = ArgumentCaptor.forClass(List.class);
verify(keys).store(eq(AuthHelper.DISABLED_NUMBER), eq(1L), listCaptor.capture());
List<PreKey> capturedList = listCaptor.getValue();
assertThat(capturedList.size()).isEqualTo(1);
assertThat(capturedList.get(0).getKeyId()).isEqualTo(31337);
assertThat(capturedList.get(0).getPublicKey()).isEqualTo("foobar");
verify(AuthHelper.DISABLED_ACCOUNT).setIdentityKey(eq("barbar"));
verify(AuthHelper.DISABLED_DEVICE).setSignedPreKey(eq(signedPreKey));
verify(accounts).update(AuthHelper.DISABLED_ACCOUNT);
}
}

View File

@@ -1,11 +1,13 @@
package org.whispersystems.textsecuregcm.tests.controllers;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableSet;
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAccount;
import org.whispersystems.textsecuregcm.auth.OptionalAccess;
import org.whispersystems.textsecuregcm.controllers.MessageController;
import org.whispersystems.textsecuregcm.entities.IncomingMessageList;
@@ -38,7 +40,7 @@ import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import io.dropwizard.auth.AuthValueFactoryProvider;
import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider;
import io.dropwizard.testing.junit.ResourceTestRule;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
@@ -68,7 +70,7 @@ public class MessageControllerTest {
@Rule
public final ResourceTestRule resources = ResourceTestRule.builder()
.addProvider(AuthHelper.getAuthFilter())
.addProvider(new AuthValueFactoryProvider.Binder<>(Account.class))
.addProvider(new PolymorphicAuthValueFactoryProvider.Binder<>(ImmutableSet.of(Account.class, DisabledPermittedAccount.class)))
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
.addResource(new MessageController(rateLimiters, pushSender, receiptSender, accountsManager,
messagesManager, apnFallbackManager))
@@ -95,7 +97,20 @@ public class MessageControllerTest {
when(rateLimiters.getMessagesLimiter()).thenReturn(rateLimiter);
}
@Test
public synchronized void testSendFromDisabledAccount() throws Exception {
Response response =
resources.getJerseyTest()
.target(String.format("/v1/messages/%s", SINGLE_DEVICE_RECIPIENT))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.put(Entity.entity(mapper.readValue(jsonFixture("fixtures/current_message_single_device.json"), IncomingMessageList.class),
MediaType.APPLICATION_JSON_TYPE));
assertThat("Unauthorized response", response.getStatus(), is(equalTo(401)));
}
@Test
public synchronized void testSingleDeviceCurrent() throws Exception {
Response response =

View File

@@ -1,9 +1,11 @@
package org.whispersystems.textsecuregcm.tests.controllers;
import com.google.common.collect.ImmutableSet;
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAccount;
import org.whispersystems.textsecuregcm.configuration.ProfilesConfiguration;
import org.whispersystems.textsecuregcm.controllers.ProfileController;
import org.whispersystems.textsecuregcm.controllers.RateLimitExceededException;
@@ -18,7 +20,7 @@ import org.whispersystems.textsecuregcm.util.SystemMapper;
import javax.ws.rs.core.Response;
import java.util.Optional;
import io.dropwizard.auth.AuthValueFactoryProvider;
import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider;
import io.dropwizard.testing.junit.ResourceTestRule;
import static org.assertj.core.api.Java6Assertions.assertThat;
import static org.mockito.Mockito.*;
@@ -40,7 +42,7 @@ public class ProfileControllerTest {
@ClassRule
public static final ResourceTestRule resources = ResourceTestRule.builder()
.addProvider(AuthHelper.getAuthFilter())
.addProvider(new AuthValueFactoryProvider.Binder<>(Account.class))
.addProvider(new PolymorphicAuthValueFactoryProvider.Binder<>(ImmutableSet.of(Account.class, DisabledPermittedAccount.class)))
.setMapper(SystemMapper.getMapper())
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
.addResource(new ProfileController(rateLimiters,
@@ -58,7 +60,7 @@ public class ProfileControllerTest {
when(profileAccount.getProfileName()).thenReturn("baz");
when(profileAccount.getAvatar()).thenReturn("profiles/bang");
when(profileAccount.getAvatarDigest()).thenReturn("buh");
when(profileAccount.isActive()).thenReturn(true);
when(profileAccount.isEnabled()).thenReturn(true);
when(accountsManager.get(AuthHelper.VALID_NUMBER_TWO)).thenReturn(Optional.of(profileAccount));
}
@@ -91,4 +93,15 @@ public class ProfileControllerTest {
assertThat(response.getStatus()).isEqualTo(401);
}
@Test
public void testProfileGetDisabled() throws Exception {
Response response = resources.getJerseyTest()
.target("/v1/profile/" + AuthHelper.VALID_NUMBER_TWO)
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.get();
assertThat(response.getStatus()).isEqualTo(401);
}
}

View File

@@ -1,11 +1,13 @@
package org.whispersystems.textsecuregcm.tests.controllers;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.collect.ImmutableSet;
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
import org.hamcrest.MatcherAssert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAccount;
import org.whispersystems.textsecuregcm.controllers.TransparentDataController;
import org.whispersystems.textsecuregcm.entities.SignedPreKey;
import org.whispersystems.textsecuregcm.mappers.RateLimitExceededExceptionMapper;
@@ -24,6 +26,7 @@ import java.util.Map;
import java.util.Optional;
import io.dropwizard.auth.AuthValueFactoryProvider;
import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider;
import io.dropwizard.testing.junit.ResourceTestRule;
import static junit.framework.TestCase.*;
import static org.hamcrest.CoreMatchers.equalTo;
@@ -42,7 +45,7 @@ public class TransparentDataControllerTest {
@Rule
public final ResourceTestRule resources = ResourceTestRule.builder()
.addProvider(AuthHelper.getAuthFilter())
.addProvider(new AuthValueFactoryProvider.Binder<>(Account.class))
.addProvider(new PolymorphicAuthValueFactoryProvider.Binder<>(ImmutableSet.of(Account.class, DisabledPermittedAccount.class)))
.addProvider(new RateLimitExceededExceptionMapper())
.setMapper(SystemMapper.getMapper())
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())

View File

@@ -1,8 +1,10 @@
package org.whispersystems.textsecuregcm.tests.controllers;
import com.google.common.collect.ImmutableSet;
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
import org.junit.Rule;
import org.junit.Test;
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAccount;
import org.whispersystems.textsecuregcm.controllers.VoiceVerificationController;
import org.whispersystems.textsecuregcm.mappers.RateLimitExceededExceptionMapper;
import org.whispersystems.textsecuregcm.storage.Account;
@@ -11,10 +13,9 @@ import org.whispersystems.textsecuregcm.util.SystemMapper;
import javax.ws.rs.core.Response;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import io.dropwizard.auth.AuthValueFactoryProvider;
import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider;
import io.dropwizard.testing.FixtureHelpers;
import io.dropwizard.testing.junit.ResourceTestRule;
import static org.assertj.core.api.Assertions.assertThat;
@@ -24,7 +25,7 @@ public class VoiceVerificationControllerTest {
@Rule
public final ResourceTestRule resources = ResourceTestRule.builder()
.addProvider(AuthHelper.getAuthFilter())
.addProvider(new AuthValueFactoryProvider.Binder<>(Account.class))
.addProvider(new PolymorphicAuthValueFactoryProvider.Binder<>(ImmutableSet.of(Account.class, DisabledPermittedAccount.class)))
.addProvider(new RateLimitExceededExceptionMapper())
.setMapper(SystemMapper.getMapper())
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())

View File

@@ -67,43 +67,43 @@ public class AccountCleanerTest {
@Before
public void setup() {
when(activeUnexpiredDevice.isActive()).thenReturn(true);
when(activeUnexpiredDevice.isEnabled()).thenReturn(true);
when(activeUnexpiredAccount.getLastSeen()).thenReturn(Long.MAX_VALUE);
when(activeUnexpiredAccount.getMasterDevice()).thenReturn(Optional.of(activeUnexpiredDevice));
when(activeExpiredAccount.getNumber()).thenReturn(AuthHelper.VALID_NUMBER);
when(activeExpiredDevice.isActive()).thenReturn(true);
when(activeExpiredDevice.isEnabled()).thenReturn(true);
when(activeExpiredAccount.getLastSeen()).thenReturn(0L);
when(activeExpiredAccount.getMasterDevice()).thenReturn(Optional.of(activeExpiredDevice));
when(inactiveUnexpiredDevice.isActive()).thenReturn(false);
when(inactiveUnexpiredDevice.isEnabled()).thenReturn(false);
when(inactiveUnexpiredAccount.getLastSeen()).thenReturn(Long.MAX_VALUE);
when(inactiveUnexpiredAccount.getMasterDevice()).thenReturn(Optional.of(inactiveUnexpiredDevice));
when(inactiveExpiredDevice.isActive()).thenReturn(false);
when(inactiveExpiredDevice.isEnabled()).thenReturn(false);
when(inactiveExpiredAccount.getLastSeen()).thenReturn(0L);
when(inactiveExpiredAccount.getMasterDevice()).thenReturn(Optional.of(inactiveExpiredDevice));
this.nowMs = System.currentTimeMillis();
when(oldMasterDevice.getLastSeen()).thenReturn(nowMs - TimeUnit.DAYS.toMillis(366));
when(oldMasterDevice.isActive()).thenReturn(true);
when(oldMasterDevice.isEnabled()).thenReturn(true);
when(oldMasterDevice.getId()).thenReturn(Device.MASTER_ID);
when(recentMasterDevice.getLastSeen()).thenReturn(nowMs - TimeUnit.DAYS.toMillis(1));
when(recentMasterDevice.isActive()).thenReturn(true);
when(recentMasterDevice.isEnabled()).thenReturn(true);
when(recentMasterDevice.getId()).thenReturn(Device.MASTER_ID);
when(agingSecondaryDevice.getLastSeen()).thenReturn(nowMs - TimeUnit.DAYS.toMillis(31));
when(agingSecondaryDevice.isActive()).thenReturn(false);
when(agingSecondaryDevice.isEnabled()).thenReturn(false);
when(agingSecondaryDevice.getId()).thenReturn(2L);
when(recentSecondaryDevice.getLastSeen()).thenReturn(nowMs - TimeUnit.DAYS.toMillis(1));
when(recentSecondaryDevice.isActive()).thenReturn(true);
when(recentSecondaryDevice.isEnabled()).thenReturn(true);
when(recentSecondaryDevice.getId()).thenReturn(2L);
when(oldSecondaryDevice.getLastSeen()).thenReturn(nowMs - TimeUnit.DAYS.toMillis(366));
when(oldSecondaryDevice.isActive()).thenReturn(false);
when(oldSecondaryDevice.isEnabled()).thenReturn(false);
when(oldSecondaryDevice.getId()).thenReturn(2L);
}
@@ -114,9 +114,9 @@ public class AccountCleanerTest {
accountCleaner.onCrawlChunk(Optional.empty(), Arrays.asList(activeUnexpiredAccount, inactiveUnexpiredAccount, inactiveExpiredAccount));
accountCleaner.onCrawlEnd(Optional.empty());
verify(activeUnexpiredDevice, atLeastOnce()).isActive();
verify(inactiveUnexpiredDevice, atLeastOnce()).isActive();
verify(inactiveExpiredDevice, atLeastOnce()).isActive();
verify(activeUnexpiredDevice, atLeastOnce()).isEnabled();
verify(inactiveUnexpiredDevice, atLeastOnce()).isEnabled();
verify(inactiveExpiredDevice, atLeastOnce()).isEnabled();
verifyNoMoreInteractions(activeUnexpiredDevice);
verifyNoMoreInteractions(activeExpiredDevice);

View File

@@ -25,23 +25,23 @@ public class AccountTest {
@Before
public void setup() {
when(oldMasterDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(366));
when(oldMasterDevice.isActive()).thenReturn(true);
when(oldMasterDevice.isEnabled()).thenReturn(true);
when(oldMasterDevice.getId()).thenReturn(Device.MASTER_ID);
when(recentMasterDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1));
when(recentMasterDevice.isActive()).thenReturn(true);
when(recentMasterDevice.isEnabled()).thenReturn(true);
when(recentMasterDevice.getId()).thenReturn(Device.MASTER_ID);
when(agingSecondaryDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(31));
when(agingSecondaryDevice.isActive()).thenReturn(false);
when(agingSecondaryDevice.isEnabled()).thenReturn(false);
when(agingSecondaryDevice.getId()).thenReturn(2L);
when(recentSecondaryDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1));
when(recentSecondaryDevice.isActive()).thenReturn(true);
when(recentSecondaryDevice.isEnabled()).thenReturn(true);
when(recentSecondaryDevice.getId()).thenReturn(2L);
when(oldSecondaryDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(366));
when(oldSecondaryDevice.isActive()).thenReturn(false);
when(oldSecondaryDevice.isEnabled()).thenReturn(false);
when(oldSecondaryDevice.getId()).thenReturn(2L);
}
@@ -52,21 +52,21 @@ public class AccountTest {
add(recentSecondaryDevice);
}}, "1234".getBytes());
assertTrue(recentAccount.isActive());
assertTrue(recentAccount.isEnabled());
Account oldSecondaryAccount = new Account("+14152222222", new HashSet<Device>() {{
add(recentMasterDevice);
add(agingSecondaryDevice);
}}, "1234".getBytes());
assertTrue(oldSecondaryAccount.isActive());
assertTrue(oldSecondaryAccount.isEnabled());
Account agingPrimaryAccount = new Account("+14152222222", new HashSet<Device>() {{
add(oldMasterDevice);
add(agingSecondaryDevice);
}}, "1234".getBytes());
assertTrue(agingPrimaryAccount.isActive());
assertTrue(agingPrimaryAccount.isEnabled());
}
@Test
@@ -76,7 +76,7 @@ public class AccountTest {
add(oldSecondaryDevice);
}}, "1234".getBytes());
assertFalse(oldPrimaryAccount.isActive());
assertFalse(oldPrimaryAccount.isEnabled());
}
}

View File

@@ -57,9 +57,9 @@ public class DirectoryReconcilerTest {
@Before
public void setup() {
when(activeAccount.getNumber()).thenReturn(VALID_NUMBER);
when(activeAccount.isActive()).thenReturn(true);
when(activeAccount.isEnabled()).thenReturn(true);
when(inactiveAccount.getNumber()).thenReturn(INACTIVE_NUMBER);
when(inactiveAccount.isActive()).thenReturn(false);
when(inactiveAccount.isEnabled()).thenReturn(false);
when(directoryManager.startBatchOperation()).thenReturn(batchOperationHandle);
}
@@ -69,9 +69,9 @@ public class DirectoryReconcilerTest {
directoryReconciler.onCrawlChunk(Optional.of(VALID_NUMBER), Arrays.asList(activeAccount, inactiveAccount));
verify(activeAccount, times(2)).getNumber();
verify(activeAccount, times(2)).isActive();
verify(activeAccount, times(2)).isEnabled();
verify(inactiveAccount, times(2)).getNumber();
verify(inactiveAccount, times(2)).isActive();
verify(inactiveAccount, times(2)).isEnabled();
ArgumentCaptor<DirectoryReconciliationRequest> request = ArgumentCaptor.forClass(DirectoryReconciliationRequest.class);
verify(reconciliationClient, times(1)).sendChunk(request.capture());

View File

@@ -1,7 +1,10 @@
package org.whispersystems.textsecuregcm.tests.util;
import com.google.common.collect.ImmutableMap;
import org.whispersystems.textsecuregcm.auth.AccountAuthenticator;
import org.whispersystems.textsecuregcm.auth.AuthenticationCredentials;
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAccount;
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAccountAuthenticator;
import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.Device;
@@ -9,9 +12,10 @@ import org.whispersystems.textsecuregcm.util.Base64;
import java.util.Optional;
import io.dropwizard.auth.AuthDynamicFeature;
import io.dropwizard.auth.AuthFilter;
import io.dropwizard.auth.PolymorphicAuthDynamicFeature;
import io.dropwizard.auth.basic.BasicCredentialAuthFilter;
import static org.mockito.Matchers.anyLong;
import io.dropwizard.auth.basic.BasicCredentials;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -26,43 +30,76 @@ public class AuthHelper {
public static final String INVVALID_NUMBER = "+14151111111";
public static final String INVALID_PASSWORD = "bar";
public static final String DISABLED_NUMBER = "+78888888";
public static final String DISABLED_PASSWORD = "poof";
public static final String VALID_IDENTITY = "BcxxDU9FGMda70E7+Uvm7pnQcEdXQ64aJCpPUeRSfcFo";
public static AccountsManager ACCOUNTS_MANAGER = mock(AccountsManager.class );
public static Account VALID_ACCOUNT = mock(Account.class );
public static Account VALID_ACCOUNT_TWO = mock(Account.class);
public static Device VALID_DEVICE = mock(Device.class );
public static Device VALID_DEVICE_TWO = mock(Device.class);
private static AuthenticationCredentials VALID_CREDENTIALS = mock(AuthenticationCredentials.class);
private static AuthenticationCredentials VALID_CREDENTIALS_TWO = mock(AuthenticationCredentials.class);
public static AccountsManager ACCOUNTS_MANAGER = mock(AccountsManager.class);
public static Account VALID_ACCOUNT = mock(Account.class );
public static Account VALID_ACCOUNT_TWO = mock(Account.class );
public static Account DISABLED_ACCOUNT = mock(Account.class );
public static AuthDynamicFeature getAuthFilter() {
public static Device VALID_DEVICE = mock(Device.class);
public static Device VALID_DEVICE_TWO = mock(Device.class);
public static Device DISABLED_DEVICE = mock(Device.class);
private static AuthenticationCredentials VALID_CREDENTIALS = mock(AuthenticationCredentials.class);
private static AuthenticationCredentials VALID_CREDENTIALS_TWO = mock(AuthenticationCredentials.class);
private static AuthenticationCredentials DISABLED_CREDENTIALS = mock(AuthenticationCredentials.class);
public static PolymorphicAuthDynamicFeature getAuthFilter() {
when(VALID_CREDENTIALS.verify("foo")).thenReturn(true);
when(VALID_CREDENTIALS_TWO.verify("baz")).thenReturn(true);
when(DISABLED_CREDENTIALS.verify(DISABLED_PASSWORD)).thenReturn(true);
when(VALID_DEVICE.getAuthenticationCredentials()).thenReturn(VALID_CREDENTIALS);
when(VALID_DEVICE_TWO.getAuthenticationCredentials()).thenReturn(VALID_CREDENTIALS_TWO);
when(DISABLED_DEVICE.getAuthenticationCredentials()).thenReturn(DISABLED_CREDENTIALS);
when(VALID_DEVICE.isMaster()).thenReturn(true);
when(VALID_DEVICE_TWO.isMaster()).thenReturn(true);
when(DISABLED_DEVICE.isMaster()).thenReturn(true);
when(VALID_DEVICE.getId()).thenReturn(1L);
when(VALID_DEVICE_TWO.getId()).thenReturn(1L);
when(DISABLED_DEVICE.getId()).thenReturn(1L);
when(VALID_DEVICE.isEnabled()).thenReturn(true);
when(VALID_DEVICE_TWO.isEnabled()).thenReturn(true);
when(DISABLED_DEVICE.isEnabled()).thenReturn(false);
when(VALID_ACCOUNT.getDevice(1L)).thenReturn(Optional.of(VALID_DEVICE));
when(VALID_ACCOUNT_TWO.getDevice(eq(1L))).thenReturn(Optional.of(VALID_DEVICE_TWO));
when(VALID_ACCOUNT_TWO.getActiveDeviceCount()).thenReturn(6);
when(DISABLED_ACCOUNT.getDevice(eq(1L))).thenReturn(Optional.of(DISABLED_DEVICE));
when(VALID_ACCOUNT_TWO.getEnabledDeviceCount()).thenReturn(6);
when(VALID_ACCOUNT.getNumber()).thenReturn(VALID_NUMBER);
when(VALID_ACCOUNT_TWO.getNumber()).thenReturn(VALID_NUMBER_TWO);
when(DISABLED_ACCOUNT.getNumber()).thenReturn(DISABLED_NUMBER);
when(VALID_ACCOUNT.getAuthenticatedDevice()).thenReturn(Optional.of(VALID_DEVICE));
when(VALID_ACCOUNT_TWO.getAuthenticatedDevice()).thenReturn(Optional.of(VALID_DEVICE_TWO));
when(DISABLED_ACCOUNT.getAuthenticatedDevice()).thenReturn(Optional.of(DISABLED_DEVICE));
when(VALID_ACCOUNT.getRelay()).thenReturn(Optional.<String>empty());
when(VALID_ACCOUNT_TWO.getRelay()).thenReturn(Optional.<String>empty());
when(VALID_ACCOUNT.isActive()).thenReturn(true);
when(VALID_ACCOUNT_TWO.isActive()).thenReturn(true);
when(VALID_ACCOUNT.isEnabled()).thenReturn(true);
when(VALID_ACCOUNT_TWO.isEnabled()).thenReturn(true);
when(DISABLED_ACCOUNT.isEnabled()).thenReturn(false);
when(VALID_ACCOUNT.getIdentityKey()).thenReturn(VALID_IDENTITY);
when(ACCOUNTS_MANAGER.get(VALID_NUMBER)).thenReturn(Optional.of(VALID_ACCOUNT));
when(ACCOUNTS_MANAGER.get(VALID_NUMBER_TWO)).thenReturn(Optional.of(VALID_ACCOUNT_TWO));
when(ACCOUNTS_MANAGER.get(DISABLED_NUMBER)).thenReturn(Optional.of(DISABLED_ACCOUNT));
return new AuthDynamicFeature(new BasicCredentialAuthFilter.Builder<Account>()
.setAuthenticator(new AccountAuthenticator(ACCOUNTS_MANAGER))
.buildAuthFilter());
AuthFilter<BasicCredentials, Account> accountAuthFilter = new BasicCredentialAuthFilter.Builder<Account>().setAuthenticator(new AccountAuthenticator(ACCOUNTS_MANAGER)).buildAuthFilter ();
AuthFilter<BasicCredentials, DisabledPermittedAccount> disabledPermittedAccountAuthFilter = new BasicCredentialAuthFilter.Builder<DisabledPermittedAccount>().setAuthenticator(new DisabledPermittedAccountAuthenticator(ACCOUNTS_MANAGER)).buildAuthFilter();
return new PolymorphicAuthDynamicFeature<>(ImmutableMap.of(Account.class, accountAuthFilter,
DisabledPermittedAccount.class, disabledPermittedAccountAuthFilter));
}
public static String getAuthHeader(String number, String password) {