From 7868e168dcd84f35e7187cefcf387192059fe101 Mon Sep 17 00:00:00 2001 From: jensp Date: Mon, 30 Nov 2015 13:45:39 +0000 Subject: [PATCH] CCM NG: Migrated Login App to new org.libreccm.security API git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@3753 8810af33-2d31-482b-a856-94f89814c4df --- .../ui/login/ChangePasswordForm.java | 186 +++++++----------- .../arsdigita/ui/login/EmailInitListener.java | 68 +++---- .../com/arsdigita/ui/login/LoginServlet.java | 11 +- ...> RecoverPasswordPanel.java.nolongerinuse} | 0 .../ui/login/ScreenNameInitListener.java | 42 ++-- .../ui/login/UserAuthenticationListener.java | 55 +++--- .../com/arsdigita/ui/login/UserEditForm.java | 74 +++---- .../java/com/arsdigita/ui/login/UserForm.java | 161 ++++++--------- .../java/com/arsdigita/ui/login/UserInfo.java | 14 +- .../com/arsdigita/ui/login/UserLoginForm.java | 145 ++++++++------ .../ui/login/UserLogoutListener.java | 22 ++- .../com/arsdigita/ui/login/UserNewForm.java | 184 +++++++---------- .../java/org/libreccm/security/Shiro.java | 22 ++- .../org/libreccm/security/UserRepository.java | 2 +- 14 files changed, 460 insertions(+), 526 deletions(-) rename ccm-core/src/main/java/com/arsdigita/ui/login/{RecoverPasswordPanel.java => RecoverPasswordPanel.java.nolongerinuse} (100%) diff --git a/ccm-core/src/main/java/com/arsdigita/ui/login/ChangePasswordForm.java b/ccm-core/src/main/java/com/arsdigita/ui/login/ChangePasswordForm.java index a79bc5f2c..14e369f52 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/login/ChangePasswordForm.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/login/ChangePasswordForm.java @@ -55,6 +55,10 @@ import org.libreccm.cdi.utils.CdiUtil; import org.libreccm.security.User; import java.util.logging.Level; +import org.apache.shiro.subject.Subject; +import org.libreccm.security.Shiro; +import org.libreccm.security.UserManager; +import org.libreccm.security.UserRepository; /** * A Form that allows a user to change their password by entering their old @@ -70,19 +74,19 @@ import java.util.logging.Level; * */ public class ChangePasswordForm extends Form - implements FormProcessListener, - FormValidationListener { + implements FormProcessListener, + FormValidationListener { private static final Logger s_log = Logger.getLogger( - ChangePasswordForm.class.getName()); + ChangePasswordForm.class.getName()); final static String CHANGE_PASSWORD_FORM_NAME = "change-password"; final static String OLD_PASSWORD_PARAM_NAME = "old-password"; final static String NEW_PASSWORD_PARAM_NAME = "new-password"; final static String CONFIRM_PASSWORD_PARAM_NAME = "confirm-password"; final static String RETURN_URL_PARAM_NAME - = LoginHelper.RETURN_URL_PARAM_NAME; + = LoginHelper.RETURN_URL_PARAM_NAME; private final UserAuthenticationListener m_listener - = new UserAuthenticationListener(); + = new UserAuthenticationListener(); private Hidden m_returnURL; // private Hidden m_recovery; private Label m_oldPasswordLabel; @@ -127,32 +131,33 @@ public class ChangePasswordForm extends Form add(m_returnURL); final CdiUtil cdiUtil = new CdiUtil(); -// final CcmSessionContext sessionContext; -// try { -// sessionContext = cdiUtil.findBean(CcmSessionContext.class); -// } catch (CdiLookupException ex) { -// throw new UncheckedWrapperException(""); -// } -// final Subject subject = sessionContext.getCurrentSubject(); -// if (subject != null && subject instanceof User) { -// final User user = (User) subject; -// final Label greeting = new Label( -// LoginHelper.getMessage( -// "login.changePasswortForm.greeting", -// new Object[]{String.format("%s %s", -// user.getName().getGivenName(), -// user.getName().getFamilyName())})); -// greeting.setFontWeight(Label.BOLD); -// greeting.setClassAttr("greeting"); -// add(greeting); -// } + final Subject subject; + final Shiro shiro; + try { + subject = cdiUtil.findBean(Subject.class); + shiro = cdiUtil.findBean(Shiro.class); + } catch (CdiLookupException ex) { + throw new UncheckedWrapperException(ex); + } + + final KernelConfig kernelConfig = KernelConfig.getConfig(); + final User user = shiro.getUser(); + + final Label greeting = new Label(LoginHelper.getMessage( + "login.changePasswordForm.greeting", + new Object[]{String.format("%s %s", + user.getGivenName(), + user.getFamilyName())})); + greeting.setFontWeight(Label.BOLD); + greeting.setClassAttr("greeting"); + add(greeting); add(new Label(LoginHelper.getMessage( - "login.changePasswortForm.introText"))); + "login.changePasswortForm.introText"))); // old password m_oldPasswordLabel = new Label(LoginHelper.getMessage( - "login.changePasswordForm.oldPasswordLabel")); + "login.changePasswordForm.oldPasswordLabel")); add(m_oldPasswordLabel); m_oldPassword = new Password(OLD_PASSWORD_PARAM_NAME); // don't use NotNullValidationListener because @@ -162,14 +167,14 @@ public class ChangePasswordForm extends Form // new password Object[] params = new Object[]{PasswordValidationListener.MIN_LENGTH}; add(new Label(LoginHelper.getMessage( - "login.changePasswordForm.newPasswordLabel", params))); + "login.changePasswordForm.newPasswordLabel", params))); m_newPassword = new Password(NEW_PASSWORD_PARAM_NAME); m_newPassword.addValidationListener(new PasswordValidationListener()); add(m_newPassword); // confirm new password add(new Label(LoginHelper.getMessage( - "login.changePasswordForm.confirmPasswordLabel"))); + "login.changePasswordForm.confirmPasswordLabel"))); m_confirmPassword = new Password(CONFIRM_PASSWORD_PARAM_NAME); // don't use PasswordValidationListener to avoid duplicate errors m_confirmPassword.addValidationListener(new NotNullValidationListener()); @@ -182,7 +187,7 @@ public class ChangePasswordForm extends Form @Override public void validate(final FormSectionEvent event) - throws FormProcessException { + throws FormProcessException { PageState state = event.getPageState(); FormData data = event.getFormData(); try { @@ -190,8 +195,8 @@ public class ChangePasswordForm extends Form if (!m_listener.isLoggedIn(state)) { // this error should never appear data.addError(LoginHelper.localize( - "login.changePasswordForm.noUserError", - state.getRequest())); + "login.changePasswordForm.noUserError", + state.getRequest())); return; } // User user = m_listener.getUser(state); @@ -200,36 +205,24 @@ public class ChangePasswordForm extends Form String oldPassword = (String) m_oldPassword.getValue(state); String newPassword = (String) m_newPassword.getValue(state); String confirmPassword = (String) m_confirmPassword.getValue(state); - - // check old password unless recovering -// try { -// // The old password can never be null or contain leading or -// // trailing slashes. -// if (oldPassword == null -// || !oldPassword.trim().equals(oldPassword)) { -// data.addError(OLD_PASSWORD_PARAM_NAME, LoginHelper -// .localize( -// "login.changePasswordForm.badPasswordError", -// state.getRequest())); -// return; -// } -// -// final CdiUtil cdiUtil = new CdiUtil(); -//// final UserManager userManager = cdiUtil.findBean( -//// UserManager.class); -//// if (!userManager.verifyPasswordForUser( -//// user, oldPassword)) { -//// data.addError(OLD_PASSWORD_PARAM_NAME, -//// LoginHelper.localize( -//// "login.changePasswordForm.badPasswordError", -//// state.getRequest())); -//// return; -//// } -// } catch (CdiLookupException ex) { -// throw new UncheckedWrapperException( -// "Failed to lookup UserManager", ex); -// } - + + //check oldPassword + final Shiro shiro; + final UserManager userManager; + try { + final CdiUtil cdiUtil = new CdiUtil(); + shiro = cdiUtil.findBean(Shiro.class); + userManager = cdiUtil.findBean(UserManager.class); + } catch(CdiLookupException ex) { + throw new UncheckedWrapperException(ex); + } + + final User user = shiro.getUser(); + if (!userManager.verifyPassword(user, oldPassword)) { + data.addError(OLD_PASSWORD_PARAM_NAME, LoginHelper.getMessage( + "login.changePasswordForm.badPasswordError")); + } + // check new password if (newPassword.equals(oldPassword)) { data.addError(NEW_PASSWORD_PARAM_NAME, LoginHelper.localize( @@ -255,7 +248,7 @@ public class ChangePasswordForm extends Form @Override public void process(final FormSectionEvent event) - throws FormProcessException { + throws FormProcessException { PageState state = event.getPageState(); FormData data = event.getFormData(); @@ -263,59 +256,26 @@ public class ChangePasswordForm extends Form if (!m_listener.isLoggedIn(state)) { // this error should never appear (checked in validate) data.addError(LoginHelper.localize( - "login.changePasswordForm.noUserError", - state.getRequest())); + "login.changePasswordForm.noUserError", + state.getRequest())); return; } -// User user = m_listener.getUser(state); -// -// // set new password -// try { -// final CdiUtil cdiUtil = new CdiUtil(); -// final UserManager userManager = cdiUtil.findBean(UserManager.class); -// final UserRepository userRepository = cdiUtil.findBean( -// UserRepository.class); -// -// String newPassword = (String) m_newPassword.getValue(state); -// userManager.updatePassword(user, newPassword); -// userRepository.save(user); -// -// s_log.debug("committing password change"); -// } catch (CdiLookupException ex) { -// throw new UncheckedWrapperException( -// "Failed to lookup UserManager or UserRepository", ex); -// } - - // mail report to user -// if (!user.getEmailAddresses().isEmpty()) { -// -// final HttpServletRequest req = state.getRequest(); -// -// final String to = user.getEmailAddresses().get(0).getAddress(); -// final String from = SecurityConfig.getConfig() -// .getAdminContactEmail(); -// final String name = user.getName().getGivenName(); -// final String subject = LoginHelper.localize( -// "login.changePasswordForm.mailSubject", req); -// final String body = LoginHelper.localize( -// "login.changePasswordForm.mailBody", -// new Object[]{name}, -// req); -// -// // try to send the message, but don't throw the exception -// // if it fails so that the password change is comitted -// // anyway. -// try { -// Mail.send(to, from, subject, body); -// } catch (javax.mail.MessagingException e) { -// s_log.error("Could not notify user of password change", e); -// } -// } else { -// s_log.debug("Could not notify user of password change: " -// + "null email, user ID: " -// + user.getSubjectId()); -// } - + + final UserManager userManager; + final Shiro shiro; + try { + final CdiUtil cdiUtil = new CdiUtil(); + userManager = cdiUtil.findBean(UserManager.class); + shiro = cdiUtil.findBean(Shiro.class); + } catch(CdiLookupException ex) { + throw new UncheckedWrapperException(ex); + } + + final User user = shiro.getUser(); + + final String newPassword = (String) m_newPassword.getValue(state); + userManager.updatePassword(user, newPassword); + final HttpServletRequest req = state.getRequest(); final String path = UI.getWorkspaceURL(req); diff --git a/ccm-core/src/main/java/com/arsdigita/ui/login/EmailInitListener.java b/ccm-core/src/main/java/com/arsdigita/ui/login/EmailInitListener.java index 40bf1cee8..fc5df69a2 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/login/EmailInitListener.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/login/EmailInitListener.java @@ -23,11 +23,17 @@ import com.arsdigita.bebop.FormData; import com.arsdigita.bebop.event.FormInitListener; import com.arsdigita.bebop.event.FormSectionEvent; import com.arsdigita.bebop.parameters.EmailParameter; +import com.arsdigita.util.UncheckedWrapperException; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import org.apache.log4j.Logger; +import org.apache.shiro.subject.Subject; +import org.libreccm.cdi.utils.CdiLookupException; +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.security.Shiro; +import org.libreccm.security.User; /** * Initializes the value of the given parameter to the current user's email @@ -40,7 +46,7 @@ import org.apache.log4j.Logger; public class EmailInitListener implements FormInitListener { private static final Logger s_log = Logger.getLogger(EmailInitListener.class - .getName()); + .getName()); private EmailParameter m_param; @@ -53,41 +59,37 @@ public class EmailInitListener implements FormInitListener { s_log.debug("START"); -// final CcmSessionContext ctx = Web.getUserContext(); + final Subject subject; + final Shiro shiro; + try { + final CdiUtil cdiUtil = new CdiUtil(); + subject = cdiUtil.findBean(Subject.class); + shiro = cdiUtil.findBean(Shiro.class); + } catch (CdiLookupException ex) { + throw new UncheckedWrapperException(ex); + } -// if (!ctx.isLoggedIn()) { -// s_log.debug("FAILURE not logged in"); -// return; -// } -// -// User user = (User) ctx.getCurrentSubject(); + if (!subject.isAuthenticated()) { + s_log.debug("FAILURE not logged in"); + return; + } -// if (user == null) { -// s_log.debug("FAILURE no such user"); -// return; -// } -// -// if (user.getEmailAddresses().isEmpty() -// || user.getEmailAddresses().get(0) == null) { -// s_log.debug("FAILURE null primary email"); -// return; -// } -// -// if (user.getEmailAddresses().get(0).getAddress() == null -// || user.getEmailAddresses().get(0).getAddress().isEmpty()) { -// s_log.debug("FAILURE null email address"); -// return; -// } -// -// try { -// InternetAddress addr = new InternetAddress(user.getEmailAddresses() -// .get(0).getAddress()); -// data.put(m_param.getName(), addr); -// } catch (AddressException e) { -// s_log.debug("FAILURE badly formed address"); -// return; -// } + final User user = shiro.getUser(); + if (user == null) { + s_log.debug("FAILURE no such user"); + return; + } + + if (user.getPrimaryEmailAddress() == null) { + s_log.debug("FAILURE null primary email"); + return; + } + + + + data.put(m_param.getName(), user.getPrimaryEmailAddress().getAddress()); + s_log.debug("SUCCESS"); } diff --git a/ccm-core/src/main/java/com/arsdigita/ui/login/LoginServlet.java b/ccm-core/src/main/java/com/arsdigita/ui/login/LoginServlet.java index 22f61005c..f8349e8cb 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/login/LoginServlet.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/login/LoginServlet.java @@ -187,11 +187,14 @@ public class LoginServlet extends BebopApplicationServlet { "changepassword")); disableClientCaching(CHANGE_USER_PASSWORD_PATH_INFO); + //Disabled until we decide what procedure we will use in the future. + //Certainly not the old question/answer approach because it not secure + //and not user friendly. /* Build the password recover page, retrieve its URL and store in map */ - put(RECOVER_USER_PASSWORD_PATH_INFO, - buildSimplePage("login.recoverPasswordPage.title", - new RecoverPasswordPanel(), - "recoverpassword")); +// put(RECOVER_USER_PASSWORD_PATH_INFO, +// buildSimplePage("login.recoverPasswordPage.title", +// new RecoverPasswordPanel(), +// "recoverpassword")); // Build the login expire page, retrieve its URL and store in map put(LOGIN_EXPIRED_PATH_INFO, buildExpiredPage()); diff --git a/ccm-core/src/main/java/com/arsdigita/ui/login/RecoverPasswordPanel.java b/ccm-core/src/main/java/com/arsdigita/ui/login/RecoverPasswordPanel.java.nolongerinuse similarity index 100% rename from ccm-core/src/main/java/com/arsdigita/ui/login/RecoverPasswordPanel.java rename to ccm-core/src/main/java/com/arsdigita/ui/login/RecoverPasswordPanel.java.nolongerinuse diff --git a/ccm-core/src/main/java/com/arsdigita/ui/login/ScreenNameInitListener.java b/ccm-core/src/main/java/com/arsdigita/ui/login/ScreenNameInitListener.java index 9676f6148..2d4f9604c 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/login/ScreenNameInitListener.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/login/ScreenNameInitListener.java @@ -23,9 +23,15 @@ import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.event.FormInitListener; import com.arsdigita.bebop.event.FormSectionEvent; import com.arsdigita.bebop.parameters.StringParameter; +import com.arsdigita.util.UncheckedWrapperException; import com.arsdigita.web.Web; import org.apache.log4j.Logger; +import org.apache.shiro.subject.Subject; +import org.libreccm.cdi.utils.CdiLookupException; +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.security.Shiro; +import org.libreccm.security.User; // Note: Previously used SiteNodeRequestContext, nows using KernelRequestContext @@ -60,17 +66,29 @@ public class ScreenNameInitListener implements FormInitListener { PageState state = event.getPageState(); FormData data = event.getFormData(); s_log.debug("START"); -// final CcmSessionContext ctx = Web.getUserContext(); -// if (!ctx.isLoggedIn()) { -// s_log.debug("FAILURE not logged in"); -// return; -// } -// final User user = (User) ctx.getCurrentSubject(); -// if (user.getScreenName() == null) { -// s_log.debug("FAILURE null screen name"); -// return; -// } -// data.put(m_param.getName(), user.getScreenName()); -// s_log.debug("SUCCESS"); + + final Subject subject; + final Shiro shiro; + try { + final CdiUtil cdiUtil = new CdiUtil(); + subject = cdiUtil.findBean(Subject.class); + shiro = cdiUtil.findBean(Shiro.class); + } catch(CdiLookupException ex) { + throw new UncheckedWrapperException(ex); + } + + if (!subject.isAuthenticated()) { + s_log.debug("FAILURE not logged in"); + return; + } + + final User user = shiro.getUser(); + if (user.getName() == null) { + s_log.debug("FAILURE null screen name"); + return; + } + + data.put(m_param.getName(), user.getName()); + s_log.debug("SUCCESS"); } } diff --git a/ccm-core/src/main/java/com/arsdigita/ui/login/UserAuthenticationListener.java b/ccm-core/src/main/java/com/arsdigita/ui/login/UserAuthenticationListener.java index ca9005db0..4f8f2c0d8 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/login/UserAuthenticationListener.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/login/UserAuthenticationListener.java @@ -33,6 +33,7 @@ import org.libreccm.cdi.utils.CdiUtil; import org.libreccm.security.User; import javax.servlet.http.HttpServletRequest; +import org.apache.shiro.subject.Subject; /** * A RequestListener that redirects the user to register if not logged in. The @@ -51,7 +52,7 @@ import javax.servlet.http.HttpServletRequest; public class UserAuthenticationListener implements RequestListener { private static final Logger s_log = Logger.getLogger( - UserAuthenticationListener.class); + UserAuthenticationListener.class); /** * If the user is logged in, returns the User object. @@ -61,27 +62,24 @@ public class UserAuthenticationListener implements RequestListener { * @return the User object for the logged in user * * @throws IllegalStateException if user is not logged in. Call isLoggedIn() - * to check for this case. + * to check for this case. */ - public User getUser(final PageState state) { + public Subject getUser(final PageState state) { if (!isLoggedIn(state)) { throw new IllegalStateException("User is not logged in"); } // Note: aborts processing with an internal error if user not logged in! // Not suiteable just to check log in status. - final CdiUtil cdiUtil = new CdiUtil(); -// try { -// final CcmSessionContext context = cdiUtil.findBean( -// CcmSessionContext.class); -// -// return (User) context.getCurrentSubject(); -// } catch (CdiLookupException ex) { -// throw new UncheckedWrapperException( -// "Failed get get CcmSessionContext.", ex); -// } - - throw new UnsupportedOperationException(); + final Subject subject; + try { + final CdiUtil cdiUtil = new CdiUtil(); + subject = cdiUtil.findBean(Subject.class); + } catch (CdiLookupException ex) { + throw new UncheckedWrapperException(ex); + } + + return subject; } /** @@ -92,8 +90,7 @@ public class UserAuthenticationListener implements RequestListener { * @return true if the user is logged in */ public boolean isLoggedIn(final PageState state) { -// return Web.getUserContext().isLoggedIn(); - return false; + return getUser(state).isAuthenticated(); } /** @@ -105,26 +102,18 @@ public class UserAuthenticationListener implements RequestListener { @Override public void pageRequested(final RequestEvent event) { PageState state = event.getPageState(); - -// final CcmSessionContext sessionContext; -// try { -// final CdiUtil cdiUtil = new CdiUtil(); -// sessionContext = cdiUtil.findBean( -// CcmSessionContext.class); -// } catch (CdiLookupException ex) { -// throw new UncheckedWrapperException( -// "Failed to lookup CcmSessionContext", ex); -// } -// if (!sessionContext.isLoggedIn()) { -// s_log.debug("User is not logged in"); -// redirectToLoginPage(state); -// } + + if (!isLoggedIn(state)) { + s_log.debug("User is not logged in"); + redirectToLoginPage(state); + + } } /** * Redirects the client to the login page. - * - * @param state + * + * @param state */ private void redirectToLoginPage(final PageState state) { HttpServletRequest req = state.getRequest(); diff --git a/ccm-core/src/main/java/com/arsdigita/ui/login/UserEditForm.java b/ccm-core/src/main/java/com/arsdigita/ui/login/UserEditForm.java index 881df7cab..26d5b939a 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/login/UserEditForm.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/login/UserEditForm.java @@ -36,13 +36,13 @@ import com.arsdigita.web.ReturnSignal; import javax.servlet.http.HttpServletRequest; -import org.apache.log4j.Logger; import org.libreccm.cdi.utils.CdiLookupException; import org.libreccm.cdi.utils.CdiUtil; import org.libreccm.core.EmailAddress; import org.libreccm.security.User; -import java.util.logging.Level; +import org.libreccm.security.Shiro; +import org.libreccm.security.UserRepository; /** * Edits a user. If returnURL is passed in to the form, then redirects to that @@ -66,21 +66,16 @@ public class UserEditForm extends UserForm @Override public Object initialValue(final PageState ps) { - User result; - final long userId = m_listener.getUser(ps).getPartyId(); -// final CdiUtil cdiUtil = new CdiUtil(); -// final UserRepository userRepository; -// try { -// userRepository = cdiUtil.findBean(UserRepository.class); -// } catch (CdiLookupException ex) { -// throw new UncheckedWrapperException( -// "Failed to lookup UserRepository.", ex); -// } -// -// result = userRepository.findById(userId); -// -// return result; - throw new UnsupportedOperationException(); + final User result; + try { + final CdiUtil cdiUtil = new CdiUtil(); + final Shiro shiro = cdiUtil.findBean(Shiro.class); + result = shiro.getUser(); + } catch(CdiLookupException ex) { + throw new UncheckedWrapperException(ex); + } + + return result; } }; @@ -114,47 +109,32 @@ public class UserEditForm extends UserForm FormData data = event.getFormData(); PageState state = event.getPageState(); + final UserRepository userRepository; + try { + final CdiUtil cdiUtil = new CdiUtil(); + userRepository = cdiUtil.findBean(UserRepository.class); + } catch(CdiLookupException ex) { + throw new UncheckedWrapperException(ex); + } + User user = getUser(state); - if (user == null) { throw new UncheckedWrapperException( "Failed to retrieve user from page state"); } -// final PersonName name = user.getName(); -// name.setGivenName((String) m_firstName.getValue(state)); -// name.setFamilyName((String) m_lastName.getValue(state)); -// -// user.setScreenName((String) m_screenName.getValue(state)); -// -// final EmailAddress newAddress = new EmailAddress(); -// newAddress.setAddress(data.get(FORM_EMAIL).toString()); -// if (user.getEmailAddresses().isEmpty()) { -// user.addEmailAddress(newAddress); -// } else { -// if (!user.getEmailAddresses().get(0).equals(newAddress)) { -// user.getEmailAddresses().get(0).setAddress(newAddress.getAddress()); -// } -// } -// -// final CdiUtil cdiUtil = new CdiUtil(); -// final UserRepository userRepository; -// try { -// userRepository = cdiUtil.findBean(UserRepository.class); -// } catch (CdiLookupException ex) { -// throw new UncheckedWrapperException( -// "Failed to lookup UserRepository", ex); -// } + user.setGivenName((String) m_firstName.getValue(state)); + user.setFamilyName((String) m_lastName.getValue(state)); + user.setName((String) m_screenName.getValue(state)); + final EmailAddress newAddress = new EmailAddress(); + newAddress.setAddress(data.get(FORM_EMAIL).toString()); + user.setPrimaryEmailAddress(newAddress); + userRepository.save(user); // redirect to workspace or return URL, if specified final HttpServletRequest req = state.getRequest(); - -// final String path = LegacyInitializer.getFullURL -// (LegacyInitializer.WORKSPACE_PAGE_KEY, req); final String path = UI.getWorkspaceURL(); - final URL fallback = com.arsdigita.web.URL.there(req, path); - throw new ReturnSignal(req, fallback); } diff --git a/ccm-core/src/main/java/com/arsdigita/ui/login/UserForm.java b/ccm-core/src/main/java/com/arsdigita/ui/login/UserForm.java index 88a9f40d6..fc47b831b 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/login/UserForm.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/login/UserForm.java @@ -39,13 +39,11 @@ import com.arsdigita.bebop.parameters.StringParameter; import com.arsdigita.kernel.KernelConfig; import com.arsdigita.util.UncheckedWrapperException; -import javax.mail.internet.AddressException; -import javax.mail.internet.InternetAddress; - import org.apache.log4j.Logger; import org.libreccm.cdi.utils.CdiLookupException; import org.libreccm.cdi.utils.CdiUtil; import org.libreccm.security.User; +import org.libreccm.security.UserRepository; /** * Common code for user new / add / edit forms. @@ -55,12 +53,12 @@ import org.libreccm.security.User; * */ public abstract class UserForm extends Form - implements LoginConstants, FormInitListener, FormValidationListener { + implements LoginConstants, FormInitListener, FormValidationListener { - private static final Logger s_log = Logger.getLogger(UserForm.class - .getName()); + private static final Logger LOGGER = Logger.getLogger(UserForm.class + .getName()); - private boolean m_newUser; + private final boolean m_newUser; protected TextField m_firstName; protected TextField m_lastName; @@ -73,19 +71,15 @@ public abstract class UserForm extends Form protected TextField m_answer; protected Label m_securitySectionHeader = new Label(LoginHelper - .getMessage("login.userNewForm.securitySectionHeader"), false); + .getMessage("login.userNewForm.securitySectionHeader"), false); protected Label m_securityBlurb = new Label(LoginHelper - .getMessage("login.userNewForm.securityBlurb")); + .getMessage("login.userNewForm.securityBlurb")); protected Label m_passwordBlurb = new Label(LoginHelper - .getMessage("login.userNewForm.passwordBlurb")); + .getMessage("login.userNewForm.passwordBlurb")); protected Label m_passwordLabel = new Label(PASSWORD); protected Label m_confirmationLabel = new Label(PASSWORD_CONFIRMATION); - protected Label m_questionBlurb = new Label(LoginHelper - .getMessage("login.userNewForm.questionBlurb")); - protected Label m_questionLabel = new Label(PASSWORD_QUESTION); - protected Label m_answerLabel = new Label(PASSWORD_ANSWER); protected PasswordValidationListener m_passwordValidationListener - = new PasswordValidationListener(); + = new PasswordValidationListener(); protected NotEmptyValidationListener m_confirmationNotEmptyValidationListener = new NotEmptyValidationListener(); protected Submit m_submit = new Submit(SUBMIT); @@ -102,8 +96,13 @@ public abstract class UserForm extends Form /** * Create a UserForm with the given name and panel. * + * @param name + * @param panel + * @param newUser */ - public UserForm(String name, Container panel, boolean newUser) { + public UserForm(final String name, + final Container panel, + final boolean newUser) { super(name, panel); m_newUser = newUser; @@ -114,7 +113,7 @@ public abstract class UserForm extends Form if (m_newUser) { m_profilePart.add(new Label(LoginHelper - .getMessage("login.userNewForm.aboutYouSectionHeader"), + .getMessage("login.userNewForm.aboutYouSectionHeader"), false), ColumnPanel.FULL_WIDTH); } @@ -126,7 +125,7 @@ public abstract class UserForm extends Form m_firstName.setSize(20); m_firstName.addValidationListener(new NotEmptyValidationListener()); m_firstName.addValidationListener(new StringLengthValidationListener( - MAX_NAME_LEN)); + MAX_NAME_LEN)); m_profilePart.add(m_firstNameLabel); m_profilePart.add(m_firstName); @@ -136,7 +135,7 @@ public abstract class UserForm extends Form m_lastName.setSize(25); m_lastName.addValidationListener(new NotEmptyValidationListener()); m_lastName.addValidationListener(new StringLengthValidationListener( - MAX_NAME_LEN)); + MAX_NAME_LEN)); m_profilePart.add(m_lastNameLabel); m_profilePart.add(m_lastName); @@ -169,15 +168,15 @@ public abstract class UserForm extends Form // add(new Label("")); if (m_newUser) { m_securityPart.add(new Label(LoginHelper - .getMessage("login.userNewForm.securitySectionHeader"), + .getMessage("login.userNewForm.securitySectionHeader"), false), ColumnPanel.FULL_WIDTH); m_securityPart.add(new Label(LoginHelper - .getMessage("login.userNewForm.securityBlurb")), + .getMessage("login.userNewForm.securityBlurb")), ColumnPanel.FULL_WIDTH); m_securityPart.add(new Label(LoginHelper - .getMessage("login.userNewForm.passwordBlurb")), + .getMessage("login.userNewForm.passwordBlurb")), ColumnPanel.FULL_WIDTH); // Password @@ -189,32 +188,15 @@ public abstract class UserForm extends Form // Password confirmation m_confirm = new Password(new StringParameter( - FORM_PASSWORD_CONFIRMATION)); + FORM_PASSWORD_CONFIRMATION)); m_confirm.addValidationListener(new NotEmptyValidationListener()); m_securityPart.add(m_confirmationLabel); m_securityPart.add(m_confirm); m_securityPart.add(new Label(LoginHelper - .getMessage("login.userNewForm.questionBlurb")), + .getMessage("login.userNewForm.questionBlurb")), ColumnPanel.FULL_WIDTH); - - // Password question - m_question = new TextField(new StringParameter( - FORM_PASSWORD_QUESTION)); - m_question.setSize(30); - m_question.addValidationListener(new NotEmptyValidationListener()); - - m_securityPart.add(m_questionLabel); - m_securityPart.add(m_question); - - // Password answer - m_answer = new TextField(new StringParameter(FORM_PASSWORD_ANSWER)); - m_answer.setSize(30); - m_answer.addValidationListener(new NotEmptyValidationListener()); - - m_securityPart.add(m_answerLabel); - m_securityPart.add(m_answer); } // Submit @@ -234,32 +216,18 @@ public abstract class UserForm extends Form * */ @Override - public void init(FormSectionEvent event) - throws FormProcessException { - PageState state = event.getPageState(); + public void init(final FormSectionEvent event) + throws FormProcessException { + final PageState state = event.getPageState(); - User user = getUser(state); + final User user = getUser(state); if (user == null) { throw new FormProcessException(LoginGlobalizationUtil.globalize( - "login.userForm.couldnt_load_user")); + "login.userForm.couldnt_load_user")); } m_firstName.setValue(state, user.getGivenName()); m_lastName.setValue(state, user.getFamilyName()); - - InternetAddress address; - try { - address = new InternetAddress(user.getEmailAddresses().get(0) - .toString()); - } catch (AddressException e) { - String[] errorMsg = new String[1]; - errorMsg[0] = user.getEmailAddresses().get(0).toString(); - throw new FormProcessException( - "Email address is bad: " + user.getEmailAddresses().get(0), - LoginHelper.getMessage("login.error.badEmail", errorMsg) - ); - } - - m_email.setValue(state, address); + m_email.setValue(state, user.getPrimaryEmailAddress().getAddress()); m_screenName.setValue(state, user.getName()); } @@ -269,7 +237,7 @@ public abstract class UserForm extends Form * * @param state * @return the current user, if the form should not be initialised with user - * data. + * data. */ protected abstract User getUser(final PageState state); @@ -284,9 +252,19 @@ public abstract class UserForm extends Form */ @Override public void validate(final FormSectionEvent event) - throws FormProcessException { - PageState state = event.getPageState(); - FormData data = event.getFormData(); + throws FormProcessException { + + final PageState state = event.getPageState(); + final FormData data = event.getFormData(); + + final UserRepository userRepository; + try { + final CdiUtil cdiUtil = new CdiUtil(); + userRepository = cdiUtil.findBean(UserRepository.class); + } catch (CdiLookupException ex) { + throw new UncheckedWrapperException(ex); + } + try { if (m_newUser) { // Verify that password and confirmation match @@ -294,46 +272,33 @@ public abstract class UserForm extends Form String confirm = (String) m_confirm.getValue(state); if ((password != null) && (confirm != null) - && !password.equals(confirm)) { + && !password.equals(confirm)) { data.addError(FORM_PASSWORD_CONFIRMATION, ERROR_MISMATCH_PASSWORD); } } - String email = null; - if (m_email.getValue(state) != null) { - InternetAddress address = (InternetAddress) m_email - .getValue(state); - email = address.getAddress(); + //Verify that primary email and screen name are unique + final User user = getUser(state); + + final String oldScreenName = user.getName(); + final String screenName = (String) m_screenName.getValue(state); + if (screenName != null && !screenName.equals(oldScreenName)) { + final User result = userRepository.findByName(screenName); + if (result != null) { + data.addError(FORM_SCREEN_NAME, ERROR_DUPLICATE_SN); + } } - final String screenName = (String) m_screenName.getValue(state); - - // If this query returns with any rows we have a duplicate - // screen name, email address, or both. Check the results and - // produce appropriate error messages. - final boolean checkPrimaryEmail = KernelConfig.getConfig() - .emailIsPrimaryIdentifier(); - -// final UserRepository userRepo; -// try { -// final CdiUtil cdiUtil = new CdiUtil(); -// userRepo = cdiUtil.findBean( -// UserRepository.class); -// } catch (CdiLookupException ex) { -// throw new FormProcessException(ex); -// } - -// final User userByEmail = userRepo.findByEmailAddress(email); -// if (userByEmail != null && checkPrimaryEmail) { -// data.addError(FORM_EMAIL, ERROR_DUPLICATE_EMAIL); -// } -// -// final User userByScreenname = userRepo.findByScreenName(screenName); -// if (userByScreenname != null) { -// data.addError(FORM_SCREEN_NAME, ERROR_DUPLICATE_SN); -// } - + final String oldEmail = user.getPrimaryEmailAddress().getAddress(); + final String email = (String) m_email.getValue(state); + if (KernelConfig.getConfig().emailIsPrimaryIdentifier() + && email != null && !email.equals(oldEmail)) { + final User result = userRepository.findByEmailAddress(email); + if (result != null) { + data.addError(FORM_EMAIL, ERROR_DUPLICATE_EMAIL); + } + } } finally { // if the form has errors, clear the password fields so we don't // send the passwords back over the network diff --git a/ccm-core/src/main/java/com/arsdigita/ui/login/UserInfo.java b/ccm-core/src/main/java/com/arsdigita/ui/login/UserInfo.java index c116a1087..980b6c816 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/login/UserInfo.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/login/UserInfo.java @@ -32,8 +32,10 @@ import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; +import org.apache.shiro.subject.Subject; import org.libreccm.cdi.utils.CdiLookupException; import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.security.Shiro; import org.libreccm.security.User; import org.libreccm.web.ApplicationRepository; import org.libreccm.web.CcmApplication; @@ -214,7 +216,17 @@ public class UserInfo extends SimpleContainer { if (!isLoggedIn(state)) { throw new IllegalStateException("user is not logged in"); } - return m_listener.getUser(state); + + final User user; + try { + final CdiUtil cdiUtil = new CdiUtil(); + final Shiro shiro = cdiUtil.findBean(Shiro.class); + user = shiro.getUser(); + } catch(CdiLookupException ex) { + throw new UncheckedWrapperException(ex); + } + + return user; } } diff --git a/ccm-core/src/main/java/com/arsdigita/ui/login/UserLoginForm.java b/ccm-core/src/main/java/com/arsdigita/ui/login/UserLoginForm.java index 1ccdb45e3..8916d6ccf 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/login/UserLoginForm.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/login/UserLoginForm.java @@ -53,18 +53,17 @@ import com.arsdigita.web.ParameterMap; import com.arsdigita.web.RedirectSignal; import com.arsdigita.web.ReturnSignal; import com.arsdigita.web.URL; -import com.arsdigita.web.Web; - -import javax.mail.internet.InternetAddress; import javax.security.auth.login.FailedLoginException; import javax.security.auth.login.LoginException; import javax.servlet.http.HttpServletRequest; import org.apache.log4j.Logger; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.UsernamePasswordToken; import org.libreccm.cdi.utils.CdiLookupException; import org.libreccm.cdi.utils.CdiUtil; -import java.util.logging.Level; +import org.apache.shiro.subject.Subject; /** * A Bebop form that accepts login and password from the user and attempts to @@ -89,21 +88,22 @@ import java.util.logging.Level; * * @version $Id$ */ -public class UserLoginForm extends Form - implements LoginConstants, FormInitListener, - FormValidationListener, FormProcessListener { +public class UserLoginForm extends Form implements LoginConstants, + FormInitListener, + FormValidationListener, + FormProcessListener { private static final Logger s_log = Logger.getLogger(UserLoginForm.class); // package friendly static form name makes writing HttpUnitTest easier final static String FORM_NAME = "user-login"; - private CheckboxGroup m_isPersistent; - private Hidden m_timestamp; - private Hidden m_returnURL; + private final CheckboxGroup m_isPersistent; + private final Hidden m_timestamp; + private final Hidden m_returnURL; private TextField m_loginName; - private Password m_password; - private boolean m_autoRegistrationOn; - private SecurityConfig securityConfig = SecurityConfig.getConfig(); + private final Password m_password; + private final boolean m_autoRegistrationOn; + private final SecurityConfig securityConfig = SecurityConfig.getConfig(); /** * Default constructor delegates to a constructor which creates a LoginForm @@ -127,7 +127,8 @@ public class UserLoginForm extends Form * @param panel * @param autoRegistrationOn */ - public UserLoginForm(Container panel, boolean autoRegistrationOn) { + public UserLoginForm(final Container panel, + final boolean autoRegistrationOn) { super(FORM_NAME, panel); setMethod(Form.POST); @@ -141,14 +142,14 @@ public class UserLoginForm extends Form add(m_timestamp); m_returnURL = new Hidden(new URLParameter( - LoginHelper.RETURN_URL_PARAM_NAME)); + LoginHelper.RETURN_URL_PARAM_NAME)); m_returnURL.setPassIn(true); add(m_returnURL); setupLogin(); add(new Label(LoginHelper.getMessage( - "login.userRegistrationForm.password"))); + "login.userRegistrationForm.password"))); m_password = new Password(new StringParameter(FORM_PASSWORD)); // Since new users should not enter a password, allow null. //m_password.addValidationListener(new NotNullValidationListener()); @@ -157,7 +158,7 @@ public class UserLoginForm extends Form SimpleContainer cookiePanel = new BoxPanel(BoxPanel.HORIZONTAL); m_isPersistent = new CheckboxGroup(FORM_PERSISTENT_LOGIN_P); Label optLabel = new Label(LoginHelper.getMessage( - "login.userRegistrationForm.cookieOption")); + "login.userRegistrationForm.cookieOption")); Option opt = new Option(FORM_PERSISTENT_LOGIN_P_DEFAULT, optLabel); m_isPersistent.addOption(opt); if (KernelConfig.getConfig().isLoginRemembered()) { @@ -166,8 +167,8 @@ public class UserLoginForm extends Form cookiePanel.add(m_isPersistent); cookiePanel.add(new DynamicLink( - "login.userRegistrationForm.explainCookieLink", - LoginServlet.getCookiesExplainPageURL())); + "login.userRegistrationForm.explainCookieLink", + LoginServlet.getCookiesExplainPageURL())); add(cookiePanel); add(new Submit(SUBMIT), ColumnPanel.CENTER | ColumnPanel.FULL_WIDTH); @@ -191,8 +192,8 @@ public class UserLoginForm extends Form */ private void setupLogin() { SimpleContainer loginMessage = new SimpleContainer( - "subsite:loginPromptMsg", - LoginServlet.SUBSITE_NS_URI); + "subsite:loginPromptMsg", + LoginServlet.SUBSITE_NS_URI); if (KernelConfig.getConfig().emailIsPrimaryIdentifier()) { loginMessage.setClassAttr("email"); @@ -204,17 +205,17 @@ public class UserLoginForm extends Form if (KernelConfig.getConfig().emailIsPrimaryIdentifier()) { add(new Label(LoginHelper.getMessage( - "login.userRegistrationForm.email"))); + "login.userRegistrationForm.email"))); m_loginName = new TextField(new EmailParameter(FORM_LOGIN)); addInitListener(new EmailInitListener((EmailParameter) m_loginName. - getParameterModel())); + getParameterModel())); } else { add(new Label(LoginHelper.getMessage( - "login.userRegistrationForm.screenName"))); + "login.userRegistrationForm.screenName"))); m_loginName = new TextField(new StringParameter(FORM_LOGIN)); addInitListener(new ScreenNameInitListener( - (StringParameter) m_loginName. - getParameterModel())); + (StringParameter) m_loginName. + getParameterModel())); } m_loginName.addValidationListener(new NotNullValidationListener()); add(m_loginName); @@ -228,14 +229,14 @@ public class UserLoginForm extends Form */ @Override public void init(FormSectionEvent event) - throws FormProcessException { + throws FormProcessException { s_log.info("In init"); if (KernelConfig.getConfig().isSSOenabled()) { // try SSO login s_log.info("trying SSO"); // try { throw new UnsupportedOperationException( - "SSO currently not supported"); + "SSO currently not supported"); // Web.getUserContext().loginSSO(); // s_log.info("loginSSO ok, now processing redirect_url"); // process(event); @@ -266,7 +267,7 @@ public class UserLoginForm extends Form */ @Override public void validate(FormSectionEvent event) - throws FormProcessException { + throws FormProcessException { s_log.debug("In validate"); @@ -303,7 +304,9 @@ public class UserLoginForm extends Form * * @throws FormProcessException */ - public void process(FormSectionEvent event) throws FormProcessException { + @Override + public void process(final FormSectionEvent event) + throws FormProcessException { s_log.debug("In process"); final PageState state = event.getPageState(); @@ -328,10 +331,30 @@ public class UserLoginForm extends Form * @throws FormProcessException if there is an unexpected login error * */ - protected void loginUser(FormSectionEvent event) - throws FormProcessException { + protected void loginUser(final FormSectionEvent event) + throws FormProcessException { PageState state = event.getPageState(); + final CdiUtil cdiUtil = new CdiUtil(); + final Subject subject; + try { + subject = cdiUtil.findBean(Subject.class); + } catch (CdiLookupException ex) { + throw new UncheckedWrapperException(ex); + } + + final UsernamePasswordToken token = new UsernamePasswordToken( + (String) m_loginName.getValue(state), + (String) m_password.getValue(state) + ); + token.setRememberMe(getPersistentLoginValue(state, + false)); + try { + subject.login(token); + } catch(AuthenticationException ex) { + onLoginFail(event, ex); + } + // try { // final CcmSessionContext ctx = Web.getUserContext(); // final String username; @@ -371,23 +394,23 @@ public class UserLoginForm extends Form * @throws com.arsdigita.bebop.FormProcessException * */ - protected void onLoginSuccess(FormSectionEvent event) - throws FormProcessException { + protected void onLoginSuccess(final FormSectionEvent event) + throws FormProcessException { // do nothing } /** * * @param event - * @param e + * @param ex * * @throws FormProcessException */ - protected void onBadPassword(FormSectionEvent event, - FailedLoginException e) - throws FormProcessException { - onLoginFail(event, e); - } +// protected void onBadPassword(final FormSectionEvent event, +// final FailedLoginException ex) +// throws FormProcessException { +// onLoginFail(event, ex); +// } /** * Executed when login fails with a bad password or when autoLoginOn is set @@ -395,43 +418,47 @@ public class UserLoginForm extends Form * password parameter with an error message. * * @param event - * @param e + * @param ex * * @throws com.arsdigita.bebop.FormProcessException * */ - protected void onLoginFail(FormSectionEvent event, - LoginException e) - throws FormProcessException { + protected void onLoginFail(final FormSectionEvent event, + final AuthenticationException ex) + throws FormProcessException { s_log.debug("Login fail"); - event.getFormData().addError((String) ERROR_LOGIN_FAIL.localize(event. - getPageState().getRequest())); + event.getFormData().addError(ERROR_LOGIN_FAIL); } /** * Executed when login fails for an unrecognized problem. Default * implementation logs the error and throws FormProcessException. * + * @param event + * @param ex + * @throws com.arsdigita.bebop.FormProcessException */ - protected void onLoginException(FormSectionEvent event, - LoginException e) - throws FormProcessException { - // unexpected error happened during login - s_log.error("Login failed", e); - throw new FormProcessException(e); - } +// protected void onLoginException(final FormSectionEvent event, +// final LoginException ex) +// throws FormProcessException { +// // unexpected error happened during login +// s_log.error("Login failed", ex); +// throw new FormProcessException(ex); +// } /** * Determines whether a persistent cookie is requested in the given form. + * FORM_PERSISTENT_LOGIN_P whose value is equal to "1". If there is no such + * field in the form data, returns the specified default value. * + * @param state + * @param defaultValue * @return true if the specified formdata has a field named - * FORM_PERSISTENT_LOGIN_P whose value is equal to "1". If there is - * no such field in the form data, returns the specified default - * value. + * * */ - protected boolean getPersistentLoginValue(PageState state, - boolean defaultValue) { + protected boolean getPersistentLoginValue(final PageState state, + final boolean defaultValue) { // Problem: // getValue(state) returns an Object of type StringArray, if the // Checkbox is marked. @@ -462,7 +489,7 @@ public class UserLoginForm extends Form * * @param state */ - protected void redirectToNewUserPage(PageState state) { + protected void redirectToNewUserPage(final PageState state) { String url = LoginServlet.getNewUserPageURL(); diff --git a/ccm-core/src/main/java/com/arsdigita/ui/login/UserLogoutListener.java b/ccm-core/src/main/java/com/arsdigita/ui/login/UserLogoutListener.java index 2bb13cce7..a607ecf42 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/login/UserLogoutListener.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/login/UserLogoutListener.java @@ -23,6 +23,7 @@ import com.arsdigita.bebop.event.ActionListener; import com.arsdigita.util.UncheckedWrapperException; import org.apache.log4j.Logger; +import org.apache.shiro.subject.Subject; import org.libreccm.cdi.utils.CdiLookupException; import org.libreccm.cdi.utils.CdiUtil; @@ -35,7 +36,7 @@ import org.libreccm.cdi.utils.CdiUtil; public class UserLogoutListener implements ActionListener { private static final Logger s_log = Logger.getLogger( - UserLogoutListener.class); + UserLogoutListener.class); /** * Logs out the user. @@ -45,15 +46,16 @@ public class UserLogoutListener implements ActionListener { */ @Override public void actionPerformed(final ActionEvent event) { - final CdiUtil cdiUtil = new CdiUtil(); -// final LoginManager loginManager; -// try { -// loginManager = cdiUtil.findBean(LoginManager.class); -// } catch (CdiLookupException ex) { -// throw new UncheckedWrapperException("Failed to lookup LoginManager", -// ex); -// } -// loginManager.logout(); + + final Subject subject; + try { + final CdiUtil cdiUtil = new CdiUtil(); + subject = cdiUtil.findBean(Subject.class); + } catch (CdiLookupException ex) { + throw new UncheckedWrapperException(ex); + } + + subject.logout(); } } diff --git a/ccm-core/src/main/java/com/arsdigita/ui/login/UserNewForm.java b/ccm-core/src/main/java/com/arsdigita/ui/login/UserNewForm.java index 3ff6f3a9b..02f6ce680 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/login/UserNewForm.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/login/UserNewForm.java @@ -33,23 +33,25 @@ import com.arsdigita.bebop.parameters.URLParameter; import com.arsdigita.kernel.KernelConfig; import com.arsdigita.ui.UI; import com.arsdigita.util.UncheckedWrapperException; -import com.arsdigita.web.Web; import com.arsdigita.web.URL; import com.arsdigita.web.ReturnSignal; +import java.util.concurrent.Callable; import static com.arsdigita.ui.login.LoginConstants.*; import javax.mail.internet.InternetAddress; -import javax.security.auth.login.LoginException; import javax.servlet.http.HttpServletRequest; import org.apache.log4j.Logger; -import org.dom4j.util.UserDataDocumentFactory; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.UsernamePasswordToken; +import org.apache.shiro.subject.Subject; import org.libreccm.cdi.utils.CdiLookupException; import org.libreccm.cdi.utils.CdiUtil; - -import org.libreccm.core.EmailAddress; +import org.libreccm.security.Shiro; import org.libreccm.security.User; +import org.libreccm.security.UserManager; +import org.libreccm.security.UserRepository; /** * Creates a new user. Collects user's basic info, such as email, password, @@ -96,7 +98,7 @@ public class UserNewForm extends UserForm implements FormInitListener, // save return URL m_returnURL = new Hidden(new URLParameter( - LoginHelper.RETURN_URL_PARAM_NAME)); + LoginHelper.RETURN_URL_PARAM_NAME)); m_returnURL.setPassIn(true); add(m_returnURL); @@ -112,8 +114,9 @@ public class UserNewForm extends UserForm implements FormInitListener, add(m_persistent); } - public void init(FormSectionEvent event) - throws FormProcessException { + @Override + public void init(final FormSectionEvent event) + throws FormProcessException { PageState state = event.getPageState(); // clear passwords from form data m_password.setValue(state, ""); @@ -128,133 +131,86 @@ public class UserNewForm extends UserForm implements FormInitListener, } } - public void process(FormSectionEvent event) - throws FormProcessException { + @Override + public void process(final FormSectionEvent event) + throws FormProcessException { PageState state = event.getPageState(); final InternetAddress address = (InternetAddress) m_email - .getValue(state); + .getValue(state); final String email = address.getAddress(); // TODO: set additional emails final String password = (String) m_password.getValue(state); - final String question = (String) m_question.getValue(state); - final String answer = (String) m_answer.getValue(state); final String firstName = (String) m_firstName.getValue(state); final String lastName = (String) m_lastName.getValue(state); - String sn = null; - if (!KernelConfig.getConfig().emailIsPrimaryIdentifier()) { - sn = (String) m_screenName.getValue(state); + final String screenName; + if (KernelConfig.getConfig().emailIsPrimaryIdentifier()) { + screenName = null; + } else { + screenName = (String) m_screenName.getValue(state); } - final String screenName = sn; final Exception[] formExceptions = new Exception[]{null}; -// final CdiUtil cdiUtil = new CdiUtil(); -// final CcmSessionContext sessionContext; -// try { -// sessionContext = cdiUtil.findBean(CcmSessionContext.class); -// } catch (CdiLookupException ex) { -// throw new UncheckedWrapperException( -// "Failed to lookup CcmSessionContext", ex); -// } -// -// final UserRepository userRepository; -// try { -// userRepository = cdiUtil.findBean(UserRepository.class); -// } catch (CdiLookupException ex) { -// throw new UncheckedWrapperException( -// "Failed to lookup UserRepository", ex); -// } -// -// final User systemUser = userRepository.retrieveSystemUser(); -// -// sessionContext.sudo(systemUser, new Runnable() { + final Shiro shiro; + try { + final CdiUtil cdiUtil = new CdiUtil(); + shiro = cdiUtil.findBean(Shiro.class); + } catch (CdiLookupException ex) { + throw new UncheckedWrapperException(ex); + } -// @Override -// public void run() { -// final User user = new User(); -// final PersonName userName = new PersonName(); -// userName.setGivenName(firstName); -// userName.setFamilyName(lastName); -// final EmailAddress emailAddress = new EmailAddress(); -// emailAddress.setAddress(email); -// user.addEmailAddress(emailAddress); -// if (!KernelConfig.getConfig().emailIsPrimaryIdentifier()) { -// user.setScreenName(screenName); -// } -// userRepository.save(user); -// -//// final PermissionManager permissionManager; -//// try { -//// permissionManager = cdiUtil -//// .findBean(PermissionManager.class); -//// } catch (CdiLookupException ex) { -//// throw new UncheckedWrapperException( -//// "Failed to lookup PermissionManager", ex); -//// } -//// -//// permissionManager.grantPermission(null, null, user); -// final UserManager userManager; -// try { -// userManager = cdiUtil.findBean(UserManager.class); -// } catch (CdiLookupException ex) { -// throw new UncheckedWrapperException( -// "Failed to lookup UserManager", ex); -// } -// userManager.updatePassword(user, password); -// user.setPasswordQuestion(question); -// user.setPasswordAnswer(answer); -// } -// -// }); + shiro.getSystemUser().execute(new Callable() { + @Override + public Void call() throws Exception { -// try { -// // finally log the user in (sets the -// // appropriate session or permanent cookie) -// String loginName = email; -// if (!KernelConfig.getConfig().emailIsPrimaryIdentifier()) { -// loginName = screenName; -// } -// -// final LoginManager loginManager; -// try { -// loginManager = cdiUtil.findBean(LoginManager.class); -// } catch (CdiLookupException ex) { -// throw new UncheckedWrapperException( -// "Failed to lookup LoginManager", ex); -// } -// -// loginManager.login(loginName, password); -// -// } catch (LoginException e) { -// // ERROR: login failed for new user -// s_log.error("login failed for new user", e); -// throw new FormProcessException(e); -// } + final UserManager userManager; + try { + final CdiUtil cdiUtil = new CdiUtil(); + userManager = cdiUtil.findBean(UserManager.class); + } catch (CdiLookupException ex) { + throw new UncheckedWrapperException(ex); + } + + userManager.createUser(firstName, + lastName, + screenName, + email, + password); + + return null; + } + }); + + try { + final String loginName; + if (KernelConfig.getConfig().emailIsPrimaryIdentifier()) { + loginName = email; + } else { + loginName = screenName; + } + + final CdiUtil cdiUtil = new CdiUtil(); + final Subject subject = cdiUtil.findBean(Subject.class); + + if (subject.isAuthenticated()) { + subject.logout(); + } + + final UsernamePasswordToken token = new UsernamePasswordToken( + loginName, password); + subject.login(token); + } catch (CdiLookupException | AuthenticationException ex) { + s_log.error("login failed for new user", ex); + throw new FormProcessException(ex); + } // redirect to workspace or return URL, if specified final HttpServletRequest req = state.getRequest(); - - // url = LegacyInitializer.getFullURL - // (LegacyInitializer.WORKSPACE_PAGE_KEY, req); final String url = UI.getWorkspaceURL(); - final URL fallback = com.arsdigita.web.URL.there(req, url); - throw new ReturnSignal(req, fallback); } - protected boolean getPersistentLoginValue(PageState state, - boolean defaultValue) { - // CheckboxGroup gets you a StringArray - String[] values = (String[]) m_persistent.getValue(state); - if (values == null) { - return defaultValue; - } - - String persistentLoginValue = (String) values[0]; - return "1".equals(persistentLoginValue); - } - } diff --git a/ccm-core/src/main/java/org/libreccm/security/Shiro.java b/ccm-core/src/main/java/org/libreccm/security/Shiro.java index b25ff893a..f0cd80311 100644 --- a/ccm-core/src/main/java/org/libreccm/security/Shiro.java +++ b/ccm-core/src/main/java/org/libreccm/security/Shiro.java @@ -18,9 +18,11 @@ */ package org.libreccm.security; +import com.arsdigita.kernel.KernelConfig; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; +import javax.inject.Inject; import javax.inject.Named; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -45,6 +47,9 @@ public class Shiro { private static final Logger LOGGER = LogManager.getLogger( Shiro.class); + @Inject + private UserRepository userRepository; + /** * Path to the Shiro INI file. */ @@ -92,13 +97,28 @@ public class Shiro { } public Subject getPublicUser() { - return buildInternalSubject("public-user"); + if (KernelConfig.getConfig().emailIsPrimaryIdentifier()) { + return buildInternalSubject("public-user@localhost"); + } else { + return buildInternalSubject("public-user"); + } } public Subject getSystemUser() { return buildInternalSubject("system-user"); } + public User getUser() { + final KernelConfig kernelConfig = KernelConfig.getConfig(); + if (kernelConfig.emailIsPrimaryIdentifier()) { + return userRepository.findByEmailAddress((String) getSubject(). + getPrincipal()); + } else { + return userRepository.findByName((String) getSubject(). + getPrincipal()); + } + } + private Subject buildInternalSubject(final String userName) { final PrincipalCollection principals = new SimplePrincipalCollection( userName, "CcmShiroRealm"); diff --git a/ccm-core/src/main/java/org/libreccm/security/UserRepository.java b/ccm-core/src/main/java/org/libreccm/security/UserRepository.java index c027d147b..693a1c98d 100644 --- a/ccm-core/src/main/java/org/libreccm/security/UserRepository.java +++ b/ccm-core/src/main/java/org/libreccm/security/UserRepository.java @@ -88,5 +88,5 @@ public class UserRepository extends AbstractEntityRepository { return result.get(0); } } - + }