Skip to content

Commit 7488b21

Browse files
committed
Add support for /email/domain/first_seen
1 parent 80fc8aa commit 7488b21

12 files changed

Lines changed: 117 additions & 4 deletions

File tree

CHANGELOG.md

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

4+
1.12.0
5+
-------------------
6+
7+
* Added support for the new email output `/email/domain/first_seen` This can
8+
be accessed via `response.getEmail().getDomain().getFirstSeen()`.
9+
410
1.11.0 (2020-02-21)
511
-------------------
612

pom.xml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,18 @@
4747
<dependency>
4848
<groupId>com.fasterxml.jackson.core</groupId>
4949
<artifactId>jackson-databind</artifactId>
50-
<version>2.10.2</version>
50+
<version>2.10.3</version>
5151
</dependency>
5252
<dependency>
5353
<groupId>com.fasterxml.jackson.core</groupId>
5454
<artifactId>jackson-annotations</artifactId>
5555
<version>2.10.3</version>
5656
</dependency>
57+
<dependency>
58+
<groupId>com.fasterxml.jackson.datatype</groupId>
59+
<artifactId>jackson-datatype-jsr310</artifactId>
60+
<version>2.10.3</version>
61+
</dependency>
5762
<dependency>
5863
<groupId>com.maxmind.geoip2</groupId>
5964
<artifactId>geoip2</artifactId>

src/main/java/com/maxmind/minfraud/AbstractModel.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.fasterxml.jackson.databind.ObjectMapper;
66
import com.fasterxml.jackson.databind.SerializationFeature;
77
import com.fasterxml.jackson.databind.util.StdDateFormat;
8+
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
89

910
import java.io.IOException;
1011

@@ -16,12 +17,13 @@ public abstract class AbstractModel {
1617
*/
1718
public final String toJson() throws IOException {
1819
ObjectMapper mapper = new ObjectMapper();
20+
mapper.registerModule(new JavaTimeModule());
1921
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
2022
mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
2123
mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
2224
mapper.disable(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS);
2325
mapper.setDateFormat(new StdDateFormat().withColonInTimeZone(true));
24-
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
26+
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
2527

2628
return mapper.writeValueAsString(this);
2729
}

src/main/java/com/maxmind/minfraud/WebServiceClient.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.fasterxml.jackson.databind.MapperFeature;
88
import com.fasterxml.jackson.databind.ObjectMapper;
99
import com.fasterxml.jackson.databind.util.StdDateFormat;
10+
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
1011
import com.maxmind.minfraud.exception.*;
1112
import com.maxmind.minfraud.request.Transaction;
1213
import com.maxmind.minfraud.response.FactorsResponse;
@@ -62,6 +63,7 @@ private WebServiceClient(WebServiceClient.Builder builder) {
6263
mapper = new ObjectMapper();
6364
mapper.disable(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS);
6465
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
66+
mapper.registerModule(new JavaTimeModule());
6567
mapper.setDateFormat(new StdDateFormat().withColonInTimeZone(true));
6668

6769
RequestConfig.Builder configBuilder = RequestConfig.custom()

src/main/java/com/maxmind/minfraud/response/Email.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,16 @@ public final class Email extends AbstractModel {
1111
private final Boolean isFree;
1212
private final Boolean isHighRisk;
1313
private final String firstSeen;
14+
private final EmailDomain domain;
1415

1516
public Email(
17+
@JsonProperty("domain") EmailDomain domain,
1618
@JsonProperty("is_disposable") Boolean isDisposable,
1719
@JsonProperty("is_free") Boolean isFree,
1820
@JsonProperty("is_high_risk") Boolean isHighRisk,
1921
@JsonProperty("first_seen") String firstSeen
2022
) {
23+
this.domain = domain;
2124
this.isDisposable = isDisposable;
2225
this.isFree = isFree;
2326
this.isHighRisk = isHighRisk;
@@ -26,6 +29,15 @@ public Email(
2629

2730
// The following constructors are for backward compatibility and
2831
// can be removed as part of a major release
32+
public Email(
33+
Boolean isDisposable,
34+
Boolean isFree,
35+
Boolean isHighRisk,
36+
String firstSeen
37+
) {
38+
this(null, isDisposable, isFree, isHighRisk, firstSeen);
39+
}
40+
2941
public Email(
3042
Boolean isFree,
3143
Boolean isHighRisk,
@@ -45,6 +57,12 @@ public Email() {
4557
this(null, null, null);
4658
}
4759

60+
/**
61+
* @return The {@code EmailDomain} model object.
62+
*/
63+
public EmailDomain getDomain() {
64+
return domain;
65+
}
4866

4967
/**
5068
* @return Whether the email address is from a disposable email provider.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.maxmind.minfraud.response;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import com.maxmind.minfraud.AbstractModel;
5+
6+
import java.time.LocalDate;
7+
8+
/**
9+
* This class contains minFraud response data related to the email domain.
10+
*/
11+
public final class EmailDomain extends AbstractModel {
12+
private final LocalDate firstSeen;
13+
14+
public EmailDomain(
15+
@JsonProperty("first_seen") LocalDate firstSeen
16+
) {
17+
this.firstSeen = firstSeen;
18+
}
19+
20+
/**
21+
* @return A date to identify the date an email domain was first
22+
* seen by MaxMind.
23+
*/
24+
@JsonProperty("first_seen")
25+
public LocalDate getFirstSeen() {
26+
return firstSeen;
27+
}
28+
}
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
11
package com.maxmind.minfraud.response;
22

3+
import com.fasterxml.jackson.databind.DeserializationFeature;
34
import com.fasterxml.jackson.databind.InjectableValues;
45
import com.fasterxml.jackson.databind.InjectableValues.Std;
6+
import com.fasterxml.jackson.databind.MapperFeature;
57
import com.fasterxml.jackson.databind.ObjectMapper;
8+
import com.fasterxml.jackson.databind.util.StdDateFormat;
9+
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
610

711
import java.io.IOException;
812
import java.util.Collections;
913

1014
public abstract class AbstractOutputTest {
1115

1216
<T> T deserialize(Class<T> cls, String json) throws IOException {
13-
ObjectMapper mapper = new ObjectMapper();
17+
ObjectMapper mapper = new ObjectMapper();
18+
mapper.disable(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS);
19+
mapper.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
20+
mapper.registerModule(new JavaTimeModule());
21+
mapper.setDateFormat(new StdDateFormat().withColonInTimeZone(true));
1422
InjectableValues inject = new Std().addValue(
1523
"locales", Collections.singletonList("en"));
1624
return mapper.readerFor(cls).with(inject).readValue(json);
1725
}
18-
1926
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.maxmind.minfraud.response;
2+
3+
import com.fasterxml.jackson.jr.ob.JSON;
4+
import org.junit.Test;
5+
6+
import java.time.LocalDate;
7+
8+
import static org.junit.Assert.*;
9+
10+
public class EmailDomainTest extends AbstractOutputTest {
11+
12+
@Test
13+
public void testEmailDomain() throws Exception {
14+
EmailDomain domain = this.deserialize(
15+
EmailDomain.class,
16+
JSON.std
17+
.composeString()
18+
.startObject()
19+
.put("first_seen", "2014-02-03")
20+
.end()
21+
.finish()
22+
);
23+
24+
assertEquals(LocalDate.parse("2014-02-03"), domain.getFirstSeen());
25+
}
26+
}

src/test/java/com/maxmind/minfraud/response/EmailTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import com.fasterxml.jackson.jr.ob.JSON;
44
import org.junit.Test;
55

6+
import java.time.LocalDate;
7+
68
import static org.junit.Assert.*;
79

810
public class EmailTest extends AbstractOutputTest {
@@ -14,6 +16,9 @@ public void testEmail() throws Exception {
1416
JSON.std
1517
.composeString()
1618
.startObject()
19+
.startObjectField("domain")
20+
.put("first_seen", "2014-02-03")
21+
.end()
1722
.put("is_disposable", false)
1823
.put("is_free", false)
1924
.put("is_high_risk", true)
@@ -22,6 +27,7 @@ public void testEmail() throws Exception {
2227
.finish()
2328
);
2429

30+
assertEquals(LocalDate.parse("2014-02-03"), email.getDomain().getFirstSeen());
2531
assertFalse(email.isDisposable());
2632
assertFalse(email.isFree());
2733
assertTrue(email.isHighRisk());

src/test/java/com/maxmind/minfraud/response/InsightsResponseTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.fasterxml.jackson.jr.ob.JSON;
44
import org.junit.Test;
55

6+
import java.time.LocalDate;
67
import java.util.UUID;
78

89
import static org.junit.Assert.assertEquals;
@@ -21,6 +22,11 @@ public void testInsights() throws Exception {
2122
.startObjectField("disposition")
2223
.put("action", "accept")
2324
.end()
25+
.startObjectField("email")
26+
.startObjectField("domain")
27+
.put("first_seen", "2014-02-03")
28+
.end()
29+
.end()
2430
.startObjectField("ip_address")
2531
.startObjectField("country")
2632
.put("iso_code", "US")
@@ -53,6 +59,7 @@ public void testInsights() throws Exception {
5359
);
5460

5561
assertEquals("disposition", "accept", insights.getDisposition().getAction());
62+
assertEquals("email domain first seen", LocalDate.parse("2014-02-03"), insights.getEmail().getDomain().getFirstSeen());
5663
assertEquals("correct country ISO", "US", insights.getIpAddress().getCountry().getIsoCode());
5764
assertTrue("correct credit card prepaid", insights.getCreditCard().isPrepaid());
5865
assertTrue("correct shipping address is in IP country", insights.getShippingAddress().isInIpCountry());

0 commit comments

Comments
 (0)