Frage/Antwort für vergessenes Passwort kann jetzt deaktiviert werden

git-svn-id: https://svn.libreccm.org/ccm/trunk@1144 8810af33-2d31-482b-a856-94f89814c4df
master
jensp 2011-10-05 14:08:35 +00:00
parent aaf628a435
commit 3447e16e8e
6 changed files with 231 additions and 221 deletions

View File

@ -44,24 +44,20 @@ import org.apache.log4j.Logger;
* @version $Revision: #8 $ $Date: 2004/08/16 $ * @version $Revision: #8 $ $Date: 2004/08/16 $
* @version $Id: SecurityConfig.java 1471 2007-03-12 11:27:55Z chrisgilbert23 $ * @version $Id: SecurityConfig.java 1471 2007-03-12 11:27:55Z chrisgilbert23 $
*/ */
public class SecurityConfig extends AbstractConfig { public class SecurityConfig extends AbstractConfig {
private static final Logger s_log = Logger.getLogger(SecurityConfig.class); private static final Logger s_log = Logger.getLogger(SecurityConfig.class);
private static SecurityConfig s_config = null; private static SecurityConfig s_config = null;
private static String s_systemAdministratorEmailAddress = null; private static String s_systemAdministratorEmailAddress = null;
/** Size of secret key in bytes. **/ /** Size of secret key in bytes. **/
public static int SECRET_KEY_BYTES = 16; public static int SECRET_KEY_BYTES = 16;
/** The class name of the SecurityHelper implementation. Must implement /** The class name of the SecurityHelper implementation. Must implement
SecurityHelper interface */ SecurityHelper interface */
private final Parameter m_securityHelperClass = new SpecificClassParameter private final Parameter m_securityHelperClass =
("waf.security_helper_class", Parameter.REQUIRED, new SpecificClassParameter(
com.arsdigita.kernel.security.DefaultSecurityHelper.class, "waf.security_helper_class", Parameter.REQUIRED,
com.arsdigita.kernel.security.SecurityHelper.class); com.arsdigita.kernel.security.DefaultSecurityHelper.class,
com.arsdigita.kernel.security.SecurityHelper.class);
// /** This parameter is obsolete. */ // /** This parameter is obsolete. */
// private final Parameter m_sessionTrackingMethod = new StringParameter // private final Parameter m_sessionTrackingMethod = new StringParameter
// ("waf.session_tracking_method", Parameter.REQUIRED, "cookie"); // ("waf.session_tracking_method", Parameter.REQUIRED, "cookie");
@ -69,16 +65,15 @@ public class SecurityConfig extends AbstractConfig {
* Authentication is checked for all requests, but requests with one of * Authentication is checked for all requests, but requests with one of
* these extensions will never cause a new cookie to be set. * these extensions will never cause a new cookie to be set.
* Include a leading dot for each extension. */ * Include a leading dot for each extension. */
private final Parameter m_excludedExtensions = new StringArrayParameter private final Parameter m_excludedExtensions = new StringArrayParameter(
("waf.excluded_extensions", Parameter.REQUIRED, "waf.excluded_extensions", Parameter.REQUIRED,
new String[] { ".jpg", ".gif", ".png", ".pdf" } ); new String[]{
".jpg", ".gif", ".png", ".pdf"});
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// This section completely moved to com.arsdigita.ui.UIConfig. // This section completely moved to com.arsdigita.ui.UIConfig.
// Configuration is not an Initializer task. // Configuration is not an Initializer task.
// Retained here during transition, should be removed when completed (2011-02) // Retained here during transition, should be removed when completed (2011-02)
// ///////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////
// /** Key for the root page of the site. */ // /** Key for the root page of the site. */
// private final Parameter m_rootPage = new StringParameter // private final Parameter m_rootPage = new StringParameter
// ("waf.pagemap.root", Parameter.REQUIRED, "register/"); // ("waf.pagemap.root", Parameter.REQUIRED, "register/");
@ -112,17 +107,14 @@ public class SecurityConfig extends AbstractConfig {
// ("waf.pagemap.permission", Parameter.REQUIRED, "permissions/"); // ("waf.pagemap.permission", Parameter.REQUIRED, "permissions/");
// private final Parameter m_permSinglePage = new StringParameter // private final Parameter m_permSinglePage = new StringParameter
// ("waf.pagemap.perm_single", Parameter.REQUIRED, "permissions/one"); // ("waf.pagemap.perm_single", Parameter.REQUIRED, "permissions/one");
// //////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////////
private final Parameter m_cookieDurationMinutes = new IntegerParameter(
"waf.pagemap.cookies_duration_minutes", Parameter.OPTIONAL, null);
private final Parameter m_cookieDurationMinutes = new IntegerParameter private final Parameter m_cookieDomain = new StringParameter(
("waf.pagemap.cookies_duration_minutes", Parameter.OPTIONAL, null); "waf.cookie_domain", Parameter.OPTIONAL, null);
private final Parameter m_cookieDomain = new StringParameter private final Parameter m_loginConfig = new StringArrayParameter(
("waf.cookie_domain", Parameter.OPTIONAL, null); "waf.login_config", Parameter.REQUIRED,
new String[]{
private final Parameter m_loginConfig = new StringArrayParameter
("waf.login_config", Parameter.REQUIRED, new String[] {
"Request:com.arsdigita.kernel.security.AdminLoginModule:sufficient", "Request:com.arsdigita.kernel.security.AdminLoginModule:sufficient",
"Request:com.arsdigita.kernel.security.RecoveryLoginModule:sufficient", "Request:com.arsdigita.kernel.security.RecoveryLoginModule:sufficient",
"Request:com.arsdigita.kernel.security.CookieLoginModule:requisite", "Request:com.arsdigita.kernel.security.CookieLoginModule:requisite",
@ -131,15 +123,16 @@ public class SecurityConfig extends AbstractConfig {
"Register:com.arsdigita.kernel.security.CookieLoginModule:optional", "Register:com.arsdigita.kernel.security.CookieLoginModule:optional",
"RegisterSSO:com.arsdigita.kernel.security.SimpleSSOLoginModule:requisite", "RegisterSSO:com.arsdigita.kernel.security.SimpleSSOLoginModule:requisite",
"RegisterSSO:com.arsdigita.kernel.security.CookieLoginModule:optional" "RegisterSSO:com.arsdigita.kernel.security.CookieLoginModule:optional"
} });
); private final Parameter m_adminEmail = new StringParameter(
"waf.admin.contact_email", Parameter.OPTIONAL, null);
private final Parameter m_adminEmail = new StringParameter private final Parameter m_autoRegistrationOn = new BooleanParameter(
("waf.admin.contact_email", Parameter.OPTIONAL, null); "waf.auto_registration_on", Parameter.REQUIRED, Boolean.TRUE);
private final Parameter m_autoRegistrationOn = new BooleanParameter private final Parameter m_userBanOn = new BooleanParameter("waf.user_ban_on",
("waf.auto_registration_on", Parameter.REQUIRED, Boolean.TRUE); Parameter.REQUIRED,
private final Parameter m_userBanOn = new BooleanParameter Boolean.FALSE);
("waf.user_ban_on", Parameter.REQUIRED, Boolean.FALSE); private final Parameter m_enableQuestion = new BooleanParameter(
"waf.user_question.enable", Parameter.REQUIRED, Boolean.FALSE);
/** /**
* Constructs an empty SecurityConfig object * Constructs an empty SecurityConfig object
@ -169,6 +162,7 @@ public class SecurityConfig extends AbstractConfig {
register(m_adminEmail); register(m_adminEmail);
register(m_autoRegistrationOn); register(m_autoRegistrationOn);
register(m_userBanOn); register(m_userBanOn);
register(m_enableQuestion);
loadInfo(); loadInfo();
} }
@ -207,13 +201,12 @@ public class SecurityConfig extends AbstractConfig {
// public final String getSessionTrackingMethod() { // public final String getSessionTrackingMethod() {
// return (String) get(m_sessionTrackingMethod); // return (String) get(m_sessionTrackingMethod);
// } // }
/** /**
* *
* @return * @return
*/ */
public final List getExcludedExtensions() { public final List getExcludedExtensions() {
return Arrays.asList( (String[]) get(m_excludedExtensions)); return Arrays.asList((String[]) get(m_excludedExtensions));
} }
// MOVED, see above // MOVED, see above
@ -254,37 +247,45 @@ public class SecurityConfig extends AbstractConfig {
// return (String) get(m_permSinglePage); // return (String) get(m_permSinglePage);
// } // }
// /////////////////////////////////////////////////////////////////////////// // ///////////////////////////////////////////////////////////////////////////
public String getCookieDomain() { public String getCookieDomain() {
return (String) get(m_cookieDomain); return (String) get(m_cookieDomain);
} }
String[] getLoginConfig() { String[] getLoginConfig() {
return (String[]) get(m_loginConfig); return (String[]) get(m_loginConfig);
} }
Integer getCookieDurationMinutes() { Integer getCookieDurationMinutes() {
return (Integer) get(m_cookieDurationMinutes); return (Integer) get(m_cookieDurationMinutes);
} }
boolean isUserBanOn() { boolean isUserBanOn() {
return ((Boolean) get(m_userBanOn)).booleanValue(); return ((Boolean) get(m_userBanOn)).booleanValue();
} }
public String getAdminContactEmail() { public String getAdminContactEmail() {
String email = (String) get(m_adminEmail); String email = (String) get(m_adminEmail);
if (email == null || email.trim().length() == 0) { if (email == null || email.trim().length() == 0) {
email = getSystemAdministratorEmailAddress(); email = getSystemAdministratorEmailAddress();
} }
return email; return email;
} }
public Boolean getEnableQuestion() {
return (Boolean) get(m_enableQuestion);
}
private static synchronized String getSystemAdministratorEmailAddress() { private static synchronized String getSystemAdministratorEmailAddress() {
if (s_systemAdministratorEmailAddress == null) { if (s_systemAdministratorEmailAddress == null) {
ObjectPermissionCollection perms = ObjectPermissionCollection perms =
PermissionService.getGrantedUniversalPermissions(); PermissionService.
getGrantedUniversalPermissions();
perms.addEqualsFilter("granteeIsUser", Boolean.TRUE); perms.addEqualsFilter("granteeIsUser", Boolean.TRUE);
perms.clearOrder(); perms.clearOrder();
perms.addOrder("granteeID"); perms.addOrder("granteeID");
if (perms.next()) { if (perms.next()) {
s_systemAdministratorEmailAddress = perms.getGranteeEmail().toString(); s_systemAdministratorEmailAddress = perms.getGranteeEmail().
toString();
perms.close(); perms.close();
} else { } else {
// Haven't found anything. We don't want to repeat this query // Haven't found anything. We don't want to repeat this query
@ -298,5 +299,4 @@ public class SecurityConfig extends AbstractConfig {
public final boolean isAutoRegistrationOn() { public final boolean isAutoRegistrationOn() {
return ((Boolean) get(m_autoRegistrationOn)).booleanValue(); return ((Boolean) get(m_autoRegistrationOn)).booleanValue();
} }
} }

View File

@ -2,23 +2,32 @@ waf.login_config.title=Login Configuration
waf.login_config.purpose=Enter JAAS login configuration, using the syntax described in Javadoc for com.arsdigita.kernel.security.LoginConfig waf.login_config.purpose=Enter JAAS login configuration, using the syntax described in Javadoc for com.arsdigita.kernel.security.LoginConfig
waf.login_config.example=Request:com.arsdigita.kernel.security.AdminLoginModule:sufficient,Register:com.arsdigita.kernel.security.LocalLoginModule:requisite waf.login_config.example=Request:com.arsdigita.kernel.security.AdminLoginModule:sufficient,Register:com.arsdigita.kernel.security.LocalLoginModule:requisite
waf.login_config.format=[string,string,...] waf.login_config.format=[string,string,...]
waf.cookie_domain.title=Cookie Domain waf.cookie_domain.title=Cookie Domain
waf.cookie_domain.purpose=Enter the domain to which the Aplaws authentication cookie is presented waf.cookie_domain.purpose=Enter the domain to which the Aplaws authentication cookie is presented
waf.cookie_domain.example=.example.com waf.cookie_domain.example=.example.com
waf.cookie_domain.format=[string] waf.cookie_domain.format=[string]
waf.admin.contact_email.title=System administrator email address waf.admin.contact_email.title=System administrator email address
waf.admin.contact_email.purpose=Email address that will be displayed on footer of login/admin pages, if empty then site-wide admin email will be substituted waf.admin.contact_email.purpose=Email address that will be displayed on footer of login/admin pages, if empty then site-wide admin email will be substituted
waf.admin.contact_email.example=ccmadmin@example.com waf.admin.contact_email.example=ccmadmin@example.com
waf.admin.contact_email.format=[string] waf.admin.contact_email.format=[string]
waf.auto_registration_on.title=Auto Registration waf.auto_registration_on.title=Auto Registration
waf.auto_registration_on.purpose=New users get automatically redirected to the create new user form waf.auto_registration_on.purpose=New users get automatically redirected to the create new user form
waf.auto_registration_on.example=true waf.auto_registration_on.example=true
waf.auto_registration_on.format=true|false waf.auto_registration_on.format=true|false
waf.user_ban_on.title=User Ban waf.user_ban_on.title=User Ban
waf.user_ban_on.purpose=Check on each access if user has been banned from the site. waf.user_ban_on.purpose=Check on each access if user has been banned from the site.
waf.user_ban_on.example=false waf.user_ban_on.example=false
waf.user_ban_on.format=true|false waf.user_ban_on.format=true|false
waf.user_question_enable.title=Enable question
waf.user_question_enable.purpose=Enable question if a user has forgotten its password
waf.user_question_enable.example=false
waf.user_question_enable.format=true|false
# Moved to com.arsdigita.ui.UIConfig (2011-02). # Moved to com.arsdigita.ui.UIConfig (2011-02).
# Retained here for easy reference during transition phase # Retained here for easy reference during transition phase
# waf.pagemap.root.title=Root Page # waf.pagemap.root.title=Root Page

View File

@ -34,6 +34,7 @@ core.ui.pagemap.workspace_url.example=pvt/
core.ui.pagemap.workspace_url.format=[string] core.ui.pagemap.workspace_url.format=[string]
#waf.pagemap.newuser.title=New User Page #waf.pagemap.newuser.title=New User Page
#waf.pagemap.newuser.purpose=Enter the relative URL for the New User Page #waf.pagemap.newuser.purpose=Enter the relative URL for the New User Page
#waf.pagemap.newuser.example=register/new-user #waf.pagemap.newuser.example=register/new-user

View File

@ -30,41 +30,41 @@ import com.arsdigita.kernel.EmailAddress;
import com.arsdigita.kernel.PersonName; import com.arsdigita.kernel.PersonName;
import com.arsdigita.kernel.User; import com.arsdigita.kernel.User;
import com.arsdigita.kernel.UserAuthentication; import com.arsdigita.kernel.UserAuthentication;
import com.arsdigita.kernel.security.SecurityConfig;
/** /**
* Form used to add a new user to the system. * Form used to add a new user to the system.
* *
* @version $Id: UserAddForm.java 287 2005-02-22 00:29:02Z sskracic $ * @version $Id: UserAddForm.java 287 2005-02-22 00:29:02Z sskracic $
*/ */
class UserAddForm extends UserForm class UserAddForm extends UserForm
implements FormProcessListener, implements FormProcessListener,
FormInitListener, FormInitListener,
AdminConstants AdminConstants {
{
private SecurityConfig securityConfig = SecurityConfig.getConfig();
private AdminSplitPanel m_adminPanel; private AdminSplitPanel m_adminPanel;
/** /**
* Default constructor. * Default constructor.
*/ */
public UserAddForm(AdminSplitPanel adminPanel) {
public UserAddForm (AdminSplitPanel adminPanel) {
super(USER_FORM_ADD); super(USER_FORM_ADD);
m_adminPanel = adminPanel; m_adminPanel = adminPanel;
addInitListener(this); addInitListener(this);
addProcessListener(this); addProcessListener(this);
// Add validation listeners for required parameters if (securityConfig.getEnableQuestion()) {
// Add validation listeners for required parameters
m_question.addValidationListener // but only if SecurityConfig.getEnableQuestion is true (jensp 2011-10-05)
(new NotEmptyValidationListener()); m_question.addValidationListener(new NotEmptyValidationListener());
}
} }
/** /**
* Initialize the form * Initialize the form
*/ */
public void init(FormSectionEvent e) { public void init(FormSectionEvent e) {
PageState state = e.getPageState(); PageState state = e.getPageState();
@ -77,16 +77,14 @@ class UserAddForm extends UserForm
/** /**
* Process the form. * Process the form.
*/ */
public void process(FormSectionEvent e)
public void process (FormSectionEvent e) throws FormProcessException {
throws FormProcessException
{
PageState state = e.getPageState(); PageState state = e.getPageState();
User user = new User(); User user = new User();
String email = String email =
((InternetAddress) m_primaryEmail.getValue(state)).getAddress(); ((InternetAddress) m_primaryEmail.getValue(state)).getAddress();
user.setPrimaryEmail(new EmailAddress(email)); user.setPrimaryEmail(new EmailAddress(email));
user.setScreenName((String) m_screenName.getValue(state)); user.setScreenName((String) m_screenName.getValue(state));
@ -106,10 +104,9 @@ class UserAddForm extends UserForm
// Add optional additional email address // Add optional additional email address
InternetAddress additional = InternetAddress additional =
(InternetAddress) m_additionalEmail.getValue(state); (InternetAddress) m_additionalEmail.getValue(state);
if (additional != null) { if (additional != null) {
user.addEmailAddress user.addEmailAddress(new EmailAddress(additional.getAddress()));
(new EmailAddress(additional.getAddress()));
} }
// Make new user persistent // Make new user persistent
@ -119,11 +116,13 @@ class UserAddForm extends UserForm
// Save user authentication credentials. // Save user authentication credentials.
UserAuthentication auth = UserAuthentication auth =
UserAuthentication.createForUser(user); UserAuthentication.createForUser(user);
auth.setPassword((String) m_password.getValue(state)); auth.setPassword((String) m_password.getValue(state));
auth.setPasswordQuestion((String) m_question.getValue(state)); if (securityConfig.getEnableQuestion()) {
auth.setPasswordAnswer((String) m_answer.getValue(state)); auth.setPasswordQuestion((String) m_question.getValue(state));
auth.setPasswordAnswer((String) m_answer.getValue(state));
}
auth.save(); auth.save();
// Switch to browse tab. // Switch to browse tab.

View File

@ -18,7 +18,6 @@
*/ */
package com.arsdigita.ui.admin; package com.arsdigita.ui.admin;
import com.arsdigita.bebop.Form; import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormData; import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.FormProcessException; import com.arsdigita.bebop.FormProcessException;
@ -36,6 +35,7 @@ import com.arsdigita.bebop.parameters.StringLengthValidationListener;
import com.arsdigita.bebop.parameters.StringParameter; import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.bebop.parameters.URLParameter; import com.arsdigita.bebop.parameters.URLParameter;
import com.arsdigita.kernel.Kernel; import com.arsdigita.kernel.Kernel;
import com.arsdigita.kernel.security.SecurityConfig;
import com.arsdigita.persistence.DataQuery; import com.arsdigita.persistence.DataQuery;
import com.arsdigita.persistence.Filter; import com.arsdigita.persistence.Filter;
import com.arsdigita.persistence.SessionManager; import com.arsdigita.persistence.SessionManager;
@ -52,23 +52,22 @@ import javax.servlet.http.HttpServletRequest;
* @author David Dao * @author David Dao
* @version $Id: UserForm.java 1508 2007-03-22 00:04:22Z apevec $ * @version $Id: UserForm.java 1508 2007-03-22 00:04:22Z apevec $
*/ */
class UserForm extends Form implements FormValidationListener, AdminConstants { class UserForm extends Form implements FormValidationListener, AdminConstants {
protected TextField m_firstName; protected TextField m_firstName;
protected TextField m_lastName; protected TextField m_lastName;
protected TextField m_primaryEmail; protected TextField m_primaryEmail;
protected TextField m_additionalEmail; protected TextField m_additionalEmail;
protected Password m_password; protected Password m_password;
protected Password m_confirmPassword; protected Password m_confirmPassword;
protected TextField m_question; protected TextField m_question;
protected TextField m_answer; protected TextField m_answer;
protected TextField m_url; protected TextField m_url;
protected TextField m_screenName; protected TextField m_screenName;
protected EmailList m_emailList; protected EmailList m_emailList;
private PasswordValidationListener m_pwListener; private PasswordValidationListener m_pwListener;
private NotEmptyValidationListener m_notNullListener; private NotEmptyValidationListener m_notNullListener;
private SecurityConfig securityConfig = SecurityConfig.getConfig();
public UserForm(String formName) { public UserForm(String formName) {
super(formName); super(formName);
@ -87,61 +86,61 @@ class UserForm extends Form implements FormValidationListener, AdminConstants {
int max = 60; int max = 60;
m_firstName = new TextField( m_firstName = new TextField(
new StringParameter(USER_FORM_INPUT_FIRST_NAME)); new StringParameter(USER_FORM_INPUT_FIRST_NAME));
m_firstName.setMaxLength(max); m_firstName.setMaxLength(max);
m_firstName.setSize(20); m_firstName.setSize(20);
m_firstName.addValidationListener m_firstName.addValidationListener(new NotEmptyValidationListener());
(new NotEmptyValidationListener()); m_firstName.addValidationListener(
m_firstName.addValidationListener new StringLengthValidationListener(max));
(new StringLengthValidationListener(max));
add(USER_FORM_LABEL_FIRST_NAME); add(USER_FORM_LABEL_FIRST_NAME);
add(m_firstName); add(m_firstName);
m_lastName = new TextField( m_lastName = new TextField(
new StringParameter(USER_FORM_INPUT_LAST_NAME)); new StringParameter(USER_FORM_INPUT_LAST_NAME));
m_lastName.setMaxLength(max); m_lastName.setMaxLength(max);
m_lastName.setSize(25); m_lastName.setSize(25);
m_lastName.addValidationListener m_lastName.addValidationListener(new NotEmptyValidationListener());
(new NotEmptyValidationListener()); m_lastName.addValidationListener(new StringLengthValidationListener(max));
m_lastName.addValidationListener
(new StringLengthValidationListener(max));
add(USER_FORM_LABEL_LAST_NAME); add(USER_FORM_LABEL_LAST_NAME);
add(m_lastName); add(m_lastName);
// Password // Password
m_password = new Password m_password = new Password(new StringParameter(USER_FORM_INPUT_PASSWORD));
(new StringParameter(USER_FORM_INPUT_PASSWORD));
add(USER_FORM_LABEL_PASSWORD); add(USER_FORM_LABEL_PASSWORD);
add(m_password); add(m_password);
// Password confirmation // Password confirmation
m_confirmPassword = new Password m_confirmPassword = new Password(new StringParameter(
(new StringParameter(USER_FORM_INPUT_PASSWORD_CONFIRMATION)); USER_FORM_INPUT_PASSWORD_CONFIRMATION));
add(USER_FORM_LABEL_PASSWORD_CONFIRMATION); add(USER_FORM_LABEL_PASSWORD_CONFIRMATION);
add(m_confirmPassword); add(m_confirmPassword);
// Password question // Password question
m_question = new TextField(new StringParameter(USER_FORM_INPUT_QUESTION)); m_question =
new TextField(new StringParameter(USER_FORM_INPUT_QUESTION));
m_question.setSize(50); m_question.setSize(50);
add(USER_FORM_LABEL_QUESTION); if (securityConfig.getEnableQuestion()) {
add(m_question); add(USER_FORM_LABEL_QUESTION);
add(m_question);
}
// Password answer // Password answer
m_answer = new TextField(new StringParameter(USER_FORM_INPUT_ANSWER)); m_answer = new TextField(new StringParameter(USER_FORM_INPUT_ANSWER));
m_answer.setSize(50); m_answer.setSize(50);
add(USER_FORM_LABEL_ANSWER); if (securityConfig.getEnableQuestion()) {
add(m_answer); add(USER_FORM_LABEL_ANSWER);
add(m_answer);
}
// Primary email address // Primary email address
m_primaryEmail = new TextField m_primaryEmail = new TextField(new EmailParameter(
(new EmailParameter(USER_FORM_INPUT_PRIMARY_EMAIL)); USER_FORM_INPUT_PRIMARY_EMAIL));
m_primaryEmail.addValidationListener m_primaryEmail.addValidationListener(new NotEmptyValidationListener());
(new NotEmptyValidationListener());
m_primaryEmail.setSize(50); m_primaryEmail.setSize(50);
add(USER_FORM_LABEL_PRIMARY_EMAIL); add(USER_FORM_LABEL_PRIMARY_EMAIL);
add(m_primaryEmail); add(m_primaryEmail);
@ -151,15 +150,15 @@ class UserForm extends Form implements FormValidationListener, AdminConstants {
add(USER_FORM_LABEL_ADDITIONAL_EMAIL_LIST); add(USER_FORM_LABEL_ADDITIONAL_EMAIL_LIST);
add(m_emailList); add(m_emailList);
m_additionalEmail = new TextField m_additionalEmail = new TextField(new EmailParameter(
(new EmailParameter(USER_FORM_INPUT_ADDITIONAL_EMAIL)); USER_FORM_INPUT_ADDITIONAL_EMAIL));
m_additionalEmail.setSize(50); m_additionalEmail.setSize(50);
add(USER_FORM_LABEL_ADDITIONAL_EMAIL); add(USER_FORM_LABEL_ADDITIONAL_EMAIL);
add(m_additionalEmail); add(m_additionalEmail);
// Screen name // Screen name
m_screenName = new TextField m_screenName = new TextField(new StringParameter(
(new StringParameter(USER_FORM_INPUT_SCREEN_NAME)); USER_FORM_INPUT_SCREEN_NAME));
if (Kernel.getConfig().screenNameIsPrimaryIdentifier()) { if (Kernel.getConfig().screenNameIsPrimaryIdentifier()) {
m_screenName.addValidationListener(new NotEmptyValidationListener()); m_screenName.addValidationListener(new NotEmptyValidationListener());
} }
@ -185,10 +184,8 @@ class UserForm extends Form implements FormValidationListener, AdminConstants {
* password-confirm field. Also verifies that primary email * password-confirm field. Also verifies that primary email
* address and screen name are unique amoung all users. * address and screen name are unique amoung all users.
*/ */
public void validate(FormSectionEvent event)
public void validate (FormSectionEvent event) throws FormProcessException {
throws FormProcessException
{
PageState ps = event.getPageState(); PageState ps = event.getPageState();
FormData data = event.getFormData(); FormData data = event.getFormData();
HttpServletRequest req = ps.getRequest(); HttpServletRequest req = ps.getRequest();
@ -199,50 +196,57 @@ class UserForm extends Form implements FormValidationListener, AdminConstants {
/** /**
* Verify that password and confirmation match. * Verify that password and confirmation match.
*/ */
if (userID == null) { if (userID == null) {
m_pwListener.validate( m_pwListener.validate(
new ParameterEvent(event.getSource(), new ParameterEvent(event.getSource(),
data.getParameter(USER_FORM_INPUT_PASSWORD))); data.getParameter(
USER_FORM_INPUT_PASSWORD)));
m_notNullListener.validate( m_notNullListener.validate(
new ParameterEvent(event.getSource(), new ParameterEvent(event.getSource(),
data.getParameter(USER_FORM_INPUT_PASSWORD_CONFIRMATION))); data.getParameter(
USER_FORM_INPUT_PASSWORD_CONFIRMATION)));
String password = (String) m_password.getValue(ps); String password = (String) m_password.getValue(ps);
String confirm = (String) m_confirmPassword.getValue(ps); String confirm = (String) m_confirmPassword.getValue(ps);
if (!StringUtils.emptyString(password) && !StringUtils.emptyString(confirm)) { if (!StringUtils.emptyString(password) && !StringUtils.emptyString(
confirm)) {
if (!password.equals(confirm)) { if (!password.equals(confirm)) {
data.addError(USER_FORM_INPUT_PASSWORD_CONFIRMATION, data.addError(USER_FORM_INPUT_PASSWORD_CONFIRMATION,
(String) USER_FORM_ERROR_PASSWORD_NOT_MATCH.localize(req)); (String) USER_FORM_ERROR_PASSWORD_NOT_MATCH.
localize(req));
} }
} }
} }
// If the password answer is anything but null, make sure it if (securityConfig.getEnableQuestion()) {
// contains some non-whitespace characters // If the password answer is anything but null, make sure it
// contains some non-whitespace characters
String answer = (String) m_answer.getValue(ps); String answer = (String) m_answer.getValue(ps);
if (userID == null) { if (userID == null) {
// Check for add form. // Check for add form.
if (answer == null || answer.trim().length()==0) { if (answer == null || answer.trim().length() == 0) {
data.addError(USER_FORM_INPUT_ANSWER, data.addError(USER_FORM_INPUT_ANSWER,
(String) USER_FORM_ERROR_ANSWER_NULL.localize(req)); (String) USER_FORM_ERROR_ANSWER_NULL.localize(
} req));
} else { }
// Check for edit form } else {
if (answer != null && answer.length() > 0 && answer.trim().length() == 0) { // Check for edit form
data.addError(USER_FORM_INPUT_ANSWER, if (answer != null && answer.length() > 0 && answer.trim().
(String) USER_FORM_ERROR_ANSWER_NULL.localize(req)); length()
== 0) {
data.addError(USER_FORM_INPUT_ANSWER,
(String) USER_FORM_ERROR_ANSWER_NULL.localize(
req));
}
} }
} }
/** /**
* Verify that primary email and screen name are unique * Verify that primary email and screen name are unique
*/ */
DataQuery query = SessionManager.getSession().retrieveQuery(
DataQuery query = SessionManager.getSession().retrieveQuery "com.arsdigita.kernel.RetrieveUsers");
("com.arsdigita.kernel.RetrieveUsers");
query.setParameter("excludeGroupId", new BigDecimal(0)); query.setParameter("excludeGroupId", new BigDecimal(0));
String email = null; String email = null;
@ -252,8 +256,8 @@ class UserForm extends Form implements FormValidationListener, AdminConstants {
String screenName = (String) m_screenName.getValue(ps); String screenName = (String) m_screenName.getValue(ps);
Filter filter = query.addFilter Filter filter = query.addFilter(
("primaryEmail = :email or screenName = :sn"); "primaryEmail = :email or screenName = :sn");
filter.set("email", email); filter.set("email", email);
filter.set("sn", screenName); filter.set("sn", screenName);
@ -267,18 +271,17 @@ class UserForm extends Form implements FormValidationListener, AdminConstants {
* screen name, email address, or both. Check the results and * screen name, email address, or both. Check the results and
* produce appropriate error messages. * produce appropriate error messages.
*/ */
while (query.next()) { while (query.next()) {
if (screenName != null && if (screenName != null && screenName.equals(query.get("screenName"))) {
screenName.equals(query.get("screenName"))) {
data.addError(USER_FORM_INPUT_SCREEN_NAME, data.addError(USER_FORM_INPUT_SCREEN_NAME,
(String) USER_FORM_ERROR_SCREEN_NAME_NOT_UNIQUE.localize(req)); (String) USER_FORM_ERROR_SCREEN_NAME_NOT_UNIQUE.
localize(req));
} }
if (email != null && if (email != null && email.equals(query.get("primaryEmail"))) {
email.equals(query.get("primaryEmail"))) {
data.addError(USER_FORM_INPUT_PRIMARY_EMAIL, data.addError(USER_FORM_INPUT_PRIMARY_EMAIL,
(String) USER_FORM_ERROR_PRIMARY_EMAIL_NOT_UNIQUE.localize(req)); (String) USER_FORM_ERROR_PRIMARY_EMAIL_NOT_UNIQUE.
localize(req));
} }
} }
@ -288,30 +291,31 @@ class UserForm extends Form implements FormValidationListener, AdminConstants {
/** /**
* Hide all security-related components * Hide all security-related components
*/ */
protected void hideSecurityInfo(PageState state) {
protected void hideSecurityInfo (PageState state) { setSecurityInfo(state, false);
setSecurityInfo(state,false);
} }
/** /**
* Show all security-related components * Show all security-related components
*/ */
protected void showSecurityInfo(PageState state) {
protected void showSecurityInfo (PageState state) { setSecurityInfo(state, true);
setSecurityInfo(state,true);
} }
private void setSecurityInfo (PageState state, boolean isVisible) { private void setSecurityInfo(PageState state, boolean isVisible) {
USER_FORM_LABEL_PASSWORD.setVisible(state, isVisible); USER_FORM_LABEL_PASSWORD.setVisible(state, isVisible);
USER_FORM_LABEL_PASSWORD_CONFIRMATION.setVisible(state, isVisible); USER_FORM_LABEL_PASSWORD_CONFIRMATION.setVisible(state, isVisible);
USER_FORM_LABEL_QUESTION.setVisible(state, isVisible); if (securityConfig.getEnableQuestion()) {
USER_FORM_LABEL_ANSWER.setVisible(state, isVisible); USER_FORM_LABEL_QUESTION.setVisible(state, isVisible);
USER_FORM_LABEL_ANSWER.setVisible(state, isVisible);
}
m_password.setVisible(state, isVisible); m_password.setVisible(state, isVisible);
m_confirmPassword.setVisible(state, isVisible); m_confirmPassword.setVisible(state, isVisible);
m_question.setVisible(state, isVisible); if (securityConfig.getEnableQuestion()) {
m_answer.setVisible(state, isVisible); m_question.setVisible(state, isVisible);
m_answer.setVisible(state, isVisible);
}
} }
} }

View File

@ -48,6 +48,7 @@ import com.arsdigita.kernel.security.AccountNotFoundException;
import com.arsdigita.kernel.security.Credential; import com.arsdigita.kernel.security.Credential;
import com.arsdigita.kernel.security.CredentialException; import com.arsdigita.kernel.security.CredentialException;
// import com.arsdigita.kernel.security.LegacyInitializer; // import com.arsdigita.kernel.security.LegacyInitializer;
import com.arsdigita.kernel.security.SecurityConfig;
import com.arsdigita.kernel.security.UserContext; import com.arsdigita.kernel.security.UserContext;
import com.arsdigita.ui.UI; import com.arsdigita.ui.UI;
import com.arsdigita.web.ParameterMap; import com.arsdigita.web.ParameterMap;
@ -71,23 +72,21 @@ import org.apache.log4j.Logger;
* *
* @version $Id: UserRegistrationForm.java 1230 2006-06-22 11:50:59Z apevec $ * @version $Id: UserRegistrationForm.java 1230 2006-06-22 11:50:59Z apevec $
*/ */
public class UserRegistrationForm extends Form public class UserRegistrationForm extends Form
implements LoginConstants, FormInitListener, implements LoginConstants, FormInitListener,
FormValidationListener, FormProcessListener { FormValidationListener, FormProcessListener {
private static final Logger s_log = private static final Logger s_log =
Logger.getLogger(UserRegistrationForm.class); Logger.getLogger(UserRegistrationForm.class);
// package friendly static form name makes writing HttpUnitTest easier // package friendly static form name makes writing HttpUnitTest easier
final static String FORM_NAME = "user-login"; final static String FORM_NAME = "user-login";
private CheckboxGroup m_isPersistent; private CheckboxGroup m_isPersistent;
private Hidden m_timestamp; private Hidden m_timestamp;
private Hidden m_returnURL; private Hidden m_returnURL;
private TextField m_loginName; private TextField m_loginName;
private Password m_password; private Password m_password;
private boolean m_autoRegistrationOn; private boolean m_autoRegistrationOn;
private SecurityConfig securityConfig = SecurityConfig.getConfig();
public UserRegistrationForm() { public UserRegistrationForm() {
this(true); this(true);
@ -111,18 +110,18 @@ public class UserRegistrationForm extends Form
m_autoRegistrationOn = autoRegistrationOn; m_autoRegistrationOn = autoRegistrationOn;
m_timestamp = new Hidden(new StringParameter (FORM_TIMESTAMP)); m_timestamp = new Hidden(new StringParameter(FORM_TIMESTAMP));
add(m_timestamp); add(m_timestamp);
m_returnURL = new Hidden(new URLParameter m_returnURL = new Hidden(new URLParameter(
(LoginHelper.RETURN_URL_PARAM_NAME)); LoginHelper.RETURN_URL_PARAM_NAME));
m_returnURL.setPassIn(true); m_returnURL.setPassIn(true);
add(m_returnURL); add(m_returnURL);
setupLogin(); setupLogin();
add(new Label(LoginHelper.getMessage add(new Label(LoginHelper.getMessage(
("login.userRegistrationForm.password"))); "login.userRegistrationForm.password")));
m_password = new Password(new StringParameter(FORM_PASSWORD)); m_password = new Password(new StringParameter(FORM_PASSWORD));
// Since new users should not enter a password, allow null. // Since new users should not enter a password, allow null.
//m_password.addValidationListener(new NotNullValidationListener()); //m_password.addValidationListener(new NotNullValidationListener());
@ -130,25 +129,27 @@ public class UserRegistrationForm extends Form
SimpleContainer cookiePanel = new BoxPanel(BoxPanel.HORIZONTAL); SimpleContainer cookiePanel = new BoxPanel(BoxPanel.HORIZONTAL);
m_isPersistent = m_isPersistent =
new CheckboxGroup(FORM_PERSISTENT_LOGIN_P); new CheckboxGroup(FORM_PERSISTENT_LOGIN_P);
Label optLabel = Label optLabel =
new Label(LoginHelper.getMessage new Label(LoginHelper.getMessage(
("login.userRegistrationForm.cookieOption")); "login.userRegistrationForm.cookieOption"));
Option opt = new Option(FORM_PERSISTENT_LOGIN_P_DEFAULT, optLabel); Option opt = new Option(FORM_PERSISTENT_LOGIN_P_DEFAULT, optLabel);
m_isPersistent.addOption(opt); m_isPersistent.addOption(opt);
if (Kernel.getConfig().isLoginRemembered()) { if (Kernel.getConfig().isLoginRemembered()) {
m_isPersistent.setOptionSelected(FORM_PERSISTENT_LOGIN_P_DEFAULT); m_isPersistent.setOptionSelected(FORM_PERSISTENT_LOGIN_P_DEFAULT);
} }
cookiePanel.add(m_isPersistent); cookiePanel.add(m_isPersistent);
cookiePanel.add(new DynamicLink cookiePanel.add(new DynamicLink(
("login.userRegistrationForm.explainCookieLink", "login.userRegistrationForm.explainCookieLink",
UI.getCookiesExplainPageURL())); UI.getCookiesExplainPageURL()));
add(cookiePanel); add(cookiePanel);
add(new Submit(SUBMIT), ColumnPanel.CENTER | ColumnPanel.FULL_WIDTH); add(new Submit(SUBMIT), ColumnPanel.CENTER | ColumnPanel.FULL_WIDTH);
add(new DynamicLink("login.userRegistrationForm.forgotPasswordLink", if (securityConfig.getEnableQuestion()) {
UI.getRecoverPasswordPageURL())); add(new DynamicLink("login.userRegistrationForm.forgotPasswordLink",
UI.getRecoverPasswordPageURL()));
}
if (m_autoRegistrationOn) { if (m_autoRegistrationOn) {
add(new DynamicLink("login.userRegistrationForm.newUserRegister", add(new DynamicLink("login.userRegistrationForm.newUserRegister",
@ -156,20 +157,19 @@ public class UserRegistrationForm extends Form
} }
add(new ElementComponent("subsite:promptToEnableCookiesMsg", add(new ElementComponent("subsite:promptToEnableCookiesMsg",
SubsiteDispatcher.SUBSITE_NS_URI)); SubsiteDispatcher.SUBSITE_NS_URI));
} }
/** /**
* Sets up the login form parameters * Sets up the login form parameters
*/ */
private void setupLogin() { private void setupLogin() {
SimpleContainer loginMessage = SimpleContainer loginMessage =
new SimpleContainer("subsite:loginPromptMsg", new SimpleContainer("subsite:loginPromptMsg",
SubsiteDispatcher.SUBSITE_NS_URI); SubsiteDispatcher.SUBSITE_NS_URI);
if (KernelHelper.emailIsPrimaryIdentifier()){ if (KernelHelper.emailIsPrimaryIdentifier()) {
loginMessage.setClassAttr("email"); loginMessage.setClassAttr("email");
} else { } else {
loginMessage.setClassAttr("screenName"); loginMessage.setClassAttr("screenName");
@ -177,26 +177,26 @@ public class UserRegistrationForm extends Form
add(loginMessage); add(loginMessage);
if (KernelHelper.emailIsPrimaryIdentifier()){ if (KernelHelper.emailIsPrimaryIdentifier()) {
add(new Label(LoginHelper.getMessage add(new Label(LoginHelper.getMessage(
("login.userRegistrationForm.email"))); "login.userRegistrationForm.email")));
m_loginName = new TextField(new EmailParameter(FORM_LOGIN)); m_loginName = new TextField(new EmailParameter(FORM_LOGIN));
addInitListener(new EmailInitListener addInitListener(new EmailInitListener((EmailParameter) m_loginName.
((EmailParameter)m_loginName.getParameterModel())); getParameterModel()));
} else { } else {
add(new Label(LoginHelper.getMessage add(new Label(LoginHelper.getMessage(
("login.userRegistrationForm.screenName"))); "login.userRegistrationForm.screenName")));
m_loginName = new TextField(new StringParameter(FORM_LOGIN)); m_loginName = new TextField(new StringParameter(FORM_LOGIN));
addInitListener(new ScreenNameInitListener addInitListener(new ScreenNameInitListener((StringParameter) m_loginName.
((StringParameter)m_loginName.getParameterModel())); getParameterModel()));
} }
m_loginName.addValidationListener(new NotNullValidationListener()); m_loginName.addValidationListener(new NotNullValidationListener());
add(m_loginName); add(m_loginName);
} }
public void init(FormSectionEvent event) public void init(FormSectionEvent event)
throws FormProcessException { throws FormProcessException {
s_log.info( "In init" ); s_log.info("In init");
if (Kernel.getConfig().isSSOenabled()) { if (Kernel.getConfig().isSSOenabled()) {
// try SSO login // try SSO login
s_log.info("trying SSO"); s_log.info("trying SSO");
@ -207,42 +207,41 @@ public class UserRegistrationForm extends Form
return; return;
} catch (LoginException le) { } catch (LoginException le) {
// continue with standard form-based login // continue with standard form-based login
s_log.debug("SSO failed",le); s_log.debug("SSO failed", le);
} }
} }
try { try {
// create timestamp // create timestamp
String value = Credential String value = Credential.create(FORM_TIMESTAMP,
.create(FORM_TIMESTAMP, 1000 * TIMESTAMP_LIFETIME_SECS) 1000 * TIMESTAMP_LIFETIME_SECS).
.toString(); toString();
m_timestamp.setValue(event.getPageState(), value); m_timestamp.setValue(event.getPageState(), value);
} catch (CredentialException e) { } catch (CredentialException e) {
s_log.debug("Could not create timestamp", e); s_log.debug("Could not create timestamp", e);
throw new FormProcessException throw new FormProcessException("Could not create timestamp", e);
("Could not create timestamp", e);
} }
} }
public void validate(FormSectionEvent event) public void validate(FormSectionEvent event)
throws FormProcessException { throws FormProcessException {
s_log.debug( "In validate" ); s_log.debug("In validate");
FormData data = event.getFormData(); FormData data = event.getFormData();
PageState state = event.getPageState(); PageState state = event.getPageState();
try { try {
// check timestamp // check timestamp
try { try {
Credential.parse((String)m_timestamp.getValue(state)); Credential.parse((String) m_timestamp.getValue(state));
} catch (CredentialException e) { } catch (CredentialException e) {
s_log.info( "Invalid credential" ); s_log.info("Invalid credential");
//final String path = LegacyInitializer.getFullURL //final String path = LegacyInitializer.getFullURL
// (LegacyInitializer.EXPIRED_PAGE_KEY, state.getRequest()); // (LegacyInitializer.EXPIRED_PAGE_KEY, state.getRequest());
final String path = UI.getLoginExpiredPageURL(); final String path = UI.getLoginExpiredPageURL();
final URL url = com.arsdigita.web.URL.there final URL url = com.arsdigita.web.URL.there(state.getRequest(),
(state.getRequest(), path); path);
throw new RedirectSignal(url, false); throw new RedirectSignal(url, false);
} }
@ -259,7 +258,7 @@ public class UserRegistrationForm extends Form
} }
public void process(FormSectionEvent event) throws FormProcessException { public void process(FormSectionEvent event) throws FormProcessException {
s_log.debug( "In process" ); s_log.debug("In process");
final PageState state = event.getPageState(); final PageState state = event.getPageState();
final HttpServletRequest req = state.getRequest(); final HttpServletRequest req = state.getRequest();
@ -281,29 +280,30 @@ public class UserRegistrationForm extends Form
* @throws FormProcessException if there is an unexpected login error * @throws FormProcessException if there is an unexpected login error
**/ **/
protected void loginUser(FormSectionEvent event) protected void loginUser(FormSectionEvent event)
throws FormProcessException { throws FormProcessException {
PageState state = event.getPageState(); PageState state = event.getPageState();
try { try {
UserContext ctx = Web.getUserContext(); UserContext ctx = Web.getUserContext();
String username = null; String username = null;
if (KernelHelper.emailIsPrimaryIdentifier()) { if (KernelHelper.emailIsPrimaryIdentifier()) {
username = ((InternetAddress) m_loginName.getValue(state)) username = ((InternetAddress) m_loginName.getValue(state)).
.getAddress(); getAddress();
} else { } else {
username = (String) m_loginName.getValue(state); username = (String) m_loginName.getValue(state);
} }
char[] password = ((String)m_password.getValue(state)) char[] password = ((String) m_password.getValue(state)).trim().
.trim().toCharArray(); toCharArray();
boolean forever = getPersistentLoginValue(event.getPageState(), false); boolean forever = getPersistentLoginValue(event.getPageState(),
false);
// attempt to log in user // attempt to log in user
ctx.login(username, password, forever); ctx.login(username, password, forever);
onLoginSuccess(event); onLoginSuccess(event);
} catch (FailedLoginException e) { } catch (FailedLoginException e) {
onLoginFail(event, e); onLoginFail(event, e);
} catch (AccountNotFoundException e) { } catch (AccountNotFoundException e) {
if ( m_autoRegistrationOn) { if (m_autoRegistrationOn) {
onAccountNotFound(event, e); onAccountNotFound(event, e);
} else { } else {
onLoginFail(event, e); onLoginFail(event, e);
@ -321,10 +321,9 @@ public class UserRegistrationForm extends Form
// do nothing // do nothing
} }
protected void onBadPassword(FormSectionEvent event, protected void onBadPassword(FormSectionEvent event,
FailedLoginException e) FailedLoginException e)
throws FormProcessException { throws FormProcessException {
onLoginFail(event, e); onLoginFail(event, e);
} }
@ -334,14 +333,12 @@ public class UserRegistrationForm extends Form
* Default implementation marks password parameter with an error * Default implementation marks password parameter with an error
* message. * message.
**/ **/
protected void onLoginFail(FormSectionEvent event, protected void onLoginFail(FormSectionEvent event,
LoginException e) LoginException e)
throws FormProcessException { throws FormProcessException {
s_log.debug("Login fail"); s_log.debug("Login fail");
event.getFormData().addError event.getFormData().addError((String) ERROR_LOGIN_FAIL.localize(event.
( (String)ERROR_LOGIN_FAIL getPageState().getRequest()));
.localize(event.getPageState().getRequest()));
} }
/** /**
@ -351,7 +348,7 @@ public class UserRegistrationForm extends Form
**/ **/
protected void onAccountNotFound(FormSectionEvent event, protected void onAccountNotFound(FormSectionEvent event,
AccountNotFoundException e) AccountNotFoundException e)
throws FormProcessException { throws FormProcessException {
PageState state = event.getPageState(); PageState state = event.getPageState();
// no such user, so bring up form for new users // no such user, so bring up form for new users
@ -387,15 +384,15 @@ public class UserRegistrationForm extends Form
* is no such field in the form data, returns the specified default * is no such field in the form data, returns the specified default
* value. * value.
**/ **/
protected boolean getPersistentLoginValue protected boolean getPersistentLoginValue(PageState state,
(PageState state, boolean defaultValue) { boolean defaultValue) {
// CheckboxGroup gets you a StringArray // CheckboxGroup gets you a StringArray
String[] values = (String[])m_isPersistent.getValue(state); String[] values = (String[]) m_isPersistent.getValue(state);
if (values == null) { if (values == null) {
return defaultValue; return defaultValue;
} }
String persistentLoginValue = (String)values[0]; String persistentLoginValue = (String) values[0];
return "1".equals(persistentLoginValue); return "1".equals(persistentLoginValue);
} }
@ -413,7 +410,7 @@ public class UserRegistrationForm extends Form
m_loginName.getValue(state)); m_loginName.getValue(state));
final URL dest = com.arsdigita.web.URL.there( final URL dest = com.arsdigita.web.URL.there(
state.getRequest(), url, map); state.getRequest(), url, map);
throw new RedirectSignal(dest, true); throw new RedirectSignal(dest, true);
} }