Skip to content

Commit 48a509b

Browse files
fduttonFaron Dutton
and
Faron Dutton
authored
Adds support for validating idn-hostname and idn-email (#775)
Resolves #774 Co-authored-by: Faron Dutton <[email protected]>
1 parent 84d8546 commit 48a509b

File tree

17 files changed

+3528
-39
lines changed

17 files changed

+3528
-39
lines changed

src/main/java/com/networknt/schema/JsonMetaSchema.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import com.fasterxml.jackson.databind.JsonNode;
2020
import com.networknt.schema.format.DateFormat;
2121
import com.networknt.schema.format.EmailFormat;
22+
import com.networknt.schema.format.IdnEmailFormat;
23+
import com.networknt.schema.format.IdnHostnameFormat;
2224
import com.networknt.schema.format.IriFormat;
2325
import com.networknt.schema.format.IriReferenceFormat;
2426
import com.networknt.schema.format.PatternFormat;
@@ -59,6 +61,8 @@ static PatternFormat pattern(String name, String regex) {
5961
COMMON_BUILTIN_FORMATS.add(pattern("uuid", "^\\p{XDigit}{8}-\\p{XDigit}{4}-\\p{XDigit}{4}-\\p{XDigit}{4}-\\p{XDigit}{12}$", "must be a valid RFC 4122 UUID"));
6062
COMMON_BUILTIN_FORMATS.add(new DateFormat());
6163
COMMON_BUILTIN_FORMATS.add(new EmailFormat());
64+
COMMON_BUILTIN_FORMATS.add(new IdnEmailFormat());
65+
COMMON_BUILTIN_FORMATS.add(new IdnHostnameFormat());
6266
COMMON_BUILTIN_FORMATS.add(new IriFormat());
6367
COMMON_BUILTIN_FORMATS.add(new IriReferenceFormat());
6468
COMMON_BUILTIN_FORMATS.add(new RegexFormat());

src/main/java/com/networknt/schema/format/EmailFormat.java

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,11 @@ public class EmailFormat extends AbstractFormat {
2424

2525
public EmailFormat() {
2626
super("email", "must be a valid RFC 5321 Mailbox");
27-
this.emailValidator = new SpecialEmailValidator(true, true);
27+
this.emailValidator = new IPv6AwareEmailValidator(true, true);
2828
}
2929

3030
@Override
3131
public boolean matches(String value) {
3232
return this.emailValidator.isValid(value);
3333
}
34-
35-
static class SpecialEmailValidator extends EmailValidator {
36-
private static final long serialVersionUID = 1L;
37-
38-
public SpecialEmailValidator(boolean b, boolean c) {
39-
super(b, c);
40-
}
41-
42-
@Override
43-
protected boolean isValidDomain(String domain) {
44-
return super.isValidDomain(domain.startsWith("[IPv6:") ? domain.replace("IPv6:", "") : domain);
45-
}
46-
47-
}
4834
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.networknt.schema.format;
2+
3+
import com.networknt.org.apache.commons.validator.routines.DomainValidator;
4+
import com.networknt.org.apache.commons.validator.routines.EmailValidator;
5+
6+
/**
7+
* This is an extension of the Apache Commons Validator that correctly
8+
* handles email addresses containing an IPv6 literal as the domain.
9+
* <p>
10+
* Apache's {@link EmailValidator} delegates validation of the domain to
11+
* its {@link DomainValidator}, which is not aware that it is validating
12+
* an email address, which has a peculiar way of representing an IPv6
13+
* literal.
14+
*/
15+
class IPv6AwareEmailValidator extends EmailValidator {
16+
private static final long serialVersionUID = 1L;
17+
18+
/**
19+
* Creates a new IPv6AwareEmailValidator.
20+
*
21+
* @param allowLocal Should local addresses be considered valid?
22+
* @param allowTld Should TLDs be allowed?
23+
*/
24+
public IPv6AwareEmailValidator(final boolean allowLocal, final boolean allowTld) {
25+
super(allowLocal, allowTld);
26+
}
27+
28+
@Override
29+
protected boolean isValidDomain(String domain) {
30+
return super.isValidDomain(domain.startsWith("[IPv6:") ? domain.replace("IPv6:", "") : domain);
31+
}
32+
33+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.networknt.schema.format;
2+
3+
import com.networknt.org.apache.commons.validator.routines.EmailValidator;
4+
5+
public class IdnEmailFormat extends AbstractFormat {
6+
7+
private final EmailValidator emailValidator;
8+
9+
public IdnEmailFormat() {
10+
super("idn-email", "must be a valid RFC 6531 Mailbox");
11+
this.emailValidator = new IPv6AwareEmailValidator(true, true);
12+
}
13+
14+
@Override
15+
public boolean matches(String value) {
16+
return this.emailValidator.isValid(value);
17+
}
18+
19+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.networknt.schema.format;
2+
3+
import com.networknt.schema.utils.RFC5892;
4+
5+
public class IdnHostnameFormat extends AbstractFormat {
6+
7+
public IdnHostnameFormat() {
8+
super("idn-hostname", "must be a valid RFC 5890 internationalized hostname");
9+
}
10+
11+
@Override
12+
public boolean matches(String value) {
13+
if (null == value || value.isEmpty()) return true;
14+
return RFC5892.isValid(value);
15+
}
16+
}

0 commit comments

Comments
 (0)