Initial multi device support refactoring.

1) Store account data as a json type, which includes all
   devices in a single object.

2) Simplify message delivery logic.

3) Make federated calls a pass through to standard controllers.

4) Simplify key retrieval logic.
This commit is contained in:
Moxie Marlinspike
2014-01-18 23:45:07 -08:00
parent 6f9226dcf9
commit 74f71fd8a6
47 changed files with 961 additions and 1211 deletions

View File

@@ -24,51 +24,58 @@ 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.Device;
import org.whispersystems.textsecuregcm.storage.AccountsManager;
import java.util.concurrent.TimeUnit;
public class DeviceAuthenticator implements Authenticator<BasicCredentials, Device> {
public class AccountAuthenticator implements Authenticator<BasicCredentials, Account> {
private final Meter authenticationFailedMeter = Metrics.newMeter(DeviceAuthenticator.class,
private final Meter authenticationFailedMeter = Metrics.newMeter(AccountAuthenticator.class,
"authentication", "failed",
TimeUnit.MINUTES);
private final Meter authenticationSucceededMeter = Metrics.newMeter(DeviceAuthenticator.class,
private final Meter authenticationSucceededMeter = Metrics.newMeter(AccountAuthenticator.class,
"authentication", "succeeded",
TimeUnit.MINUTES);
private final Logger logger = LoggerFactory.getLogger(DeviceAuthenticator.class);
private final Logger logger = LoggerFactory.getLogger(AccountAuthenticator.class);
private final AccountsManager accountsManager;
public DeviceAuthenticator(AccountsManager accountsManager) {
public AccountAuthenticator(AccountsManager accountsManager) {
this.accountsManager = accountsManager;
}
@Override
public Optional<Device> authenticate(BasicCredentials basicCredentials)
public Optional<Account> authenticate(BasicCredentials basicCredentials)
throws AuthenticationException
{
AuthorizationHeader authorizationHeader;
try {
authorizationHeader = AuthorizationHeader.fromUserAndPassword(basicCredentials.getUsername(), basicCredentials.getPassword());
AuthorizationHeader authorizationHeader = AuthorizationHeader.fromUserAndPassword(basicCredentials.getUsername(), basicCredentials.getPassword());
Optional<Account> account = accountsManager.get(authorizationHeader.getNumber());
if (!account.isPresent()) {
return Optional.absent();
}
Optional<Device> device = account.get().getDevice(authorizationHeader.getDeviceId());
if (!device.isPresent()) {
return Optional.absent();
}
if (device.get().getAuthenticationCredentials().verify(basicCredentials.getPassword())) {
authenticationSucceededMeter.mark();
account.get().setAuthenticatedDevice(device.get());
return account;
}
authenticationFailedMeter.mark();
return Optional.absent();
} catch (InvalidAuthorizationHeaderException iahe) {
return Optional.absent();
}
Optional<Device> device = accountsManager.get(authorizationHeader.getNumber(), authorizationHeader.getDeviceId());
if (!device.isPresent()) {
return Optional.absent();
}
if (device.get().getAuthenticationCredentials().verify(basicCredentials.getPassword())) {
authenticationSucceededMeter.mark();
return device;
}
authenticationFailedMeter.mark();
return Optional.absent();
}
}