From 5e9e97306be3ea8bab6f650f5c3e8200b4efa5f1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Roland=20H=C3=A4der?= Date: Thu, 22 Jun 2017 22:52:09 +0200 Subject: [PATCH] Please cherry-pick: - New feature to allow users on registration entering no password. The application will then generate a random password for the user and also sends it in clear-text to the EJB (HTTPS is not meant here) so the bean can deliver it to the user. - user registration page will now show proper messages for above feature - removed obsolete template (seems to be still around?) - ifBothPasswordsEmptyAllowed() implemented - added missing i18n strings MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Roland Häder --- .../localization/bundle_de_DE.properties | 30 +++++ .../localization/bundle_en_US.properties | 18 +++ .../PizzaAdminContactWebRequestBean.java | 2 +- .../contact/PizzaContactWebSessionBean.java | 2 +- .../beans/user/PizzaUserWebSessionBean.java | 8 ++ .../user/PizzaUserWebSessionController.java | 10 ++ .../PizzaUserRegisterWebSessionBean.java | 100 +++++++++++++--- .../guest/user/guest_registration_form.tpl | 108 ------------------ .../register/guest_form_register_page1.tpl | 10 +- .../register/guest_form_register_single.tpl | 10 +- web/WEB-INF/web.xml | 5 + web/guest/user/user_register.xhtml | 4 +- 12 files changed, 176 insertions(+), 131 deletions(-) delete mode 100644 web/WEB-INF/templates/guest/user/guest_registration_form.tpl diff --git a/src/java/org/mxchange/localization/bundle_de_DE.properties b/src/java/org/mxchange/localization/bundle_de_DE.properties index 7b36b438..f719fd6f 100644 --- a/src/java/org/mxchange/localization/bundle_de_DE.properties +++ b/src/java/org/mxchange/localization/bundle_de_DE.properties @@ -780,3 +780,33 @@ ADMIN_LINK_SHOW_CONTACT_DATA=Kontaktdaten anzeigen ERROR_USER_PASSWORD_TO_WEAK=Das eingegebene Passwort ist zu schwach. Bitte geben Sie Bustaben, Zahlen und Sonderzeichen ein, um ein sicheres Passwort zu erstellen. #@TODO Please fix German umlauts! GUEST_REGISTRATION_USER_NAME_NOT_ENTERED=Bitte geben Sie einen Benutzernamen ein. Dieser wird auf Verfuegbarkeit hin getestet. +#@TODO Please fix German umlauts! +PAGE_TITLE_LOGIN_FINANCIAL_OVERVIEW=Finanzen-Uebersicht +#@TODO Please fix German umlauts! +SUB_TITLE_LOGIN_FINANCIAL_OVERVIEW=Uebersicht Ihrer Finanzen: +#@TODO Please fix German umlauts! +PAGE_TITLE_LOGIN_FINANCIAL_ADD_RECEIPT=Rechnung hinzufuegen/erfassen +SUB_TITLE_LOGIN_FINANCIAL_ADD_RECEIPT=Weitere Rechnung erfassen: +#@TODO Please fix German umlauts! +PAGE_TITLE_LOGIN_FINANCIAL_ADD_INCOME=Neue Einkommensart hinzufuegen +#@TODO Please fix German umlauts! +SUB_TITLE_LOGIN_FINANCIAL_ADD_INCOME=Weitere Einkommensart hinzufuegen: +LOGIN_FINANCIAL_ADD_INCOME_FORM_TITLE=Daten einer Einkommensart erfassen: +LOGIN_FINANCIAL_INCOME_INTERVAL=Einkommensinterval: +#@TODO Please fix German umlauts! +FIELD_FINANCIAL_INCOME_REQUIRED=Feld "Einkommensinterval" muss ausgewaehlt werden. +#@TODO Please fix German umlauts! +BUTTON_LOGIN_FINCIAL_ADD_INCOME=Einkommensart hinzufuegen +LOGIN_FINANCIAL_INCOME_SINGLE_VALUE=Einkommensbetrag: +#@TODO Please fix German umlauts! +FIELD_FINANCIAL_INCOME_SINGLE_VALUE_REQUIRED=Feld "Einkommensbetrag" bitte ausfuellen. +LOGIN_FINANCIAL_INCOME_TITLE=Bezeichnung der Einkommensart: +#@TODO Please fix German umlauts! +FIELD_FINANCIAL_INCOME_TITLE_REQUIRED=Feld "Title" muss ausgefuellt werden. +#@TODO Please fix German umlauts! +ERROR_USER_PASSWORD_EMPTY=Sie muessen ein Passwort eingeben. +#@TODO Please fix German umlauts! +ERROR_USER_PASSWORD_REPEAT_EMPTY=Sie muessen das eingegebene Passwort wiederholen. +GUEST_REGISTRATION_USER_PASSWORDS_EMPTY_ALLOWED=Lassen Sie beide Passwortfelder leer, wird Ihnen ein Passwort per Zufall generiert. +#@TODO Please fix German umlauts! +GUEST_REGISTRATION_USER_PASSWORDS_EMPTY_NOT_ALLOWED=Sie muessen selbst ein Passwort vergeben. Bitte geben Sie dies zur Bestaetigung zweimal ein. diff --git a/src/java/org/mxchange/localization/bundle_en_US.properties b/src/java/org/mxchange/localization/bundle_en_US.properties index 967dc2da..9314c6de 100644 --- a/src/java/org/mxchange/localization/bundle_en_US.properties +++ b/src/java/org/mxchange/localization/bundle_en_US.properties @@ -777,3 +777,21 @@ BUTTON_USER_CHANGE_PASSWORD=Change password ADMIN_LINK_SHOW_CONTACT_DATA=Show contact data ERROR_USER_PASSWORD_TO_WEAK=Your entered password is to weak. Please enter letters, numbers and special characters to create a secure password. GUEST_REGISTRATION_USER_NAME_NOT_ENTERED=Please enter a user name. The entered name is being checked for availability. +PAGE_TITLE_LOGIN_FINANCIAL_OVERVIEW=Financials Overview +SUB_TITLE_LOGIN_FINANCIAL_OVERVIEW=Overview of your financials: +PAGE_TITLE_LOGIN_FINANCIAL_ADD_RECEIPT=Add receipt +SUB_TITLE_LOGIN_FINANCIAL_ADD_RECEIPT=Add new receipt: +PAGE_TITLE_LOGIN_FINANCIAL_ADD_INCOME=Add new income type +SUB_TITLE_LOGIN_FINANCIAL_ADD_INCOME=Add new income type: +LOGIN_FINANCIAL_ADD_INCOME_FORM_TITLE=Enter all data of one income type: +LOGIN_FINANCIAL_INCOME_INTERVAL=Income interval: +FIELD_FINANCIAL_INCOME_REQUIRED=Field "Income interval" must be selected. +BUTTON_LOGIN_FINCIAL_ADD_INCOME=Add income type +LOGIN_FINANCIAL_INCOME_SINGLE_VALUE=Income value: +FIELD_FINANCIAL_INCOME_SINGLE_VALUE_REQUIRED=Field "Income value" must be filled out. +LOGIN_FINANCIAL_INCOME_TITLE=Title of income type: +FIELD_FINANCIAL_INCOME_TITLE_REQUIRED=Field "Title" must be filled out. +ERROR_USER_PASSWORD_EMPTY=You have to enter a password. +ERROR_USER_PASSWORD_REPEAT_EMPTY=You have to repeat the entered password. +GUEST_REGISTRATION_USER_PASSWORDS_EMPTY_ALLOWED=If you left both password fields empty, a random password will generated for you. +GUEST_REGISTRATION_USER_PASSWORDS_EMPTY_NOT_ALLOWED=You have to enter an own password. Please enter it twice for confirmation. diff --git a/src/java/org/mxchange/pizzaapplication/beans/contact/PizzaAdminContactWebRequestBean.java b/src/java/org/mxchange/pizzaapplication/beans/contact/PizzaAdminContactWebRequestBean.java index 6af68fdf..b6acfa1a 100644 --- a/src/java/org/mxchange/pizzaapplication/beans/contact/PizzaAdminContactWebRequestBean.java +++ b/src/java/org/mxchange/pizzaapplication/beans/contact/PizzaAdminContactWebRequestBean.java @@ -35,7 +35,7 @@ import org.mxchange.jcontacts.contact.Contact; import org.mxchange.jcontacts.contact.ContactSessionBeanRemote; import org.mxchange.jcontacts.contact.UserContact; import org.mxchange.jcontacts.contact.title.PersonalTitle; -import org.mxchange.jcontacts.contact.utils.ContactUtils; +import org.mxchange.jcontacts.contact.ContactUtils; import org.mxchange.jcontacts.events.contact.add.AdminAddedContactEvent; import org.mxchange.jcontacts.events.contact.add.ObservableAdminAddedContactEvent; import org.mxchange.jcontacts.events.contact.update.AdminUpdatedContactEvent; diff --git a/src/java/org/mxchange/pizzaapplication/beans/contact/PizzaContactWebSessionBean.java b/src/java/org/mxchange/pizzaapplication/beans/contact/PizzaContactWebSessionBean.java index cdc991da..b1923b55 100644 --- a/src/java/org/mxchange/pizzaapplication/beans/contact/PizzaContactWebSessionBean.java +++ b/src/java/org/mxchange/pizzaapplication/beans/contact/PizzaContactWebSessionBean.java @@ -36,7 +36,7 @@ import org.mxchange.jcontacts.contact.Contact; import org.mxchange.jcontacts.contact.ContactSessionBeanRemote; import org.mxchange.jcontacts.contact.UserContact; import org.mxchange.jcontacts.contact.title.PersonalTitle; -import org.mxchange.jcontacts.contact.utils.ContactUtils; +import org.mxchange.jcontacts.contact.ContactUtils; import org.mxchange.jcontacts.events.contact.add.ObservableAdminAddedContactEvent; import org.mxchange.jcontacts.events.contact.update.ObservableAdminUpdatedContactEvent; import org.mxchange.jcontacts.exceptions.ContactNotFoundException; diff --git a/src/java/org/mxchange/pizzaapplication/beans/user/PizzaUserWebSessionBean.java b/src/java/org/mxchange/pizzaapplication/beans/user/PizzaUserWebSessionBean.java index cecc3cf3..06f8d61e 100644 --- a/src/java/org/mxchange/pizzaapplication/beans/user/PizzaUserWebSessionBean.java +++ b/src/java/org/mxchange/pizzaapplication/beans/user/PizzaUserWebSessionBean.java @@ -660,6 +660,14 @@ public class PizzaUserWebSessionBean extends BasePizzaController implements Pizz this.userProfileMode = userProfileMode; } + @Override + public boolean ifBothPasswordsEmptyAllowed () { + // Check feature first + return ((this.featureController.isFeatureEnabled("allow_user_registration_empty_password")) && + ((this.getUserPassword() == null) || (this.getUserPassword().isEmpty())) && + ((this.getUserPasswordRepeat() == null) || (this.getUserPasswordRepeat().isEmpty()))); + } + /** * Post-initialization of this class */ diff --git a/src/java/org/mxchange/pizzaapplication/beans/user/PizzaUserWebSessionController.java b/src/java/org/mxchange/pizzaapplication/beans/user/PizzaUserWebSessionController.java index 8d0ce489..b56053d1 100644 --- a/src/java/org/mxchange/pizzaapplication/beans/user/PizzaUserWebSessionController.java +++ b/src/java/org/mxchange/pizzaapplication/beans/user/PizzaUserWebSessionController.java @@ -36,6 +36,16 @@ public interface PizzaUserWebSessionController extends Serializable { */ public static final Integer MINIMUM_PASSWORD_LENGTH = 5; + /** + * Checks if both user passwords are left empty and if this is enabled + * (allowed) in context parameter. If true, the calling bean should create a + * random password (preferable with UserUtils.createRandomPassword() and set + * it in both user password fields. + *

+ * @return Whether empty passwords are allowed + */ + boolean ifBothPasswordsEmptyAllowed (); + /** * All users *

diff --git a/src/java/org/mxchange/pizzaapplication/beans/user/register/PizzaUserRegisterWebSessionBean.java b/src/java/org/mxchange/pizzaapplication/beans/user/register/PizzaUserRegisterWebSessionBean.java index 16f67ce8..c9872cea 100644 --- a/src/java/org/mxchange/pizzaapplication/beans/user/register/PizzaUserRegisterWebSessionBean.java +++ b/src/java/org/mxchange/pizzaapplication/beans/user/register/PizzaUserRegisterWebSessionBean.java @@ -35,9 +35,9 @@ import org.mxchange.jusercore.events.registration.UserRegisteredEvent; import org.mxchange.jusercore.exceptions.DataRepeatMismatchException; 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.User; import org.mxchange.jusercore.model.user.UserUtils; +import org.mxchange.jusercore.model.user.register.UserRegistrationSessionBeanRemote; import org.mxchange.jusercore.model.user.status.UserAccountStatus; import org.mxchange.pizzaapplication.beans.BasePizzaController; import org.mxchange.pizzaapplication.beans.contact.PizzaContactWebSessionController; @@ -114,6 +114,9 @@ public class PizzaUserRegisterWebSessionBean extends BasePizzaController impleme // Get user instance User user = this.userController.createUserInstance(true); + // Null random password means registration requires user-entered password + String randomPassword = null; + // Is the user already used? if (null == user) { // user must be set @@ -122,17 +125,53 @@ public class PizzaUserRegisterWebSessionBean extends BasePizzaController impleme // Not all required fields are set throw new FaceletException("Not all required fields are set."); //NOI18N } else if ((this.featureController.isFeatureEnabled("user_name_required")) && (this.userController.isUserNameRegistered(user))) { //NOI18N - // User name is already used - throw new FaceletException(new UserNameAlreadyRegisteredException(user)); + // Is multi-page enabled? + if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N + // User name is already used, should not happen here + throw new FaceletException(new UserNameAlreadyRegisteredException(user)); + } else { + // May happen here, reset field + this.userController.setUserName(null); + this.showFacesMessage("form_register_single:userName", "ERROR_USER_NAME_ALREADY_USED"); //NOI18N + return ""; //NOI18N + } } else if (this.contactController.isEmailAddressRegistered(user.getUserContact())) { - // Email address has already been taken - throw new FaceletException(new EmailAddressAlreadyRegisteredException(user)); + // Is multi-page enabled? + if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N + // Email address has already been taken, should not happen here + throw new FaceletException(new EmailAddressAlreadyRegisteredException(user)); + } else { + // May happen here, reset fields + this.contactController.setEmailAddress(null); + this.contactController.setEmailAddressRepeat(null); + this.showFacesMessage("form_register_single:emailAddressRepeat", "ERROR_EMAIL_ADDRESS_ALREADY_USED"); //NOI18N + return ""; //NOI18N + } } else if (!this.contactController.isSameEmailAddressEntered()) { - // Not same email address entered - throw new FaceletException(new DataRepeatMismatchException(MessageFormat.format("Email addresses not matching: {0} != {1}", this.contactController.getEmailAddress(), this.contactController.getEmailAddressRepeat()))); //NOI18N + // Is multi-page enabled? + if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N + // Not same email address entered, should not happen here + throw new FaceletException(new DataRepeatMismatchException(MessageFormat.format("Email addresses not matching: {0} != {1}", this.contactController.getEmailAddress(), this.contactController.getEmailAddressRepeat()))); //NOI18N + } else { + // May happen here, reset fields + this.contactController.setEmailAddress(null); + this.contactController.setEmailAddressRepeat(null); + this.showFacesMessage("form_register_single:emailAddressRepeat", "ERROR_EMAIL_ADDRESSES_MISMATCHING"); //NOI18N + return ""; //NOI18N + } } else if (!this.userController.isSamePasswordEntered()) { - // Not same password entered - throw new FaceletException(new DataRepeatMismatchException("Passwords not matching.")); //NOI18N + // Is multi-page enabled? + if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N + // Not same password entered, should no longer happen here + throw new FaceletException(new DataRepeatMismatchException("Passwords not matching.")); //NOI18N + } else if (this.userController.ifBothPasswordsEmptyAllowed()) { + // Both passwords are left empty and is allowed, then generate a random password + randomPassword = UserUtils.createRandomPassword(PizzaUserWebSessionController.MINIMUM_PASSWORD_LENGTH); + + // Set it in both fields + this.userController.setUserPassword(randomPassword); + this.userController.setUserPasswordRepeat(randomPassword); + } } // Encrypt password @@ -161,7 +200,7 @@ public class PizzaUserRegisterWebSessionBean extends BasePizzaController impleme String baseUrl = FacesUtils.generateBaseUrl(); // Call bean - User registeredUser = this.registerBean.registerUser(user, baseUrl); + User registeredUser = this.registerBean.registerUser(user, baseUrl, randomPassword); // The id number should be set assert (registeredUser.getUserId() instanceof Long) : "registeredUser.userId is null after registerUser() was called."; //NOI18N @@ -193,11 +232,35 @@ public class PizzaUserRegisterWebSessionBean extends BasePizzaController impleme // user must be set throw new NullPointerException("user is null after createUserInstance() was called"); //NOI18N } else if ((this.featureController.isFeatureEnabled("user_name_required")) && (this.userController.isUserNameRegistered(user))) { //NOI18N - // User name is already used - throw new FaceletException(new UserNameAlreadyRegisteredException(user)); + // User name is already used, so clear it + this.userController.setUserName(null); + this.showFacesMessage("form_register_page1:userName", "ERROR_USER_NAME_ALREADY_USED"); //NOI18N + return ""; //NOI18N } else if (!this.contactController.isSameEmailAddressEntered()) { - // Not same email address entered - throw new FaceletException(new DataRepeatMismatchException(MessageFormat.format("Email addresses not matching: {0} != {1}", this.contactController.getEmailAddress(), this.contactController.getEmailAddressRepeat()))); //NOI18N + // Not same email address entered, clear both + this.contactController.setEmailAddress(null); + this.contactController.setEmailAddressRepeat(null); + this.showFacesMessage("form_register_page1:emailAddressRepeat", "ERROR_EMAIL_ADDRESSES_MISMATCHING"); //NOI18N + return ""; //NOI18N + } else if (!this.userController.isSamePasswordEntered()) { + // Is multi-page enabled? + if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N + // Unset both + this.userController.setUserPassword(null); + this.userController.setUserPasswordRepeat(null); + + // Output faces message + this.showFacesMessage("form_register_page1:userPassword", "ERROR_USER_PASSWORD_EMPTY"); //NOI18N + this.showFacesMessage("form_register_page1:userPasswordRepeat", "ERROR_USER_PASSWORD_REPEAT_EMPTY"); //NOI18N + return ""; //NOI18N + } else if (this.userController.ifBothPasswordsEmptyAllowed()) { + // Both passwords are left empty and is allowed, then generate a random password + String randomPassword = UserUtils.createRandomPassword(PizzaUserWebSessionController.MINIMUM_PASSWORD_LENGTH); + + // Set it in both fields + this.userController.setUserPassword(randomPassword); + this.userController.setUserPasswordRepeat(randomPassword); + } } // Create half contact instance with email address @@ -209,12 +272,15 @@ public class PizzaUserRegisterWebSessionBean extends BasePizzaController impleme // Check if email address is registered if (this.contactController.isEmailAddressRegistered(user.getUserContact())) { - // Email address has already been taken - throw new FaceletException(new EmailAddressAlreadyRegisteredException(user)); + // Email address has already been taken, clear both + this.contactController.setEmailAddress(null); + this.contactController.setEmailAddressRepeat(null); + this.showFacesMessage("form_register_page1:emailAddress", "ERROR_EMAIL_ADDRESS_ALREADY_USED"); //NOI18N + return ""; //NOI18N } // Now only redirect to next page as the JSF does it - return "user_register_page2"; //NOI18N + return "register_page2"; //NOI18N } /** diff --git a/web/WEB-INF/templates/guest/user/guest_registration_form.tpl b/web/WEB-INF/templates/guest/user/guest_registration_form.tpl deleted file mode 100644 index 7c46749d..00000000 --- a/web/WEB-INF/templates/guest/user/guest_registration_form.tpl +++ /dev/null @@ -1,108 +0,0 @@ - - - - -

-
- -
- - - -
-
- #{msg.GUEST_REGISTRATION_EMAIL_LEGEND} - -
-
- -
- -
- -
- -
-
- - - - - -
-
- -
- -
- -
- -
-
- - - - - -
-
- -
- -
- -
- -
-
- - - - - -
- -
-
- -
- -
- -
- -
-
- -
-
- -
- -
- -
- -
-
- -
- -
-
-
- - - - -
- - diff --git a/web/WEB-INF/templates/guest/user/register/guest_form_register_page1.tpl b/web/WEB-INF/templates/guest/user/register/guest_form_register_page1.tpl index aba8452c..e53ce9ec 100644 --- a/web/WEB-INF/templates/guest/user/register/guest_form_register_page1.tpl +++ b/web/WEB-INF/templates/guest/user/register/guest_form_register_page1.tpl @@ -73,7 +73,15 @@
- +
    +
  • + +
  • +
    + +
  • +
    +
diff --git a/web/WEB-INF/templates/guest/user/register/guest_form_register_single.tpl b/web/WEB-INF/templates/guest/user/register/guest_form_register_single.tpl index 9a1dd99a..312d8ab1 100644 --- a/web/WEB-INF/templates/guest/user/register/guest_form_register_single.tpl +++ b/web/WEB-INF/templates/guest/user/register/guest_form_register_single.tpl @@ -75,7 +75,15 @@
- +
    +
  • + +
  • +
    + +
  • +
    +
diff --git a/web/WEB-INF/web.xml b/web/WEB-INF/web.xml index 2ad0bb14..55067665 100644 --- a/web/WEB-INF/web.xml +++ b/web/WEB-INF/web.xml @@ -97,6 +97,11 @@ is_feature_user_registration_in_index_enabled false + + Whether user can leave both passwords empty on registration. + allow_user_registration_empty_password + false + Maximum passwords that must be different. max_user_password_history diff --git a/web/guest/user/user_register.xhtml b/web/guest/user/user_register.xhtml index 124eefc0..9e33b2c6 100644 --- a/web/guest/user/user_register.xhtml +++ b/web/guest/user/user_register.xhtml @@ -19,13 +19,13 @@ -
+ -
+
-- 2.39.2