2 * Copyright (C) 2016 - 2022 Free Software Foundation
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.
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.
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/>.
17 package org.mxchange.addressbook.beans.user.email_address;
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;
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.user.User;
39 import org.mxchange.jusercore.model.user.email_address.UserEmailChangeSessionBeanRemote;
40 import org.mxchange.juserlogincore.exceptions.UserPasswordMismatchException;
43 * A web session-scoped bean for changing email addresses
45 * @author Roland Häder<roland@mxchange.org>
47 @Named ("userEmailChangeController")
49 public class AddressbookEmailChangeWebRequestBean extends BaseAddressbookBean implements AddressbookEmailChangeWebRequestController {
54 private static final long serialVersionUID = 186_078_724_659_153L;
57 * Email address 1 (changing)
59 private String emailAddress;
62 * Email address 2 (repeat in changing)
64 private String emailAddressRepeat;
67 * Remote email change bean
69 @EJB (lookup = "java:global/addressbook-ejb/userEmailChange!org.mxchange.jusercore.model.user.email_address.UserEmailChangeSessionBeanRemote")
70 private UserEmailChangeSessionBeanRemote emailChangeBean;
76 private AddressbookFeaturesWebApplicationController featureController;
79 * Local list of already queued email addresses
82 @NamedCache (cacheName = "queuedEmailCache")
83 private Cache<String, Boolean> queuedEmailCache;
86 * Login controller (bean)
89 private AddressbookUserLoginWebSessionController userLoginController;
94 public AddressbookEmailChangeWebRequestBean () {
95 // Call super constructor
100 * Changes logged-in user's email address if the current password matches.
102 * @return Redirect outcome
104 public String doUserChangeEmailAddress () {
105 // This method shall only be called if the user is logged-in
106 if (!this.userLoginController.isUserLoggedIn()) {
108 throw new IllegalStateException("User is not logged-in"); //NOI18N
109 } else if (!this.featureController.isFeatureEnabled("user_change_email_address")) { //NOI18N
110 // Editing is not allowed
111 throw new IllegalStateException("User tried to change email address"); //NOI18N
112 } else if (!this.isRequiredChangeEmailAddressSet()) {
113 // Not all required fields are set
114 throw new FaceletException("Not all required fields are set."); //NOI18N
115 } else if (!Objects.equals(this.getEmailAddress(), this.getEmailAddressRepeat())) {
116 // Email address 1+2 mismatch
117 this.showFacesMessage("form_user_change_email_address:emailAddressRepeat", "ERROR_USER_EMAIL_ADDRESSES_MISMATCH"); //NOI18N
119 } else if (!this.userLoginController.ifCurrentPasswordMatches()) {
120 // Password not matching
121 this.showFacesMessage("form_login_user_change_email_address:currentPassword", new UserPasswordMismatchException(this.userLoginController.getLoggedInUser())); //NOI18N
126 final User user = this.userLoginController.getLoggedInUser();
128 // It should be there, so run some tests on it
129 assert (user instanceof User) : "Instance userLoginController.loggedInUser is null"; //NOI18N
130 assert (user.getUserId() instanceof Long) : "Instance userLoginController.loggedInUser.userId is null"; //NOI18N
131 assert (user.getUserId() > 0) : MessageFormat.format("userLoginController.loggedInUser.userId={0} is invalid", user.getUserId()); //NOI18N
132 assert (user.getUserContact() instanceof Contact) : "Instance userLoginController.loggedInUser.userContact is null"; //NOI18N
133 assert (user.getUserContact().getContactId() instanceof Long) : "Instance userLoginController.userContact.contactId is null"; //NOI18N
134 assert (user.getUserContact().getContactId() > 0) : MessageFormat.format("Instance userLoginController.userContact.contactId={0} is invalid", user.getUserContact().getContactId()); //NOI18N
136 // Check if the email address is already enqueued
137 if (this.isEmailAddressQueued(this.getEmailAddress())) {
138 // Clear both email addresses
139 this.setEmailAddress(null);
140 this.setEmailAddressRepeat(null);
142 // Yes, then abort here
143 this.showFacesMessage("form_user_change_email_address:emailAddress", "ERROR_USER_CHANGE_EMAIL_ADDRESS_ALREADY_QUEUED"); //NOI18N
147 // Create change object, to save EJB calls, the hash is not generated here
148 final ChangeableEmailAddress emailChange = new EmailAddressChange(user, this.getEmailAddress());
151 final String baseUrl = FacesUtils.generateBaseUrl();
154 this.emailChangeBean.enqueueEmailAddressForChange(emailChange, baseUrl);
156 // Unset all so the user is forced to re-enter it
160 return "user_login_email_change_queued"; //NOI18N
164 * Getter for email address 1 (changing)
166 * @return Email address
168 public String getEmailAddress () {
169 return this.emailAddress;
173 * Setter for email address 1 (changing)
175 * @param emailAddress Email address 1
177 public void setEmailAddress (final String emailAddress) {
178 this.emailAddress = emailAddress;
182 * Getter for email address 2 (repeat changing)
184 * @return Email address 2
186 public String getEmailAddressRepeat () {
187 return this.emailAddressRepeat;
191 * Setter for email address 2 (repeat changing)
193 * @param emailAddressRepeat Email address 2
195 public void setEmailAddressRepeat (final String emailAddressRepeat) {
196 this.emailAddressRepeat = emailAddressRepeat;
203 public void init () {
205 if (!this.queuedEmailCache.iterator().hasNext()) {
207 final List<String> list = this.emailChangeBean.allQueuedAddresses();
210 for (final Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
212 final String next = iterator.next();
215 this.queuedEmailCache.put(next, Boolean.TRUE);
221 public boolean isRequiredChangeEmailAddressSet () {
222 return ((this.getEmailAddress() != null) &&
223 (this.getEmailAddressRepeat() != null));
227 * Clears email address fields so the user has to re-enter them
229 private void clear () {
231 this.setEmailAddress(null);
232 this.setEmailAddressRepeat(null);
236 * Checks if given email address has already been queued. First a local list
237 * is being checked, if not found, the EJB is called. Only if found, the
238 * result is "cached" in the list.
240 * @param emailAddress Email address to verify
242 * @return Whether the email address in field emailAddress is already queued
244 private boolean isEmailAddressQueued (final String emailAddress) {
245 // It should be there
246 assert (emailAddress != null) : "emailAddress should not be null"; //NOI18N
247 assert (!emailAddress.trim().isEmpty()) : "emailAddress should not be empty"; //NOI18N
250 if (this.queuedEmailCache.containsKey(emailAddress)) {
256 final boolean isQueued = this.emailChangeBean.isEmailAddressEnqueued(emailAddress);
261 this.queuedEmailCache.put(emailAddress, Boolean.TRUE);