From: Roland Häder Date: Thu, 22 Jun 2017 20:55:38 +0000 (+0200) Subject: Please cherry-pick: X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=29d62f6f70bd7cdc474394a20d144f60bbd0ea7e;p=jfinancials-mailer-ejb.git Please cherry-pick: - moved EJBs to proper package as they are user-related beans - handled over randomPassword parameter to sendEmail() - or null if not possible/wanted Signed-off-by: Roland Häder --- diff --git a/src/java/org/mxchange/addressbook/beans/resendlink/AddressbookResendLinkSessionBean.java b/src/java/org/mxchange/addressbook/beans/resendlink/AddressbookResendLinkSessionBean.java deleted file mode 100644 index 08cc740..0000000 --- a/src/java/org/mxchange/addressbook/beans/resendlink/AddressbookResendLinkSessionBean.java +++ /dev/null @@ -1,131 +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.addressbook.beans.resendlink; - -import java.text.MessageFormat; -import java.util.Locale; -import javax.ejb.EJB; -import javax.ejb.EJBException; -import javax.ejb.Stateless; -import javax.mail.Address; -import javax.mail.internet.AddressException; -import javax.mail.internet.InternetAddress; -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.register.UserRegistrationSessionBeanRemote; -import org.mxchange.jusercore.model.resendlink.ResendLinkSessionBeanRemote; -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; - -/** - * A session-based EJB for resending confirmation links - *

- * @author Roland Häder - */ -@Stateless (name = "resendLink", 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(); - } - - @Override - public void 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); - - // Get managed instance - User managedUser = this.getEntityManager().find(LoginUser.class, user.getUserId()); - - // Set it in user - managedUser.setUserConfirmKey(confirmationKey); - - // Init variable - Address emailAddress; - - try { - // Create email address and set - emailAddress = new InternetAddress(managedUser.getUserContact().getContactEmailAddress()); - } catch (final AddressException ex) { - // Throw again - throw new EJBException(ex); - } - - // Send email - // @TODO: Internationlize the subject line somehow - this.sendEmail("Resend confirmation link", "resend_confirmation_link", emailAddress, user, baseUrl); //NOI18N - - // Log trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.resendConfirmationLink: EXIT!", this.getClass().getSimpleName())); //NOI18N - } - -} diff --git a/src/java/org/mxchange/jcontacts/contact/AddressbookContactSessionBean.java b/src/java/org/mxchange/jcontacts/contact/AddressbookContactSessionBean.java index b39bc76..61dd937 100644 --- a/src/java/org/mxchange/jcontacts/contact/AddressbookContactSessionBean.java +++ b/src/java/org/mxchange/jcontacts/contact/AddressbookContactSessionBean.java @@ -24,7 +24,6 @@ import javax.ejb.Stateless; import javax.persistence.NoResultException; import javax.persistence.Query; import org.mxchange.addressbook.database.BaseAddressbookDatabaseBean; -import org.mxchange.jcontacts.contact.utils.ContactUtils; import org.mxchange.jcontacts.exceptions.ContactNotFoundException; /** diff --git a/src/java/org/mxchange/jusercore/model/email_address/AddressbookUserEmailChangeSessionBean.java b/src/java/org/mxchange/jusercore/model/email_address/AddressbookUserEmailChangeSessionBean.java deleted file mode 100644 index db07376..0000000 --- a/src/java/org/mxchange/jusercore/model/email_address/AddressbookUserEmailChangeSessionBean.java +++ /dev/null @@ -1,249 +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.email_address; - -import java.text.MessageFormat; -import java.util.GregorianCalendar; -import java.util.List; -import javax.ejb.EJB; -import javax.ejb.EJBException; -import javax.ejb.Stateless; -import javax.mail.Address; -import javax.mail.internet.AddressException; -import javax.mail.internet.InternetAddress; -import javax.persistence.NoResultException; -import javax.persistence.Query; -import org.mxchange.addressbook.database.BaseAddressbookDatabaseBean; -import org.mxchange.jusercore.model.user.UserSessionBeanRemote; -import org.mxchange.jusercore.model.user.UserUtils; - -/** - * A session-scoped bean for changing email addresses - *

- * @author Roland Häder - */ -@Stateless (name = "userEmailChange", description = "A bean handling user email changes") -public class AddressbookUserEmailChangeSessionBean extends BaseAddressbookDatabaseBean implements UserEmailChangeSessionBeanRemote { - - /** - * Serial number - */ - private static final long serialVersionUID = 182_698_165_971_548L; - - /** - * User bean - */ - @EJB - private UserSessionBeanRemote userBean; - - /** - * Default constructor - */ - public AddressbookUserEmailChangeSessionBean () { - // Call super constructor - super(); - } - - @Override - @SuppressWarnings ("unchecked") - public List allQueuedAddresses () { - // Trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.allQueuedAddresses: CALLED!", this.getClass().getSimpleName())); //NOI18N - - // Get named query - Query query = this.getEntityManager().createNamedQuery("AllEmailAddressChanges", String.class); //NOI18N - - // Get all entries - List emailAddresses = query.getResultList(); - - // Trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.allQueuedAddresses: emailAddresses.size()={1} - EXIT!", this.getClass().getSimpleName(), emailAddresses.size())); //NOI18N - - // Return it - return emailAddresses; - } - - @Override - public void enqueueEmailAddressForChange (final ChangeableEmailAddress emailChange, final String baseUrl) { - // Trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.enqueueEmailAddressForChange: emailChange={1},baseUrl={2} - CALLED!", this.getClass().getSimpleName(), emailChange, baseUrl)); //NOI18N - - // Email address change should be valid - if (null == emailChange) { - // Abort here - throw new NullPointerException("emailChange is null"); //NOI18N - } else if (emailChange.getEmailChangeUser() == null) { - // Throw NPE again - throw new NullPointerException("emailChange.emailChangeUser is null"); //NOI18N - } else if (emailChange.getEmailChangeUser().getUserId() == null) { - // Throw NPE again - throw new NullPointerException("emailChange.emailChangeUser.userId is null"); //NOI18N - } else if (emailChange.getEmailChangeUser().getUserId() < 1) { - // Not valid id - throw new IllegalArgumentException(MessageFormat.format("emailChange.emailChangeUser.userId={0} is invalid.", emailChange.getEmailChangeUser().getUserId())); //NOI18N - } else if (!this.userBean.ifUserExists(emailChange.getEmailChangeUser())) { - // User does not exist - throw new EJBException(MessageFormat.format("Email change with id {0} does not exist.", emailChange.getEmailChangeId())); //NOI18N - } else if (emailChange.getEmailAddress().trim().isEmpty()) { - // Email address is empty - throw new IllegalArgumentException("emailChange.emaiLAddress is empty."); //NOI18N - } else if (this.isEmailAddressEnqueued(emailChange.getEmailAddress())) { - // Email address is already enqueued - throw new EJBException(MessageFormat.format("Email address {0} is already enqueued.", emailChange.getEmailAddress())); //NOI18N - } - - // The email change is not (yet) there, add secure hash and "created" timestamp - emailChange.setEmailChangeCreated(new GregorianCalendar()); - this.generateSecureHash(emailChange); - - // Make user managed - emailChange.setEmailChangeUser(this.getManagedUser(emailChange.getEmailChangeUser())); - - // Persist it - //@TODO Fix email delivery then allow this: this.getEntityManager().persist(emailChange); - // Init variable - Address emailAddress; - - try { - // Create email address and set - emailAddress = new InternetAddress(emailChange.getEmailAddress()); - } catch (final AddressException ex) { - // Throw again - throw new EJBException(ex); - } - - // Send email - this.sendEmail("Email change", "email_change", emailAddress, emailChange.getEmailChangeUser(), baseUrl); //NOI18N - - // Trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.enqueueEmailAddressForChange - EXIT!", this.getClass().getSimpleName())); //NOI18N - } - - @Override - public boolean isEmailAddressEnqueued (final String emailAddress) { - // Trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.isEmailAddressEnqueued: emailAddress={1} - CALLED!", this.getClass().getSimpleName(), emailAddress)); //NOI18N - - // Create query instance - Query query = this.getEntityManager().createNamedQuery("SearchEmailChangeByEmail"); //NOI18N - - // Add email address as parameter - query.setParameter("email", emailAddress); //NOI18N - - // Initialize variable - boolean isFound = false; - - // Try it - try { - // Try to get single result - ChangeableEmailAddress dummy = (ChangeableEmailAddress) query.getSingleResult(); - - // Found it - isFound = true; - } catch (final NoResultException ex) { - // Log it - this.getLoggerBeanLocal().logException(ex); - } - - // Trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.isEmailAddressEnqueued: isFound={1} - EXIT!", this.getClass().getSimpleName(), isFound)); //NOI18N - - // Return it - return isFound; - } - - @Override - public void updateEmailAddress (final ChangeableEmailAddress emailAddress) { - // Trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.updateEmailAddress: emailAddress={1} - CALLED!", this.getClass().getSimpleName(), emailAddress)); //NOI18N - - // Email address change should be valid - if (null == emailAddress) { - // Abort here - throw new NullPointerException("emailAddress is null"); //NOI18N - } else if (emailAddress.getEmailChangeId() == null) { - // Throw NPE again - throw new NullPointerException("emailAddress.emailChangeId is null"); //NOI18N - } else if (emailAddress.getEmailChangeId() < 1) { - // Not valid - throw new IllegalArgumentException(MessageFormat.format("emailAddress.emailChangeId={0} is not valid.", emailAddress.getEmailChangeId())); //NOI18N - } else if (emailAddress.getEmailAddress().trim().isEmpty()) { - // Email address is empty - throw new IllegalArgumentException("emailAddress.emaiLAddress is empty."); //NOI18N - } else if (!this.userBean.ifUserExists(emailAddress.getEmailChangeUser())) { - // User does not exist - throw new EJBException(MessageFormat.format("Email change with id {0} does not exist.", emailAddress.getEmailChangeId())); //NOI18N - } else if (!this.isEmailAddressEnqueued(emailAddress.getEmailAddress())) { - // Email address is not enqueued - throw new EJBException(MessageFormat.format("Email address {0} is not enqueued.", emailAddress.getEmailAddress())); //NOI18N - } - - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - /** - * Generates a secure, unique hash for given email address change. This - * requires to check if the hash is really not there. - *

- * @param emailAddressChange Email address change - */ - private void generateSecureHash (final ChangeableEmailAddress emailAddressChange) { - // Email address change should be valid - if (null == emailAddressChange) { - // Abort here - throw new NullPointerException("emailAddressChange is null"); //NOI18N - } else if (emailAddressChange.getEmailAddress().trim().isEmpty()) { - // Email address is empty - throw new IllegalArgumentException("emailAddressChange.emaiLAddress is empty."); //NOI18N - } - - // Initialize loop with null - String hash = null; - - // Default is not used - boolean isUsed = true; - - // 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", emailAddressChange.getEmailAddress(), emailAddressChange.toString())); //NOI18N - - // The hash *may* be unique, better test it - Query query = this.getEntityManager().createNamedQuery("SearchEmailChangeByHash", EmailAddressChange.class); //NOI18N - - // Set hash as parameter - query.setParameter("hash", hash); //NOI18N - - // Try to get single result - try { - // Get single result - ChangeableEmailAddress dummy = (ChangeableEmailAddress) query.getSingleResult(); - } catch (final NoResultException ex) { - // Not found - isUsed = false; - } - } - - // hash should not be null and set - assert (hash != null) : "hash is null"; //NOI18N - assert (!hash.isEmpty()) : "hash is empty"; //NOI18N - - // Set it in email change - emailAddressChange.setEmailChangeHash(hash); - } - -} diff --git a/src/java/org/mxchange/jusercore/model/login/AddressbookUserLoginSessionBean.java b/src/java/org/mxchange/jusercore/model/login/AddressbookUserLoginSessionBean.java index c33ba5f..3802daa 100644 --- a/src/java/org/mxchange/jusercore/model/login/AddressbookUserLoginSessionBean.java +++ b/src/java/org/mxchange/jusercore/model/login/AddressbookUserLoginSessionBean.java @@ -25,7 +25,7 @@ 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.register.UserRegistrationSessionBeanRemote; +import org.mxchange.jusercore.model.user.register.UserRegistrationSessionBeanRemote; import org.mxchange.jusercore.model.user.User; import org.mxchange.jusercore.model.user.UserSessionBeanRemote; import org.mxchange.jusercore.model.user.UserUtils; diff --git a/src/java/org/mxchange/jusercore/model/register/AddressbookUserRegistrationSessionBean.java b/src/java/org/mxchange/jusercore/model/register/AddressbookUserRegistrationSessionBean.java deleted file mode 100644 index ff98ffc..0000000 --- a/src/java/org/mxchange/jusercore/model/register/AddressbookUserRegistrationSessionBean.java +++ /dev/null @@ -1,207 +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.register; - -import java.text.MessageFormat; -import javax.ejb.EJB; -import javax.ejb.EJBException; -import javax.ejb.Stateless; -import javax.mail.Address; -import javax.mail.internet.AddressException; -import javax.mail.internet.InternetAddress; -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 = "register", 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(); - } - - @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) throws UserNameAlreadyRegisteredException, EmailAddressAlreadyRegisteredException { - // Trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.registerUser: user={1},baseUrl={2} - CALLED!", this.getClass().getSimpleName(), user, baseUrl)); //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); - - // Init variable - Address emailAddress; - - try { - // Create email address and set - emailAddress = new InternetAddress(addedUser.getUserContact().getContactEmailAddress()); - } catch (final AddressException ex) { - // Throw again - throw new EJBException(ex); - } - - // Send email - // @TODO: Internationlize the subject line somehow - this.sendEmail("Registration", "registration", emailAddress, addedUser, baseUrl); //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/AddressbookAdminUserSessionBean.java b/src/java/org/mxchange/jusercore/model/user/AddressbookAdminUserSessionBean.java index 664a0b0..fa2ca78 100644 --- a/src/java/org/mxchange/jusercore/model/user/AddressbookAdminUserSessionBean.java +++ b/src/java/org/mxchange/jusercore/model/user/AddressbookAdminUserSessionBean.java @@ -32,7 +32,7 @@ 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.register.UserRegistrationSessionBeanRemote; +import org.mxchange.jusercore.model.user.register.UserRegistrationSessionBeanRemote; import org.mxchange.jusercore.model.user.status.UserAccountStatus; /** @@ -279,7 +279,7 @@ public class AddressbookAdminUserSessionBean extends BaseAddressbookDatabaseBean // Send out email // @TODO externalize subject line - this.sendEmail("Account locked", "account_locked", emailAddress, managedUser, baseUrl); //NOI18N + this.sendEmail("User account locked", "user_account_locked", emailAddress, managedUser, baseUrl, null); //NOI18N // Trace message this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.lockUserAccount: managedUser={1} - EXIT!", this.getClass().getSimpleName(), managedUser)); //NOI18N @@ -349,7 +349,7 @@ public class AddressbookAdminUserSessionBean extends BaseAddressbookDatabaseBean // Send out email // @TODO externalize subject line - this.sendEmail("Account unlocked", "account_unlocked", emailAddress, managedUser, baseUrl); //NOI18N + this.sendEmail("User account unlocked", "user_account_unlocked", emailAddress, managedUser, baseUrl, null); //NOI18N // Trace message this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.lockUserAccount: managedUser={1} - EXIT!", this.getClass().getSimpleName(), managedUser)); //NOI18N diff --git a/src/java/org/mxchange/jusercore/model/user/AddressbookUserSessionBean.java b/src/java/org/mxchange/jusercore/model/user/AddressbookUserSessionBean.java index 33ac6a3..33db348 100644 --- a/src/java/org/mxchange/jusercore/model/user/AddressbookUserSessionBean.java +++ b/src/java/org/mxchange/jusercore/model/user/AddressbookUserSessionBean.java @@ -30,6 +30,7 @@ import javax.persistence.PersistenceException; import javax.persistence.Query; import org.mxchange.addressbook.database.BaseAddressbookDatabaseBean; import org.mxchange.jcontacts.contact.Contact; +import org.mxchange.jcontacts.contact.ContactUtils; import org.mxchange.jphone.phonenumbers.fax.DialableFaxNumber; import org.mxchange.jphone.phonenumbers.landline.DialableLandLineNumber; import org.mxchange.jphone.phonenumbers.mobile.DialableMobileNumber; @@ -37,10 +38,10 @@ 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.register.UserRegistrationSessionBeanRemote; 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; /** @@ -188,7 +189,7 @@ public class AddressbookUserSessionBean extends BaseAddressbookDatabaseBean impl } // Send out email - this.sendEmail("Account confirmed", "account_confirmed", emailAddress, updatedUser, baseUrl); //NOI18N + this.sendEmail("User account confirmed", "user_account_confirmed", emailAddress, updatedUser, baseUrl, null); //NOI18N // Trace message this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.confirmAccount: updatedUser={1} - EXIT!", this.getClass().getSimpleName(), updatedUser)); //NOI18N @@ -587,7 +588,7 @@ public class AddressbookUserSessionBean extends BaseAddressbookDatabaseBean impl assert (managedUser instanceof User) : MessageFormat.format("User with id {0} not found, but should be.", user.getUserId()); //NOI18N // Copy all data - managedUser.copyAll(user); + UserUtils.copyAll(user, managedUser); // Set as updated managedUser.setUserUpdated(new GregorianCalendar()); @@ -667,7 +668,7 @@ public class AddressbookUserSessionBean extends BaseAddressbookDatabaseBean impl } // Send email to user - this.sendEmail("User password change", "user_password_change", emailAddress, user, baseUrl); //NOI18N + this.sendEmail("User password change", "user_password_change", emailAddress, user, baseUrl, null); //NOI18N // Trace message this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.updateUserPassword: entry.userPasswordHistoryId={1} - EXIT!", this.getClass().getSimpleName(), entry.getUserPasswordHistoryId())); //NOI18N @@ -706,7 +707,7 @@ public class AddressbookUserSessionBean extends BaseAddressbookDatabaseBean impl assert (managedUser instanceof User) : MessageFormat.format("User with id {0} not found, but should be.", user.getUserId()); //NOI18N // Copy all data - managedUser.copyAll(user); + UserUtils.copyAll(user, managedUser); // Set as updated managedUser.setUserUpdated(new GregorianCalendar()); @@ -722,7 +723,7 @@ public class AddressbookUserSessionBean extends BaseAddressbookDatabaseBean impl this.getLoggerBeanLocal().logDebug(MessageFormat.format("updateUserPersonalData: managedContact.contactId={0}", managedContact.getContactId())); //NOI18N // Copy all - managedContact.copyAll(user.getUserContact()); + ContactUtils.copyAll(user.getUserContact(), managedContact); // Set it back in user user.setUserContact(managedContact); 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 new file mode 100644 index 0000000..bcfd656 --- /dev/null +++ b/src/java/org/mxchange/jusercore/model/user/email_address/AddressbookUserEmailChangeSessionBean.java @@ -0,0 +1,249 @@ +/* + * 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.email_address; + +import java.text.MessageFormat; +import java.util.GregorianCalendar; +import java.util.List; +import javax.ejb.EJB; +import javax.ejb.EJBException; +import javax.ejb.Stateless; +import javax.mail.Address; +import javax.mail.internet.AddressException; +import javax.mail.internet.InternetAddress; +import javax.persistence.NoResultException; +import javax.persistence.Query; +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.email_address.UserEmailChangeSessionBeanRemote; +import org.mxchange.jusercore.model.user.UserSessionBeanRemote; +import org.mxchange.jusercore.model.user.UserUtils; + +/** + * A session-scoped bean for changing email addresses + *

+ * @author Roland Häder + */ +@Stateless (name = "userEmailChange", description = "A bean handling user email changes") +public class AddressbookUserEmailChangeSessionBean extends BaseAddressbookDatabaseBean implements UserEmailChangeSessionBeanRemote { + + /** + * Serial number + */ + private static final long serialVersionUID = 182_698_165_971_548L; + + /** + * User bean + */ + @EJB + private UserSessionBeanRemote userBean; + + /** + * Default constructor + */ + public AddressbookUserEmailChangeSessionBean () { + // Call super constructor + super(); + } + + @Override + @SuppressWarnings ("unchecked") + public List allQueuedAddresses () { + // Trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.allQueuedAddresses: CALLED!", this.getClass().getSimpleName())); //NOI18N + + // Get named query + Query query = this.getEntityManager().createNamedQuery("AllEmailAddressChanges", String.class); //NOI18N + + // Get all entries + List emailAddresses = query.getResultList(); + + // Trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.allQueuedAddresses: emailAddresses.size()={1} - EXIT!", this.getClass().getSimpleName(), emailAddresses.size())); //NOI18N + + // Return it + return emailAddresses; + } + + @Override + public void enqueueEmailAddressForChange (final ChangeableEmailAddress emailChange, final String baseUrl) { + // Trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.enqueueEmailAddressForChange: emailChange={1},baseUrl={2} - CALLED!", this.getClass().getSimpleName(), emailChange, baseUrl)); //NOI18N + + // Email address change should be valid + if (null == emailChange) { + // Abort here + throw new NullPointerException("emailChange is null"); //NOI18N + } else if (emailChange.getEmailChangeUser() == null) { + // Throw NPE again + throw new NullPointerException("emailChange.emailChangeUser is null"); //NOI18N + } else if (emailChange.getEmailChangeUser().getUserId() == null) { + // Throw NPE again + throw new NullPointerException("emailChange.emailChangeUser.userId is null"); //NOI18N + } else if (emailChange.getEmailChangeUser().getUserId() < 1) { + // Not valid id + throw new IllegalArgumentException(MessageFormat.format("emailChange.emailChangeUser.userId={0} is invalid.", emailChange.getEmailChangeUser().getUserId())); //NOI18N + } else if (!this.userBean.ifUserExists(emailChange.getEmailChangeUser())) { + // User does not exist + throw new EJBException(MessageFormat.format("Email change with id {0} does not exist.", emailChange.getEmailChangeId())); //NOI18N + } else if (emailChange.getEmailAddress().trim().isEmpty()) { + // Email address is empty + throw new IllegalArgumentException("emailChange.emaiLAddress is empty."); //NOI18N + } else if (this.isEmailAddressEnqueued(emailChange.getEmailAddress())) { + // Email address is already enqueued + throw new EJBException(MessageFormat.format("Email address {0} is already enqueued.", emailChange.getEmailAddress())); //NOI18N + } + + // The email change is not (yet) there, add secure hash and "created" timestamp + emailChange.setEmailChangeCreated(new GregorianCalendar()); + this.generateSecureHash(emailChange); + + // Persist it + //@TODO Fix email delivery then allow this: this.getEntityManager().persist(emailChange); + // Init variable + Address emailAddress; + + try { + // Create email address and set + emailAddress = new InternetAddress(emailChange.getEmailAddress()); + } catch (final AddressException ex) { + // Throw again + throw new EJBException(ex); + } + + // Send email + this.sendEmail("User email change", "user_email_change", emailAddress, emailChange.getEmailChangeUser(), baseUrl, null); //NOI18N + + // Trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.enqueueEmailAddressForChange - EXIT!", this.getClass().getSimpleName())); //NOI18N + } + + @Override + public boolean isEmailAddressEnqueued (final String emailAddress) { + // Trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.isEmailAddressEnqueued: emailAddress={1} - CALLED!", this.getClass().getSimpleName(), emailAddress)); //NOI18N + + // Create query instance + Query query = this.getEntityManager().createNamedQuery("SearchEmailChangeByEmail"); //NOI18N + + // Add email address as parameter + query.setParameter("email", emailAddress); //NOI18N + + // Initialize variable + boolean isFound = false; + + // Try it + try { + // Try to get single result + ChangeableEmailAddress dummy = (ChangeableEmailAddress) query.getSingleResult(); + + // Found it + isFound = true; + } catch (final NoResultException ex) { + // Log it + this.getLoggerBeanLocal().logException(ex); + } + + // Trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.isEmailAddressEnqueued: isFound={1} - EXIT!", this.getClass().getSimpleName(), isFound)); //NOI18N + + // Return it + return isFound; + } + + @Override + public void updateEmailAddress (final ChangeableEmailAddress emailAddress) { + // Trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.updateEmailAddress: emailAddress={1} - CALLED!", this.getClass().getSimpleName(), emailAddress)); //NOI18N + + // Email address change should be valid + if (null == emailAddress) { + // Abort here + throw new NullPointerException("emailAddress is null"); //NOI18N + } else if (emailAddress.getEmailChangeId() == null) { + // Throw NPE again + throw new NullPointerException("emailAddress.emailChangeId is null"); //NOI18N + } else if (emailAddress.getEmailChangeId() < 1) { + // Not valid + throw new IllegalArgumentException(MessageFormat.format("emailAddress.emailChangeId={0} is not valid.", emailAddress.getEmailChangeId())); //NOI18N + } else if (emailAddress.getEmailAddress().trim().isEmpty()) { + // Email address is empty + throw new IllegalArgumentException("emailAddress.emaiLAddress is empty."); //NOI18N + } else if (!this.userBean.ifUserExists(emailAddress.getEmailChangeUser())) { + // User does not exist + throw new EJBException(MessageFormat.format("Email change with id {0} does not exist.", emailAddress.getEmailChangeId())); //NOI18N + } else if (!this.isEmailAddressEnqueued(emailAddress.getEmailAddress())) { + // Email address is not enqueued + throw new EJBException(MessageFormat.format("Email address {0} is not enqueued.", emailAddress.getEmailAddress())); //NOI18N + } + + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + /** + * Generates a secure, unique hash for given email address change. This + * requires to check if the hash is really not there. + *

+ * @param emailAddress Email address change + */ + private void generateSecureHash (final ChangeableEmailAddress emailAddress) { + // Email address change should be valid + if (null == emailAddress) { + // Abort here + throw new NullPointerException("emailAddress is null"); //NOI18N + } else if (emailAddress.getEmailAddress().trim().isEmpty()) { + // Email address is empty + throw new IllegalArgumentException("emailAddress.emaiLAddress is empty."); //NOI18N + } + + // Initialize loop with null + String hash = null; + + // Default is not used + boolean isUsed = true; + + // 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 + + // The hash *may* be unique, better test it + Query query = this.getEntityManager().createNamedQuery("SearchEmailChangeByHash", EmailAddressChange.class); //NOI18N + + // Set hash as parameter + query.setParameter("hash", hash); //NOI18N + + // Try to get single result + try { + // Get single result + ChangeableEmailAddress dummy = (ChangeableEmailAddress) query.getSingleResult(); + } catch (final NoResultException ex) { + // Not found + isUsed = false; + } + } + + // hash should not be null and set + assert (hash != null) : "hash is null"; //NOI18N + assert (!hash.isEmpty()) : "hash is empty"; //NOI18N + + // Set it in email change + emailAddress.setEmailChangeHash(hash); + } + +} diff --git a/src/java/org/mxchange/jusercore/model/user/register/AddressbookUserRegistrationSessionBean.java b/src/java/org/mxchange/jusercore/model/user/register/AddressbookUserRegistrationSessionBean.java new file mode 100644 index 0000000..707116e --- /dev/null +++ b/src/java/org/mxchange/jusercore/model/user/register/AddressbookUserRegistrationSessionBean.java @@ -0,0 +1,218 @@ +/* + * 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.EJBException; +import javax.ejb.Stateless; +import javax.mail.Address; +import javax.mail.internet.AddressException; +import javax.mail.internet.InternetAddress; +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.register.UserRegistrationSessionBeanRemote; +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 = "register", 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(); + } + + @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); + + // Init variable + Address emailAddress; + + try { + // Create email address and set + emailAddress = new InternetAddress(addedUser.getUserContact().getContactEmailAddress()); + } catch (final AddressException ex) { + // Throw again + throw new EJBException(ex); + } + + // 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, emailAddress, 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 new file mode 100644 index 0000000..259b43a --- /dev/null +++ b/src/java/org/mxchange/jusercore/model/user/resendlink/AddressbookResendLinkSessionBean.java @@ -0,0 +1,131 @@ +/* + * 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.EJBException; +import javax.ejb.Stateless; +import javax.mail.Address; +import javax.mail.internet.AddressException; +import javax.mail.internet.InternetAddress; +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.register.UserRegistrationSessionBeanRemote; +import org.mxchange.jusercore.model.resendlink.ResendLinkSessionBeanRemote; +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; + +/** + * A session-based EJB for resending confirmation links + *

+ * @author Roland Häder + */ +@Stateless (name = "resendLink", 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(); + } + + @Override + public void 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); + + // Get managed instance + User managedUser = this.getEntityManager().find(LoginUser.class, user.getUserId()); + + // Set it in user + managedUser.setUserConfirmKey(confirmationKey); + + // Init variable + Address emailAddress; + + try { + // Create email address and set + emailAddress = new InternetAddress(managedUser.getUserContact().getContactEmailAddress()); + } catch (final AddressException ex) { + // Throw again + throw new EJBException(ex); + } + + // Send email + // @TODO: Internationlize the subject line somehow + this.sendEmail("Resend user confirmation link", "user_resend_confirmation_link", emailAddress, user, baseUrl, null); //NOI18N + + // Log trace message + this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.resendConfirmationLink: EXIT!", this.getClass().getSimpleName())); //NOI18N + } + +}