Switch ProfileController to the actual badge converter

This commit is contained in:
Ehren Kret 2021-09-15 16:19:35 -05:00
parent 72a0c1be0f
commit 98a31d1474
3 changed files with 35 additions and 9 deletions

View File

@ -29,7 +29,6 @@ import io.dropwizard.jdbi3.JdbiFactory;
import io.dropwizard.setup.Bootstrap; import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment; import io.dropwizard.setup.Environment;
import io.lettuce.core.resource.ClientResources; import io.lettuce.core.resource.ClientResources;
import io.micrometer.core.instrument.Clock;
import io.micrometer.core.instrument.Meter.Id; import io.micrometer.core.instrument.Meter.Id;
import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tags; import io.micrometer.core.instrument.Tags;
@ -37,6 +36,7 @@ import io.micrometer.core.instrument.config.MeterFilter;
import io.micrometer.core.instrument.distribution.DistributionStatisticConfig; import io.micrometer.core.instrument.distribution.DistributionStatisticConfig;
import io.micrometer.datadog.DatadogMeterRegistry; import io.micrometer.datadog.DatadogMeterRegistry;
import java.net.http.HttpClient; import java.net.http.HttpClient;
import java.time.Clock;
import java.time.Duration; import java.time.Duration;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -69,6 +69,7 @@ import org.whispersystems.textsecuregcm.auth.DisabledPermittedAccountAuthenticat
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAuthenticatedAccount; import org.whispersystems.textsecuregcm.auth.DisabledPermittedAuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialGenerator; import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialGenerator;
import org.whispersystems.textsecuregcm.auth.TurnTokenGenerator; import org.whispersystems.textsecuregcm.auth.TurnTokenGenerator;
import org.whispersystems.textsecuregcm.badges.ConfiguredProfileBadgeConverter;
import org.whispersystems.textsecuregcm.badges.ProfileBadgeConverter; import org.whispersystems.textsecuregcm.badges.ProfileBadgeConverter;
import org.whispersystems.textsecuregcm.configuration.DirectoryServerConfiguration; import org.whispersystems.textsecuregcm.configuration.DirectoryServerConfiguration;
import org.whispersystems.textsecuregcm.controllers.AccountController; import org.whispersystems.textsecuregcm.controllers.AccountController;
@ -269,7 +270,8 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
.build(); .build();
{ {
final DatadogMeterRegistry datadogMeterRegistry = new DatadogMeterRegistry(config.getDatadogConfiguration(), Clock.SYSTEM); final DatadogMeterRegistry datadogMeterRegistry = new DatadogMeterRegistry(
config.getDatadogConfiguration(), io.micrometer.core.instrument.Clock.SYSTEM);
datadogMeterRegistry.config().commonTags( datadogMeterRegistry.config().commonTags(
Tags.of( Tags.of(
@ -295,7 +297,8 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
environment.getObjectMapper().setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE); environment.getObjectMapper().setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
environment.getObjectMapper().setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); environment.getObjectMapper().setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
ProfileBadgeConverter profileBadgeConverter = (acceptableLanguages, accountBadges) -> List.of(); // TODO: Provide an actual implementation. ProfileBadgeConverter profileBadgeConverter = new ConfiguredProfileBadgeConverter(
Clock.systemUTC(), config.getBadges());
JdbiFactory jdbiFactory = new JdbiFactory(DefaultNameStrategy.CHECK_EMPTY); JdbiFactory jdbiFactory = new JdbiFactory(DefaultNameStrategy.CHECK_EMPTY);
Jdbi accountJdbi = jdbiFactory.build(environment, config.getAccountsDatabaseConfiguration(), "accountdb"); Jdbi accountJdbi = jdbiFactory.build(environment, config.getAccountsDatabaseConfiguration(), "accountdb");

View File

@ -296,8 +296,11 @@ public class ProfileController {
@GET @GET
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Path("/username/{username}") @Path("/username/{username}")
public Profile getProfileByUsername(@Auth AuthenticatedAccount auth, @PathParam("username") String username) public Profile getProfileByUsername(
throws RateLimitExceededException { @Auth AuthenticatedAccount auth,
@Context ContainerRequestContext containerRequestContext,
@PathParam("username") String username)
throws RateLimitExceededException {
rateLimiters.getUsernameLookupLimiter().validate(auth.getAccount().getUuid()); rateLimiters.getUsernameLookupLimiter().validate(auth.getAccount().getUuid());
username = username.toLowerCase(); username = username.toLowerCase();
@ -326,7 +329,7 @@ public class ProfileController {
UserCapabilities.createForAccount(accountProfile.get()), UserCapabilities.createForAccount(accountProfile.get()),
username, username,
accountProfile.get().getUuid(), accountProfile.get().getUuid(),
List.of(), profileBadgeConverter.convert(containerRequestContext.getAcceptableLanguages(), accountProfile.get().getBadges()),
null); null);
} }
@ -367,8 +370,10 @@ public class ProfileController {
@GET @GET
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Path("/{identifier}") @Path("/{identifier}")
public Profile getProfile(@Auth Optional<AuthenticatedAccount> auth, public Profile getProfile(
@Auth Optional<AuthenticatedAccount> auth,
@HeaderParam(OptionalAccess.UNIDENTIFIED) Optional<Anonymous> accessKey, @HeaderParam(OptionalAccess.UNIDENTIFIED) Optional<Anonymous> accessKey,
@Context ContainerRequestContext containerRequestContext,
@HeaderParam("User-Agent") String userAgent, @HeaderParam("User-Agent") String userAgent,
@PathParam("identifier") UUID identifier, @PathParam("identifier") UUID identifier,
@QueryParam("ca") boolean useCaCertificate) @QueryParam("ca") boolean useCaCertificate)
@ -399,7 +404,7 @@ public class ProfileController {
UserCapabilities.createForAccount(accountProfile.get()), UserCapabilities.createForAccount(accountProfile.get()),
username.orElse(null), username.orElse(null),
null, null,
List.of(), profileBadgeConverter.convert(containerRequestContext.getAcceptableLanguages(), accountProfile.get().getBadges()),
null); null);
} }

View File

@ -21,6 +21,8 @@ import com.google.common.collect.ImmutableSet;
import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider; import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider;
import io.dropwizard.testing.junit5.DropwizardExtensionsSupport; import io.dropwizard.testing.junit5.DropwizardExtensionsSupport;
import io.dropwizard.testing.junit5.ResourceExtension; import io.dropwizard.testing.junit5.ResourceExtension;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@ -29,6 +31,7 @@ import javax.ws.rs.client.Entity;
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 org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomStringUtils;
import org.assertj.core.api.Condition;
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory; import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
@ -45,6 +48,7 @@ import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfigurati
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicPaymentsConfiguration; import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicPaymentsConfiguration;
import org.whispersystems.textsecuregcm.controllers.ProfileController; import org.whispersystems.textsecuregcm.controllers.ProfileController;
import org.whispersystems.textsecuregcm.controllers.RateLimitExceededException; import org.whispersystems.textsecuregcm.controllers.RateLimitExceededException;
import org.whispersystems.textsecuregcm.entities.Badge;
import org.whispersystems.textsecuregcm.entities.CreateProfileRequest; import org.whispersystems.textsecuregcm.entities.CreateProfileRequest;
import org.whispersystems.textsecuregcm.entities.Profile; import org.whispersystems.textsecuregcm.entities.Profile;
import org.whispersystems.textsecuregcm.entities.ProfileAvatarUploadAttributes; import org.whispersystems.textsecuregcm.entities.ProfileAvatarUploadAttributes;
@ -97,7 +101,15 @@ class ProfileControllerTest {
profilesManager, profilesManager,
usernamesManager, usernamesManager,
dynamicConfigurationManager, dynamicConfigurationManager,
(acceptableLanguages, accountBadges) -> List.of(), // TODO: Test with some badges. (acceptableLanguages, accountBadges) -> {
try {
return List.of(
new Badge(new URL("https://example.com/badge/1"), "Test Badge", "This badge is in unit tests.")
);
} catch (MalformedURLException e) {
throw new AssertionError(e);
}
},
s3client, s3client,
postPolicyGenerator, postPolicyGenerator,
policySigner, policySigner,
@ -184,6 +196,8 @@ class ProfileControllerTest {
assertThat(profile.getName()).isEqualTo("baz"); assertThat(profile.getName()).isEqualTo("baz");
assertThat(profile.getAvatar()).isEqualTo("profiles/bang"); assertThat(profile.getAvatar()).isEqualTo("profiles/bang");
assertThat(profile.getUsername()).isEqualTo("n00bkiller"); assertThat(profile.getUsername()).isEqualTo("n00bkiller");
assertThat(profile.getBadges()).hasSize(1).element(0).has(new Condition<>(
badge -> "Test Badge".equals(badge.getName()), "has badge with expected name"));
verify(accountsManager).get(AuthHelper.VALID_UUID_TWO); verify(accountsManager).get(AuthHelper.VALID_UUID_TWO);
verify(usernamesManager, times(1)).get(eq(AuthHelper.VALID_UUID_TWO)); verify(usernamesManager, times(1)).get(eq(AuthHelper.VALID_UUID_TWO));
@ -203,6 +217,8 @@ class ProfileControllerTest {
assertThat(profile.getAvatar()).isEqualTo("profiles/bang"); assertThat(profile.getAvatar()).isEqualTo("profiles/bang");
assertThat(profile.getUsername()).isEqualTo("n00bkiller"); assertThat(profile.getUsername()).isEqualTo("n00bkiller");
assertThat(profile.getUuid()).isEqualTo(AuthHelper.VALID_UUID_TWO); assertThat(profile.getUuid()).isEqualTo(AuthHelper.VALID_UUID_TWO);
assertThat(profile.getBadges()).hasSize(1).element(0).has(new Condition<>(
badge -> "Test Badge".equals(badge.getName()), "has badge with expected name"));
verify(accountsManager, times(1)).get(eq(AuthHelper.VALID_UUID_TWO)); verify(accountsManager, times(1)).get(eq(AuthHelper.VALID_UUID_TWO));
verify(usernamesManager, times(1)).get(eq("n00bkiller")); verify(usernamesManager, times(1)).get(eq("n00bkiller"));
@ -563,6 +579,8 @@ class ProfileControllerTest {
assertThat(profile.getCapabilities().isGv1Migration()).isFalse(); assertThat(profile.getCapabilities().isGv1Migration()).isFalse();
assertThat(profile.getUsername()).isEqualTo("n00bkiller"); assertThat(profile.getUsername()).isEqualTo("n00bkiller");
assertThat(profile.getUuid()).isNull(); assertThat(profile.getUuid()).isNull();
assertThat(profile.getBadges()).hasSize(1).element(0).has(new Condition<>(
badge -> "Test Badge".equals(badge.getName()), "has badge with expected name"));
verify(accountsManager, times(1)).get(eq(AuthHelper.VALID_UUID_TWO)); verify(accountsManager, times(1)).get(eq(AuthHelper.VALID_UUID_TWO));
verify(usernamesManager, times(1)).get(eq(AuthHelper.VALID_UUID_TWO)); verify(usernamesManager, times(1)).get(eq(AuthHelper.VALID_UUID_TWO));