From: Roland Häder Date: Wed, 12 Jul 2017 19:13:56 +0000 (+0200) Subject: Please cherry-pick: X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=2aae212c5b641b9f2c5459f779ac1ca1ddf9d37a;p=addressbook-ejb.git Please cherry-pick: - imported new location (package) of classes/interfaces - moved EJBs to proper locations Signed-off-by: Roland Häder --- diff --git a/src/java/org/mxchange/jusercore/model/user/AddressbookAdminUserSessionBean.java b/src/java/org/mxchange/jusercore/model/user/AddressbookAdminUserSessionBean.java index 1dc8927..e2e86d7 100644 --- a/src/java/org/mxchange/jusercore/model/user/AddressbookAdminUserSessionBean.java +++ b/src/java/org/mxchange/jusercore/model/user/AddressbookAdminUserSessionBean.java @@ -28,8 +28,8 @@ import org.mxchange.jusercore.exceptions.UserNotFoundException; import org.mxchange.jusercore.exceptions.UserStatusConfirmedException; import org.mxchange.jusercore.exceptions.UserStatusLockedException; import org.mxchange.jusercore.exceptions.UserStatusUnconfirmedException; -import org.mxchange.jusercore.model.user.register.UserRegistrationSessionBeanRemote; import org.mxchange.jusercore.model.user.status.UserAccountStatus; +import org.mxchange.juserlogincore.model.user.register.UserRegistrationSessionBeanRemote; /** * An administrative user EJB @@ -262,7 +262,6 @@ public class AddressbookAdminUserSessionBean extends BaseAddressbookDatabaseBean User managedUser = this.userBean.updateUserData(user); // @TODO Create user lock history entry - // Send out email // @TODO externalize subject line this.sendEmail("User account locked", "user_account_locked", managedUser, baseUrl, null); //NOI18N @@ -322,7 +321,6 @@ public class AddressbookAdminUserSessionBean extends BaseAddressbookDatabaseBean User managedUser = this.userBean.updateUserData(user); // @TODO Create user lock history entry - // Send out email // @TODO externalize subject line this.sendEmail("User account unlocked", "user_account_unlocked", managedUser, baseUrl, null); //NOI18N diff --git a/src/java/org/mxchange/jusercore/model/user/AddressbookUserSessionBean.java b/src/java/org/mxchange/jusercore/model/user/AddressbookUserSessionBean.java index 6a0724b..093283a 100644 --- a/src/java/org/mxchange/jusercore/model/user/AddressbookUserSessionBean.java +++ b/src/java/org/mxchange/jusercore/model/user/AddressbookUserSessionBean.java @@ -41,8 +41,8 @@ import org.mxchange.jusercore.exceptions.UserStatusUnconfirmedException; import org.mxchange.jusercore.model.user.password_history.PasswordHistory; import org.mxchange.jusercore.model.user.password_history.UserPasswordHistory; import org.mxchange.jusercore.model.user.profilemodes.ProfileMode; -import org.mxchange.jusercore.model.user.register.UserRegistrationSessionBeanRemote; import org.mxchange.jusercore.model.user.status.UserAccountStatus; +import org.mxchange.juserlogincore.model.user.register.UserRegistrationSessionBeanRemote; /** * A user EJB diff --git a/src/java/org/mxchange/jusercore/model/user/email_address/AddressbookUserEmailChangeSessionBean.java b/src/java/org/mxchange/jusercore/model/user/email_address/AddressbookUserEmailChangeSessionBean.java index c035310..008e75d 100644 --- a/src/java/org/mxchange/jusercore/model/user/email_address/AddressbookUserEmailChangeSessionBean.java +++ b/src/java/org/mxchange/jusercore/model/user/email_address/AddressbookUserEmailChangeSessionBean.java @@ -28,7 +28,7 @@ import org.mxchange.addressbook.database.BaseAddressbookDatabaseBean; import org.mxchange.jusercore.model.email_address.ChangeableEmailAddress; import org.mxchange.jusercore.model.email_address.EmailAddressChange; import org.mxchange.jusercore.model.user.UserSessionBeanRemote; -import org.mxchange.jusercore.model.user.UserUtils; +import org.mxchange.juserlogincore.login.UserLoginUtils; /** * A session-scoped bean for changing email addresses @@ -206,7 +206,7 @@ public class AddressbookUserEmailChangeSessionBean extends BaseAddressbookDataba // Search for free hash while (isUsed) { // Generate hash, there is already in UserUtils a nice method that can be used for this purpose. - hash = UserUtils.encryptPassword(String.format("%s:%s", emailAddress.getEmailAddress(), emailAddress.toString())); //NOI18N + hash = UserLoginUtils.encryptPassword(String.format("%s:%s", emailAddress.getEmailAddress(), emailAddress.toString())); //NOI18N // The hash *may* be unique, better test it Query query = this.getEntityManager().createNamedQuery("SearchEmailChangeByHash", EmailAddressChange.class); //NOI18N diff --git a/src/java/org/mxchange/jusercore/model/user/login/FinancialsUserLoginSessionBean.java b/src/java/org/mxchange/jusercore/model/user/login/FinancialsUserLoginSessionBean.java deleted file mode 100644 index 699565c..0000000 --- a/src/java/org/mxchange/jusercore/model/user/login/FinancialsUserLoginSessionBean.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2016, 2017 Roland Häder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -package org.mxchange.jusercore.model.user.login; - -import java.text.MessageFormat; -import javax.ejb.EJB; -import javax.ejb.Stateless; -import org.mxchange.addressbook.database.BaseAddressbookDatabaseBean; -import org.mxchange.jusercore.container.login.LoginContainer; -import org.mxchange.jusercore.exceptions.UserNotFoundException; -import org.mxchange.jusercore.exceptions.UserPasswordMismatchException; -import org.mxchange.jusercore.exceptions.UserStatusLockedException; -import org.mxchange.jusercore.exceptions.UserStatusUnconfirmedException; -import org.mxchange.jusercore.model.login.user.UserLoginSessionBeanRemote; -import org.mxchange.jusercore.model.user.User; -import org.mxchange.jusercore.model.user.UserSessionBeanRemote; -import org.mxchange.jusercore.model.user.UserUtils; -import org.mxchange.jusercore.model.user.register.UserRegistrationSessionBeanRemote; -import org.mxchange.jusercore.model.user.status.UserAccountStatus; - -/** - * A session EJB for user logins - *

- * @author Roland Häder - */ -@Stateless (name = "userLogin", description = "A bean handling the user login for Financials project") -public class FinancialsUserLoginSessionBean extends BaseAddressbookDatabaseBean implements UserLoginSessionBeanRemote { - - /** - * Serial number - */ - private static final long serialVersionUID = 21_785_978_127_581_965L; - - /** - * Registration EJB - */ - @EJB - private UserRegistrationSessionBeanRemote registerBean; - - /** - * User EJB - */ - @EJB - private UserSessionBeanRemote userBean; - - /** - * Default constructor - */ - public FinancialsUserLoginSessionBean () { - // Call super constructor - super(); - } - - @Override - public User validateUserAccountStatus (final LoginContainer container) throws UserNotFoundException, UserStatusLockedException, UserStatusUnconfirmedException, UserPasswordMismatchException { - // Trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.loginUser: container={1} - CALLED!", this.getClass().getSimpleName(), container)); //NOI18N - - // Check some beans - assert (this.userBean instanceof UserSessionBeanRemote) : "this.userBean is not set"; //NOI18N - assert (this.registerBean instanceof UserRegistrationSessionBeanRemote) : "this.registerBean is not set"; //NOI18N - - // user should not be null - if (null == container) { - // Abort here - throw new NullPointerException("container is null"); //NOI18N - } else if (container.getUser() == null) { - // NPE again - throw new NullPointerException("container.user is null"); //NOI18N - } else if (container.getUserPassword() == null) { - // And yet again NPE - throw new NullPointerException("container.userPassword is null"); //NOI18N - } else if (container.getUserPassword().isEmpty()) { - // Empty password is not allowed, hardcoded. - throw new IllegalArgumentException("container.userPassword is empty"); //NOI18N - } - - // Is the account there? - if (!this.registerBean.isUserNameRegistered(container.getUser())) { - // Not registered - throw new UserNotFoundException(container.getUser()); - } - - // Get user instance from persistance - User updatedUser = this.userBean.fillUserData(container.getUser()); - - // Debug message - this.getLoggerBeanLocal().logDebug(MessageFormat.format("loginUser: updatedUser={0}", updatedUser)); //NOI18N - - // Is the user account unconfirmed? - if (updatedUser.getUserAccountStatus().equals(UserAccountStatus.UNCONFIRMED)) { - // Is unconfirmed - throw new UserStatusUnconfirmedException(container.getUser()); - } else if (updatedUser.getUserAccountStatus().equals(UserAccountStatus.LOCKED)) { - // Is locked - throw new UserStatusLockedException(container.getUser()); - } else if (!this.isPasswordMatching(container, updatedUser)) { - // Not matcing passwords - throw new UserPasswordMismatchException(container.getUser()); - } - - // Trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.loginUser: updatedUser={1} - EXIT!", this.getClass().getSimpleName(), updatedUser)); //NOI18N - - // Return it - return updatedUser; - } - - /** - * Checks if password matches of both instances. Both user instances must - * not match, the first one is the one from the calling bean/controller, the - * second is the from database. - *

- * @param container Container instance holding the user instance and - * clear-text password - * @param updatedUser Updated user instance found for given user name - *

- * @return Whether the password matches - */ - private boolean isPasswordMatching (final LoginContainer container, final User updatedUser) { - // First math both instances - if (null == container) { - // Throw NPE - throw new NullPointerException("container is null"); //NOI18N - } else if (null == updatedUser) { - // Throw NPE - throw new NullPointerException("updatedUser is null"); //NOI18N - } else if (container.getUser().equals(updatedUser)) { - // Both same instance! - throw new IllegalArgumentException(MessageFormat.format("container.user matches updatedUser: {0}", container.getUser())); //NOI18N - } - - // Is it the same same password? - return UserUtils.ifPasswordMatches(container, updatedUser); - } - -} diff --git a/src/java/org/mxchange/jusercore/model/user/register/AddressbookUserRegistrationSessionBean.java b/src/java/org/mxchange/jusercore/model/user/register/AddressbookUserRegistrationSessionBean.java deleted file mode 100644 index 385111d..0000000 --- a/src/java/org/mxchange/jusercore/model/user/register/AddressbookUserRegistrationSessionBean.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (C) 2016, 2017 Roland Häder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -package org.mxchange.jusercore.model.user.register; - -import java.text.MessageFormat; -import java.util.Objects; -import javax.ejb.EJB; -import javax.ejb.Stateless; -import javax.persistence.NoResultException; -import javax.persistence.Query; -import org.mxchange.addressbook.database.BaseAddressbookDatabaseBean; -import org.mxchange.jcontacts.contact.Contact; -import org.mxchange.jusercore.exceptions.EmailAddressAlreadyRegisteredException; -import org.mxchange.jusercore.exceptions.UserNameAlreadyRegisteredException; -import org.mxchange.jusercore.model.user.AdminUserSessionBeanRemote; -import org.mxchange.jusercore.model.user.LoginUser; -import org.mxchange.jusercore.model.user.User; -import org.mxchange.jusercore.model.user.UserSessionBeanRemote; -import org.mxchange.jusercore.model.user.UserUtils; - -/** - * A session-scoped bean for user registration - *

- * @author Roland Häder - */ -@Stateless (name = "userRegistration", description = "A bean handling the user registration") -public class AddressbookUserRegistrationSessionBean extends BaseAddressbookDatabaseBean implements UserRegistrationSessionBeanRemote { - - /** - * Serial number - */ - private static final long serialVersionUID = 12_348_958_986_818_627L; - - /** - * Administrative user bean - */ - @EJB - private AdminUserSessionBeanRemote adminUserBean; - - /** - * Regular user EJB - */ - @EJB - private UserSessionBeanRemote userBean; - - /** - * Default constructor - */ - public AddressbookUserRegistrationSessionBean () { - // Call super constructor - super("jms/addressbook-queue-factory", "jms/addressbook-email-queue"); //NOI18N - } - - @Override - public String generateConfirmationKey (final User user) { - // Trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.generateConfirmationKey: user={1} - CALLED!", this.getClass().getSimpleName(), user)); //NOI18N - - // user should not be null - if (null == user) { - // Abort here - throw new NullPointerException("user is null"); //NOI18N - } - - // Create named instance - Query query = this.getEntityManager().createNamedQuery("SearchUserByConfirmKey", LoginUser.class); //NOI18N - - // Init confirmation key - String confirmationKey = null; - - // Find a free one - while (confirmationKey == null) { - // Create new one - String key = UserUtils.generatedConfirmationKey(user); - - // Set key as parameter - query.setParameter("confirmKey", key); //NOI18N - - // Try it - try { - // Get contact instance - Contact contact = (Contact) query.getSingleResult(); - - // Warning message - this.getLoggerBeanLocal().logWarning(MessageFormat.format("{0}.generateConfirmationKey: key {1} already found: contact.contactId={2}", this.getClass().getSimpleName(), key, contact.getContactId())); //NOI18N - } catch (final NoResultException ex) { - // Not found, normal case - confirmationKey = key; - break; - } - } - - // Log trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.generateConfirmationKey: confirmationKey={1} - EXIT!", this.getClass().getSimpleName(), confirmationKey)); //NOI18N - - // Return it - return confirmationKey; - } - - @Override - public boolean isEmailAddressRegistered (final User user) { - // Trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.isEmailAddressRegistered: user={1} - CALLED!", this.getClass().getSimpleName(), user)); //NOI18N - - // Check bean - assert (this.userBean instanceof UserSessionBeanRemote) : "this.userBean is not set"; //NOI18N - - // user should not be null - if (null == user) { - // Abort here - throw new NullPointerException("user is null"); //NOI18N - } - - // Call other bean - return this.userBean.isEmailAddressRegistered(user); - } - - @Override - public boolean isUserNameRegistered (final User user) { - // Trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.isUserNameRegistered: user={1} - CALLED!", this.getClass().getSimpleName(), user)); //NOI18N - - // Check bean - assert (this.userBean instanceof UserSessionBeanRemote) : "this.userBean is not set"; //NOI18N - - // user should not be null - if (null == user) { - // Abort here - throw new NullPointerException("user is null"); //NOI18N - } - - // Call other bean - return this.userBean.isUserNameRegistered(user); - } - - @Override - public User registerUser (final User user, final String baseUrl, final String randomPassword) throws UserNameAlreadyRegisteredException, EmailAddressAlreadyRegisteredException { - // Trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.registerUser: user={1},baseUrl={2},randomPassword[]={3} - CALLED!", this.getClass().getSimpleName(), user, baseUrl, Objects.toString(randomPassword))); //NOI18N - - // user should not be null - if (null == user) { - // Abort here - throw new NullPointerException("user is null"); //NOI18N - } else if (user.getUserContact() == null) { - // Throw NPE again - throw new NullPointerException("user.userContact is null"); //NOI18N - } else if (user.getUserContact().getContactEmailAddress() == null) { - // Throw NPE again - throw new NullPointerException("user.userContact.contactEmailAddress is null"); //NOI18N - } else if (user.getUserContact().getContactEmailAddress().isEmpty()) { - // Is empty - throw new IllegalArgumentException("user.userContact.contactEmailAddress is empty"); //NOI18N - } - - // Check if user is registered - if (this.isUserNameRegistered(user)) { - // Abort here - throw new UserNameAlreadyRegisteredException(user); - } else if (this.isEmailAddressRegistered(user)) { - // Abort here - throw new EmailAddressAlreadyRegisteredException(user); - } - - // Call other EJB - User addedUser = this.adminUserBean.addUser(user); - - // Default template is with no random password - String templateName = "user_registration"; //NOI18N - - // Is password set? - if ((randomPassword instanceof String) && (!randomPassword.isEmpty())) { - // Switch to other template - templateName = "user_registration_random"; //NOI18N - } - - // Send email - // @TODO: Internationlize the subject line somehow - this.sendEmail("Registration", templateName, addedUser, baseUrl, randomPassword); //NOI18N - - // Trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.registerUser: addedUser={1},addedUser.userId={2} - EXIT!", this.getClass().getSimpleName(), addedUser, addedUser.getUserId())); //NOI18N - - // Return it - return addedUser; - } - -} diff --git a/src/java/org/mxchange/jusercore/model/user/resendlink/AddressbookResendLinkSessionBean.java b/src/java/org/mxchange/jusercore/model/user/resendlink/AddressbookResendLinkSessionBean.java deleted file mode 100644 index e79147a..0000000 --- a/src/java/org/mxchange/jusercore/model/user/resendlink/AddressbookResendLinkSessionBean.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2016, 2017 Roland Häder - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -package org.mxchange.jusercore.model.user.resendlink; - -import java.text.MessageFormat; -import java.util.Locale; -import javax.ejb.EJB; -import javax.ejb.Stateless; -import org.mxchange.addressbook.database.BaseAddressbookDatabaseBean; -import org.mxchange.jusercore.exceptions.UserNotFoundException; -import org.mxchange.jusercore.exceptions.UserStatusConfirmedException; -import org.mxchange.jusercore.exceptions.UserStatusLockedException; -import org.mxchange.jusercore.model.user.LoginUser; -import org.mxchange.jusercore.model.user.User; -import org.mxchange.jusercore.model.user.UserSessionBeanRemote; -import org.mxchange.jusercore.model.user.register.UserRegistrationSessionBeanRemote; -import org.mxchange.jusercore.model.user.status.UserAccountStatus; - -/** - * A session-based EJB for resending confirmation links - *

- * @author Roland Häder - */ -@Stateless (name = "userResendConfirmationLink", description = "A bean resending confirmation links") -public class AddressbookResendLinkSessionBean extends BaseAddressbookDatabaseBean implements ResendLinkSessionBeanRemote { - - /** - * Serial number - */ - private static final long serialVersionUID = 71_546_726_857_195_360L; - - /** - * Registration bean - */ - @EJB - private UserRegistrationSessionBeanRemote registerBean; - - /** - * Regular user bean - */ - @EJB - private UserSessionBeanRemote userBean; - - /** - * Default constructor - */ - public AddressbookResendLinkSessionBean () { - // Call super constructor - super("jms/addressbook-queue-factory", "jms/addressbook-email-queue"); //NOI18N - } - - @Override - public User resendConfirmationLink (final User user, final Locale locale, final String baseUrl) throws UserNotFoundException, UserStatusConfirmedException, UserStatusLockedException { - // Log trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.resendConfirmationLink: user={1},locale={2},baseUrl={3} - CALLED!", this.getClass().getSimpleName(), user, locale, baseUrl)); //NOI18N - - // The user instance should be valid - if (null == user) { - // Throw NPE - throw new NullPointerException("user is null"); //NOI18N - } else if (user.getUserId() == null) { - // Throw NPE again - throw new NullPointerException("user.userId is null"); //NOI18N - } else if (user.getUserId() < 1) { - // Invalid id number - throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is not valid", user.getUserId())); //NOI18N - } else if (!this.userBean.ifUserExists(user)) { - // User not found - throw new UserNotFoundException(user); - } else if (user.getUserConfirmKey() == null) { - // Throw NPE again - throw new NullPointerException("this.userConfirmKey is null"); //NOI18N - } else if (user.getUserAccountStatus() == UserAccountStatus.CONFIRMED) { - // User account status is not UNCONFIRMED - throw new UserStatusConfirmedException(user); - } else if (user.getUserAccountStatus() == UserAccountStatus.LOCKED) { - // User account status is not UNCONFIRMED - throw new UserStatusLockedException(user); - } else if (null == locale) { - // Locale should be set - throw new NullPointerException("locale is null"); //NOI18N - } - - // Get new registration key - String confirmationKey = this.registerBean.generateConfirmationKey(user); - - // Debug message - this.getLoggerBeanLocal().logDebug(MessageFormat.format("{0}.resendConfirmationLink: confirmationKey={1}", this.getClass().getSimpleName(), confirmationKey)); //NOI18N - - // Get managed instance - User managedUser = this.getEntityManager().find(LoginUser.class, user.getUserId()); - - // Set it in user - managedUser.setUserConfirmKey(confirmationKey); - - // Send email - // @TODO: Internationlize the subject line somehow - this.sendEmail("Resend user confirmation link", "user_resend_confirmation_link", managedUser, baseUrl, null); //NOI18N - - // Log trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.resendConfirmationLink: managedUser={1} - EXIT!", this.getClass().getSimpleName(), managedUser)); //NOI18N - - // Return updated instance - return managedUser; - } - -} diff --git a/src/java/org/mxchange/juserlogincore/model/user/login/FinancialsUserLoginSessionBean.java b/src/java/org/mxchange/juserlogincore/model/user/login/FinancialsUserLoginSessionBean.java new file mode 100644 index 0000000..99fb347 --- /dev/null +++ b/src/java/org/mxchange/juserlogincore/model/user/login/FinancialsUserLoginSessionBean.java @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2016, 2017 Roland Häder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.mxchange.juserlogincore.model.user.login; + +import java.text.MessageFormat; +import javax.ejb.EJB; +import javax.ejb.Stateless; +import org.mxchange.addressbook.database.BaseAddressbookDatabaseBean; +import org.mxchange.jusercore.exceptions.UserNotFoundException; +import org.mxchange.jusercore.exceptions.UserStatusLockedException; +import org.mxchange.jusercore.exceptions.UserStatusUnconfirmedException; +import org.mxchange.jusercore.model.user.User; +import org.mxchange.jusercore.model.user.UserSessionBeanRemote; +import org.mxchange.jusercore.model.user.status.UserAccountStatus; +import org.mxchange.juserlogincore.container.login.LoginContainer; +import org.mxchange.juserlogincore.exceptions.UserPasswordMismatchException; +import org.mxchange.juserlogincore.login.UserLoginUtils; +import org.mxchange.juserlogincore.model.login.user.UserLoginSessionBeanRemote; +import org.mxchange.juserlogincore.model.user.register.UserRegistrationSessionBeanRemote; + +/** + * A session EJB for user logins + *

+ * @author Roland Häder + */ +@Stateless (name = "userLogin", description = "A bean handling the user login for Financials project") +public class FinancialsUserLoginSessionBean extends BaseAddressbookDatabaseBean implements UserLoginSessionBeanRemote { + + /** + * Serial number + */ + private static final long serialVersionUID = 21_785_978_127_581_965L; + + /** + * Registration EJB + */ + @EJB + private UserRegistrationSessionBeanRemote registerBean; + + /** + * User EJB + */ + @EJB + private UserSessionBeanRemote userBean; + + /** + * Default constructor + */ + public FinancialsUserLoginSessionBean () { + // Call super constructor + super(); + } + + @Override + public User validateUserAccountStatus (final LoginContainer container) throws UserNotFoundException, UserStatusLockedException, UserStatusUnconfirmedException, UserPasswordMismatchException { + // Trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.loginUser: container={1} - CALLED!", this.getClass().getSimpleName(), container)); //NOI18N + + // Check some beans + assert (this.userBean instanceof UserSessionBeanRemote) : "this.userBean is not set"; //NOI18N + assert (this.registerBean instanceof UserRegistrationSessionBeanRemote) : "this.registerBean is not set"; //NOI18N + + // user should not be null + if (null == container) { + // Abort here + throw new NullPointerException("container is null"); //NOI18N + } else if (container.getUser() == null) { + // NPE again + throw new NullPointerException("container.user is null"); //NOI18N + } else if (container.getUserPassword() == null) { + // And yet again NPE + throw new NullPointerException("container.userPassword is null"); //NOI18N + } else if (container.getUserPassword().isEmpty()) { + // Empty password is not allowed, hardcoded. + throw new IllegalArgumentException("container.userPassword is empty"); //NOI18N + } + + // Is the account there? + if (!this.registerBean.isUserNameRegistered(container.getUser())) { + // Not registered + throw new UserNotFoundException(container.getUser()); + } + + // Get user instance from persistance + User updatedUser = this.userBean.fillUserData(container.getUser()); + + // Debug message + this.getLoggerBeanLocal().logDebug(MessageFormat.format("loginUser: updatedUser={0}", updatedUser)); //NOI18N + + // Is the user account unconfirmed? + if (updatedUser.getUserAccountStatus().equals(UserAccountStatus.UNCONFIRMED)) { + // Is unconfirmed + throw new UserStatusUnconfirmedException(container.getUser()); + } else if (updatedUser.getUserAccountStatus().equals(UserAccountStatus.LOCKED)) { + // Is locked + throw new UserStatusLockedException(container.getUser()); + } else if (!this.isPasswordMatching(container, updatedUser)) { + // Not matcing passwords + throw new UserPasswordMismatchException(container.getUser()); + } + + // Trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.loginUser: updatedUser={1} - EXIT!", this.getClass().getSimpleName(), updatedUser)); //NOI18N + + // Return it + return updatedUser; + } + + /** + * Checks if password matches of both instances. Both user instances must + * not match, the first one is the one from the calling bean/controller, the + * second is the from database. + *

+ * @param container Container instance holding the user instance and + * clear-text password + * @param updatedUser Updated user instance found for given user name + *

+ * @return Whether the password matches + */ + private boolean isPasswordMatching (final LoginContainer container, final User updatedUser) { + // First math both instances + if (null == container) { + // Throw NPE + throw new NullPointerException("container is null"); //NOI18N + } else if (null == updatedUser) { + // Throw NPE + throw new NullPointerException("updatedUser is null"); //NOI18N + } else if (container.getUser().equals(updatedUser)) { + // Both same instance! + throw new IllegalArgumentException(MessageFormat.format("container.user matches updatedUser: {0}", container.getUser())); //NOI18N + } + + // Is it the same same password? + return UserLoginUtils.ifPasswordMatches(container, updatedUser); + } + +} diff --git a/src/java/org/mxchange/juserlogincore/model/user/register/AddressbookUserRegistrationSessionBean.java b/src/java/org/mxchange/juserlogincore/model/user/register/AddressbookUserRegistrationSessionBean.java new file mode 100644 index 0000000..60bade0 --- /dev/null +++ b/src/java/org/mxchange/juserlogincore/model/user/register/AddressbookUserRegistrationSessionBean.java @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2016, 2017 Roland Häder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.mxchange.juserlogincore.model.user.register; + +import java.text.MessageFormat; +import java.util.Objects; +import javax.ejb.EJB; +import javax.ejb.Stateless; +import javax.persistence.NoResultException; +import javax.persistence.Query; +import org.mxchange.addressbook.database.BaseAddressbookDatabaseBean; +import org.mxchange.jcontacts.contact.Contact; +import org.mxchange.jusercore.exceptions.EmailAddressAlreadyRegisteredException; +import org.mxchange.jusercore.exceptions.UserNameAlreadyRegisteredException; +import org.mxchange.jusercore.model.user.AdminUserSessionBeanRemote; +import org.mxchange.jusercore.model.user.LoginUser; +import org.mxchange.jusercore.model.user.User; +import org.mxchange.jusercore.model.user.UserSessionBeanRemote; +import org.mxchange.juserlogincore.login.UserLoginUtils; + +/** + * A session-scoped bean for user registration + *

+ * @author Roland Häder + */ +@Stateless (name = "userRegistration", description = "A bean handling the user registration") +public class AddressbookUserRegistrationSessionBean extends BaseAddressbookDatabaseBean implements UserRegistrationSessionBeanRemote { + + /** + * Serial number + */ + private static final long serialVersionUID = 12_348_958_986_818_627L; + + /** + * Administrative user bean + */ + @EJB + private AdminUserSessionBeanRemote adminUserBean; + + /** + * Regular user EJB + */ + @EJB + private UserSessionBeanRemote userBean; + + /** + * Default constructor + */ + public AddressbookUserRegistrationSessionBean () { + // Call super constructor + super("jms/addressbook-queue-factory", "jms/addressbook-email-queue"); //NOI18N + } + + @Override + public String generateConfirmationKey (final User user) { + // Trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.generateConfirmationKey: user={1} - CALLED!", this.getClass().getSimpleName(), user)); //NOI18N + + // user should not be null + if (null == user) { + // Abort here + throw new NullPointerException("user is null"); //NOI18N + } + + // Create named instance + Query query = this.getEntityManager().createNamedQuery("SearchUserByConfirmKey", LoginUser.class); //NOI18N + + // Init confirmation key + String confirmationKey = null; + + // Find a free one + while (confirmationKey == null) { + // Create new one + String key = UserLoginUtils.generatedConfirmationKey(user); + + // Set key as parameter + query.setParameter("confirmKey", key); //NOI18N + + // Try it + try { + // Get contact instance + Contact contact = (Contact) query.getSingleResult(); + + // Warning message + this.getLoggerBeanLocal().logWarning(MessageFormat.format("{0}.generateConfirmationKey: key {1} already found: contact.contactId={2}", this.getClass().getSimpleName(), key, contact.getContactId())); //NOI18N + } catch (final NoResultException ex) { + // Not found, normal case + confirmationKey = key; + break; + } + } + + // Log trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.generateConfirmationKey: confirmationKey={1} - EXIT!", this.getClass().getSimpleName(), confirmationKey)); //NOI18N + + // Return it + return confirmationKey; + } + + @Override + public boolean isEmailAddressRegistered (final User user) { + // Trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.isEmailAddressRegistered: user={1} - CALLED!", this.getClass().getSimpleName(), user)); //NOI18N + + // Check bean + assert (this.userBean instanceof UserSessionBeanRemote) : "this.userBean is not set"; //NOI18N + + // user should not be null + if (null == user) { + // Abort here + throw new NullPointerException("user is null"); //NOI18N + } + + // Call other bean + return this.userBean.isEmailAddressRegistered(user); + } + + @Override + public boolean isUserNameRegistered (final User user) { + // Trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.isUserNameRegistered: user={1} - CALLED!", this.getClass().getSimpleName(), user)); //NOI18N + + // Check bean + assert (this.userBean instanceof UserSessionBeanRemote) : "this.userBean is not set"; //NOI18N + + // user should not be null + if (null == user) { + // Abort here + throw new NullPointerException("user is null"); //NOI18N + } + + // Call other bean + return this.userBean.isUserNameRegistered(user); + } + + @Override + public User registerUser (final User user, final String baseUrl, final String randomPassword) throws UserNameAlreadyRegisteredException, EmailAddressAlreadyRegisteredException { + // Trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.registerUser: user={1},baseUrl={2},randomPassword[]={3} - CALLED!", this.getClass().getSimpleName(), user, baseUrl, Objects.toString(randomPassword))); //NOI18N + + // user should not be null + if (null == user) { + // Abort here + throw new NullPointerException("user is null"); //NOI18N + } else if (user.getUserContact() == null) { + // Throw NPE again + throw new NullPointerException("user.userContact is null"); //NOI18N + } else if (user.getUserContact().getContactEmailAddress() == null) { + // Throw NPE again + throw new NullPointerException("user.userContact.contactEmailAddress is null"); //NOI18N + } else if (user.getUserContact().getContactEmailAddress().isEmpty()) { + // Is empty + throw new IllegalArgumentException("user.userContact.contactEmailAddress is empty"); //NOI18N + } + + // Check if user is registered + if (this.isUserNameRegistered(user)) { + // Abort here + throw new UserNameAlreadyRegisteredException(user); + } else if (this.isEmailAddressRegistered(user)) { + // Abort here + throw new EmailAddressAlreadyRegisteredException(user); + } + + // Call other EJB + User addedUser = this.adminUserBean.addUser(user); + + // Default template is with no random password + String templateName = "user_registration"; //NOI18N + + // Is password set? + if ((randomPassword instanceof String) && (!randomPassword.isEmpty())) { + // Switch to other template + templateName = "user_registration_random"; //NOI18N + } + + // Send email + // @TODO: Internationlize the subject line somehow + this.sendEmail("Registration", templateName, addedUser, baseUrl, randomPassword); //NOI18N + + // Trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.registerUser: addedUser={1},addedUser.userId={2} - EXIT!", this.getClass().getSimpleName(), addedUser, addedUser.getUserId())); //NOI18N + + // Return it + return addedUser; + } + +} diff --git a/src/java/org/mxchange/juserlogincore/model/user/resendlink/AddressbookResendLinkSessionBean.java b/src/java/org/mxchange/juserlogincore/model/user/resendlink/AddressbookResendLinkSessionBean.java new file mode 100644 index 0000000..77d5f44 --- /dev/null +++ b/src/java/org/mxchange/juserlogincore/model/user/resendlink/AddressbookResendLinkSessionBean.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2016, 2017 Roland Häder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.mxchange.juserlogincore.model.user.resendlink; + +import java.text.MessageFormat; +import java.util.Locale; +import javax.ejb.EJB; +import javax.ejb.Stateless; +import org.mxchange.addressbook.database.BaseAddressbookDatabaseBean; +import org.mxchange.jusercore.exceptions.UserNotFoundException; +import org.mxchange.jusercore.exceptions.UserStatusConfirmedException; +import org.mxchange.jusercore.exceptions.UserStatusLockedException; +import org.mxchange.jusercore.model.user.LoginUser; +import org.mxchange.jusercore.model.user.User; +import org.mxchange.jusercore.model.user.UserSessionBeanRemote; +import org.mxchange.jusercore.model.user.status.UserAccountStatus; +import org.mxchange.juserlogincore.model.user.register.UserRegistrationSessionBeanRemote; + +/** + * A session-based EJB for resending confirmation links + *

+ * @author Roland Häder + */ +@Stateless (name = "userResendConfirmationLink", description = "A bean resending confirmation links") +public class AddressbookResendLinkSessionBean extends BaseAddressbookDatabaseBean implements ResendLinkSessionBeanRemote { + + /** + * Serial number + */ + private static final long serialVersionUID = 71_546_726_857_195_360L; + + /** + * Registration bean + */ + @EJB + private UserRegistrationSessionBeanRemote registerBean; + + /** + * Regular user bean + */ + @EJB + private UserSessionBeanRemote userBean; + + /** + * Default constructor + */ + public AddressbookResendLinkSessionBean () { + // Call super constructor + super("jms/addressbook-queue-factory", "jms/addressbook-email-queue"); //NOI18N + } + + @Override + public User resendConfirmationLink (final User user, final Locale locale, final String baseUrl) throws UserNotFoundException, UserStatusConfirmedException, UserStatusLockedException { + // Log trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.resendConfirmationLink: user={1},locale={2},baseUrl={3} - CALLED!", this.getClass().getSimpleName(), user, locale, baseUrl)); //NOI18N + + // The user instance should be valid + if (null == user) { + // Throw NPE + throw new NullPointerException("user is null"); //NOI18N + } else if (user.getUserId() == null) { + // Throw NPE again + throw new NullPointerException("user.userId is null"); //NOI18N + } else if (user.getUserId() < 1) { + // Invalid id number + throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is not valid", user.getUserId())); //NOI18N + } else if (!this.userBean.ifUserExists(user)) { + // User not found + throw new UserNotFoundException(user); + } else if (user.getUserConfirmKey() == null) { + // Throw NPE again + throw new NullPointerException("this.userConfirmKey is null"); //NOI18N + } else if (user.getUserAccountStatus() == UserAccountStatus.CONFIRMED) { + // User account status is not UNCONFIRMED + throw new UserStatusConfirmedException(user); + } else if (user.getUserAccountStatus() == UserAccountStatus.LOCKED) { + // User account status is not UNCONFIRMED + throw new UserStatusLockedException(user); + } else if (null == locale) { + // Locale should be set + throw new NullPointerException("locale is null"); //NOI18N + } + + // Get new registration key + String confirmationKey = this.registerBean.generateConfirmationKey(user); + + // Debug message + this.getLoggerBeanLocal().logDebug(MessageFormat.format("{0}.resendConfirmationLink: confirmationKey={1}", this.getClass().getSimpleName(), confirmationKey)); //NOI18N + + // Get managed instance + User managedUser = this.getEntityManager().find(LoginUser.class, user.getUserId()); + + // Set it in user + managedUser.setUserConfirmKey(confirmationKey); + + // Send email + // @TODO: Internationlize the subject line somehow + this.sendEmail("Resend user confirmation link", "user_resend_confirmation_link", managedUser, baseUrl, null); //NOI18N + + // Log trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.resendConfirmationLink: managedUser={1} - EXIT!", this.getClass().getSimpleName(), managedUser)); //NOI18N + + // Return updated instance + return managedUser; + } + +}