Auto refactor Only: s/Account/Device/g

This commit is contained in:
Matt Corallo 2014-01-11 10:56:29 -10:00
parent 5a837d4481
commit bd6cf10402
20 changed files with 217 additions and 298 deletions

View File

@ -20,7 +20,6 @@ import com.google.common.base.Optional;
import com.yammer.dropwizard.Service; import com.yammer.dropwizard.Service;
import com.yammer.dropwizard.config.Bootstrap; import com.yammer.dropwizard.config.Bootstrap;
import com.yammer.dropwizard.config.Environment; import com.yammer.dropwizard.config.Environment;
import com.yammer.dropwizard.config.FilterBuilder;
import com.yammer.dropwizard.db.DatabaseConfiguration; import com.yammer.dropwizard.db.DatabaseConfiguration;
import com.yammer.dropwizard.jdbi.DBIFactory; import com.yammer.dropwizard.jdbi.DBIFactory;
import com.yammer.dropwizard.migrations.MigrationsBundle; import com.yammer.dropwizard.migrations.MigrationsBundle;
@ -28,7 +27,7 @@ import com.yammer.metrics.reporting.GraphiteReporter;
import net.spy.memcached.MemcachedClient; import net.spy.memcached.MemcachedClient;
import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.skife.jdbi.v2.DBI; import org.skife.jdbi.v2.DBI;
import org.whispersystems.textsecuregcm.auth.AccountAuthenticator; import org.whispersystems.textsecuregcm.auth.DeviceAuthenticator;
import org.whispersystems.textsecuregcm.auth.FederatedPeerAuthenticator; import org.whispersystems.textsecuregcm.auth.FederatedPeerAuthenticator;
import org.whispersystems.textsecuregcm.auth.MultiBasicAuthProvider; import org.whispersystems.textsecuregcm.auth.MultiBasicAuthProvider;
import org.whispersystems.textsecuregcm.configuration.NexmoConfiguration; import org.whispersystems.textsecuregcm.configuration.NexmoConfiguration;
@ -52,7 +51,7 @@ import org.whispersystems.textsecuregcm.push.PushSender;
import org.whispersystems.textsecuregcm.sms.NexmoSmsSender; import org.whispersystems.textsecuregcm.sms.NexmoSmsSender;
import org.whispersystems.textsecuregcm.sms.SmsSender; import org.whispersystems.textsecuregcm.sms.SmsSender;
import org.whispersystems.textsecuregcm.sms.TwilioSmsSender; import org.whispersystems.textsecuregcm.sms.TwilioSmsSender;
import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.storage.Accounts; import org.whispersystems.textsecuregcm.storage.Accounts;
import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.DirectoryManager; import org.whispersystems.textsecuregcm.storage.DirectoryManager;
@ -67,7 +66,6 @@ import org.whispersystems.textsecuregcm.util.CORSHeaderFilter;
import org.whispersystems.textsecuregcm.util.UrlSigner; import org.whispersystems.textsecuregcm.util.UrlSigner;
import org.whispersystems.textsecuregcm.workers.DirectoryCommand; import org.whispersystems.textsecuregcm.workers.DirectoryCommand;
import java.io.IOException;
import java.security.Security; import java.security.Security;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -111,7 +109,7 @@ public class WhisperServerService extends Service<WhisperServerConfiguration> {
PendingAccountsManager pendingAccountsManager = new PendingAccountsManager(pendingAccounts, memcachedClient); PendingAccountsManager pendingAccountsManager = new PendingAccountsManager(pendingAccounts, memcachedClient);
PendingDevicesManager pendingDevicesManager = new PendingDevicesManager(pendingDevices, memcachedClient); PendingDevicesManager pendingDevicesManager = new PendingDevicesManager(pendingDevices, memcachedClient);
AccountsManager accountsManager = new AccountsManager(accounts, directory, memcachedClient); AccountsManager accountsManager = new AccountsManager(accounts, directory, memcachedClient);
AccountAuthenticator accountAuthenticator = new AccountAuthenticator(accountsManager ); DeviceAuthenticator deviceAuthenticator = new DeviceAuthenticator(accountsManager );
FederatedClientManager federatedClientManager = new FederatedClientManager(config.getFederationConfiguration()); FederatedClientManager federatedClientManager = new FederatedClientManager(config.getFederationConfiguration());
StoredMessageManager storedMessageManager = new StoredMessageManager(storedMessages); StoredMessageManager storedMessageManager = new StoredMessageManager(storedMessages);
RateLimiters rateLimiters = new RateLimiters(config.getLimitsConfiguration(), memcachedClient); RateLimiters rateLimiters = new RateLimiters(config.getLimitsConfiguration(), memcachedClient);
@ -126,8 +124,8 @@ public class WhisperServerService extends Service<WhisperServerConfiguration> {
environment.addProvider(new MultiBasicAuthProvider<>(new FederatedPeerAuthenticator(config.getFederationConfiguration()), environment.addProvider(new MultiBasicAuthProvider<>(new FederatedPeerAuthenticator(config.getFederationConfiguration()),
FederatedPeer.class, FederatedPeer.class,
accountAuthenticator, deviceAuthenticator,
Account.class, "WhisperServer")); Device.class, "WhisperServer"));
environment.addResource(new AccountController(pendingAccountsManager, accountsManager, rateLimiters, smsSender)); environment.addResource(new AccountController(pendingAccountsManager, accountsManager, rateLimiters, smsSender));
environment.addResource(new DeviceController(pendingDevicesManager, accountsManager, rateLimiters)); environment.addResource(new DeviceController(pendingDevicesManager, accountsManager, rateLimiters));
@ -136,7 +134,7 @@ public class WhisperServerService extends Service<WhisperServerConfiguration> {
environment.addResource(new KeysController(rateLimiters, keys, accountsManager, federatedClientManager)); environment.addResource(new KeysController(rateLimiters, keys, accountsManager, federatedClientManager));
environment.addResource(new FederationController(keys, accountsManager, pushSender, urlSigner)); environment.addResource(new FederationController(keys, accountsManager, pushSender, urlSigner));
environment.addServlet(new MessageController(rateLimiters, accountAuthenticator, environment.addServlet(new MessageController(rateLimiters, deviceAuthenticator,
pushSender, federatedClientManager), pushSender, federatedClientManager),
MessageController.PATH); MessageController.PATH);

View File

@ -1,74 +0,0 @@
/**
* Copyright (C) 2013 Open WhisperSystems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whispersystems.textsecuregcm.auth;
import com.google.common.base.Optional;
import com.yammer.dropwizard.auth.AuthenticationException;
import com.yammer.dropwizard.auth.Authenticator;
import com.yammer.dropwizard.auth.basic.BasicCredentials;
import com.yammer.metrics.Metrics;
import com.yammer.metrics.core.Meter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.AccountsManager;
import java.util.concurrent.TimeUnit;
public class AccountAuthenticator implements Authenticator<BasicCredentials, Account> {
private final Meter authenticationFailedMeter = Metrics.newMeter(AccountAuthenticator.class,
"authentication", "failed",
TimeUnit.MINUTES);
private final Meter authenticationSucceededMeter = Metrics.newMeter(AccountAuthenticator.class,
"authentication", "succeeded",
TimeUnit.MINUTES);
private final Logger logger = LoggerFactory.getLogger(AccountAuthenticator.class);
private final AccountsManager accountsManager;
public AccountAuthenticator(AccountsManager accountsManager) {
this.accountsManager = accountsManager;
}
@Override
public Optional<Account> authenticate(BasicCredentials basicCredentials)
throws AuthenticationException
{
AuthorizationHeader authorizationHeader;
try {
authorizationHeader = AuthorizationHeader.fromUserAndPassword(basicCredentials.getUsername(), basicCredentials.getPassword());
} catch (InvalidAuthorizationHeaderException iahe) {
return Optional.absent();
}
Optional<Account> account = accountsManager.get(authorizationHeader.getNumber(), authorizationHeader.getDeviceId());
if (!account.isPresent()) {
return Optional.absent();
}
if (account.get().getAuthenticationCredentials().verify(basicCredentials.getPassword())) {
authenticationSucceededMeter.mark();
return account;
}
authenticationFailedMeter.mark();
return Optional.absent();
}
}

View File

@ -31,7 +31,7 @@ import org.whispersystems.textsecuregcm.entities.GcmRegistrationId;
import org.whispersystems.textsecuregcm.limits.RateLimiters; import org.whispersystems.textsecuregcm.limits.RateLimiters;
import org.whispersystems.textsecuregcm.sms.SmsSender; import org.whispersystems.textsecuregcm.sms.SmsSender;
import org.whispersystems.textsecuregcm.sms.TwilioSmsSender; import org.whispersystems.textsecuregcm.sms.TwilioSmsSender;
import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.PendingAccountsManager; import org.whispersystems.textsecuregcm.storage.PendingAccountsManager;
import org.whispersystems.textsecuregcm.util.Util; import org.whispersystems.textsecuregcm.util.Util;
@ -134,19 +134,19 @@ public class AccountController {
throw new WebApplicationException(Response.status(403).build()); throw new WebApplicationException(Response.status(403).build());
} }
Account account = new Account(); Device device = new Device();
account.setNumber(number); device.setNumber(number);
account.setAuthenticationCredentials(new AuthenticationCredentials(password)); device.setAuthenticationCredentials(new AuthenticationCredentials(password));
account.setSignalingKey(accountAttributes.getSignalingKey()); device.setSignalingKey(accountAttributes.getSignalingKey());
account.setSupportsSms(accountAttributes.getSupportsSms()); device.setSupportsSms(accountAttributes.getSupportsSms());
account.setFetchesMessages(accountAttributes.getFetchesMessages()); device.setFetchesMessages(accountAttributes.getFetchesMessages());
account.setDeviceId(0); device.setDeviceId(0);
accounts.createResetNumber(account); accounts.createResetNumber(device);
pendingAccounts.remove(number); pendingAccounts.remove(number);
logger.debug("Stored account..."); logger.debug("Stored device...");
} catch (InvalidAuthorizationHeaderException e) { } catch (InvalidAuthorizationHeaderException e) {
logger.info("Bad Authorization Header", e); logger.info("Bad Authorization Header", e);
throw new WebApplicationException(Response.status(401).build()); throw new WebApplicationException(Response.status(401).build());
@ -159,36 +159,36 @@ public class AccountController {
@PUT @PUT
@Path("/gcm/") @Path("/gcm/")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public void setGcmRegistrationId(@Auth Account account, @Valid GcmRegistrationId registrationId) { public void setGcmRegistrationId(@Auth Device device, @Valid GcmRegistrationId registrationId) {
account.setApnRegistrationId(null); device.setApnRegistrationId(null);
account.setGcmRegistrationId(registrationId.getGcmRegistrationId()); device.setGcmRegistrationId(registrationId.getGcmRegistrationId());
accounts.update(account); accounts.update(device);
} }
@Timed @Timed
@DELETE @DELETE
@Path("/gcm/") @Path("/gcm/")
public void deleteGcmRegistrationId(@Auth Account account) { public void deleteGcmRegistrationId(@Auth Device device) {
account.setGcmRegistrationId(null); device.setGcmRegistrationId(null);
accounts.update(account); accounts.update(device);
} }
@Timed @Timed
@PUT @PUT
@Path("/apn/") @Path("/apn/")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public void setApnRegistrationId(@Auth Account account, @Valid ApnRegistrationId registrationId) { public void setApnRegistrationId(@Auth Device device, @Valid ApnRegistrationId registrationId) {
account.setApnRegistrationId(registrationId.getApnRegistrationId()); device.setApnRegistrationId(registrationId.getApnRegistrationId());
account.setGcmRegistrationId(null); device.setGcmRegistrationId(null);
accounts.update(account); accounts.update(device);
} }
@Timed @Timed
@DELETE @DELETE
@Path("/apn/") @Path("/apn/")
public void deleteApnRegistrationId(@Auth Account account) { public void deleteApnRegistrationId(@Auth Device device) {
account.setApnRegistrationId(null); device.setApnRegistrationId(null);
accounts.update(account); accounts.update(device);
} }
@Timed @Timed

View File

@ -26,7 +26,7 @@ import org.whispersystems.textsecuregcm.entities.AttachmentUri;
import org.whispersystems.textsecuregcm.federation.FederatedClientManager; import org.whispersystems.textsecuregcm.federation.FederatedClientManager;
import org.whispersystems.textsecuregcm.federation.NoSuchPeerException; import org.whispersystems.textsecuregcm.federation.NoSuchPeerException;
import org.whispersystems.textsecuregcm.limits.RateLimiters; import org.whispersystems.textsecuregcm.limits.RateLimiters;
import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.util.Conversions; import org.whispersystems.textsecuregcm.util.Conversions;
import org.whispersystems.textsecuregcm.util.UrlSigner; import org.whispersystems.textsecuregcm.util.UrlSigner;
@ -38,7 +38,6 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.io.IOException; import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom; import java.security.SecureRandom;
@ -65,8 +64,8 @@ public class AttachmentController {
@Timed @Timed
@GET @GET
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public Response allocateAttachment(@Auth Account account) throws RateLimitExceededException { public Response allocateAttachment(@Auth Device device) throws RateLimitExceededException {
rateLimiters.getAttachmentLimiter().validate(account.getNumber()); rateLimiters.getAttachmentLimiter().validate(device.getNumber());
long attachmentId = generateAttachmentId(); long attachmentId = generateAttachmentId();
URL url = urlSigner.getPreSignedUrl(attachmentId, HttpMethod.PUT); URL url = urlSigner.getPreSignedUrl(attachmentId, HttpMethod.PUT);
@ -79,7 +78,7 @@ public class AttachmentController {
@GET @GET
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Path("/{attachmentId}") @Path("/{attachmentId}")
public Response redirectToAttachment(@Auth Account account, public Response redirectToAttachment(@Auth Device device,
@PathParam("attachmentId") long attachmentId, @PathParam("attachmentId") long attachmentId,
@QueryParam("relay") String relay) @QueryParam("relay") String relay)
{ {

View File

@ -27,7 +27,7 @@ import org.whispersystems.textsecuregcm.auth.AuthorizationHeader;
import org.whispersystems.textsecuregcm.auth.InvalidAuthorizationHeaderException; import org.whispersystems.textsecuregcm.auth.InvalidAuthorizationHeaderException;
import org.whispersystems.textsecuregcm.entities.AccountAttributes; import org.whispersystems.textsecuregcm.entities.AccountAttributes;
import org.whispersystems.textsecuregcm.limits.RateLimiters; import org.whispersystems.textsecuregcm.limits.RateLimiters;
import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.PendingDevicesManager; import org.whispersystems.textsecuregcm.storage.PendingDevicesManager;
import org.whispersystems.textsecuregcm.util.VerificationCode; import org.whispersystems.textsecuregcm.util.VerificationCode;
@ -66,14 +66,15 @@ public class DeviceController {
@Timed @Timed
@GET @GET
@Path("/provisioning_code")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public VerificationCode createDeviceToken(@Auth Account account) public VerificationCode createDeviceToken(@Auth Device device)
throws RateLimitExceededException throws RateLimitExceededException
{ {
rateLimiters.getVerifyLimiter().validate(account.getNumber()); //TODO: New limiter? rateLimiters.getVerifyLimiter().validate(device.getNumber()); //TODO: New limiter?
VerificationCode verificationCode = generateVerificationCode(); VerificationCode verificationCode = generateVerificationCode();
pendingDevices.store(account.getNumber(), verificationCode.getVerificationCode()); pendingDevices.store(device.getNumber(), verificationCode.getVerificationCode());
return verificationCode; return verificationCode;
} }
@ -88,7 +89,7 @@ public class DeviceController {
@Valid AccountAttributes accountAttributes) @Valid AccountAttributes accountAttributes)
throws RateLimitExceededException throws RateLimitExceededException
{ {
Account account; Device device;
try { try {
AuthorizationHeader header = AuthorizationHeader.fromFullHeader(authorizationHeader); AuthorizationHeader header = AuthorizationHeader.fromFullHeader(authorizationHeader);
String number = header.getNumber(); String number = header.getNumber();
@ -104,24 +105,24 @@ public class DeviceController {
throw new WebApplicationException(Response.status(403).build()); throw new WebApplicationException(Response.status(403).build());
} }
account = new Account(); device = new Device();
account.setNumber(number); device.setNumber(number);
account.setAuthenticationCredentials(new AuthenticationCredentials(password)); device.setAuthenticationCredentials(new AuthenticationCredentials(password));
account.setSignalingKey(accountAttributes.getSignalingKey()); device.setSignalingKey(accountAttributes.getSignalingKey());
account.setSupportsSms(accountAttributes.getSupportsSms()); device.setSupportsSms(accountAttributes.getSupportsSms());
account.setFetchesMessages(accountAttributes.getFetchesMessages()); device.setFetchesMessages(accountAttributes.getFetchesMessages());
accounts.createAccountOnExistingNumber(account); accounts.createAccountOnExistingNumber(device);
pendingDevices.remove(number); pendingDevices.remove(number);
logger.debug("Stored new device account..."); logger.debug("Stored new device device...");
} catch (InvalidAuthorizationHeaderException e) { } catch (InvalidAuthorizationHeaderException e) {
logger.info("Bad Authorization Header", e); logger.info("Bad Authorization Header", e);
throw new WebApplicationException(Response.status(401).build()); throw new WebApplicationException(Response.status(401).build());
} }
return account.getDeviceId(); return device.getDeviceId();
} }
@VisibleForTesting protected VerificationCode generateVerificationCode() { @VisibleForTesting protected VerificationCode generateVerificationCode() {

View File

@ -18,12 +18,11 @@ package org.whispersystems.textsecuregcm.controllers;
import com.google.common.base.Optional; import com.google.common.base.Optional;
import com.yammer.dropwizard.auth.Auth; import com.yammer.dropwizard.auth.Auth;
import com.yammer.metrics.annotation.Metered;
import com.yammer.metrics.annotation.Timed; import com.yammer.metrics.annotation.Timed;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.whispersystems.textsecuregcm.limits.RateLimiters; import org.whispersystems.textsecuregcm.limits.RateLimiters;
import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.entities.ClientContact; import org.whispersystems.textsecuregcm.entities.ClientContact;
import org.whispersystems.textsecuregcm.entities.ClientContactTokens; import org.whispersystems.textsecuregcm.entities.ClientContactTokens;
import org.whispersystems.textsecuregcm.entities.ClientContacts; import org.whispersystems.textsecuregcm.entities.ClientContacts;
@ -61,10 +60,10 @@ public class DirectoryController {
@GET @GET
@Path("/{token}") @Path("/{token}")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public Response getTokenPresence(@Auth Account account, @PathParam("token") String token) public Response getTokenPresence(@Auth Device device, @PathParam("token") String token)
throws RateLimitExceededException throws RateLimitExceededException
{ {
rateLimiters.getContactsLimiter().validate(account.getNumber()); rateLimiters.getContactsLimiter().validate(device.getNumber());
try { try {
Optional<ClientContact> contact = directory.get(Base64.decodeWithoutPadding(token)); Optional<ClientContact> contact = directory.get(Base64.decodeWithoutPadding(token));
@ -83,10 +82,10 @@ public class DirectoryController {
@Path("/tokens") @Path("/tokens")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public ClientContacts getContactIntersection(@Auth Account account, @Valid ClientContactTokens contacts) public ClientContacts getContactIntersection(@Auth Device device, @Valid ClientContactTokens contacts)
throws RateLimitExceededException throws RateLimitExceededException
{ {
rateLimiters.getContactsLimiter().validate(account.getNumber(), contacts.getContacts().size()); rateLimiters.getContactsLimiter().validate(device.getNumber(), contacts.getContacts().size());
try { try {
List<byte[]> tokens = new LinkedList<>(); List<byte[]> tokens = new LinkedList<>();

View File

@ -32,7 +32,7 @@ import org.whispersystems.textsecuregcm.entities.RelayMessage;
import org.whispersystems.textsecuregcm.entities.UnstructuredPreKeyList; import org.whispersystems.textsecuregcm.entities.UnstructuredPreKeyList;
import org.whispersystems.textsecuregcm.federation.FederatedPeer; import org.whispersystems.textsecuregcm.federation.FederatedPeer;
import org.whispersystems.textsecuregcm.push.PushSender; import org.whispersystems.textsecuregcm.push.PushSender;
import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.Keys; import org.whispersystems.textsecuregcm.storage.Keys;
import org.whispersystems.textsecuregcm.util.Pair; import org.whispersystems.textsecuregcm.util.Pair;
@ -124,7 +124,7 @@ public class FederationController {
deviceIds.second().add(message.getDestinationDeviceId()); deviceIds.second().add(message.getDestinationDeviceId());
} }
Map<Pair<String, Long>, Account> accountCache = new HashMap<>(); Map<Pair<String, Long>, Device> accountCache = new HashMap<>();
List<String> numbersMissingDevices = new LinkedList<>(); List<String> numbersMissingDevices = new LinkedList<>();
pushSender.fillLocalAccountsCache(destinations, accountCache, numbersMissingDevices); pushSender.fillLocalAccountsCache(destinations, accountCache, numbersMissingDevices);
@ -132,15 +132,15 @@ public class FederationController {
List<String> failure = new LinkedList<>(numbersMissingDevices); List<String> failure = new LinkedList<>(numbersMissingDevices);
for (RelayMessage message : messages) { for (RelayMessage message : messages) {
Account account = accountCache.get(new Pair<>(message.getDestination(), message.getDestinationDeviceId())); Device device = accountCache.get(new Pair<>(message.getDestination(), message.getDestinationDeviceId()));
if (account == null) if (device == null)
continue; continue;
OutgoingMessageSignal signal = OutgoingMessageSignal.parseFrom(message.getOutgoingMessageSignal()) OutgoingMessageSignal signal = OutgoingMessageSignal.parseFrom(message.getOutgoingMessageSignal())
.toBuilder() .toBuilder()
.setRelay(peer.getName()) .setRelay(peer.getName())
.build(); .build();
try { try {
pushSender.sendMessage(account, signal); pushSender.sendMessage(device, signal);
} catch (NoSuchUserException e) { } catch (NoSuchUserException e) {
logger.info("No such user", e); logger.info("No such user", e);
failure.add(message.getDestination()); failure.add(message.getDestination());
@ -169,14 +169,14 @@ public class FederationController {
public ClientContacts getUserTokens(@Auth FederatedPeer peer, public ClientContacts getUserTokens(@Auth FederatedPeer peer,
@PathParam("offset") int offset) @PathParam("offset") int offset)
{ {
List<Account> numberList = accounts.getAllMasterAccounts(offset, ACCOUNT_CHUNK_SIZE); List<Device> numberList = accounts.getAllMasterAccounts(offset, ACCOUNT_CHUNK_SIZE);
List<ClientContact> clientContacts = new LinkedList<>(); List<ClientContact> clientContacts = new LinkedList<>();
for (Account account : numberList) { for (Device device : numberList) {
byte[] token = Util.getContactToken(account.getNumber()); byte[] token = Util.getContactToken(device.getNumber());
ClientContact clientContact = new ClientContact(token, null, account.getSupportsSms()); ClientContact clientContact = new ClientContact(token, null, device.getSupportsSms());
if (!account.isActive()) if (!device.isActive())
clientContact.setInactive(true); clientContact.setInactive(true);
clientContacts.add(clientContact); clientContacts.add(clientContact);

View File

@ -27,7 +27,7 @@ import org.whispersystems.textsecuregcm.entities.UnstructuredPreKeyList;
import org.whispersystems.textsecuregcm.federation.FederatedClientManager; import org.whispersystems.textsecuregcm.federation.FederatedClientManager;
import org.whispersystems.textsecuregcm.federation.NoSuchPeerException; import org.whispersystems.textsecuregcm.federation.NoSuchPeerException;
import org.whispersystems.textsecuregcm.limits.RateLimiters; import org.whispersystems.textsecuregcm.limits.RateLimiters;
import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.Keys; import org.whispersystems.textsecuregcm.storage.Keys;
@ -66,13 +66,13 @@ public class KeysController {
@Timed @Timed
@PUT @PUT
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public void setKeys(@Auth Account account, @Valid PreKeyList preKeys) { public void setKeys(@Auth Device device, @Valid PreKeyList preKeys) {
keys.store(account.getNumber(), account.getDeviceId(), preKeys.getLastResortKey(), preKeys.getKeys()); keys.store(device.getNumber(), device.getDeviceId(), preKeys.getLastResortKey(), preKeys.getKeys());
} }
public List<PreKey> getKeys(Account account, String number, String relay) throws RateLimitExceededException private List<PreKey> getKeys(Device device, String number, String relay) throws RateLimitExceededException
{ {
rateLimiters.getPreKeysLimiter().validate(account.getNumber() + "__" + number); rateLimiters.getPreKeysLimiter().validate(device.getNumber() + "__" + number);
try { try {
UnstructuredPreKeyList keyList; UnstructuredPreKeyList keyList;
@ -95,15 +95,15 @@ public class KeysController {
@GET @GET
@Path("/{number}") @Path("/{number}")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public Response get(@Auth Account account, public Response get(@Auth Device device,
@PathParam("number") String number, @PathParam("number") String number,
@QueryParam("multikeys") Optional<String> multikey, @QueryParam("multikeys") Optional<String> multikey,
@QueryParam("relay") String relay) @QueryParam("relay") String relay)
throws RateLimitExceededException throws RateLimitExceededException
{ {
if (!multikey.isPresent()) if (!multikey.isPresent())
return Response.ok(getKeys(account, number, relay).get(0)).type(MediaType.APPLICATION_JSON).build(); return Response.ok(getKeys(device, number, relay).get(0)).type(MediaType.APPLICATION_JSON).build();
else else
return Response.ok(getKeys(account, number, relay)).type(MediaType.APPLICATION_JSON).build(); return Response.ok(getKeys(device, number, relay)).type(MediaType.APPLICATION_JSON).build();
} }
} }

View File

@ -28,7 +28,7 @@ import com.yammer.metrics.core.Timer;
import com.yammer.metrics.core.TimerContext; import com.yammer.metrics.core.TimerContext;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.whispersystems.textsecuregcm.auth.AccountAuthenticator; import org.whispersystems.textsecuregcm.auth.DeviceAuthenticator;
import org.whispersystems.textsecuregcm.auth.AuthorizationHeader; import org.whispersystems.textsecuregcm.auth.AuthorizationHeader;
import org.whispersystems.textsecuregcm.auth.InvalidAuthorizationHeaderException; import org.whispersystems.textsecuregcm.auth.InvalidAuthorizationHeaderException;
import org.whispersystems.textsecuregcm.entities.IncomingMessage; import org.whispersystems.textsecuregcm.entities.IncomingMessage;
@ -41,7 +41,7 @@ import org.whispersystems.textsecuregcm.federation.FederatedClientManager;
import org.whispersystems.textsecuregcm.federation.NoSuchPeerException; import org.whispersystems.textsecuregcm.federation.NoSuchPeerException;
import org.whispersystems.textsecuregcm.limits.RateLimiters; import org.whispersystems.textsecuregcm.limits.RateLimiters;
import org.whispersystems.textsecuregcm.push.PushSender; import org.whispersystems.textsecuregcm.push.PushSender;
import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.util.Base64; import org.whispersystems.textsecuregcm.util.Base64;
import org.whispersystems.textsecuregcm.util.IterablePair; import org.whispersystems.textsecuregcm.util.IterablePair;
import org.whispersystems.textsecuregcm.util.Pair; import org.whispersystems.textsecuregcm.util.Pair;
@ -74,19 +74,19 @@ public class MessageController extends HttpServlet {
private final Logger logger = LoggerFactory.getLogger(MessageController.class); private final Logger logger = LoggerFactory.getLogger(MessageController.class);
private final RateLimiters rateLimiters; private final RateLimiters rateLimiters;
private final AccountAuthenticator accountAuthenticator; private final DeviceAuthenticator deviceAuthenticator;
private final PushSender pushSender; private final PushSender pushSender;
private final FederatedClientManager federatedClientManager; private final FederatedClientManager federatedClientManager;
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
private final ExecutorService executor; private final ExecutorService executor;
public MessageController(RateLimiters rateLimiters, public MessageController(RateLimiters rateLimiters,
AccountAuthenticator accountAuthenticator, DeviceAuthenticator deviceAuthenticator,
PushSender pushSender, PushSender pushSender,
FederatedClientManager federatedClientManager) FederatedClientManager federatedClientManager)
{ {
this.rateLimiters = rateLimiters; this.rateLimiters = rateLimiters;
this.accountAuthenticator = accountAuthenticator; this.deviceAuthenticator = deviceAuthenticator;
this.pushSender = pushSender; this.pushSender = pushSender;
this.federatedClientManager = federatedClientManager; this.federatedClientManager = federatedClientManager;
this.objectMapper = new ObjectMapper(); this.objectMapper = new ObjectMapper();
@ -98,13 +98,13 @@ public class MessageController extends HttpServlet {
TimerContext timerContext = timer.time(); TimerContext timerContext = timer.time();
try { try {
Account sender = authenticate(req); Device sender = authenticate(req);
IncomingMessageList messages = parseIncomingMessages(req); IncomingMessageList messages = parseIncomingMessages(req);
rateLimiters.getMessagesLimiter().validate(sender.getNumber()); rateLimiters.getMessagesLimiter().validate(sender.getNumber());
Map<Pair<String, Long>, Account> accountCache = new HashMap<>(); Map<Pair<String, Long>, Device> accountCache = new HashMap<>();
List<String> numbersMissingDevices = new LinkedList<>(); List<String> numbersMissingDevices = new LinkedList<>();
List<IncomingMessage> incomingMessages = messages.getMessages(); List<IncomingMessage> incomingMessages = messages.getMessages();
@ -140,7 +140,7 @@ public class MessageController extends HttpServlet {
private void handleAsyncDelivery(final TimerContext timerContext, private void handleAsyncDelivery(final TimerContext timerContext,
final AsyncContext context, final AsyncContext context,
final IterablePair<IncomingMessage, OutgoingMessageSignal> listPair, final IterablePair<IncomingMessage, OutgoingMessageSignal> listPair,
final Map<Pair<String, Long>, Account> accountCache, final Map<Pair<String, Long>, Device> accountCache,
final List<String> numbersMissingDevices) final List<String> numbersMissingDevices)
{ {
executor.submit(new Runnable() { executor.submit(new Runnable() {
@ -223,7 +223,7 @@ public class MessageController extends HttpServlet {
@Nullable @Nullable
private List<OutgoingMessageSignal> getOutgoingMessageSignals(String sourceNumber, private List<OutgoingMessageSignal> getOutgoingMessageSignals(String sourceNumber,
List<IncomingMessage> incomingMessages, List<IncomingMessage> incomingMessages,
Map<Pair<String, Long>, Account> accountCache, Map<Pair<String, Long>, Device> accountCache,
List<String> numbersMissingDevices) List<String> numbersMissingDevices)
{ {
List<OutgoingMessageSignal> outgoingMessages = new LinkedList<>(); List<OutgoingMessageSignal> outgoingMessages = new LinkedList<>();
@ -310,13 +310,13 @@ public class MessageController extends HttpServlet {
return messages; return messages;
} }
private Account authenticate(HttpServletRequest request) throws AuthenticationException { private Device authenticate(HttpServletRequest request) throws AuthenticationException {
try { try {
AuthorizationHeader authorizationHeader = AuthorizationHeader.fromFullHeader(request.getHeader("Authorization")); AuthorizationHeader authorizationHeader = AuthorizationHeader.fromFullHeader(request.getHeader("Authorization"));
BasicCredentials credentials = new BasicCredentials(authorizationHeader.getNumber() + "." + authorizationHeader.getDeviceId(), BasicCredentials credentials = new BasicCredentials(authorizationHeader.getNumber() + "." + authorizationHeader.getDeviceId(),
authorizationHeader.getPassword() ); authorizationHeader.getPassword() );
Optional<Account> account = accountAuthenticator.authenticate(credentials); Optional<Device> account = deviceAuthenticator.authenticate(credentials);
if (account.isPresent()) return account.get(); if (account.isPresent()) return account.get();
else throw new AuthenticationException("Bad credentials"); else throw new AuthenticationException("Bad credentials");
@ -332,7 +332,7 @@ public class MessageController extends HttpServlet {
// @POST // @POST
// @Consumes(MediaType.APPLICATION_JSON) // @Consumes(MediaType.APPLICATION_JSON)
// @Produces(MediaType.APPLICATION_JSON) // @Produces(MediaType.APPLICATION_JSON)
// public MessageResponse sendMessage(@Auth Account sender, IncomingMessageList messages) // public MessageResponse sendMessage(@Auth Device sender, IncomingMessageList messages)
// throws IOException // throws IOException
// { // {
// List<String> success = new LinkedList<>(); // List<String> success = new LinkedList<>();

View File

@ -23,7 +23,7 @@ import org.whispersystems.textsecuregcm.configuration.GcmConfiguration;
import org.whispersystems.textsecuregcm.controllers.NoSuchUserException; import org.whispersystems.textsecuregcm.controllers.NoSuchUserException;
import org.whispersystems.textsecuregcm.entities.EncryptedOutgoingMessage; import org.whispersystems.textsecuregcm.entities.EncryptedOutgoingMessage;
import org.whispersystems.textsecuregcm.entities.MessageProtos; import org.whispersystems.textsecuregcm.entities.MessageProtos;
import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.DirectoryManager; import org.whispersystems.textsecuregcm.storage.DirectoryManager;
import org.whispersystems.textsecuregcm.storage.StoredMessageManager; import org.whispersystems.textsecuregcm.storage.StoredMessageManager;
@ -68,67 +68,67 @@ public class PushSender {
* @param accountCache Map from &lt;number, deviceId&gt; to account * @param accountCache Map from &lt;number, deviceId&gt; to account
* @param numbersMissingDevices list of numbers missing devices * @param numbersMissingDevices list of numbers missing devices
*/ */
public void fillLocalAccountsCache(Map<String, Pair<Boolean, Set<Long>>> destinations, Map<Pair<String, Long>, Account> accountCache, List<String> numbersMissingDevices) { public void fillLocalAccountsCache(Map<String, Pair<Boolean, Set<Long>>> destinations, Map<Pair<String, Long>, Device> accountCache, List<String> numbersMissingDevices) {
for (Map.Entry<String, Pair<Boolean, Set<Long>>> destination : destinations.entrySet()) { for (Map.Entry<String, Pair<Boolean, Set<Long>>> destination : destinations.entrySet()) {
if (destination.getValue().first()) { if (destination.getValue().first()) {
String number = destination.getKey(); String number = destination.getKey();
List<Account> accountList = accounts.getAllByNumber(number); List<Device> deviceList = accounts.getAllByNumber(number);
Set<Long> deviceIdsIncluded = destination.getValue().second(); Set<Long> deviceIdsIncluded = destination.getValue().second();
if (accountList.size() != deviceIdsIncluded.size()) if (deviceList.size() != deviceIdsIncluded.size())
numbersMissingDevices.add(number); numbersMissingDevices.add(number);
else { else {
for (Account account : accountList) { for (Device device : deviceList) {
if (!deviceIdsIncluded.contains(account.getDeviceId())) { if (!deviceIdsIncluded.contains(device.getDeviceId())) {
numbersMissingDevices.add(number); numbersMissingDevices.add(number);
break; break;
} }
} }
for (Account account : accountList) for (Device device : deviceList)
accountCache.put(new Pair<>(number, account.getDeviceId()), account); accountCache.put(new Pair<>(number, device.getDeviceId()), device);
} }
} }
} }
} }
public void sendMessage(Account account, MessageProtos.OutgoingMessageSignal outgoingMessage) public void sendMessage(Device device, MessageProtos.OutgoingMessageSignal outgoingMessage)
throws IOException, NoSuchUserException throws IOException, NoSuchUserException
{ {
String signalingKey = account.getSignalingKey(); String signalingKey = device.getSignalingKey();
EncryptedOutgoingMessage message = new EncryptedOutgoingMessage(outgoingMessage, signalingKey); EncryptedOutgoingMessage message = new EncryptedOutgoingMessage(outgoingMessage, signalingKey);
if (account.getGcmRegistrationId() != null) sendGcmMessage(account, message); if (device.getGcmRegistrationId() != null) sendGcmMessage(device, message);
else if (account.getApnRegistrationId() != null) sendApnMessage(account, message); else if (device.getApnRegistrationId() != null) sendApnMessage(device, message);
else if (account.getFetchesMessages()) storeFetchedMessage(account, message); else if (device.getFetchesMessages()) storeFetchedMessage(device, message);
else throw new NoSuchUserException("No push identifier!"); else throw new NoSuchUserException("No push identifier!");
} }
private void sendGcmMessage(Account account, EncryptedOutgoingMessage outgoingMessage) private void sendGcmMessage(Device device, EncryptedOutgoingMessage outgoingMessage)
throws IOException, NoSuchUserException throws IOException, NoSuchUserException
{ {
try { try {
String canonicalId = gcmSender.sendMessage(account.getGcmRegistrationId(), String canonicalId = gcmSender.sendMessage(device.getGcmRegistrationId(),
outgoingMessage); outgoingMessage);
if (canonicalId != null) { if (canonicalId != null) {
account.setGcmRegistrationId(canonicalId); device.setGcmRegistrationId(canonicalId);
accounts.update(account); accounts.update(device);
} }
} catch (NoSuchUserException e) { } catch (NoSuchUserException e) {
logger.debug("No Such User", e); logger.debug("No Such User", e);
account.setGcmRegistrationId(null); device.setGcmRegistrationId(null);
accounts.update(account); accounts.update(device);
throw new NoSuchUserException("User no longer exists in GCM."); throw new NoSuchUserException("User no longer exists in GCM.");
} }
} }
private void sendApnMessage(Account account, EncryptedOutgoingMessage outgoingMessage) private void sendApnMessage(Device device, EncryptedOutgoingMessage outgoingMessage)
throws IOException throws IOException
{ {
apnSender.sendMessage(account.getApnRegistrationId(), outgoingMessage); apnSender.sendMessage(device.getApnRegistrationId(), outgoingMessage);
} }
private void storeFetchedMessage(Account account, EncryptedOutgoingMessage outgoingMessage) throws IOException { private void storeFetchedMessage(Device device, EncryptedOutgoingMessage outgoingMessage) throws IOException {
storedMessageManager.storeMessage(account, outgoingMessage); storedMessageManager.storeMessage(device, outgoingMessage);
} }
} }

View File

@ -58,15 +58,15 @@ public abstract class Accounts {
GCM_ID + ", " + APN_ID + ", " + SUPPORTS_SMS + ") " + GCM_ID + ", " + APN_ID + ", " + SUPPORTS_SMS + ") " +
"VALUES (:number, :device_id, :auth_token, :salt, :signaling_key, :fetches_messages, :gcm_id, :apn_id, :supports_sms)") "VALUES (:number, :device_id, :auth_token, :salt, :signaling_key, :fetches_messages, :gcm_id, :apn_id, :supports_sms)")
@GetGeneratedKeys @GetGeneratedKeys
abstract long insertStep(@AccountBinder Account account); abstract long insertStep(@AccountBinder Device device);
@SqlQuery("SELECT " + DEVICE_ID + " FROM accounts WHERE " + NUMBER + " = :number ORDER BY " + DEVICE_ID + " DESC LIMIT 1 FOR UPDATE") @SqlQuery("SELECT " + DEVICE_ID + " FROM accounts WHERE " + NUMBER + " = :number ORDER BY " + DEVICE_ID + " DESC LIMIT 1 FOR UPDATE")
abstract long getHighestDeviceId(@Bind("number") String number); abstract long getHighestDeviceId(@Bind("number") String number);
@Transaction(TransactionIsolationLevel.SERIALIZABLE) @Transaction(TransactionIsolationLevel.SERIALIZABLE)
public long insert(@AccountBinder Account account) { public long insert(@AccountBinder Device device) {
account.setDeviceId(getHighestDeviceId(account.getNumber()) + 1); device.setDeviceId(getHighestDeviceId(device.getNumber()) + 1);
return insertStep(account); return insertStep(device);
} }
@SqlUpdate("DELETE FROM accounts WHERE " + NUMBER + " = :number RETURNING id") @SqlUpdate("DELETE FROM accounts WHERE " + NUMBER + " = :number RETURNING id")
@ -76,41 +76,41 @@ public abstract class Accounts {
SIGNALING_KEY + " = :signaling_key, " + GCM_ID + " = :gcm_id, " + APN_ID + " = :apn_id, " + SIGNALING_KEY + " = :signaling_key, " + GCM_ID + " = :gcm_id, " + APN_ID + " = :apn_id, " +
FETCHES_MESSAGES + " = :fetches_messages, " + SUPPORTS_SMS + " = :supports_sms " + FETCHES_MESSAGES + " = :fetches_messages, " + SUPPORTS_SMS + " = :supports_sms " +
"WHERE " + NUMBER + " = :number AND " + DEVICE_ID + " = :device_id") "WHERE " + NUMBER + " = :number AND " + DEVICE_ID + " = :device_id")
abstract void update(@AccountBinder Account account); abstract void update(@AccountBinder Device device);
@Mapper(AccountMapper.class) @Mapper(AccountMapper.class)
@SqlQuery("SELECT * FROM accounts WHERE " + NUMBER + " = :number AND " + DEVICE_ID + " = :device_id") @SqlQuery("SELECT * FROM accounts WHERE " + NUMBER + " = :number AND " + DEVICE_ID + " = :device_id")
abstract Account get(@Bind("number") String number, @Bind("device_id") long deviceId); abstract Device get(@Bind("number") String number, @Bind("device_id") long deviceId);
@SqlQuery("SELECT COUNT(DISTINCT " + NUMBER + ") from accounts") @SqlQuery("SELECT COUNT(DISTINCT " + NUMBER + ") from accounts")
abstract long getNumberCount(); abstract long getNumberCount();
@Mapper(AccountMapper.class) @Mapper(AccountMapper.class)
@SqlQuery("SELECT * FROM accounts WHERE " + DEVICE_ID + " = 1 OFFSET :offset LIMIT :limit") @SqlQuery("SELECT * FROM accounts WHERE " + DEVICE_ID + " = 1 OFFSET :offset LIMIT :limit")
abstract List<Account> getAllFirstAccounts(@Bind("offset") int offset, @Bind("limit") int length); abstract List<Device> getAllFirstAccounts(@Bind("offset") int offset, @Bind("limit") int length);
@Mapper(AccountMapper.class) @Mapper(AccountMapper.class)
@SqlQuery("SELECT * FROM accounts WHERE " + DEVICE_ID + " = 1") @SqlQuery("SELECT * FROM accounts WHERE " + DEVICE_ID + " = 1")
public abstract Iterator<Account> getAllFirstAccounts(); public abstract Iterator<Device> getAllFirstAccounts();
@Mapper(AccountMapper.class) @Mapper(AccountMapper.class)
@SqlQuery("SELECT * FROM accounts WHERE " + NUMBER + " = :number") @SqlQuery("SELECT * FROM accounts WHERE " + NUMBER + " = :number")
public abstract List<Account> getAllByNumber(@Bind("number") String number); public abstract List<Device> getAllByNumber(@Bind("number") String number);
@Transaction(TransactionIsolationLevel.SERIALIZABLE) @Transaction(TransactionIsolationLevel.SERIALIZABLE)
public long insertClearingNumber(Account account) { public long insertClearingNumber(Device device) {
removeAccountsByNumber(account.getNumber()); removeAccountsByNumber(device.getNumber());
account.setDeviceId(getHighestDeviceId(account.getNumber()) + 1); device.setDeviceId(getHighestDeviceId(device.getNumber()) + 1);
return insertStep(account); return insertStep(device);
} }
public static class AccountMapper implements ResultSetMapper<Account> { public static class AccountMapper implements ResultSetMapper<Device> {
@Override @Override
public Account map(int i, ResultSet resultSet, StatementContext statementContext) public Device map(int i, ResultSet resultSet, StatementContext statementContext)
throws SQLException throws SQLException
{ {
return new Account(resultSet.getLong(ID), resultSet.getString(NUMBER), resultSet.getLong(DEVICE_ID), return new Device(resultSet.getLong(ID), resultSet.getString(NUMBER), resultSet.getLong(DEVICE_ID),
resultSet.getString(AUTH_TOKEN), resultSet.getString(SALT), resultSet.getString(AUTH_TOKEN), resultSet.getString(SALT),
resultSet.getString(SIGNALING_KEY), resultSet.getString(GCM_ID), resultSet.getString(SIGNALING_KEY), resultSet.getString(GCM_ID),
resultSet.getString(APN_ID), resultSet.getString(APN_ID),
@ -125,23 +125,23 @@ public abstract class Accounts {
public static class AccountBinderFactory implements BinderFactory { public static class AccountBinderFactory implements BinderFactory {
@Override @Override
public Binder build(Annotation annotation) { public Binder build(Annotation annotation) {
return new Binder<AccountBinder, Account>() { return new Binder<AccountBinder, Device>() {
@Override @Override
public void bind(SQLStatement<?> sql, public void bind(SQLStatement<?> sql,
AccountBinder accountBinder, AccountBinder accountBinder,
Account account) Device device)
{ {
sql.bind(ID, account.getId()); sql.bind(ID, device.getId());
sql.bind(NUMBER, account.getNumber()); sql.bind(NUMBER, device.getNumber());
sql.bind(DEVICE_ID, account.getDeviceId()); sql.bind(DEVICE_ID, device.getDeviceId());
sql.bind(AUTH_TOKEN, account.getAuthenticationCredentials() sql.bind(AUTH_TOKEN, device.getAuthenticationCredentials()
.getHashedAuthenticationToken()); .getHashedAuthenticationToken());
sql.bind(SALT, account.getAuthenticationCredentials().getSalt()); sql.bind(SALT, device.getAuthenticationCredentials().getSalt());
sql.bind(SIGNALING_KEY, account.getSignalingKey()); sql.bind(SIGNALING_KEY, device.getSignalingKey());
sql.bind(GCM_ID, account.getGcmRegistrationId()); sql.bind(GCM_ID, device.getGcmRegistrationId());
sql.bind(APN_ID, account.getApnRegistrationId()); sql.bind(APN_ID, device.getApnRegistrationId());
sql.bind(SUPPORTS_SMS, account.getSupportsSms() ? 1 : 0); sql.bind(SUPPORTS_SMS, device.getSupportsSms() ? 1 : 0);
sql.bind(FETCHES_MESSAGES, account.getFetchesMessages() ? 1 : 0); sql.bind(FETCHES_MESSAGES, device.getFetchesMessages() ? 1 : 0);
} }
}; };
} }

View File

@ -44,84 +44,84 @@ public class AccountsManager {
return accounts.getNumberCount(); return accounts.getNumberCount();
} }
public List<Account> getAllMasterAccounts(int offset, int length) { public List<Device> getAllMasterAccounts(int offset, int length) {
return accounts.getAllFirstAccounts(offset, length); return accounts.getAllFirstAccounts(offset, length);
} }
public Iterator<Account> getAllMasterAccounts() { public Iterator<Device> getAllMasterAccounts() {
return accounts.getAllFirstAccounts(); return accounts.getAllFirstAccounts();
} }
/** Creates a new Account and NumberData, clearing all existing accounts/data on the given number */ /** Creates a new Device and NumberData, clearing all existing accounts/data on the given number */
public void createResetNumber(Account account) { public void createResetNumber(Device device) {
long id = accounts.insertClearingNumber(account); long id = accounts.insertClearingNumber(device);
account.setId(id); device.setId(id);
if (memcachedClient != null) { if (memcachedClient != null) {
memcachedClient.set(getKey(account.getNumber(), account.getDeviceId()), 0, account); memcachedClient.set(getKey(device.getNumber(), device.getDeviceId()), 0, device);
} }
updateDirectory(account); updateDirectory(device);
} }
/** Creates a new Account for an existing NumberData (setting the deviceId) */ /** Creates a new Device for an existing NumberData (setting the deviceId) */
public void createAccountOnExistingNumber(Account account) { public void createAccountOnExistingNumber(Device device) {
long id = accounts.insert(account); long id = accounts.insert(device);
account.setId(id); device.setId(id);
if (memcachedClient != null) { if (memcachedClient != null) {
memcachedClient.set(getKey(account.getNumber(), account.getDeviceId()), 0, account); memcachedClient.set(getKey(device.getNumber(), device.getDeviceId()), 0, device);
} }
updateDirectory(account); updateDirectory(device);
} }
public void update(Account account) { public void update(Device device) {
if (memcachedClient != null) { if (memcachedClient != null) {
memcachedClient.set(getKey(account.getNumber(), account.getDeviceId()), 0, account); memcachedClient.set(getKey(device.getNumber(), device.getDeviceId()), 0, device);
} }
accounts.update(account); accounts.update(device);
updateDirectory(account); updateDirectory(device);
} }
public Optional<Account> get(String number, long deviceId) { public Optional<Device> get(String number, long deviceId) {
Account account = null; Device device = null;
if (memcachedClient != null) { if (memcachedClient != null) {
account = (Account)memcachedClient.get(getKey(number, deviceId)); device = (Device)memcachedClient.get(getKey(number, deviceId));
} }
if (account == null) { if (device == null) {
account = accounts.get(number, deviceId); device = accounts.get(number, deviceId);
if (account != null && memcachedClient != null) { if (device != null && memcachedClient != null) {
memcachedClient.set(getKey(number, deviceId), 0, account); memcachedClient.set(getKey(number, deviceId), 0, device);
} }
} }
if (account != null) return Optional.of(account); if (device != null) return Optional.of(device);
else return Optional.absent(); else return Optional.absent();
} }
public List<Account> getAllByNumber(String number) { public List<Device> getAllByNumber(String number) {
return accounts.getAllByNumber(number); return accounts.getAllByNumber(number);
} }
private void updateDirectory(Account account) { private void updateDirectory(Device device) {
if (account.getDeviceId() != 1) if (device.getDeviceId() != 1)
return; return;
if (account.isActive()) { if (device.isActive()) {
byte[] token = Util.getContactToken(account.getNumber()); byte[] token = Util.getContactToken(device.getNumber());
ClientContact clientContact = new ClientContact(token, null, account.getSupportsSms()); ClientContact clientContact = new ClientContact(token, null, device.getSupportsSms());
directory.add(clientContact); directory.add(clientContact);
} else { } else {
directory.remove(account.getNumber()); directory.remove(device.getNumber());
} }
} }
private String getKey(String number, long accountId) { private String getKey(String number, long accountId) {
return Account.class.getSimpleName() + Account.MEMCACHE_VERION + number + accountId; return Device.class.getSimpleName() + Device.MEMCACHE_VERION + number + accountId;
} }
} }

View File

@ -22,7 +22,7 @@ import org.whispersystems.textsecuregcm.util.Util;
import java.io.Serializable; import java.io.Serializable;
public class Account implements Serializable { public class Device implements Serializable {
public static final int MEMCACHE_VERION = 1; public static final int MEMCACHE_VERION = 1;
@ -42,11 +42,11 @@ public class Account implements Serializable {
private boolean supportsSms; private boolean supportsSms;
private boolean fetchesMessages; private boolean fetchesMessages;
public Account() {} public Device() {}
public Account(long id, String number, long deviceId, String hashedAuthenticationToken, String salt, public Device(long id, String number, long deviceId, String hashedAuthenticationToken, String salt,
String signalingKey, String gcmRegistrationId, String apnRegistrationId, String signalingKey, String gcmRegistrationId, String apnRegistrationId,
boolean supportsSms, boolean fetchesMessages) boolean supportsSms, boolean fetchesMessages)
{ {
this.id = id; this.id = id;
this.number = number; this.number = number;

View File

@ -79,10 +79,10 @@ public abstract class Keys {
} }
@Transaction(TransactionIsolationLevel.SERIALIZABLE) @Transaction(TransactionIsolationLevel.SERIALIZABLE)
public UnstructuredPreKeyList get(String number, List<Account> accounts) { public UnstructuredPreKeyList get(String number, List<Device> devices) {
List<PreKey> preKeys = new LinkedList<>(); List<PreKey> preKeys = new LinkedList<>();
for (Account account : accounts) { for (Device device : devices) {
PreKey preKey = retrieveFirst(number, account.getDeviceId()); PreKey preKey = retrieveFirst(number, device.getDeviceId());
if (preKey != null) if (preKey != null)
preKeys.add(preKey); preKeys.add(preKey);
} }

View File

@ -27,11 +27,11 @@ public class StoredMessageManager {
this.storedMessages = storedMessages; this.storedMessages = storedMessages;
} }
public void storeMessage(Account account, EncryptedOutgoingMessage outgoingMessage) throws IOException { public void storeMessage(Device device, EncryptedOutgoingMessage outgoingMessage) throws IOException {
storedMessages.insert(account.getId(), outgoingMessage.serialize()); storedMessages.insert(device.getId(), outgoingMessage.serialize());
} }
public List<String> getStoredMessage(Account account) { public List<String> getStoredMessage(Device device) {
return storedMessages.getMessagesForAccountId(account.getId()); return storedMessages.getMessagesForAccountId(device.getId());
} }
} }

View File

@ -22,7 +22,7 @@ import org.slf4j.LoggerFactory;
import org.whispersystems.textsecuregcm.entities.ClientContact; import org.whispersystems.textsecuregcm.entities.ClientContact;
import org.whispersystems.textsecuregcm.federation.FederatedClient; import org.whispersystems.textsecuregcm.federation.FederatedClient;
import org.whispersystems.textsecuregcm.federation.FederatedClientManager; import org.whispersystems.textsecuregcm.federation.FederatedClientManager;
import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.DirectoryManager; import org.whispersystems.textsecuregcm.storage.DirectoryManager;
import org.whispersystems.textsecuregcm.storage.DirectoryManager.BatchOperationHandle; import org.whispersystems.textsecuregcm.storage.DirectoryManager.BatchOperationHandle;
@ -53,22 +53,22 @@ public class DirectoryUpdater {
BatchOperationHandle batchOperation = directory.startBatchOperation(); BatchOperationHandle batchOperation = directory.startBatchOperation();
try { try {
Iterator<Account> accounts = accountsManager.getAllMasterAccounts(); Iterator<Device> accounts = accountsManager.getAllMasterAccounts();
if (accounts == null) if (accounts == null)
return; return;
while (accounts.hasNext()) { while (accounts.hasNext()) {
Account account = accounts.next(); Device device = accounts.next();
if (account.isActive()) { if (device.isActive()) {
byte[] token = Util.getContactToken(account.getNumber()); byte[] token = Util.getContactToken(device.getNumber());
ClientContact clientContact = new ClientContact(token, null, account.getSupportsSms()); ClientContact clientContact = new ClientContact(token, null, device.getSupportsSms());
directory.add(batchOperation, clientContact); directory.add(batchOperation, clientContact);
logger.debug("Adding local token: " + Base64.encodeBytesWithoutPadding(token)); logger.debug("Adding local token: " + Base64.encodeBytesWithoutPadding(token));
} else { } else {
directory.remove(batchOperation, account.getNumber()); directory.remove(batchOperation, device.getNumber());
} }
} }
} finally { } finally {

View File

@ -11,15 +11,12 @@ import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer; import org.mockito.stubbing.Answer;
import org.whispersystems.textsecuregcm.controllers.AccountController; import org.whispersystems.textsecuregcm.controllers.AccountController;
import org.whispersystems.textsecuregcm.controllers.DeviceController;
import org.whispersystems.textsecuregcm.entities.AccountAttributes;
import org.whispersystems.textsecuregcm.limits.RateLimiter; import org.whispersystems.textsecuregcm.limits.RateLimiter;
import org.whispersystems.textsecuregcm.limits.RateLimiters; import org.whispersystems.textsecuregcm.limits.RateLimiters;
import org.whispersystems.textsecuregcm.sms.SmsSender; import org.whispersystems.textsecuregcm.sms.SmsSender;
import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.PendingAccountsManager; import org.whispersystems.textsecuregcm.storage.PendingAccountsManager;
import org.whispersystems.textsecuregcm.storage.PendingDevicesManager;
import org.whispersystems.textsecuregcm.tests.util.AuthHelper; import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
import org.whispersystems.textsecuregcm.util.VerificationCode; import org.whispersystems.textsecuregcm.util.VerificationCode;
@ -80,10 +77,10 @@ public class AccountControllerTest extends ResourceTest {
Mockito.doAnswer(new Answer() { Mockito.doAnswer(new Answer() {
@Override @Override
public Object answer(InvocationOnMock invocation) throws Throwable { public Object answer(InvocationOnMock invocation) throws Throwable {
((Account)invocation.getArguments()[0]).setDeviceId(2); ((Device)invocation.getArguments()[0]).setDeviceId(2);
return null; return null;
} }
}).when(accountsManager).createAccountOnExistingNumber(any(Account.class)); }).when(accountsManager).createAccountOnExistingNumber(any(Device.class));
addResource(new DumbVerificationAccountController(pendingAccountsManager, accountsManager, rateLimiters, smsSender)); addResource(new DumbVerificationAccountController(pendingAccountsManager, accountsManager, rateLimiters, smsSender));
} }
@ -110,7 +107,7 @@ public class AccountControllerTest extends ResourceTest {
assertThat(response.getStatus()).isEqualTo(204); assertThat(response.getStatus()).isEqualTo(204);
verify(accountsManager).createResetNumber(isA(Account.class)); verify(accountsManager).createResetNumber(isA(Device.class));
ArgumentCaptor<String> number = ArgumentCaptor.forClass(String.class); ArgumentCaptor<String> number = ArgumentCaptor.forClass(String.class);
verify(pendingAccountsManager).remove(number.capture()); verify(pendingAccountsManager).remove(number.capture());

View File

@ -27,7 +27,7 @@ import org.whispersystems.textsecuregcm.controllers.DeviceController;
import org.whispersystems.textsecuregcm.entities.AccountAttributes; import org.whispersystems.textsecuregcm.entities.AccountAttributes;
import org.whispersystems.textsecuregcm.limits.RateLimiter; import org.whispersystems.textsecuregcm.limits.RateLimiter;
import org.whispersystems.textsecuregcm.limits.RateLimiters; import org.whispersystems.textsecuregcm.limits.RateLimiters;
import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.PendingDevicesManager; import org.whispersystems.textsecuregcm.storage.PendingDevicesManager;
import org.whispersystems.textsecuregcm.tests.util.AuthHelper; import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
@ -75,17 +75,17 @@ public class DeviceControllerTest extends ResourceTest {
Mockito.doAnswer(new Answer() { Mockito.doAnswer(new Answer() {
@Override @Override
public Object answer(InvocationOnMock invocation) throws Throwable { public Object answer(InvocationOnMock invocation) throws Throwable {
((Account) invocation.getArguments()[0]).setDeviceId(2); ((Device) invocation.getArguments()[0]).setDeviceId(2);
return null; return null;
} }
}).when(accountsManager).createAccountOnExistingNumber(any(Account.class)); }).when(accountsManager).createAccountOnExistingNumber(any(Device.class));
addResource(new DumbVerificationDeviceController(pendingDevicesManager, accountsManager, rateLimiters)); addResource(new DumbVerificationDeviceController(pendingDevicesManager, accountsManager, rateLimiters));
} }
@Test @Test
public void validDeviceRegisterTest() throws Exception { public void validDeviceRegisterTest() throws Exception {
VerificationCode deviceCode = client().resource("/v1/devices/") VerificationCode deviceCode = client().resource("/v1/devices/provisioning_code")
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.get(VerificationCode.class); .get(VerificationCode.class);
@ -98,7 +98,7 @@ public class DeviceControllerTest extends ResourceTest {
.put(Long.class); .put(Long.class);
assertThat(deviceId).isNotEqualTo(AuthHelper.DEFAULT_DEVICE_ID); assertThat(deviceId).isNotEqualTo(AuthHelper.DEFAULT_DEVICE_ID);
ArgumentCaptor<Account> newAccount = ArgumentCaptor.forClass(Account.class); ArgumentCaptor<Device> newAccount = ArgumentCaptor.forClass(Device.class);
verify(accountsManager).createAccountOnExistingNumber(newAccount.capture()); verify(accountsManager).createAccountOnExistingNumber(newAccount.capture());
assertThat(deviceId).isEqualTo(newAccount.getValue().getDeviceId()); assertThat(deviceId).isEqualTo(newAccount.getValue().getDeviceId());

View File

@ -9,12 +9,11 @@ import org.whispersystems.textsecuregcm.entities.PreKey;
import org.whispersystems.textsecuregcm.entities.UnstructuredPreKeyList; import org.whispersystems.textsecuregcm.entities.UnstructuredPreKeyList;
import org.whispersystems.textsecuregcm.limits.RateLimiter; import org.whispersystems.textsecuregcm.limits.RateLimiter;
import org.whispersystems.textsecuregcm.limits.RateLimiters; import org.whispersystems.textsecuregcm.limits.RateLimiters;
import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.Keys; import org.whispersystems.textsecuregcm.storage.Keys;
import org.whispersystems.textsecuregcm.tests.util.AuthHelper; import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
import javax.jws.WebResult;
import java.util.Arrays; import java.util.Arrays;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -31,7 +30,7 @@ public class KeyControllerTest extends ResourceTest {
private final PreKey SAMPLE_KEY2 = new PreKey(2, EXISTS_NUMBER, 2, 5667, "test3", "test4", false); private final PreKey SAMPLE_KEY2 = new PreKey(2, EXISTS_NUMBER, 2, 5667, "test3", "test4", false);
private final Keys keys = mock(Keys.class); private final Keys keys = mock(Keys.class);
Account[] fakeAccount; Device[] fakeDevice;
@Override @Override
protected void setUpResources() { protected void setUpResources() {
@ -41,20 +40,20 @@ public class KeyControllerTest extends ResourceTest {
RateLimiter rateLimiter = mock(RateLimiter.class ); RateLimiter rateLimiter = mock(RateLimiter.class );
AccountsManager accounts = mock(AccountsManager.class); AccountsManager accounts = mock(AccountsManager.class);
fakeAccount = new Account[2]; fakeDevice = new Device[2];
fakeAccount[0] = mock(Account.class); fakeDevice[0] = mock(Device.class);
fakeAccount[1] = mock(Account.class); fakeDevice[1] = mock(Device.class);
when(rateLimiters.getPreKeysLimiter()).thenReturn(rateLimiter); when(rateLimiters.getPreKeysLimiter()).thenReturn(rateLimiter);
when(keys.get(eq(EXISTS_NUMBER), anyList())).thenReturn(new UnstructuredPreKeyList(Arrays.asList(SAMPLE_KEY, SAMPLE_KEY2))); when(keys.get(eq(EXISTS_NUMBER), anyList())).thenReturn(new UnstructuredPreKeyList(Arrays.asList(SAMPLE_KEY, SAMPLE_KEY2)));
when(keys.get(eq(NOT_EXISTS_NUMBER), anyList())).thenReturn(null); when(keys.get(eq(NOT_EXISTS_NUMBER), anyList())).thenReturn(null);
when(fakeAccount[0].getDeviceId()).thenReturn(AuthHelper.DEFAULT_DEVICE_ID); when(fakeDevice[0].getDeviceId()).thenReturn(AuthHelper.DEFAULT_DEVICE_ID);
when(fakeAccount[1].getDeviceId()).thenReturn((long) 2); when(fakeDevice[1].getDeviceId()).thenReturn((long) 2);
when(accounts.getAllByNumber(EXISTS_NUMBER)).thenReturn(Arrays.asList(fakeAccount[0], fakeAccount[1])); when(accounts.getAllByNumber(EXISTS_NUMBER)).thenReturn(Arrays.asList(fakeDevice[0], fakeDevice[1]));
when(accounts.getAllByNumber(NOT_EXISTS_NUMBER)).thenReturn(new LinkedList<Account>()); when(accounts.getAllByNumber(NOT_EXISTS_NUMBER)).thenReturn(new LinkedList<Device>());
addResource(new KeysController(rateLimiters, keys, accounts, null)); addResource(new KeysController(rateLimiters, keys, accounts, null));
} }
@ -72,7 +71,7 @@ public class KeyControllerTest extends ResourceTest {
assertThat(result.getId() == 0); assertThat(result.getId() == 0);
assertThat(result.getNumber() == null); assertThat(result.getNumber() == null);
verify(keys).get(eq(EXISTS_NUMBER), eq(Arrays.asList(fakeAccount))); verify(keys).get(eq(EXISTS_NUMBER), eq(Arrays.asList(fakeDevice)));
verifyNoMoreInteractions(keys); verifyNoMoreInteractions(keys);
List<PreKey> results = client().resource(String.format("/v1/keys/%s?multikeys", EXISTS_NUMBER)) List<PreKey> results = client().resource(String.format("/v1/keys/%s?multikeys", EXISTS_NUMBER))
@ -96,7 +95,7 @@ public class KeyControllerTest extends ResourceTest {
assertThat(result.getId() == 1); assertThat(result.getId() == 1);
assertThat(result.getNumber() == null); assertThat(result.getNumber() == null);
verify(keys, times(2)).get(eq(EXISTS_NUMBER), eq(Arrays.asList(fakeAccount[0], fakeAccount[1]))); verify(keys, times(2)).get(eq(EXISTS_NUMBER), eq(Arrays.asList(fakeDevice[0], fakeDevice[1])));
verifyNoMoreInteractions(keys); verifyNoMoreInteractions(keys);
} }
@ -108,7 +107,7 @@ public class KeyControllerTest extends ResourceTest {
assertThat(response.getClientResponseStatus().getStatusCode()).isEqualTo(404); assertThat(response.getClientResponseStatus().getStatusCode()).isEqualTo(404);
verify(keys).get(NOT_EXISTS_NUMBER, new LinkedList<Account>()); verify(keys).get(NOT_EXISTS_NUMBER, new LinkedList<Device>());
} }
@Test @Test

View File

@ -1,13 +1,13 @@
package org.whispersystems.textsecuregcm.tests.util; package org.whispersystems.textsecuregcm.tests.util;
import com.google.common.base.Optional; import com.google.common.base.Optional;
import org.whispersystems.textsecuregcm.auth.AccountAuthenticator; import org.whispersystems.textsecuregcm.auth.DeviceAuthenticator;
import org.whispersystems.textsecuregcm.auth.AuthenticationCredentials; import org.whispersystems.textsecuregcm.auth.AuthenticationCredentials;
import org.whispersystems.textsecuregcm.auth.FederatedPeerAuthenticator; import org.whispersystems.textsecuregcm.auth.FederatedPeerAuthenticator;
import org.whispersystems.textsecuregcm.auth.MultiBasicAuthProvider; import org.whispersystems.textsecuregcm.auth.MultiBasicAuthProvider;
import org.whispersystems.textsecuregcm.configuration.FederationConfiguration; import org.whispersystems.textsecuregcm.configuration.FederationConfiguration;
import org.whispersystems.textsecuregcm.federation.FederatedPeer; import org.whispersystems.textsecuregcm.federation.FederatedPeer;
import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.util.Base64; import org.whispersystems.textsecuregcm.util.Base64;
@ -23,19 +23,19 @@ public class AuthHelper {
public static final String INVVALID_NUMBER = "+14151111111"; public static final String INVVALID_NUMBER = "+14151111111";
public static final String INVALID_PASSWORD = "bar"; public static final String INVALID_PASSWORD = "bar";
public static MultiBasicAuthProvider<FederatedPeer, Account> getAuthenticator() { public static MultiBasicAuthProvider<FederatedPeer, Device> getAuthenticator() {
AccountsManager accounts = mock(AccountsManager.class); AccountsManager accounts = mock(AccountsManager.class);
Account account = mock(Account.class); Device device = mock(Device.class);
AuthenticationCredentials credentials = mock(AuthenticationCredentials.class); AuthenticationCredentials credentials = mock(AuthenticationCredentials.class);
when(credentials.verify("foo")).thenReturn(true); when(credentials.verify("foo")).thenReturn(true);
when(account.getAuthenticationCredentials()).thenReturn(credentials); when(device.getAuthenticationCredentials()).thenReturn(credentials);
when(accounts.get(VALID_NUMBER, DEFAULT_DEVICE_ID)).thenReturn(Optional.of(account)); when(accounts.get(VALID_NUMBER, DEFAULT_DEVICE_ID)).thenReturn(Optional.of(device));
return new MultiBasicAuthProvider<>(new FederatedPeerAuthenticator(new FederationConfiguration()), return new MultiBasicAuthProvider<>(new FederatedPeerAuthenticator(new FederationConfiguration()),
FederatedPeer.class, FederatedPeer.class,
new AccountAuthenticator(accounts), new DeviceAuthenticator(accounts),
Account.class, "WhisperServer"); Device.class, "WhisperServer");
} }
public static String getAuthHeader(String number, String password) { public static String getAuthHeader(String number, String password) {