View Javadoc
1   /*
2    * The contents of this file are subject to the terms of the Common Development and
3    * Distribution License (the License). You may not use this file except in compliance with the
4    * License.
5    *
6    * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
7    * specific language governing permission and limitations under the License.
8    *
9    * When distributing Covered Software, include this CDDL Header Notice in each file and include
10   * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
11   * Header, with the fields enclosed by brackets [] replaced by your own identifying
12   * information: "Portions copyright [year] [name of copyright owner]".
13   *
14   * Copyright 2015-2016 ForgeRock AS.
15   */
16  
17  package org.forgerock.selfservice.example;
18  
19  import static org.wrensecurity.guava.common.base.Strings.isNullOrEmpty;
20  import static org.forgerock.json.JsonValue.field;
21  import static org.forgerock.json.JsonValue.json;
22  import static org.forgerock.json.JsonValue.object;
23  import static org.forgerock.json.resource.Responses.newActionResponse;
24  
25  import org.forgerock.services.context.Context;
26  import org.forgerock.json.JsonValue;
27  import org.forgerock.json.resource.ActionRequest;
28  import org.forgerock.json.resource.ActionResponse;
29  import org.forgerock.json.resource.BadRequestException;
30  import org.forgerock.json.resource.InternalServerErrorException;
31  import org.forgerock.json.resource.NotSupportedException;
32  import org.forgerock.json.resource.PatchRequest;
33  import org.forgerock.json.resource.ReadRequest;
34  import org.forgerock.json.resource.ResourceException;
35  import org.forgerock.json.resource.ResourceResponse;
36  import org.forgerock.json.resource.SingletonResourceProvider;
37  import org.forgerock.json.resource.UpdateRequest;
38  import org.forgerock.util.Reject;
39  import org.forgerock.util.promise.Promise;
40  import org.slf4j.Logger;
41  import org.slf4j.LoggerFactory;
42  
43  import javax.mail.Authenticator;
44  import javax.mail.Message;
45  import javax.mail.MessagingException;
46  import javax.mail.PasswordAuthentication;
47  import javax.mail.Session;
48  import javax.mail.Transport;
49  import javax.mail.internet.InternetAddress;
50  import javax.mail.internet.MimeMessage;
51  import java.util.Properties;
52  
53  /**
54   * Example email service.
55   *
56   * @since 0.1.0
57   */
58  final class ExampleEmailService implements SingletonResourceProvider {
59  
60      private static final Logger LOGGER = LoggerFactory.getLogger(ExampleEmailService.class);
61  
62      private final String host;
63      private final String port;
64      private final String username;
65      private final String password;
66  
67      ExampleEmailService(JsonValue config) {
68          host = config.get("host").required().asString();
69          port = config.get("port").required().asString();
70          username = System.getProperty("mailserver.username");
71          password = System.getProperty("mailserver.password");
72          Reject.ifNull(username, password);
73      }
74  
75      @Override
76      public Promise<ActionResponse, ResourceException> actionInstance(Context context, ActionRequest request) {
77          if (request.getAction().equals("send")) {
78              try {
79                  JsonValue response = sendEmail(request.getContent());
80                  return newActionResponse(response).asPromise();
81              } catch (ResourceException rE) {
82                  return rE.asPromise();
83              }
84          }
85  
86          return new NotSupportedException("Unknown action " + request.getAction()).asPromise();
87      }
88  
89      private JsonValue sendEmail(JsonValue document) throws ResourceException {
90          String to = document.get("to").asString();
91  
92          if (isNullOrEmpty(to)) {
93              throw new BadRequestException("Field to is not specified");
94          }
95  
96          String from = document.get("from").asString();
97  
98          if (isNullOrEmpty(from)) {
99              throw new BadRequestException("Field from is not specified");
100         }
101 
102         String subject = document.get("subject").asString();
103 
104         if (isNullOrEmpty(subject)) {
105             throw new BadRequestException("Field subject is not specified");
106         }
107 
108         String messageBody = document.get("body").asString();
109 
110         if (isNullOrEmpty(messageBody)) {
111             throw new BadRequestException("Field message is not specified");
112         }
113 
114         Properties props = new Properties();
115         props.put("mail.smtp.auth", "true");
116         props.put("mail.smtp.starttls.enable", "true");
117         props.put("mail.smtp.host", host);
118         props.put("mail.smtp.port", port);
119 
120         Session session = Session.getInstance(props, new Authenticator() {
121 
122             protected PasswordAuthentication getPasswordAuthentication() {
123                 return new PasswordAuthentication(username, password);
124             }
125 
126         });
127 
128         try {
129             Message message = new MimeMessage(session);
130             message.setFrom(new InternetAddress(from));
131             message.setRecipients(Message.RecipientType.TO,
132                     InternetAddress.parse(to));
133             message.setSubject(subject);
134             message.setContent(messageBody, "text/html; charset=UTF-8");
135 
136             Transport.send(message);
137             LOGGER.debug("Email sent to " + to);
138 
139         } catch (MessagingException mE) {
140             throw new InternalServerErrorException(mE);
141         }
142 
143         return json(object(field("status", "okay")));
144     }
145 
146     @Override
147     public Promise<ResourceResponse, ResourceException> patchInstance(Context context, PatchRequest request) {
148         return new NotSupportedException().asPromise();
149     }
150 
151     @Override
152     public Promise<ResourceResponse, ResourceException> readInstance(Context context, ReadRequest request) {
153         return new NotSupportedException().asPromise();
154     }
155 
156     @Override
157     public Promise<ResourceResponse, ResourceException> updateInstance(Context context, UpdateRequest request) {
158         return new NotSupportedException().asPromise();
159     }
160 
161 }