From: Roland Häder Date: Thu, 22 Jun 2017 21:13:00 +0000 (+0200) Subject: Don't cherry-pick: X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=c9f3fe99d29c4816def2c80fcc432b2397e4536e;p=jjobs-ejb.git Don't 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 - changed jar-dependency jjobs-core.jar to project-dependency Signed-off-by: Roland Häder --- diff --git a/lib/jjobs-core.jar b/lib/jjobs-core.jar deleted file mode 100644 index 5f7ce3a..0000000 Binary files a/lib/jjobs-core.jar and /dev/null differ diff --git a/lib/jjobs-mailer.jar b/lib/jjobs-mailer.jar deleted file mode 100644 index 69cc926..0000000 Binary files a/lib/jjobs-mailer.jar and /dev/null differ diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml index 42a0ae9..df7c1f5 100644 --- a/nbproject/build-impl.xml +++ b/nbproject/build-impl.xml @@ -806,6 +806,9 @@ exists or setup the property manually. For example like this: COMPILATION SECTION --> + + + @@ -817,6 +820,9 @@ exists or setup the property manually. For example like this: + + + @@ -840,18 +846,21 @@ exists or setup the property manually. For example like this: + + - - + + + - + @@ -859,57 +868,66 @@ exists or setup the property manually. For example like this: + + - - + + + - + - + - - - - - - + + + + + + - - - - - + + + + + + + + + + - - + + + - + @@ -1296,6 +1314,7 @@ exists or setup the property manually. For example like this: CLEANUP SECTION --> + diff --git a/nbproject/project.properties b/nbproject/project.properties index 98c1ef8..ca3162f 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -31,7 +31,6 @@ file.reference.jcore-logger-lib.jar=lib/jcore-logger-lib.jar file.reference.jcoreee.jar=lib/jcoreee.jar file.reference.jcountry-core.jar=lib/jcountry-core.jar file.reference.jcountry-lib.jar=lib/jcountry-lib.jar -file.reference.jjobs-core.jar=lib/jjobs-core.jar file.reference.jjobs-mailer.jar=lib/jjobs-mailer.jar file.reference.jletter-lib.jar=lib/jletter-lib.jar file.reference.jmailer-ee.jar=lib/jmailer-ee.jar @@ -73,7 +72,7 @@ javac.classpath=\ ${file.reference.jaddressbook-core.jar}:\ ${file.reference.jaddressbook-lib.jar}:\ ${file.reference.jmailer-ee.jar}:\ - ${file.reference.jjobs-core.jar}:\ + ${reference.jjobs-core.jar}:\ ${reference.jjobs-lib.jar}:\ ${reference.jjobs-mailer.jar}:\ ${file.reference.cdi-api.jar} @@ -104,11 +103,13 @@ javadoc.windowtitle=Jobs EJB meta.inf=${source.root}/conf meta.inf.excludes=sun-cmp-mappings.xml platform.active=default_platform +project.jjobs-core=../../NetBeansProjects/jjobs-core project.jjobs-lib=../jjobs-lib project.jjobs-mailer=../jjobs-mailer project.juser-core=../juser-core project.license=agpl30 project.serviceLocator.class=org.mxchange.jjobs.mailer.model.delivery.JobsMailer +reference.jjobs-core.jar=${project.jjobs-core}/dist/jjobs-core.jar reference.jjobs-lib.jar=${project.jjobs-lib}/dist/jjobs-lib.jar reference.jjobs-mailer.jar=${project.jjobs-mailer}/dist/jjobs-mailer.jar resource.dir=setup @@ -128,7 +129,6 @@ source.reference.jcore-logger-lib.jar=../jcore-logger-lib/src/ source.reference.jcoreee.jar=../jcoreee/src/ source.reference.jcountry-core.jar=../jcountry-core/src/ source.reference.jcountry-lib.jar=../jcountry-lib/src/ -source.reference.jjobs-core.jar=../jjobs-core/src/ source.reference.jjobs-mailer.jar=../jjobs-mailer/src/ source.reference.jletter-lib.jar=../jletter-lib/src/ source.reference.jmailer-ee.jar=../jmailer-ee/src/ diff --git a/nbproject/project.xml b/nbproject/project.xml index 50b4fc2..521ac6d 100644 --- a/nbproject/project.xml +++ b/nbproject/project.xml @@ -7,18 +7,21 @@ 1.6.5 file.reference.jcoreee.jar file.reference.jcore-logger-lib.jar + file.reference.jcontacts-core.jar + file.reference.jcontacts-lib.jar file.reference.jcountry-core.jar file.reference.jcountry-lib.jar file.reference.jphone-core.jar file.reference.jphone-lib.jar - file.reference.jcontacts-core.jar - file.reference.jcontacts-lib.jar file.reference.juser-core.jar file.reference.juser-lib.jar file.reference.juser-activity-core.jar file.reference.juser-activity-lib.jar + file.reference.jletter-lib.jar + file.reference.jaddressbook-core.jar + file.reference.jaddressbook-lib.jar file.reference.jmailer-ee.jar - file.reference.jjobs-core.jar + reference.jjobs-core.jar reference.jjobs-lib.jar reference.jjobs-mailer.jar file.reference.cdi-api.jar @@ -33,6 +36,14 @@ ./lib/nblibraries.properties + + jjobs-core + jar + + jar + clean + jar + jjobs-lib jar diff --git a/src/java/org/mxchange/jjobs/beans/resendlink/JobsResendLinkSessionBean.java b/src/java/org/mxchange/jjobs/beans/resendlink/JobsResendLinkSessionBean.java deleted file mode 100644 index 62e2216..0000000 --- a/src/java/org/mxchange/jjobs/beans/resendlink/JobsResendLinkSessionBean.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.jjobs.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.jjobs.database.BaseJobsDatabaseBean; -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 JobsResendLinkSessionBean extends BaseJobsDatabaseBean 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 JobsResendLinkSessionBean () { - // 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/jusercore/model/email_address/JobsUserEmailChangeSessionBean.java b/src/java/org/mxchange/jusercore/model/email_address/JobsUserEmailChangeSessionBean.java deleted file mode 100644 index a5324ff..0000000 --- a/src/java/org/mxchange/jusercore/model/email_address/JobsUserEmailChangeSessionBean.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.jjobs.database.BaseJobsDatabaseBean; -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 JobsUserEmailChangeSessionBean extends BaseJobsDatabaseBean implements UserEmailChangeSessionBeanRemote { - - /** - * Serial number - */ - private static final long serialVersionUID = 182_698_165_971_548L; - - /** - * User bean - */ - @EJB - private UserSessionBeanRemote userBean; - - /** - * Default constructor - */ - public JobsUserEmailChangeSessionBean () { - // 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/JobsUserLoginSessionBean.java b/src/java/org/mxchange/jusercore/model/login/JobsUserLoginSessionBean.java index be35b3c..53b20cf 100644 --- a/src/java/org/mxchange/jusercore/model/login/JobsUserLoginSessionBean.java +++ b/src/java/org/mxchange/jusercore/model/login/JobsUserLoginSessionBean.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/JobsUserRegistrationSessionBean.java b/src/java/org/mxchange/jusercore/model/register/JobsUserRegistrationSessionBean.java deleted file mode 100644 index 5c92f4d..0000000 --- a/src/java/org/mxchange/jusercore/model/register/JobsUserRegistrationSessionBean.java +++ /dev/null @@ -1,206 +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.jcontacts.contact.Contact; -import org.mxchange.jjobs.database.BaseJobsDatabaseBean; -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 JobsUserRegistrationSessionBean extends BaseJobsDatabaseBean 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 JobsUserRegistrationSessionBean () { - // 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/JobsAdminUserSessionBean.java b/src/java/org/mxchange/jusercore/model/user/JobsAdminUserSessionBean.java index 7b5c7a1..f06f0df 100644 --- a/src/java/org/mxchange/jusercore/model/user/JobsAdminUserSessionBean.java +++ b/src/java/org/mxchange/jusercore/model/user/JobsAdminUserSessionBean.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; /** @@ -144,13 +144,13 @@ public class JobsAdminUserSessionBean extends BaseJobsDatabaseBean implements Ad } // Get a managed instance - User managedUser = this.getManagedUser(user); + User updatedUser = this.getManagedUser(user); // Should be found! - assert (managedUser instanceof User) : MessageFormat.format("User with id {0} not found, but should be.", user.getUserId()); //NOI18N + assert (updatedUser instanceof User) : MessageFormat.format("User with id {0} not found, but should be.", user.getUserId()); //NOI18N // Delete it - this.getEntityManager().remove(managedUser); + this.getEntityManager().remove(updatedUser); // Trace message this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.deleteUser: EXIT!", this.getClass().getSimpleName())); //NOI18N @@ -263,14 +263,14 @@ public class JobsAdminUserSessionBean extends BaseJobsDatabaseBean implements Ad user.setUserLastLockedReason(userLockReason); // Update user - User managedUser = this.userBean.updateUserData(user); + User updatedUser = this.userBean.updateUserData(user); // Init variable Address emailAddress; try { // Create email address and set - emailAddress = new InternetAddress(managedUser.getUserContact().getContactEmailAddress()); + emailAddress = new InternetAddress(updatedUser.getUserContact().getContactEmailAddress()); } catch (final AddressException ex) { // Throw again throw new EJBException(ex); @@ -278,13 +278,13 @@ public class JobsAdminUserSessionBean extends BaseJobsDatabaseBean implements Ad // 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, updatedUser, baseUrl, null); //NOI18N // Trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.lockUserAccount: managedUser={1} - EXIT!", this.getClass().getSimpleName(), managedUser)); //NOI18N + this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.lockUserAccount: updatedUser={1} - EXIT!", this.getClass().getSimpleName(), updatedUser)); //NOI18N // Return detached (and updated) user - return managedUser; + return updatedUser; } @Override @@ -332,14 +332,14 @@ public class JobsAdminUserSessionBean extends BaseJobsDatabaseBean implements Ad user.setUserAccountStatus(UserAccountStatus.CONFIRMED); // Update user - User managedUser = this.userBean.updateUserData(user); + User updatedUser = this.userBean.updateUserData(user); // Init variable Address emailAddress; try { // Create email address and set - emailAddress = new InternetAddress(managedUser.getUserContact().getContactEmailAddress()); + emailAddress = new InternetAddress(updatedUser.getUserContact().getContactEmailAddress()); } catch (final AddressException ex) { // Throw again throw new EJBException(ex); @@ -347,13 +347,13 @@ public class JobsAdminUserSessionBean extends BaseJobsDatabaseBean implements Ad // 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, updatedUser, baseUrl, null); //NOI18N // Trace message - this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.lockUserAccount: managedUser={1} - EXIT!", this.getClass().getSimpleName(), managedUser)); //NOI18N + this.getLoggerBeanLocal().logTrace(MessageFormat.format("{0}.lockUserAccount: updatedUser={1} - EXIT!", this.getClass().getSimpleName(), updatedUser)); //NOI18N // Return changed account - return managedUser; + return updatedUser; } } diff --git a/src/java/org/mxchange/jusercore/model/user/JobsUserSessionBean.java b/src/java/org/mxchange/jusercore/model/user/JobsUserSessionBean.java index dd68947..4598a86 100644 --- a/src/java/org/mxchange/jusercore/model/user/JobsUserSessionBean.java +++ b/src/java/org/mxchange/jusercore/model/user/JobsUserSessionBean.java @@ -37,10 +37,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 +188,7 @@ public class JobsUserSessionBean extends BaseJobsDatabaseBean implements UserSes } // 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 @@ -674,7 +674,7 @@ public class JobsUserSessionBean extends BaseJobsDatabaseBean implements UserSes } // 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 diff --git a/src/java/org/mxchange/jusercore/model/user/email_address/JobsUserEmailChangeSessionBean.java b/src/java/org/mxchange/jusercore/model/user/email_address/JobsUserEmailChangeSessionBean.java new file mode 100644 index 0000000..e96e462 --- /dev/null +++ b/src/java/org/mxchange/jusercore/model/user/email_address/JobsUserEmailChangeSessionBean.java @@ -0,0 +1,252 @@ +/* + * 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.jjobs.database.BaseJobsDatabaseBean; +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 JobsUserEmailChangeSessionBean extends BaseJobsDatabaseBean implements UserEmailChangeSessionBeanRemote { + + /** + * Serial number + */ + private static final long serialVersionUID = 182_698_165_971_548L; + + /** + * User bean + */ + @EJB + private UserSessionBeanRemote userBean; + + /** + * Default constructor + */ + public JobsUserEmailChangeSessionBean () { + // 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("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 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/user/register/JobsUserRegistrationSessionBean.java b/src/java/org/mxchange/jusercore/model/user/register/JobsUserRegistrationSessionBean.java new file mode 100644 index 0000000..303ba29 --- /dev/null +++ b/src/java/org/mxchange/jusercore/model/user/register/JobsUserRegistrationSessionBean.java @@ -0,0 +1,217 @@ +/* + * 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.jcontacts.contact.Contact; +import org.mxchange.jjobs.database.BaseJobsDatabaseBean; +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 JobsUserRegistrationSessionBean extends BaseJobsDatabaseBean 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 JobsUserRegistrationSessionBean () { + // 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/JobsResendLinkSessionBean.java b/src/java/org/mxchange/jusercore/model/user/resendlink/JobsResendLinkSessionBean.java new file mode 100644 index 0000000..22b0673 --- /dev/null +++ b/src/java/org/mxchange/jusercore/model/user/resendlink/JobsResendLinkSessionBean.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.jjobs.database.BaseJobsDatabaseBean; +import org.mxchange.jusercore.exceptions.UserNotFoundException; +import org.mxchange.jusercore.exceptions.UserStatusConfirmedException; +import org.mxchange.jusercore.exceptions.UserStatusLockedException; +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.register.UserRegistrationSessionBeanRemote; +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 JobsResendLinkSessionBean extends BaseJobsDatabaseBean 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 JobsResendLinkSessionBean () { + // 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 + } + +}