1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2024-11-26 14:22:05 +01:00

Implement UserId.parse(mailbox)

This commit is contained in:
Paul Schaub 2022-12-19 16:25:27 +01:00
parent dbcca586d1
commit 59217d2501
2 changed files with 171 additions and 1 deletions

View file

@ -5,10 +5,21 @@
package org.pgpainless.key.util; package org.pgpainless.key.util;
import java.util.Comparator; import java.util.Comparator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public final class UserId implements CharSequence { public final class UserId implements CharSequence {
private static final Pattern emailPattern = Pattern.compile("(?:[\\p{L}\\u0900-\\u097F0-9!#\\$%&'*+/=?^_`{|}~-]+(?:\\.[\\p{L}\\u0900-\\u097F0-9!#\\$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-" +
"\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[\\p{L}\\u0900-\\u097F0-9](?:[\\p{L}\\u0900-\\u097F0-9" +
"-]*[\\p{L}\\u0900-\\u097F0-9])?\\.)+[\\p{L}\\u0900-\\u097F0-9](?:[\\p{L}\\u0900-\\u097F0-9-]*[\\p{L}\\u0900-\\u097F0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" +
"\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[$\\p{L}\\u0900-\\u097F0-9-]*[\\p{L}\\u0900-\\u097F0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f" +
"\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)])");
private static final Pattern nameAddrPattern = Pattern.compile("^((?<name>.+?)\\s)?(\\((?<comment>.+?)\\)\\s)?(<(?<email>.+?)>)?$");
public static final class Builder { public static final class Builder {
private String name; private String name;
private String comment; private String comment;
@ -58,6 +69,37 @@ public final class UserId implements CharSequence {
} }
} }
public static UserId parse(@Nonnull String string) {
Builder builder = newBuilder();
string = string.trim();
Matcher matcher = nameAddrPattern.matcher(string);
if (matcher.find()) {
String name = matcher.group("name");
String comment = matcher.group("comment");
String mail = matcher.group("email");
matcher = emailPattern.matcher(mail);
if (!matcher.matches()) {
throw new IllegalArgumentException("Malformed email address");
}
if (name != null) {
builder.withName(name);
}
if (comment != null) {
builder.withComment(comment);
}
builder.withEmail(mail);
} else {
matcher = emailPattern.matcher(string);
if (matcher.matches()) {
builder.withEmail(string);
} else {
throw new IllegalArgumentException("Malformed email address");
}
}
return builder.build();
}
private final String name; private final String name;
private final String comment; private final String comment;
private final String email; private final String email;
@ -86,6 +128,24 @@ public final class UserId implements CharSequence {
} }
public String getName() { public String getName() {
return getName(false);
}
public String getName(boolean preserveQuotes) {
if (name == null || name.isEmpty()) {
return name;
}
if (name.startsWith("\"")) {
if (preserveQuotes) {
return name;
}
String withoutQuotes = name.substring(1);
if (withoutQuotes.endsWith("\"")) {
withoutQuotes = withoutQuotes.substring(0, withoutQuotes.length() - 1);
}
return withoutQuotes;
}
return name; return name;
} }
@ -116,7 +176,7 @@ public final class UserId implements CharSequence {
public @Nonnull String toString() { public @Nonnull String toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
if (name != null && !name.isEmpty()) { if (name != null && !name.isEmpty()) {
sb.append(name); sb.append(getName(true));
} }
if (comment != null && !comment.isEmpty()) { if (comment != null && !comment.isEmpty()) {
if (sb.length() > 0) { if (sb.length() > 0) {

View file

@ -271,4 +271,114 @@ public class UserIdTest {
assertNotEquals(0, UserId.compare(id1, id6, c)); assertNotEquals(0, UserId.compare(id1, id6, c));
assertNotEquals(0, UserId.compare(id6, id1, c)); assertNotEquals(0, UserId.compare(id6, id1, c));
} }
@Test
public void parseNameAndEmail() {
UserId id = UserId.parse("Alice <alice@pgpainless.org>");
assertEquals("Alice", id.getName());
assertNull(id.getComment());
assertEquals("alice@pgpainless.org", id.getEmail());
assertEquals("Alice <alice@pgpainless.org>", id.toString());
}
@Test
public void parseNameCommentAndEmail() {
UserId id = UserId.parse("Alice (work mail) <alice@pgpainless.org>");
assertEquals("Alice", id.getName());
assertEquals("work mail", id.getComment());
assertEquals("alice@pgpainless.org", id.getEmail());
assertEquals("Alice (work mail) <alice@pgpainless.org>", id.toString());
}
@Test
public void parseLongNameAndEmail() {
UserId id = UserId.parse("Alice von Painleicester <alice@pgpainless.org>");
assertEquals("Alice von Painleicester", id.getName());
assertNull(id.getComment());
assertEquals("alice@pgpainless.org", id.getEmail());
assertEquals("Alice von Painleicester <alice@pgpainless.org>", id.toString());
}
@Test
public void parseLongNameCommentAndEmail() {
UserId id = UserId.parse("Alice von Painleicester (work email) <alice@pgpainless.org>");
assertEquals("Alice von Painleicester", id.getName());
assertEquals("work email", id.getComment());
assertEquals("alice@pgpainless.org", id.getEmail());
assertEquals("Alice von Painleicester (work email) <alice@pgpainless.org>", id.toString());
}
@Test
public void parseQuotedNameAndEmail() {
UserId id = UserId.parse("\"Alice\" <alice@pgpainless.org>");
assertEquals("Alice", id.getName());
assertNull(id.getComment());
assertEquals("alice@pgpainless.org", id.getEmail());
assertEquals("\"Alice\" <alice@pgpainless.org>", id.toString());
}
@Test
public void parseQuotedNameCommentAndEmail() {
UserId id = UserId.parse("\"Alice\" (work email) <alice@pgpainless.org>");
assertEquals("Alice", id.getName());
assertEquals("work email", id.getComment());
assertEquals("alice@pgpainless.org", id.getEmail());
assertEquals("\"Alice\" (work email) <alice@pgpainless.org>", id.toString());
}
@Test
public void parseLongQuotedNameAndEmail() {
UserId id = UserId.parse("\"Alice Mac Painlester\" <alice@pgpainless.org>");
assertEquals("Alice Mac Painlester", id.getName());
assertNull(id.getComment());
assertEquals("alice@pgpainless.org", id.getEmail());
assertEquals("\"Alice Mac Painlester\" <alice@pgpainless.org>", id.toString());
}
@Test
public void parseLongQuotedNameCommentAndEmail() {
UserId id = UserId.parse("\"Alice Mac Painlester\" (work email) <alice@pgpainless.org>");
assertEquals("Alice Mac Painlester", id.getName());
assertEquals("work email", id.getComment());
assertEquals("alice@pgpainless.org", id.getEmail());
assertEquals("\"Alice Mac Painlester\" (work email) <alice@pgpainless.org>", id.toString());
}
@Test
public void parseEmailOnly() {
UserId id = UserId.parse("alice@pgpainless.org");
assertNull(id.getName());
assertNull(id.getComment());
assertEquals("alice@pgpainless.org", id.getEmail());
assertEquals("<alice@pgpainless.org>", id.toString());
}
@Test
public void parseBracketedEmailOnly() {
UserId id = UserId.parse("<alice@pgpainless.org>");
assertNull(id.getName());
assertNull(id.getComment());
assertEquals("alice@pgpainless.org", id.getEmail());
assertEquals("<alice@pgpainless.org>", id.toString());
}
} }