CCM NG:
- Users which register using the login app are now added to the group "registered-users" (which is created if not existing) - Logic for user registration moved the ccm-core/org.libreccm.security.RegistrationManager - Some JavaDoc git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4019 8810af33-2d31-482b-a856-94f89814c4dfpull/2/head
parent
822c5288f3
commit
87b46a531e
|
|
@ -36,9 +36,11 @@ import com.arsdigita.kernel.security.SecurityConfig;
|
||||||
import com.arsdigita.web.RedirectSignal;
|
import com.arsdigita.web.RedirectSignal;
|
||||||
import com.arsdigita.web.URL;
|
import com.arsdigita.web.URL;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.util.Strings;
|
||||||
import org.libreccm.cdi.utils.CdiUtil;
|
import org.libreccm.cdi.utils.CdiUtil;
|
||||||
import org.libreccm.configuration.ConfigurationManager;
|
import org.libreccm.configuration.ConfigurationManager;
|
||||||
import org.libreccm.security.ChallengeManager;
|
import org.libreccm.security.ChallengeManager;
|
||||||
|
import org.libreccm.security.RegistrationManager;
|
||||||
import org.libreccm.security.Shiro;
|
import org.libreccm.security.Shiro;
|
||||||
import org.libreccm.security.User;
|
import org.libreccm.security.User;
|
||||||
import org.libreccm.security.UserManager;
|
import org.libreccm.security.UserManager;
|
||||||
|
|
@ -82,17 +84,6 @@ public class UserNewForm extends Form {
|
||||||
addListeners();
|
addListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
// public UserNewForm(String name) {
|
|
||||||
// super(name);
|
|
||||||
// addWidgets();
|
|
||||||
// addListeners();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public UserNewForm(final String name, final Container container) {
|
|
||||||
// super(name, container);
|
|
||||||
// addWidgets();
|
|
||||||
// addListeners();
|
|
||||||
// }
|
|
||||||
private void addWidgets() {
|
private void addWidgets() {
|
||||||
formPanel = new BoxPanel(BoxPanel.VERTICAL);
|
formPanel = new BoxPanel(BoxPanel.VERTICAL);
|
||||||
|
|
||||||
|
|
@ -103,8 +94,6 @@ public class UserNewForm extends Form {
|
||||||
"login.form.new_user.username.hint", LOGIN_BUNDLE));
|
"login.form.new_user.username.hint", LOGIN_BUNDLE));
|
||||||
userName.setMaxLength(32);
|
userName.setMaxLength(32);
|
||||||
userName.setSize(32);
|
userName.setSize(32);
|
||||||
userName.addValidationListener(new NotEmptyValidationListener());
|
|
||||||
userName.addValidationListener(new StringLengthValidationListener(32));
|
|
||||||
formPanel.add(userName);
|
formPanel.add(userName);
|
||||||
|
|
||||||
givenName = new TextField(GIVEN_NAME);
|
givenName = new TextField(GIVEN_NAME);
|
||||||
|
|
@ -114,8 +103,6 @@ public class UserNewForm extends Form {
|
||||||
"login.form.new_user.givenname.hint", LOGIN_BUNDLE));
|
"login.form.new_user.givenname.hint", LOGIN_BUNDLE));
|
||||||
givenName.setMaxLength(256);
|
givenName.setMaxLength(256);
|
||||||
givenName.setSize(32);
|
givenName.setSize(32);
|
||||||
givenName.addValidationListener(new NotEmptyValidationListener());
|
|
||||||
givenName.addValidationListener(new StringLengthValidationListener(256));
|
|
||||||
formPanel.add(givenName);
|
formPanel.add(givenName);
|
||||||
|
|
||||||
familyName = new TextField(FAMILY_NAME);
|
familyName = new TextField(FAMILY_NAME);
|
||||||
|
|
@ -125,9 +112,6 @@ public class UserNewForm extends Form {
|
||||||
"login.form.new_user.familyname.hint", LOGIN_BUNDLE));
|
"login.form.new_user.familyname.hint", LOGIN_BUNDLE));
|
||||||
familyName.setMaxLength(256);
|
familyName.setMaxLength(256);
|
||||||
familyName.setSize(32);
|
familyName.setSize(32);
|
||||||
familyName.addValidationListener(new NotEmptyValidationListener());
|
|
||||||
familyName.addValidationListener(
|
|
||||||
new StringLengthValidationListener(256));
|
|
||||||
formPanel.add(familyName);
|
formPanel.add(familyName);
|
||||||
|
|
||||||
email = new TextField(EMAIL);
|
email = new TextField(EMAIL);
|
||||||
|
|
@ -137,8 +121,6 @@ public class UserNewForm extends Form {
|
||||||
LOGIN_BUNDLE));
|
LOGIN_BUNDLE));
|
||||||
email.setMaxLength(256);
|
email.setMaxLength(256);
|
||||||
email.setSize(48);
|
email.setSize(48);
|
||||||
email.addValidationListener(new NotEmptyValidationListener());
|
|
||||||
email.addValidationListener(new StringLengthValidationListener(256));
|
|
||||||
formPanel.add(email);
|
formPanel.add(email);
|
||||||
|
|
||||||
password = new Password(PASSWORD);
|
password = new Password(PASSWORD);
|
||||||
|
|
@ -148,7 +130,6 @@ public class UserNewForm extends Form {
|
||||||
"login.form.new_user.password.hint", LOGIN_BUNDLE));
|
"login.form.new_user.password.hint", LOGIN_BUNDLE));
|
||||||
password.setMaxLength(256);
|
password.setMaxLength(256);
|
||||||
password.setSize(32);
|
password.setSize(32);
|
||||||
password.addValidationListener(new NotEmptyValidationListener());
|
|
||||||
formPanel.add(password);
|
formPanel.add(password);
|
||||||
|
|
||||||
passwordConfirm = new Password(PASSWORD_CONFIRMATION);
|
passwordConfirm = new Password(PASSWORD_CONFIRMATION);
|
||||||
|
|
@ -158,7 +139,6 @@ public class UserNewForm extends Form {
|
||||||
"login.form.new_user.password_confirmation.hint", LOGIN_BUNDLE));
|
"login.form.new_user.password_confirmation.hint", LOGIN_BUNDLE));
|
||||||
passwordConfirm.setMaxLength(256);
|
passwordConfirm.setMaxLength(256);
|
||||||
passwordConfirm.setSize(32);
|
passwordConfirm.setSize(32);
|
||||||
passwordConfirm.addValidationListener(new NotEmptyValidationListener());
|
|
||||||
formPanel.add(passwordConfirm);
|
formPanel.add(passwordConfirm);
|
||||||
|
|
||||||
saveCancelSection = new SaveCancelSection();
|
saveCancelSection = new SaveCancelSection();
|
||||||
|
|
@ -210,34 +190,129 @@ public class UserNewForm extends Form {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final String userNameData = data.getString(USERNAME);
|
||||||
|
final String givenNameData = data.getString(GIVEN_NAME);
|
||||||
|
final String familyNameData = data.getString(FAMILY_NAME);
|
||||||
|
final String emailData = data.getString(EMAIL);
|
||||||
|
final String passwordData = data.getString(PASSWORD);
|
||||||
|
final String passwordConfirmationData = data.getString(
|
||||||
|
PASSWORD_CONFIRMATION);
|
||||||
|
|
||||||
|
if (Strings.isBlank(userNameData)) {
|
||||||
|
data.addError(
|
||||||
|
USERNAME,
|
||||||
|
new GlobalizedMessage(
|
||||||
|
"login.form.new_user.error.username.is_blank",
|
||||||
|
LOGIN_BUNDLE));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (userNameData != null && userNameData.length() > 32) {
|
||||||
|
data.addError(
|
||||||
|
USERNAME,
|
||||||
|
new GlobalizedMessage(
|
||||||
|
"login.form.new_user.error.username.too_long",
|
||||||
|
LOGIN_BUNDLE));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Strings.isBlank(givenNameData)) {
|
||||||
|
data.addError(
|
||||||
|
GIVEN_NAME,
|
||||||
|
new GlobalizedMessage(
|
||||||
|
"login.form.new_user.error.givenname.is_blank",
|
||||||
|
LOGIN_BUNDLE));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (givenNameData != null && givenNameData.length() > 256) {
|
||||||
|
data.addError(
|
||||||
|
GIVEN_NAME,
|
||||||
|
new GlobalizedMessage(
|
||||||
|
"login.form.new_user.error.givename.too_long",
|
||||||
|
LOGIN_BUNDLE));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Strings.isBlank(familyNameData)) {
|
||||||
|
data.addError(
|
||||||
|
FAMILY_NAME,
|
||||||
|
new GlobalizedMessage(
|
||||||
|
"login.form.new_user.error.familyname.is_blank",
|
||||||
|
LOGIN_BUNDLE));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (familyNameData != null && familyNameData.length() > 256) {
|
||||||
|
data.addError(
|
||||||
|
FAMILY_NAME,
|
||||||
|
new GlobalizedMessage(
|
||||||
|
"login.form.new_user.error.familyname.too_long",
|
||||||
|
LOGIN_BUNDLE));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Strings.isBlank(emailData)) {
|
||||||
|
data.addError(
|
||||||
|
EMAIL,
|
||||||
|
new GlobalizedMessage(
|
||||||
|
"login.form.new_user.error.email.is_blank",
|
||||||
|
LOGIN_BUNDLE));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (emailData != null && emailData.length() > 256) {
|
||||||
|
data.addError(
|
||||||
|
EMAIL,
|
||||||
|
new GlobalizedMessage(
|
||||||
|
"login.form.new_user.error.email.too_long",
|
||||||
|
LOGIN_BUNDLE));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Strings.isBlank(passwordData)) {
|
||||||
|
data.addError(
|
||||||
|
PASSWORD,
|
||||||
|
new GlobalizedMessage(
|
||||||
|
"login.form.new_user.error.password.is_blank",
|
||||||
|
LOGIN_BUNDLE));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Strings.isBlank(passwordConfirmationData)) {
|
||||||
|
data.addError(
|
||||||
|
PASSWORD_CONFIRMATION,
|
||||||
|
new GlobalizedMessage(
|
||||||
|
"login.form.new_user.error.password.is_blank",
|
||||||
|
LOGIN_BUNDLE));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final UserRepository userRepository = cdiUtil.findBean(
|
final UserRepository userRepository = cdiUtil.findBean(
|
||||||
UserRepository.class);
|
UserRepository.class);
|
||||||
//check if there is already an account for the provided email
|
//check if there is already an account for the provided email
|
||||||
if (userRepository.findByEmailAddress((String) data.get(
|
if (userRepository.findByEmailAddress(emailData) != null) {
|
||||||
EMAIL)) != null) {
|
data.addError(
|
||||||
data.addError(new GlobalizedMessage(
|
EMAIL,
|
||||||
"login.form.new_user.error.email_already_registered",
|
new GlobalizedMessage(
|
||||||
LOGIN_BUNDLE));
|
"login.form.new_user.error.email_already_registered",
|
||||||
|
LOGIN_BUNDLE));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if username is already in use
|
//check if username is already in use
|
||||||
if (userRepository.findByName((String) data.get(USERNAME))
|
if (userRepository.findByName(userNameData) != null) {
|
||||||
!= null) {
|
data.addError(
|
||||||
data.addError(new GlobalizedMessage(
|
USERNAME,
|
||||||
"login.form.new_user.error.username_already_in_use",
|
new GlobalizedMessage(
|
||||||
LOGIN_BUNDLE));
|
"login.form.new_user.error.username_already_in_use",
|
||||||
|
LOGIN_BUNDLE));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check if password and confirmation match
|
//Check if password and confirmation match
|
||||||
final String passwordData = (String) data.get(PASSWORD);
|
if (!passwordData.equals(passwordConfirmationData)) {
|
||||||
final String confirmation = (String) data.get(
|
data.addError(
|
||||||
PASSWORD_CONFIRMATION);
|
PASSWORD,
|
||||||
|
new GlobalizedMessage(
|
||||||
if (!passwordData.equals(confirmation)) {
|
"login.form.new_user.error.passwords_do_not_match",
|
||||||
data.addError(new GlobalizedMessage(
|
LOGIN_BUNDLE));
|
||||||
"login.form.new_user.error.passwords_do_not_match",
|
|
||||||
LOGIN_BUNDLE));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -252,31 +327,48 @@ public class UserNewForm extends Form {
|
||||||
|
|
||||||
final Shiro shiro = cdiUtil.findBean(Shiro.class);
|
final Shiro shiro = cdiUtil.findBean(Shiro.class);
|
||||||
shiro.getSystemUser().execute(() -> {
|
shiro.getSystemUser().execute(() -> {
|
||||||
final UserRepository userRepository = cdiUtil.findBean(
|
// final UserRepository userRepository = cdiUtil.findBean(
|
||||||
UserRepository.class);
|
// UserRepository.class);
|
||||||
final UserManager userManager = cdiUtil.findBean(
|
// final UserManager userManager = cdiUtil.findBean(
|
||||||
UserManager.class);
|
// UserManager.class);
|
||||||
|
//
|
||||||
|
// final String givenNameData = (String) data.get(
|
||||||
|
// GIVEN_NAME);
|
||||||
|
// final String familyNameData = (String) data
|
||||||
|
// .get(FAMILY_NAME);
|
||||||
|
// final String username = (String) data.get(USERNAME);
|
||||||
|
// final String emailAddress = (String) data.get(EMAIL);
|
||||||
|
// final String passwordData = (String) data.get(PASSWORD);
|
||||||
|
// final User user = userManager.createUser(givenNameData,
|
||||||
|
// familyNameData,
|
||||||
|
// username,
|
||||||
|
// emailAddress,
|
||||||
|
// passwordData);
|
||||||
|
// user.setBanned(true);
|
||||||
|
// userRepository.save(user);
|
||||||
|
//
|
||||||
|
// //challenge erzeugen
|
||||||
|
// final ChallengeManager challengeManager = cdiUtil
|
||||||
|
// .findBean(ChallengeManager.class);
|
||||||
|
// try {
|
||||||
|
// challengeManager.sendAccountActivation(user);
|
||||||
|
// } catch (MessagingException ex) {
|
||||||
|
// throw new FormProcessException(
|
||||||
|
// "Failed to send account activation challenge.",
|
||||||
|
// new GlobalizedMessage(
|
||||||
|
// "login.form_new_user.error.creating_challenge_failed",
|
||||||
|
// LOGIN_BUNDLE), ex);
|
||||||
|
// }
|
||||||
|
|
||||||
final String givenNameData = (String) data.get(
|
final RegistrationManager registrationManager = cdiUtil
|
||||||
GIVEN_NAME);
|
.findBean(RegistrationManager.class);
|
||||||
final String familyNameData = (String) data
|
|
||||||
.get(FAMILY_NAME);
|
|
||||||
final String username = (String) data.get(USERNAME);
|
|
||||||
final String emailAddress = (String) data.get(EMAIL);
|
|
||||||
final String passwordData = (String) data.get(PASSWORD);
|
|
||||||
final User user = userManager.createUser(givenNameData,
|
|
||||||
familyNameData,
|
|
||||||
username,
|
|
||||||
emailAddress,
|
|
||||||
passwordData);
|
|
||||||
user.setBanned(true);
|
|
||||||
userRepository.save(user);
|
|
||||||
|
|
||||||
//challenge erzeugen
|
|
||||||
final ChallengeManager challengeManager = cdiUtil
|
|
||||||
.findBean(ChallengeManager.class);
|
|
||||||
try {
|
try {
|
||||||
challengeManager.sendAccountActivation(user);
|
registrationManager.registerUser(
|
||||||
|
data.getString(USERNAME),
|
||||||
|
data.getString(FAMILY_NAME),
|
||||||
|
data.getString(GIVEN_NAME),
|
||||||
|
data.getString(EMAIL),
|
||||||
|
data.getString(PASSWORD));
|
||||||
} catch (MessagingException ex) {
|
} catch (MessagingException ex) {
|
||||||
throw new FormProcessException(
|
throw new FormProcessException(
|
||||||
"Failed to send account activation challenge.",
|
"Failed to send account activation challenge.",
|
||||||
|
|
|
||||||
|
|
@ -305,7 +305,7 @@ public abstract class AbstractEntityRepository<K, E> {
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
throw new IllegalArgumentException("Can't delete a null entity.");
|
throw new IllegalArgumentException("Can't delete a null entity.");
|
||||||
}
|
}
|
||||||
|
|
||||||
//We need to make sure we use a none detached entity, therefore the merge
|
//We need to make sure we use a none detached entity, therefore the merge
|
||||||
entityManager.remove(entityManager.merge(entity));
|
entityManager.remove(entityManager.merge(entity));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,6 @@ import java.util.Objects;
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.mail.MessagingException;
|
import javax.mail.MessagingException;
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import static com.arsdigita.ui.login.LoginServlet.*;
|
import static com.arsdigita.ui.login.LoginServlet.*;
|
||||||
|
|
@ -102,6 +101,13 @@ public class ChallengeManager {
|
||||||
@Inject
|
@Inject
|
||||||
private HttpServletRequest request;
|
private HttpServletRequest request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a email verification challenge.
|
||||||
|
*
|
||||||
|
* @param user The user for which the challenge is created.
|
||||||
|
*
|
||||||
|
* @return The text of the challenge mail.
|
||||||
|
*/
|
||||||
public String createEmailVerification(final User user) {
|
public String createEmailVerification(final User user) {
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
|
|
@ -110,6 +116,15 @@ public class ChallengeManager {
|
||||||
return createMail(user, OneTimeAuthTokenPurpose.EMAIL_VERIFICATION);
|
return createMail(user, OneTimeAuthTokenPurpose.EMAIL_VERIFICATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a email verification challenge and sends it to the user per email
|
||||||
|
* using the users primary email address.
|
||||||
|
*
|
||||||
|
* @param user The user to which the challenge is send.
|
||||||
|
*
|
||||||
|
* @throws MessagingException If there is a problem sending the email to the
|
||||||
|
* user.
|
||||||
|
*/
|
||||||
public void sendEmailVerification(final User user)
|
public void sendEmailVerification(final User user)
|
||||||
throws MessagingException {
|
throws MessagingException {
|
||||||
final String text = createEmailVerification(user);
|
final String text = createEmailVerification(user);
|
||||||
|
|
@ -119,6 +134,17 @@ public class ChallengeManager {
|
||||||
text);
|
text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finishes a email verification challenge. Checks if the submitted token
|
||||||
|
* matches the token stored in the database and removes the challenge from
|
||||||
|
* the database.
|
||||||
|
*
|
||||||
|
* @param user The user which submitted the request.
|
||||||
|
* @param submittedToken The token submitted by the user.
|
||||||
|
*
|
||||||
|
* @throws ChallengeFailedException If the provided token does not match the
|
||||||
|
* stored token.
|
||||||
|
*/
|
||||||
public void finishEmailVerification(final User user,
|
public void finishEmailVerification(final User user,
|
||||||
final String submittedToken)
|
final String submittedToken)
|
||||||
throws ChallengeFailedException {
|
throws ChallengeFailedException {
|
||||||
|
|
@ -138,6 +164,14 @@ public class ChallengeManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an account activation challenge. This is used for example when a
|
||||||
|
* new users is registered using the login application.
|
||||||
|
*
|
||||||
|
* @param user The user for which the challenge is created.
|
||||||
|
*
|
||||||
|
* @return The challenge message.
|
||||||
|
*/
|
||||||
public String createAccountActivation(final User user) {
|
public String createAccountActivation(final User user) {
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
|
|
@ -146,6 +180,14 @@ public class ChallengeManager {
|
||||||
return createMail(user, OneTimeAuthTokenPurpose.ACCOUNT_ACTIVATION);
|
return createMail(user, OneTimeAuthTokenPurpose.ACCOUNT_ACTIVATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a account activation challenge and sends it to the user by email.
|
||||||
|
*
|
||||||
|
* @param user The user to which the challenge is send.
|
||||||
|
*
|
||||||
|
* @throws MessagingException If something goes wrong when sending the
|
||||||
|
* message.
|
||||||
|
*/
|
||||||
public void sendAccountActivation(final User user)
|
public void sendAccountActivation(final User user)
|
||||||
throws MessagingException {
|
throws MessagingException {
|
||||||
final String text = createAccountActivation(user);
|
final String text = createAccountActivation(user);
|
||||||
|
|
@ -155,6 +197,17 @@ public class ChallengeManager {
|
||||||
text);
|
text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finishes an account activation challenge. If the submitted token matches
|
||||||
|
* the stored token the {@code banned} status for the user is set to
|
||||||
|
* {@link false}.
|
||||||
|
*
|
||||||
|
* @param user The user which submitted the request.
|
||||||
|
* @param submittedToken The submitted token.
|
||||||
|
*
|
||||||
|
* @throws ChallengeFailedException If the submitted token does not match
|
||||||
|
* the stored token.
|
||||||
|
*/
|
||||||
public void finishAccountActivation(final User user,
|
public void finishAccountActivation(final User user,
|
||||||
final String submittedToken)
|
final String submittedToken)
|
||||||
throws ChallengeFailedException {
|
throws ChallengeFailedException {
|
||||||
|
|
@ -173,6 +226,13 @@ public class ChallengeManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a password recover challenge for a user.
|
||||||
|
*
|
||||||
|
* @param user The user for which the password recover challenge is created.
|
||||||
|
*
|
||||||
|
* @return The challenge message.
|
||||||
|
*/
|
||||||
public String createPasswordRecover(final User user) {
|
public String createPasswordRecover(final User user) {
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
|
|
@ -181,6 +241,15 @@ public class ChallengeManager {
|
||||||
return createMail(user, OneTimeAuthTokenPurpose.RECOVER_PASSWORD);
|
return createMail(user, OneTimeAuthTokenPurpose.RECOVER_PASSWORD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a password recover challenge for the provided author and sends it
|
||||||
|
* the user via email.
|
||||||
|
*
|
||||||
|
* @param user The user for which the challenge is created.
|
||||||
|
*
|
||||||
|
* @throws MessagingException If something goes wrong when sending the
|
||||||
|
* message.
|
||||||
|
*/
|
||||||
public void sendPasswordRecover(final User user)
|
public void sendPasswordRecover(final User user)
|
||||||
throws MessagingException {
|
throws MessagingException {
|
||||||
final String text = createPasswordRecover(user);
|
final String text = createPasswordRecover(user);
|
||||||
|
|
@ -190,6 +259,18 @@ public class ChallengeManager {
|
||||||
text);
|
text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finishes a password recover challenge. If the submitted token matches to
|
||||||
|
* stored token the password of the user is set to the provided new
|
||||||
|
* password.
|
||||||
|
*
|
||||||
|
* @param user The user which submitted the request.
|
||||||
|
* @param submittedToken The submitted token.
|
||||||
|
* @param newPassword The new password.
|
||||||
|
*
|
||||||
|
* @throws ChallengeFailedException If the submitted token does not match
|
||||||
|
* the stored token.
|
||||||
|
*/
|
||||||
public void finishPasswordRecover(final User user,
|
public void finishPasswordRecover(final User user,
|
||||||
final String submittedToken,
|
final String submittedToken,
|
||||||
final String newPassword)
|
final String newPassword)
|
||||||
|
|
@ -211,6 +292,15 @@ public class ChallengeManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper method for creating the emails send the the {@code send*}
|
||||||
|
* methods.
|
||||||
|
*
|
||||||
|
* @param user The user to which the mail is send.
|
||||||
|
* @param purpose The purpose of the challenge.
|
||||||
|
*
|
||||||
|
* @return The text of the mail.
|
||||||
|
*/
|
||||||
private String createMail(final User user,
|
private String createMail(final User user,
|
||||||
final OneTimeAuthTokenPurpose purpose) {
|
final OneTimeAuthTokenPurpose purpose) {
|
||||||
final OneTimeAuthToken token = oneTimeAuthManager.createForUser(
|
final OneTimeAuthToken token = oneTimeAuthManager.createForUser(
|
||||||
|
|
@ -254,6 +344,14 @@ public class ChallengeManager {
|
||||||
return substitutor.replace(template);
|
return substitutor.replace(template);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for retrieving the email subject from the
|
||||||
|
* {@link EmailTemplates} configuration.
|
||||||
|
*
|
||||||
|
* @param purpose The purpose of the challenge.
|
||||||
|
*
|
||||||
|
* @return The subject for the challenge mail for the provided purpose.
|
||||||
|
*/
|
||||||
private String retrieveEmailSubject(final OneTimeAuthTokenPurpose purpose) {
|
private String retrieveEmailSubject(final OneTimeAuthTokenPurpose purpose) {
|
||||||
LOGGER.debug("Retreving email subject...");
|
LOGGER.debug("Retreving email subject...");
|
||||||
final Locale locale = globalizationHelper.getNegotiatedLocale();
|
final Locale locale = globalizationHelper.getNegotiatedLocale();
|
||||||
|
|
@ -290,6 +388,13 @@ public class ChallengeManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for retrieving the email template.
|
||||||
|
*
|
||||||
|
* @param purpose The purpose of the challenge.
|
||||||
|
*
|
||||||
|
* @return The template for the challenge message for the provided purpose.
|
||||||
|
*/
|
||||||
private String retrieveEmailTemplate(
|
private String retrieveEmailTemplate(
|
||||||
final OneTimeAuthTokenPurpose purpose) {
|
final OneTimeAuthTokenPurpose purpose) {
|
||||||
|
|
||||||
|
|
@ -326,6 +431,19 @@ public class ChallengeManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for validating a submitted token and deleting the
|
||||||
|
* {@link OneTimeAuthToken} for the challenge.
|
||||||
|
*
|
||||||
|
* @param user The user which submitted the challenge.
|
||||||
|
* @param submittedToken The token submitted by the user.
|
||||||
|
* @param purpose The purpose of the challenge.
|
||||||
|
*
|
||||||
|
* @return {@code true} If the provided token matches the stored token,
|
||||||
|
* {@code false} if not.
|
||||||
|
*
|
||||||
|
* @throws ChallengeFailedException
|
||||||
|
*/
|
||||||
private boolean finishChallenge(final User user,
|
private boolean finishChallenge(final User user,
|
||||||
final String submittedToken,
|
final String submittedToken,
|
||||||
final OneTimeAuthTokenPurpose purpose)
|
final OneTimeAuthTokenPurpose purpose)
|
||||||
|
|
@ -361,6 +479,15 @@ public class ChallengeManager {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for sending emails.
|
||||||
|
*
|
||||||
|
* @param user The user to which the mail is send.
|
||||||
|
* @param subject The subject of the mail.
|
||||||
|
* @param text The text (body) of the mail.
|
||||||
|
*
|
||||||
|
* @throws MessagingException If something goes wrong when sending the mail.
|
||||||
|
*/
|
||||||
private void sendMessage(final User user,
|
private void sendMessage(final User user,
|
||||||
final String subject,
|
final String subject,
|
||||||
final String text) throws MessagingException {
|
final String text) throws MessagingException {
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,7 @@ import java.util.List;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.ejb.DependsOn;
|
|
||||||
import javax.ejb.Singleton;
|
import javax.ejb.Singleton;
|
||||||
import javax.ejb.Startup;
|
|
||||||
import javax.ejb.Stateless;
|
|
||||||
import javax.ejb.Timeout;
|
import javax.ejb.Timeout;
|
||||||
import javax.ejb.TimerConfig;
|
import javax.ejb.TimerConfig;
|
||||||
import javax.ejb.TimerService;
|
import javax.ejb.TimerService;
|
||||||
|
|
@ -66,6 +63,9 @@ public class OneTimeAuthTokenCleaner {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private OneTimeAuthManager oneTimeAuthManager;
|
private OneTimeAuthManager oneTimeAuthManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private UserRepository userRepository;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
|
|
@ -79,8 +79,8 @@ public class OneTimeAuthTokenCleaner {
|
||||||
LOGGER.debug("Creating interval for {} s.", interval / 1000);
|
LOGGER.debug("Creating interval for {} s.", interval / 1000);
|
||||||
// LOGGER.debug("First run cleaning process will be executed in {} s.",
|
// LOGGER.debug("First run cleaning process will be executed in {} s.",
|
||||||
// interval / 1000);
|
// interval / 1000);
|
||||||
timerService.createIntervalTimer(interval,
|
timerService.createIntervalTimer(interval,
|
||||||
interval,
|
interval,
|
||||||
new TimerConfig());
|
new TimerConfig());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -99,25 +99,30 @@ public class OneTimeAuthTokenCleaner {
|
||||||
tokens.forEach(t -> {
|
tokens.forEach(t -> {
|
||||||
if (oneTimeAuthManager.isValid(t)) {
|
if (oneTimeAuthManager.isValid(t)) {
|
||||||
LOGGER.debug("OneTimeAuthToken with id {} is still valid. "
|
LOGGER.debug("OneTimeAuthToken with id {} is still valid. "
|
||||||
+ "Expires at {}.",
|
+ "Expires at {}.",
|
||||||
t.getTokenId(),
|
t.getTokenId(),
|
||||||
t.getValidUntil());
|
t.getValidUntil());
|
||||||
} else {
|
} else {
|
||||||
LOGGER.debug("OneTimeAuthToken with id {} is invalid. "
|
LOGGER.debug("OneTimeAuthToken with id {} is invalid. "
|
||||||
+ "Expires at {} UTC.",
|
+ "Expires at {} UTC.",
|
||||||
t.getTokenId(),
|
t.getTokenId(),
|
||||||
t.getValidUntil());
|
t.getValidUntil());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens.stream()
|
tokens.stream()
|
||||||
.filter((token) -> (!oneTimeAuthManager.isValid(token)))
|
.filter((token) -> (!oneTimeAuthManager.isValid(token)))
|
||||||
.forEach((token) -> {
|
.forEach((token) -> {
|
||||||
LOGGER.debug("Token with id {} expired at {} UTC. "
|
LOGGER.debug("Token with id {} expired at {} UTC. "
|
||||||
+ "Invalidating token.",
|
+ "Invalidating token.",
|
||||||
token.getTokenId(), token.getValidUntil());
|
token.getTokenId(), token.getValidUntil());
|
||||||
oneTimeAuthManager.invalidate(token);
|
oneTimeAuthManager.invalidate(token);
|
||||||
|
if (token.getPurpose()
|
||||||
|
== OneTimeAuthTokenPurpose.ACCOUNT_ACTIVATION) {
|
||||||
|
final User user = token.getUser();
|
||||||
|
userRepository.delete(user);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,159 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 LibreCCM Foundation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.libreccm.security;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.FormProcessException;
|
||||||
|
import com.arsdigita.globalization.GlobalizedMessage;
|
||||||
|
import com.arsdigita.ui.login.UserNewForm;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.util.Strings;
|
||||||
|
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.mail.MessagingException;
|
||||||
|
|
||||||
|
import static com.arsdigita.ui.login.LoginConstants.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The CDI bean encapsulates all steps for registering a user, for example by a
|
||||||
|
* form provided to the user (like the {@link UserNewForm} of the login
|
||||||
|
* application).
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
public class RegistrationManager {
|
||||||
|
|
||||||
|
public static final String REGISTERED_USERS = "registered-users";
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private UserRepository userRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private UserManager userManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private GroupRepository groupRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private GroupManager groupManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ChallengeManager challengeManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a new user.
|
||||||
|
*
|
||||||
|
* The method checks if there is already a{@code user} with the same
|
||||||
|
* {@code user} name and/or email address than the provided. In that case an
|
||||||
|
* {@link IllegalArgumentException} is thrown.
|
||||||
|
*
|
||||||
|
* If there is no {@code user} with the same username and/or email address
|
||||||
|
* than the provided {@code user} the new {@code user} is created and added
|
||||||
|
* to the group {@code registered-users}. If the group does exists the group
|
||||||
|
* is created.
|
||||||
|
*
|
||||||
|
* Finally the method creates a {@code user} activation challenge and sends
|
||||||
|
* it to the user.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param userName The user name of the new user.
|
||||||
|
* @param familyName The family name of the new user.
|
||||||
|
* @param givenName The given name of the new user.
|
||||||
|
* @param emailAddress The email address of the new user.
|
||||||
|
* @param password The password of the new user.
|
||||||
|
*
|
||||||
|
* @throws MessagingException If there is problem sending the
|
||||||
|
* activation challenge to the new user.
|
||||||
|
* @throws IllegalArgumentException If the provided {@code user} is
|
||||||
|
*/
|
||||||
|
public void registerUser(final String userName,
|
||||||
|
final String familyName,
|
||||||
|
final String givenName,
|
||||||
|
final String emailAddress,
|
||||||
|
final String password) throws MessagingException {
|
||||||
|
|
||||||
|
if (Strings.isBlank(userName)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"The provided user name is blank.");
|
||||||
|
}
|
||||||
|
if (Strings.isBlank(familyName)) {
|
||||||
|
throw new IllegalArgumentException("The family name is blank.");
|
||||||
|
}
|
||||||
|
if (Strings.isBlank(givenName)) {
|
||||||
|
throw new IllegalArgumentException("The given name is blank.");
|
||||||
|
}
|
||||||
|
if (Strings.isBlank(emailAddress)) {
|
||||||
|
throw new IllegalArgumentException("The email address is blank.");
|
||||||
|
}
|
||||||
|
if (Strings.isBlank(password)) {
|
||||||
|
throw new IllegalArgumentException("The password is blank.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkIfUserNameExists(userName)) {
|
||||||
|
throw new IllegalArgumentException(String.format(
|
||||||
|
"There is already an user with the username \"%s\".",
|
||||||
|
userName));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkIfEmailIsInUse(emailAddress)) {
|
||||||
|
throw new IllegalArgumentException(String.format(
|
||||||
|
"The email address \"%s\" is already registered.",
|
||||||
|
emailAddress));
|
||||||
|
}
|
||||||
|
|
||||||
|
final User user = userManager.createUser(givenName,
|
||||||
|
familyName,
|
||||||
|
userName,
|
||||||
|
emailAddress,
|
||||||
|
password);
|
||||||
|
user.setBanned(true);
|
||||||
|
userRepository.save(user);
|
||||||
|
|
||||||
|
final Group registeredUsers = groupRepository.findByName(
|
||||||
|
REGISTERED_USERS);
|
||||||
|
final Group group;
|
||||||
|
if (registeredUsers == null) {
|
||||||
|
final Group newGroup = new Group();
|
||||||
|
newGroup.setName("registered-users");
|
||||||
|
groupRepository.save(newGroup);
|
||||||
|
group = newGroup;
|
||||||
|
} else {
|
||||||
|
group = registeredUsers;
|
||||||
|
}
|
||||||
|
|
||||||
|
groupManager.addMemberToGroup(user, group);
|
||||||
|
|
||||||
|
challengeManager.sendAccountActivation(user);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkIfUserNameExists(final String userName) {
|
||||||
|
final User user = userRepository.findByName(userName);
|
||||||
|
|
||||||
|
return user != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkIfEmailIsInUse(final String emailAddress) {
|
||||||
|
final User user = userRepository.findByEmailAddress(emailAddress);
|
||||||
|
|
||||||
|
return user != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -25,6 +25,7 @@ import java.util.List;
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
import javax.persistence.EntityGraph;
|
import javax.persistence.EntityGraph;
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Repository for user objects.
|
* Repository for user objects.
|
||||||
|
|
@ -159,4 +160,21 @@ public class UserRepository extends AbstractEntityRepository<Long, User> {
|
||||||
return query.getResultList();
|
return query.getResultList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void delete(final User entity) {
|
||||||
|
final User delete = getEntityManager().find(User.class,
|
||||||
|
entity.getPartyId());
|
||||||
|
|
||||||
|
delete.getGroupMemberships().forEach(m -> {
|
||||||
|
getEntityManager().remove(m);
|
||||||
|
});
|
||||||
|
|
||||||
|
delete.getRoleMemberships().forEach(m -> {
|
||||||
|
getEntityManager().remove(m);
|
||||||
|
});
|
||||||
|
|
||||||
|
getEntityManager().remove(delete);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -107,3 +107,12 @@ login.form.reset_password.error.password_mismatch=Password and confirmation do n
|
||||||
login.form.new_user.error.username_already_in_use=The provided user name is already in use. Please choose another user name.
|
login.form.new_user.error.username_already_in_use=The provided user name is already in use. Please choose another user name.
|
||||||
login.form.new_user.error.email_already_registered=There is an account already registered for the provided email address.
|
login.form.new_user.error.email_already_registered=There is an account already registered for the provided email address.
|
||||||
login.form.reset_password.scucess.login=Click here to login
|
login.form.reset_password.scucess.login=Click here to login
|
||||||
|
login.form.new_user.error.username.is_blank=The user name can't be blank.
|
||||||
|
login.form.new_user.error.username.too_long=The user name can't be longer then 32 characters.
|
||||||
|
login.form.new_user.error.givenname.is_blank=The given name can't be blank.
|
||||||
|
login.form.new_user.error.givename.too_long=The given name can't be longer than 256 characters.
|
||||||
|
login.form.new_user.error.familyname.is_blank=The family name can't be blank.
|
||||||
|
login.form.new_user.error.familyname.too_long=The family name can't be longer than 256 characters
|
||||||
|
login.form.new_user.error.email.is_blank=The Email address can't be empty.
|
||||||
|
login.form.new_user.error.email.too_long=The Email address can't be longer than 256 characters.
|
||||||
|
login.form.new_user.error.password.is_blank=The password can't be blank.
|
||||||
|
|
|
||||||
|
|
@ -107,3 +107,12 @@ login.form.reset_password.error.password_mismatch=Passwort und Best\u00e4tigung
|
||||||
login.form.new_user.error.username_already_in_use=Der eingegeben Benutzername ist bereits vergeben. Bitte w\u00e4hlen Sie einen anderen Benutzernamen.
|
login.form.new_user.error.username_already_in_use=Der eingegeben Benutzername ist bereits vergeben. Bitte w\u00e4hlen Sie einen anderen Benutzernamen.
|
||||||
login.form.new_user.error.email_already_registered=Es gibt bereits ein Benutzerkonto f\u00fcr die eingebene E-Mail-Adresse
|
login.form.new_user.error.email_already_registered=Es gibt bereits ein Benutzerkonto f\u00fcr die eingebene E-Mail-Adresse
|
||||||
login.form.reset_password.scucess.login=Zur Anmeldung
|
login.form.reset_password.scucess.login=Zur Anmeldung
|
||||||
|
login.form.new_user.error.username.is_blank=The user name can't be blank.
|
||||||
|
login.form.new_user.error.username.too_long=The user name can't be longer then 32 characters.
|
||||||
|
login.form.new_user.error.givenname.is_blank=The given name can't be blank.
|
||||||
|
login.form.new_user.error.givename.too_long=The given name can't be longer than 256 characters.
|
||||||
|
login.form.new_user.error.familyname.is_blank=The family name can't be blank.
|
||||||
|
login.form.new_user.error.familyname.too_long=The family name can't be longer than 256 characters
|
||||||
|
login.form.new_user.error.email.is_blank=The Email address can't be empty.
|
||||||
|
login.form.new_user.error.email.too_long=The Email address can't be longer than 256 characters.
|
||||||
|
login.form.new_user.error.password.is_blank=The password can't be blank.
|
||||||
|
|
|
||||||
|
|
@ -107,3 +107,12 @@ login.form.reset_password.error.password_mismatch=Password and confirmation do n
|
||||||
login.form.new_user.error.username_already_in_use=The provided user name is already in use. Please choose another user name.
|
login.form.new_user.error.username_already_in_use=The provided user name is already in use. Please choose another user name.
|
||||||
login.form.new_user.error.email_already_registered=There is an account already registered for the provided email address.
|
login.form.new_user.error.email_already_registered=There is an account already registered for the provided email address.
|
||||||
login.form.reset_password.scucess.login=Click here to login
|
login.form.reset_password.scucess.login=Click here to login
|
||||||
|
login.form.new_user.error.username.is_blank=Der Benutzername darf nicht leer sein.
|
||||||
|
login.form.new_user.error.username.too_long=Der Benutzername darf nicht l\u00e4nger als 32 Zeichen sein.
|
||||||
|
login.form.new_user.error.givenname.is_blank=Der Vorname darf nicht leer sein.
|
||||||
|
login.form.new_user.error.givename.too_long=Der Vorname kann nicht l\u00e4nger als 256 Zeichen sein.
|
||||||
|
login.form.new_user.error.familyname.is_blank=Der Familienname darf nicht leer sein.
|
||||||
|
login.form.new_user.error.familyname.too_long=Der Familienname darf nicht l\u00e4nger als 256 Zeichen sein.
|
||||||
|
login.form.new_user.error.email.is_blank=Die E-Mail-Adresse darf nicht leer sein.
|
||||||
|
login.form.new_user.error.email.too_long=Die E-Mail-Adresse darf nicht l\u00e4nger als 256 Zeichen sein.
|
||||||
|
login.form.new_user.error.password.is_blank=Das Passwort darf nicht leer sein.
|
||||||
|
|
|
||||||
|
|
@ -107,3 +107,12 @@ login.form.reset_password.error.password_mismatch=Password and confirmation do n
|
||||||
login.form.new_user.error.username_already_in_use=The provided user name is already in use. Please choose another user name.
|
login.form.new_user.error.username_already_in_use=The provided user name is already in use. Please choose another user name.
|
||||||
login.form.new_user.error.email_already_registered=There is an account already registered for the provided email address.
|
login.form.new_user.error.email_already_registered=There is an account already registered for the provided email address.
|
||||||
login.form.reset_password.scucess.login=Click here to login
|
login.form.reset_password.scucess.login=Click here to login
|
||||||
|
login.form.new_user.error.username.is_blank=The user name can't be blank.
|
||||||
|
login.form.new_user.error.username.too_long=The user name can't be longer then 32 characters.
|
||||||
|
login.form.new_user.error.givenname.is_blank=The given name can't be blank.
|
||||||
|
login.form.new_user.error.givename.too_long=The given name can't be longer than 256 characters.
|
||||||
|
login.form.new_user.error.familyname.is_blank=The family name can't be blank.
|
||||||
|
login.form.new_user.error.familyname.too_long=The family name can't be longer than 256 characters
|
||||||
|
login.form.new_user.error.email.is_blank=The Email address can't be empty.
|
||||||
|
login.form.new_user.error.email.too_long=The Email address can't be longer than 256 characters.
|
||||||
|
login.form.new_user.error.password.is_blank=The password can't be blank.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue