Skip to content

Commit

Permalink
Rename AuthenticatedAccount to AuthenticatedDevice
Browse files Browse the repository at this point in the history
  • Loading branch information
jon-signal committed Aug 14, 2024
1 parent 1ea9e38 commit 0075e94
Show file tree
Hide file tree
Showing 68 changed files with 285 additions and 292 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import java.util.ServiceLoader;
import java.util.Set;
import javax.ws.rs.Consumes;
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.AuthenticatedDevice;

/**
* One of the extension mechanisms of Swagger Core library (OpenAPI processor) is via custom implementations
Expand Down Expand Up @@ -62,11 +62,11 @@ public ResolvedParameter extractParameters(
if (annotations.stream().anyMatch(a -> a.annotationType().equals(Auth.class))) {
// this is the case of authenticated endpoint,
if (type instanceof SimpleType simpleType
&& simpleType.getRawClass().equals(AuthenticatedAccount.class)) {
&& simpleType.getRawClass().equals(AuthenticatedDevice.class)) {
return AUTHENTICATED_ACCOUNT;
}
if (type instanceof SimpleType simpleType
&& isOptionalOfType(simpleType, AuthenticatedAccount.class)) {
&& isOptionalOfType(simpleType, AuthenticatedDevice.class)) {
return OPTIONAL_AUTHENTICATED_ACCOUNT;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
import org.whispersystems.textsecuregcm.attachments.GcsAttachmentGenerator;
import org.whispersystems.textsecuregcm.attachments.TusAttachmentGenerator;
import org.whispersystems.textsecuregcm.auth.AccountAuthenticator;
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.AuthenticatedDevice;
import org.whispersystems.textsecuregcm.auth.CertificateGenerator;
import org.whispersystems.textsecuregcm.auth.CloudflareTurnCredentialsManager;
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialsGenerator;
Expand Down Expand Up @@ -974,8 +974,8 @@ protected void configureServer(final ServerBuilder<?> serverBuilder) {
config.getExternalRequestFilterConfiguration().paths().toArray(new String[]{}));
}

final AuthFilter<BasicCredentials, AuthenticatedAccount> accountAuthFilter =
new BasicCredentialAuthFilter.Builder<AuthenticatedAccount>()
final AuthFilter<BasicCredentials, AuthenticatedDevice> accountAuthFilter =
new BasicCredentialAuthFilter.Builder<AuthenticatedDevice>()
.setAuthenticator(accountAuthenticator)
.buildAuthFilter();

Expand All @@ -992,12 +992,12 @@ protected void configureServer(final ServerBuilder<?> serverBuilder) {
environment.jersey().register(new RequestStatisticsFilter(TrafficSource.HTTP));
environment.jersey().register(MultiRecipientMessageProvider.class);
environment.jersey().register(new AuthDynamicFeature(accountAuthFilter));
environment.jersey().register(new AuthValueFactoryProvider.Binder<>(AuthenticatedAccount.class));
environment.jersey().register(new AuthValueFactoryProvider.Binder<>(AuthenticatedDevice.class));
environment.jersey().register(new WebsocketRefreshApplicationEventListener(accountsManager, clientPresenceManager));
environment.jersey().register(new TimestampResponseFilter());

///
WebSocketEnvironment<AuthenticatedAccount> webSocketEnvironment = new WebSocketEnvironment<>(environment,
WebSocketEnvironment<AuthenticatedDevice> webSocketEnvironment = new WebSocketEnvironment<>(environment,
config.getWebSocketConfiguration(), Duration.ofMillis(90000));
webSocketEnvironment.jersey().register(new VirtualExecutorServiceProvider("managed-async-websocket-virtual-thread-"));
webSocketEnvironment.setAuthenticator(new WebSocketAccountAuthenticator(accountAuthenticator, new AccountPrincipalSupplier(accountsManager)));
Expand Down Expand Up @@ -1128,7 +1128,7 @@ protected void configureServer(final ServerBuilder<?> serverBuilder) {
webSocketEnvironment.jersey().register(controller);
}

WebSocketEnvironment<AuthenticatedAccount> provisioningEnvironment = new WebSocketEnvironment<>(environment,
WebSocketEnvironment<AuthenticatedDevice> provisioningEnvironment = new WebSocketEnvironment<>(environment,
webSocketEnvironment.getRequestLog(), Duration.ofMillis(60000));
provisioningEnvironment.jersey().register(new WebsocketRefreshApplicationEventListener(accountsManager, clientPresenceManager));
provisioningEnvironment.setConnectListener(new ProvisioningConnectListener(provisioningManager));
Expand All @@ -1144,11 +1144,11 @@ protected void configureServer(final ServerBuilder<?> serverBuilder) {

JettyWebSocketServletContainerInitializer.configure(environment.getApplicationContext(), null);

WebSocketResourceProviderFactory<AuthenticatedAccount> webSocketServlet = new WebSocketResourceProviderFactory<>(
webSocketEnvironment, AuthenticatedAccount.class, config.getWebSocketConfiguration(),
WebSocketResourceProviderFactory<AuthenticatedDevice> webSocketServlet = new WebSocketResourceProviderFactory<>(
webSocketEnvironment, AuthenticatedDevice.class, config.getWebSocketConfiguration(),
RemoteAddressFilter.REMOTE_ADDRESS_ATTRIBUTE_NAME);
WebSocketResourceProviderFactory<AuthenticatedAccount> provisioningServlet = new WebSocketResourceProviderFactory<>(
provisioningEnvironment, AuthenticatedAccount.class, config.getWebSocketConfiguration(),
WebSocketResourceProviderFactory<AuthenticatedDevice> provisioningServlet = new WebSocketResourceProviderFactory<>(
provisioningEnvironment, AuthenticatedDevice.class, config.getWebSocketConfiguration(),
RemoteAddressFilter.REMOTE_ADDRESS_ATTRIBUTE_NAME);

ServletRegistration.Dynamic websocket = environment.servlets().addServlet("WebSocket", webSocketServlet);
Expand All @@ -1169,8 +1169,8 @@ protected void configureServer(final ServerBuilder<?> serverBuilder) {
}

private void registerExceptionMappers(Environment environment,
WebSocketEnvironment<AuthenticatedAccount> webSocketEnvironment,
WebSocketEnvironment<AuthenticatedAccount> provisioningEnvironment) {
WebSocketEnvironment<AuthenticatedDevice> webSocketEnvironment,
WebSocketEnvironment<AuthenticatedDevice> provisioningEnvironment) {

List.of(
new LoggingUnhandledExceptionMapper(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import org.whispersystems.textsecuregcm.util.Pair;
import org.whispersystems.textsecuregcm.util.Util;

public class AccountAuthenticator implements Authenticator<BasicCredentials, AuthenticatedAccount> {
public class AccountAuthenticator implements Authenticator<BasicCredentials, AuthenticatedDevice> {

private static final String LEGACY_NAME_PREFIX = "org.whispersystems.textsecuregcm.auth.BaseAccountAuthenticator";

Expand Down Expand Up @@ -73,7 +73,7 @@ static Pair<String, Byte> getIdentifierAndDeviceId(final String basicUsername) {
}

@Override
public Optional<AuthenticatedAccount> authenticate(BasicCredentials basicCredentials) {
public Optional<AuthenticatedDevice> authenticate(BasicCredentials basicCredentials) {
boolean succeeded = false;
String failureReason = null;

Expand Down Expand Up @@ -112,7 +112,7 @@ public Optional<AuthenticatedAccount> authenticate(BasicCredentials basicCredent
device.get(),
SaltedTokenHash.generateFor(basicCredentials.getPassword())); // new credentials have current version
}
return Optional.of(new AuthenticatedAccount(authenticatedAccount, device.get()));
return Optional.of(new AuthenticatedDevice(authenticatedAccount, device.get()));
} else {
failureReason = "incorrectPassword";
return Optional.empty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@
package org.whispersystems.textsecuregcm.auth;

import java.security.Principal;
import java.util.function.Supplier;
import javax.security.auth.Subject;
import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.Device;

public class AuthenticatedAccount implements Principal, AccountAndAuthenticatedDeviceHolder {
public class AuthenticatedDevice implements Principal, AccountAndAuthenticatedDeviceHolder {

private final Account account;
private final Device device;

public AuthenticatedAccount(final Account account, final Device device) {
public AuthenticatedDevice(final Account account, final Device device) {
this.account = account;
this.device = device;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
* any active WebSocket connections for the account must be closed in order for clients to get a refreshed
* {@link io.dropwizard.auth.Auth} object with a current device list.
*
* @see AuthenticatedAccount
* @see AuthenticatedDevice
*/
public class LinkedDeviceRefreshRequirementProvider implements WebsocketRefreshRequirementProvider {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import javax.ws.rs.core.Response.Status;
import org.signal.libsignal.usernames.BaseUsernameException;
import org.whispersystems.textsecuregcm.auth.AccountAndAuthenticatedDeviceHolder;
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.AuthenticatedDevice;
import org.whispersystems.textsecuregcm.auth.SaltedTokenHash;
import org.whispersystems.textsecuregcm.auth.TurnToken;
import org.whispersystems.textsecuregcm.auth.TurnTokenGenerator;
Expand Down Expand Up @@ -99,7 +99,7 @@ public AccountController(
@GET
@Path("/turn/")
@Produces(MediaType.APPLICATION_JSON)
public TurnToken getTurnToken(@ReadOnly @Auth AuthenticatedAccount auth) throws RateLimitExceededException {
public TurnToken getTurnToken(@ReadOnly @Auth AuthenticatedDevice auth) throws RateLimitExceededException {
rateLimiters.getTurnLimiter().validate(auth.getAccount().getUuid());
return turnTokenGenerator.generate(auth.getAccount().getUuid());
}
Expand All @@ -108,7 +108,7 @@ public TurnToken getTurnToken(@ReadOnly @Auth AuthenticatedAccount auth) throws
@Path("/gcm/")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public void setGcmRegistrationId(@Mutable @Auth AuthenticatedAccount auth,
public void setGcmRegistrationId(@Mutable @Auth AuthenticatedDevice auth,
@NotNull @Valid GcmRegistrationId registrationId) {

final Account account = auth.getAccount();
Expand All @@ -128,7 +128,7 @@ public void setGcmRegistrationId(@Mutable @Auth AuthenticatedAccount auth,

@DELETE
@Path("/gcm/")
public void deleteGcmRegistrationId(@Mutable @Auth AuthenticatedAccount auth) {
public void deleteGcmRegistrationId(@Mutable @Auth AuthenticatedDevice auth) {
Account account = auth.getAccount();
Device device = auth.getAuthenticatedDevice();

Expand All @@ -143,7 +143,7 @@ public void deleteGcmRegistrationId(@Mutable @Auth AuthenticatedAccount auth) {
@Path("/apn/")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public void setApnRegistrationId(@Mutable @Auth AuthenticatedAccount auth,
public void setApnRegistrationId(@Mutable @Auth AuthenticatedDevice auth,
@NotNull @Valid ApnRegistrationId registrationId) {

final Account account = auth.getAccount();
Expand All @@ -161,7 +161,7 @@ public void setApnRegistrationId(@Mutable @Auth AuthenticatedAccount auth,

@DELETE
@Path("/apn/")
public void deleteApnRegistrationId(@Mutable @Auth AuthenticatedAccount auth) {
public void deleteApnRegistrationId(@Mutable @Auth AuthenticatedDevice auth) {
Account account = auth.getAccount();
Device device = auth.getAuthenticatedDevice();

Expand All @@ -180,7 +180,7 @@ public void deleteApnRegistrationId(@Mutable @Auth AuthenticatedAccount auth) {
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Path("/registration_lock")
public void setRegistrationLock(@Mutable @Auth AuthenticatedAccount auth, @NotNull @Valid RegistrationLock accountLock) {
public void setRegistrationLock(@Mutable @Auth AuthenticatedDevice auth, @NotNull @Valid RegistrationLock accountLock) {
SaltedTokenHash credentials = SaltedTokenHash.generateFor(accountLock.getRegistrationLock());

accounts.update(auth.getAccount(),
Expand All @@ -189,13 +189,13 @@ public void setRegistrationLock(@Mutable @Auth AuthenticatedAccount auth, @NotNu

@DELETE
@Path("/registration_lock")
public void removeRegistrationLock(@Mutable @Auth AuthenticatedAccount auth) {
public void removeRegistrationLock(@Mutable @Auth AuthenticatedDevice auth) {
accounts.update(auth.getAccount(), a -> a.setRegistrationLock(null, null));
}

@PUT
@Path("/name/")
public void setName(@Mutable @Auth AuthenticatedAccount auth, @NotNull @Valid DeviceName deviceName) {
public void setName(@Mutable @Auth AuthenticatedDevice auth, @NotNull @Valid DeviceName deviceName) {
Account account = auth.getAccount();
Device device = auth.getAuthenticatedDevice();
accounts.updateDevice(account, device.getId(), d -> d.setName(deviceName.getDeviceName()));
Expand All @@ -206,7 +206,7 @@ public void setName(@Mutable @Auth AuthenticatedAccount auth, @NotNull @Valid De
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public void setAccountAttributes(
@Mutable @Auth AuthenticatedAccount auth,
@Mutable @Auth AuthenticatedDevice auth,
@HeaderParam(HeaderUtils.X_SIGNAL_AGENT) String userAgent,
@NotNull @Valid AccountAttributes attributes) {
final Account account = auth.getAccount();
Expand Down Expand Up @@ -236,14 +236,14 @@ public void setAccountAttributes(
@Path("/me")
@Deprecated() // use whoami
@Produces(MediaType.APPLICATION_JSON)
public AccountIdentityResponse getMe(@ReadOnly @Auth AuthenticatedAccount auth) {
public AccountIdentityResponse getMe(@ReadOnly @Auth AuthenticatedDevice auth) {
return buildAccountIdentityResponse(auth);
}

@GET
@Path("/whoami")
@Produces(MediaType.APPLICATION_JSON)
public AccountIdentityResponse whoAmI(@ReadOnly @Auth AuthenticatedAccount auth) {
public AccountIdentityResponse whoAmI(@ReadOnly @Auth AuthenticatedDevice auth) {
return buildAccountIdentityResponse(auth);
}

Expand All @@ -266,7 +266,7 @@ private AccountIdentityResponse buildAccountIdentityResponse(AccountAndAuthentic
)
@ApiResponse(responseCode = "204", description = "Username successfully deleted.", useReturnTypeSchema = true)
@ApiResponse(responseCode = "401", description = "Account authentication check failed.")
public CompletableFuture<Response> deleteUsernameHash(@Mutable @Auth final AuthenticatedAccount auth) {
public CompletableFuture<Response> deleteUsernameHash(@Mutable @Auth final AuthenticatedDevice auth) {
return accounts.clearUsernameHash(auth.getAccount())
.thenApply(Util.ASYNC_EMPTY_RESPONSE);
}
Expand All @@ -288,7 +288,7 @@ public CompletableFuture<Response> deleteUsernameHash(@Mutable @Auth final Authe
@ApiResponse(responseCode = "422", description = "Invalid request format.")
@ApiResponse(responseCode = "429", description = "Ratelimited.")
public CompletableFuture<ReserveUsernameHashResponse> reserveUsernameHash(
@Mutable @Auth final AuthenticatedAccount auth,
@Mutable @Auth final AuthenticatedDevice auth,
@NotNull @Valid final ReserveUsernameHashRequest usernameRequest) throws RateLimitExceededException {

rateLimiters.getUsernameReserveLimiter().validate(auth.getAccount().getUuid());
Expand Down Expand Up @@ -328,7 +328,7 @@ public CompletableFuture<ReserveUsernameHashResponse> reserveUsernameHash(
@ApiResponse(responseCode = "422", description = "Invalid request format.")
@ApiResponse(responseCode = "429", description = "Ratelimited.")
public CompletableFuture<UsernameHashResponse> confirmUsernameHash(
@Mutable @Auth final AuthenticatedAccount auth,
@Mutable @Auth final AuthenticatedDevice auth,
@NotNull @Valid final ConfirmUsernameHashRequest confirmRequest) {

try {
Expand Down Expand Up @@ -373,7 +373,7 @@ public CompletableFuture<UsernameHashResponse> confirmUsernameHash(
@ApiResponse(responseCode = "400", description = "Request must not be authenticated.")
@ApiResponse(responseCode = "404", description = "Account not found for the given username.")
public CompletableFuture<AccountIdentifierResponse> lookupUsernameHash(
@ReadOnly @Auth final Optional<AuthenticatedAccount> maybeAuthenticatedAccount,
@ReadOnly @Auth final Optional<AuthenticatedDevice> maybeAuthenticatedAccount,
@PathParam("usernameHash") final String usernameHash) {

requireNotAuthenticated(maybeAuthenticatedAccount);
Expand Down Expand Up @@ -412,7 +412,7 @@ public CompletableFuture<AccountIdentifierResponse> lookupUsernameHash(
@ApiResponse(responseCode = "422", description = "Invalid request format.")
@ApiResponse(responseCode = "429", description = "Ratelimited.")
public UsernameLinkHandle updateUsernameLink(
@Mutable @Auth final AuthenticatedAccount auth,
@Mutable @Auth final AuthenticatedDevice auth,
@NotNull @Valid final EncryptedUsername encryptedUsername) throws RateLimitExceededException {
// check ratelimiter for username link operations
rateLimiters.forDescriptor(RateLimiters.For.USERNAME_LINK_OPERATION).validate(auth.getAccount().getUuid());
Expand Down Expand Up @@ -446,7 +446,7 @@ public UsernameLinkHandle updateUsernameLink(
@ApiResponse(responseCode = "204", description = "Username Link successfully deleted.", useReturnTypeSchema = true)
@ApiResponse(responseCode = "401", description = "Account authentication check failed.")
@ApiResponse(responseCode = "429", description = "Ratelimited.")
public void deleteUsernameLink(@Mutable @Auth final AuthenticatedAccount auth) throws RateLimitExceededException {
public void deleteUsernameLink(@Mutable @Auth final AuthenticatedDevice auth) throws RateLimitExceededException {
// check ratelimiter for username link operations
rateLimiters.forDescriptor(RateLimiters.For.USERNAME_LINK_OPERATION).validate(auth.getAccount().getUuid());
clearUsernameLink(auth.getAccount());
Expand All @@ -469,7 +469,7 @@ public void deleteUsernameLink(@Mutable @Auth final AuthenticatedAccount auth) t
@ApiResponse(responseCode = "422", description = "Invalid request format.")
@ApiResponse(responseCode = "429", description = "Ratelimited.")
public CompletableFuture<EncryptedUsername> lookupUsernameLink(
@ReadOnly @Auth final Optional<AuthenticatedAccount> maybeAuthenticatedAccount,
@ReadOnly @Auth final Optional<AuthenticatedDevice> maybeAuthenticatedAccount,
@PathParam("uuid") final UUID usernameLinkHandle) {

requireNotAuthenticated(maybeAuthenticatedAccount);
Expand All @@ -495,7 +495,7 @@ public CompletableFuture<EncryptedUsername> lookupUsernameLink(
@Path("/account/{identifier}")
@RateLimitedByIp(RateLimiters.For.CHECK_ACCOUNT_EXISTENCE)
public Response accountExists(
@ReadOnly @Auth final Optional<AuthenticatedAccount> authenticatedAccount,
@ReadOnly @Auth final Optional<AuthenticatedDevice> authenticatedAccount,

@Parameter(description = "An ACI or PNI account identifier to check")
@PathParam("identifier") final ServiceIdentifier accountIdentifier) {
Expand All @@ -510,7 +510,7 @@ public Response accountExists(

@DELETE
@Path("/me")
public CompletableFuture<Response> deleteAccount(@Mutable @Auth AuthenticatedAccount auth) {
public CompletableFuture<Response> deleteAccount(@Mutable @Auth AuthenticatedDevice auth) {
return accounts.delete(auth.getAccount(), AccountsManager.DeletionReason.USER_REQUEST).thenApply(Util.ASYNC_EMPTY_RESPONSE);
}

Expand All @@ -528,7 +528,7 @@ private void updateUsernameLink(
accounts.update(account, a -> a.setUsernameLinkDetails(usernameLinkHandle, encryptedUsername));
}

private void requireNotAuthenticated(final Optional<AuthenticatedAccount> authenticatedAccount) {
private void requireNotAuthenticated(final Optional<AuthenticatedDevice> authenticatedAccount) {
if (authenticatedAccount.isPresent()) {
throw new BadRequestException("Operation requires unauthenticated access");
}
Expand Down
Loading

0 comments on commit 0075e94

Please sign in to comment.