123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- /*
- * Password Management Servlets (PWM)
- * http://www.pwm-project.org
- *
- * Copyright (c) 2006-2009 Novell, Inc.
- * Copyright (c) 2009-2017 The PWM Project
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
- package password.pwm.config;
- import password.pwm.AppProperty;
- import password.pwm.PwmConstants;
- import password.pwm.error.ErrorInformation;
- import password.pwm.error.PwmDataValidationException;
- import password.pwm.error.PwmError;
- import password.pwm.error.PwmOperationalException;
- import password.pwm.error.PwmUnrecoverableException;
- import password.pwm.i18n.Display;
- import password.pwm.util.LocaleHelper;
- import password.pwm.util.java.JsonUtil;
- import password.pwm.util.java.StringUtil;
- import java.io.Serializable;
- import java.math.BigInteger;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Collections;
- import java.util.List;
- import java.util.Locale;
- import java.util.Map;
- import java.util.StringTokenizer;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- import java.util.regex.PatternSyntaxException;
- /**
- * @author Jason D. Rivard
- */
- public class FormConfiguration implements Serializable {
- // ------------------------------ FIELDS ------------------------------
- public enum Type {text, email, number, password, random, tel, hidden, date, datetime, time, week, month, url, select, userDN, checkbox}
- private String name;
- private int minimumLength;
- private int maximumLength;
- private Type type = Type.text;
- private boolean required;
- private boolean confirmationRequired;
- private boolean readonly;
- private boolean unique;
- private boolean multivalue;
- private Map<String,String> labels = Collections.singletonMap("", "");
- private Map<String,String> regexErrors = Collections.singletonMap("","");
- private Map<String,String> description = Collections.singletonMap("","");
- private String regex;
- private String placeholder;
- private String javascript;
- private Map<String,String> selectOptions = Collections.emptyMap();
- // -------------------------- STATIC METHODS --------------------------
- public static FormConfiguration parseOldConfigString(final String config)
- throws PwmOperationalException
- {
- if (config == null) {
- throw new NullPointerException("config can not be null");
- }
- final FormConfiguration formItem = new FormConfiguration();
- final StringTokenizer st = new StringTokenizer(config, ":");
- // attribute name
- formItem.name = st.nextToken();
- // label
- formItem.labels = Collections.singletonMap("",st.nextToken());
- // type
- {
- final String typeStr = st.nextToken();
- try {
- formItem.type = Type.valueOf(typeStr.toLowerCase());
- } catch (IllegalArgumentException e) {
- throw new PwmOperationalException(new ErrorInformation(PwmError.CONFIG_FORMAT_ERROR,null,new String[]{"unknown type for form config: " + typeStr}));
- }
- }
- //minimum length
- try {
- formItem.minimumLength = Integer.parseInt(st.nextToken());
- } catch (NumberFormatException e) {
- throw new PwmOperationalException(new ErrorInformation(PwmError.CONFIG_FORMAT_ERROR,null,new String[]{"invalid minimum length type for form config: " + e.getMessage()}));
- }
- //maximum length
- try {
- formItem.maximumLength = Integer.parseInt(st.nextToken());
- } catch (NumberFormatException e) {
- throw new PwmOperationalException(new ErrorInformation(PwmError.CONFIG_FORMAT_ERROR,null,new String[]{"invalid maximum length type for form config: " + e.getMessage()}));
- }
- //required
- formItem.required = Boolean.TRUE.toString().equalsIgnoreCase(st.nextToken());
- //confirmation
- formItem.confirmationRequired = Boolean.TRUE.toString().equalsIgnoreCase(st.nextToken());
- return formItem;
- }
- public void validate() throws PwmOperationalException {
- if (this.getName() == null || this.getName().length() < 1) {
- throw new PwmOperationalException(new ErrorInformation(PwmError.CONFIG_FORMAT_ERROR,null,new String[]{" form field name is required"}));
- }
- if (this.getType() == null) {
- throw new PwmOperationalException(new ErrorInformation(PwmError.CONFIG_FORMAT_ERROR,null,new String[]{" type is required for field " + this.getName()}));
- }
- if (labels == null || this.labels.isEmpty() || this.getLabel(PwmConstants.DEFAULT_LOCALE) == null || this.getLabel(PwmConstants.DEFAULT_LOCALE).length() < 1) {
- throw new PwmOperationalException(new ErrorInformation(PwmError.CONFIG_FORMAT_ERROR,null,new String[]{" a default label value is required for " + this.getName()}));
- }
- if (this.getRegex() != null && this.getRegex().length() > 0) {
- try {
- Pattern.compile(this.getRegex());
- } catch (PatternSyntaxException e) {
- throw new PwmOperationalException(new ErrorInformation(PwmError.CONFIG_FORMAT_ERROR,null,new String[]{" regular expression for '" + this.getName() + " ' is not valid: " + e.getMessage()}));
- }
- }
- if (this.getType() == Type.select) {
- if (this.getSelectOptions() == null || this.getSelectOptions().isEmpty()) {
- throw new PwmOperationalException(new ErrorInformation(PwmError.CONFIG_FORMAT_ERROR,null,new String[]{" field '" + this.getName() + " ' is type select, but no select options are defined"}));
- }
- }
- }
- // --------------------------- CONSTRUCTORS ---------------------------
- public FormConfiguration() {
- labels = Collections.singletonMap("","");
- regexErrors = Collections.singletonMap("","");
- }
- // --------------------- GETTER / SETTER METHODS ---------------------
- public String getName() {
- return name;
- }
- public String getLabel(final Locale locale) {
- return LocaleHelper.resolveStringKeyLocaleMap(locale, labels);
- }
- public Map<String,String> getLabelLocaleMap() {
- return Collections.unmodifiableMap(this.labels);
- }
- public String getRegexError(final Locale locale) {
- return LocaleHelper.resolveStringKeyLocaleMap(locale, regexErrors);
- }
- public String getDescription(final Locale locale) {
- return LocaleHelper.resolveStringKeyLocaleMap(locale, description);
- }
- public Map<String,String> getLabelDescriptionLocaleMap() {
- return Collections.unmodifiableMap(this.description);
- }
- public int getMaximumLength() {
- return maximumLength;
- }
- public int getMinimumLength() {
- return minimumLength;
- }
- public Type getType() {
- return type;
- }
- public boolean isConfirmationRequired() {
- return confirmationRequired;
- }
- public boolean isRequired() {
- return required;
- }
- public boolean isReadonly() {
- return readonly;
- }
- public boolean isUnique() {
- return unique;
- }
- public boolean isMultivalue() {
- return multivalue;
- }
- public String getRegex() {
- return regex;
- }
- public String getPlaceholder() {
- return placeholder;
- }
- public String getJavascript() {
- return javascript;
- }
- public Map<String,String> getSelectOptions() {
- return Collections.unmodifiableMap(selectOptions);
- }
- // ------------------------ CANONICAL METHODS ------------------------
- public boolean equals(final Object o) {
- if (this == o) {
- return true;
- }
- if (!(o instanceof FormConfiguration)) {
- return false;
- }
- final FormConfiguration parameterConfig = (FormConfiguration) o;
- return !(name != null ? !name.equals(parameterConfig.name) : parameterConfig.name != null);
- }
- public int hashCode() {
- return (name != null ? name.hashCode() : 0);
- }
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append("FormItem: ");
- sb.append(JsonUtil.serialize(this));
- return sb.toString();
- }
- // -------------------------- OTHER METHODS --------------------------
- public void checkValue(final Configuration config, final String value, final Locale locale)
- throws PwmDataValidationException, PwmUnrecoverableException {
- //check if value is missing and required.
- if (required && (value == null || value.length() < 1)) {
- final ErrorInformation error = new ErrorInformation(PwmError.ERROR_FIELD_REQUIRED, null, new String[]{getLabel(locale)});
- throw new PwmDataValidationException(error);
- }
- switch (type) {
- case number:
- if (value != null && value.length() > 0) {
- try {
- new BigInteger(value);
- } catch (NumberFormatException e) {
- final ErrorInformation error = new ErrorInformation(PwmError.ERROR_FIELD_NOT_A_NUMBER, null, new String[]{getLabel(locale)});
- throw new PwmDataValidationException(error);
- }
- }
- break;
- case email:
- if (value != null && value.length() > 0) {
- if (!testEmailAddress(config, value)) {
- final ErrorInformation error = new ErrorInformation(PwmError.ERROR_FIELD_INVALID_EMAIL, null, new String[]{getLabel(locale)});
- throw new PwmDataValidationException(error);
- }
- }
- break;
- default:
- // continue for other types
- break;
- }
- if (value != null && (this.getMinimumLength() > 0) && (value.length() > 0) && (value.length() < this.getMinimumLength())) {
- final ErrorInformation error = new ErrorInformation(PwmError.ERROR_FIELD_TOO_SHORT, null, new String[]{getLabel(locale)});
- throw new PwmDataValidationException(error);
- }
- if (value != null && value.length() > this.getMaximumLength()) {
- final ErrorInformation error = new ErrorInformation(PwmError.ERROR_FIELD_TOO_LONG, null, new String[]{getLabel(locale)});
- throw new PwmDataValidationException(error);
- }
- if (value != null && value.length() > 0 && this.getRegex() != null && this.getRegex().length() > 0) {
- if (!value.matches(this.getRegex())) {
- final String configuredErrorMessage = this.getRegexError(locale);
- final ErrorInformation error = new ErrorInformation(PwmError.ERROR_FIELD_REGEX_NOMATCH, null, configuredErrorMessage, new String[]{getLabel(locale)});
- throw new PwmDataValidationException(error);
- }
- }
- }
- public static List<String> convertToListOfNames(final Collection<FormConfiguration> formConfigurations) {
- if (formConfigurations == null) {
- return Collections.emptyList();
- }
- final ArrayList<String> returnList = new ArrayList<>();
- for (final FormConfiguration formConfiguration : formConfigurations) {
- returnList.add(formConfiguration.getName());
- }
- return returnList;
- }
- /**
- * Return false if an invalid email address is issued.
- * @param config
- * @param address
- * @return
- */
- public static boolean testEmailAddress(final Configuration config, final String address) {
- final String patternStr;
- if (config != null) {
- patternStr = config.readAppProperty(AppProperty.FORM_EMAIL_REGEX);
- } else {
- patternStr = AppProperty.FORM_EMAIL_REGEX.getDefaultValue();
- }
- final Pattern pattern = Pattern.compile(patternStr);
- final Matcher matcher = pattern.matcher(address);
- return matcher.matches();
- }
- public String displayValue(final String value, final Locale locale, final Configuration config) {
- if (value == null) {
- return LocaleHelper.getLocalizedMessage(locale, Display.Value_NotApplicable, config);
- }
- if (this.getType() == Type.select) {
- if (this.getSelectOptions() != null) {
- for (final String key : selectOptions.keySet()) {
- if (value.equals(key)) {
- final String displayValue = selectOptions.get(key);
- if (!StringUtil.isEmpty(displayValue)) {
- return displayValue;
- }
- }
- }
- }
- }
- return value;
- }
- }
|