Skip to content

Commit

Permalink
Move NotificationTemplate to MailNotificationService as it's mostly r…
Browse files Browse the repository at this point in the history
…elevant for formatting email
  • Loading branch information
jpassing committed Nov 28, 2023
1 parent 1026807 commit 6242d9d
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,18 @@
package com.google.solutions.jitaccess.core.services;

import com.google.common.base.Preconditions;
import com.google.common.escape.Escaper;
import com.google.common.html.HtmlEscapers;
import com.google.solutions.jitaccess.core.AccessException;
import com.google.solutions.jitaccess.core.adapters.SmtpAdapter;

import java.io.IOException;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.EnumSet;

/**
Expand Down Expand Up @@ -97,15 +102,15 @@ public void sendNotification(Notification notification) throws NotificationExcep
Preconditions.checkNotNull(notification, "notification");

var htmlTemplate = loadResource(
String.format("notifications/%s.html", notification.getTemplateId()));
String.format("notifications/%s.html", notification.getType()));
if (htmlTemplate == null) {
//
// Unknown kind of notification, ignore.
//
return;
}

var formattedMessage = new NotificationTemplate(
var formattedMessage = new MessageTemplate(
htmlTemplate,
this.options.timeZone,
HtmlEscapers.htmlEscaper())
Expand All @@ -130,6 +135,61 @@ public void sendNotification(Notification notification) throws NotificationExcep
// Inner classes.
// -------------------------------------------------------------------------

/**
* Template for turning a notification object into some textual representation.
*/
public static class MessageTemplate {
private final String template;
private final Escaper escaper;
private final ZoneId timezoneId;

public MessageTemplate(
String template,
ZoneId timezoneId,
Escaper escaper
) {
Preconditions.checkNotNull(template, "template");
Preconditions.checkNotNull(timezoneId, "timezoneId");
Preconditions.checkNotNull(escaper, "escaper");

this.template = template;
this.timezoneId = timezoneId;
this.escaper = escaper;
}

public String format(NotificationService.Notification notification) {
Preconditions.checkNotNull(notification, "notification");

//
// Replace all {{PROPERTY}} placeholders in the template.
//

var message = this.template;
for (var property : notification.properties.entrySet()) {
String propertyValue;
if (property.getValue() instanceof Instant) {
//
// Apply time zone and convert to string.
//
propertyValue = OffsetDateTime
.ofInstant((Instant) property.getValue(), this.timezoneId)
.truncatedTo(ChronoUnit.SECONDS)
.format(DateTimeFormatter.RFC_1123_DATE_TIME);
}
else {
//
// Convert to a safe string.
//
propertyValue = escaper.escape(property.getValue().toString());
}

message = message.replace("{{" + property.getKey() + "}}", propertyValue);
}

return message;
}
}

public static class Options {
public static final ZoneId DEFAULT_TIMEZONE = ZoneOffset.UTC;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,10 @@
package com.google.solutions.jitaccess.core.services;

import com.google.common.base.Preconditions;
import com.google.common.escape.Escaper;
import com.google.solutions.jitaccess.core.data.UserId;

import jakarta.enterprise.context.ApplicationScoped;
import java.io.IOException;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
Expand Down Expand Up @@ -96,7 +90,10 @@ public String getSubject() {
return subject;
}

public abstract String getTemplateId();
/**
* @return string identifying the type of notification.
*/
public abstract String getType();

protected Notification(
Collection<UserId> toRecipients,
Expand Down Expand Up @@ -126,61 +123,6 @@ public String toString() {
}
}

/**
* Template for turning a notification object into some textual representation.
*/
public static class NotificationTemplate {
private final String template;
private final Escaper escaper;
private final ZoneId timezoneId;

public NotificationTemplate(
String template,
ZoneId timezoneId,
Escaper escaper
) {
Preconditions.checkNotNull(template, "template");
Preconditions.checkNotNull(timezoneId, "timezoneId");
Preconditions.checkNotNull(escaper, "escaper");

this.template = template;
this.timezoneId = timezoneId;
this.escaper = escaper;
}

public String format(NotificationService.Notification notification) {
Preconditions.checkNotNull(notification, "notification");

//
// Replace all {{PROPERTY}} placeholders in the template.
//

var message = this.template;
for (var property : notification.properties.entrySet()) {
String propertyValue;
if (property.getValue() instanceof Instant) {
//
// Apply time zone and convert to string.
//
propertyValue = OffsetDateTime
.ofInstant((Instant)property.getValue(), this.timezoneId)
.truncatedTo(ChronoUnit.SECONDS)
.format(DateTimeFormatter.RFC_1123_DATE_TIME);
}
else {
//
// Convert to a safe string.
//
propertyValue = escaper.escape(property.getValue().toString());
}

message = message.replace("{{" + property.getKey() + "}}", propertyValue);
}

return message;
}
}

public static class NotificationException extends Exception {
public NotificationException(String message, Throwable cause) {
super(message, cause);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,7 @@ protected RequestActivationNotification(
}

@Override
public String getTemplateId() {
public String getType() {
return "RequestActivation";
}
}
Expand Down Expand Up @@ -932,7 +932,7 @@ protected boolean isReply() {
}

@Override
public String getTemplateId() {
public String getType() {
return "ActivationApproved";
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ protected TestNotification(
}

@Override
public String getTemplateId() {
public String getType() {
return this.templateId;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

import static org.junit.jupiter.api.Assertions.assertEquals;

public class TestNotificationTemplate {
public class TestMessageTemplate {
private static class TestNotification extends NotificationService.Notification {
private final String templateId;

Expand All @@ -53,7 +53,7 @@ protected TestNotification(
}

@Override
public String getTemplateId() {
public String getType() {
return this.templateId;
}
}
Expand All @@ -74,7 +74,7 @@ public void whenPropertiesContainHtmlTags_ThenFormatEscapesTags() {
properties,
"ignored-templateid");

var template = new NotificationService.NotificationTemplate(
var template = new MailNotificationService.MessageTemplate(
notification.properties
.entrySet()
.stream()
Expand All @@ -99,7 +99,7 @@ public void whenPropertiesContainDates_ThenFormatAppliesTimezone() {
properties,
"ignored-templateid");

var template = new NotificationService.NotificationTemplate(
var template = new MailNotificationService.MessageTemplate(
notification.properties
.entrySet()
.stream()
Expand Down

0 comments on commit 6242d9d

Please sign in to comment.