]> git.mxchange.org Git - addressbook-war.git/blob
93cc951ef12babc19e9ded9e6ea1841017cd44a8
[addressbook-war.git] /
1 /*
2  * Copyright (C) 2016 - 2022 Free Software Foundation
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.addressbook.beans.user.email_address;
18
19 import fish.payara.cdi.jsr107.impl.NamedCache;
20 import java.text.MessageFormat;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Objects;
24 import javax.annotation.PostConstruct;
25 import javax.cache.Cache;
26 import javax.ejb.EJB;
27 import javax.enterprise.context.RequestScoped;
28 import javax.faces.view.facelets.FaceletException;
29 import javax.inject.Inject;
30 import javax.inject.Named;
31 import org.mxchange.addressbook.beans.BaseAddressbookBean;
32 import org.mxchange.addressbook.beans.features.AddressbookFeaturesWebApplicationController;
33 import org.mxchange.addressbook.beans.user.login.AddressbookUserLoginWebSessionController;
34 import org.mxchange.jcontacts.model.contact.Contact;
35 import org.mxchange.jcoreee.utils.FacesUtils;
36 import org.mxchange.jusercore.model.email_address.ChangeableEmailAddress;
37 import org.mxchange.jusercore.model.email_address.EmailAddressChange;
38 import org.mxchange.jusercore.model.email_address.status.EmailChangeStatus;
39 import org.mxchange.jusercore.model.user.User;
40 import org.mxchange.jusercore.model.user.email_address.UserEmailChangeSessionBeanRemote;
41 import org.mxchange.juserlogincore.exceptions.UserPasswordMismatchException;
42
43 /**
44  * A web session-scoped bean for changing email addresses
45  * <p>
46  * @author Roland Häder<roland@mxchange.org>
47  */
48 @Named ("userEmailChangeController")
49 @RequestScoped
50 public class AddressbookEmailChangeWebRequestBean extends BaseAddressbookBean implements AddressbookEmailChangeWebRequestController {
51
52         /**
53          * Serial number
54          */
55         private static final long serialVersionUID = 186_078_724_659_153L;
56
57         /**
58          * Email address 1 (changing)
59          */
60         private String emailAddress;
61
62         /**
63          * Email address 2 (repeat in changing)
64          */
65         private String emailAddressRepeat;
66
67         /**
68          * Remote email change bean
69          */
70         @EJB (lookup = "java:global/addressbook-ejb/userEmailChange!org.mxchange.jusercore.model.user.email_address.UserEmailChangeSessionBeanRemote")
71         private UserEmailChangeSessionBeanRemote emailChangeBean;
72
73         /**
74          * Features controller
75          */
76         @Inject
77         private AddressbookFeaturesWebApplicationController featureController;
78
79         /**
80          * Local list of already queued email addresses
81          */
82         @Inject
83         @NamedCache (cacheName = "queuedEmailCache")
84         private Cache<String, Boolean> queuedEmailCache;
85
86         /**
87          * Login controller (bean)
88          */
89         @Inject
90         private AddressbookUserLoginWebSessionController userLoginController;
91
92         /**
93          * Default constructor
94          */
95         public AddressbookEmailChangeWebRequestBean () {
96                 // Call super constructor
97                 super();
98         }
99
100         /**
101          * Changes logged-in user's email address if the current password matches.
102          * <p>
103          * @return Redirect outcome
104          */
105         public String doUserChangeEmailAddress () {
106                 // This method shall only be called if the user is logged-in
107                 if (!this.userLoginController.isUserLoggedIn()) {
108                         // Not logged-in
109                         throw new IllegalStateException("User is not logged-in"); //NOI18N
110                 } else if (!this.featureController.isFeatureEnabled("user_change_email_address")) { //NOI18N
111                         // Editing is not allowed
112                         throw new IllegalStateException("User tried to change email address"); //NOI18N
113                 } else if (!this.isRequiredChangeEmailAddressSet()) {
114                         // Not all required fields are set
115                         throw new FaceletException("Not all required fields are set."); //NOI18N
116                 } else if (!Objects.equals(this.getEmailAddress(), this.getEmailAddressRepeat())) {
117                         // Email address 1+2 mismatch
118                         this.showFacesMessage("form_user_change_email_address:emailAddressRepeat", "ERROR_USER_EMAIL_ADDRESSES_MISMATCH"); //NOI18N
119                         return ""; //NOI18N
120                 } else if (!this.userLoginController.ifCurrentPasswordMatches()) {
121                         // Password not matching
122                         this.showFacesMessage("form_login_user_change_email_address:currentPassword", new UserPasswordMismatchException(this.userLoginController.getLoggedInUser())); //NOI18N
123                         return ""; //NOI18N
124                 }
125
126                 // Get user instance
127                 final User user = this.userLoginController.getLoggedInUser();
128
129                 // It should be there, so run some tests on it
130                 assert (user instanceof User) : "Instance userLoginController.loggedInUser is null"; //NOI18N
131                 assert (user.getUserId() instanceof Long) : "Instance userLoginController.loggedInUser.userId is null"; //NOI18N
132                 assert (user.getUserId() > 0) : MessageFormat.format("userLoginController.loggedInUser.userId={0} is invalid", user.getUserId()); //NOI18N
133                 assert (user.getUserContact() instanceof Contact) : "Instance userLoginController.loggedInUser.userContact is null"; //NOI18N
134                 assert (user.getUserContact().getContactId() instanceof Long) : "Instance userLoginController.userContact.contactId is null"; //NOI18N
135                 assert (user.getUserContact().getContactId() > 0) : MessageFormat.format("Instance userLoginController.userContact.contactId={0} is invalid", user.getUserContact().getContactId()); //NOI18N
136
137                 // Check if the email address is already enqueued
138                 if (this.isEmailAddressQueued(this.getEmailAddress())) {
139                         // Clear both email addresses
140                         this.setEmailAddress(null);
141                         this.setEmailAddressRepeat(null);
142
143                         // Yes, then abort here
144                         this.showFacesMessage("form_user_change_email_address:emailAddress", "ERROR_USER_CHANGE_EMAIL_ADDRESS_ALREADY_QUEUED"); //NOI18N
145                         return ""; //NOI18N
146                 }
147
148                 // Create change object, to save EJB calls, the hash is not generated here
149                 final ChangeableEmailAddress emailChange = new EmailAddressChange(
150                                                                          user,
151                                                                          this.getEmailAddress(),
152                                                                          EmailChangeStatus.NEW
153                                                          );
154
155                 // Get base URL
156                 final String baseUrl = FacesUtils.generateBaseUrl();
157
158                 // Call EJB
159                 this.emailChangeBean.enqueueEmailAddressForChange(emailChange, baseUrl);
160
161                 // Unset all so the user is forced to re-enter it
162                 this.clear();
163
164                 // All fine
165                 return "user_login_email_change_queued"; //NOI18N
166         }
167
168         /**
169          * Getter for email address 1 (changing)
170          * <p>
171          * @return Email address
172          */
173         public String getEmailAddress () {
174                 return this.emailAddress;
175         }
176
177         /**
178          * Setter for email address 1 (changing)
179          * <p>
180          * @param emailAddress Email address 1
181          */
182         public void setEmailAddress (final String emailAddress) {
183                 this.emailAddress = emailAddress;
184         }
185
186         /**
187          * Getter for email address 2 (repeat changing)
188          * <p>
189          * @return Email address 2
190          */
191         public String getEmailAddressRepeat () {
192                 return this.emailAddressRepeat;
193         }
194
195         /**
196          * Setter for email address 2 (repeat changing)
197          * <p>
198          * @param emailAddressRepeat Email address 2
199          */
200         public void setEmailAddressRepeat (final String emailAddressRepeat) {
201                 this.emailAddressRepeat = emailAddressRepeat;
202         }
203
204         /**
205          * Post-construction
206          */
207         @PostConstruct
208         public void init () {
209                 // Is cache there?
210                 if (!this.queuedEmailCache.iterator().hasNext()) {
211                         // Get whole list
212                         final List<String> list = this.emailChangeBean.allQueuedAddresses();
213
214                         // Add all
215                         for (final Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
216                                 // Get next element
217                                 final String next = iterator.next();
218
219                                 // Add it to cache
220                                 this.queuedEmailCache.put(next, Boolean.TRUE);
221                         }
222                 }
223         }
224
225         @Override
226         public boolean isRequiredChangeEmailAddressSet () {
227                 return ((this.getEmailAddress() != null) &&
228                                 (this.getEmailAddressRepeat() != null));
229         }
230
231         /**
232          * Clears email address fields so the user has to re-enter them
233          */
234         private void clear () {
235                 // Clear fields
236                 this.setEmailAddress(null);
237                 this.setEmailAddressRepeat(null);
238         }
239
240         /**
241          * Checks if given email address has already been queued. First a local list
242          * is being checked, if not found, the EJB is called. Only if found, the
243          * result is "cached" in the list.
244          * <p>
245          * @param emailAddress Email address to verify
246          * <p>
247          * @return Whether the email address in field emailAddress is already queued
248          */
249         private boolean isEmailAddressQueued (final String emailAddress) {
250                 // It should be there
251                 assert (emailAddress != null) : "emailAddress should not be null"; //NOI18N
252                 assert (!emailAddress.trim().isEmpty()) : "emailAddress should not be empty"; //NOI18N
253
254                 // Check list
255                 if (this.queuedEmailCache.containsKey(emailAddress)) {
256                         // Okay, found it
257                         return true;
258                 }
259
260                 // Check EJB
261                 final boolean isQueued = this.emailChangeBean.isEmailAddressEnqueued(emailAddress);
262
263                 // Is it there?
264                 if (isQueued) {
265                         // Add to list
266                         this.queuedEmailCache.put(emailAddress, Boolean.TRUE);
267                 }
268
269                 // Return status
270                 return isQueued;
271         }
272
273 }