Encapsulate GeoLiteAPI class
This commit is contained in:
parent
1326606f37
commit
1361174892
@ -115,6 +115,7 @@ public class AuthMe extends JavaPlugin {
|
|||||||
private SpawnLoader spawnLoader;
|
private SpawnLoader spawnLoader;
|
||||||
private BukkitService bukkitService;
|
private BukkitService bukkitService;
|
||||||
private AuthMeServiceInitializer initializer;
|
private AuthMeServiceInitializer initializer;
|
||||||
|
private GeoLiteAPI geoLiteApi;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Private instances (mail and ProtocolLib)
|
* Private instances (mail and ProtocolLib)
|
||||||
@ -256,9 +257,6 @@ public class AuthMe extends JavaPlugin {
|
|||||||
// Set console filter
|
// Set console filter
|
||||||
setupConsoleFilter();
|
setupConsoleFilter();
|
||||||
|
|
||||||
// Download and load GeoIp.dat file if absent
|
|
||||||
GeoLiteAPI.isDataAvailable();
|
|
||||||
|
|
||||||
// Set up the mail API
|
// Set up the mail API
|
||||||
setupMailApi();
|
setupMailApi();
|
||||||
|
|
||||||
@ -313,6 +311,7 @@ public class AuthMe extends JavaPlugin {
|
|||||||
commandHandler = initializer.get(CommandHandler.class);
|
commandHandler = initializer.get(CommandHandler.class);
|
||||||
api = initializer.get(NewAPI.class);
|
api = initializer.get(NewAPI.class);
|
||||||
management = initializer.get(Management.class);
|
management = initializer.get(Management.class);
|
||||||
|
geoLiteApi = initializer.get(GeoLiteAPI.class);
|
||||||
initializer.get(API.class);
|
initializer.get(API.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -678,7 +677,7 @@ public class AuthMe extends JavaPlugin {
|
|||||||
.replace("{WORLD}", player.getWorld().getName())
|
.replace("{WORLD}", player.getWorld().getName())
|
||||||
.replace("{SERVER}", server.getServerName())
|
.replace("{SERVER}", server.getServerName())
|
||||||
.replace("{VERSION}", server.getBukkitVersion())
|
.replace("{VERSION}", server.getBukkitVersion())
|
||||||
.replace("{COUNTRY}", GeoLiteAPI.getCountryName(ipAddress));
|
.replace("{COUNTRY}", geoLiteApi.getCountryName(ipAddress));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
package fr.xephi.authme.settings;
|
package fr.xephi.authme.settings;
|
||||||
|
|
||||||
import fr.xephi.authme.AuthMe;
|
|
||||||
import fr.xephi.authme.ConsoleLogger;
|
import fr.xephi.authme.ConsoleLogger;
|
||||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||||
import fr.xephi.authme.datasource.DataSource;
|
import fr.xephi.authme.datasource.DataSource;
|
||||||
@ -145,8 +144,7 @@ public class SpawnLoader implements Reloadable {
|
|||||||
* @see RestrictionSettings#SPAWN_PRIORITY
|
* @see RestrictionSettings#SPAWN_PRIORITY
|
||||||
*/
|
*/
|
||||||
public Location getSpawnLocation(Player player) {
|
public Location getSpawnLocation(Player player) {
|
||||||
AuthMe plugin = AuthMe.getInstance();
|
if (player == null || player.getWorld() == null) {
|
||||||
if (plugin == null || player == null || player.getWorld() == null) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
package fr.xephi.authme.util;
|
package fr.xephi.authme.util;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.maxmind.geoip.LookupService;
|
import com.maxmind.geoip.LookupService;
|
||||||
import fr.xephi.authme.AuthMe;
|
|
||||||
import fr.xephi.authme.ConsoleLogger;
|
import fr.xephi.authme.ConsoleLogger;
|
||||||
|
import fr.xephi.authme.initialization.DataFolder;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -19,10 +21,22 @@ public class GeoLiteAPI {
|
|||||||
"[LICENSE] This product uses data from the GeoLite API created by MaxMind, available at http://www.maxmind.com";
|
"[LICENSE] This product uses data from the GeoLite API created by MaxMind, available at http://www.maxmind.com";
|
||||||
private static final String GEOIP_URL =
|
private static final String GEOIP_URL =
|
||||||
"http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz";
|
"http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz";
|
||||||
private static LookupService lookupService;
|
private LookupService lookupService;
|
||||||
private static Thread downloadTask;
|
private Thread downloadTask;
|
||||||
|
|
||||||
private GeoLiteAPI() {
|
private final File dataFile;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
GeoLiteAPI(@DataFolder File dataFolder) {
|
||||||
|
this.dataFile = new File(dataFolder, "GeoIP.dat");
|
||||||
|
// Fires download of recent data or the initialization of the look up service
|
||||||
|
isDataAvailable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
GeoLiteAPI(@DataFolder File dataFolder, LookupService lookupService) {
|
||||||
|
this.dataFile = dataFolder;
|
||||||
|
this.lookupService = lookupService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,20 +44,19 @@ public class GeoLiteAPI {
|
|||||||
*
|
*
|
||||||
* @return True if the data is available, false otherwise.
|
* @return True if the data is available, false otherwise.
|
||||||
*/
|
*/
|
||||||
public synchronized static boolean isDataAvailable() {
|
private synchronized boolean isDataAvailable() {
|
||||||
if (downloadTask != null && downloadTask.isAlive()) {
|
if (downloadTask != null && downloadTask.isAlive()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (lookupService != null) {
|
if (lookupService != null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
final File pluginFolder = AuthMe.getInstance().getDataFolder();
|
|
||||||
final File data = new File(pluginFolder, "GeoIP.dat");
|
if (dataFile.exists()) {
|
||||||
if (data.exists()) {
|
boolean dataIsOld = (System.currentTimeMillis() - dataFile.lastModified()) > TimeUnit.DAYS.toMillis(30);
|
||||||
boolean dataIsOld = (System.currentTimeMillis() - data.lastModified()) > TimeUnit.DAYS.toMillis(30);
|
|
||||||
if (!dataIsOld) {
|
if (!dataIsOld) {
|
||||||
try {
|
try {
|
||||||
lookupService = new LookupService(data);
|
lookupService = new LookupService(dataFile);
|
||||||
ConsoleLogger.info(LICENSE);
|
ConsoleLogger.info(LICENSE);
|
||||||
return true;
|
return true;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -51,13 +64,19 @@ public class GeoLiteAPI {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!data.delete()) {
|
if (!dataFile.delete()) {
|
||||||
ConsoleLogger.showError("Failed to delete GeoLiteAPI database");
|
ConsoleLogger.showError("Failed to delete GeoLiteAPI database");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Ok, let's try to download the data file!
|
// Ok, let's try to download the data file!
|
||||||
downloadTask = new Thread(new Runnable() {
|
downloadTask = createDownloadTask();
|
||||||
|
downloadTask.start();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Thread createDownloadTask() {
|
||||||
|
return new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
@ -69,7 +88,7 @@ public class GeoLiteAPI {
|
|||||||
if (conn.getURL().toString().endsWith(".gz")) {
|
if (conn.getURL().toString().endsWith(".gz")) {
|
||||||
input = new GZIPInputStream(input);
|
input = new GZIPInputStream(input);
|
||||||
}
|
}
|
||||||
OutputStream output = new FileOutputStream(data);
|
OutputStream output = new FileOutputStream(dataFile);
|
||||||
byte[] buffer = new byte[2048];
|
byte[] buffer = new byte[2048];
|
||||||
int length = input.read(buffer);
|
int length = input.read(buffer);
|
||||||
while (length >= 0) {
|
while (length >= 0) {
|
||||||
@ -83,8 +102,6 @@ public class GeoLiteAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
downloadTask.start();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,7 +111,7 @@ public class GeoLiteAPI {
|
|||||||
*
|
*
|
||||||
* @return two-character ISO 3166-1 alpha code for the country.
|
* @return two-character ISO 3166-1 alpha code for the country.
|
||||||
*/
|
*/
|
||||||
public static String getCountryCode(String ip) {
|
public String getCountryCode(String ip) {
|
||||||
if (!"127.0.0.1".equals(ip) && isDataAvailable()) {
|
if (!"127.0.0.1".equals(ip) && isDataAvailable()) {
|
||||||
return lookupService.getCountry(ip).getCode();
|
return lookupService.getCountry(ip).getCode();
|
||||||
}
|
}
|
||||||
@ -108,7 +125,7 @@ public class GeoLiteAPI {
|
|||||||
*
|
*
|
||||||
* @return The name of the country.
|
* @return The name of the country.
|
||||||
*/
|
*/
|
||||||
public static String getCountryName(String ip) {
|
public String getCountryName(String ip) {
|
||||||
if (!"127.0.0.1".equals(ip) && isDataAvailable()) {
|
if (!"127.0.0.1".equals(ip) && isDataAvailable()) {
|
||||||
return lookupService.getCountry(ip).getName();
|
return lookupService.getCountry(ip).getName();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import fr.xephi.authme.settings.properties.RestrictionSettings;
|
|||||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -23,19 +24,20 @@ import java.util.regex.Pattern;
|
|||||||
*/
|
*/
|
||||||
public class ValidationService implements Reloadable {
|
public class ValidationService implements Reloadable {
|
||||||
|
|
||||||
private final NewSetting settings;
|
@Inject
|
||||||
private final DataSource dataSource;
|
private NewSetting settings;
|
||||||
private final PermissionsManager permissionsManager;
|
@Inject
|
||||||
|
private DataSource dataSource;
|
||||||
|
@Inject
|
||||||
|
private PermissionsManager permissionsManager;
|
||||||
|
@Inject
|
||||||
|
private GeoLiteAPI geoLiteApi;
|
||||||
|
|
||||||
private Pattern passwordRegex;
|
private Pattern passwordRegex;
|
||||||
|
|
||||||
@Inject
|
ValidationService() { }
|
||||||
public ValidationService(NewSetting settings, DataSource dataSource, PermissionsManager permissionsManager) {
|
|
||||||
this.settings = settings;
|
|
||||||
this.dataSource = dataSource;
|
|
||||||
this.permissionsManager = permissionsManager;
|
|
||||||
reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
@Override
|
@Override
|
||||||
public void reload() {
|
public void reload() {
|
||||||
passwordRegex = Utils.safePatternCompile(settings.getProperty(RestrictionSettings.ALLOWED_PASSWORD_REGEX));
|
passwordRegex = Utils.safePatternCompile(settings.getProperty(RestrictionSettings.ALLOWED_PASSWORD_REGEX));
|
||||||
@ -105,7 +107,7 @@ public class ValidationService implements Reloadable {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
String countryCode = GeoLiteAPI.getCountryCode(hostAddress);
|
String countryCode = geoLiteApi.getCountryCode(hostAddress);
|
||||||
return validateWhitelistAndBlacklist(countryCode,
|
return validateWhitelistAndBlacklist(countryCode,
|
||||||
ProtectionSettings.COUNTRIES_WHITELIST,
|
ProtectionSettings.COUNTRIES_WHITELIST,
|
||||||
ProtectionSettings.COUNTRIES_BLACKLIST);
|
ProtectionSettings.COUNTRIES_BLACKLIST);
|
||||||
|
|||||||
104
src/test/java/fr/xephi/authme/util/GeoLiteAPITest.java
Normal file
104
src/test/java/fr/xephi/authme/util/GeoLiteAPITest.java
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package fr.xephi.authme.util;
|
||||||
|
|
||||||
|
import com.maxmind.geoip.Country;
|
||||||
|
import com.maxmind.geoip.LookupService;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.TemporaryFolder;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.mockito.BDDMockito.given;
|
||||||
|
import static org.mockito.Matchers.anyString;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for {@link GeoLiteAPI}.
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class GeoLiteAPITest {
|
||||||
|
|
||||||
|
private GeoLiteAPI geoLiteApi;
|
||||||
|
private File dataFolder;
|
||||||
|
@Mock
|
||||||
|
private LookupService lookupService;
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void initializeGeoLiteApi() throws IOException {
|
||||||
|
dataFolder = temporaryFolder.newFolder();
|
||||||
|
geoLiteApi = new GeoLiteAPI(dataFolder, lookupService);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldGetCountry() {
|
||||||
|
// given
|
||||||
|
String ip = "123.45.67.89";
|
||||||
|
String countryCode = "XX";
|
||||||
|
Country country = mock(Country.class);
|
||||||
|
given(country.getCode()).willReturn(countryCode);
|
||||||
|
given(lookupService.getCountry(ip)).willReturn(country);
|
||||||
|
|
||||||
|
// when
|
||||||
|
String result = geoLiteApi.getCountryCode(ip);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result, equalTo(countryCode));
|
||||||
|
verify(lookupService).getCountry(ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldNotLookUpCountryForLocalhostIp() {
|
||||||
|
// given
|
||||||
|
String ip = "127.0.0.1";
|
||||||
|
|
||||||
|
// when
|
||||||
|
String result = geoLiteApi.getCountryCode(ip);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result, equalTo("--"));
|
||||||
|
verify(lookupService, never()).getCountry(anyString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldLookUpCountryName() {
|
||||||
|
// given
|
||||||
|
String ip = "24.45.167.89";
|
||||||
|
String countryName = "Ecuador";
|
||||||
|
Country country = mock(Country.class);
|
||||||
|
given(country.getName()).willReturn(countryName);
|
||||||
|
given(lookupService.getCountry(ip)).willReturn(country);
|
||||||
|
|
||||||
|
// when
|
||||||
|
String result = geoLiteApi.getCountryName(ip);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result, equalTo(countryName));
|
||||||
|
verify(lookupService).getCountry(ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldNotLookUpCountryNameForLocalhostIp() {
|
||||||
|
// given
|
||||||
|
String ip = "127.0.0.1";
|
||||||
|
|
||||||
|
// when
|
||||||
|
String result = geoLiteApi.getCountryName(ip);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result, equalTo("N/A"));
|
||||||
|
verify(lookupService, never()).getCountry(ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -5,17 +5,18 @@ import fr.xephi.authme.datasource.DataSource;
|
|||||||
import fr.xephi.authme.output.MessageKey;
|
import fr.xephi.authme.output.MessageKey;
|
||||||
import fr.xephi.authme.permission.PermissionsManager;
|
import fr.xephi.authme.permission.PermissionsManager;
|
||||||
import fr.xephi.authme.permission.PlayerStatePermission;
|
import fr.xephi.authme.permission.PlayerStatePermission;
|
||||||
|
import fr.xephi.authme.runner.BeforeInjecting;
|
||||||
|
import fr.xephi.authme.runner.DelayedInjectionRunner;
|
||||||
|
import fr.xephi.authme.runner.InjectDelayed;
|
||||||
import fr.xephi.authme.settings.NewSetting;
|
import fr.xephi.authme.settings.NewSetting;
|
||||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||||
import fr.xephi.authme.util.ValidationService.ValidationResult;
|
import fr.xephi.authme.util.ValidationService.ValidationResult;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -28,9 +29,10 @@ import static org.mockito.Mockito.mock;
|
|||||||
/**
|
/**
|
||||||
* Test for {@link ValidationService}.
|
* Test for {@link ValidationService}.
|
||||||
*/
|
*/
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(DelayedInjectionRunner.class)
|
||||||
public class ValidationServiceTest {
|
public class ValidationServiceTest {
|
||||||
|
|
||||||
|
@InjectDelayed
|
||||||
private ValidationService validationService;
|
private ValidationService validationService;
|
||||||
@Mock
|
@Mock
|
||||||
private NewSetting settings;
|
private NewSetting settings;
|
||||||
@ -38,8 +40,10 @@ public class ValidationServiceTest {
|
|||||||
private DataSource dataSource;
|
private DataSource dataSource;
|
||||||
@Mock
|
@Mock
|
||||||
private PermissionsManager permissionsManager;
|
private PermissionsManager permissionsManager;
|
||||||
|
@Mock
|
||||||
|
private GeoLiteAPI geoLiteApi;
|
||||||
|
|
||||||
@Before
|
@BeforeInjecting
|
||||||
public void createService() {
|
public void createService() {
|
||||||
given(settings.getProperty(RestrictionSettings.ALLOWED_PASSWORD_REGEX)).willReturn("[a-zA-Z]+");
|
given(settings.getProperty(RestrictionSettings.ALLOWED_PASSWORD_REGEX)).willReturn("[a-zA-Z]+");
|
||||||
given(settings.getProperty(SecuritySettings.MIN_PASSWORD_LENGTH)).willReturn(3);
|
given(settings.getProperty(SecuritySettings.MIN_PASSWORD_LENGTH)).willReturn(3);
|
||||||
@ -47,7 +51,6 @@ public class ValidationServiceTest {
|
|||||||
given(settings.getProperty(SecuritySettings.UNSAFE_PASSWORDS))
|
given(settings.getProperty(SecuritySettings.UNSAFE_PASSWORDS))
|
||||||
.willReturn(Arrays.asList("unsafe", "other-unsafe"));
|
.willReturn(Arrays.asList("unsafe", "other-unsafe"));
|
||||||
given(settings.getProperty(EmailSettings.MAX_REG_PER_EMAIL)).willReturn(3);
|
given(settings.getProperty(EmailSettings.MAX_REG_PER_EMAIL)).willReturn(3);
|
||||||
validationService = new ValidationService(settings, dataSource, permissionsManager);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user