SAML support for CCM

git-svn-id: https://svn.libreccm.org/ccm/trunk@6168 8810af33-2d31-482b-a856-94f89814c4df
master
jensp 2019-08-29 08:52:02 +00:00
parent 4798acca86
commit 6e856be184
4 changed files with 242 additions and 103 deletions

View File

@ -5,13 +5,24 @@
*/
package com.arsdigita.kernel.security;
import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.kernel.UserAuthentication;
import com.onelogin.saml2.Auth;
import com.onelogin.saml2.exception.Error;
import com.onelogin.saml2.exception.SettingsException;
import org.apache.log4j.Logger;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import javax.servlet.http.HttpServletRequest;
@ -23,10 +34,13 @@ import javax.servlet.http.HttpServletResponse;
*/
public class SamlLoginModule implements LoginModule {
private static final Logger LOGGER = Logger.getLogger(SamlLoginModule.class);
private CallbackHandler callbackHandler;
private HttpServletRequest request;
private HttpServletResponse response;
private Subject subject;
private BigDecimal userId;
@Override
public void initialize(final Subject subject,
@ -40,22 +54,54 @@ public class SamlLoginModule implements LoginModule {
@Override
public boolean login() throws LoginException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
final HttpServletRequest request = getRequest();
final HttpServletResponse response = getResponse();
final Auth auth;
try {
auth = new Auth(request, response);
} catch (IOException | SettingsException | Error ex) {
LOGGER.error("SAML Login failed.", ex);
throw new LoginException("SAML Login failed. Configuration error?");
}
final List<String> errors = auth.getErrors();
if (!errors.isEmpty()) {
LOGGER.error(String.format("SAML Login errors: %s",
String.join(";\n", errors)));
throw new LoginException(String.format("SAML Login errors: %s",
String.join(";\n", errors)));
}
if (!auth.isAuthenticated()) {
throw new LoginException("Not authenticated.");
}
userId = getUserId(auth.getNameId());
return true;
}
@Override
public boolean commit() throws LoginException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
if (userId != null) {
subject.getPrincipals().add(new PartyPrincipal(userId));
}
return true;
}
@Override
public boolean abort() throws LoginException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
return true;
}
@Override
public boolean logout() throws LoginException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
getRequest().getSession().invalidate();
return true;
}
protected HttpServletRequest getRequest() throws LoginException {
@ -86,4 +132,18 @@ public class SamlLoginModule implements LoginModule {
}
}
protected BigDecimal getUserId(final String ssoLogin)
throws LoginException {
try {
final UserAuthentication userAuth = UserAuthentication
.retrieveForSSOlogin(ssoLogin);
return userAuth.getUser().getID();
} catch(DataObjectNotFoundException ex) {
throw new FailedLoginException(
String.format("SSO login %s not found", ssoLogin)
);
}
}
}

View File

@ -126,7 +126,9 @@ public class SecurityConfig extends AbstractConfig {
"Register:com.arsdigita.kernel.security.UserIDLoginModule:requisite",
"Register:com.arsdigita.kernel.security.CookieLoginModule:optional",
"RegisterSSO:com.arsdigita.kernel.security.SimpleSSOLoginModule:requisite",
"RegisterSSO:com.arsdigita.kernel.security.CookieLoginModule:optional"
"RegisterSSO:com.arsdigita.kernel.security.CookieLoginModule:optional",
"RegisterSAML:com.arsdigita.kernel.security.SamlLoginModule:requisite",
"RegisterSAML:com.arsdigita.kernel.security.CookieLoginModule:optional"
});
private final Parameter m_adminEmail = new StringParameter(
"waf.admin.contact_email", Parameter.OPTIONAL, null);

View File

