]> git.mxchange.org Git - jjobs-war.git/blob - src/java/org/mxchange/jjobs/beans/user/JobsUserWebRequestBean.java
Please cherry-pick:
[jjobs-war.git] / src / java / org / mxchange / jjobs / beans / user / JobsUserWebRequestBean.java
1 /*
2  * Copyright (C) 2016 - 2020 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.jjobs.beans.user;
18
19 import java.text.MessageFormat;
20 import java.util.Objects;
21 import javax.ejb.EJB;
22 import javax.enterprise.context.RequestScoped;
23 import javax.enterprise.event.Event;
24 import javax.enterprise.event.Observes;
25 import javax.enterprise.inject.Any;
26 import javax.faces.context.FacesContext;
27 import javax.faces.view.facelets.FaceletException;
28 import javax.inject.Inject;
29 import javax.inject.Named;
30 import org.mxchange.jcontacts.model.contact.Contact;
31 import org.mxchange.jcoreee.events.locale.ObservableLocaleChangeEvent;
32 import org.mxchange.jjobs.beans.BaseJobsBean;
33 import org.mxchange.jjobs.beans.contact.JobsContactWebRequestController;
34 import org.mxchange.jjobs.beans.features.JobsFeaturesWebApplicationController;
35 import org.mxchange.jjobs.beans.user.login.JobsUserLoginWebSessionController;
36 import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
37 import org.mxchange.jusercore.events.user.clear.password.ObservableClearUserPasswordEvent;
38 import org.mxchange.jusercore.events.user.clear.username.ObservableClearUserNameEvent;
39 import org.mxchange.jusercore.events.user.created.ObservableCreatedUserEvent;
40 import org.mxchange.jusercore.events.user.linked.ObservableAdminLinkedUserEvent;
41 import org.mxchange.jusercore.events.user.update.ObservableUpdatedUserPersonalDataEvent;
42 import org.mxchange.jusercore.events.user.update.UpdatedUserPersonalDataEvent;
43 import org.mxchange.jusercore.model.user.LoginUser;
44 import org.mxchange.jusercore.model.user.User;
45 import org.mxchange.jusercore.model.user.UserSessionBeanRemote;
46 import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
47 import org.mxchange.juserlogincore.events.login.ObservableUserLoggedInEvent;
48 import org.mxchange.juserlogincore.events.registration.ObservableUserRegisteredEvent;
49 import org.mxchange.juserlogincore.events.user.password_change.ObservableUpdatedUserPasswordEvent;
50 import org.mxchange.juserlogincore.exceptions.UserPasswordMismatchException;
51 import org.mxchange.juserlogincore.login.UserLoginUtils;
52
53 /**
54  * A user controller (bean)
55  * <p>
56  * @author Roland Häder<roland@mxchange.org>
57  */
58 @Named ("userController")
59 @RequestScoped
60 public class JobsUserWebRequestBean extends BaseJobsBean implements JobsUserWebRequestController {
61
62         /**
63          * Serial number
64          */
65         private static final long serialVersionUID = 542_145_347_916L;
66
67         /**
68          * General contact controller
69          */
70         @Inject
71         private JobsContactWebRequestController contactController;
72
73         /**
74          * Features controller
75          */
76         @Inject
77         private JobsFeaturesWebApplicationController featureController;
78
79         /**
80          * Localization controller
81          */
82         @Inject
83         private JobsLocalizationSessionController localizationController;
84
85         /**
86          * Event being fired when user updated personal data
87          */
88         @Inject
89         @Any
90         private Event<ObservableUpdatedUserPersonalDataEvent> updatedPersonalDataEvent;
91
92         /**
93          * Remote user bean
94          */
95         @EJB (lookup = "java:global/jjobs-ejb/user!org.mxchange.jusercore.model.user.UserSessionBeanRemote")
96         private UserSessionBeanRemote userBean;
97
98         /**
99          * User id
100          */
101         private Long userId;
102
103         /**
104          * Login controller (bean)
105          */
106         @Inject
107         private JobsUserLoginWebSessionController userLoginController;
108
109         /**
110          * User name
111          */
112         private String userName;
113
114         /**
115          * User password (clear-text from web form)
116          */
117         private String userPassword;
118
119         /**
120          * User password repeated (clear-text from web form)
121          */
122         private String userPasswordRepeat;
123
124         /**
125          * Whether the user wants a public profile
126          */
127         private ProfileMode userProfileMode;
128
129         /**
130          * Default constructor
131          */
132         public JobsUserWebRequestBean () {
133                 // Call super constructor
134                 super();
135         }
136
137         /**
138          * Event observer for newly added users by administrator
139          * <p>
140          * @param event Event being fired
141          */
142         public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
143                 // Event and contained entity instance should not be null
144                 if (null == event) {
145                         // Throw NPE
146                         throw new NullPointerException("event is null"); //NOI18N
147                 } else if (event.getAddedUser() == null) {
148                         // Throw NPE again
149                         throw new NullPointerException("event.addedUser is null"); //NOI18N
150                 } else if (event.getAddedUser().getUserId() == null) {
151                         // userId is null
152                         throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
153                 } else if (event.getAddedUser().getUserId() < 1) {
154                         // Not avalid id
155                         throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
156                 }
157
158                 // Set user id again
159                 this.setUserId(event.getAddedUser().getUserId());
160         }
161
162         /**
163          * Event observer for linked users with existing contact data
164          * <p>
165          * @param event Event being fired
166          */
167         public void afterAdminLinkedUserEvent (@Observes final ObservableAdminLinkedUserEvent event) {
168                 // Event and contained entity instance should not be null
169                 if (null == event) {
170                         // Throw NPE
171                         throw new NullPointerException("event is null"); //NOI18N
172                 } else if (event.getLinkedUser() == null) {
173                         // Throw NPE again
174                         throw new NullPointerException("event.linkedUser is null"); //NOI18N
175                 } else if (event.getLinkedUser().getUserId() == null) {
176                         // userId is null
177                         throw new NullPointerException("event.linkedUser.userId is null"); //NOI18N
178                 } else if (event.getLinkedUser().getUserId() < 1) {
179                         // Not avalid id
180                         throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLinkedUser(), event.getLinkedUser().getUserId())); //NOI18N
181                 }
182
183                 // Set user id again
184                 this.setUserId(event.getLinkedUser().getUserId());
185         }
186
187         /**
188          * Event observer for when a bean helper has successfully created a user
189          * instance, means the user exists. If the user does not exist, this event
190          * should not fire but instead a proper exception must be thrown.
191          * <p>
192          * @param event User created event
193          */
194         public void afterCreatedUserEvent (@Observes final ObservableCreatedUserEvent event) {
195                 // Is the instance valid?
196                 if (null == event) {
197                         // Throw NPE
198                         throw new NullPointerException("event is null"); //NOI18N
199                 } else if (event.getCreatedUser() == null) {
200                         // Throw NPE again
201                         throw new NullPointerException("event.createdUser is null"); //NOI18N
202                 } else if (event.getCreatedUser().getUserId() == null) {
203                         // Throw NPE again
204                         throw new NullPointerException("event.createdUser.userId is null"); //NOI18N
205                 } else if (event.getCreatedUser().getUserId() < 1) {
206                         // Throw NPE again
207                         throw new NullPointerException(MessageFormat.format("event.createdUser.userId={0} is not valid", event.getCreatedUser().getUserId())); //NOI18N
208                 }
209
210                 // Get user instance
211                 final User user = event.getCreatedUser();
212
213                 // Set all fields here
214                 this.copyUser(user);
215         }
216
217         /**
218          * Event observer for logged-in user
219          * <p>
220          * @param event Event instance
221          */
222         public void afterUserLoginEvent (@Observes final ObservableUserLoggedInEvent event) {
223                 // Event and contained entity instance should not be null
224                 if (null == event) {
225                         // Throw NPE
226                         throw new NullPointerException("event is null"); //NOI18N
227                 } else if (event.getLoggedInUser() == null) {
228                         // Throw NPE again
229                         throw new NullPointerException("event.registeredUser is null"); //NOI18N
230                 } else if (event.getLoggedInUser().getUserId() == null) {
231                         // userId is null
232                         throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
233                 } else if (event.getLoggedInUser().getUserId() < 1) {
234                         // Not avalid id
235                         throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedInUser(), event.getLoggedInUser().getUserId())); //NOI18N
236                 }
237
238                 // "Cache" user instance
239                 final User loggedInUser = event.getLoggedInUser();
240
241                 // Copy all data to this bean
242                 this.copyUser(loggedInUser);
243         }
244
245         /**
246          * Event observer for user password changes
247          * <p>
248          * @param event Event being fired
249          */
250         public void afterUserPasswordChangedEvent (@Observes final ObservableUpdatedUserPasswordEvent event) {
251                 // Is it valid?
252                 if (null == event) {
253                         // Throw NPE
254                         throw new NullPointerException("event is null"); //NOI18N
255                 } else if (event.getUserPassword() == null) {
256                         // Throw NPE
257                         throw new NullPointerException("event.userPassword is null"); //NOI18N
258                 } else if (event.getUserPassword().isEmpty()) {
259                         // Throw NPE
260                         throw new IllegalArgumentException("event.userPassword is empty"); //NOI18N
261                 }
262
263                 // Set it here
264                 this.setUserPassword(event.getUserPassword());
265                 this.setUserPasswordRepeat(event.getUserPassword());
266         }
267
268         /**
269          * Event observer for new user registrations
270          * <p>
271          * @param event User registration event
272          */
273         public void afterUserRegistrationEvent (@Observes final ObservableUserRegisteredEvent event) {
274                 // Event and contained entity instance should not be null
275                 if (null == event) {
276                         // Throw NPE
277                         throw new NullPointerException("event is null"); //NOI18N
278                 } else if (event.getRegisteredUser() == null) {
279                         // Throw NPE again
280                         throw new NullPointerException("event.registeredUser is null"); //NOI18N
281                 } else if (event.getRegisteredUser().getUserId() == null) {
282                         // userId is null
283                         throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
284                 } else if (event.getRegisteredUser().getUserId() < 1) {
285                         // Not avalid id
286                         throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getRegisteredUser(), event.getRegisteredUser().getUserId())); //NOI18N
287                 }
288
289                 // Get user instance
290                 final User registeredUser = event.getRegisteredUser();
291
292                 // Copy all data from registered->user
293                 this.copyUser(registeredUser);
294
295                 // Set user id again
296                 this.setUserId(registeredUser.getUserId());
297         }
298
299         /**
300          * Event observer for when a user name should be cleared
301          * <p>
302          * @param event Event being fired
303          */
304         public void clearUserNameEvent (@Observes final ObservableClearUserNameEvent event) {
305                 // Is it valid?
306                 if (null == event) {
307                         // Throw NPE
308                         throw new NullPointerException("event is null"); //NOI18N
309                 }
310
311                 // Clear it
312                 this.clearUserName();
313         }
314
315         /**
316          * Event observer for when both user passwords should be cleared
317          * <p>
318          * @param event Event being fired
319          */
320         public void clearUserPasswordEvent (@Observes final ObservableClearUserPasswordEvent event) {
321                 // Is it valid?
322                 if (null == event) {
323                         // Throw NPE
324                         throw new NullPointerException("event is null"); //NOI18N
325                 }
326
327                 // Clear it
328                 this.clearUserPasswords();
329         }
330
331         @Override
332         public User createUserInstance (final boolean createContactData) {
333                 // Required personal data must be set
334                 assert (this.isRequiredPersonalDataSet()) : "not all personal data is set"; //NOI18N
335
336                 // Is user name required?
337                 if (!this.isUserNameRequired()) {
338                         // Generate pseudo-random user name
339                         // @TODO Refacture this to avoid EJB call
340                         final String randomName = this.userBean.generateRandomUserName();
341
342                         // Set it and inivisible profile
343                         this.setUserName(randomName);
344                         this.setUserProfileMode(ProfileMode.INVISIBLE);
345
346                         // Generate random password
347                         final String randomPassword = UserLoginUtils.createRandomPassword(JobsUserWebRequestController.MINIMUM_PASSWORD_LENGTH);
348
349                         // Set random password
350                         this.setUserPassword(randomPassword);
351                         this.setUserPasswordRepeat(randomPassword);
352                 }
353
354                 // Create new user instance
355                 final User user = new LoginUser();
356
357                 // Set user name profile mode and locale
358                 user.setUserName(this.getUserName());
359                 user.setUserProfileMode(this.getUserProfileMode());
360                 user.setUserLocale(this.localizationController.getLocale());
361
362                 // Is multiple registration page
363                 if ((createContactData) || (!this.featureController.isFeatureEnabled("user_register_multiple_page"))) { //NOI18N
364                         // Create contact instance
365                         final Contact contact = this.contactController.createContactInstance();
366
367                         // Set contact in user
368                         user.setUserContact(contact);
369                 }
370
371                 // Return it
372                 return user;
373         }
374
375         @Override
376         public User createUserLogin () {
377                 // Is all data set?
378                 if (this.getUserName() == null) {
379                         // Throw NPE
380                         throw new NullPointerException("userName is null"); //NOI18N
381                 } else if (this.getUserName().isEmpty()) {
382                         // Is empty
383                         throw new IllegalStateException("userName is empty."); //NOI18N
384                 }
385
386                 // Create new user instance
387                 final User user = new LoginUser();
388
389                 // Update all data ...
390                 user.setUserName(this.getUserName());
391
392                 // Return the new instance
393                 return user;
394         }
395
396         @Override
397         public String doChangePersonalData () {
398                 // This method shall only be called if the user is logged-in
399                 if (!this.userLoginController.isUserLoggedIn()) {
400                         // Not logged-in
401                         throw new IllegalStateException("User is not logged-in"); //NOI18N
402                 } else if (!this.isRequiredChangePersonalDataSet()) {
403                         // Not all required fields are set
404                         throw new FaceletException("Not all required fields are set."); //NOI18N
405                 } else if (!this.userLoginController.ifCurrentPasswordMatches()) {
406                         // Password not matching
407                         throw new FaceletException(new UserPasswordMismatchException(this.userLoginController.getLoggedInUser()));
408                 } else if (!this.featureController.isFeatureEnabled("change_user_personal_data")) { //NOI18N
409                         // Editing is not allowed
410                         throw new IllegalStateException("User tried to edit personal data."); //NOI18N
411                 }
412
413                 // Get user instance
414                 final User user = this.userLoginController.getLoggedInUser();
415
416                 // Copy contact data to contact instance
417                 this.contactController.updateContactDataFromController(user.getUserContact());
418
419                 // It should be there, so run some tests on it
420                 assert (user instanceof User) : "Instance userLoginController.loggedInUser is null"; //NOI18N
421                 assert (user.getUserId() instanceof Long) : "Instance userLoginController.loggedInUser.userId is null"; //NOI18N
422                 assert (user.getUserId() > 0) : MessageFormat.format("userLoginController.loggedInUser.userId={0} is invalid", user.getUserId()); //NOI18N
423                 assert (user.getUserContact() instanceof Contact) : "Instance userLoginController.loggedInUser.userContact is null"; //NOI18N
424                 assert (user.getUserContact().getContactId() instanceof Long) : "Instance userLoginController.userContact.contactId is null"; //NOI18N
425                 assert (user.getUserContact().getContactId() > 0) : MessageFormat.format("Instance userLoginController.userContact.contactId={0} is invalid", user.getUserContact().getContactId()); //NOI18N
426
427                 // Update all fields
428                 user.setUserProfileMode(this.getUserProfileMode());
429
430                 // Send it to the EJB
431                 final User updatedUser = this.userBean.updateUserPersonalData(user);
432
433                 // Fire event
434                 this.updatedPersonalDataEvent.fire(new UpdatedUserPersonalDataEvent(updatedUser));
435
436                 // All fine
437                 return "user_contact_data_saved"; //NOI18N
438         }
439
440         /**
441          * Getter for user id
442          * <p>
443          * @return User id
444          */
445         public Long getUserId () {
446                 return this.userId;
447         }
448
449         /**
450          * Setter for user id
451          * <p>
452          * @param userId User id
453          */
454         public void setUserId (final Long userId) {
455                 this.userId = userId;
456         }
457
458         /**
459          * Getter for user name
460          * <p>
461          * @return User name
462          */
463         public String getUserName () {
464                 return this.userName;
465         }
466
467         /**
468          * Setter for user name
469          * <p>
470          * @param userName User name
471          */
472         public void setUserName (final String userName) {
473                 this.userName = userName;
474         }
475
476         @Override
477         public String getUserPassword () {
478                 return this.userPassword;
479         }
480
481         /**
482          * Setter for clear-text user password
483          * <p>
484          * @param userPassword Clear-text user password
485          */
486         public void setUserPassword (final String userPassword) {
487                 this.userPassword = userPassword;
488         }
489
490         /**
491          * Getter for clear-text user password repeated
492          * <p>
493          * @return Clear-text user password repeated
494          */
495         public String getUserPasswordRepeat () {
496                 return this.userPasswordRepeat;
497         }
498
499         /**
500          * Setter for clear-text user password repeated
501          * <p>
502          * @param userPasswordRepeat Clear-text user password repeated
503          */
504         public void setUserPasswordRepeat (final String userPasswordRepeat) {
505                 this.userPasswordRepeat = userPasswordRepeat;
506         }
507
508         /**
509          * Getter for user profile mode
510          * <p>
511          * @return User profile mode
512          */
513         public ProfileMode getUserProfileMode () {
514                 return this.userProfileMode;
515         }
516
517         /**
518          * Setter for user profile mode
519          * <p>
520          * @param userProfileMode User profile mode
521          */
522         public void setUserProfileMode (final ProfileMode userProfileMode) {
523                 this.userProfileMode = userProfileMode;
524         }
525
526         @Override
527         public boolean ifBothPasswordsEmptyAllowed () {
528                 // Check feature first
529                 return ((this.featureController.isFeatureEnabled("allow_user_registration_empty_password")) && //NOI18N
530                                 ((this.getUserPassword() == null) || (this.getUserPassword().isEmpty())) &&
531                                 ((this.getUserPasswordRepeat() == null) || (this.getUserPasswordRepeat().isEmpty())));
532         }
533
534         @Override
535         public boolean isRequiredChangePersonalDataSet () {
536                 return ((this.getUserProfileMode() != null) &&
537                                 (this.getUserName() != null) && (!this.getUserName().isEmpty()) &&
538                                 (this.contactController.isRequiredChangePersonalDataSet()));
539         }
540
541         @Override
542         public boolean isRequiredPersonalDataSet () {
543                 if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N
544                         // Multiple registration page
545                         return this.contactController.isRequiredPersonalDataSet();
546                 } else {
547                         // Single registration page
548                         return (((this.getUserName() != null) || (!this.isUserNameRequired())) &&
549                                         (this.getUserProfileMode() != null) &&
550                                         (this.contactController.isRequiredPersonalDataSet()) &&
551                                         (this.getUserPassword() != null) &&
552                                         (this.getUserPasswordRepeat() != null));
553                 }
554         }
555
556         @Override
557         public boolean isSamePasswordEntered () {
558                 return ((!this.getUserPassword().isEmpty()) && (Objects.equals(this.getUserPassword(), this.getUserPasswordRepeat())));
559         }
560
561         @Override
562         public boolean isUserIdEmpty () {
563                 return ((this.getUserId() == null) || (this.getUserId() == 0));
564         }
565
566         @Override
567         public boolean isUserNameRequired () {
568                 // Get context parameter
569                 final String contextParameter = FacesContext.getCurrentInstance().getExternalContext().getInitParameter("is_user_login_require_user_name"); //NOI18N
570
571                 // Is it set?
572                 final boolean isRequired = ((contextParameter instanceof String) && (contextParameter.toLowerCase().equals("true"))); //NOI18N
573
574                 // Return value
575                 return isRequired;
576         }
577
578         /**
579          * Clears user name
580          */
581         private void clearUserName () {
582                 // Clear it
583                 this.setUserName(null);
584         }
585
586         /**
587          * Clears both user passwords
588          */
589         private void clearUserPasswords () {
590                 // Clear both
591                 this.setUserPassword(null);
592                 this.setUserPasswordRepeat(null);
593         }
594
595         /**
596          * Copies given user into the controller
597          * <p>
598          * @param user User instance
599          */
600         private void copyUser (final User user) {
601                 // Make sure the instance is valid
602                 if (null == user) {
603                         // Throw NPE
604                         throw new NullPointerException("user is null"); //NOI18N
605                 } else if (user.getUserContact() == null) {
606                         // Throw again ...
607                         throw new NullPointerException("user.userContact is null"); //NOI18N
608                 }
609
610                 // Copy all fields:
611                 // - base data
612                 this.setUserId(user.getUserId());
613                 this.setUserProfileMode(user.getUserProfileMode());
614         }
615
616 }