Clarify naming around spam filtering.
This commit is contained in:
parent
a01fcdad28
commit
a89e30fe75
|
@ -7,5 +7,5 @@
|
|||
#
|
||||
# External developers may safely ignore this submodule.
|
||||
[submodule "abusive-message-filter"]
|
||||
path = abusive-message-filter
|
||||
path = spam-filter
|
||||
url = REDACTED
|
||||
|
|
10
pom.xml
10
pom.xml
|
@ -364,22 +364,22 @@
|
|||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>include-abusive-message-filter</id>
|
||||
<id>include-spam-filter</id>
|
||||
<activation>
|
||||
<file>
|
||||
<exists>abusive-message-filter/pom.xml</exists>
|
||||
<exists>spam-filter/pom.xml</exists>
|
||||
</file>
|
||||
</activation>
|
||||
<modules>
|
||||
<module>abusive-message-filter</module>
|
||||
<module>spam-filter</module>
|
||||
</modules>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>exclude-abusive-message-filter</id>
|
||||
<id>exclude-spam-filter</id>
|
||||
<activation>
|
||||
<file>
|
||||
<missing>abusive-message-filter/pom.xml</missing>
|
||||
<missing>spam-filter/pom.xml</missing>
|
||||
</file>
|
||||
</activation>
|
||||
</profile>
|
||||
|
|
|
@ -446,7 +446,7 @@
|
|||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>exclude-abusive-message-filter</id>
|
||||
<id>exclude-spam-filter</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
|
|
@ -12,7 +12,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import org.whispersystems.textsecuregcm.configuration.AbusiveMessageFilterConfiguration;
|
||||
import org.whispersystems.textsecuregcm.configuration.SpamFilterConfiguration;
|
||||
import org.whispersystems.textsecuregcm.configuration.AccountDatabaseCrawlerConfiguration;
|
||||
import org.whispersystems.textsecuregcm.configuration.AdminEventLoggingConfiguration;
|
||||
import org.whispersystems.textsecuregcm.configuration.ApnConfiguration;
|
||||
|
@ -268,7 +268,7 @@ public class WhisperServerConfiguration extends Configuration {
|
|||
|
||||
@Valid
|
||||
@JsonProperty
|
||||
private AbusiveMessageFilterConfiguration abusiveMessageFilter;
|
||||
private SpamFilterConfiguration spamFilterConfiguration;
|
||||
|
||||
@Valid
|
||||
@NotNull
|
||||
|
@ -453,8 +453,8 @@ public class WhisperServerConfiguration extends Configuration {
|
|||
return reportMessage;
|
||||
}
|
||||
|
||||
public AbusiveMessageFilterConfiguration getAbusiveMessageFilterConfiguration() {
|
||||
return abusiveMessageFilter;
|
||||
public SpamFilterConfiguration getSpamFilterConfiguration() {
|
||||
return spamFilterConfiguration;
|
||||
}
|
||||
|
||||
public UsernameConfiguration getUsername() {
|
||||
|
|
|
@ -70,11 +70,11 @@ import org.signal.libsignal.zkgroup.receipts.ServerZkReceiptOperations;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.dispatch.DispatchManager;
|
||||
import org.whispersystems.textsecuregcm.abuse.AbusiveMessageFilter;
|
||||
import org.whispersystems.textsecuregcm.abuse.FilterAbusiveMessages;
|
||||
import org.whispersystems.textsecuregcm.abuse.RateLimitChallengeListener;
|
||||
import org.whispersystems.textsecuregcm.abuse.ReportSpamTokenHandler;
|
||||
import org.whispersystems.textsecuregcm.abuse.ReportSpamTokenProvider;
|
||||
import org.whispersystems.textsecuregcm.spam.SpamFilter;
|
||||
import org.whispersystems.textsecuregcm.spam.FilterSpam;
|
||||
import org.whispersystems.textsecuregcm.spam.RateLimitChallengeListener;
|
||||
import org.whispersystems.textsecuregcm.spam.ReportSpamTokenHandler;
|
||||
import org.whispersystems.textsecuregcm.spam.ReportSpamTokenProvider;
|
||||
import org.whispersystems.textsecuregcm.auth.AccountAuthenticator;
|
||||
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
|
||||
import org.whispersystems.textsecuregcm.auth.CertificateGenerator;
|
||||
|
@ -677,14 +677,14 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
|||
|
||||
environment.jersey().register(new KeysController(rateLimiters, keys, accountsManager));
|
||||
|
||||
boolean registeredAbusiveMessageFilter = false;
|
||||
boolean registeredSpamFilter = false;
|
||||
ReportSpamTokenProvider reportSpamTokenProvider = null;
|
||||
ReportSpamTokenHandler reportSpamTokenHandler = null;
|
||||
|
||||
for (final AbusiveMessageFilter filter : ServiceLoader.load(AbusiveMessageFilter.class)) {
|
||||
if (filter.getClass().isAnnotationPresent(FilterAbusiveMessages.class)) {
|
||||
for (final SpamFilter filter : ServiceLoader.load(SpamFilter.class)) {
|
||||
if (filter.getClass().isAnnotationPresent(FilterSpam.class)) {
|
||||
try {
|
||||
filter.configure(config.getAbusiveMessageFilterConfiguration().getEnvironment());
|
||||
filter.configure(config.getSpamFilterConfiguration().getEnvironment());
|
||||
|
||||
ReportSpamTokenProvider thisProvider = filter.getReportSpamTokenProvider();
|
||||
if (reportSpamTokenProvider == null) {
|
||||
|
@ -704,13 +704,13 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
|||
environment.jersey().register(filter);
|
||||
webSocketEnvironment.jersey().register(filter);
|
||||
|
||||
log.info("Registered abusive message filter: {}", filter.getClass().getName());
|
||||
registeredAbusiveMessageFilter = true;
|
||||
log.info("Registered spam filter: {}", filter.getClass().getName());
|
||||
registeredSpamFilter = true;
|
||||
} catch (final Exception e) {
|
||||
log.warn("Failed to register abusive message filter: {}", filter.getClass().getName(), e);
|
||||
log.warn("Failed to register spam filter: {}", filter.getClass().getName(), e);
|
||||
}
|
||||
} else {
|
||||
log.warn("Abusive message filter {} not annotated with @FilterAbusiveMessages and will not be installed",
|
||||
log.warn("Spam filter {} not annotated with @FilterSpam and will not be installed",
|
||||
filter.getClass().getName());
|
||||
}
|
||||
|
||||
|
@ -720,8 +720,8 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
|||
}
|
||||
}
|
||||
|
||||
if (!registeredAbusiveMessageFilter) {
|
||||
log.warn("No abusive message filters installed");
|
||||
if (!registeredSpamFilter) {
|
||||
log.warn("No spam filters installed");
|
||||
}
|
||||
|
||||
if (reportSpamTokenProvider == null) {
|
||||
|
|
|
@ -9,14 +9,14 @@ import com.fasterxml.jackson.annotation.JsonCreator;
|
|||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
public class AbusiveMessageFilterConfiguration {
|
||||
public class SpamFilterConfiguration {
|
||||
|
||||
@JsonProperty
|
||||
@NotBlank
|
||||
private final String environment;
|
||||
|
||||
@JsonCreator
|
||||
public AbusiveMessageFilterConfiguration(@JsonProperty("environment") final String environment) {
|
||||
public SpamFilterConfiguration(@JsonProperty("environment") final String environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
package org.whispersystems.textsecuregcm.configuration.dynamic;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.time.Duration;
|
||||
|
||||
public class DynamicAbusiveHostRulesConfiguration {
|
||||
|
||||
@JsonProperty
|
||||
private Duration expirationTime = Duration.ofDays(1);
|
||||
|
||||
public Duration getExpirationTime() {
|
||||
return expirationTime;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package org.whispersystems.textsecuregcm.configuration.dynamic;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
@ -48,10 +47,6 @@ public class DynamicConfiguration {
|
|||
@Valid
|
||||
private DynamicTurnConfiguration turn = new DynamicTurnConfiguration();
|
||||
|
||||
@JsonProperty
|
||||
@Valid
|
||||
DynamicAbusiveHostRulesConfiguration abusiveHostRules = new DynamicAbusiveHostRulesConfiguration();
|
||||
|
||||
@JsonProperty
|
||||
@Valid
|
||||
DynamicMessagePersisterConfiguration messagePersister = new DynamicMessagePersisterConfiguration();
|
||||
|
@ -102,10 +97,6 @@ public class DynamicConfiguration {
|
|||
return turn;
|
||||
}
|
||||
|
||||
public DynamicAbusiveHostRulesConfiguration getAbusiveHostRules() {
|
||||
return abusiveHostRules;
|
||||
}
|
||||
|
||||
public DynamicMessagePersisterConfiguration getMessagePersisterConfiguration() {
|
||||
return messagePersister;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ import javax.ws.rs.core.Response.Status;
|
|||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.textsecuregcm.abuse.FilterAbusiveMessages;
|
||||
import org.whispersystems.textsecuregcm.spam.FilterSpam;
|
||||
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
|
||||
import org.whispersystems.textsecuregcm.auth.AuthenticationCredentials;
|
||||
import org.whispersystems.textsecuregcm.auth.BasicAuthorizationHeader;
|
||||
|
@ -265,7 +265,7 @@ public class AccountController {
|
|||
@Timed
|
||||
@GET
|
||||
@Path("/{transport}/code/{number}")
|
||||
@FilterAbusiveMessages
|
||||
@FilterSpam
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response createAccount(@PathParam("transport") String transport,
|
||||
@PathParam("number") String number,
|
||||
|
|
|
@ -62,9 +62,9 @@ import javax.ws.rs.core.Response;
|
|||
import javax.ws.rs.core.Response.Status;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.textsecuregcm.abuse.FilterAbusiveMessages;
|
||||
import org.whispersystems.textsecuregcm.abuse.ReportSpamTokenHandler;
|
||||
import org.whispersystems.textsecuregcm.abuse.ReportSpamTokenProvider;
|
||||
import org.whispersystems.textsecuregcm.spam.FilterSpam;
|
||||
import org.whispersystems.textsecuregcm.spam.ReportSpamTokenHandler;
|
||||
import org.whispersystems.textsecuregcm.spam.ReportSpamTokenProvider;
|
||||
import org.whispersystems.textsecuregcm.auth.Anonymous;
|
||||
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
|
||||
import org.whispersystems.textsecuregcm.auth.CombinedUnidentifiedSenderAccessKeys;
|
||||
|
@ -177,7 +177,7 @@ public class MessageController {
|
|||
@PUT
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@FilterAbusiveMessages
|
||||
@FilterSpam
|
||||
public Response sendMessage(@Auth Optional<AuthenticatedAccount> source,
|
||||
@HeaderParam(OptionalAccess.UNIDENTIFIED) Optional<Anonymous> accessKey,
|
||||
@HeaderParam(HttpHeaders.USER_AGENT) String userAgent,
|
||||
|
@ -355,7 +355,7 @@ public class MessageController {
|
|||
@PUT
|
||||
@Consumes(MultiRecipientMessageProvider.MEDIA_TYPE)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@FilterAbusiveMessages
|
||||
@FilterSpam
|
||||
public Response sendMultiRecipientMessage(
|
||||
@HeaderParam(OptionalAccess.UNIDENTIFIED) @Nullable CombinedUnidentifiedSenderAccessKeys accessKeys,
|
||||
@HeaderParam(HttpHeaders.USER_AGENT) String userAgent,
|
||||
|
|
|
@ -9,7 +9,7 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.whispersystems.textsecuregcm.abuse.RateLimitChallengeListener;
|
||||
import org.whispersystems.textsecuregcm.spam.RateLimitChallengeListener;
|
||||
import org.whispersystems.textsecuregcm.captcha.CaptchaChecker;
|
||||
import org.whispersystems.textsecuregcm.controllers.RateLimitExceededException;
|
||||
import org.whispersystems.textsecuregcm.metrics.UserAgentTagUtil;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.abuse;
|
||||
package org.whispersystems.textsecuregcm.spam;
|
||||
|
||||
import javax.ws.rs.NameBinding;
|
||||
import java.lang.annotation.ElementType;
|
||||
|
@ -12,10 +12,10 @@ import java.lang.annotation.RetentionPolicy;
|
|||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* A name-binding annotation that associates {@link AbusiveMessageFilter}s with resource methods.
|
||||
* A name-binding annotation that associates {@link SpamFilter}s with resource methods.
|
||||
*/
|
||||
@NameBinding
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
public @interface FilterAbusiveMessages {
|
||||
public @interface FilterSpam {
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.abuse;
|
||||
package org.whispersystems.textsecuregcm.spam;
|
||||
|
||||
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
|
@ -3,7 +3,7 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.abuse;
|
||||
package org.whispersystems.textsecuregcm.spam;
|
||||
|
||||
public enum RateLimitChallengeType {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.whispersystems.textsecuregcm.abuse;
|
||||
package org.whispersystems.textsecuregcm.spam;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
|
@ -1,4 +1,4 @@
|
|||
package org.whispersystems.textsecuregcm.abuse;
|
||||
package org.whispersystems.textsecuregcm.spam;
|
||||
|
||||
import javax.ws.rs.container.ContainerRequestContext;
|
||||
import java.util.Optional;
|
|
@ -3,27 +3,27 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.abuse;
|
||||
package org.whispersystems.textsecuregcm.spam;
|
||||
|
||||
import io.dropwizard.lifecycle.Managed;
|
||||
import javax.ws.rs.container.ContainerRequestFilter;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* An abusive message filter is a {@link ContainerRequestFilter} that filters requests to message-sending endpoints to
|
||||
* detect and respond to patterns of abusive behavior.
|
||||
* A spam filter is a {@link ContainerRequestFilter} that filters requests to message-sending endpoints to
|
||||
* detect and respond to patterns of spam.
|
||||
* <p/>
|
||||
* Abusive message filters are managed components that are generally loaded dynamically via a
|
||||
* Spam filters are managed components that are generally loaded dynamically via a
|
||||
* {@link java.util.ServiceLoader}. Their {@link #configure(String)} method will be called prior to be adding to the
|
||||
* server's pool of {@link Managed} objects.
|
||||
* <p/>
|
||||
* Abusive message filters must be annotated with {@link FilterAbusiveMessages}, a name binding annotation that
|
||||
* Spam filters must be annotated with {@link FilterSpam}, a name binding annotation that
|
||||
* restricts the endpoints to which the filter may apply.
|
||||
*/
|
||||
public interface AbusiveMessageFilter extends ContainerRequestFilter, Managed {
|
||||
public interface SpamFilter extends ContainerRequestFilter, Managed {
|
||||
|
||||
/**
|
||||
* Configures this abusive message filter. This method will be called before the filter is added to the server's pool
|
||||
* Configures this spam filter. This method will be called before the filter is added to the server's pool
|
||||
* of managed objects and before the server processes any requests.
|
||||
*
|
||||
* @param environmentName the name of the environment in which this filter is running (e.g. "staging" or "production")
|
|
@ -89,7 +89,7 @@ public class ReportMessageManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the number of times messages from the given account have been reported by recipients as abusive. Note that
|
||||
* Returns the number of times messages from the given account have been reported by recipients as spam. Note that
|
||||
* this method makes a call to an external service, and callers should take care to memoize calls where possible and
|
||||
* avoid unnecessary calls.
|
||||
*
|
||||
|
|
|
@ -67,8 +67,8 @@ import org.junit.jupiter.params.ParameterizedTest;
|
|||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.whispersystems.textsecuregcm.abuse.ReportSpamTokenHandler;
|
||||
import org.whispersystems.textsecuregcm.abuse.ReportSpamTokenProvider;
|
||||
import org.whispersystems.textsecuregcm.spam.ReportSpamTokenHandler;
|
||||
import org.whispersystems.textsecuregcm.spam.ReportSpamTokenProvider;
|
||||
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
|
||||
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAuthenticatedAccount;
|
||||
import org.whispersystems.textsecuregcm.auth.OptionalAccess;
|
||||
|
|
|
@ -12,11 +12,10 @@ import java.util.UUID;
|
|||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.whispersystems.textsecuregcm.abuse.RateLimitChallengeListener;
|
||||
import org.whispersystems.textsecuregcm.spam.RateLimitChallengeListener;
|
||||
import org.whispersystems.textsecuregcm.captcha.AssessmentResult;
|
||||
import org.whispersystems.textsecuregcm.captcha.CaptchaChecker;
|
||||
import org.whispersystems.textsecuregcm.controllers.RateLimitExceededException;
|
||||
import org.whispersystems.textsecuregcm.captcha.RecaptchaClient;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
|
||||
class RateLimitChallengeManagerTest {
|
||||
|
|
Loading…
Reference in New Issue