]> git.mxchange.org Git - addressbook-mailer-ejb.git/blob - src/java/org/mxchange/jusercore/model/email_address/AddressbookEmailChangeSessionBean.java
f63a0ff636bb123c2478a29c782ee5f6e9545cb3
[addressbook-mailer-ejb.git] / src / java / org / mxchange / jusercore / model / email_address / AddressbookEmailChangeSessionBean.java
1 /*
2  * Copyright (C) 2016 Roland Haeder
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Affero General Public License as
6  * published by the Free Software Foundation, either version 3 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU Affero General Public License for more details.
13  *
14  * You should have received a copy of the GNU Affero General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 package org.mxchange.jusercore.model.email_address;
18
19 import java.text.MessageFormat;
20 import java.util.GregorianCalendar;
21 import java.util.List;
22 import javax.annotation.PostConstruct;
23 import javax.ejb.EJB;
24 import javax.ejb.EJBException;
25 import javax.ejb.Stateless;
26 import javax.faces.FacesException;
27 import javax.jms.Connection;
28 import javax.jms.JMSException;
29 import javax.jms.MessageProducer;
30 import javax.jms.ObjectMessage;
31 import javax.jms.Queue;
32 import javax.jms.QueueConnectionFactory;
33 import javax.jms.Session;
34 import javax.naming.Context;
35 import javax.naming.InitialContext;
36 import javax.naming.NamingException;
37 import javax.persistence.NoResultException;
38 import javax.persistence.Query;
39 import org.mxchange.addressbook.mailer.model.delivery.AddressbookMailer;
40 import org.mxchange.addressbook.mailer.model.delivery.DeliverableAddressbookEmail;
41 import org.mxchange.jcoreee.database.BaseDatabaseBean;
42 import org.mxchange.jusercore.model.user.UserSessionBeanRemote;
43 import org.mxchange.jusercore.model.user.UserUtils;
44
45 /**
46  * A session bean for changing email addresses
47  * <p>
48  * @author Roland Haeder<roland@mxchange.org>
49  */
50 @Stateless (name = "emailchange", description = "A bean handling email changes")
51 public class AddressbookEmailChangeSessionBean extends BaseDatabaseBean implements EmailChangeSessionBeanRemote {
52
53         /**
54          * Serial number
55          */
56         private static final long serialVersionUID = 182_698_165_971_548L;
57
58         /**
59          * Connection
60          */
61         private Connection connection;
62
63         /**
64          * Object message
65          */
66         private ObjectMessage message;
67
68         /**
69          * Message producer
70          */
71         private MessageProducer messageProducer;
72
73         /**
74          * Mailer message queue
75          */
76         private Queue queue;
77
78         /**
79          * Session instance
80          */
81         private Session session;
82
83         /**
84          * User bean
85          */
86         @EJB
87         private UserSessionBeanRemote userBean;
88
89         /**
90          * Default constructor
91          */
92         public AddressbookEmailChangeSessionBean () {
93         }
94
95         @Override
96         @SuppressWarnings ("unchecked")
97         public List<String> allQueuedAddressesAsList () {
98                 // Trace message
99                 this.getLoggerBeanLocal().logTrace("allQueuedAddressesAsList: CALLED!"); //NOI18N
100
101                 // Get named query
102                 Query query = this.getEntityManager().createNamedQuery("AllEmailAddressChanges", List.class); //NOI18N
103
104                 // Get all entries
105                 List<String> emailAddresses = query.getResultList();
106
107                 // Trace message
108                 this.getLoggerBeanLocal().logTrace(MessageFormat.format("allQueuedAddressesAsList: emailAddresses.size()={0} - EXIT!", emailAddresses.size())); //NOI18N
109
110                 // Return it
111                 return emailAddresses;
112         }
113
114         @Override
115         public void enqueueEmailAddressForChange (final ChangeableEmailAddress emailChange) {
116                 // Trace message
117                 this.getLoggerBeanLocal().logTrace(MessageFormat.format("enqueueEmailAddressForChange: emailChange={0} - CALLED!", emailChange)); //NOI18N
118
119                 // Email address change should be valid
120                 if (null == emailChange) {
121                         // Abort here
122                         throw new NullPointerException("emailChange is null"); //NOI18N
123                 } else if (emailChange.getEmailChangeUser() == null) {
124                         // Throw NPE again
125                         throw new NullPointerException("emailChange.emailChangeUser is null"); //NOI18N
126                 } else if (emailChange.getEmailChangeUser().getUserId() == null) {
127                         // Throw NPE again
128                         throw new NullPointerException("emailChange.emailChangeUser.userId is null"); //NOI18N
129                 } else if (emailChange.getEmailChangeUser().getUserId() < 1) {
130                         // Not valid id
131                         throw new IllegalArgumentException(MessageFormat.format("emailChange.emailChangeUser.userId={0} is invalid.", emailChange.getEmailChangeUser().getUserId())); //NOI18N
132                 } else if (!this.userBean.ifUserExists(emailChange.getEmailChangeUser())) {
133                         // User does not exist
134                         throw new EJBException(MessageFormat.format("Email change with id {0} does not exist.", emailChange.getEmailChangeId())); //NOI18N
135                 } else if (emailChange.getEmailAddress().trim().isEmpty()) {
136                         // Email address is empty
137                         throw new IllegalArgumentException("emailChange.emaiLAddress is empty."); //NOI18N
138                 } else if (this.isEmailAddressEnqueued(emailChange.getEmailAddress())) {
139                         // Email address is already enqueued
140                         throw new EJBException(MessageFormat.format("Email address {0} is already enqueued.", emailChange.getEmailAddress())); //NOI18N
141                 }
142
143                 // The email change is not (yet) there, add secure hash and "created" timestamp
144                 emailChange.setEmailChangeCreated(new GregorianCalendar());
145                 this.generateSecureHash(emailChange);
146
147                 // Persist it
148                 //this.getEntityManager().persist(emailChange);
149                 // Get mailer instance
150                 DeliverableAddressbookEmail mailer = new AddressbookMailer();
151
152                 // Send out email change
153                 mailer.sendEmailChangeMail(this.messageProducer, this.message, emailChange);
154         }
155
156         /**
157          * Initialization of this bean
158          */
159         @PostConstruct
160         public void init () {
161                 try {
162                         // Get initial context
163                         Context context = new InitialContext();
164
165                         // Get factory from JMS resource
166                         QueueConnectionFactory connectionFactory = (QueueConnectionFactory) context.lookup("jms/addressbook-queue-factory"); //NOI18N
167
168                         // Lookup queue
169                         this.queue = (Queue) context.lookup("jms/addressbook-email-queue"); //NOI18N
170
171                         // Create connection
172                         this.connection = connectionFactory.createConnection();
173
174                         // Init session instance
175                         this.session = this.connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
176
177                         // And message producer
178                         this.messageProducer = this.session.createProducer(this.queue);
179
180                         // Finally the message instance itself
181                         this.message = this.session.createObjectMessage();
182                 } catch (final NamingException | JMSException e) {
183                         // Continued to throw
184                         throw new FacesException(e);
185                 }
186         }
187
188         @Override
189         public boolean isEmailAddressEnqueued (final String emailAddress) {
190                 // Trace message
191                 this.getLoggerBeanLocal().logTrace(MessageFormat.format("isEmailAddressEnqueued: emailAddress={0} - CALLED!", emailAddress)); //NOI18N
192
193                 // Create query instance
194                 Query query = this.getEntityManager().createNamedQuery("SearchEmailChangeByEmail"); //NOI18N
195
196                 // Add email address as parameter
197                 query.setParameter("email", emailAddress); //NOI18N
198
199                 // Initialize variable
200                 boolean isFound = false;
201
202                 // Try it
203                 try {
204                         // Try to get single result
205                         ChangeableEmailAddress dummy = (ChangeableEmailAddress) query.getSingleResult();
206
207                         // Found it
208                         isFound = true;
209                 } catch (final NoResultException ex) {
210                         // Log it
211                         this.getLoggerBeanLocal().logException(ex);
212                 }
213
214                 // Trace message
215                 this.getLoggerBeanLocal().logTrace(MessageFormat.format("isEmailAddressEnqueued: isFound={0} - EXIT!", isFound)); //NOI18N
216
217                 // Return it
218                 return isFound;
219         }
220
221         @Override
222         public void updateEmailAddress (final ChangeableEmailAddress emailAddress) {
223                 // Trace message
224                 this.getLoggerBeanLocal().logTrace(MessageFormat.format("updateEmailAddress: emailAddress={0} - CALLED!", emailAddress)); //NOI18N
225
226                 // Email address change should be valid
227                 if (null == emailAddress) {
228                         // Abort here
229                         throw new NullPointerException("emailAddress is null"); //NOI18N
230                 } else if (emailAddress.getEmailChangeId() == null) {
231                         // Throw NPE again
232                         throw new NullPointerException("emailAddress.emailChangeId is null"); //NOI18N
233                 } else if (emailAddress.getEmailChangeId() < 1) {
234                         // Not valid
235                         throw new IllegalArgumentException(MessageFormat.format("emailAddress.emailChangeId={0} is not valid.", emailAddress.getEmailChangeId())); //NOI18N
236                 } else if (emailAddress.getEmailAddress().trim().isEmpty()) {
237                         // Email address is empty
238                         throw new IllegalArgumentException("emailAddress.emaiLAddress is empty."); //NOI18N
239                 } else if (!this.userBean.ifUserExists(emailAddress.getEmailChangeUser())) {
240                         // User does not exist
241                         throw new EJBException(MessageFormat.format("Email change with id {0} does not exist.", emailAddress.getEmailChangeId())); //NOI18N
242                 } else if (!this.isEmailAddressEnqueued(emailAddress.getEmailAddress())) {
243                         // Email address is not enqueued
244                         throw new EJBException(MessageFormat.format("Email address {0} is not enqueued.", emailAddress.getEmailAddress())); //NOI18N
245                 }
246
247                 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
248         }
249
250         /**
251          * Generates a secure, unique hash for given email address change. This
252          * requires to check if the hash is really not there.
253          * <p>
254          * @param emailAddress Email address change
255          */
256         private void generateSecureHash (final ChangeableEmailAddress emailAddress) {
257                 // Email address change should be valid
258                 if (null == emailAddress) {
259                         // Abort here
260                         throw new NullPointerException("emailAddress is null"); //NOI18N
261                 } else if (emailAddress.getEmailAddress().trim().isEmpty()) {
262                         // Email address is empty
263                         throw new IllegalArgumentException("emailAddress.emaiLAddress is empty."); //NOI18N
264                 }
265
266                 // Initialize loop with null
267                 String hash = null;
268
269                 // Default is not used
270                 boolean isUsed = true;
271
272                 // Search for free hash
273                 while (isUsed) {
274                         // Generate hash, there is already in UserUtils a nice method that can be used for this purpose.
275                         hash = UserUtils.encryptPassword(String.format("%s:%s", emailAddress.getEmailAddress(), emailAddress.toString())); //NOI18N
276
277                         // The hash *may* be unique, better test it
278                         Query query = this.getEntityManager().createNamedQuery("SearchEmailChangeByHash", EmailAddressChange.class); //NOI18N
279
280                         // Set hash as parameter
281                         query.setParameter("hash", hash); //NOI18N
282
283                         // Try to get single result
284                         try {
285                                 // Get single result
286                                 ChangeableEmailAddress dummy = (ChangeableEmailAddress) query.getSingleResult();
287                         } catch (final NoResultException ex) {
288                                 // Not found
289                                 isUsed = false;
290                         }
291                 }
292
293                 // hash should not be null and set
294                 assert (hash != null) : "hash is null"; //NOI18N
295                 assert (!hash.isEmpty()) : "hash is empty"; //NOI18N
296
297                 // Set it in email change
298                 emailAddress.setEmailChangeHash(hash);
299         }
300
301 }