[AB-177] adding ability to restrict the allowed mentions and configure them via commands on a server basis, default is defined via property file

This commit is contained in:
Sheldan
2021-02-06 04:05:55 +01:00
parent b838678c15
commit 7aa5cbe304
23 changed files with 764 additions and 18 deletions

View File

@@ -0,0 +1,53 @@
package dev.sheldan.abstracto.core.commands.config.mention;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.features.CoreFeatures;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.commands.config.ConfigModuleInterface;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.service.AllowedMentionService;
import net.dv8tion.jda.api.entities.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
@Component
public class AllowMention extends AbstractConditionableCommand {
@Autowired
private AllowedMentionService allowedMentionService;
@Override
public CommandResult execute(CommandContext commandContext) {
String mentionTypeInput = (String) commandContext.getParameters().getParameters().get(0);
Message.MentionType mentionType = allowedMentionService.getMentionTypeFromString(mentionTypeInput);
allowedMentionService.allowMentionForServer(mentionType, commandContext.getGuild().getIdLong());
return CommandResult.fromSuccess();
}
@Override
public CommandConfiguration getConfiguration() {
Parameter mentionTypeParameter = Parameter.builder().name("mentionType").type(String.class).templated(true).build();
List<Parameter> parameters = Arrays.asList(mentionTypeParameter);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("allowMention")
.module(ConfigModuleInterface.CONFIG)
.parameters(parameters)
.templated(true)
.supportsEmbedException(true)
.help(helpInfo)
.causesReaction(true)
.build();
}
@Override
public FeatureEnum getFeature() {
return CoreFeatures.CORE_FEATURE;
}
}

View File

@@ -0,0 +1,55 @@
package dev.sheldan.abstracto.core.commands.config.mention;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.features.CoreFeatures;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.commands.config.ConfigModuleInterface;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.service.AllowedMentionService;
import net.dv8tion.jda.api.entities.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
@Component
public class DisallowMention extends AbstractConditionableCommand {
@Autowired
private AllowedMentionService allowedMentionService;
@Override
public CommandResult execute(CommandContext commandContext) {
String mentionTypeInput = (String) commandContext.getParameters().getParameters().get(0);
Message.MentionType mentionType = allowedMentionService.getMentionTypeFromString(mentionTypeInput);
allowedMentionService.disAllowMentionForServer(mentionType, commandContext.getGuild().getIdLong());
return CommandResult.fromSuccess();
}
@Override
public CommandConfiguration getConfiguration() {
Parameter mentionTypeParameter = Parameter.builder().name("mentionType").type(String.class).templated(true).build();
List<Parameter> parameters = Arrays.asList(mentionTypeParameter);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("disallowMention")
.module(ConfigModuleInterface.CONFIG)
.parameters(parameters)
.templated(true)
.supportsEmbedException(true)
.help(helpInfo)
.causesReaction(true)
.build();
}
@Override
public FeatureEnum getFeature() {
return CoreFeatures.CORE_FEATURE;
}
}

View File

@@ -1,6 +1,5 @@
package dev.sheldan.abstracto.core.commands.utility;
import dev.sheldan.abstracto.core.command.UtilityModuleInterface;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
@@ -10,6 +9,7 @@ import dev.sheldan.abstracto.core.command.config.features.CoreFeatures;
import dev.sheldan.abstracto.core.command.config.validator.MaxStringLengthValidator;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.commands.config.ConfigModuleInterface;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.models.database.AEmote;
import dev.sheldan.abstracto.core.service.EmoteService;
@@ -47,7 +47,7 @@ public class SetEmote extends AbstractConditionableCommand {
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("setEmote")
.module(UtilityModuleInterface.UTILITY)
.module(ConfigModuleInterface.CONFIG)
.parameters(parameters)
.supportsEmbedException(true)
.help(helpInfo)

View File

@@ -0,0 +1,16 @@
package dev.sheldan.abstracto.core.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "abstracto.allowedmention")
public class AllowedMentionConfig {
private Boolean everyone;
private Boolean role;
private Boolean user;
}