@ -57,7 +57,8 @@ import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
/**
* Provides methods for logging in and logging out the current user and accessing the user ID.
* Provides methods for logging in and logging out the current user and
* accessing the user ID.
*
* @author Sameer Ajmani
* @version $Id: UserContext.java 1498 2007-03-19 16:22:15Z apevec $
@ -81,6 +82,11 @@ public class UserContext {
*/
public static final String REGISTER_SSO_LOGIN_CONTEXT = "RegisterSSO";
/**
* Name of the SAML login context
*/
public static final String REGISTER_SAML_LOGIN_CONTEXT = "RegisterSAML";
// fields
private HttpServletRequest m_req;
private HttpServletResponse m_res;
@ -101,7 +107,8 @@ public class UserContext {
}
/**
* Loads the values for this <code>UserContext</code> from the given Subject.
* Loads the values for this <code>UserContext</code> from the given
* Subject.
*/
private void loadValues(Subject subject)
throws LoginException {
@ -118,11 +125,12 @@ public class UserContext {
}
/**
* Creates a user context from an HTTP request. Attempts to log in the user automatically to
* load the user ID. Code should access this class using
* Creates a user context from an HTTP request. Attempts to log in the user
* automatically to load the user ID. Code should access this class using
* <code>KernelHelper.getKernelRequestContext(req).getUserContext()</code>.
*
* @throws RedirectException if the user should be redirected to the login page.
* @throws RedirectException if the user should be redirected to the login
* page.
*/
public UserContext(HttpServletRequest req,
HttpServletResponse res)
@ -149,7 +157,8 @@ public class UserContext {
login(UserAuthentication.retrieveForLoginName(username).getUser());
s_log.debug("SUCCESS login(username)");
} catch (DataObjectNotFoundException e) {
throw new AccountNotFoundException("user " + username + " does not exist", e);
throw new AccountNotFoundException("user " + username
+ " does not exist", e);
}
}
@ -169,7 +178,8 @@ public class UserContext {
login(User.retrieve(userID));
s_log.debug("SUCCESS login(userID)");
} catch (DataObjectNotFoundException e) {
throw new AccountNotFoundException("user " + userID + " does not exist", e);
throw new AccountNotFoundException("user " + userID
+ " does not exist", e);
}
}
@ -178,8 +188,9 @@ public class UserContext {
*
* @param target the User to become
*
* @throws FailedLoginException if the current user is not logged in, doesn't exist, or doesn't
* have admin privileges on the target user.
* @throws FailedLoginException if the current user is not logged in,
* doesn't exist, or doesn't have admin
* privileges on the target user.
*
* @throws LoginException if an error occurs.
*/
@ -205,8 +216,9 @@ public class UserContext {
throw new LoginException("This user is currently banned");
}
PermissionDescriptor superuser = new PermissionDescriptor(PrivilegeDescriptor.ADMIN, target,
user);
PermissionDescriptor superuser = new PermissionDescriptor(
PrivilegeDescriptor.ADMIN, target,
user);
if (!PermissionService.checkPermission(superuser)) {
s_log.debug("FAILURE login(User): insufficient privileges");
@ -214,14 +226,16 @@ public class UserContext {
+ " failed to log in as user "
+ target.getID()
+ " due to insufficient privileges");
throw new FailedLoginException("insufficient privileges to become target user");
throw new FailedLoginException(
"insufficient privileges to become target user");
}
// set the target user ID in the Subject and login
Subject subject = new Subject();
subject.getPrincipals().add(new PartyPrincipal(target.getID()));
CallbackHandler handler = new RequestCallbackHandler();
LoginContext context = new LoginContext(REQUEST_LOGIN_CONTEXT, subject, handler);
LoginContext context = new LoginContext(REQUEST_LOGIN_CONTEXT, subject,
handler);
clearValues();
context.login();
loadValues(context.getSubject());
@ -241,7 +255,8 @@ public class UserContext {
/**
* Determines whether the user is logged in.
*
* @return <code>true</code> if the user is logged in, <code>false</code> otherwise.
* @return <code>true</code> if the user is logged in, <code>false</code>
* otherwise.
*/
public boolean isLoggedIn() {
return (m_userID != null);
@ -250,7 +265,8 @@ public class UserContext {
/**
* Determines whether the user is recovering a forgotten password.
*
* @return <code>true</code> if the user is recovering, <code>false</code> otherwise.
* @return <code>true</code> if the user is recovering, <code>false</code>
* otherwise.
*/
public boolean isRecovering() {
return m_recovering;
@ -266,7 +282,8 @@ public class UserContext {
}
/**
* Returns the set of all possible URL params used by UserContext. Package-private.
* Returns the set of all possible URL params used by UserContext.
* Package-private.
*
* @return an unmodifiable set of bebop ParameterModels.
*/
@ -274,8 +291,9 @@ public class UserContext {
try {
// LoginModules add ParameterModels to Subject in initialize()
LoginContext context = new LoginContext(REQUEST_LOGIN_CONTEXT);
return Collections.unmodifiableSet(context.getSubject().getPublicCredentials(
ParameterModel.class));
return Collections.unmodifiableSet(context.getSubject()
.getPublicCredentials(
ParameterModel.class));
} catch (LoginException e) {
throw new UncheckedWrapperException("Could not load context", e);
}
@ -296,10 +314,12 @@ public class UserContext {
}
/**
* Returns a User object for the current user. Subsequent calls to this method return references
* to the same User object until the <code>logout</code> method is called.
* Returns a User object for the current user. Subsequent calls to this
* method return references to the same User object until the
* <code>logout</code> method is called.
*
* @return the User object for the logged in user or null if the user is not found.
* @return the User object for the logged in user or null if the user is not
* found.
*
* @throws IllegalStateException if the user is not logged in.
*/
@ -321,10 +341,11 @@ public class UserContext {
}
/**
* Logs in the user from data in the current request. Checks the session ID using
* <code>SessionContext</code>.
* Logs in the user from data in the current request. Checks the session ID
* using <code>SessionContext</code>.
*
* @throws RedirectException if the user should be redirected to the login page.
* @throws RedirectException if the user should be redirected to the login
* page.
*/
private void login()
throws RedirectException {
@ -333,7 +354,8 @@ public class UserContext {
boolean success = false;
try {
// log in user from request parameters
LoginContext context = new LoginContext(REQUEST_LOGIN_CONTEXT, handler);
LoginContext context = new LoginContext(REQUEST_LOGIN_CONTEXT,
handler);
clearValues();
context.login();
loadValues(context.getSubject());
@ -362,7 +384,7 @@ public class UserContext {
// common code for all exception cases
if (Util.getSecurityHelper().requiresLogin(m_req)) {
s_log.debug("This request requires logging in; "
+ "requesting redirect to login UI");
+ "requesting redirect to login UI");
redirectToLoginPage(m_req);
} else {
s_log.debug("This request does not require logging in");
@ -404,7 +426,8 @@ public class UserContext {
return;
}
m_username = userpass.substring(0, colon);
m_password = userpass.substring(colon + 1, userpass.length()).toCharArray();
m_password = userpass.substring(colon + 1, userpass.length())
.toCharArray();
} catch (IOException e) {
throw new UncheckedWrapperException(e);
}
@ -417,10 +440,12 @@ public class UserContext {
for (int i = 0; i < callbacks.length; i++) {
Callback cb = callbacks[i];
if (cb instanceof HTTPRequestCallback) {
((HTTPRequestCallback) cb).setRequest(UserContext.this.m_req);
((HTTPRequestCallback) cb)
.setRequest(UserContext.this.m_req);
} else if (cb instanceof HTTPResponseCallback) {
((HTTPResponseCallback) cb).setResponse(UserContext.this.m_res);
((HTTPResponseCallback) cb).setResponse(
UserContext.this.m_res);
} else if (cb instanceof LifetimeCallback) {
((LifetimeCallback) cb).setForever(false);
@ -440,7 +465,8 @@ public class UserContext {
}
/**
* Creates a URL to send the user to the login page and then return to the current page.
* Creates a URL to send the user to the login page and then return to the
* current page.
*
* @throws com.arsdigita.web.LoginSignal
*/
@ -449,18 +475,19 @@ public class UserContext {
}
/**
* Name of the request parameter that stores the URL to return to after redirecting to the login
* page.
* Name of the request parameter that stores the URL to return to after
* redirecting to the login page.
*
* @deprecated Use com.arsdigita.ui.login.LoginHelper.RETURN_URL_PARAM_NAME instead
* @deprecated Use com.arsdigita.ui.login.LoginHelper.RETURN_URL_PARAM_NAME
* instead
*/
public final static String RETURN_URL_PARAM_NAME = "return_url";
/**
* Encodes the given request into a return URL parameter. Returns
* <code>URLencode(returnURL)</code> where returnURL is
* <code>returnURI?key=URLencode(val)&...</code>. The original parameter values are
* doubly-encoded so that they are decoded appropriately.
* <code>returnURI?key=URLencode(val)&...</code>. The original parameter
* values are doubly-encoded so that they are decoded appropriately.
*
*
* @param req the request to encode
@ -496,7 +523,8 @@ public class UserContext {
}
/**
* Logs in the user. Checks the session ID using <code>SessionContext</code>.
* Logs in the user. Checks the session ID using
* <code>SessionContext</code>.
*
* @param username the user's username
* @param password the user's password
@ -510,16 +538,19 @@ public class UserContext {
throws LoginException {
s_log.debug("START login(username, password, forever)");
try {
CallbackHandler handler = new LoginCallbackHandler(username, password, forever);
LoginContext context = new LoginContext(REGISTER_LOGIN_CONTEXT, handler);
CallbackHandler handler = new LoginCallbackHandler(username,
password, forever);
LoginContext context = new LoginContext(REGISTER_LOGIN_CONTEXT,
handler);
clearValues();
context.login();
// We now check if the user is banned and, if so, we don't allow
// the user to login.
if (Kernel.getSecurityConfig().isUserBanOn()
&& UserAuthentication.retrieveForLoginName(username).getUser()
.isBanned()) {
&& UserAuthentication.retrieveForLoginName(username)
.getUser()
.isBanned()) {
throw new LoginException("This user is currently banned");
}
@ -533,8 +564,8 @@ public class UserContext {
}
/**
* Logs in the user using alternative "RegisterSSO" login context. It is expected that SSO token
* is present in the request
* Logs in the user using alternative "RegisterSSO" login context. It is
* expected that SSO token is present in the request
*
* @see SimpleSSOLoginModule
* @throws LoginException
@ -560,6 +591,30 @@ public class UserContext {
}
}
/**
* Logs in the user using a SAML response (which should be available in the
* request).
* @throws javax.security.auth.login.LoginException
*/
public void loginSAML() throws LoginException {
try {
final CallbackHandler handler = new RequestCallbackHandler();
final LoginContext context = new LoginContext(
REGISTER_SAML_LOGIN_CONTEXT,
handler);
clearValues();
context.login();
loadValues(context.getSubject());
m_session.loadSessionID(handler);
s_log.debug("SUCCESS loginSAML()");
} catch (LoginException ex) {
SecurityLogger.info("register SAML login failed: ", ex);
throw ex;
}
}
/**
* Implements callbacks for interactive (register-based) login.
*/
@ -597,10 +652,12 @@ public class UserContext {
for (int i = 0; i < callbacks.length; i++) {
Callback cb = callbacks[i];
if (cb instanceof HTTPRequestCallback) {
((HTTPRequestCallback) cb).setRequest(UserContext.this.m_req);
((HTTPRequestCallback) cb)
.setRequest(UserContext.this.m_req);
} else if (cb instanceof HTTPResponseCallback) {
((HTTPResponseCallback) cb).setResponse(UserContext.this.m_res);
((HTTPResponseCallback) cb).setResponse(
UserContext.this.m_res);
} else if (cb instanceof LifetimeCallback) {
((LifetimeCallback) cb).setForever(m_forever);
@ -639,8 +696,8 @@ public class UserContext {
}
/**
* Logs out the user. Clears the cached User object. Loads a new session ID using
* <code>SessionContext</code>.
* Logs out the user. Clears the cached User object. Loads a new session ID
* using <code>SessionContext</code>.
*
* @throws LoginException if logout fails.
*/
@ -657,7 +714,8 @@ public class UserContext {
}
/**
* Reports an unsupported callback to the debug log and throws an exception. Package-private.
* Reports an unsupported callback to the debug log and throws an exception.
* Package-private.
*
* @throws UnsupportedCallbackException with appropriate error message
*/

View File

@ -75,12 +75,15 @@ import java.net.URISyntaxException;
*
* @version $Id: UserLoginForm.java 1230 2006-06-22 11:50:59Z apevec $
*/
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);
= Logger.getLogger(UserLoginForm.class);
// package friendly static form name makes writing HttpUnitTest easier
final static String FORM_NAME = "user-login";
@ -91,7 +94,7 @@ public class UserLoginForm extends Form
private TextField m_loginName;
private Password m_password;
private boolean m_autoRegistrationOn;
private SecurityConfig securityConfig = SecurityConfig.getConfig();
private final SecurityConfig securityConfig = SecurityConfig.getConfig();
/**
* Default constructor delegates to a constructor which creates a LoginForm
@ -129,14 +132,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());
@ -145,7 +148,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 (Kernel.getConfig().isLoginRemembered()) {
@ -154,8 +157,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);
@ -165,16 +168,16 @@ public class UserLoginForm extends Form
if (securityConfig.getEnableQuestion()) {
add(new DynamicLink("login.userRegistrationForm.forgotPasswordLink",
LoginServlet.getRecoverPasswordPageURL()));
LoginServlet.getRecoverPasswordPageURL()));
}
if (m_autoRegistrationOn) {
add(new DynamicLink("login.userRegistrationForm.newUserRegister",
LoginServlet.getNewUserPageURL()));
LoginServlet.getNewUserPageURL()));
}
add(new ElementComponent("subsite:promptToEnableCookiesMsg",
LoginServlet.SUBSITE_NS_URI));
LoginServlet.SUBSITE_NS_URI));
}
/**
@ -182,8 +185,8 @@ public class UserLoginForm extends Form
*/
private void setupLogin() {
SimpleContainer loginMessage
= new SimpleContainer("subsite:loginPromptMsg",
LoginServlet.SUBSITE_NS_URI);
= new SimpleContainer("subsite:loginPromptMsg",
LoginServlet.SUBSITE_NS_URI);
if (Kernel.getConfig().emailIsPrimaryIdentifier()) {
loginMessage.setClassAttr("email");
@ -195,15 +198,16 @@ public class UserLoginForm extends Form
if (Kernel.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.
addInitListener(new ScreenNameInitListener(
(StringParameter) m_loginName.
getParameterModel()));
}
//m_loginName.addValidationListener(new NotNullValidationListener());
@ -213,11 +217,12 @@ public class UserLoginForm extends Form
/**
*
* @param event
*
* @throws FormProcessException
*/
@Override
public void init(FormSectionEvent event)
throws FormProcessException {
throws FormProcessException {
s_log.info("In init");
if (Kernel.getConfig().isSSOenabled()) {
// try SSO login
@ -232,27 +237,31 @@ public class UserLoginForm extends Form
s_log.debug("SSO failed", le);
}
}
if (securityConfig.getEnableSaml()) {
// ToDo Try SAML login via OneLogin
}
try {
// create timestamp
String value = Credential.create(FORM_TIMESTAMP,
1000 * TIMESTAMP_LIFETIME_SECS).
toString();
1000 * TIMESTAMP_LIFETIME_SECS).
toString();
m_timestamp.setValue(event.getPageState(), value);
} catch (CredentialException e) {
s_log.debug("Could not create timestamp", e);
throw new FormProcessException(LoginGlobalizationUtil.globalize(
"login.userLoginForm.couldnt_create_timestamp"));
"login.userLoginForm.couldnt_create_timestamp"));
}
}
/**
*
* @param event
*
* @throws FormProcessException
*/
@Override
public void validate(FormSectionEvent event)
throws FormProcessException {
throws FormProcessException {
s_log.debug("In validate");
@ -274,8 +283,9 @@ public class UserLoginForm extends Form
s_log.info("Invalid credential");
final String path = LoginServlet.getLoginExpiredPageURL();
final URL url = com.arsdigita.web.URL.there(state.getRequest(),
path);
final URL url = com.arsdigita.web.URL.there(state
.getRequest(),
path);
throw new RedirectSignal(url, false);
}
@ -295,8 +305,10 @@ public class UserLoginForm extends Form
/**
*
* @param event
*
* @throws FormProcessException
*/
@Override
public void process(FormSectionEvent event) throws FormProcessException {
s_log.debug("In process");
@ -315,15 +327,17 @@ public class UserLoginForm extends Form
}
//Cancel:
if (m_saveCancelSection.getCancelButton().isSelected(state)) {
//redirect the user to the place they came from.
try {
String refererURI = new URI(req.getHeader("referer")).getPath();
if (refererURI.equals("/ccm/register/")) {
final String path = UI.getRootPageURL(req);
throw new RedirectSignal(com.arsdigita.web.URL.there(req, path), true);
throw new RedirectSignal(com.arsdigita.web.URL.there(req,
path),
true);
}
throw new ReturnSignal(req, refererURI);
} catch (URISyntaxException e) {
@ -341,11 +355,12 @@ public class UserLoginForm extends Form
* onBadPassword, onAccountNotFound, onLoginException).
*
* @param event
*
* @throws FormProcessException if there is an unexpected login error
*
*/
protected void loginUser(FormSectionEvent event)
throws FormProcessException {
throws FormProcessException {
PageState state = event.getPageState();
try {
@ -353,15 +368,15 @@ public class UserLoginForm extends Form
String username = null;
if (Kernel.getConfig().emailIsPrimaryIdentifier()) {
username = ((InternetAddress) m_loginName.getValue(state)).
getAddress();
getAddress();
} else {
username = (String) m_loginName.getValue(state);
}
char[] password = ((String) m_password.getValue(state)).trim().
toCharArray();
toCharArray();
boolean forever = getPersistentLoginValue(event.getPageState(),
false);
false);
// attempt to log in user
ctx.login(username, password, forever);
onLoginSuccess(event);
@ -382,11 +397,12 @@ public class UserLoginForm extends Form
* Executed when login succeeds. Default implementation does nothing.
*
* @param event
*
* @throws com.arsdigita.bebop.FormProcessException
*
*/
protected void onLoginSuccess(FormSectionEvent event)
throws FormProcessException {
throws FormProcessException {
// do nothing
}
@ -394,11 +410,12 @@ public class UserLoginForm extends Form
*
* @param event
* @param e
*
* @throws FormProcessException
*/
protected void onBadPassword(FormSectionEvent event,
FailedLoginException e)
throws FormProcessException {
FailedLoginException e)
throws FormProcessException {
onLoginFail(event, e);
}
@ -409,15 +426,16 @@ public class UserLoginForm extends Form
*
* @param event
* @param e
*
* @throws com.arsdigita.bebop.FormProcessException
*
*/
protected void onLoginFail(FormSectionEvent event,
LoginException e)
throws FormProcessException {
LoginException e)
throws FormProcessException {
s_log.debug("Login fail");
event.getFormData().addError((String) ERROR_LOGIN_FAIL.localize(event.
getPageState().getRequest()));
getPageState().getRequest()));
}
/**
@ -427,8 +445,8 @@ public class UserLoginForm extends Form
*
*/
protected void onAccountNotFound(FormSectionEvent event,
AccountNotFoundException e)
throws FormProcessException {
AccountNotFoundException e)
throws FormProcessException {
PageState state = event.getPageState();
// no such user, so bring up form for new users
@ -449,8 +467,8 @@ public class UserLoginForm extends Form
*
*/
protected void onLoginException(FormSectionEvent event,
LoginException e)
throws FormProcessException {
LoginException e)
throws FormProcessException {
// unexpected error happened during login
s_log.error("Login failed", e);
throw new FormProcessException(e);
@ -460,12 +478,13 @@ public class UserLoginForm extends Form
* Determines whether a persistent cookie is requested in the given form.
*
* @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.
* 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) {
boolean defaultValue) {
// Problem:
// getValue(state) returns an Object of type StringArray, if the
// Checkbox is marked.
@ -502,15 +521,15 @@ public class UserLoginForm extends Form
ParameterMap map = new ParameterMap();
map.setParameter(LoginHelper.RETURN_URL_PARAM_NAME,
m_returnURL.getValue(state));
m_returnURL.getValue(state));
map.setParameter(FORM_PERSISTENT_LOGIN_P,
m_isPersistent.getValue(state));
m_isPersistent.getValue(state));
map.setParameter(FORM_EMAIL,
m_loginName.getValue(state));
m_loginName.getValue(state));
final URL dest = com.arsdigita.web.URL.there(state.getRequest(),
url,
map);
url,
map);
throw new RedirectSignal(dest, true);