Settings: use class constants for properties, create custom writer

- Create Property class for defining config properties
  - Create logic for typed retrival of properties from YAML file
- Add custom save method
  - Retain comments from Comment annotations in the classes
  - Write in a sorted order: first discovered properties are first written to config.yml
- Adjust properties to reflect the current config.yml
- Add sample tests for the retrieval and writing of properties with the new setup
This commit is contained in:
ljacqu
2016-01-03 15:22:32 +01:00
parent c2deb9d0b5
commit 7d41ccbc9c
23 changed files with 1225 additions and 518 deletions
@@ -0,0 +1,111 @@
package fr.xephi.authme.settings.custom;
import fr.xephi.authme.settings.custom.domain.Property;
import fr.xephi.authme.settings.custom.domain.PropertyType;
import org.bukkit.configuration.file.YamlConfiguration;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.io.File;
import java.net.URL;
import java.util.List;
import static fr.xephi.authme.settings.custom.domain.Property.newProperty;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.equalTo;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
public class NewSettingTest {
private static final String CONFIG_FILE = "437-config-test.yml";
@Test
public void shouldReturnIntegerFromFile() {
// given
YamlConfiguration file = mock(YamlConfiguration.class);
Property<Integer> config = TestConfiguration.DURATION_IN_SECONDS;
given(file.getInt("test.duration", 4)).willReturn(18);
NewSetting settings = new NewSetting(file, "conf.txt");
// when
int retrieve = settings.getOption(config);
// then
assertThat(retrieve, equalTo(18));
}
@Test
public void shouldLoadAllConfigs() {
// given
YamlConfiguration file = mock(YamlConfiguration.class);
given(file.getString(anyString(), anyString())).willAnswer(new Answer<String>() {
@Override
public String answer(InvocationOnMock invocation) throws Throwable {
// Return the second parameter -> the default
return (String) invocation.getArguments()[1];
}
});
given(file.getInt(eq(EmailSettings.RECOVERY_PASSWORD_LENGTH.getPath()), anyInt()))
.willReturn(20);
given(file.getBoolean(eq(SecuritySettings.REMOVE_PASSWORD_FROM_CONSOLE.getPath()), anyBoolean()))
.willReturn(false);
// when
NewSetting settings = new NewSetting(file, "conf.txt");
// then
// Expect the value we told the YAML mock to return:
assertThat(settings.getOption(EmailSettings.RECOVERY_PASSWORD_LENGTH), equalTo(20));
// Expect the default:
assertThat(settings.getOption(EmailSettings.SMTP_HOST), equalTo(EmailSettings.SMTP_HOST.getDefaultValue()));
// Expect the value we told the YAML mock to return:
assertThat(settings.getOption(SecuritySettings.REMOVE_PASSWORD_FROM_CONSOLE), equalTo(false));
}
@Test
public void executeIntegrationTest() {
// given
YamlConfiguration yamlFile = YamlConfiguration.loadConfiguration(getConfigFile());
NewSetting settings = new NewSetting(yamlFile, "conf.txt");
// when
int result = settings.getOption(TestConfiguration.DURATION_IN_SECONDS);
String systemName = settings.getOption(TestConfiguration.SYSTEM_NAME);
String helpHeader = settings.getOption(newProperty("settings.helpHeader", ""));
List<String> unsafePasswords = settings.getOption(
newProperty(PropertyType.STRING_LIST, "Security.unsafePasswords"));
// then
assertThat(result, equalTo(22));
assertThat(systemName, equalTo(TestConfiguration.SYSTEM_NAME.getDefaultValue()));
assertThat(helpHeader, equalTo("AuthMeReloaded"));
assertThat(unsafePasswords, contains("123456", "qwerty", "54321"));
}
private File getConfigFile() {
URL url = getClass().getClassLoader().getResource(CONFIG_FILE);
if (url == null) {
throw new RuntimeException("File '" + CONFIG_FILE + "' could not be loaded");
}
return new File(url.getFile());
}
private static class TestConfiguration {
public static final Property<Integer> DURATION_IN_SECONDS =
newProperty("test.duration", 4);
public static final Property<String> SYSTEM_NAME =
newProperty("test.systemName", "[TestDefaultValue]");
}
}
@@ -0,0 +1,42 @@
package fr.xephi.authme.settings.custom;
import org.junit.Test;
import java.io.File;
import java.net.URL;
import static org.junit.Assert.assertThat;
import static org.hamcrest.Matchers.equalTo;
/**
* Test for the save() function of new settings
*/
public class NewSettingsWriteTest {
private static final String CONFIG_FILE = "437-write-test.yml";
@Test
public void shouldWriteProperties() {
File file = getConfigFile();
NewSetting setting = new NewSetting(file);
setting.save();
// assert that we can load the file again -- i.e. that it's valid YAML!
NewSetting newSetting = new NewSetting(file);
assertThat(newSetting.getOption(SecuritySettings.CAPTCHA_LENGTH),
equalTo(SecuritySettings.CAPTCHA_LENGTH.getDefaultValue()));
assertThat(newSetting.getOption(ProtectionSettings.COUNTRIES_BLACKLIST),
equalTo(ProtectionSettings.COUNTRIES_BLACKLIST.getDefaultValue()));
}
private File getConfigFile() {
URL url = getClass().getClassLoader().getResource(CONFIG_FILE);
if (url == null) {
throw new RuntimeException("File '" + CONFIG_FILE + "' could not be loaded");
}
return new File(url.getFile());
}
}
+44
View File
@@ -0,0 +1,44 @@
test:
duration: 22
DataSource:
# What type of database do you want to use?
# Valid values: sqlite, mysql
backend: sqlite
# Enable database caching, should improve database performance
caching: true
settings:
# The name shown in the help messages.
helpHeader: AuthMeReloaded
GameMode:
# ForceSurvivalMode to player when join ?
ForceSurvivalMode: false
Security:
SQLProblem:
# Stop the server if we can't contact the sql database
# Take care with this, if you set that to false,
# AuthMe automatically disable and the server is not protected!
stopServer: true
ReloadCommand:
# /reload support
useReloadCommandSupport: true
console:
# Remove spam console
noConsoleSpam: false
# Replace passwords in the console when player type a command like /login
removePassword: true
captcha:
# Player need to put a captcha when he fails too lot the password
useCaptcha: false
# Max allowed tries before request a captcha
maxLoginTry: 5
# Captcha length
captchaLength: 5
unsafePasswords:
- '123456'
- 'qwerty'
- '54321'
Email:
# Email SMTP server host
mailSMTP: smtp.gmail.com
# Email SMTP server port
mailPort: 465
+172
View File
@@ -0,0 +1,172 @@
Converter:
Rakamak:
# Rakamak file name
fileName: 'users.rak'
# Rakamak use IP?
useIP: false
# Rakamak IP file name
ipFileName: 'UsersIp.rak'
CrazyLogin:
# CrazyLogin database file name
fileName: 'accounts.db'
DataSource:
# What type of database do you want to use?
# Valid values: sqlite, mysql
backend: 'sqlite'
# Enable database caching, should improve database performance
caching: true
# Database host address
mySQLHost: '127.0.0.1'
# Database port
mySQLPort: '3306'
# Username about Database Connection Infos
mySQLUsername: 'authme'
# Password about Database Connection Infos
mySQLPassword: '123456'
# Database Name, use with converters or as SQLITE database name
mySQLDatabase: 'authme'
# Table of the database
mySQLTablename: 'authme'
# Column of IDs to sort data
mySQLColumnId: 'id'
# Column for storing or checking players nickname
mySQLColumnName: 'username'
# Column for storing or checking players RealName
mySQLRealName: 'realname'
# Column for storing players passwords
mySQLColumnPassword: 'password'
# Column for storing players emails
mySQLColumnEmail: 'email'
# Column for storing if a player is logged in or not
mySQLColumnLogged: 'email'
# Column for storing players ips
mySQLColumnIp: 'ip'
# Column for storing players lastlogins
mySQLColumnLastLogin: 'lastlogin'
# Column for storing player LastLocation - X
mySQLlastlocX: 'x'
# Column for storing player LastLocation - Y
mySQLlastlocY: 'y'
# Column for storing player LastLocation - Z
mySQLlastlocZ: 'z'
# Column for storing player LastLocation - World Name
mySQLlastlocWorld: 'world'
# Enable this when you allow registration through a website
mySQLWebsite: false
ExternalBoardOptions:
# Column for storing players passwords salts
mySQLColumnSalt: ''
# Column for storing players groups
mySQLColumnGroup: ''
Email:
# Email SMTP server host
mailSMTP: 'smtp.gmail.com'
# Email SMTP server port
mailPort: 465
# Email account which sends the mails
mailAccount: ''
# Email account password
mailPassword: ''
# Recovery password length
RecoveryPasswordLength: 8
# Mail Subject
mailSubject: 'Your new AuthMe password'
# Like maxRegPerIP but with email
maxRegPerEmail: 1
# Recall players to add an email?
recallPlayers: false
# Delay in minute for the recall scheduler
delayRecall: 5
# Blacklist these domains for emails
emailBlacklisted:
- '10minutemail.com'
# Whitelist ONLY these domains for emails
emailWhitelisted: []
# Send the new password drawn in an image?
generateImage: false
# The OAuth2 token
emailOauth2Token: ''
Hooks:
# Do we need to hook with multiverse for spawn checking?
multiverse: true
# Do we need to hook with BungeeCord?
bungeecord: false
# Do we need to disable Essentials SocialSpy on join?
disableSocialSpy: false
# Do we need to force /motd Essentials command on join?
useEssentialsMotd: false
# Do we need to cache custom Attributes?
customAttributes: false
bungeecord:
# Send player to this BungeeCord server after register/login
server: ''
Protection:
# Enable some servers protection (country based login, antibot)
enableProtection: false
# Countries allowed to join the server and register, see http://dev.bukkit.org/bukkit-plugins/authme-reloaded/pages/countries-codes/ for countries' codes
# PLEASE USE QUOTES!
countries:
- 'US'
- 'GB'
- 'A1'
# Countries not allowed to join the server and register
# PLEASE USE QUOTES!
countriesBlacklist: []
# Do we need to enable automatic antibot system?
enableAntiBot: false
# Max number of player allowed to login in 5 secs before enable AntiBot system automatically
antiBotSensibility: 5
# Duration in minutes of the antibot automatic system
antiBotDuration: 10
Purge:
# If enabled, AuthMe automatically purges old, unused accounts
useAutoPurge: false
# Number of Days an account become Unused
daysBeforeRemovePlayer: 60
# Do we need to remove the player.dat file during purge process?
removePlayerDat: false
# Do we need to remove the Essentials/users/player.yml file during purge process?
removeEssentialsFiles: false
# World where are players.dat stores
defaultWorld: 'world'
# Do we need to remove LimitedCreative/inventories/player.yml, player_creative.yml files during purge process ?
removeLimitedCreativesInventories: false
# Do we need to remove the AntiXRayData/PlayerData/player file during purge process?
removeAntiXRayFile: false
# Do we need to remove permissions?
removePermissions: false
Security:
SQLProblem:
# Stop the server if we can't contact the sql database
# Take care with this, if you set this to false,
# AuthMe will automatically disable and the server won't be protected!
stopServer: true
ReloadCommand:
# /reload support
useReloadCommandSupport: true
console:
# Remove spam from console?
noConsoleSpam: false
# Remove passwords from console?
removePassword: true
captcha:
# Player need to put a captcha when he fails too lot the password
useCaptcha: false
# Max allowed tries before request a captcha
maxLoginTry: 5
# Captcha length
captchaLength: 5
stop:
# Kick players before stopping the server, that allow us to save position of players
# and all needed information correctly without any corruption.
kickPlayersBeforeStopping: true