aboutsummaryrefslogtreecommitdiffstats
path: root/controller-api
diff options
context:
space:
mode:
authorOla Aunrønning <olaa@yahooinc.com>2022-10-27 14:47:25 +0200
committerGitHub <noreply@github.com>2022-10-27 14:47:25 +0200
commit30a93b4910c1de1a10ebccfa545d03e1deac8056 (patch)
tree48f239e59fd895064f653165652b8d111140d991 /controller-api
parent0cb3aa286942e998a598c390332466a432b6e956 (diff)
parentc6903a0afe6244587ccf2ae345acaff3b55fb12b (diff)
Merge pull request #24555 from vespa-engine/olaa/email-verification
Add email verification
Diffstat (limited to 'controller-api')
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/Mailer.java4
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/MockMailer.java6
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java6
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java6
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java3
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/Email.java56
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/PendingMailVerification.java81
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/TenantContact.java14
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/TenantContacts.java18
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/TenantInfo.java4
10 files changed, 183 insertions, 15 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/Mailer.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/Mailer.java
index 18662edc85e..27eec34cf4e 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/Mailer.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/Mailer.java
@@ -1,6 +1,8 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.controller.api.integration.organization;
+import com.yahoo.vespa.hosted.controller.tenant.PendingMailVerification;
+
/**
* Allows sending e-mail from a particular <code>user@domain</code>.
*
@@ -17,4 +19,6 @@ public interface Mailer {
/** Returns the domain this is configured to use. */
String domain();
+ void sendVerificationMail(PendingMailVerification pendingMailVerification);
+
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/MockMailer.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/MockMailer.java
index cb2b76d845c..dcfa9b7ea07 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/MockMailer.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/MockMailer.java
@@ -3,6 +3,7 @@ package com.yahoo.vespa.hosted.controller.api.integration.stubs;
import com.yahoo.vespa.hosted.controller.api.integration.organization.Mail;
import com.yahoo.vespa.hosted.controller.api.integration.organization.Mailer;
+import com.yahoo.vespa.hosted.controller.tenant.PendingMailVerification;
import java.util.ArrayList;
import java.util.HashMap;
@@ -47,6 +48,11 @@ public class MockMailer implements Mailer {
return "domain";
}
+ @Override
+ public void sendVerificationMail(PendingMailVerification pendingMailVerification) {
+ send(new Mail(List.of(pendingMailVerification.getMailAddress()), "subject", "message"));
+ }
+
/** Returns the list of mails sent to the given recipient. Modifications affect the set of mails stored in this. */
public List<Mail> inbox(String recipient) {
return mails.getOrDefault(recipient, List.of());
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java
index c2682334ce0..b8de63b61a9 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java
@@ -58,6 +58,7 @@ enum PathGroup {
"/application/v4/tenant/{tenant}/info/profile",
"/application/v4/tenant/{tenant}/info/billing",
"/application/v4/tenant/{tenant}/info/contacts",
+ "/application/v4/tenant/{tenant}/info/resend-mail-verification",
"/application/v4/tenant/{tenant}/notifications",
"/routing/v1/status/tenant/{tenant}/{*}"),
@@ -255,7 +256,10 @@ enum PathGroup {
/** Paths used to approve requests to access tenant resources */
accessRequestApproval(Matcher.tenant, "/application/v4/tenant/{tenant}/access/approve/operator",
- "/application/v4/tenant/{tenant}/access/managed/operator");
+ "/application/v4/tenant/{tenant}/access/managed/operator"),
+
+ /** Path used for email verification */
+ emailVerification("/user/v1/email/verify");
final List<String> pathSpecs;
final List<Matcher> matchers;
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java
index 91eaec53aa4..2d4f98dfa8d 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java
@@ -209,7 +209,11 @@ enum Policy {
horizonProxyOperations(Privilege.grant(Action.all())
.on(PathGroup.horizonProxy)
- .in(SystemName.PublicCd, SystemName.Public));
+ .in(SystemName.PublicCd, SystemName.Public)),
+
+ emailVerification(Privilege.grant(Action.create)
+ .on(PathGroup.emailVerification)
+ .in(SystemName.PublicCd, SystemName.Public));
private final Set<Privilege> privileges;
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java
index a9d67c2d78a..e40c99a64be 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java
@@ -28,7 +28,8 @@ public enum RoleDefinition {
everyone(Policy.classifiedRead,
Policy.publicRead,
Policy.user,
- Policy.tenantCreate),
+ Policy.tenantCreate,
+ Policy.emailVerification),
/** Build service which may submit new applications for continuous deployment. */
buildService(everyone,
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/Email.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/Email.java
new file mode 100644
index 00000000000..ea6e0e9c754
--- /dev/null
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/Email.java
@@ -0,0 +1,56 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.controller.tenant;
+
+import java.util.Objects;
+
+/**
+ * @author olaa
+ */
+public class Email {
+
+ private final String emailAddress;
+ private final boolean isVerified;
+
+ public Email(String emailAddress, boolean isVerified) {
+ this.emailAddress = emailAddress;
+ this.isVerified = isVerified;
+ }
+
+ public String getEmailAddress() {
+ return emailAddress;
+ }
+
+ public boolean isVerified() {
+ return isVerified;
+ }
+
+ public static Email empty() {
+ return new Email("", true);
+ }
+
+ public Email withEmailAddress(String emailAddress) {
+ return new Email(emailAddress, isVerified);
+ }
+
+ public Email withVerification(boolean isVerified) {
+ return new Email(emailAddress, isVerified);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Email email = (Email) o;
+ return isVerified == email.isVerified && Objects.equals(emailAddress, email.emailAddress);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(emailAddress, isVerified);
+ }
+
+ @Override
+ public String toString() {
+ return emailAddress;
+ }
+}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/PendingMailVerification.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/PendingMailVerification.java
new file mode 100644
index 00000000000..af5ae746d22
--- /dev/null
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/PendingMailVerification.java
@@ -0,0 +1,81 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.controller.tenant;
+
+import com.yahoo.config.provision.TenantName;
+
+import java.time.Instant;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @author olaa
+ */
+public class PendingMailVerification {
+
+ private final TenantName tenantName;
+ private final String mailAddress;
+ private final String verificationCode;
+ private final Instant verificationDeadline;
+ private final MailType mailType;
+
+ public PendingMailVerification(TenantName tenantName, String mailAddress, String verificationCode, Instant verificationDeadline, MailType mailType) {
+ this.tenantName = tenantName;
+ this.mailAddress = mailAddress;
+ this.verificationCode = verificationCode;
+ this.verificationDeadline = verificationDeadline;
+ this.mailType = mailType;
+ }
+
+ public TenantName getTenantName() {
+ return tenantName;
+ }
+
+ public String getMailAddress() {
+ return mailAddress;
+ }
+
+ public String getVerificationCode() {
+ return verificationCode;
+ }
+
+ public Instant getVerificationDeadline() {
+ return verificationDeadline;
+ }
+
+ public MailType getMailType() {
+ return mailType;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ PendingMailVerification that = (PendingMailVerification) o;
+ return Objects.equals(tenantName, that.tenantName) &&
+ Objects.equals(mailAddress, that.mailAddress) &&
+ Objects.equals(verificationCode, that.verificationCode) &&
+ Objects.equals(verificationDeadline, that.verificationDeadline) &&
+ mailType == that.mailType;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(tenantName, mailAddress, verificationCode, verificationDeadline, mailType);
+ }
+
+ @Override
+ public String toString() {
+ return "PendingMailVerification{" +
+ "tenantName=" + tenantName +
+ ", mailAddress='" + mailAddress + '\'' +
+ ", verificationCode='" + verificationCode + '\'' +
+ ", verificationDeadline=" + verificationDeadline +
+ ", mailType=" + mailType +
+ '}';
+ }
+
+ public enum MailType {
+ TENANT_CONTACT,
+ NOTIFICATIONS
+ }
+}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/TenantContact.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/TenantContact.java
index 3aa5600ed87..482bb26bcf9 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/TenantContact.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/TenantContact.java
@@ -8,36 +8,36 @@ import java.util.Objects;
*/
public class TenantContact {
private final String name;
- private final String email;
+ private final Email email;
private final String phone;
- private TenantContact(String name, String email, String phone) {
+ private TenantContact(String name, Email email, String phone) {
this.name = Objects.requireNonNull(name);
this.email = Objects.requireNonNull(email);
this.phone = Objects.requireNonNull(phone);
}
- public static TenantContact from(String name, String email, String phone) {
+ public static TenantContact from(String name, Email email, String phone) {
return new TenantContact(name, email, phone);
}
- public static TenantContact from(String name, String email) {
+ public static TenantContact from(String name, Email email) {
return TenantContact.from(name, email, "");
}
public static TenantContact empty() {
- return new TenantContact("", "", "");
+ return new TenantContact("", Email.empty(), "");
}
public String name() { return name; }
- public String email() { return email; }
+ public Email email() { return email; }
public String phone() { return phone; }
public TenantContact withName(String name) {
return new TenantContact(name, email, phone);
}
- public TenantContact withEmail(String email) {
+ public TenantContact withEmail(Email email) {
return new TenantContact(name, email, phone);
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/TenantContacts.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/TenantContacts.java
index bd8671d814f..7e0fc50660e 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/TenantContacts.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/TenantContacts.java
@@ -5,6 +5,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
+import java.util.stream.Collectors;
/**
* Tenant contacts are targets of the notification system. Sometimes they
@@ -35,6 +36,13 @@ public class TenantContacts {
return contacts;
}
+ public <T extends Contact> List<T> ofType(Class<T> type) {
+ return contacts.stream()
+ .filter(type::isInstance)
+ .map(type::cast)
+ .collect(Collectors.toList());
+ }
+
public boolean isEmpty() {
return contacts.isEmpty();
}
@@ -77,14 +85,18 @@ public class TenantContacts {
}
public static class EmailContact extends Contact {
- private final String email;
+ private final Email email;
- public EmailContact(List<Audience> audiences, String email) {
+ public EmailContact(List<Audience> audiences, Email email) {
super(audiences);
this.email = email;
}
- public String email() { return email; }
+ public Email email() { return email; }
+
+ public EmailContact withEmail(Email email) {
+ return new EmailContact(audiences(), email);
+ }
@Override
public Type type() {
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/TenantInfo.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/TenantInfo.java
index 0ca7863fbce..36a302ed0d8 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/TenantInfo.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/TenantInfo.java
@@ -23,7 +23,7 @@ public class TenantInfo {
private final TenantBilling billingContact;
private final TenantContacts contacts;
- TenantInfo(String name, String email, String website, String contactName, String contactEmail,
+ TenantInfo(String name, String email, String website, String contactName, Email contactEmail,
TenantAddress address, TenantBilling billingContact, TenantContacts contacts) {
this(name, email, website, TenantContact.from(contactName, contactEmail), address, billingContact, contacts);
}
@@ -39,7 +39,7 @@ public class TenantInfo {
}
public static TenantInfo empty() {
- return new TenantInfo("", "", "", "", "", TenantAddress.empty(), TenantBilling.empty(), TenantContacts.empty());
+ return new TenantInfo("", "", "", "", Email.empty(), TenantAddress.empty(), TenantBilling.empty(), TenantContacts.empty());
}
public String name() {