View File

@@ -0,0 +1,15 @@
package dev.sheldan.abstracto.core.repository;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AllowedMention;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface AllowedMentionRepository extends JpaRepository<AllowedMention, Long> {
Optional<AllowedMention> findByServer(AServer server);
}

View File

@@ -5,11 +5,13 @@ import dev.sheldan.abstracto.core.models.database.AChannelGroup;
import dev.sheldan.abstracto.core.models.database.AServer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.stereotype.Repository;
import javax.persistence.QueryHint;
import java.util.List;
import java.util.Optional;
@Repository
public interface ChannelGroupRepository extends JpaRepository<AChannelGroup, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))

View File

@@ -0,0 +1,125 @@
package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.config.AllowedMentionConfig;
import dev.sheldan.abstracto.core.models.database.AllowedMention;
import dev.sheldan.abstracto.core.exception.UnknownMentionTypeException;
import dev.sheldan.abstracto.core.service.management.AllowedMentionManagementService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
@Component
@Slf4j
public class AllowedMentionServiceBean implements AllowedMentionService {
public static final String EVERYONE_MENTION_KEY = "everyone";
public static final String ROLE_MENTION_KEY = "role";
public static final String USER_MENTION_KEY = "user";
@Autowired
private AllowedMentionConfig allowedMentionConfig;
@Autowired
private AllowedMentionManagementService allowedMentionManagementService;
private final HashMap<String, Message.MentionType> ALL_MENTION_TYPES = new HashMap<>();
@Override
public boolean allMentionsAllowed(Long serverId) {
return getEffectiveAllowedMention(serverId).allAllowed();
}
@Override
public List<Message.MentionType> getAllowedMentionTypesForServer(Long serverId) {
AllowedMention allowedMention = getEffectiveAllowedMention(serverId);
return mapAllowedMentionToMentionType(allowedMention);
}
@Override
public void allowMentionForServer(Message.MentionType mentionType, Long serverId) {
log.info("Allowing mention {} for server {}.", mentionType, serverId);
setOrInitializeAllowedMention(mentionType, serverId, true);
}
@Override
public void disAllowMentionForServer(Message.MentionType mentionType, Long serverId) {
log.info("Disallowing mention {} for server {}.", mentionType, serverId);
setOrInitializeAllowedMention(mentionType, serverId, false);
}
@Override
public AllowedMention getDefaultAllowedMention() {
return AllowedMention
.builder()
.everyone(allowedMentionConfig.getEveryone())
.role(allowedMentionConfig.getRole())
.user(allowedMentionConfig.getUser())
.build();
}
@Override
public AllowedMention getEffectiveAllowedMention(Long serverId) {
Optional<AllowedMention> customAllowMentions = allowedMentionManagementService.getCustomAllowedMentionFor(serverId);
return customAllowMentions.orElseGet(this::getDefaultAllowedMention);
}
@Override
public Message.MentionType getMentionTypeFromString(String input) {
input = input.toLowerCase();
if (ALL_MENTION_TYPES.containsKey(input)) {
return ALL_MENTION_TYPES.get(input);
}
throw new UnknownMentionTypeException();
}
private List<Message.MentionType> mapAllowedMentionToMentionType(AllowedMention allowedMention) {
// if all are allowed, we dont want to restrict it
if(allowedMention.allAllowed()) {
return null;
}
List<Message.MentionType> types = new ArrayList<>();
if(allowedMention.getEveryone()) {
types.add(Message.MentionType.EVERYONE);
}
if(allowedMention.getRole()) {
types.add(Message.MentionType.ROLE);
}
if(allowedMention.getUser()) {
types.add(Message.MentionType.USER);
}
return types;
}
private void setOrInitializeAllowedMention(Message.MentionType mentionType, Long serverId, boolean initialMentionValue) {
Optional<AllowedMention> customAllowedMentionOptional = allowedMentionManagementService.getCustomAllowedMentionFor(serverId);
AllowedMention customAllowedMention = customAllowedMentionOptional.orElseGet(this::getDefaultAllowedMention);
switch (mentionType) {
case EVERYONE:
customAllowedMention.setEveryone(initialMentionValue);
break;
case ROLE:
customAllowedMention.setRole(initialMentionValue);
break;
case USER:
customAllowedMention.setUser(initialMentionValue);
break;
}
if (!customAllowedMentionOptional.isPresent()) {
allowedMentionManagementService.createCustomAllowedMention(serverId, customAllowedMention);
}
}
@PostConstruct
public void postConstruct() {
ALL_MENTION_TYPES.put(EVERYONE_MENTION_KEY, Message.MentionType.EVERYONE);
ALL_MENTION_TYPES.put(ROLE_MENTION_KEY, Message.MentionType.ROLE);
ALL_MENTION_TYPES.put(USER_MENTION_KEY, Message.MentionType.USER);
}
}

View File

@@ -44,6 +44,9 @@ public class ChannelServiceBean implements ChannelService {
@Autowired
private TemplateService templateService;
@Autowired
private AllowedMentionService allowedMentionService;
@Autowired
private MetricService metricService;
@@ -119,14 +122,21 @@ public class ChannelServiceBean implements ChannelService {
log.trace("Sending message {} from channel {} and server {} to channel {}.",
message.getId(), message.getChannel().getId(), message.getGuild().getId(), channel.getId());
metricService.incrementCounter(MESSAGE_SEND_METRIC);
return channel.sendMessage(message).submit();
return channel.sendMessage(message).allowedMentions(getAllowedMentionsFor(channel)).submit();
}
private List<Message.MentionType> getAllowedMentionsFor(MessageChannel channel) {
if(channel instanceof GuildChannel) {
return allowedMentionService.getAllowedMentionTypesForServer(((GuildChannel) channel).getGuild().getIdLong());
}
return null;
}
@Override
public CompletableFuture<Message> sendTextToChannel(String text, MessageChannel channel) {
log.trace("Sending text to channel {}.", channel.getId());
metricService.incrementCounter(MESSAGE_SEND_METRIC);
return channel.sendMessage(text).submit();
return channel.sendMessage(text).allowedMentions(getAllowedMentionsFor(channel)).submit();
}
@Override
@@ -155,7 +165,7 @@ public class ChannelServiceBean implements ChannelService {
@Override
public MessageAction sendEmbedToChannelInComplete(MessageEmbed embed, MessageChannel channel) {
metricService.incrementCounter(MESSAGE_SEND_METRIC);
return channel.sendMessage(embed);
return channel.sendMessage(embed).allowedMentions(getAllowedMentionsFor(channel));
}
@Override
@@ -213,8 +223,9 @@ public class ChannelServiceBean implements ChannelService {
}
}
allMessageActions.add(0, firstMessageAction);
List<Message.MentionType> allowedMentions = getAllowedMentionsFor(textChannel);
allMessageActions.forEach(messageAction ->
futures.add(messageAction.submit())
futures.add(messageAction.allowedMentions(allowedMentions).submit())
);
return futures;
}

View File

