2 * Copyright (C) 2016 Roland Haeder
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;
19 import java.text.MessageFormat;
20 import java.util.Collections;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Objects;
24 import javax.annotation.PostConstruct;
25 import javax.enterprise.context.RequestScoped;
26 import javax.enterprise.event.Event;
27 import javax.enterprise.event.Observes;
28 import javax.enterprise.inject.Any;
29 import javax.faces.view.facelets.FaceletException;
30 import javax.inject.Inject;
31 import javax.inject.Named;
32 import javax.naming.Context;
33 import javax.naming.InitialContext;
34 import javax.naming.NamingException;
35 import org.mxchange.addressbook.beans.contact.AddressbookContactWebSessionController;
36 import org.mxchange.jcontacts.contact.Contact;
37 import org.mxchange.jusercore.events.user.AdminAddedUserEvent;
38 import org.mxchange.jusercore.events.user.AdminUserAddedEvent;
39 import org.mxchange.jusercore.exceptions.EmailAddressAlreadyRegisteredException;
40 import org.mxchange.jusercore.exceptions.UserNameAlreadyRegisteredException;
41 import org.mxchange.jusercore.exceptions.UserNotFoundException;
42 import org.mxchange.jusercore.exceptions.UserPasswordRepeatMismatchException;
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.UserUtils;
47 import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
48 import org.mxchange.jusercore.model.user.status.UserAccountStatus;
51 * A user bean (controller)
53 * @author Roland Haeder<roland@mxchange.org>
55 @Named ("adminUserController")
57 public class AddressbookAdminUserWebRequestBean implements AddressbookAdminUserWebRequestController {
62 private static final long serialVersionUID = 542_145_347_916L;
65 * An event fired when the administrator has added a new user
69 private Event<AdminAddedUserEvent> addedUserEvent;
72 * Admin helper instance
75 private RateCalcAdminWebRequestController adminHelper;
78 * Regular contact controller
81 private AddressbookContactWebSessionController contactController;
84 * An event fired when the administrator has updated a new user
88 private Event<AdminUpdatedUserDataEvent> updatedUserDataEvent;
93 private final UserSessionBeanRemote userBean;
96 * Regular user controller
99 private AddressbookUserWebSessionController userController;
102 * A list of all user profiles
104 private List<User> userList;
109 private String userName;
112 * User password (unencrypted from web form)
114 private String userPassword;
117 * User password repeated (unencrypted from web form)
119 private String userPasswordRepeat;
122 * Default constructor
124 public AddressbookAdminUserWebRequestBean () {
127 // Get initial context
128 Context context = new InitialContext();
131 this.userBean = (UserSessionBeanRemote) context.lookup("java:global/addressbook-ejb/user!org.mxchange.jusercore.model.user.UserSessionBeanRemote"); //NOI18N
132 } catch (final NamingException e) {
134 throw new FaceletException(e);
139 public void addUser () {
140 // Create new user instance
141 User localUser = new LoginUser();
143 // Set user name, CONFIRMED and INVISIBLE
144 localUser.setUserName(this.getUserName());
145 localUser.setUserAccountStatus(UserAccountStatus.CONFIRMED);
146 localUser.setUserProfileMode(ProfileMode.INVISIBLE);
148 // Create contact instance
149 Contact contact = this.contactController.createContactInstance();
151 // Set contact in user
152 localUser.setUserContact(contact);
154 // Init variable for password
155 String password = null;
157 // Is the user name or email address used already?
158 // @TODO Add password length check
159 if (this.userController.isUserNameRegistered(localUser)) {
160 // User name is already used
161 throw new FaceletException(new UserNameAlreadyRegisteredException(localUser));
162 } else if (this.contactController.isEmailAddressRegistered(localUser.getUserContact())) {
163 // Email address is already used
164 throw new FaceletException(new EmailAddressAlreadyRegisteredException(localUser));
165 } else if ((this.getUserPassword() == null && (this.getUserPasswordRepeat() == null)) || ((this.getUserPassword().isEmpty()) && (this.getUserPasswordRepeat().isEmpty()))) {
166 // Empty password entered, then generate one
167 password = UserUtils.createRandomPassword(AddressbookUserWebSessionController.MINIMUM_PASSWORD_LENGTH);
168 } else if (!this.isSamePasswordEntered()) {
169 // Both passwords don't match
170 throw new FaceletException(new UserPasswordRepeatMismatchException(localUser));
172 // Both match, so get it from this bean
173 password = this.getUserPassword();
176 // The password should not be null and at least 5 characters long
177 assert (password != null) : "password is null"; //NOI18N
178 assert (password.length() >= AddressbookUserWebSessionController.MINIMUM_PASSWORD_LENGTH) : "Password is not long enough."; //NOI18N
180 // Encrypt password and set it
181 localUser.setUserEncryptedPassword(UserUtils.encryptPassword(password));
183 // Init updated user instance
184 User updatedUser = null;
187 // Now, that all is set, call EJB
188 updatedUser = this.userBean.addUser(localUser);
189 } catch (final UserNameAlreadyRegisteredException | EmailAddressAlreadyRegisteredException ex) {
191 throw new FaceletException(ex);
195 this.addedUserEvent.fire(new AdminUserAddedEvent(updatedUser));
197 // Add user to local list
198 this.userList.add(updatedUser);
200 // Clear contact instance
201 this.contactController.clear();
205 public void afterUserUpdatedPersonalData (@Observes final UpdatedUserPersonalDataEvent event) {
209 throw new NullPointerException("event is null");
210 } else if (event.getUpdatedUser() == null) {
212 throw new NullPointerException("event.updatedUser is null");
213 } else if (event.getUpdatedUser().getUserId() == null) {
215 throw new NullPointerException("event.updatedUser.userId is null");
216 } else if (event.getUpdatedUser().getUserId() < 1) {
218 throw new IllegalArgumentException(MessageFormat.format("event.updatedUser.userId={0} is in valid", event.getUpdatedUser().getUserId()));
221 // All fine, so update list
222 this.updateList(event.getUpdatedUser());
226 public List<User> allUsers () {
228 return Collections.unmodifiableList(this.userList);
232 public void editUserData () {
234 User user = this.adminHelper.getUser();
236 // Null password means not setting it
237 String encryptedPassword = null;
239 // Check if user instance is in helper and valid
242 throw new NullPointerException("adminHelper.user is null");
243 } else if (user.getUserId() == null) {
245 throw new NullPointerException("adminHelper.user.userId is null");
246 } else if (user.getUserId() < 1) {
248 throw new IllegalStateException(MessageFormat.format("adminHelper.user.userId={0} is invalid", user.getUserId()));
249 } else if (this.getUserName() == null) {
250 // Not all required fields are set
251 throw new NullPointerException("this.userName is null");
252 } else if (this.getUserName().isEmpty()) {
253 // Not all required fields are set
254 throw new IllegalArgumentException("this.userName is empty");
255 } else if (((!this.getUserPassword().isEmpty()) || (!this.getUserPasswordRepeat().isEmpty())) && (!this.isSamePasswordEntered())) {
256 // Not same password entered
257 this.setUserPassword(null);
258 this.setUserPasswordRepeat(null);
261 throw new FaceletException("Not same password entered");
262 } else if (this.isSamePasswordEntered()) {
263 // Same password entered, create container
264 if (UserUtils.ifPasswordMatches(new UserLoginContainer(user, this.getUserPassword()))) {
265 // Same password entered
266 throw new FaceletException("Same password as stored entered.");
270 encryptedPassword = UserUtils.encryptPassword(this.getUserPassword());
274 user.setUserName(this.getUserName());
276 // Is a password set?
277 if (encryptedPassword != null) {
279 user.setUserEncryptedPassword(encryptedPassword);
282 // Call EJB for updating user data
283 User updatedUser = this.userBean.updateUserData(user);
286 this.updateList(updatedUser);
289 this.updatedUserDataEvent.fire(new AdminUserDataUpdatedEvent(updatedUser));
293 public String getUserName () {
294 return this.userName;
298 public void setUserName (final String userName) {
299 this.userName = userName;
303 public String getUserPassword () {
304 return this.userPassword;
308 public void setUserPassword (final String userPassword) {
309 this.userPassword = userPassword;
313 public String getUserPasswordRepeat () {
314 return this.userPasswordRepeat;
318 public void setUserPasswordRepeat (final String userPasswordRepeat) {
319 this.userPasswordRepeat = userPasswordRepeat;
323 public boolean hasUsers () {
324 return (!this.allUsers().isEmpty());
328 * Post-initialization of this class
331 public void init () {
332 // Initialize user list
333 this.userList = this.userBean.allUsers();
337 public User lookupUserById (final Long userId) throws UserNotFoundException {
338 // Parameter must be valid
339 if (null == userId) {
341 throw new NullPointerException("userId is null"); //NOI18N
342 } else if (userId < 1) {
344 throw new IllegalArgumentException(MessageFormat.format("userId={0} is not valid.", userId)); //NOI18N
350 // Try to lookup it in visible user list
351 for (final Iterator<User> iterator = this.userList.iterator(); iterator.hasNext();) {
353 User next = iterator.next();
355 // Is the user id found?
356 if (Objects.equals(next.getUserId(), userId)) {
357 // Copy to other variable
365 // Not visible for the current user
366 throw new UserNotFoundException(userId);
374 * Checks if same password is entered and that they are not empty.
376 * @return Whether the same password was entered
378 private boolean isSamePasswordEntered () {
379 return ((!this.getUserPassword().isEmpty()) && (Objects.equals(this.getUserPassword(), this.getUserPasswordRepeat())));
383 * Updates list with given user instance
385 * @param user User instance
387 private void updateList (final User user) {
388 // The user should be valid
391 throw new NullPointerException("user is null");
392 } else if (user.getUserId() == null) {
394 throw new NullPointerException("user.userId is null");
395 } else if (user.getUserId() < 1) {
397 throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is invalid", user.getUserId()));
401 Iterator<User> iterator = this.userList.iterator();
404 while (iterator.hasNext()) {
406 User next = iterator.next();
408 // Is the same user id?
409 if (Objects.equals(user.getUserId(), next.getUserId())) {
410 // Found it, so remove it
411 this.userList.remove(next);
417 this.userList.add(user);