CCM NG: Migrated more configuration classes to the new system

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@3793 8810af33-2d31-482b-a856-94f89814c4df
pull/2/head
jensp 2016-01-13 18:11:56 +00:00
parent b35e44a867
commit 361ba65ed8
34 changed files with 461 additions and 535 deletions

View File

@ -1,10 +1,10 @@
/*
* Copyright (C) 2004 Red Hat Inc. All Rights Reserved.
* Copyright (C) 2016 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -13,77 +13,109 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.formbuilder;
import com.arsdigita.runtime.AbstractConfig;
import com.arsdigita.util.parameter.BooleanParameter;
import com.arsdigita.util.parameter.Parameter;
import com.arsdigita.util.parameter.StringParameter;
import org.apache.log4j.Logger;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.configuration.Configuration;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.configuration.Setting;
import java.util.Objects;
/**
* @see com.arsdigita.bebop.Bebop
* @author Justin Ross
* @version $Id: FormBuilderConfig.java 1498 2007-03-19 16:22:15Z apevec $
*/
public final class FormBuilderConfig extends AbstractConfig {
private static final Logger s_log = Logger.getLogger(FormBuilderConfig.class);
private final Parameter m_actionsHelp;
private final Parameter m_controlsHelp;
private final BooleanParameter m_interpolateEmailActionsToAddress;
public FormBuilderConfig() {
m_actionsHelp = new StringParameter
("waf.formbuilder.actions_help_url", Parameter.REQUIRED, "");
m_controlsHelp = new StringParameter
("waf.formbuilder.controls_help_url", Parameter.REQUIRED, "");
m_interpolateEmailActionsToAddress = new BooleanParameter
("waf.formbuilder.interpolate_email_actions_to_address",
Parameter.OPTIONAL, Boolean.FALSE);
register(m_actionsHelp);
register(m_controlsHelp);
register(m_interpolateEmailActionsToAddress);
loadInfo();
}
/**
* This returns the string that can be used to create the URL to
* point to the help page. If it starts with "/" then it is
* assumed to be located on this server. If it starts with
* anything else, it is assumed to be a link to a foreign site.
* This can be null if no help link should appear.
*
* NOTE: As of version 6.6 and earlier the help function is not working.
* Returns null to deactivate the help link.
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public String getActionsHelpLink() {
// return (String) get(m_actionsHelp);
return null;
@Configuration(
descBundle = "com.arsdigita.formbuilder.FormBuilderConfigDescription",
descKey = "formbuilder.config.description")
public final class FormBuilderConfig {
@Setting(descKey = "formbuilder.config.actions_help_url")
private String actionsHelpUrl;
@Setting(descKey = "formbuilder.config.controls_help_url")
private String controlsHelpUrl;
@Setting(descKey = "formbuilder.config.interpolate_email_actions")
private Boolean interpolateEmailActions;
public static FormBuilderConfig getConfig() {
final CdiUtil cdiUtil = new CdiUtil();
final ConfigurationManager confManager = cdiUtil.findBean(
ConfigurationManager.class);
return confManager.findConfiguration(FormBuilderConfig.class);
}
/**
* This returns the string that can be used to create the URL to
* point to the help page.
* This can be null is no help link should appear
*
* NOTE: See deactivated help system above.
*/
public String getControlsHelpLink() {
// return (String)get(m_controlsHelp);
return null;
public String getActionsHelpUrl() {
return actionsHelpUrl;
}
public boolean getInterpolateEmailActionsToAddress() {
return get(m_interpolateEmailActionsToAddress).equals(Boolean.TRUE);
public void setActionsHelpUrl(final String actionsHelpUrl) {
this.actionsHelpUrl = actionsHelpUrl;
}
public String getControlsHelpUrl() {
return controlsHelpUrl;
}
public void setControlsHelpUrl(final String controlsHelpUrl) {
this.controlsHelpUrl = controlsHelpUrl;
}
public Boolean getInterpolateEmailActions() {
return interpolateEmailActions;
}
public void setInterpolateEmailActions(final Boolean interpolateEmailActions) {
this.interpolateEmailActions = interpolateEmailActions;
}
@Override
public int hashCode() {
int hash = 5;
hash = 71 * hash + Objects.hashCode(actionsHelpUrl);
hash = 71 * hash + Objects.hashCode(controlsHelpUrl);
hash = 71 * hash + Objects.hashCode(interpolateEmailActions);
return hash;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof FormBuilderConfig)) {
return false;
}
final FormBuilderConfig other = (FormBuilderConfig) obj;
if (!Objects.equals(actionsHelpUrl, other.getActionsHelpUrl())) {
return false;
}
if (!Objects.equals(controlsHelpUrl, other.getControlsHelpUrl())) {
return false;
}
return Objects.equals(interpolateEmailActions,
other.getInterpolateEmailActions());
}
@Override
public String toString() {
return String.format("%s{ "
+ "actionsHelpUrl = \"%s\", "
+ "controlsHelpUrl = \"%s\", "
+ "interpolateEmailActions = %b"
+ " }",
super.toString(),
actionsHelpUrl,
controlsHelpUrl,
interpolateEmailActions);
}
}

