1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.forgerock.selfservice.example;
17
18 import static org.forgerock.json.JsonValue.field;
19 import static org.forgerock.json.JsonValue.json;
20 import static org.forgerock.json.JsonValue.object;
21 import static org.forgerock.json.resource.Responses.newActionResponse;
22 import static org.wrensecurity.guava.common.base.Strings.isNullOrEmpty;
23
24 import jakarta.mail.Authenticator;
25 import jakarta.mail.Message;
26 import jakarta.mail.MessagingException;
27 import jakarta.mail.PasswordAuthentication;
28 import jakarta.mail.Session;
29 import jakarta.mail.Transport;
30 import jakarta.mail.internet.InternetAddress;
31 import jakarta.mail.internet.MimeMessage;
32 import java.util.Properties;
33 import org.forgerock.json.JsonValue;
34 import org.forgerock.json.resource.ActionRequest;
35 import org.forgerock.json.resource.ActionResponse;
36 import org.forgerock.json.resource.BadRequestException;
37 import org.forgerock.json.resource.InternalServerErrorException;
38 import org.forgerock.json.resource.NotSupportedException;
39 import org.forgerock.json.resource.PatchRequest;
40 import org.forgerock.json.resource.ReadRequest;
41 import org.forgerock.json.resource.ResourceException;
42 import org.forgerock.json.resource.ResourceResponse;
43 import org.forgerock.json.resource.SingletonResourceProvider;
44 import org.forgerock.json.resource.UpdateRequest;
45 import org.forgerock.services.context.Context;
46 import org.forgerock.util.Reject;
47 import org.forgerock.util.promise.Promise;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51
52
53
54
55
56 final class ExampleEmailService implements SingletonResourceProvider {
57
58 private static final Logger LOGGER = LoggerFactory.getLogger(ExampleEmailService.class);
59
60 private final String host;
61 private final String port;
62 private final String username;
63 private final String password;
64
65 ExampleEmailService(JsonValue config) {
66 host = config.get("host").required().asString();
67 port = config.get("port").required().asString();
68 username = System.getProperty("mailserver.username");
69 password = System.getProperty("mailserver.password");
70 Reject.ifNull(username, password);
71 }
72
73 @Override
74 public Promise<ActionResponse, ResourceException> actionInstance(Context context, ActionRequest request) {
75 if (request.getAction().equals("send")) {
76 try {
77 JsonValue response = sendEmail(request.getContent());
78 return newActionResponse(response).asPromise();
79 } catch (ResourceException rE) {
80 return rE.asPromise();
81 }
82 }
83
84 return new NotSupportedException("Unknown action " + request.getAction()).asPromise();
85 }
86
87 private JsonValue sendEmail(JsonValue document) throws ResourceException {
88 String to = document.get("to").asString();
89
90 if (isNullOrEmpty(to)) {
91 throw new BadRequestException("Field to is not specified");
92 }
93
94 String from = document.get("from").asString();
95
96 if (isNullOrEmpty(from)) {
97 throw new BadRequestException("Field from is not specified");
98 }
99
100 String subject = document.get("subject").asString();
101
102 if (isNullOrEmpty(subject)) {
103 throw new BadRequestException("Field subject is not specified");
104 }
105
106 String messageBody = document.get("body").asString();
107
108 if (isNullOrEmpty(messageBody)) {
109 throw new BadRequestException("Field message is not specified");
110 }
111
112 Properties props = new Properties();
113 props.put("mail.smtp.auth", "true");
114 props.put("mail.smtp.starttls.enable", "true");
115 props.put("mail.smtp.host", host);
116 props.put("mail.smtp.port", port);
117
118 Session session = Session.getInstance(props, new Authenticator() {
119
120 @Override
121 protected PasswordAuthentication getPasswordAuthentication() {
122 return new PasswordAuthentication(username, password);
123 }
124
125 });
126
127 try {
128 Message message = new MimeMessage(session);
129 message.setFrom(new InternetAddress(from));
130 message.setRecipients(Message.RecipientType.TO,
131 InternetAddress.parse(to));
132 message.setSubject(subject);
133 message.setContent(messageBody, "text/html; charset=UTF-8");
134
135 Transport.send(message);
136 LOGGER.debug("Email sent to " + to);
137
138 } catch (MessagingException mE) {
139 throw new InternalServerErrorException(mE);
140 }
141
142 return json(object(field("status", "okay")));
143 }
144
145 @Override
146 public Promise<ResourceResponse, ResourceException> patchInstance(Context context, PatchRequest request) {
147 return new NotSupportedException().asPromise();
148 }
149
150 @Override
151 public Promise<ResourceResponse, ResourceException> readInstance(Context context, ReadRequest request) {
152 return new NotSupportedException().asPromise();
153 }
154
155 @Override
156 public Promise<ResourceResponse, ResourceException> updateInstance(Context context, UpdateRequest request) {
157 return new NotSupportedException().asPromise();
158 }
159
160 }