]> git.mxchange.org Git - jjobs-war.git/blob - src/java/org/mxchange/jjobs/beans/login/JobsUserLoginWebSessionBean.java
added missing language i18n strings + show logout form only to logged-in users ...
[jjobs-war.git] / src / java / org / mxchange / jjobs / beans / login / JobsUserLoginWebSessionBean.java
1 /*
2  * Copyright (C) 2016 Roland Haeder
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.login;
18
19 import java.text.MessageFormat;
20 import java.util.Collections;
21 import java.util.List;
22 import java.util.Objects;
23 import javax.enterprise.context.SessionScoped;
24 import javax.enterprise.event.Event;
25 import javax.enterprise.event.Observes;
26 import javax.enterprise.inject.Any;
27 import javax.faces.context.FacesContext;
28 import javax.faces.view.facelets.FaceletException;
29 import javax.inject.Inject;
30 import javax.inject.Named;
31 import javax.naming.Context;
32 import javax.naming.InitialContext;
33 import javax.naming.NamingException;
34 import org.mxchange.jjobs.beans.BaseJobsController;
35 import org.mxchange.jjobs.beans.user.JobsUserWebSessionController;
36 import org.mxchange.jusercore.container.login.LoginContainer;
37 import org.mxchange.jusercore.container.login.UserLoginContainer;
38 import org.mxchange.jusercore.events.login.UserLoggedInEvent;
39 import org.mxchange.jusercore.events.login.UserLoginEvent;
40 import org.mxchange.jusercore.events.user.password_change.UpdatedUserPasswordEvent;
41 import org.mxchange.jusercore.exceptions.UserNotFoundException;
42 import org.mxchange.jusercore.exceptions.UserPasswordMismatchException;
43 import org.mxchange.jusercore.exceptions.UserStatusLockedException;
44 import org.mxchange.jusercore.exceptions.UserStatusUnconfirmedException;
45 import org.mxchange.jusercore.model.login.UserLoginSessionBeanRemote;
46 import org.mxchange.jusercore.model.user.User;
47 import org.mxchange.jusercore.model.user.UserUtils;
48 import org.mxchange.jusercore.model.user.password_history.PasswordHistory;
49 import org.mxchange.jusercore.model.user.password_history.UserPasswordHistorySessionBeanRemote;
50 import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
51 import org.mxchange.jusercore.model.user.status.UserAccountStatus;
52
53 /**
54  * A web bean for user registration
55  * <p>
56  * @author Roland Haeder<roland@mxchange.org>
57  */
58 @Named ("loginController")
59 @SessionScoped
60 public class JobsUserLoginWebSessionBean extends BaseJobsController implements JobsUserLoginWebSessionController {
61
62         /**
63          * Path name for guest base template
64          */
65         private static final String GUEST_BASE_TEMPLATE_NAME = "guest/guest"; //NOI18N
66
67         /**
68          * Path name for logged-in user base template
69          */
70         private static final String USER_BASE_TEMPLATE_NAME = "login/user/user"; //NOI18N
71
72         /**
73          * Serial number
74          */
75         private static final long serialVersionUID = 47_828_986_719_691_592L;
76
77         /**
78          * Current password
79          */
80         private String currentPassword;
81
82         /**
83          * Logged-in user instance
84          */
85         private User loggedInUser;
86
87         /**
88          * User controller
89          */
90         @Inject
91         private JobsUserWebSessionController userController;
92
93         /**
94          * Event being fired when user logs in
95          */
96         @Inject
97         @Any
98         private Event<UserLoggedInEvent> loginEvent;
99
100         /**
101          * EJB for user-login
102          */
103         private UserLoginSessionBeanRemote userLoginBean;
104
105         /**
106          * Flag whether the user has logged-in, set only from inside
107          */
108         private boolean userLoggedIn;
109
110         /**
111          * User's password history
112          */
113         private List<PasswordHistory> userPasswordHistory;
114
115         /**
116          * EJB for user's password history
117          */
118         private UserPasswordHistorySessionBeanRemote userPasswordHistoryBean;
119
120         /**
121          * Default constructor
122          */
123         public JobsUserLoginWebSessionBean () {
124                 try {
125                         // Get initial context
126                         Context context = new InitialContext();
127
128                         // Try to lookup
129                         this.userLoginBean = (UserLoginSessionBeanRemote) context.lookup("java:global/jjobs-ejb/login!org.mxchange.jusercore.model.login.UserLoginSessionBeanRemote"); //NOI18N
130
131                         // Also find this
132                         this.userPasswordHistoryBean = (UserPasswordHistorySessionBeanRemote) context.lookup(""); //NOI18N
133
134                         // Defaul template is guest
135                         this.baseTemplatePathName = GUEST_BASE_TEMPLATE_NAME;
136                 } catch (final NamingException ex) {
137                         // Continue to throw
138                         throw new FaceletException(ex);
139                 }
140         }
141
142         @Override
143         public void afterUserUpdatedPasswordEvent (@Observes final UpdatedUserPasswordEvent event) {
144                 // Check parameter
145                 if (null == event) {
146                         // Throw NPE
147                         throw new NullPointerException("event is null"); //NOI18N
148                 } else if (event.getPasswordHistory() == null) {
149                         // Throw NPE again
150                         throw new NullPointerException("event.passwordHistory is null"); //NOI18N
151                 } else if (event.getPasswordHistory().getUserPasswordHistoryId() == null) {
152                         // ... and again
153                         throw new NullPointerException("event.passwordHistory.userPasswordHistoryId is null"); //NOI18N
154                 } else if (event.getPasswordHistory().getUserPasswordHistoryId() < 1) {
155                         // Invalid value
156                         throw new IllegalArgumentException(MessageFormat.format("event.passwordHistory.userPasswordHistoryId={0} is in valid", event.getPasswordHistory().getUserPasswordHistoryId())); //NOI18N
157                 }
158
159                 // All fine, so update list
160                 this.updatePasswordHistory(event.getPasswordHistory());
161         }
162
163         @Override
164         public String doAdminLogout () {
165                 // Is a user logged-in?
166                 if (this.isUserLoggedIn()) {
167                         // Call other logout
168                         return this.doUserLogout();
169                 }
170
171                 // Invalidate session
172                 FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
173
174                 // Set template type to guest
175                 this.setBaseTemplatePathName(GUEST_BASE_TEMPLATE_NAME); //NOI18N
176
177                 // Redirect to index
178                 return "index?faces-redirect=true"; //NOI18N
179         }
180
181         @Override
182         public String doUserLogin () {
183                 // Get user instance
184                 User user = this.userController.createUserLogin();
185
186                 // Create login container
187                 LoginContainer container = new UserLoginContainer(user, this.userController.getUserPassword());
188
189                 try {
190                         // Call bean
191                         User confirmedUser = this.userLoginBean.validateUserAccountStatus(container);
192
193                         // All fine here so set it here
194                         this.setLoggedInUser(confirmedUser);
195
196                         // Retrieve user's password list
197                         this.userPasswordHistory = this.userPasswordHistoryBean.getUserPasswordHistory(confirmedUser);
198
199                         // Set template to "login"
200                         this.setTemplateType("login"); //NOI18N
201
202                         // Fire event away. Keep this last before return statement.
203                         this.loginEvent.fire(new UserLoginEvent(confirmedUser));
204
205                         // All fine
206                         return "login"; //NOI18N
207                 } catch (final UserNotFoundException | UserStatusLockedException | UserStatusUnconfirmedException ex) {
208                         // Show JSF message
209                         this.showFacesMessage("form_user_login:userName", ex); //NOI18N
210                         return ""; //NOI18N
211                 } catch (final UserPasswordMismatchException ex) {
212                         // Show JSF message
213                         this.showFacesMessage("form_user_login:userPassword", ex); //NOI18N
214                         return ""; //NOI18N
215                 }
216         }
217
218         @Override
219         public String getCurrentPassword () {
220                 return this.currentPassword;
221         }
222
223         @Override
224         public void setCurrentPassword (final String currentPassword) {
225                 this.currentPassword = currentPassword;
226         }
227
228         @Override
229         public User getLoggedInUser () {
230                 return this.loggedInUser;
231         }
232
233         @Override
234         public void setLoggedInUser (final User loggedInUser) {
235                 this.loggedInUser = loggedInUser;
236         }
237
238         @Override
239         public List<PasswordHistory> getUserPasswordHistory () {
240                 return Collections.unmodifiableList(this.userPasswordHistory);
241         }
242
243         @Override
244         public boolean ifCurrentPasswordMatches () {
245                 // The current password must be set and not empty
246                 if (this.getCurrentPassword() == null) {
247                         // Is not set
248                         throw new NullPointerException("this.currentPassword is null"); //NOI18N
249                 } else if (this.getCurrentPassword().isEmpty()) {
250                         // Is set empty
251                         throw new IllegalStateException("this.currentPassword is empty."); //NOI18N
252                 }
253
254                 // Create "container"
255                 LoginContainer container = new UserLoginContainer(this.getLoggedInUser(), this.getCurrentPassword());
256
257                 // Now check if it matches
258                 return UserUtils.ifPasswordMatches(container, this.getLoggedInUser());
259         }
260
261         @Override
262         public boolean ifUserMustChangePassword () {
263                 return (this.isUserLoggedIn() && this.getLoggedInUser().getUserMustChangePassword());
264         }
265
266         @Override
267         public boolean isInvisible () {
268                 // Check on login
269                 if (!this.isUserLoggedIn()) {
270                         // Not logged in!
271                         throw new IllegalStateException("isInvisible() has been invoked for a guest."); //NOI18N
272                 }
273
274                 // Check logged-in first, then invisibility
275                 return this.getLoggedInUser().getUserProfileMode().equals(ProfileMode.INVISIBLE);
276         }
277
278         @Override
279         public boolean isPasswordInHistory (final String userPassword) {
280                 // Default is not found
281                 boolean isPasswordInHistory = false;
282
283                 // Init variables
284                 int count = 1;
285                 int maxEntries = this.getIntegerContextParameter("max_user_password_history"); //NOI18N
286
287                 // Check all passwords
288                 for (final PasswordHistory entry : this.getUserPasswordHistory()) {
289                         // Is password the same?
290                         if (UserUtils.ifPasswordMatches(userPassword, entry.getUserPasswordHistoryUser())) {
291                                 // Yes, found it
292                                 isPasswordInHistory = true;
293                                 break;
294                         } else if (count == maxEntries) {
295                                 // Maximum reached
296                                 break;
297                         }
298
299                         // Count up
300                         count++;
301                 }
302
303                 // Return status
304                 return isPasswordInHistory;
305         }
306
307         @Override
308         public boolean isUserLoggedIn () {
309                 // Trace message
310                 // NOISY-DEBUG System.out.println(MessageFormat.format("JobsUserLoginWebSessionBean:isUserLoggedIn: this.loggedInUser={0},this.templateType={1} - CALLED!", this.getLoggedInUser(), this.getTemplateType()));
311
312                 // Compare instance
313                 this.userLoggedIn = ((this.getLoggedInUser() instanceof User) && (Objects.equals(this.getLoggedInUser().getUserAccountStatus(), UserAccountStatus.CONFIRMED)));
314
315                 // Trace message
316                 // NOISY-DEBUG System.out.println(MessageFormat.format("JobsUserLoginWebSessionBean:isUserLoggedIn: this.userLoggedIn={0} - EXIT!", this.userLoggedIn));
317
318                 // Return it
319                 return this.userLoggedIn;
320         }
321
322         /**
323          * Clears this bean
324          */
325         private void clear () {
326                 // Clear all fields
327                 this.setCurrentPassword(null);
328         }
329
330         /**
331          * Updates password history by adding given entry to it as long as it is not
332          * there.
333          * <p>
334          * @param passwordHistory Password history entry
335          */
336         private void updatePasswordHistory (final PasswordHistory passwordHistory) {
337                 if (null == passwordHistory) {
338                         // Throw NPE
339                         throw new NullPointerException("passwordHistory is null"); //NOI18N
340                 } else if (passwordHistory.getUserPasswordHistoryId() == null) {
341                         // Throw NPE again
342                         throw new NullPointerException("passwordHistory.userPasswordHistoryId is null"); //NOI18N
343                 } else if (passwordHistory.getUserPasswordHistoryId() < 1) {
344                         // Invalid id
345                         throw new IllegalArgumentException(MessageFormat.format("passwordHistory.userPasswordHistoryId={0} is not valid.", passwordHistory.getUserPasswordHistoryId())); //NOI18N
346                 }
347
348                 // Is it there?
349                 if (this.userPasswordHistory.contains(passwordHistory)) {
350                         // Excact copy found
351                         return;
352                 }
353
354                 // Check all entries
355                 for (final PasswordHistory entry : this.userPasswordHistory) {
356                         // Is same id number?
357                         if (Objects.equals(entry.getUserPasswordHistoryId(), passwordHistory.getUserPasswordHistoryId())) {
358                                 // Found it
359                                 return;
360                         }
361                 }
362
363                 // Not found, so add it
364                 this.userPasswordHistory.add(passwordHistory);
365         }
366
367 }