View File

@ -1,10 +1,10 @@
/*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
* Copyright (C) 2016 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -13,227 +13,171 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.kernel.security;
import com.arsdigita.runtime.AbstractConfig;
import com.arsdigita.util.parameter.BooleanParameter;
import com.arsdigita.util.parameter.IntegerParameter;
import com.arsdigita.util.parameter.Parameter;
import com.arsdigita.util.parameter.SpecificClassParameter;
import com.arsdigita.util.parameter.StringArrayParameter;
import com.arsdigita.util.parameter.StringParameter;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.configuration.Configuration;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.configuration.Setting;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.StringJoiner;
/**
* A record containing server-session scoped security configuration properties.
*
* Accessors of this class may return null. Developers should take care to trap
* null return values in their code.
*
*
* @author Rafael H. Schloming &lt;rhs@mit.edu&gt;
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class SecurityConfig extends AbstractConfig {
@Configuration(
descBundle = "com.arsdigita.kernel.security.SecurityConfigDescription",
descKey = "security.config.description")
public final class SecurityConfig {
private static SecurityConfig s_config = null;
private static String s_systemAdministratorEmailAddress = null;
/**
* Size of secret key in bytes. *
*/
@SuppressWarnings("PublicField")
public static int SECRET_KEY_BYTES = 16;
/**
* The class name of the SecurityHelper implementation. Must implement
* SecurityHelper interface
*/
private final Parameter m_securityHelperClass = new SpecificClassParameter(
"waf.security_helper_class", Parameter.REQUIRED,
com.arsdigita.kernel.security.DefaultSecurityHelper.class,
com.arsdigita.kernel.security.SecurityHelper.class);
/**
* List of extensions excluded from authentication cookies. Authentication
* is checked for all requests, but requests with one of these extensions
* will never cause a new cookie to be set. Include a leading dot for each
* extension.
*/
private final Parameter m_excludedExtensions = new StringArrayParameter(
"waf.excluded_extensions", Parameter.REQUIRED,
@Setting(descKey = "security.confg.excluded_extensions")
private List<String> excludedExtensions = Arrays.asList(
new String[]{".jpg", ".gif", ".png", ".pdf"});
private final Parameter m_cookieDurationMinutes = new IntegerParameter(
"waf.pagemap.cookies_duration_minutes", Parameter.OPTIONAL, null);
@Setting(descKey = "security.config.auto_registration_enabled")
private Boolean autoRegistrationEnabled = false;
private final Parameter m_cookieDomain = new StringParameter(
"waf.cookie_domain", Parameter.OPTIONAL, null);
@Setting(descKey = "security.config.password_recovery_enabled")
private Boolean passwordRecoveryEnabled = true;
private final Parameter m_adminEmail = new StringParameter(
"waf.admin.contact_email", Parameter.OPTIONAL, null);
@Setting(descKey = "security.config.hash_algorithm")
private String hashAlgorithm = "SHA-512";
private final Parameter m_autoRegistrationOn = new BooleanParameter(
"waf.auto_registration_on", Parameter.REQUIRED, Boolean.TRUE);
@Setting(descKey = "security.config.salt_length")
private Integer saltLength = 256;
private final Parameter m_userBanOn = new BooleanParameter(
"waf.user_ban_on",
Parameter.REQUIRED,
Boolean.FALSE);
@Setting(descKey = "security.config.hash_iterations")
private Integer hashIterations = 50000;
private final Parameter m_enableQuestion = new BooleanParameter(
"waf.user_question.enable", Parameter.REQUIRED, Boolean.FALSE);
/**
* The default hash algorithm used for new passwords. Default is SHA-512
* which should sufficient for good security.
*/
private final Parameter m_hashAlgorithm = new StringParameter(
"waf.security.hash_algorithm", Parameter.REQUIRED, "SHA-512");
/**
* Default length of the salt for new passwords.
*/
private final Parameter m_saltLength = new IntegerParameter(
"waf.security.salt_length", Parameter.REQUIRED, 256);
/**
* Default number of hash iterations for new passwords.
*/
private final Parameter m_hashIterations = new IntegerParameter(
"waf.security.hash_iterations", Parameter.REQUIRED, 50000);
/**
* Constructs an empty SecurityConfig object
*/
public SecurityConfig() {
register(m_securityHelperClass);
register(m_excludedExtensions);
register(m_cookieDomain);
register(m_cookieDurationMinutes);
register(m_adminEmail);
register(m_autoRegistrationOn);
register(m_userBanOn);
register(m_enableQuestion);
register(m_hashAlgorithm);
register(m_saltLength);
register(m_hashIterations);
loadInfo();
public static SecurityConfig getConfig() {
final CdiUtil cdiUtil = new CdiUtil();
final ConfigurationManager confManager = cdiUtil.findBean(
ConfigurationManager.class);
return confManager.findConfiguration(SecurityConfig.class);
}
/**
* Returns the singleton configuration record for the runtime environment.
*
* @return The <code>RuntimeConfig</code> record; it cannot be null
*/
public static final synchronized SecurityConfig getConfig() {
if (s_config == null) {
s_config = new SecurityConfig();
s_config.load();
public List<String> getExcludedExtensions() {
return new ArrayList<>(excludedExtensions);
}
return s_config;
public void setExcludedExtensions(final List<String> excludedExtensions) {
this.excludedExtensions = excludedExtensions;
}
/**
*
* @return
*/
public final Class getSecurityHelperClass() {
return (Class) get(m_securityHelperClass);
public Boolean isAutoRegistrationEnabled() {
return autoRegistrationEnabled;
}
// /**
// * Obsolete!
// * @return
// */
// public final String getSessionTrackingMethod() {
// return (String) get(m_sessionTrackingMethod);
// }
/**
*
* @return
*/
public final List<String> getExcludedExtensions() {
return Arrays.asList((String[]) get(m_excludedExtensions));
public void setAutoRegistrationEnabled(
final Boolean autoRegistrationEnabled) {
this.autoRegistrationEnabled = autoRegistrationEnabled;
}
public String getCookieDomain() {
return (String) get(m_cookieDomain);
public boolean isPasswordRecoveryEnabled() {
return passwordRecoveryEnabled;
}
Integer getCookieDurationMinutes() {
return (Integer) get(m_cookieDurationMinutes);
}
boolean isUserBanOn() {
return ((Boolean) get(m_userBanOn)).booleanValue();
}
public String getAdminContactEmail() {
String email = (String) get(m_adminEmail);
// Return empty string instead of looking up into the database. If no
// email if configured for the admin we consider that as a configuration
// issue.
if (email == null || email.isEmpty()) {
return "";
} else {
return email;
}
// if (email == null || email.trim().length() == 0) {
// email = getSystemAdministratorEmailAddress();
// }
// return email;
}
public Boolean getEnableQuestion() {
return (Boolean) get(m_enableQuestion);
}
// private static synchronized String getSystemAdministratorEmailAddress() {
// if (s_systemAdministratorEmailAddress == null) {
// ObjectPermissionCollection perms = PermissionService.
// getGrantedUniversalPermissions();
// perms.addEqualsFilter("granteeIsUser", Boolean.TRUE);
// perms.clearOrder();
// perms.addOrder("granteeID");
// if (perms.next()) {
// s_systemAdministratorEmailAddress = perms.getGranteeEmail().
// toString();
// perms.close();
// } else {
// // Haven't found anything. We don't want to repeat this query
// // over and over again.
// s_systemAdministratorEmailAddress = "";
// }
// }
// return s_systemAdministratorEmailAddress;
// }
public final boolean isAutoRegistrationOn() {
return ((Boolean) get(m_autoRegistrationOn)).booleanValue();
public void setPasswordRecoveryEnabled(
final boolean passwordRecoveryEnabled) {
this.passwordRecoveryEnabled = passwordRecoveryEnabled;
}
public String getHashAlgorithm() {
return (String) get(m_hashAlgorithm);
return hashAlgorithm;
}
public void setHashAlgorithm(final String hashAlgorithm) {
this.hashAlgorithm = hashAlgorithm;
}
public Integer getSaltLength() {
return (Integer) get(m_saltLength);
return saltLength;
}
public void setSaltLength(Integer saltLength) {
this.saltLength = saltLength;
}
public Integer getHashIterations() {
return (Integer) get(m_hashIterations);
return hashIterations;
}
public void setHashIterations(final Integer hashIterations) {
this.hashIterations = hashIterations;
}
@Override
public int hashCode() {
int hash = 7;
hash = 97 * hash + Objects.hashCode(excludedExtensions);
hash = 97 * hash + Objects.hashCode(autoRegistrationEnabled);
hash = 97 * hash + Objects.hashCode(passwordRecoveryEnabled);
hash = 97 * hash + Objects.hashCode(hashAlgorithm);
hash = 97 * hash + Objects.hashCode(saltLength);
hash = 97 * hash + Objects.hashCode(hashIterations);
return hash;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof SecurityConfig)) {
return false;
}
final SecurityConfig other = (SecurityConfig) obj;
if (!Objects.equals(hashAlgorithm, other.getHashAlgorithm())) {
return false;
}
if (!Objects.equals(excludedExtensions, other.getExcludedExtensions())) {
return false;
}
if (!Objects.equals(autoRegistrationEnabled,
other.isAutoRegistrationEnabled())) {
return false;
}
if (!(Objects.equals(passwordRecoveryEnabled,
other.isPasswordRecoveryEnabled()))) {
return false;
}
if (!Objects.equals(saltLength, other.getSaltLength())) {
return false;
}
return Objects.equals(hashIterations, other.getHashIterations());
}
@Override
public String toString() {
final StringJoiner joiner = new StringJoiner(", ");
excludedExtensions.forEach(s -> joiner.add(s));
return String.format("%s{ "
+ "excludedExtensions = { %s }, "
+ "autoRegistrationEnabled = %b, "
+ "passwordRecoveryEnabled = %b, "
+ "hashAlgorithm = \"%s\", "
+ "saltLength = %d, "
+ "hashIterations = %d"
+ " }",
super.toString(),
joiner.toString(),
autoRegistrationEnabled,
passwordRecoveryEnabled,
hashAlgorithm,
saltLength,
hashIterations);
}
}

View File

@ -23,9 +23,6 @@ import com.arsdigita.util.Classes;
import java.util.Iterator;
import java.util.List;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import javax.servlet.http.HttpServletRequest;
/**
*
@ -33,7 +30,7 @@ import javax.servlet.http.HttpServletRequest;
*/
public class Util {
private static SecurityConfig s_conf = SecurityConfig.getConfig();
private static final SecurityConfig s_conf = SecurityConfig.getConfig();
private static SecurityHelper s_helper = null;

View File

@ -122,7 +122,7 @@ class UserForm extends Form implements FormValidationListener, AdminConstants {
= new TextField(new StringParameter(USER_FORM_INPUT_QUESTION));
m_question.setSize(50);
if (securityConfig.getEnableQuestion()) {
if (securityConfig.isPasswordRecoveryEnabled()) {
add(USER_FORM_LABEL_QUESTION);
add(m_question);
}
@ -131,7 +131,7 @@ class UserForm extends Form implements FormValidationListener, AdminConstants {
m_answer = new TextField(new StringParameter(USER_FORM_INPUT_ANSWER));
m_answer.setSize(50);
if (securityConfig.getEnableQuestion()) {
if (securityConfig.isPasswordRecoveryEnabled()) {
add(USER_FORM_LABEL_ANSWER);
add(m_answer);
}
@ -211,7 +211,7 @@ class UserForm extends Form implements FormValidationListener, AdminConstants {
}
}
if (securityConfig.getEnableQuestion()) {
if (securityConfig.isPasswordRecoveryEnabled()) {
// If the password answer is anything but null, make sure it
// contains some non-whitespace characters
String answer = (String) m_answer.getValue(ps);
@ -285,14 +285,14 @@ class UserForm extends Form implements FormValidationListener, AdminConstants {
USER_FORM_LABEL_PASSWORD.setVisible(state, isVisible);
USER_FORM_LABEL_PASSWORD_CONFIRMATION.setVisible(state, isVisible);
if (securityConfig.getEnableQuestion()) {
if (securityConfig.isPasswordRecoveryEnabled()) {
USER_FORM_LABEL_QUESTION.setVisible(state, isVisible);
USER_FORM_LABEL_ANSWER.setVisible(state, isVisible);
}
m_password.setVisible(state, isVisible);
m_confirmPassword.setVisible(state, isVisible);
if (securityConfig.getEnableQuestion()) {
if (securityConfig.isPasswordRecoveryEnabled()) {
m_question.setVisible(state, isVisible);
m_answer.setVisible(state, isVisible);
}

View File

@ -48,12 +48,12 @@ import static com.arsdigita.ui.login.LoginConstants.*;
* the Login application UI.
*
* It manages user registration page, new user page, user workspace, logout, and
permissions admin pages.
It just defines a mapping URL_MSG <-> various pages and uses the super class to
actually server the pages. Additionally is provides service methods to expose
various properties, especially the URL_MSG's of public subpages (e.g. logout) and
initializes the creation of the UI.
* permissions admin pages.
*
* It just defines a mapping URL_MSG <-> various pages and uses the super class
* to actually server the pages. Additionally is provides service methods to
* expose various properties, especially the URL_MSG's of public subpages (e.g.
* logout) and initializes the creation of the UI.
*
* @author Peter Boy <pboy@barkhof.uni-bremen.de>
*/
@ -116,8 +116,8 @@ public class LoginServlet extends BebopApplicationServlet {
public static final String LOGOUT_PATH_INFO = "/logout/";
/**
* Base URL_MSG of the Login application for internal use, fetched from Login
domain class.
* Base URL_MSG of the Login application for internal use, fetched from
* Login domain class.
*/
private final static String s_loginURL = LOGIN_PAGE_URL;
@ -127,8 +127,8 @@ public class LoginServlet extends BebopApplicationServlet {
public static final String APPLICATION_NAME = "login";
/**
* User extension point used to create the pages to server and setup a URL_MSG -
page mapping.
* User extension point used to create the pages to server and setup a
* URL_MSG - page mapping.
*
* @throws ServletException
*/
@ -144,9 +144,10 @@ public class LoginServlet extends BebopApplicationServlet {
* page map. KernelSecurityConfig determines whether to create a link
* to a NewUserRegistrationForm or to skip.*/
put("/",
buildSimplePage("login.userRegistrationForm.title",
buildSimplePage(
"login.userRegistrationForm.title",
new UserLoginForm(SecurityConfig.getConfig()
.isAutoRegistrationOn()),
.isAutoRegistrationEnabled()),
"login"));
disableClientCaching("/");
@ -158,7 +159,7 @@ public class LoginServlet extends BebopApplicationServlet {
/* Determines if a NewUserRegistrationForm has to be created by quering
* Kernel.getSecurityConfig() and acts appropriately */
if (SecurityConfig.getConfig().isAutoRegistrationOn()) {
if (SecurityConfig.getConfig().isAutoRegistrationEnabled()) {
put(NEW_USER_PATH_INFO,
buildSimplePage("login.userNewForm.title",
new UserNewForm(),
@ -189,7 +190,6 @@ public class LoginServlet extends BebopApplicationServlet {
// buildSimplePage("login.recoverPasswordPage.title",
// new RecoverPasswordPanel(),
// "recoverpassword"));
// Build the login expire page, retrieve its URL_MSG and store in map
put(LOGIN_EXPIRED_PATH_INFO, buildExpiredPage());
@ -319,15 +319,16 @@ public class LoginServlet extends BebopApplicationServlet {
}
/**
* Provides an (absolute) URL_MSG to a user profile editig page. It is relative
to document root without any constant prefix if there is one configured.
XXX This implementation starts with a leading slash and ends with a
slash. In previous configurations String urls began without a slash in
order to be able to provide a full URL_MSG which also contains the context
part. Since version 5.2 the context part is handled by (new) dispatcher.
The leading slash it API change! It's impacts have to be checked.
(2011-02)
* Provides an (absolute) URL_MSG to a user profile editig page. It is
* relative to document root without any constant prefix if there is one
* configured.
*
* XXX This implementation starts with a leading slash and ends with a
* slash. In previous configurations String urls began without a slash in
* order to be able to provide a full URL_MSG which also contains the
* context part. Since version 5.2 the context part is handled by (new)
* dispatcher. The leading slash it API change! It's impacts have to be
* checked. (2011-02)
*
* @return url to EditUserProfile page as String
*/
@ -341,15 +342,15 @@ public class LoginServlet extends BebopApplicationServlet {
/**
* Provides an (absolute URL_MSG) to an optional new user registration page
(accessible only if activated). It is relative to document root without
any constant prefix if there is one configured.
XXX This implementation starts with a leading slash and ends with a
slash. In previous configurations String urls began without a slash in
order to be able to provide a full URL_MSG which also contains the context
part. Since version 5.2 the context part is handled by (new) dispatcher.
The leading slash it API change! It's impacts have to be checked.
(2011-02)
* (accessible only if activated). It is relative to document root without
* any constant prefix if there is one configured.
*
* XXX This implementation starts with a leading slash and ends with a
* slash. In previous configurations String urls began without a slash in
* order to be able to provide a full URL_MSG which also contains the
* context part. Since version 5.2 the context part is handled by (new)
* dispatcher. The leading slash it API change! It's impacts have to be
* checked. (2011-02)
*
* @return url to new user registration page as String
*/
@ -358,16 +359,16 @@ public class LoginServlet extends BebopApplicationServlet {
}
/**
* Provides an absolute URL_MSG (leading slash) for a password recovery page. It
is relative to document root without any constant prefix if there is one
configured.
XXX This implementation starts with a leading slash and ends with a
slash. In previous configurations String urls began without a slash in
order to be able to provide a full URL_MSG which also contains the context
part. Since version 5.2 the context part is handled by (new) dispatcher.
The leading slash it API change! It's impacts have tp be checked.
(2011-02)
* Provides an absolute URL_MSG (leading slash) for a password recovery
* page. It is relative to document root without any constant prefix if
* there is one configured.
*
* XXX This implementation starts with a leading slash and ends with a
* slash. In previous configurations String urls began without a slash in
* order to be able to provide a full URL_MSG which also contains the
* context part. Since version 5.2 the context part is handled by (new)
* dispatcher. The leading slash it API change! It's impacts have tp be
* checked. (2011-02)
*
* @return url String for new user registration page as String
*/
@ -376,16 +377,16 @@ public class LoginServlet extends BebopApplicationServlet {
}
/**
* Provides an absolute URL_MSG (leading slash) for a cookie explanation page.
* It is relative to document root without any constant prefix if there is
one configured.
XXX This implementation starts with a leading slash and ends with a
slash. In previous configurations String urls began without a slash in
order to be able to provide a full URL_MSG which also contains the context
part. Since version 5.2 the context part is handled by (new) dispatcher.
The leading slash it API change! It's impacts have tp be checked.
(2011-02)
* Provides an absolute URL_MSG (leading slash) for a cookie explanation
* page. It is relative to document root without any constant prefix if
* there is one configured.
*
* XXX This implementation starts with a leading slash and ends with a
* slash. In previous configurations String urls began without a slash in
* order to be able to provide a full URL_MSG which also contains the
* context part. Since version 5.2 the context part is handled by (new)
* dispatcher. The leading slash it API change! It's impacts have tp be
* checked. (2011-02)
*
* @return url String for new user registration page as String
*/
@ -394,16 +395,16 @@ public class LoginServlet extends BebopApplicationServlet {
}
/**
* Provides an absolute URL_MSG (leading slash) for a login expired info page.
* It is relative to document root without any constant prefix if there is
one configured.
XXX This implementation starts with a leading slash and ends with a
slash. In previous configurations String urls began without a slash in
order to be able to provide a full URL_MSG which also contains the context
part. Since version 5.2 the context part is handled by (new) dispatcher.
The leading slash it API change! It's impacts have tp be checked.
(2011-02)
* Provides an absolute URL_MSG (leading slash) for a login expired info
* page. It is relative to document root without any constant prefix if
* there is one configured.
*
* XXX This implementation starts with a leading slash and ends with a
* slash. In previous configurations String urls began without a slash in
* order to be able to provide a full URL_MSG which also contains the
* context part. Since version 5.2 the context part is handled by (new)
* dispatcher. The leading slash it API change! It's impacts have tp be
* checked. (2011-02)
*
* @return url String for new user registration page as String
*/
@ -412,16 +413,16 @@ public class LoginServlet extends BebopApplicationServlet {
}
/**
* Provides an absolute URL_MSG (leading slash) for the system logout page. It
is relative to document root without any constant prefix if there is one
configured.
XXX This implementation starts with a leading slash and ends with a
slash. In previous configurations String urls began without a slash in
order to be able to provide a full URL_MSG which also contains the context
part. Since version 5.2 the context part is handled by (new) dispatcher.
The leading slash it API change! It's impacts have tp be checked.
(2011-02)
* Provides an absolute URL_MSG (leading slash) for the system logout page.
* It is relative to document root without any constant prefix if there is
* one configured.
*
* XXX This implementation starts with a leading slash and ends with a
* slash. In previous configurations String urls began without a slash in
* order to be able to provide a full URL_MSG which also contains the
* context part. Since version 5.2 the context part is handled by (new)
* dispatcher. The leading slash it API change! It's impacts have tp be
* checked. (2011-02)
*
* @return URL_MSG for logout page as String
*/

View File

@ -61,7 +61,6 @@ import org.apache.shiro.authc.UsernamePasswordToken;
import org.libreccm.cdi.utils.CdiUtil;
import org.apache.shiro.subject.Subject;
import org.libreccm.configuration.ConfigurationManager;
/**
* A Bebop form that accepts login and password from the user and attempts to
@ -173,7 +172,7 @@ public class UserLoginForm extends Form implements LoginConstants,
add(new Submit(SUBMIT), ColumnPanel.CENTER | ColumnPanel.FULL_WIDTH);
if (securityConfig.getEnableQuestion()) {
if (securityConfig.isPasswordRecoveryEnabled()) {
add(new DynamicLink("login.userRegistrationForm.forgotPasswordLink",
LoginServlet.getRecoverPasswordPageURL()));
}

View File

@ -36,8 +36,7 @@ public class DateFormatter implements Formatter {
public static final DateFormatterConfig getConfig() {
if (m_config == null) {
m_config = new DateFormatterConfig();
m_config.load();
m_config = DateFormatterConfig.getConfig();
}
return m_config;
}

View File

@ -1,21 +1,86 @@
/*
* Copyright (C) 2016 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.xml.formatters;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.configuration.Configuration;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.configuration.Setting;
import com.arsdigita.runtime.AbstractConfig;
import com.arsdigita.util.parameter.Parameter;
import com.arsdigita.util.parameter.StringParameter;
import java.util.Objects;
public final class DateFormatterConfig extends AbstractConfig {
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Configuration(
descBundle = "com.arsdigita.xml.formatters.DataFormatterDescription",
descKey = "dataformatter.config.description")
public final class DateFormatterConfig {
private final Parameter m_locale;
@Setting(descKey = "dateformatter.config.locale")
private String locale = null;
public DateFormatterConfig() {
m_locale = new StringParameter("waf.xml.formatters.locale", Parameter.OPTIONAL, null);
register(m_locale);
loadInfo();
public static DateFormatterConfig getConfig() {
final CdiUtil cdiUtil = new CdiUtil();
final ConfigurationManager confManager = cdiUtil.findBean(
ConfigurationManager.class);
return confManager.findConfiguration(DateFormatterConfig.class);
}
public final String getLocale() {
return (String) get (m_locale);
public String getLocale() {
return locale;
}
public void setLocale(final String locale) {
this.locale = locale;
}
@Override
public int hashCode() {
int hash = 5;
hash = 13 * hash + Objects.hashCode(this.locale);
return hash;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof DateFormatterConfig)) {
return false;
}
final DateFormatterConfig other = (DateFormatterConfig) obj;
return Objects.equals(this.locale, other.getLocale());
}
@Override
public String toString() {
return String.format("%s{ "
+ "locale = %s"
+ " }",
super.toString(),
locale);
}
}

View File

@ -1,4 +0,0 @@
waf.xml.formatters.locale.title=Locale language code (see http://ftp.ics.uci.edu/pub/ietf/http/related/iso639.txt)
waf.xml.formatters.locale.purpose=If set will use this rather than the contexts locale. Useful for things that may be formatted differently in other locales, eg dates.
waf.xml.formatters.locale.example=en
waf.xml.formatters.locale.format=[string]

View File

@ -19,11 +19,13 @@
package org.libreccm.security;
import com.arsdigita.kernel.security.SecurityConfig;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.executable.ValidateOnExecution;
import org.apache.shiro.authc.credential.PasswordMatcher;
import org.apache.shiro.authc.credential.PasswordService;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
@ -127,7 +129,7 @@ public class UserManager {
* @return The hashed password.b
*/
private String hashPassword(final String password) {
//Get the values from the SecurityConfig
//Get the values from the LegacySecurityConfig
final String hashAlgo = SecurityConfig.getConfig().getHashAlgorithm();
final int iterations = SecurityConfig.getConfig().getHashIterations();
@ -149,7 +151,7 @@ public class UserManager {
/**
* Helper method for generating a random salt. The length of the generated
* salt is configured in the {@link SecurityConfig}.
* salt is configured in the {@link LegacySecurityConfig}.
*
* @return A new random salt.
*/

View File

@ -1,12 +0,0 @@
waf.formbuilder.controls_help_url.title=Help link for creating FormBuilder controls
waf.formbuilder.controls_help_url.purpose=This is a string that can be used to create the URL to point to the help page that explains how to create controls within the formbuilder. If it starts with "/" then it is assumed to be located on this server. If it starts with anything else, it is assumed to be a link to a foreign site.
waf.formbuilder.controls_help_url.example=/help/formbuilder/creations-controls.jsp
waf.formbuilder.controls_help_url.format=[string]
waf.formbuilder.actions_help_url.title=Help link for creating FormBuilder actions
waf.formbuilder.actions_help_url.purpose=This is a string that can be used to create the URL to point to the help page that explains how to create actions within the formbuilder. If it starts with "/" then it is assumed to be located on this server. If it starts with anything else, it is assumed to be a link to a foreign site.
waf.formbuilder.actions_help_url.example=/help/formbuilder/creations-actions.jsp
waf.formbuilder.actions_help_url.format=[string]
waf.formbuilder.interpolate_email_actions_to_address.title=Interpolate the to: field
waf.formbuilder.interpolate_email_actions_to_address.purpose=Should the to: field of email actions be interpolated, ie translated using submitted form values
waf.formbuilder.interpolate_email_actions_to_address.example=boolean
waf.formbuilder.interpolate_email_actions_to_address.format=[true]

View File

@ -0,0 +1,22 @@
# Copyright (C) 2016 LibreCCM Foundation.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA
formbuilder.config.description = Configuration parameters for the FormBuilder
formbuilder.config.actions_help_url = This is a string that can be used to create the URL to point to the help page that explains how to create actions within the formbuilder. If it starts with "/" then it is assumed to be located on this server. If it starts with anything else, it is assumed to be a link to a foreign site.
formbuilder.config.controls_help_url = This is a string that can be used to create the URL to point to the help page that explains how to create controls within the formbuilder. If it starts with "/" then it is assumed to be located on this server. If it starts with anything else, it is assumed to be a link to a foreign site.
formbuilder.config.interpolate_email_actions = Should the to: field of email actions be interpolated, ie translated using submitted form values

View File

@ -0,0 +1,25 @@
# Copyright (C) 2016 LibreCCM Foundation.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA
security.config.description = A record containing server-session scoped security configuration properties.
security.confg.excluded_extensions = List of extensions excluded from authentication cookies.
security.config.auto_registration_enabled = Wether new users get automatically redirected to the create new user form
security.config.password_recovery_enabled = Enables or disables the password recovery function for users.
security.config.hash_algorithm = Sets the Hash Algorithm to use for new passwords. The available algorithms depend on the Java Runtime.
security.config.salt_length = Sets the length of the salt for new passwords
security.config.hash_iterations = Number of iterations when hashing new passwords

View File

@ -1,44 +0,0 @@
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.example=Request:com.arsdigita.kernel.security.AdminLoginModule:sufficient,Register:com.arsdigita.kernel.security.LocalLoginModule:requisite
waf.login_config.format=[string,string,...]
waf.cookie_domain.title=Cookie Domain
waf.cookie_domain.purpose=Enter the domain to which the Aplaws authentication cookie is presented
waf.cookie_domain.example=.example.com
waf.cookie_domain.format=[string]
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.example=ccmadmin@example.com
waf.admin.contact_email.format=[string]
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.example=true
waf.auto_registration_on.format=true|false
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.example=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
waf.security.hash_algorithm.title=Default Hash Algorithm for new passwords
waf.security.hash_algorithm.purpose=Sets the Hash Algorithm to use for new passwords. The available algorithms depend on the Java Runtime.
waf.security.hash_algorithm.example=SHA-512
waf.security.hash_algorithm.format=[string]
waf.security.salt_length.title=Default Salt Length for new passwords
waf.security.salt_length.purpose=Sets the length of the salt for new passwords
waf.security.salt_length.example=256
waf.security.salt_length.format=[int]
waf.security.hash_iterations.title=Number of hash iterations for new passwords
waf.security.hash_iterations.purpose=Number of iterations when hashing new passwords
waf.security.hash_iterations.example=50000
waf.security.hash_iterations.format=[int]

View File

@ -0,0 +1,19 @@
# Copyright (C) 2016 LibreCCM Foundation.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA
dateformatter.config.description = Configuration for date formatters
dateformatter.config.locale = If set will use this rather than the contexts locale. Useful for things that may be formatted differently in other locales, eg dates.

View File

@ -1,4 +0,0 @@
waf.xml.formatters.locale.title=Locale language code (see http://ftp.ics.uci.edu/pub/ietf/http/related/iso639.txt)
waf.xml.formatters.locale.purpose=If set will use this rather than the contexts locale. Useful for things that may be formatted differently in other locales, eg dates.
waf.xml.formatters.locale.example=en
waf.xml.formatters.locale.format=[string]

View File

@ -156,23 +156,15 @@ public class SecurityConfigTest {
assertThat(excludedExtensions.get(2), is(equalTo(".png")));
assertThat(excludedExtensions.get(3), is(equalTo(".pdf")));
assertThat(securityConfig.getCookieDurationMinutes(), is(nullValue()));
assertThat(securityConfig.isAutoRegistrationEnabled(), is(false));
assertThat(securityConfig.getCookieDomain(),
is(equalTo(".example.org")));
assertThat(securityConfig.isPasswordRecoveryEnabled(), is(true));
assertThat(securityConfig.getAdminContactEmail(),
is(equalTo("admin@example.org")));
assertThat(securityConfig.getHashAlgorithm(), is(equalTo("SHA-512")));
assertThat(securityConfig.isAutoRegistrationOn(), is(false));
assertThat(securityConfig.getSaltLength(), is(256));
assertThat(securityConfig.isUserBanOn(), is(true));
assertThat(securityConfig.getEnableQuestion(), is(false));
assertThat(securityConfig.getHashAlgorithm(), is(equalTo("SHA-256")));
assertThat(securityConfig.getSaltLength(), is(128));
assertThat(securityConfig.getHashIterations(), is(50000));
}
}

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<registry>
<config class="com.arsdigita.kernel.KernelConfig"
storage="ccm-core/kernel.properties"/>
</registry>

View File

@ -1,5 +0,0 @@
waf.kernel.supported_languages=de,en
waf.debug=true
waf.kernel.language_independent_items=true
waf.kernel.primary_user_identifier=email
waf.kernel.data_permission_check_enabled=false

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<registry>
<config class="com.arsdigita.kernel.KernelConfig"
storage="ccm-core/kernel.properties"/>
<config class="com.arsdigita.kernel.security.SecurityConfig"
storage="ccm-core/security.properties"/>
</registry>

View File

@ -1,15 +0,0 @@
waf.login_config=Register:com.arsdigita.kernel.security.LocalLoginModule:requisite
waf.cookie_domain=.example.org
waf.admin.contact_email=admin@example.org
waf.auto_registration_on=false
waf.user_ban_on=true
waf.user_question_enable=false
waf.security.hash_algorithm=SHA-256
waf.security.salt_length=128

View File

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
<Logger name="org.libreccm.configuration.ConfigurationManager"
level="debug">
<AppenderRef ref="Console"/>
</Logger>
<Logger name="org.libreccm.categorization.CategoryRepository"
level="debug">
<AppenderRef ref="Console"/>
</Logger>
</Loggers>
</Configuration>

View File

@ -1 +0,0 @@
waf.kernel.primary_user_identifier=screen_name

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
<Logger name="org.libreccm.security.Shiro"
level="debug">
<AppenderRef ref="Console"/>
</Logger>
</Loggers>
</Configuration>

View File

@ -1,10 +0,0 @@
[main]
passwordMatcher = org.apache.shiro.authc.credential.PasswordMatcher
passwordService = org.apache.shiro.authc.credential.DefaultPasswordService
passwordMatcher.passwordService = $passwordService
ccmRealm = org.libreccm.security.CcmShiroRealm
ccmRealm.credentialsMatcher = $passwordMatcher
securityManager.realms = $ccmRealm

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<registry>
<config class="com.arsdigita.kernel.KernelConfig"
storage="ccm-core/kernel.properties"/>
<config class="com.arsdigita.kernel.security.SecurityConfig"
storage="ccm-core/security.properties"/>
</registry>

View File

@ -1 +0,0 @@
# this file is empty by purpose.

View File

@ -1,10 +0,0 @@
[main]
passwordMatcher = org.apache.shiro.authc.credential.PasswordMatcher
passwordService = org.apache.shiro.authc.credential.DefaultPasswordService
passwordMatcher.passwordService = $passwordService
ccmRealm = org.libreccm.security.CcmShiroRealm
ccmRealm.credentialsMatcher = $passwordMatcher
securityManager.realms = $ccmRealm