Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ CHANGELOG
-------------------
* The HTTP client now allows up to 20 connections to be active at once.
Previously the limit was 2.
* The `isResidentialProxy()` method was added to
`com.maxmind.geoip2.model.AnonymousIpResponse` and
`com.maxmind.geoip2.record.Traits` for use with the Anonymous IP database
and GeoIP2 Precision insights.

2.14.0 (2020-06-15)
-------------------
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ try {
System.out.println(response.isAnonymousVpn()); // false
System.out.println(response.isHostingProvider()); // false
System.out.println(response.isPublicProxy()); // false
System.out.println(response.isResidentialProxy()); // false
System.out.println(response.isTorExitNode()); //true
} finally {
reader.close();
Expand Down
28 changes: 26 additions & 2 deletions src/main/java/com/maxmind/geoip2/model/AnonymousIpResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class AnonymousIpResponse extends AbstractResponse {
private final boolean isAnonymousVpn;
private final boolean isHostingProvider;
private final boolean isPublicProxy;
private final boolean isResidentialProxy;
private final boolean isTorExitNode;
private final String ipAddress;
private final Network network;
Expand All @@ -37,19 +38,34 @@ public AnonymousIpResponse(
this(ipAddress, isAnonymous, isAnonymousVpn, isHostingProvider, isPublicProxy, isTorExitNode, null);
}

// This is for compatibility and should be removed if we do a major release.
public AnonymousIpResponse(
String ipAddress,
boolean isAnonymous,
boolean isAnonymousVpn,
boolean isHostingProvider,
boolean isPublicProxy,
boolean isTorExitNode,
Network network
) {
this(ipAddress, isAnonymous, isAnonymousVpn, isHostingProvider, isPublicProxy, false, isTorExitNode, network);
}

public AnonymousIpResponse(
@JacksonInject("ip_address") @JsonProperty("ip_address") String ipAddress,
@JsonProperty("is_anonymous") boolean isAnonymous,
@JsonProperty("is_anonymous_vpn") boolean isAnonymousVpn,
@JsonProperty("is_hosting_provider") boolean isHostingProvider,
@JsonProperty("is_public_proxy") boolean isPublicProxy,
@JsonProperty("is_residential_proxy") boolean isResidentialProxy,
@JsonProperty("is_tor_exit_node") boolean isTorExitNode,
@JacksonInject("network") @JsonProperty("network") @JsonDeserialize(using = NetworkDeserializer.class) Network network
) {
this.isAnonymous = isAnonymous;
this.isAnonymousVpn = isAnonymousVpn;
this.isHostingProvider = isHostingProvider;
this.isPublicProxy = isPublicProxy;
this.isResidentialProxy = isResidentialProxy;
this.isTorExitNode = isTorExitNode;
this.ipAddress = ipAddress;
this.network = network;
Expand Down Expand Up @@ -91,6 +107,15 @@ public boolean isPublicProxy() {
return isPublicProxy;
}

/**
* @return whether the IP address is on a suspected anonymizing network and
* belongs to a residential ISP.
*/
@JsonProperty("is_residential_proxy")
public boolean isResidentialProxy() {
return isResidentialProxy;
}

/**
* @return whether the IP address is a Tor exit node.
*/
Expand All @@ -99,7 +124,6 @@ public boolean isTorExitNode() {
return isTorExitNode;
}


/**
* @return The IP address that the data in the model is for.
*/
Expand All @@ -118,4 +142,4 @@ public String getIpAddress() {
public Network getNetwork() {
return this.network;
}
}
}
50 changes: 47 additions & 3 deletions src/main/java/com/maxmind/geoip2/record/Traits.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public final class Traits extends AbstractRecord {
private final boolean isHostingProvider;
private final boolean isLegitimateProxy;
private final boolean isPublicProxy;
private final boolean isResidentialProxy;
private final boolean isSatelliteProvider;
private final boolean isTorExitNode;
private final String isp;
Expand Down Expand Up @@ -118,6 +119,37 @@ public Traits(
null, organization, userType, null, null);
}

// This is for back-compat. If we ever do a major release, it should be
// removed.
public Traits(
Integer autonomousSystemNumber,
String autonomousSystemOrganization,
ConnectionType connectionType,
String domain,
String ipAddress,
boolean isAnonymous,
boolean isAnonymousProxy,
boolean isAnonymousVpn,
boolean isHostingProvider,
boolean isLegitimateProxy,
boolean isPublicProxy,
boolean isSatelliteProvider,
boolean isTorExitNode,
String isp,
Network network,
String organization,
String userType,
Integer userCount,
Double staticIpScore
) {
this(autonomousSystemNumber, autonomousSystemOrganization,
connectionType, domain, ipAddress, isAnonymous,
isAnonymousProxy, isAnonymousVpn, isHostingProvider,
isLegitimateProxy, isPublicProxy, false, isSatelliteProvider,
isTorExitNode, isp, network, organization, userType, userCount,
staticIpScore);
}

public Traits(
@JsonProperty("autonomous_system_number") Integer autonomousSystemNumber,
@JsonProperty("autonomous_system_organization") String autonomousSystemOrganization,
Expand All @@ -130,6 +162,7 @@ public Traits(
@JsonProperty("is_hosting_provider") boolean isHostingProvider,
@JsonProperty("is_legitimate_proxy") boolean isLegitimateProxy,
@JsonProperty("is_public_proxy") boolean isPublicProxy,
@JsonProperty("is_residential_proxy") boolean isResidentialProxy,
@JsonProperty("is_satellite_provider") boolean isSatelliteProvider,
@JsonProperty("is_tor_exit_node") boolean isTorExitNode,
@JsonProperty("isp") String isp,
Expand All @@ -150,6 +183,7 @@ public Traits(
this.isHostingProvider = isHostingProvider;
this.isLegitimateProxy = isLegitimateProxy;
this.isPublicProxy = isPublicProxy;
this.isResidentialProxy = isResidentialProxy;
this.isSatelliteProvider = isSatelliteProvider;
this.isTorExitNode = isTorExitNode;
this.isp = isp;
Expand Down Expand Up @@ -294,9 +328,9 @@ public boolean isHostingProvider() {
}

/**
* @return True if MaxMind believes this IP address to be a legitimate
* proxy, such as an internal VPN used by a corporation. This is only
* available in the GeoIP2 Enterprise database.
* @return This is true if MaxMind believes this IP address to be a
* legitimate proxy, such as an internal VPN used by a corporation. This is
* only available in the GeoIP2 Enterprise database.
*/
@JsonProperty("is_legitimate_proxy")
public boolean isLegitimateProxy() {
Expand All @@ -312,6 +346,16 @@ public boolean isPublicProxy() {
return this.isPublicProxy;
}

/**
* @return This is true if the IP address is on a suspected anonymizing
* network and belongs to a residential ISP. This attribute is only
* available from GeoIP2 Precision Insights.
*/
@JsonProperty("is_residential_proxy")
public boolean isResidentialProxy() {
return this.isResidentialProxy;
}

/**
* @return This is true if the IP belong to a satellite Internet provider.
* This attribute is returned by all end points.
Expand Down
14 changes: 12 additions & 2 deletions src/test/java/com/maxmind/geoip2/DatabaseReaderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,6 @@ public void incorrectDatabaseMethod() throws Exception {
}
}


@Test
public void testAnonymousIp() throws Exception {
try (DatabaseReader reader = new DatabaseReader.Builder(
Expand All @@ -215,6 +214,7 @@ public void testAnonymousIp() throws Exception {
assertTrue(response.isAnonymousVpn());
assertFalse(response.isHostingProvider());
assertFalse(response.isPublicProxy());
assertFalse(response.isResidentialProxy());
assertFalse(response.isTorExitNode());
assertEquals(ipAddress.getHostAddress(), response.getIpAddress());
assertEquals("1.2.0.0/16", response.getNetwork().toString());
Expand All @@ -224,6 +224,17 @@ public void testAnonymousIp() throws Exception {
}
}

@Test
public void testAnonymousIpIsResidentialProxy() throws Exception {
try (DatabaseReader reader = new DatabaseReader.Builder(
this.getFile("GeoIP2-Anonymous-IP-Test.mmdb")).build()
) {
InetAddress ipAddress = InetAddress.getByName("81.2.69.1");
AnonymousIpResponse response = reader.anonymousIp(ipAddress);
assertTrue(response.isResidentialProxy());
}
}

@Test
public void testAsn() throws Exception {
try (DatabaseReader reader = new DatabaseReader.Builder(
Expand Down Expand Up @@ -291,7 +302,6 @@ public void testCountry() throws Exception {
InetAddress ipAddress = InetAddress.getByName("74.209.24.0");

CountryResponse response = reader.country(ipAddress);
assertEquals(99, response.getCountry().getConfidence().intValue());
assertEquals(6252001, response.getCountry().getGeoNameId().intValue());
assertEquals(ipAddress.getHostAddress(), response.getTraits().getIpAddress());
assertEquals("74.209.16.0/20", response.getTraits().getNetwork().toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ public void testTraits() {
assertTrue("traits.isAnonymousVpn() returns true", traits.isAnonymousVpn());
assertTrue("traits.isHostingProvider() returns true", traits.isHostingProvider());
assertTrue("traits.isPublicProxy() returns true", traits.isPublicProxy());
assertTrue("traits.isResidentialProxy() returns true", traits.isResidentialProxy());
assertTrue("traits.isSatelliteProvider() returns true", traits.isSatelliteProvider());
assertTrue("traits.isTorExitNode() returns true", traits.isTorExitNode());
assertEquals("traits.getIsp() does not return Comcast", "Comcast",
Expand Down
4 changes: 4 additions & 0 deletions src/test/java/com/maxmind/geoip2/model/JsonTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public void testInsightsSerialization() throws IOException {
.put("is_hosting_provider", true)
.put("is_legitimate_proxy", true)
.put("is_public_proxy", true)
.put("is_residential_proxy", true)
.put("is_satellite_provider", true)
.put("is_tor_exit_node", true)
.put("network", "1.2.3.0/24")
Expand Down Expand Up @@ -147,6 +148,7 @@ public void testCitySerialization() throws IOException {
.put("is_hosting_provider", false)
.put("is_legitimate_proxy", false)
.put("is_public_proxy", false)
.put("is_residential_proxy", false)
.put("is_tor_exit_node", false)
.put("network", "1.2.3.0/24")
.end()
Expand Down Expand Up @@ -234,6 +236,7 @@ public void testCountrySerialization() throws IOException {
.put("is_hosting_provider", false)
.put("is_legitimate_proxy", false)
.put("is_public_proxy", false)
.put("is_residential_proxy", false)
.put("is_tor_exit_node", false)
.put("network", "1.2.3.0/24")
.end()
Expand Down Expand Up @@ -276,6 +279,7 @@ public void testAnonymousIPSerialization() throws Exception {
.put("is_anonymous_vpn", true)
.put("is_hosting_provider", true)
.put("is_public_proxy", true)
.put("is_residential_proxy", false)
.put("is_tor_exit_node", true)
.put("ip_address", "1.1.1.1")
.put("network", "1.1.1.0/24")
Expand Down
2 changes: 1 addition & 1 deletion src/test/resources/maxmind-db
Submodule maxmind-db updated 41 files
+ bad-data/maxminddb-python/bad-unicode-in-map-key.mmdb
+2 −1 source-data/GeoIP2-Anonymous-IP-Test.json
+488 −488 source-data/GeoIP2-City-Test.json
+4,383 −17 source-data/GeoIP2-Country-Test.json
+48 −34 source-data/GeoIP2-Enterprise-Test.json
+3 −1 source-data/GeoIP2-ISP-Test.json
+199 −69 source-data/GeoIP2-Precision-Enterprise-Test.json
+426 −426 source-data/GeoIP2-Static-IP-Score-Test.json
+2,832 −2,832 source-data/GeoIP2-User-Count-Test.json
+ test-data/GeoIP2-Anonymous-IP-Test.mmdb
+ test-data/GeoIP2-City-Test-Broken-Double-Format.mmdb
+ test-data/GeoIP2-City-Test-Invalid-Node-Count.mmdb
+ test-data/GeoIP2-City-Test.mmdb
+ test-data/GeoIP2-Connection-Type-Test.mmdb
+ test-data/GeoIP2-Country-Test.mmdb
+ test-data/GeoIP2-DensityIncome-Test.mmdb
+ test-data/GeoIP2-Domain-Test.mmdb
+ test-data/GeoIP2-Enterprise-Test.mmdb
+ test-data/GeoIP2-ISP-Test.mmdb
+ test-data/GeoIP2-Precision-Enterprise-Test.mmdb
+ test-data/GeoIP2-Static-IP-Score-Test.mmdb
+ test-data/GeoIP2-User-Count-Test.mmdb
+ test-data/GeoLite2-ASN-Test.mmdb
+ test-data/MaxMind-DB-no-ipv4-search-tree.mmdb
+ test-data/MaxMind-DB-string-value-entries.mmdb
+ test-data/MaxMind-DB-test-broken-pointers-24.mmdb
+ test-data/MaxMind-DB-test-broken-search-tree-24.mmdb
+ test-data/MaxMind-DB-test-decoder.mmdb
+ test-data/MaxMind-DB-test-ipv4-24.mmdb
+ test-data/MaxMind-DB-test-ipv4-28.mmdb
+ test-data/MaxMind-DB-test-ipv4-32.mmdb
+ test-data/MaxMind-DB-test-ipv6-24.mmdb
+ test-data/MaxMind-DB-test-ipv6-28.mmdb
+ test-data/MaxMind-DB-test-ipv6-32.mmdb
+ test-data/MaxMind-DB-test-metadata-pointers.mmdb
+ test-data/MaxMind-DB-test-mixed-24.mmdb
+ test-data/MaxMind-DB-test-mixed-28.mmdb
+ test-data/MaxMind-DB-test-mixed-32.mmdb
+ test-data/MaxMind-DB-test-nested.mmdb
+ test-data/MaxMind-DB-test-pointer-decoder.mmdb
+83 −31 test-data/write-test-data.pl
1 change: 1 addition & 0 deletions src/test/resources/test-data/insights0.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"is_anonymous_vpn": true,
"is_hosting_provider": true,
"is_public_proxy": true,
"is_residential_proxy": true,
"is_satellite_provider": true,
"is_tor_exit_node": true,
"organization": "Blorg",
Expand Down