]> git.mxchange.org Git - jfinancials-war.git/blob - src/java/org/mxchange/jfinancials/beans/user/FinancialsAdminUserWebRequestBean.java
Updated copyright year
[jfinancials-war.git] / src / java / org / mxchange / jfinancials / beans / user / FinancialsAdminUserWebRequestBean.java
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.jfinancials.beans.user;
18
19 import java.text.MessageFormat;
20 import java.util.Locale;
21 import java.util.Objects;
22 import javax.ejb.EJB;
23 import javax.enterprise.context.RequestScoped;
24 import javax.enterprise.event.Event;
25 import javax.enterprise.event.Observes;
26 import javax.enterprise.inject.Any;
27 import javax.faces.FacesException;
28 import javax.faces.application.FacesMessage;
29 import javax.faces.context.FacesContext;
30 import javax.inject.Inject;
31 import javax.inject.Named;
32 import org.mxchange.jcontacts.model.contact.Contact;
33 import org.mxchange.jcoreee.utils.FacesUtils;
34 import org.mxchange.jfinancials.beans.BaseFinancialsBean;
35 import org.mxchange.jfinancials.beans.contact.FinancialsAdminContactWebRequestController;
36 import org.mxchange.jfinancials.beans.contact.FinancialsContactWebRequestController;
37 import org.mxchange.jfinancials.beans.features.FinancialsFeaturesWebApplicationController;
38 import org.mxchange.jfinancials.beans.user.list.FinancialsUserListWebViewController;
39 import org.mxchange.jusercore.events.user.add.AdminAddedUserEvent;
40 import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
41 import org.mxchange.jusercore.events.user.created.ObservableCreatedUserEvent;
42 import org.mxchange.jusercore.events.user.delete.AdminDeletedUserEvent;
43 import org.mxchange.jusercore.events.user.delete.ObservableAdminDeletedUserEvent;
44 import org.mxchange.jusercore.events.user.linked.AdminLinkedUserEvent;
45 import org.mxchange.jusercore.events.user.linked.ObservableAdminLinkedUserEvent;
46 import org.mxchange.jusercore.events.user.locked.AdminLockedUserEvent;
47 import org.mxchange.jusercore.events.user.locked.ObservableAdminLockedUserEvent;
48 import org.mxchange.jusercore.events.user.unlocked.AdminUnlockedUserEvent;
49 import org.mxchange.jusercore.events.user.unlocked.ObservableAdminUnlockedUserEvent;
50 import org.mxchange.jusercore.events.user.update.post.AdminPostUserDataUpdatedEvent;
51 import org.mxchange.jusercore.events.user.update.post.ObservableAdminPostUserDataUpdatedEvent;
52 import org.mxchange.jusercore.exceptions.EmailAddressAlreadyRegisteredException;
53 import org.mxchange.jusercore.exceptions.UserNameAlreadyRegisteredException;
54 import org.mxchange.jusercore.exceptions.UserNotFoundException;
55 import org.mxchange.jusercore.exceptions.UserStatusConfirmedException;
56 import org.mxchange.jusercore.exceptions.UserStatusLockedException;
57 import org.mxchange.jusercore.exceptions.UserStatusUnconfirmedException;
58 import org.mxchange.jusercore.model.user.AdminUserSessionBeanRemote;
59 import org.mxchange.jusercore.model.user.LoginUser;
60 import org.mxchange.jusercore.model.user.User;
61 import org.mxchange.jusercore.model.user.UserSessionBeanRemote;
62 import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
63 import org.mxchange.jusercore.model.user.status.UserAccountStatus;
64 import org.mxchange.juserlogincore.container.login.UserLoginContainer;
65 import org.mxchange.juserlogincore.events.registration.ObservableUserRegisteredEvent;
66 import org.mxchange.juserlogincore.exceptions.UserPasswordRepeatMismatchException;
67 import org.mxchange.juserlogincore.login.UserLoginUtils;
68
69 /**
70  * A user bean (controller)
71  * <p>
72  * @author Roland Häder<roland@mxchange.org>
73  */
74 @Named ("adminUserController")
75 @RequestScoped
76 public class FinancialsAdminUserWebRequestBean extends BaseFinancialsBean implements FinancialsAdminUserWebRequestController {
77
78         /**
79          * Serial number
80          */
81         private static final long serialVersionUID = 542_145_347_916L;
82
83         /**
84          * An event fired when the administrator has added a new user
85          */
86         @Inject
87         @Any
88         private Event<ObservableAdminAddedUserEvent> addedUserEvent;
89
90         /**
91          * Regular contact controller
92          */
93         @Inject
94         private FinancialsAdminContactWebRequestController adminContactController;
95
96         /**
97          * Administrative user EJB
98          */
99         @EJB (lookup = "java:global/jfinancials-ejb/adminUser!org.mxchange.jusercore.model.user.AdminUserSessionBeanRemote")
100         private AdminUserSessionBeanRemote adminUserBean;
101
102         /**
103          * Contact instance
104          */
105         private Contact contact;
106
107         /**
108          * Regular contact controller
109          */
110         @Inject
111         private FinancialsContactWebRequestController contactController;
112
113         /**
114          * Event being fired when administrator has deleted user
115          */
116         @Inject
117         @Any
118         private Event<ObservableAdminDeletedUserEvent> deleteUserEvent;
119
120         /**
121          * Features controller
122          */
123         @Inject
124         private FinancialsFeaturesWebApplicationController featureController;
125
126         /**
127          * An event fired when the administrator has updated a new user
128          */
129         @Inject
130         @Any
131         private Event<ObservableAdminPostUserDataUpdatedEvent> updatedUserDataEvent;
132
133         /**
134          * User instance
135          */
136         private User user;
137
138         /**
139          * General user EJB
140          */
141         @EJB (lookup = "java:global/jfinancials-ejb/user!org.mxchange.jusercore.model.user.UserSessionBeanRemote")
142         private UserSessionBeanRemote userBean;
143
144         /**
145          * Delete reason
146          */
147         private String userDeleteReason;
148
149         /**
150          * An event fired when the administrator has linked a user with existing
151          * contact data.
152          */
153         @Inject
154         @Any
155         private Event<ObservableAdminLinkedUserEvent> userLinkedEvent;
156
157         /**
158          * Regular user controller
159          */
160         @Inject
161         private FinancialsUserListWebViewController userListController;
162
163         /**
164          * User lock reason
165          */
166         private String userLockReason;
167
168         /**
169          * Event being fired when an administrator has locked a user
170          */
171         @Inject
172         @Any
173         private Event<ObservableAdminLockedUserEvent> userLockedEvent;
174
175         /**
176          * Flag whether user must change password after login
177          */
178         private Boolean userMustChangePassword;
179
180         /**
181          * User name
182          */
183         private String userName;
184
185         /**
186          * User password (clear-text from web form)
187          */
188         private String userPassword;
189
190         /**
191          * User password repeated (clear-text from web form)
192          */
193         private String userPasswordRepeat;
194
195         /**
196          * Whether the user wants a public profile
197          */
198         private ProfileMode userProfileMode;
199
200         /**
201          * Event being fired when administrator unlocks an account
202          */
203         @Inject
204         @Any
205         private Event<ObservableAdminUnlockedUserEvent> userUnlockedEvent;
206
207         /**
208          * Default constructor
209          */
210         public FinancialsAdminUserWebRequestBean () {
211                 // Call super constructor
212                 super();
213         }
214
215         /**
216          * Adds user instance to database by preparing a complete user instance and
217          * sending it to the EJB. The data set in the controller is being verified,
218          * e.g. if the user name or email address is not used yet.
219          * <p>
220          */
221         public void addUser () {
222                 // As the form cannot validate the data (required="true"), check it here
223                 if (this.getUserName() == null) {
224                         // Throw NPE
225                         throw new NullPointerException("userName is null"); //NOI18N
226                 } else if (this.getUserName().isEmpty()) {
227                         // Is empty
228                         throw new IllegalArgumentException("userName is null"); //NOI18N
229                 } else if (this.getContact() == null) {
230                         // No contact instance set, so test required fields: gender, first name and family name
231                         this.adminContactController.validateContactData();
232                 }
233
234                 // Create new user instance
235                 final User newUser = this.createUserInstance();
236
237                 // Is the user name or email address used already?
238                 // @TODO Add password length check
239                 if ((this.featureController.isFeatureEnabled("user_login_require_user_name")) && (this.userListController.isUserNameRegistered(newUser))) {
240                         // User name is already used
241                         throw new FacesException(new UserNameAlreadyRegisteredException(newUser));
242                 } else if ((this.getContact() == null) && (this.contactController.isEmailAddressRegistered(newUser.getUserContact()))) {
243                         // Email address is already used
244                         this.showFacesMessage("admin_add_user:emailAddress", "ERROR_EMAIL_ADDRESS_ALREADY_USED", FacesMessage.SEVERITY_WARN); //NOI18N
245
246                         // Always clear password
247                         this.setUserPassword(null);
248                         this.setUserPasswordRepeat(null);
249
250                         // Skip it
251                         return;
252                 }
253
254                 // Init variable
255                 final User updatedUser;
256
257                 try {
258                         // Now, that all is set, call EJB
259                         if (this.getContact() instanceof Contact) {
260                                 // Link contact with this user
261                                 updatedUser = this.adminUserBean.linkUser(newUser);
262                         } else {
263                                 // Add new user
264                                 updatedUser = this.adminUserBean.addUser(newUser);
265                         }
266                 } catch (final UserNameAlreadyRegisteredException | EmailAddressAlreadyRegisteredException ex) {
267                         // Throw again
268                         throw new FacesException(ex);
269                 }
270
271                 // Now, that all is set, call EJB
272                 if (this.getContact() instanceof Contact) {
273                         // Fire event
274                         this.userLinkedEvent.fire(new AdminLinkedUserEvent(updatedUser));
275                 } else {
276                         // Fire event
277                         this.addedUserEvent.fire(new AdminAddedUserEvent(updatedUser));
278                 }
279                 // Clear helper
280                 this.setContact(null);
281
282                 // Clear this bean
283                 this.clear();
284         }
285
286         /**
287          * Event observer for when a bean helper has successfully created a user
288          * instance, means the user exists. If the user does not exist, this event
289          * should not fire but instead a proper exception must be thrown.
290          * <p>
291          * @param event User created event
292          */
293         public void afterCreatedUserEvent (@Observes final ObservableCreatedUserEvent event) {
294                 // Is the instance valid?
295                 if (null == event) {
296                         // Throw NPE
297                         throw new NullPointerException("event is null"); //NOI18N
298                 } else if (event.getCreatedUser() == null) {
299                         // Throw NPE again
300                         throw new NullPointerException("event.createdUser is null"); //NOI18N
301                 } else if (event.getCreatedUser().getUserId() == null) {
302                         // Throw NPE again
303                         throw new NullPointerException("event.createdUser.userId is null"); //NOI18N
304                 } else if (event.getCreatedUser().getUserId() < 1) {
305                         // Throw NPE again
306                         throw new NullPointerException(MessageFormat.format("event.createdUser.userId={0} is not valid", event.getCreatedUser().getUserId())); //NOI18N
307                 }
308
309                 // Set whole user
310                 this.setUser(event.getCreatedUser());
311         }
312
313         /**
314          * Event observer for new user registrations
315          * <p>
316          * @param event User registration event
317          */
318         public void afterUserRegistrationEvent (@Observes final ObservableUserRegisteredEvent event) {
319                 // Event and contained entity instance should not be null
320                 if (null == event) {
321                         // Throw NPE
322                         throw new NullPointerException("event is null"); //NOI18N
323                 } else if (event.getRegisteredUser() == null) {
324                         // Throw NPE again
325                         throw new NullPointerException("event.user is null"); //NOI18N
326                 } else if (event.getRegisteredUser().getUserId() == null) {
327                         // userId is null
328                         throw new NullPointerException("event.user.userId is null"); //NOI18N
329                 } else if (event.getRegisteredUser().getUserId() < 1) {
330                         // Not avalid id
331                         throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getRegisteredUser(), event.getRegisteredUser().getUserId())); //NOI18N
332                 }
333
334                 // Get user instance
335                 final User registeredUser = event.getRegisteredUser();
336
337                 // @TODO Nothing to do with the user here?
338                 // Clear all data
339                 this.clear();
340         }
341
342         /**
343          * Deletes given user account
344          */
345         public void deleteUserData () {
346                 // Is the user instance valid and CONFIRMED?
347                 if (this.getUser() == null) {
348                         // Throw NPE
349                         throw new NullPointerException("user is null"); //NOI18N
350                 } else if (this.getUser().getUserId() == null) {
351                         // Throw again
352                         throw new NullPointerException("user.userId is null"); //NOI18N
353                 } else if (this.getUser().getUserId() < 1) {
354                         // Invalid id number
355                         throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is not valid", this.getUser().getUserId())); //NOI18N
356                 }
357
358                 try {
359                         // All fine, delete it
360                         this.adminUserBean.deleteUser(this.getUser(), this.getUserDeleteReason());
361                 } catch (final UserNotFoundException ex) {
362                         // Should not happen, so throw again
363                         throw new FacesException(ex);
364                 }
365
366                 // Fire event
367                 this.deleteUserEvent.fire(new AdminDeletedUserEvent(this.getUser(), this.getUserDeleteReason()));
368         }
369
370         /**
371          * Edits currently loaded user's data in database.
372          */
373         public void editUserData () {
374                 // Null password means not setting it
375                 String encryptedPassword = null;
376
377                 // Check if user instance is in helper and valid
378                 if (this.getUser() == null) {
379                         // Throw NPE
380                         throw new NullPointerException("beanHelper.user is null"); //NOI18N
381                 } else if (this.getUser().getUserId() == null) {
382                         // Throw NPE again
383                         throw new NullPointerException("beanHelper.user.userId is null"); //NOI18N
384                 } else if (this.getUser().getUserId() < 1) {
385                         // Invalid id
386                         throw new IllegalStateException(MessageFormat.format("beanHelper.user.userId={0} is invalid", this.getUser().getUserId())); //NOI18N
387                 } else if (this.getUserName() == null) {
388                         // Not all required fields are set
389                         throw new NullPointerException("this.userName is null"); //NOI18N
390                 } else if (this.getUserName().isEmpty()) {
391                         // Not all required fields are set
392                         throw new IllegalArgumentException("this.userName is empty"); //NOI18N
393                 } else if (((!this.getUserPassword().isEmpty()) || (!this.getUserPasswordRepeat().isEmpty())) && (!this.isSamePasswordEntered())) {
394                         // Clear password fields
395                         this.setUserPassword(null);
396                         this.setUserPasswordRepeat(null);
397
398                         // Not same password entered
399                         this.showFacesMessage("form_edit_user:userPassword", "ADMIN_USER_PASSWORD_REPEAT_DIFFERENT", FacesMessage.SEVERITY_INFO); //NOI18N
400                         return;
401                 } else if ((!Objects.equals(this.getUser().getUserName(), this.getUserName())) && (this.userBean.ifUserNameExists(this.getUserName()))) {
402                         // Clear all fields
403                         this.clear();
404
405                         // User name already exists
406                         this.showFacesMessage("form_edit_user:userName", "ADMIN_USER_NAME_ALREADY_EXISTS", FacesMessage.SEVERITY_WARN); //NOI18N
407                         return;
408                 } else if (this.isSamePasswordEntered()) {
409                         // Same password entered, create container
410                         if ((Objects.equals(this.getUser().getUserMustChangePassword(), this.getUserMustChangePassword())) && (UserLoginUtils.ifPasswordMatches(new UserLoginContainer(this.getUser(), this.getUserPassword())))) {
411                                 // Clear password fields
412                                 this.setUserPassword(null);
413                                 this.setUserPasswordRepeat(null);
414
415                                 // Same password entered
416                                 this.showFacesMessage("form_edit_user:userPassword", "ADMIN_USER_ENTERED_SAME_AS_OLD_PASSWORD", FacesMessage.SEVERITY_WARN); //NOI18N
417                                 return;
418                         }
419
420                         // Encrypt password
421                         encryptedPassword = UserLoginUtils.encryptPassword(this.getUserPassword());
422                 }
423
424                 // Set user name and flag
425                 this.getUser().setUserName(this.getUserName());
426                 this.getUser().setUserMustChangePassword(this.getUserMustChangePassword());
427
428                 // Is a password set?
429                 if (encryptedPassword != null) {
430                         // Set it as well
431                         this.getUser().setUserEncryptedPassword(encryptedPassword);
432                 }
433
434                 // Init updated User instance
435                 final User updatedUser;
436
437                 try {
438                         // Call EJB for updating user data
439                         updatedUser = this.userBean.updateUserData(this.getUser());
440                 } catch (final UserNotFoundException ex) {
441                         // Throw as cause
442                         throw new FacesException(ex);
443                 }
444
445                 // Fire event
446                 this.updatedUserDataEvent.fire(new AdminPostUserDataUpdatedEvent(updatedUser));
447         }
448
449         /**
450          * Getter for contact instance
451          * <p>
452          * @return Contact instance
453          */
454         public Contact getContact () {
455                 return this.contact;
456         }
457
458         /**
459          * Setter for contact instance
460          * <p>
461          * @param contact Contact instance
462          */
463         public void setContact (final Contact contact) {
464                 this.contact = contact;
465         }
466
467         /**
468          * Getter for user instance
469          * <p>
470          * @return User instance
471          */
472         public User getUser () {
473                 return this.user;
474         }
475
476         /**
477          * Setter for user instance
478          * <p>
479          * @param user User instance
480          */
481         public void setUser (final User user) {
482                 this.user = user;
483         }
484
485         /**
486          * Getter for user delete reason
487          * <p>
488          * @return User delete reason
489          */
490         public String getUserDeleteReason () {
491                 return this.userDeleteReason;
492         }
493
494         /**
495          * Setter for user delete reason
496          * <p>
497          * @param userDeleteReason User delete reason
498          */
499         public void setUserDeleteReason (final String userDeleteReason) {
500                 this.userDeleteReason = userDeleteReason;
501         }
502
503         /**
504          * Getter for user lock reason
505          * <p>
506          * @return User lock reason
507          */
508         public String getUserLockReason () {
509                 return this.userLockReason;
510         }
511
512         /**
513          * Setter for user lock reason
514          * <p>
515          * @param userLockReason User lock reason
516          */
517         public void setUserLockReason (final String userLockReason) {
518                 this.userLockReason = userLockReason;
519         }
520
521         /**
522          * Getter for flag if user needs to change password
523          * <p>
524          * @return Flag if user needs to change password
525          */
526         public Boolean getUserMustChangePassword () {
527                 return this.userMustChangePassword;
528         }
529
530         /**
531          * Setter for flag if user needs to change password
532          * <p>
533          * @param userMustChangePassword Flag if user needs to change password
534          */
535         public void setUserMustChangePassword (final Boolean userMustChangePassword) {
536                 this.userMustChangePassword = userMustChangePassword;
537         }
538
539         /**
540          * Getter for user name
541          * <p>
542          * @return User name
543          */
544         public String getUserName () {
545                 return this.userName;
546         }
547
548         /**
549          * Setter for user name
550          * <p>
551          * @param userName User name
552          */
553         public void setUserName (final String userName) {
554                 this.userName = userName;
555         }
556
557         /**
558          * Getter for clear-text user password
559          * <p>
560          * @return Clear-text user password
561          */
562         public String getUserPassword () {
563                 return this.userPassword;
564         }
565
566         /**
567          * Setter for clear-text user password
568          * <p>
569          * @param userPassword Clear-text user password
570          */
571         public void setUserPassword (final String userPassword) {
572                 this.userPassword = userPassword;
573         }
574
575         /**
576          * Getter for clear-text user password repeated
577          * <p>
578          * @return Clear-text user password repeated
579          */
580         public String getUserPasswordRepeat () {
581                 return this.userPasswordRepeat;
582         }
583
584         /**
585          * Setter for clear-text user password repeated
586          * <p>
587          * @param userPasswordRepeat Clear-text user password repeated
588          */
589         public void setUserPasswordRepeat (final String userPasswordRepeat) {
590                 this.userPasswordRepeat = userPasswordRepeat;
591         }
592
593         /**
594          * Getter for user profile mode
595          * <p>
596          * @return User profile mode
597          */
598         public ProfileMode getUserProfileMode () {
599                 return this.userProfileMode;
600         }
601
602         /**
603          * Setter for user profile mode
604          * <p>
605          * @param userProfileMode User profile mode
606          */
607         public void setUserProfileMode (final ProfileMode userProfileMode) {
608                 this.userProfileMode = userProfileMode;
609         }
610
611         /**
612          * Locks selected user's account. This method makes sure that a lock reason
613          * is provided that th user later can read on login attempts.
614          * <p>
615          * @return Redirect outcome
616          */
617         public String lockUserAccount () {
618                 // Is the user instance valid and CONFIRMED?
619                 if (this.getUser() == null) {
620                         // Throw NPE
621                         throw new NullPointerException("this.user is null"); //NOI18N
622                 } else if (this.getUser().getUserId() == null) {
623                         // Throw again
624                         throw new NullPointerException("this.user.userId is null"); //NOI18N
625                 } else if (this.getUser().getUserId() < 1) {
626                         // Invalid id number
627                         throw new IllegalArgumentException(MessageFormat.format("this.user.userId={0} is not valid", this.getUser().getUserId())); //NOI18N
628                 } else if (this.getUser().getUserAccountStatus() == UserAccountStatus.LOCKED) {
629                         // User account is locked
630                         throw new FacesException(new UserStatusLockedException(this.getUser()));
631                 } else if (this.getUser().getUserAccountStatus() == UserAccountStatus.UNCONFIRMED) {
632                         // User account is locked
633                         throw new FacesException(new UserStatusUnconfirmedException(this.getUser()));
634                 } else if (this.getUserLockReason() == null) {
635                         // Throw NPE again
636                         throw new NullPointerException("this.userLockReason is null"); //NOI18N
637                 } else if (this.getUserLockReason().isEmpty()) {
638                         // Empty lock reason
639                         throw new IllegalArgumentException("this.userLockReason is empty"); //NOI18N
640                 }
641
642                 // Init updated user instance
643                 final User updatedUser;
644
645                 try {
646                         // Get base URL
647                         final String baseUrl = FacesUtils.generateBaseUrl();
648
649                         // Call EJB to lock account
650                         updatedUser = this.adminUserBean.lockUserAccount(this.getUser(), this.getUserLockReason(), baseUrl);
651                 } catch (final UserStatusLockedException | UserStatusUnconfirmedException | UserNotFoundException ex) {
652                         // Throw again
653                         throw new FacesException(ex);
654                 }
655
656                 // Fire event
657                 this.userLockedEvent.fire(new AdminLockedUserEvent(updatedUser));
658
659                 // Clear bean
660                 this.clear();
661
662                 // Should go fine at this point, redirect to user profile
663                 return "admin_show_user"; //NOI18N
664         }
665
666         /**
667          * Unlocks selected user's account. This method makes sure that the account
668          * is locked.
669          * <p>
670          * @return Redirect outcome
671          */
672         public String unlockUserAccount () {
673                 // Is the user instance valid and CONFIRMED?
674                 if (this.getUser() == null) {
675                         // Throw NPE
676                         throw new NullPointerException("this.user is null"); //NOI18N
677                 } else if (this.getUser().getUserId() == null) {
678                         // Throw again
679                         throw new NullPointerException("this.user.userId is null"); //NOI18N
680                 } else if (this.getUser().getUserId() < 1) {
681                         // Invalid id number
682                         throw new IllegalArgumentException(MessageFormat.format("this.user.userId={0} is not valid", this.getUser().getUserId())); //NOI18N
683                 } else if (this.getUser().getUserAccountStatus() == UserAccountStatus.CONFIRMED) {
684                         // User account is locked
685                         throw new FacesException(new UserStatusConfirmedException(this.getUser()));
686                 } else if (this.getUser().getUserAccountStatus() == UserAccountStatus.UNCONFIRMED) {
687                         // User account is locked
688                         throw new FacesException(new UserStatusUnconfirmedException(this.getUser()));
689                 }
690
691                 // Init updated user instance
692                 final User updatedUser;
693
694                 try {
695                         // Get base URL
696                         final String baseUrl = FacesUtils.generateBaseUrl();
697
698                         // Call EJB to unlock account
699                         updatedUser = this.adminUserBean.unlockUserAccount(this.getUser(), baseUrl);
700                 } catch (final UserStatusConfirmedException | UserStatusUnconfirmedException | UserNotFoundException ex) {
701                         // Throw again
702                         throw new FacesException(ex);
703                 }
704
705                 // Fire event
706                 this.userUnlockedEvent.fire(new AdminUnlockedUserEvent(updatedUser));
707
708                 // Clear bean
709                 this.clear();
710
711                 // Should go fine at this point, redirect to user profile
712                 return "admin_show_user"; //NOI18N
713         }
714
715         /**
716          * Clears this bean
717          */
718         private void clear () {
719                 // Clear all data
720                 this.setContact(null);
721                 this.setUserDeleteReason(null);
722                 this.setUser(null);
723                 this.setUserLockReason(null);
724                 this.setUserMustChangePassword(null);
725                 this.setUserName(null);
726                 this.setUserPassword(null);
727                 this.setUserPasswordRepeat(null);
728                 this.setUserProfileMode(null);
729
730         }
731
732         /**
733          * Creates a new user instance from all currently saved data from this bean
734          * <p>
735          * @return New user instance
736          */
737         private User createUserInstance () {
738                 // Init variable for password
739                 String password = null;
740
741                 // Init instance
742                 final Contact userContact;
743
744                 // Is a contact instance in helper set?
745                 if ((this.getUserPassword() == null && (this.getUserPasswordRepeat() == null)) || ((this.getUserPassword().isEmpty()) && (this.getUserPasswordRepeat().isEmpty()))) {
746                         // Empty password entered, then generate one
747                         password = UserLoginUtils.createRandomPassword(FinancialsUserWebRequestController.MINIMUM_PASSWORD_LENGTH);
748                 } else if (!this.isSamePasswordEntered()) {
749                         // Both passwords don't match
750                         throw new FacesException(new UserPasswordRepeatMismatchException());
751                 } else {
752                         // Both match, so get it from this bean
753                         password = this.getUserPassword();
754                 }
755
756                 // The password should not be null and at least 5 characters long
757                 assert (password != null) : "password is null"; //NOI18N
758                 assert (password.length() >= FinancialsUserWebRequestController.MINIMUM_PASSWORD_LENGTH) : "Password is not long enough."; //NOI18N
759
760                 // Is contact instance given? Else create one
761                 if (this.getContact() instanceof Contact) {
762                         // Then use it for contact linking
763                         userContact = this.getContact();
764                 } else {
765                         // Create contact instance
766                         userContact = this.contactController.createContactInstance();
767                 }
768
769                 // Create new instance
770                 final User newUser = new LoginUser(
771                                    this.getUserName(),
772                                    this.getUserProfileMode(),
773                                    this.getUserMustChangePassword(),
774                                    UserLoginUtils.encryptPassword(password),
775                                    UserAccountStatus.CONFIRMED,
776                                    userContact
777                    );
778
779                 // Get locale from view-root
780                 final Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
781
782                 // Copy user locale
783                 newUser.setUserLocale(locale);
784
785                 // Return it
786                 return newUser;
787         }
788
789         /**
790          * Checks if same password is entered and that they are not empty.
791          * <p>
792          * @return Whether the same password was entered
793          */
794         private boolean isSamePasswordEntered () {
795                 return ((!this.getUserPassword().isEmpty()) && (Objects.equals(this.getUserPassword(), this.getUserPasswordRepeat())));
796         }
797
798 }