2 * Copyright (C) 2016 - 2024 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.jjobs.beans.user.password;
19 import java.util.Objects;
21 import javax.enterprise.context.RequestScoped;
22 import javax.enterprise.event.Event;
23 import javax.enterprise.inject.Any;
24 import javax.faces.FacesException;
25 import javax.faces.application.FacesMessage;
26 import javax.inject.Inject;
27 import javax.inject.Named;
28 import org.mxchange.jcoreee.utils.FacesUtils;
29 import org.mxchange.jjobs.beans.BaseJobsBean;
30 import org.mxchange.jjobs.beans.features.JobsFeaturesWebApplicationController;
31 import org.mxchange.jjobs.beans.user.login.JobsUserLoginWebSessionController;
32 import org.mxchange.jusercore.exceptions.UserNotFoundException;
33 import org.mxchange.jusercore.exceptions.UserStatusLockedException;
34 import org.mxchange.jusercore.exceptions.UserStatusUnconfirmedException;
35 import org.mxchange.jusercore.model.user.User;
36 import org.mxchange.jusercore.model.user.UserSessionBeanRemote;
37 import org.mxchange.jusercore.model.user.password_history.PasswordHistory;
38 import org.mxchange.juserlogincore.events.user.password_change.ObservableUpdatedUserPasswordEvent;
39 import org.mxchange.juserlogincore.events.user.password_change.UpdatedUserPasswordEvent;
40 import org.mxchange.juserlogincore.exceptions.UserPasswordMismatchException;
41 import org.mxchange.juserlogincore.utils.UserLoginUtils;
44 * A user password (change) controller (bean)
46 * @author Roland Häder<roland@mxchange.org>
48 @Named ("userPasswordController")
50 public class JobsUserPasswordWebRequestBean extends BaseJobsBean implements JobsUserPasswordWebRequestController {
55 private static final long serialVersionUID = 15_267_867_367_501L;
61 private JobsFeaturesWebApplicationController featureController;
66 @EJB (lookup = "java:global/jjobs-ejb/user!org.mxchange.jusercore.model.user.UserSessionBeanRemote")
67 private UserSessionBeanRemote userBean;
70 * Current password (for confirmation of password change)
72 private String userCurrentPassword;
75 * Login bean (controller)
78 private JobsUserLoginWebSessionController userLoginController;
81 * User password (clear-text from web form)
83 private String userPassword;
86 * User password repeated (clear-text from web form)
88 private String userPasswordRepeat;
91 * Event being fired when user's password has been updated
95 private Event<ObservableUpdatedUserPasswordEvent> userUpdatedPasswordEvent;
100 public JobsUserPasswordWebRequestBean () {
101 // Call super constructor
106 * Changes logged-in user's password. It must not match with current
107 * password and should not appear in password history list for X
108 * (configurable) entries.
110 * @return Redirect outcome
112 public String doChangePassword () {
113 // This method shall only be called if the user is logged-in
114 if (!this.userLoginController.isUserLoggedIn()) {
116 throw new IllegalStateException("User is not logged-in"); //NOI18N
117 } else if (!this.isRequiredChangePasswordSet()) {
118 // Not all required fields are set
119 throw new FacesException("Not all required fields are set."); //NOI18N
120 } else if (!this.userLoginController.ifCurrentPasswordMatches()) {
121 // Password not matching
122 throw new FacesException(new UserPasswordMismatchException(this.userLoginController.getLoggedInUser()));
123 } else if (!this.featureController.isFeatureEnabled("change_user_password")) { //NOI18N
124 // Editing is not allowed
125 throw new IllegalStateException("User tried to change password."); //NOI18N
126 } else if (!UserLoginUtils.ifPasswordMatches(this.getUserCurrentPassword(), this.userLoginController.getLoggedInUser())) {
127 // Password mismatches
128 this.showFacesMessage("form_user_change_password:userCurrentPassword", "Entered current password does not matched stored password.", FacesMessage.SEVERITY_WARN); //NOI18N
135 } else if (!Objects.equals(this.getUserPassword(), this.getUserPasswordRepeat())) {
136 // Both entered passwords don't match
137 this.showFacesMessage("form_user_change_password:userPasswordRepeat", "Entered new passwords mismatch.", FacesMessage.SEVERITY_ERROR); //NOI18N
144 } else if (Objects.equals(this.getUserCurrentPassword(), this.getUserPassword())) {
145 // New password matches current
146 this.showFacesMessage("form_user_change_password:userPassword", "Entered new password is same as current password.", FacesMessage.SEVERITY_WARN); //NOI18N
153 } else if (this.userLoginController.isPasswordInHistory(this.getUserPassword())) {
154 // Is already in list (to old passwords are ignored)
155 this.showFacesMessage("form_user_change_password:userPassword", "Entered new password is has already been used some time ago.", FacesMessage.SEVERITY_WARN); //NOI18N
165 final User user = this.userLoginController.getLoggedInUser();
168 final String encryptedPassword = UserLoginUtils.encryptPassword(this.getUserPassword());
171 user.setUserEncryptedPassword(encryptedPassword);
174 final PasswordHistory passwordHistory;
178 final String baseUrl = FacesUtils.generateBaseUrl();
180 // All is set, then update password
181 passwordHistory = this.userBean.updateUserPassword(user, baseUrl);
182 } catch (final UserNotFoundException | UserStatusUnconfirmedException | UserStatusLockedException ex) {
187 throw new FacesException(ex);
191 this.userUpdatedPasswordEvent.fire(new UpdatedUserPasswordEvent(passwordHistory, this.getUserPassword()));
197 return "login_data_saved"; //NOI18N
201 * Getter for current clear-text user password
203 * @return Current clear-text user password
205 public String getUserCurrentPassword () {
206 return this.userCurrentPassword;
210 * Setter for current clear-text user password
212 * @param userCurrentPassword Current clear-text user password
214 public void setUserCurrentPassword (final String userCurrentPassword) {
215 this.userCurrentPassword = userCurrentPassword;
219 * Getter for clear-text user password
221 * @return Clear-text user password
223 public String getUserPassword () {
224 return this.userPassword;
228 * Setter for clear-text user password
230 * @param userPassword Clear-text user password
232 public void setUserPassword (final String userPassword) {
233 this.userPassword = userPassword;
237 * Getter for clear-text user password repeated
239 * @return Clear-text user password repeated
241 public String getUserPasswordRepeat () {
242 return this.userPasswordRepeat;
246 * Setter for clear-text user password repeated
248 * @param userPasswordRepeat Clear-text user password repeated
250 public void setUserPasswordRepeat (final String userPasswordRepeat) {
251 this.userPasswordRepeat = userPasswordRepeat;
255 public boolean isRequiredChangePasswordSet () {
257 return ((this.getUserCurrentPassword() != null) &&
258 (!this.getUserCurrentPassword().isEmpty()) &&
259 (this.getUserPassword() != null) &&
260 (!this.getUserPassword().isEmpty()) &&
261 (this.getUserPasswordRepeat() != null) &&
262 (!this.getUserPasswordRepeat().isEmpty()));
268 private void clear () {
270 this.setUserPassword(null);
271 this.setUserPasswordRepeat(null);