Skip to content

Commit c0774c2

Browse files
authored
Merge pull request #334 from maxmind/sromani/add-ip-risk
GeoIP2 Java API is updated for IP Risk database
2 parents f36f431 + b992684 commit c0774c2

File tree

8 files changed

+300
-94
lines changed

8 files changed

+300
-94
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
4.0.0
5+
------------------
6+
7+
* Added support for the GeoIP2 IP Risk database.
8+
49
3.0.2 (2022-10-31)
510
------------------
611

src/main/java/com/maxmind/geoip2/DatabaseProvider.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,29 @@ AnonymousIpResponse anonymousIp(InetAddress ipAddress) throws IOException,
4949
Optional<AnonymousIpResponse> tryAnonymousIp(InetAddress ipAddress) throws IOException,
5050
GeoIp2Exception;
5151

52+
53+
/**
54+
* Look up an IP address in a GeoIP2 IP Risk database.
55+
*
56+
* @param ipAddress IPv4 or IPv6 address to lookup.
57+
* @return an IPRiskResponse for the requested IP address.
58+
* @throws com.maxmind.geoip2.exception.GeoIp2Exception if there is an error looking up the IP
59+
* @throws java.io.IOException if there is an IO error
60+
*/
61+
IpRiskResponse ipRisk(InetAddress ipAddress) throws IOException,
62+
GeoIp2Exception;
63+
64+
/**
65+
* Look up an IP address in a GeoIP2 IP Risk database.
66+
*
67+
* @param ipAddress IPv4 or IPv6 address to lookup.
68+
* @return an IPRiskResponse for the requested IP address or empty if the IP address is not in the DB.
69+
* @throws com.maxmind.geoip2.exception.GeoIp2Exception if there is an error looking up the IP
70+
* @throws java.io.IOException if there is an IO error
71+
*/
72+
Optional<IpRiskResponse> tryIpRisk(InetAddress ipAddress) throws IOException,
73+
GeoIp2Exception;
74+
5275
/**
5376
* Look up an IP address in a GeoLite2 ASN database.
5477
*

src/main/java/com/maxmind/geoip2/DatabaseReader.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ private enum DatabaseType {
7575
COUNTRY,
7676
DOMAIN,
7777
ENTERPRISE,
78+
IP_RISK,
7879
ISP;
7980

8081
final int type;
@@ -106,6 +107,9 @@ private int getDatabaseType() {
106107
if (databaseType.contains("GeoIP2-Anonymous-IP")) {
107108
type |= DatabaseType.ANONYMOUS_IP.type;
108109
}
110+
if (databaseType.contains("GeoIP2-IP-Risk")) {
111+
type |= DatabaseType.IP_RISK.type;
112+
}
109113
if (databaseType.contains("GeoLite2-ASN")) {
110114
type |= DatabaseType.ASN.type;
111115
}
@@ -410,6 +414,51 @@ private Optional<AnonymousIpResponse> getAnonymousIp(
410414
);
411415
}
412416

417+
/**
418+
* Look up an IP address in a GeoIP2 IP Risk database.
419+
*
420+
* @param ipAddress IPv4 or IPv6 address to lookup.
421+
* @return a IPRiskResponse for the requested IP address.
422+
* @throws GeoIp2Exception if there is an error looking up the IP
423+
* @throws IOException if there is an IO error
424+
*/
425+
@Override
426+
public IpRiskResponse ipRisk(InetAddress ipAddress) throws IOException,
427+
GeoIp2Exception {
428+
Optional<IpRiskResponse> r = getIpRisk(ipAddress);
429+
if (r.isEmpty()) {
430+
throw new AddressNotFoundException("The address "
431+
+ ipAddress.getHostAddress() + " is not in the database.");
432+
}
433+
return r.get();
434+
}
435+
436+
@Override
437+
public Optional<IpRiskResponse> tryIpRisk(InetAddress ipAddress) throws IOException,
438+
GeoIp2Exception {
439+
return getIpRisk(ipAddress);
440+
}
441+
442+
private Optional<IpRiskResponse> getIpRisk( InetAddress ipAddress) throws IOException,
443+
GeoIp2Exception {
444+
LookupResult<IpRiskResponse> result = this.get(
445+
ipAddress,
446+
IpRiskResponse.class,
447+
DatabaseType.IP_RISK
448+
);
449+
IpRiskResponse response = result.getModel();
450+
if (response == null) {
451+
return Optional.empty();
452+
}
453+
return Optional.of(
454+
new IpRiskResponse(
455+
response,
456+
result.getIpAddress(),
457+
result.getNetwork()
458+
)
459+
);
460+
}
461+
413462
/**
414463
* Look up an IP address in a GeoLite2 ASN database.
415464
*

src/main/java/com/maxmind/geoip2/model/AnonymousIpResponse.java

Lines changed: 2 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
import com.fasterxml.jackson.annotation.JacksonInject;
44
import com.fasterxml.jackson.annotation.JsonProperty;
55
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
6-
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
7-
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
86
import com.maxmind.db.MaxMindDbConstructor;
97
import com.maxmind.db.MaxMindDbParameter;
108
import com.maxmind.db.Network;
@@ -13,16 +11,7 @@
1311
/**
1412
* This class provides the GeoIP2 Anonymous IP model.
1513
*/
16-
public class AnonymousIpResponse extends AbstractResponse {
17-
18-
private final boolean isAnonymous;
19-
private final boolean isAnonymousVpn;
20-
private final boolean isHostingProvider;
21-
private final boolean isPublicProxy;
22-
private final boolean isResidentialProxy;
23-
private final boolean isTorExitNode;
24-
private final String ipAddress;
25-
private final Network network;
14+
public class AnonymousIpResponse extends IpBaseResponse {
2615

2716
public AnonymousIpResponse(
2817
@JacksonInject("ip_address") @JsonProperty("ip_address") String ipAddress,
@@ -34,14 +23,7 @@ public AnonymousIpResponse(
3423
@JsonProperty("is_tor_exit_node") boolean isTorExitNode,
3524
@JacksonInject("network") @JsonProperty("network") @JsonDeserialize(using = NetworkDeserializer.class) Network network
3625
) {
37-
this.isAnonymous = isAnonymous;
38-
this.isAnonymousVpn = isAnonymousVpn;
39-
this.isHostingProvider = isHostingProvider;
40-
this.isPublicProxy = isPublicProxy;
41-
this.isResidentialProxy = isResidentialProxy;
42-
this.isTorExitNode = isTorExitNode;
43-
this.ipAddress = ipAddress;
44-
this.network = network;
26+
super(ipAddress, isAnonymous, isAnonymousVpn, isHostingProvider, isPublicProxy, isResidentialProxy, isTorExitNode, network);
4527
}
4628

4729
@MaxMindDbConstructor
@@ -83,76 +65,4 @@ public AnonymousIpResponse(
8365
network
8466
);
8567
}
86-
87-
/**
88-
* @return whether the IP address belongs to any sort of anonymous network.
89-
*/
90-
@JsonProperty("is_anonymous")
91-
public boolean isAnonymous() {
92-
return isAnonymous;
93-
}
94-
95-
/**
96-
* @return whether the IP address is registered to an anonymous VPN
97-
* provider. If a VPN provider does not register subnets under names
98-
* associated with them, we will likely only flag their IP ranges using
99-
* isHostingProvider.
100-
*/
101-
@JsonProperty("is_anonymous_vpn")
102-
public boolean isAnonymousVpn() {
103-
return isAnonymousVpn;
104-
}
105-
106-
/**
107-
* @return whether the IP address belongs to a hosting or VPN provider
108-
* (see description of isAnonymousVpn).
109-
*/
110-
@JsonProperty("is_hosting_provider")
111-
public boolean isHostingProvider() {
112-
return isHostingProvider;
113-
}
114-
115-
/**
116-
* @return whether the IP address belongs to a public proxy.
117-
*/
118-
@JsonProperty("is_public_proxy")
119-
public boolean isPublicProxy() {
120-
return isPublicProxy;
121-
}
122-
123-
/**
124-
* @return whether the IP address is on a suspected anonymizing network and
125-
* belongs to a residential ISP.
126-
*/
127-
@JsonProperty("is_residential_proxy")
128-
public boolean isResidentialProxy() {
129-
return isResidentialProxy;
130-
}
131-
132-
/**
133-
* @return whether the IP address is a Tor exit node.
134-
*/
135-
@JsonProperty("is_tor_exit_node")
136-
public boolean isTorExitNode() {
137-
return isTorExitNode;
138-
}
139-
140-
/**
141-
* @return The IP address that the data in the model is for.
142-
*/
143-
@JsonProperty("ip_address")
144-
public String getIpAddress() {
145-
return this.ipAddress;
146-
}
147-
148-
/**
149-
* @return The network associated with the record. In particular, this is
150-
* the largest network where all the fields besides IP address have the
151-
* same value.
152-
*/
153-
@JsonProperty
154-
@JsonSerialize(using = ToStringSerializer.class)
155-
public Network getNetwork() {
156-
return this.network;
157-
}
15868
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package com.maxmind.geoip2.model;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
5+
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
6+
import com.maxmind.db.Network;
7+
8+
/**
9+
* This class provides the base IP model.
10+
*/
11+
public class IpBaseResponse extends AbstractResponse {
12+
13+
private final boolean isAnonymous;
14+
private final boolean isAnonymousVpn;
15+
private final boolean isHostingProvider;
16+
private final boolean isPublicProxy;
17+
private final boolean isResidentialProxy;
18+
private final boolean isTorExitNode;
19+
private final String ipAddress;
20+
private final Network network;
21+
22+
public IpBaseResponse(
23+
String ipAddress,
24+
boolean isAnonymous,
25+
boolean isAnonymousVpn,
26+
boolean isHostingProvider,
27+
boolean isPublicProxy,
28+
boolean isResidentialProxy,
29+
boolean isTorExitNode,
30+
Network network
31+
) {
32+
this.isAnonymous = isAnonymous;
33+
this.isAnonymousVpn = isAnonymousVpn;
34+
this.isHostingProvider = isHostingProvider;
35+
this.isPublicProxy = isPublicProxy;
36+
this.isResidentialProxy = isResidentialProxy;
37+
this.isTorExitNode = isTorExitNode;
38+
this.ipAddress = ipAddress;
39+
this.network = network;
40+
}
41+
42+
/**
43+
* @return whether the IP address belongs to any sort of anonymous network.
44+
*/
45+
@JsonProperty("is_anonymous")
46+
public boolean isAnonymous() {
47+
return isAnonymous;
48+
}
49+
50+
/**
51+
* @return whether the IP address is registered to an anonymous VPN
52+
* provider. If a VPN provider does not register subnets under names
53+
* associated with them, we will likely only flag their IP ranges using
54+
* isHostingProvider.
55+
*/
56+
@JsonProperty("is_anonymous_vpn")
57+
public boolean isAnonymousVpn() {
58+
return isAnonymousVpn;
59+
}
60+
61+
/**
62+
* @return whether the IP address belongs to a hosting or VPN provider
63+
* (see description of isAnonymousVpn).
64+
*/
65+
@JsonProperty("is_hosting_provider")
66+
public boolean isHostingProvider() {
67+
return isHostingProvider;
68+
}
69+
70+
/**
71+
* @return whether the IP address belongs to a public proxy.
72+
*/
73+
@JsonProperty("is_public_proxy")
74+
public boolean isPublicProxy() {
75+
return isPublicProxy;
76+
}
77+
78+
/**
79+
* @return whether the IP address is on a suspected anonymizing network and
80+
* belongs to a residential ISP.
81+
*/
82+
@JsonProperty("is_residential_proxy")
83+
public boolean isResidentialProxy() {
84+
return isResidentialProxy;
85+
}
86+
87+
/**
88+
* @return whether the IP address is a Tor exit node.
89+
*/
90+
@JsonProperty("is_tor_exit_node")
91+
public boolean isTorExitNode() {
92+
return isTorExitNode;
93+
}
94+
95+
/**
96+
* @return The IP address that the data in the model is for.
97+
*/
98+
@JsonProperty("ip_address")
99+
public String getIpAddress() {
100+
return this.ipAddress;
101+
}
102+
103+
/**
104+
* @return The network associated with the record. In particular, this is
105+
* the largest network where all the fields besides IP address have the
106+
* same value.
107+
*/
108+
@JsonProperty
109+
@JsonSerialize(using = ToStringSerializer.class)
110+
public Network getNetwork() {
111+
return this.network;
112+
}
113+
}

0 commit comments

Comments
 (0)