@@ -56,7 +56,7 @@ public class StartupServiceBean implements Startup {
}
@Override
@Transactional(isolation = Isolation.SERIALIZABLE)
@Transactional
public void synchronize() {
log.info("Synchronizing servers.");
synchronizeServers();
@@ -70,7 +70,7 @@ public class StartupServiceBean implements Startup {
availableServers.forEach(aLong -> {
AServer newAServer = serverManagementService.loadOrCreate(aLong);
Guild newGuild = instance.getGuildById(aLong);
log.trace("Synchronizing server: {}", aLong);
log.info("Synchronizing server: {}", aLong);
if(newGuild != null){
synchronizeRolesOf(newGuild, newAServer);
synchronizeChannelsOf(newGuild, newAServer);
@@ -91,7 +91,6 @@ public class StartupServiceBean implements Startup {
Set<Long> newRoles = SetUtils.difference(availableRoles, knownRolesId);
newRoles.forEach(aLong -> {
roleManagementService.createRole(aLong, existingAServer);
log.trace("Adding new role: {}", aLong);
});
}
@@ -103,7 +102,6 @@ public class StartupServiceBean implements Startup {
Set<Long> newChannels = SetUtils.difference(existingChannelsIds, knownChannelsIds);
newChannels.forEach(aLong -> {
GuildChannel channel1 = available.stream().filter(channel -> channel.getIdLong() == aLong).findFirst().get();
log.trace("Adding new channel: {}", aLong);
AChannelType type = AChannelType.getAChannelType(channel1.getType());
channelManagementService.createChannel(channel1.getIdLong(), type, existingServer);
});

View File

@@ -0,0 +1,55 @@
package dev.sheldan.abstracto.core.service.management;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AllowedMention;
import dev.sheldan.abstracto.core.repository.AllowedMentionRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Optional;
@Component
@Slf4j
public class AllowedMentionManagementServiceBean implements AllowedMentionManagementService {
@Autowired
private AllowedMentionRepository allowedMentionRepository;
@Autowired
private ServerManagementService serverManagementServiceBean;
@Override
public Optional<AllowedMention> getCustomAllowedMentionFor(Long serverId) {
return allowedMentionRepository.findById(serverId);
}
@Override
public Optional<AllowedMention> getCustomAllowedMentionFor(AServer server) {
return allowedMentionRepository.findByServer(server);
}
@Override
public boolean hasCustomAllowedMention(Long serverId) {
return getCustomAllowedMentionFor(serverId).isPresent();
}
@Override
public AllowedMention createCustomAllowedMention(Long serverId, AllowedMention base) {
log.info("Creating custom allowed mention for server {} based on {}.", serverId, base);
AServer server = serverManagementServiceBean.loadOrCreate(serverId);
AllowedMention allowedMention = AllowedMention
.builder()
.everyone(base.getEveryone())
.role(base.getRole())
.user(base.getUser())
.server(server).build();
allowedMentionRepository.save(allowedMention);
return allowedMention;
}
@Override
public void deleteCustomAllowedMention(Long serverId) {
allowedMentionRepository.deleteById(serverId);
}
}

View File

@@ -25,7 +25,6 @@ public class RoleManagementServiceBean implements RoleManagementService {
.server(server)
.deleted(false)
.build();
server.getRoles().add(build);
log.info("Creating role {} in server {}.", id, server.getId());
return repository.save(build);
}

View File

@@ -1,4 +1,9 @@
abstracto.startup.synchronize=true
abstracto.eventWaiter.threads=10
server.port=8080
server.port=8080
abstracto.allowedmention.everyone=false
abstracto.allowedmention.role=true
abstracto.allowedmention.user=true

View File

@@ -33,12 +33,6 @@
<column name="feature_id" valueComputed="${coreFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="command">
<column name="name" value="setEmote"/>
<column name="module_id" valueComputed="${utilityModule}"/>
<column name="feature_id" valueComputed="${coreFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
</changeSet>
<changeSet author="Sheldan" id="core-channels-commands" >
<insert tableName="command">
@@ -187,5 +181,23 @@
<column name="feature_id" valueComputed="${coreFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="command">
<column name="name" value="setEmote"/>
<column name="module_id" valueComputed="${configModule}"/>
<column name="feature_id" valueComputed="${coreFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="command">
<column name="name" value="allowMention"/>
<column name="module_id" valueComputed="${configModule}"/>
<column name="feature_id" valueComputed="${coreFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
<insert tableName="command">
<column name="name" value="disallowMention"/>
<column name="module_id" valueComputed="${configModule}"/>
<column name="feature_id" valueComputed="${coreFeature}"/>
<column name="created" valueComputed="${today}"/>
</insert>
</changeSet>
</databaseChangeLog>

View File

@@ -0,0 +1,26 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<changeSet author="Sheldan" id="allowed_mention-table">
<createTable tableName="allowed_mention">
<column name="server_id" type="BIGINT">
<constraints nullable="false" primaryKey="true" primaryKeyName="allowed_mention_pkey"/>
</column>
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE"/>
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
<column name="everyone_mention" type="BOOLEAN"/>
<column name="user_mention" type="BOOLEAN"/>
<column name="role_mention" type="BOOLEAN"/>
</createTable>
</changeSet>
<changeSet author="Sheldan" id="allowed_mention-fk_allowed_mention_server">
<addForeignKeyConstraint baseColumnNames="server_id" baseTableName="allowed_mention" constraintName="fk_allowed_mention_server"
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
</changeSet>
</databaseChangeLog>

View File

@@ -27,4 +27,5 @@
<include file="system_config.xml" relativeToChangelogFile="true"/>
<include file="auser.xml" relativeToChangelogFile="true"/>
<include file="counter.xml" relativeToChangelogFile="true"/>
<include file="allowed_mention.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -0,0 +1,169 @@
package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.config.AllowedMentionConfig;
import dev.sheldan.abstracto.core.exception.UnknownMentionTypeException;
import dev.sheldan.abstracto.core.models.database.AllowedMention;
import dev.sheldan.abstracto.core.service.management.AllowedMentionManagementService;
import net.dv8tion.jda.api.entities.Message;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.List;
import java.util.Optional;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class AllowedMentionServiceBeanTest {
@InjectMocks
private AllowedMentionServiceBean testUnit;
@Mock
private AllowedMentionConfig allowedMentionConfig;
@Mock
private AllowedMentionManagementService allowedMentionManagementService;
@Mock
private AllowedMention allowedMention;
private static final Long SERVER_ID = 4L;
@Before
public void setup() {
testUnit.postConstruct();
}
@Test
public void allMentionsAllowedDefaultAll() {
allDefaultConfigAllowed();
when(allowedMentionManagementService.getCustomAllowedMentionFor(SERVER_ID)).thenReturn(Optional.empty());
Assert.assertTrue(testUnit.allMentionsAllowed(SERVER_ID));
}
@Test
public void allMentionsAllowedDefaultNotAll() {
when(allowedMentionConfig.getEveryone()).thenReturn(true);
when(allowedMentionConfig.getRole()).thenReturn(false);
when(allowedMentionConfig.getUser()).thenReturn(true);
when(allowedMentionManagementService.getCustomAllowedMentionFor(SERVER_ID)).thenReturn(Optional.empty());
Assert.assertFalse(testUnit.allMentionsAllowed(SERVER_ID));
}
@Test
public void allMentionsAllowedCustomAll() {
when(allowedMention.allAllowed()).thenReturn(true);
when(allowedMentionManagementService.getCustomAllowedMentionFor(SERVER_ID)).thenReturn(Optional.of(allowedMention));
Assert.assertTrue(testUnit.allMentionsAllowed(SERVER_ID));
}
@Test
public void getAllowedMentionTypesForServerEmpty() {
allDefaultConfigAllowed();
when(allowedMentionManagementService.getCustomAllowedMentionFor(SERVER_ID)).thenReturn(Optional.empty());
List<Message.MentionType> allowedMentions = testUnit.getAllowedMentionTypesForServer(SERVER_ID);
Assert.assertNull(allowedMentions);
}
@Test
public void getAllowedMentionTypesAllAllowed() {
when(allowedMentionConfig.getEveryone()).thenReturn(true);
when(allowedMentionConfig.getRole()).thenReturn(false);
when(allowedMentionConfig.getUser()).thenReturn(false);
when(allowedMentionManagementService.getCustomAllowedMentionFor(SERVER_ID)).thenReturn(Optional.empty());
List<Message.MentionType> allowedMentions = testUnit.getAllowedMentionTypesForServer(SERVER_ID);
Assert.assertEquals(1, allowedMentions.size());
Assert.assertEquals(Message.MentionType.EVERYONE, allowedMentions.get(0));
}
@Test
public void getAllowedMentionTypesAllDisallowed() {
when(allowedMentionConfig.getEveryone()).thenReturn(false);
when(allowedMentionConfig.getRole()).thenReturn(false);
when(allowedMentionConfig.getUser()).thenReturn(false);
when(allowedMentionManagementService.getCustomAllowedMentionFor(SERVER_ID)).thenReturn(Optional.empty());
List<Message.MentionType> allowedMentions = testUnit.getAllowedMentionTypesForServer(SERVER_ID);
Assert.assertEquals(0, allowedMentions.size());
}
@Test
public void allowMentionForServerWithExistingCustom() {
when(allowedMentionManagementService.getCustomAllowedMentionFor(SERVER_ID)).thenReturn(Optional.of(allowedMention));
testUnit.allowMentionForServer(Message.MentionType.EVERYONE, SERVER_ID);
verify(allowedMention, times(1)).setEveryone(true);
}
@Test
public void allowMentionForServerWithNewCustom() {
when(allowedMentionManagementService.getCustomAllowedMentionFor(SERVER_ID)).thenReturn(Optional.empty());
testUnit.allowMentionForServer(Message.MentionType.EVERYONE, SERVER_ID);
ArgumentCaptor<AllowedMention> argumentCaptor = ArgumentCaptor.forClass(AllowedMention.class);
verify(allowedMentionManagementService, times(1)).createCustomAllowedMention(eq(SERVER_ID), argumentCaptor.capture());
AllowedMention creationArgument = argumentCaptor.getValue();
Assert.assertTrue(creationArgument.getEveryone());
}
@Test
public void disAllowMentionForServer() {
when(allowedMentionManagementService.getCustomAllowedMentionFor(SERVER_ID)).thenReturn(Optional.empty());
testUnit.disAllowMentionForServer(Message.MentionType.EVERYONE, SERVER_ID);
ArgumentCaptor<AllowedMention> argumentCaptor = ArgumentCaptor.forClass(AllowedMention.class);
verify(allowedMentionManagementService, times(1)).createCustomAllowedMention(eq(SERVER_ID), argumentCaptor.capture());
AllowedMention creationArgument = argumentCaptor.getValue();
Assert.assertFalse(creationArgument.getEveryone());
}
@Test
public void getDefaultAllowedMention() {
when(allowedMentionConfig.getEveryone()).thenReturn(true);
AllowedMention defaultMention = testUnit.getDefaultAllowedMention();
Assert.assertEquals(true, defaultMention.getEveryone());
}
@Test
public void getEffectiveAllowedMentionWithCustom() {
when(allowedMentionManagementService.getCustomAllowedMentionFor(SERVER_ID)).thenReturn(Optional.of(allowedMention));
AllowedMention effectiveMention = testUnit.getEffectiveAllowedMention(SERVER_ID);
Assert.assertEquals(allowedMention, effectiveMention);
}
@Test
public void getEffectiveAllowedMentionNoCustom() {
when(allowedMentionConfig.getEveryone()).thenReturn(true);
when(allowedMentionManagementService.getCustomAllowedMentionFor(SERVER_ID)).thenReturn(Optional.empty());
AllowedMention effectiveMention = testUnit.getEffectiveAllowedMention(SERVER_ID);
Assert.assertNull(effectiveMention.getServer());
Assert.assertTrue(effectiveMention.getEveryone());
}
@Test
public void getMentionTypeFromString() {
Message.MentionType result = testUnit.getMentionTypeFromString("everyone");
Assert.assertEquals(Message.MentionType.EVERYONE, result);
}
@Test
public void getMentionTypeFromStringIgnoreCase() {
Message.MentionType result = testUnit.getMentionTypeFromString("eVeRyOnE");
Assert.assertEquals(Message.MentionType.EVERYONE, result);
}
@Test(expected = UnknownMentionTypeException.class)
public void getUnknownMentionType() {
testUnit.getMentionTypeFromString("test");
}
private void allDefaultConfigAllowed() {
when(allowedMentionConfig.getEveryone()).thenReturn(true);
when(allowedMentionConfig.getRole()).thenReturn(true);
when(allowedMentionConfig.getUser()).thenReturn(true);
}
}

View File

@@ -0,0 +1,82 @@
package dev.sheldan.abstracto.core.service.management;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AllowedMention;
import dev.sheldan.abstracto.core.repository.AllowedMentionRepository;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Optional;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class AllowedMentionManagementServiceBeanTest {
@InjectMocks
private AllowedMentionManagementServiceBean testUnit;
@Mock
private AllowedMentionRepository allowedMentionRepository;
@Mock
private ServerManagementService serverManagementService;
@Mock
private AllowedMention allowedMention;
@Mock
private AServer server;
private static final Long SERVER_ID = 4L;
@Test
public void getCustomAllowedMentionForIdExisting() {
when(allowedMentionRepository.findById(SERVER_ID)).thenReturn(Optional.of(allowedMention));
Optional<AllowedMention> foundMentionOptional = testUnit.getCustomAllowedMentionFor(SERVER_ID);
Assert.assertTrue(foundMentionOptional.isPresent());
foundMentionOptional.ifPresent(foundMention -> Assert.assertEquals(allowedMention, foundMention));
}
@Test
public void getCustomAllowedMentionForIdNotExisting() {
when(allowedMentionRepository.findById(SERVER_ID)).thenReturn(Optional.empty());
Optional<AllowedMention> foundMentionOptional = testUnit.getCustomAllowedMentionFor(SERVER_ID);
Assert.assertFalse(foundMentionOptional.isPresent());
}
@Test
public void testGetCustomAllowedMentionForServer() {
when(allowedMentionRepository.findByServer(server)).thenReturn(Optional.of(allowedMention));
Optional<AllowedMention> foundMentionOptional = testUnit.getCustomAllowedMentionFor(server);
Assert.assertTrue(foundMentionOptional.isPresent());
foundMentionOptional.ifPresent(foundMention -> Assert.assertEquals(allowedMention, foundMention));
}
@Test
public void hasCustomAllowedMention() {
when(allowedMentionRepository.findById(SERVER_ID)).thenReturn(Optional.of(allowedMention));
Assert.assertTrue(testUnit.hasCustomAllowedMention(SERVER_ID));
}
@Test
public void createCustomAllowedMention() {
when(serverManagementService.loadOrCreate(SERVER_ID)).thenReturn(server);
AllowedMention createdMention = testUnit.createCustomAllowedMention(SERVER_ID, allowedMention);
ArgumentCaptor<AllowedMention> mentionCaptor = ArgumentCaptor.forClass(AllowedMention.class);
verify(allowedMentionRepository, times(1)).save(mentionCaptor.capture());
Assert.assertEquals(createdMention, mentionCaptor.getValue());
Assert.assertEquals(server, createdMention.getServer());
}
@Test
public void deleteCustomAllowedMention() {
testUnit.deleteCustomAllowedMention(SERVER_ID);
verify(allowedMentionRepository, times(1)).deleteById(SERVER_ID);
}
}

View File

@@ -0,0 +1,15 @@
package dev.sheldan.abstracto.core.exception;
import dev.sheldan.abstracto.templating.Templatable;
public class UnknownMentionTypeException extends AbstractoRunTimeException implements Templatable {
@Override
public String getTemplateName() {
return "unknown_mention_type_exception";
}
@Override
public Object getTemplateModel() {
return new Object();
}
}

View File

@@ -44,9 +44,14 @@ public class AServer implements SnowFlake, Serializable {
this.updated = Instant.now();
}
@OneToOne(mappedBy = "server", cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
private AllowedMention allowedMention;
@OneToMany(
fetch = FetchType.LAZY,
orphanRemoval = true,
cascade = {CascadeType.PERSIST, CascadeType.MERGE},
mappedBy = "server")
@Builder.Default
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

View File

@@ -0,0 +1,64 @@
package dev.sheldan.abstracto.core.models.database;
import lombok.*;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.io.Serializable;
import java.time.Instant;
@Entity
@Table(name="allowed_mention")
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@Cacheable
@Getter
@Setter
@ToString
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class AllowedMention implements Serializable {
@Id
@Column(name = "server_id")
private Long id;
@OneToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@MapsId
@JoinColumn(name = "server_id")
private AServer server;
@Getter
@Column(name = "everyone_mention")
private Boolean everyone;
@Getter
@Column(name = "user_mention")
private Boolean user;
@Getter
@Column(name = "role_mention")
private Boolean role;
@Column(name = "created")
private Instant created;
@PrePersist
private void onInsert() {
this.created = Instant.now();
}
@Column(name = "updated")
private Instant updateTimestamp;
@PreUpdate
private void onUpdate() {
this.updateTimestamp = Instant.now();
}
public boolean allAllowed() {
return everyone && user && role;
}
}

View File

@@ -0,0 +1,16 @@
package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.models.database.AllowedMention;
import net.dv8tion.jda.api.entities.Message;
import java.util.List;
public interface AllowedMentionService {
boolean allMentionsAllowed(Long serverId);
List<Message.MentionType> getAllowedMentionTypesForServer(Long serverId);
void allowMentionForServer(Message.MentionType mentionType, Long serverId);
void disAllowMentionForServer(Message.MentionType mentionType, Long serverId);
AllowedMention getDefaultAllowedMention();
AllowedMention getEffectiveAllowedMention(Long serverId);
Message.MentionType getMentionTypeFromString(String input);
}

View File

@@ -0,0 +1,14 @@
package dev.sheldan.abstracto.core.service.management;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AllowedMention;
import java.util.Optional;
public interface AllowedMentionManagementService {
Optional<AllowedMention> getCustomAllowedMentionFor(Long serverId);
Optional<AllowedMention> getCustomAllowedMentionFor(AServer server);
boolean hasCustomAllowedMention(Long serverId);
AllowedMention createCustomAllowedMention(Long server, AllowedMention base);
void deleteCustomAllowedMention(Long serverId);
}

View File

@@ -114,6 +114,14 @@ Listing all feature modes::
Setting up a feature with an interactive wizard::
Usage: `setupFeature <featureName>`
* Description: Starts an interactive wizard to configure the necessary properties and post targets of a feature. Also includes custom steps. Closes with a summary page to see all changes.
Allow the bot to use certain mentions::
Usage: `allowMention <mentionType>`
* Description: Allows the bot to use certain mentions. ´mentionType` can either be `everyone`, `role` or `user`. If @everyone is enabled, this also enabled @here mentions.
This change takes immediate effect and is only for the current server. Per default user and role mentions are enabled.
Disallow the bot to use certain mentions::
Usage: `disallowMention <mentionType>`
* Description: Disallows the bot to use certain mentions. ´mentionType` can either be `everyone`, `role` or `user`. If @everyone is disabled, this also disables @here mentions.
This change takes immediate effect and is only for the current server. Per default everyone/here mentions are disabled.
.What does it mean if a role is immune?