mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-12-23 19:38:00 +01:00
Merge pull request #92 from IvanPizhenko/91-imporve-class-userid
issue #91 Improve class UserId
This commit is contained in:
commit
b30fc2beec
4 changed files with 285 additions and 84 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2020 Paul Schaub.
|
* Copyright 2020 Paul Schaub. Copyright 2021 Flowcrypt a.s.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -13,13 +13,66 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.pgpainless.key.util;
|
package org.pgpainless.key.util;
|
||||||
|
|
||||||
public final class UserId implements CharSequence {
|
public final class UserId implements CharSequence {
|
||||||
|
public static final class Builder {
|
||||||
|
private String name;
|
||||||
|
private String comment;
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
private Builder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private Builder(String name, String comment, String email) {
|
||||||
|
this.name = name;
|
||||||
|
this.comment = comment;
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withName(String name) {
|
||||||
|
checkNotNull("name", name);
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withComment(String comment) {
|
||||||
|
checkNotNull("comment", comment);
|
||||||
|
this.comment = comment;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withEmail(String email) {
|
||||||
|
checkNotNull("email", email);
|
||||||
|
this.email = email;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder noName() {
|
||||||
|
name = null;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder noComment() {
|
||||||
|
comment = null;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder noEmail() {
|
||||||
|
email = null;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserId build() {
|
||||||
|
return new UserId(name, comment, email);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final String comment;
|
private final String comment;
|
||||||
private final String email;
|
private final String email;
|
||||||
|
private long hash = Long.MAX_VALUE;
|
||||||
|
|
||||||
private UserId(String name, String comment, String email) {
|
private UserId(String name, String comment, String email) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
@ -27,85 +80,36 @@ public final class UserId implements CharSequence {
|
||||||
this.email = email;
|
this.email = email;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
if (name != null) {
|
|
||||||
sb.append(name);
|
|
||||||
}
|
|
||||||
if (comment != null) {
|
|
||||||
sb.append(" (").append(comment).append(')');
|
|
||||||
}
|
|
||||||
if (email != null) {
|
|
||||||
sb.append(sb.length() != 0 ? ' ' : "").append(email);
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UserId onlyEmail(String email) {
|
public static UserId onlyEmail(String email) {
|
||||||
if (email == null) {
|
checkNotNull("email", email);
|
||||||
throw new IllegalArgumentException("Email must not be null.");
|
|
||||||
}
|
|
||||||
return new UserId(null, null, email);
|
return new UserId(null, null, email);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UserId nameAndEmail(String name, String email) {
|
public static UserId nameAndEmail(String name, String email) {
|
||||||
return withName(name).noComment().withEmail(email);
|
checkNotNull("name", name);
|
||||||
|
checkNotNull("email", email);
|
||||||
|
return new UserId(name, null, email);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static WithComment withName(String name) {
|
public static Builder newBuilder() {
|
||||||
if (name == null) {
|
return new Builder();
|
||||||
throw new IllegalArgumentException("Name must not be null.");
|
|
||||||
}
|
|
||||||
return new WithComment(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class WithComment {
|
public Builder toBuilder() {
|
||||||
|
return new Builder(name, comment, email);
|
||||||
private final String name;
|
|
||||||
|
|
||||||
public WithComment(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public WithEmail withComment(String comment) {
|
public String getName() {
|
||||||
if (comment == null) {
|
return name;
|
||||||
throw new IllegalArgumentException("Comment must not be null.");
|
|
||||||
}
|
|
||||||
return new WithEmail(name, comment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public WithEmail noComment() {
|
public String getComment() {
|
||||||
return new WithEmail(name, null);
|
return comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserId build() {
|
public String getEmail() {
|
||||||
return new UserId(name, null, null);
|
return email;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static class WithEmail {
|
|
||||||
|
|
||||||
private final String name;
|
|
||||||
private final String comment;
|
|
||||||
|
|
||||||
public WithEmail(String name, String comment) {
|
|
||||||
this.name = name;
|
|
||||||
this.comment = comment;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserId withEmail(String email) {
|
|
||||||
if (email == null) {
|
|
||||||
throw new IllegalArgumentException("Email must not be null.");
|
|
||||||
}
|
|
||||||
return new UserId(name, comment, email.matches("^<.+>$") ? email : '<' + email + '>');
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserId noEmail() {
|
|
||||||
return new UserId(name, comment, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int length() {
|
public int length() {
|
||||||
|
@ -122,4 +126,69 @@ public final class UserId implements CharSequence {
|
||||||
return toString().subSequence(i, i1);
|
return toString().subSequence(i, i1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return asString(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of the object.
|
||||||
|
* @param ignoreEmptyValues Flag which indicates that empty string values should not be outputted.
|
||||||
|
* @return a string representation of the object.
|
||||||
|
*/
|
||||||
|
public String asString(boolean ignoreEmptyValues) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
if (name != null && (!ignoreEmptyValues || !name.isEmpty())) {
|
||||||
|
sb.append(name);
|
||||||
|
}
|
||||||
|
if (comment != null && (!ignoreEmptyValues || !comment.isEmpty())) {
|
||||||
|
sb.append(" (").append(comment).append(')');
|
||||||
|
}
|
||||||
|
if (email != null && (!ignoreEmptyValues || !email.isEmpty())) {
|
||||||
|
final boolean moreThanJustEmail = sb.length() > 0;
|
||||||
|
if (moreThanJustEmail) sb.append(" <");
|
||||||
|
sb.append(email);
|
||||||
|
if (moreThanJustEmail) sb.append('>');
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == null) return false;
|
||||||
|
if (o == this) return true;
|
||||||
|
if (!(o instanceof UserId)) return false;
|
||||||
|
final UserId other = (UserId) o;
|
||||||
|
return isEqualComponent(name, other.name, false)
|
||||||
|
&& isEqualComponent(comment, other.comment, false)
|
||||||
|
&& isEqualComponent(email, other.email, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
if (hash != Long.MAX_VALUE) {
|
||||||
|
return (int) hash;
|
||||||
|
} else {
|
||||||
|
int hash = 7;
|
||||||
|
hash = 31 * hash + (name == null ? 0 : name.hashCode());
|
||||||
|
hash = 31 * hash + (comment == null ? 0 : comment.hashCode());
|
||||||
|
hash = 31 * hash + (email == null ? 0 : email.toLowerCase().hashCode());
|
||||||
|
this.hash = hash;
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isEqualComponent(String value, String otherValue, boolean ignoreCase) {
|
||||||
|
final boolean valueIsNull = (value == null);
|
||||||
|
final boolean otherValueIsNull = (otherValue == null);
|
||||||
|
return (valueIsNull && otherValueIsNull)
|
||||||
|
|| (!valueIsNull && !otherValueIsNull
|
||||||
|
&& (ignoreCase ? value.equalsIgnoreCase(otherValue) : value.equals(otherValue)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkNotNull(String paramName, String value) {
|
||||||
|
if (value == null) {
|
||||||
|
throw new IllegalArgumentException(paramName + " must be not null");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2020 Paul Schaub.
|
* Copyright 2020 Paul Schaub. Copyright 2021 Flowcrypt a.s.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -15,37 +15,36 @@
|
||||||
*/
|
*/
|
||||||
package org.pgpainless.key;
|
package org.pgpainless.key;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.pgpainless.key.util.UserId;
|
import org.pgpainless.key.util.UserId;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
public class UserIdTest {
|
public class UserIdTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void throwForNullName() {
|
public void throwForNullName() {
|
||||||
assertThrows(IllegalArgumentException.class, () -> UserId.withName(null));
|
assertThrows(IllegalArgumentException.class, () -> UserId.newBuilder().withName(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void throwForNullComment() {
|
public void throwForNullComment() {
|
||||||
assertThrows(IllegalArgumentException.class, () -> UserId.withName("foo")
|
assertThrows(IllegalArgumentException.class, () -> UserId.newBuilder().withComment(null));
|
||||||
.withComment(null));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void throwForNullEmail() {
|
public void throwForNullEmail() {
|
||||||
assertThrows(IllegalArgumentException.class, () -> UserId.withName("foo")
|
assertThrows(IllegalArgumentException.class, () -> UserId.newBuilder().withEmail(null));
|
||||||
.withComment("bar")
|
|
||||||
.withEmail(null));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFormatOnlyName() {
|
public void testFormatOnlyName() {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"Juliet Capulet",
|
"Juliet Capulet",
|
||||||
UserId.withName("Juliet Capulet")
|
UserId.newBuilder().withName("Juliet Capulet")
|
||||||
.build().toString());
|
.build().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,26 +52,28 @@ public class UserIdTest {
|
||||||
public void testFormatNameAndComment() {
|
public void testFormatNameAndComment() {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"Juliet Capulet (from the play)",
|
"Juliet Capulet (from the play)",
|
||||||
UserId.withName("Juliet Capulet")
|
UserId.newBuilder().withName("Juliet Capulet")
|
||||||
.withComment("from the play")
|
.withComment("from the play")
|
||||||
.noEmail().toString());
|
.noEmail().build().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFormatNameCommentAndMail() {
|
public void testFormatNameCommentAndMail() {
|
||||||
assertEquals("Juliet Capulet (from the play) <juliet@capulet.lit>",
|
assertEquals("Juliet Capulet (from the play) <juliet@capulet.lit>",
|
||||||
UserId.withName("Juliet Capulet")
|
UserId.newBuilder().withName("Juliet Capulet")
|
||||||
.withComment("from the play")
|
.withComment("from the play")
|
||||||
.withEmail("juliet@capulet.lit")
|
.withEmail("juliet@capulet.lit")
|
||||||
|
.build()
|
||||||
.toString());
|
.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFormatNameAndEmail() {
|
public void testFormatNameAndEmail() {
|
||||||
assertEquals("Juliet Capulet <juliet@capulet.lit>",
|
assertEquals("Juliet Capulet <juliet@capulet.lit>",
|
||||||
UserId.withName("Juliet Capulet")
|
UserId.newBuilder().withName("Juliet Capulet")
|
||||||
.noComment()
|
.noComment()
|
||||||
.withEmail("juliet@capulet.lit")
|
.withEmail("juliet@capulet.lit")
|
||||||
|
.build()
|
||||||
.toString());
|
.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,4 +87,134 @@ public class UserIdTest {
|
||||||
UserId userId = UserId.nameAndEmail("Maurice Moss", "moss.m@reynholm.co.uk");
|
UserId userId = UserId.nameAndEmail("Maurice Moss", "moss.m@reynholm.co.uk");
|
||||||
assertEquals("Maurice Moss <moss.m@reynholm.co.uk>", userId.toString());
|
assertEquals("Maurice Moss <moss.m@reynholm.co.uk>", userId.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBuilderWithName() {
|
||||||
|
final UserId userId = UserId.newBuilder().withName("John Smith").build();
|
||||||
|
assertEquals("John Smith", userId.getName());
|
||||||
|
assertNull(userId.getComment());
|
||||||
|
assertNull(userId.getEmail());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBuilderWithComment() {
|
||||||
|
final UserId userId = UserId.newBuilder().withComment("Sales Dept.").build();
|
||||||
|
assertNull(userId.getName());
|
||||||
|
assertEquals("Sales Dept.", userId.getComment());
|
||||||
|
assertNull(userId.getEmail());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBuilderWithEmail() {
|
||||||
|
final UserId userId = UserId.newBuilder().withEmail("john.smith@example.com").build();
|
||||||
|
assertNull(userId.getName());
|
||||||
|
assertNull(userId.getComment());
|
||||||
|
assertEquals("john.smith@example.com", userId.getEmail());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBuilderWithAll() {
|
||||||
|
final UserId userId = UserId.newBuilder().withEmail("john.smith@example.com")
|
||||||
|
.withName("John Smith")
|
||||||
|
.withEmail("john.smith@example.com")
|
||||||
|
.withComment("Sales Dept.").build();
|
||||||
|
assertEquals("John Smith", userId.getName());
|
||||||
|
assertEquals("Sales Dept.", userId.getComment());
|
||||||
|
assertEquals("john.smith@example.com", userId.getEmail());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBuilderNoName() {
|
||||||
|
final UserId.Builder builder = UserId.newBuilder()
|
||||||
|
.withEmail("john.smith@example.com")
|
||||||
|
.withName("John Smith")
|
||||||
|
.withComment("Sales Dept.").build().toBuilder();
|
||||||
|
final UserId userId = builder.noName().build();
|
||||||
|
assertNull(userId.getName());
|
||||||
|
assertEquals("Sales Dept.", userId.getComment());
|
||||||
|
assertEquals("john.smith@example.com", userId.getEmail());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBuilderNoComment() {
|
||||||
|
final UserId.Builder builder = UserId.newBuilder()
|
||||||
|
.withEmail("john.smith@example.com")
|
||||||
|
.withName("John Smith")
|
||||||
|
.withComment("Sales Dept.").build().toBuilder();
|
||||||
|
final UserId userId = builder.noComment().build();
|
||||||
|
assertEquals("John Smith", userId.getName());
|
||||||
|
assertNull(userId.getComment());
|
||||||
|
assertEquals("john.smith@example.com", userId.getEmail());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBuilderNoEmail() {
|
||||||
|
final UserId.Builder builder = UserId.newBuilder()
|
||||||
|
.withEmail("john.smith@example.com")
|
||||||
|
.withName("John Smith")
|
||||||
|
.withComment("Sales Dept.").build().toBuilder();
|
||||||
|
final UserId userId = builder.noEmail().build();
|
||||||
|
assertEquals("John Smith", userId.getName());
|
||||||
|
assertEquals("Sales Dept.", userId.getComment());
|
||||||
|
assertNull(userId.getEmail());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testEmailOnlyFormatting() {
|
||||||
|
final UserId userId = UserId.onlyEmail("john.smith@example.com");
|
||||||
|
assertEquals("john.smith@example.com", userId.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testEmptyNameAndValidEmailFormatting() {
|
||||||
|
final UserId userId = UserId.nameAndEmail("", "john.smith@example.com");
|
||||||
|
assertEquals("john.smith@example.com", userId.toString());
|
||||||
|
assertEquals("john.smith@example.com", userId.asString(false));
|
||||||
|
assertEquals("john.smith@example.com", userId.asString(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testEmptyNameAndEmptyCommentAndValidEmailFormatting() {
|
||||||
|
final UserId userId = UserId.newBuilder()
|
||||||
|
.withComment("")
|
||||||
|
.withName("")
|
||||||
|
.withEmail("john.smith@example.com")
|
||||||
|
.build();
|
||||||
|
assertEquals(" () <john.smith@example.com>", userId.toString());
|
||||||
|
assertEquals(" () <john.smith@example.com>", userId.asString(false));
|
||||||
|
assertEquals("john.smith@example.com", userId.asString(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testEqualsWithDifferentCaseEmails() {
|
||||||
|
final String name = "John Smith";
|
||||||
|
final String comment = "Sales Dept.";
|
||||||
|
final String email = "john.smith@example.com";
|
||||||
|
final String upperEmail = email.toUpperCase();
|
||||||
|
final UserId userId1 = UserId.newBuilder().withComment(comment).withName(name).withEmail(email).build();
|
||||||
|
final UserId userId2 = UserId.newBuilder().withComment(comment).withName(name).withEmail(upperEmail).build();
|
||||||
|
assertEquals(userId1, userId2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testNotEqualWithDifferentNames() {
|
||||||
|
final String name1 = "John Smith";
|
||||||
|
final String name2 = "Don Duck";
|
||||||
|
final String comment = "Sales Dept.";
|
||||||
|
final String email = "john.smith@example.com";
|
||||||
|
final UserId userId1 = UserId.newBuilder().withComment(comment).withName(name1).withEmail(email).build();
|
||||||
|
final UserId userId2 = UserId.newBuilder().withComment(comment).withName(name2).withEmail(email).build();
|
||||||
|
assertNotEquals(userId1, userId2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testNotEqualWithDifferentComments() {
|
||||||
|
final String name = "John Smith";
|
||||||
|
final String comment1 = "Sales Dept.";
|
||||||
|
final String comment2 = "Legal Dept.";
|
||||||
|
final String email = "john.smith@example.com";
|
||||||
|
final UserId userId1 = UserId.newBuilder().withComment(comment1).withName(name).withEmail(email).build();
|
||||||
|
final UserId userId2 = UserId.newBuilder().withComment(comment2).withName(name).withEmail(email).build();
|
||||||
|
assertNotEquals(userId1, userId2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2021 Ivan Pizhenko, Paul Schaub.
|
* Copyright 2021 Paul Schaub. Copyright 2021 Flowcrypt a.s.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -39,7 +39,8 @@ public class SelectUserIdTest {
|
||||||
.simpleEcKeyRing("<alice@wonderland.lit>");
|
.simpleEcKeyRing("<alice@wonderland.lit>");
|
||||||
secretKeys = PGPainless.modifyKeyRing(secretKeys)
|
secretKeys = PGPainless.modifyKeyRing(secretKeys)
|
||||||
.addUserId(
|
.addUserId(
|
||||||
UserId.withName("Alice Liddell").noComment().withEmail("crazy@the-rabbit.hole"),
|
UserId.newBuilder().withName("Alice Liddell").noComment()
|
||||||
|
.withEmail("crazy@the-rabbit.hole").build(),
|
||||||
SecretKeyRingProtector.unprotectedKeys())
|
SecretKeyRingProtector.unprotectedKeys())
|
||||||
.done();
|
.done();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue