Skip to content

Commit bfb22da

Browse files
committed
introduce domain properties
1 parent 9fd838b commit bfb22da

39 files changed

+497
-290
lines changed

server/src/main/java/password/pwm/AppProperty.java

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,6 @@ public enum AppProperty
6060
CACHE_FORM_UNIQUE_VALUE_LIFETIME_MS ( "cache.uniqueFormValueLifetimeMS" ),
6161
CLIENT_ACTIVITY_MAX_EPS_RATE ( "client.ajax.activityMaxEpsRate" ),
6262
CLIENT_AJAX_PW_WAIT_CHECK_SECONDS ( "client.ajax.changePasswordWaitCheckSeconds" ),
63-
CLIENT_AJAX_TYPING_TIMEOUT ( "client.ajax.typingTimeout" ),
64-
CLIENT_AJAX_TYPING_WAIT ( "client.ajax.typingWait" ),
6563
CLIENT_FORM_NONCE_ENABLE ( "client.formNonce.enable" ),
6664
CLIENT_FORM_NONCE_LENGTH ( "client.formNonce.length" ),
6765
CLIENT_FORM_CLIENT_REGEX_ENABLED ( "client.form.clientRegexEnable" ),
@@ -112,20 +110,6 @@ public enum AppProperty
112110
HTTP_RESOURCES_ENABLE_PATH_NONCE ( "http.resources.pathNonceEnable" ),
113111
HTTP_RESOURCES_NONCE_PATH_PREFIX ( "http.resources.pathNoncePrefix" ),
114112
HTTP_RESOURCES_ZIP_FILES ( "http.resources.zipFiles" ),
115-
HTTP_COOKIE_DEFAULT_SECURE_FLAG ( "http.cookie.default.secureFlag" ),
116-
HTTP_COOKIE_HTTPONLY_ENABLE ( "http.cookie.httponly.enable" ),
117-
HTTP_COOKIE_THEME_NAME ( "http.cookie.theme.name" ),
118-
HTTP_COOKIE_THEME_AGE ( "http.cookie.theme.age" ),
119-
HTTP_COOKIE_LOCALE_NAME ( "http.cookie.locale.name" ),
120-
HTTP_COOKIE_AUTHRECORD_NAME ( "http.cookie.authRecord.name" ),
121-
HTTP_COOKIE_AUTHRECORD_AGE ( "http.cookie.authRecord.age" ),
122-
HTTP_COOKIE_MAX_READ_LENGTH ( "http.cookie.maxReadLength" ),
123-
HTTP_COOKIE_CAPTCHA_SKIP_NAME ( "http.cookie.captchaSkip.name" ),
124-
HTTP_COOKIE_CAPTCHA_SKIP_AGE ( "http.cookie.captchaSkip.age" ),
125-
HTTP_COOKIE_LOGIN_NAME ( "http.cookie.login.name" ),
126-
HTTP_COOKIE_NONCE_NAME ( "http.cookie.nonce.name" ),
127-
HTTP_COOKIE_NONCE_LENGTH ( "http.cookie.nonce.length" ),
128-
HTTP_COOKIE_SAMESITE_VALUE ( "http.cookie.sameSite.value" ),
129113
HTTP_BASIC_AUTH_CHARSET ( "http.basicAuth.charset" ),
130114
HTTP_BODY_MAXREAD_LENGTH ( "http.body.maxReadLength" ),
131115
HTTP_CLIENT_ALWAYS_LOG_ENTITIES ( "http.client.alwaysLogEntities" ),
@@ -218,31 +202,6 @@ public enum AppProperty
218202
HELPDESK_TOKEN_VALUE ( "helpdesk.token.value" ),
219203
HELPDESK_VERIFICATION_INVALID_DELAY_MS ( "helpdesk.verification.invalid.delayMs" ),
220204
HELPDESK_VERIFICATION_TIMEOUT_SECONDS ( "helpdesk.verification.timeoutSeconds" ),
221-
LDAP_RESOLVE_CANONICAL_DN ( "ldap.resolveCanonicalDN" ),
222-
LDAP_CACHE_CANONICAL_ENABLE ( "ldap.cache.canonical.enable" ),
223-
LDAP_CACHE_CANONICAL_SECONDS ( "ldap.cache.canonical.seconds" ),
224-
LDAP_CACHE_USER_GUID_ENABLE ( "ldap.cache.userGuid.enable" ),
225-
LDAP_CACHE_USER_GUID_SECONDS ( "ldap.cache.userGuid.seconds" ),
226-
LDAP_CHAI_SETTINGS ( "ldap.chaiSettings" ),
227-
LDAP_PROXY_CONNECTION_PER_PROFILE ( "ldap.proxy.connectionsPerProfile" ),
228-
LDAP_PROXY_MAX_CONNECTIONS ( "ldap.proxy.maxConnections" ),
229-
LDAP_PROXY_IDLE_THREAD_LOCAL_TIMEOUT_MS ( "ldap.proxy.idleThreadLocal.timeoutMS" ),
230-
LDAP_EXTENSIONS_NMAS_ENABLE ( "ldap.extensions.nmas.enable" ),
231-
LDAP_CONNECTION_TIMEOUT ( "ldap.connection.timeoutMS" ),
232-
LDAP_PROFILE_RETRY_DELAY ( "ldap.profile.retryDelayMS" ),
233-
LDAP_PROMISCUOUS_ENABLE ( "ldap.promiscuousEnable" ),
234-
LDAP_PASSWORD_REPLICA_CHECK_INIT_DELAY_MS ( "ldap.password.replicaCheck.initialDelayMS" ),
235-
LDAP_PASSWORD_REPLICA_CHECK_CYCLE_DELAY_MS ( "ldap.password.replicaCheck.cycleDelayMS" ),
236-
LDAP_PASSWORD_CHANGE_SELF_ENABLE ( "ldap.password.change.self.enable" ),
237-
LDAP_PASSWORD_CHANGE_HELPDESK_ENABLE ( "ldap.password.change.helpdesk.enable" ),
238-
LDAP_GUID_PATTERN ( "ldap.guid.pattern" ),
239-
LDAP_BROWSER_MAX_ENTRIES ( "ldap.browser.maxEntries" ),
240-
LDAP_SEARCH_PAGING_ENABLE ( "ldap.search.paging.enable" ),
241-
LDAP_SEARCH_PAGING_SIZE ( "ldap.search.paging.size" ),
242-
LDAP_SEARCH_PARALLEL_ENABLE ( "ldap.search.parallel.enable" ),
243-
LDAP_SEARCH_PARALLEL_FACTOR ( "ldap.search.parallel.factor" ),
244-
LDAP_SEARCH_PARALLEL_THREAD_MAX ( "ldap.search.parallel.threadMax" ),
245-
LDAP_ORACLE_POST_TEMPPW_USE_CURRENT_TIME ( "ldap.oracle.postTempPasswordUseCurrentTime" ),
246205
LOGGING_OUTPUT_CONFIGURATION ( "logging.output.configuration.enable" ),
247206
LOGGING_OUTPUT_HEALTHCHECK ( "logging.output.healthCheck.enable" ),
248207
LOGGING_OUTPUT_RUNTIME ( "logging.output.runtime.enable" ),
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* Password Management Servlets (PWM)
3+
* http://www.pwm-project.org
4+
*
5+
* Copyright (c) 2006-2009 Novell, Inc.
6+
* Copyright (c) 2009-2021 The PWM Project
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License");
9+
* you may not use this file except in compliance with the License.
10+
* You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*/
20+
21+
package password.pwm;
22+
23+
import password.pwm.util.java.EnumUtil;
24+
25+
import java.util.Objects;
26+
import java.util.Optional;
27+
import java.util.ResourceBundle;
28+
29+
public enum DomainProperty
30+
{
31+
CLIENT_AJAX_TYPING_TIMEOUT ( "client.ajax.typingTimeout" ),
32+
CLIENT_AJAX_TYPING_WAIT ( "client.ajax.typingWait" ),
33+
HTTP_COOKIE_DEFAULT_SECURE_FLAG ( "http.cookie.default.secureFlag" ),
34+
HTTP_COOKIE_HTTPONLY_ENABLE ( "http.cookie.httponly.enable" ),
35+
HTTP_COOKIE_THEME_NAME ( "http.cookie.theme.name" ),
36+
HTTP_COOKIE_THEME_AGE ( "http.cookie.theme.age" ),
37+
HTTP_COOKIE_LOCALE_NAME ( "http.cookie.locale.name" ),
38+
HTTP_COOKIE_AUTHRECORD_NAME ( "http.cookie.authRecord.name" ),
39+
HTTP_COOKIE_AUTHRECORD_AGE ( "http.cookie.authRecord.age" ),
40+
HTTP_COOKIE_MAX_READ_LENGTH ( "http.cookie.maxReadLength" ),
41+
HTTP_COOKIE_CAPTCHA_SKIP_NAME ( "http.cookie.captchaSkip.name" ),
42+
HTTP_COOKIE_CAPTCHA_SKIP_AGE ( "http.cookie.captchaSkip.age" ),
43+
HTTP_COOKIE_LOGIN_NAME ( "http.cookie.login.name" ),
44+
HTTP_COOKIE_NONCE_NAME ( "http.cookie.nonce.name" ),
45+
HTTP_COOKIE_NONCE_LENGTH ( "http.cookie.nonce.length" ),
46+
HTTP_COOKIE_SAMESITE_VALUE ( "http.cookie.sameSite.value" ),
47+
LDAP_RESOLVE_CANONICAL_DN ( "ldap.resolveCanonicalDN" ),
48+
LDAP_CACHE_CANONICAL_ENABLE ( "ldap.cache.canonical.enable" ),
49+
LDAP_CACHE_CANONICAL_SECONDS ( "ldap.cache.canonical.seconds" ),
50+
LDAP_CACHE_USER_GUID_ENABLE ( "ldap.cache.userGuid.enable" ),
51+
LDAP_CACHE_USER_GUID_SECONDS ( "ldap.cache.userGuid.seconds" ),
52+
LDAP_CHAI_SETTINGS ( "ldap.chaiSettings" ),
53+
LDAP_PROXY_CONNECTION_PER_PROFILE ( "ldap.proxy.connectionsPerProfile" ),
54+
LDAP_PROXY_MAX_CONNECTIONS ( "ldap.proxy.maxConnections" ),
55+
LDAP_PROXY_IDLE_THREAD_LOCAL_TIMEOUT_MS ( "ldap.proxy.idleThreadLocal.timeoutMS" ),
56+
LDAP_EXTENSIONS_NMAS_ENABLE ( "ldap.extensions.nmas.enable" ),
57+
LDAP_CONNECTION_TIMEOUT ( "ldap.connection.timeoutMS" ),
58+
LDAP_PROFILE_RETRY_DELAY ( "ldap.profile.retryDelayMS" ),
59+
LDAP_PROMISCUOUS_ENABLE ( "ldap.promiscuousEnable" ),
60+
LDAP_PASSWORD_REPLICA_CHECK_INIT_DELAY_MS ( "ldap.password.replicaCheck.initialDelayMS" ),
61+
LDAP_PASSWORD_REPLICA_CHECK_CYCLE_DELAY_MS ( "ldap.password.replicaCheck.cycleDelayMS" ),
62+
LDAP_PASSWORD_CHANGE_SELF_ENABLE ( "ldap.password.change.self.enable" ),
63+
LDAP_PASSWORD_CHANGE_HELPDESK_ENABLE ( "ldap.password.change.helpdesk.enable" ),
64+
LDAP_GUID_PATTERN ( "ldap.guid.pattern" ),
65+
LDAP_BROWSER_MAX_ENTRIES ( "ldap.browser.maxEntries" ),
66+
LDAP_SEARCH_PAGING_ENABLE ( "ldap.search.paging.enable" ),
67+
LDAP_SEARCH_PAGING_SIZE ( "ldap.search.paging.size" ),
68+
LDAP_SEARCH_PARALLEL_ENABLE ( "ldap.search.parallel.enable" ),
69+
LDAP_SEARCH_PARALLEL_FACTOR ( "ldap.search.parallel.factor" ),
70+
LDAP_SEARCH_PARALLEL_THREAD_MAX ( "ldap.search.parallel.threadMax" ),
71+
LDAP_ORACLE_POST_TEMPPW_USE_CURRENT_TIME ( "ldap.oracle.postTempPasswordUseCurrentTime" ),;
72+
73+
private final String key;
74+
private final String defaultValue;
75+
76+
DomainProperty( final String key )
77+
{
78+
this.key = key;
79+
this.defaultValue = readDomainPropertiesBundle( key );
80+
}
81+
82+
public String getKey( )
83+
{
84+
return key;
85+
}
86+
87+
public String getDefaultValue( )
88+
{
89+
return defaultValue;
90+
}
91+
92+
public boolean isDefaultValue( final String value )
93+
{
94+
return Objects.equals( defaultValue, value );
95+
}
96+
97+
public static Optional<DomainProperty> forKey( final String key )
98+
{
99+
return EnumUtil.readEnumFromPredicate( DomainProperty.class, domainProperty -> Objects.equals( domainProperty.getKey(), key ) );
100+
}
101+
102+
private static String readDomainPropertiesBundle( final String key )
103+
{
104+
return ResourceBundle.getBundle( DomainProperty.class.getName() ).getString( key );
105+
}
106+
}

server/src/main/java/password/pwm/config/DomainConfig.java

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
package password.pwm.config;
2222

2323
import password.pwm.AppProperty;
24+
import password.pwm.DomainProperty;
2425
import password.pwm.bean.DomainID;
2526
import password.pwm.bean.EmailItemBean;
2627
import password.pwm.bean.PrivateKeyCertificate;
@@ -56,11 +57,12 @@
5657
import password.pwm.util.java.CollectionUtil;
5758
import password.pwm.util.java.CollectorUtil;
5859
import password.pwm.util.java.EnumUtil;
60+
import password.pwm.util.java.StringUtil;
5961
import password.pwm.util.secure.PwmSecurityKey;
6062

6163
import java.security.cert.X509Certificate;
6264
import java.util.ArrayList;
63-
import java.util.Collections;
65+
import java.util.EnumMap;
6466
import java.util.List;
6567
import java.util.Locale;
6668
import java.util.Map;
@@ -85,13 +87,17 @@ public class DomainConfig implements SettingReader
8587
private final StoredSettingReader settingReader;
8688
private final PwmSecurityKey domainSecurityKey;
8789

90+
private final Map<DomainProperty, String> domainProperties;
91+
8892
public DomainConfig( final AppConfig appConfig, final DomainID domainID )
8993
{
9094
this.appConfig = Objects.requireNonNull( appConfig );
9195
this.storedConfiguration = appConfig.getStoredConfiguration();
9296
this.domainID = Objects.requireNonNull( domainID );
9397
this.settingReader = new StoredSettingReader( storedConfiguration, null, domainID );
9498

99+
this.domainProperties = makeDomainPropertyOverrides( domainID, appConfig );
100+
95101
this.cachedPasswordPolicy = getPasswordProfileIDs().stream()
96102
.map( profile -> PwmPasswordPolicy.createPwmPasswordPolicy( this, profile ) )
97103
.collect( CollectorUtil.toUnmodifiableLinkedMap(
@@ -283,6 +289,11 @@ public String readAppProperty( final AppProperty property )
283289
return appConfig.readAppProperty( property );
284290
}
285291

292+
public String readDomainProperty( final DomainProperty property )
293+
{
294+
return domainProperties.getOrDefault( property, property.getDefaultValue() );
295+
}
296+
286297
public DomainID getDomainID()
287298
{
288299
return domainID;
@@ -395,7 +406,7 @@ private List<DataStorageMethod> calculateMethods(
395406
{
396407
methods.add( DataStorageMethod.NMAS );
397408
}
398-
return Collections.unmodifiableList( methods );
409+
return List.copyOf( methods );
399410
}
400411

401412

@@ -427,6 +438,35 @@ private static PwmSecurityKey makeDomainSecurityKey(
427438
}
428439
}
429440

441+
private static Map<DomainProperty, String> makeDomainPropertyOverrides( final DomainID domainID, final AppConfig appConfig )
442+
{
443+
final List<String> settingValues = appConfig.readSettingAsStringArray( PwmSetting.APP_PROPERTY_OVERRIDES );
444+
445+
final Map<String, String> stringMap = StringUtil.convertStringListToNameValuePair( settingValues, "=" );
446+
447+
final Map<DomainProperty, String> appPropertyMap = new EnumMap<>( DomainProperty.class );
448+
for ( final Map.Entry<String, String> stringEntry : stringMap.entrySet() )
449+
{
450+
final String value = stringEntry.getValue();
451+
final String domainPrefixedPropKey = domainID.stringValue() + "." + stringEntry.getKey();
452+
453+
final Optional<DomainProperty> domainProperty = DomainProperty.forKey( domainPrefixedPropKey )
454+
.or( () -> DomainProperty.forKey( stringEntry.getKey() ) );
455+
456+
domainProperty
457+
.ifPresent( domainPropertyKey ->
458+
{
459+
if ( !domainPropertyKey.isDefaultValue( value ) )
460+
{
461+
appPropertyMap.put( domainPropertyKey, value );
462+
}
463+
} );
464+
}
465+
466+
return CollectionUtil.unmodifiableEnumMap( appPropertyMap, DomainProperty.class );
467+
}
468+
469+
430470
@Override
431471
public String getValueHash()
432472
{

server/src/main/java/password/pwm/config/profile/LdapProfile.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import com.novell.ldapchai.exception.ChaiOperationException;
2525
import com.novell.ldapchai.exception.ChaiUnavailableException;
2626
import com.novell.ldapchai.provider.ChaiProvider;
27-
import password.pwm.AppProperty;
27+
import password.pwm.DomainProperty;
2828
import password.pwm.PwmDomain;
2929
import password.pwm.bean.DomainID;
3030
import password.pwm.bean.ProfileID;
@@ -168,14 +168,14 @@ public String readCanonicalDN(
168168
final Instant startTime = Instant.now();
169169

170170
{
171-
final boolean doCanonicalDnResolve = Boolean.parseBoolean( pwmDomain.getConfig().readAppProperty( AppProperty.LDAP_RESOLVE_CANONICAL_DN ) );
171+
final boolean doCanonicalDnResolve = Boolean.parseBoolean( pwmDomain.getConfig().readDomainProperty( DomainProperty.LDAP_RESOLVE_CANONICAL_DN ) );
172172
if ( !doCanonicalDnResolve )
173173
{
174174
return dnValue;
175175
}
176176
}
177177

178-
final boolean enableCanonicalCache = Boolean.parseBoolean( pwmDomain.getConfig().readAppProperty( AppProperty.LDAP_CACHE_CANONICAL_ENABLE ) );
178+
final boolean enableCanonicalCache = Boolean.parseBoolean( pwmDomain.getConfig().readDomainProperty( DomainProperty.LDAP_CACHE_CANONICAL_ENABLE ) );
179179

180180
String canonicalValue = null;
181181
final CacheKey cacheKey = CacheKey.newKey( LdapProfile.class, null, "canonicalDN-" + this.getId() + "-" + dnValue );
@@ -198,7 +198,7 @@ public String readCanonicalDN(
198198

199199
if ( enableCanonicalCache )
200200
{
201-
final long cacheSeconds = Long.parseLong( pwmDomain.getConfig().readAppProperty( AppProperty.LDAP_CACHE_CANONICAL_SECONDS ) );
201+
final long cacheSeconds = Long.parseLong( pwmDomain.getConfig().readDomainProperty( DomainProperty.LDAP_CACHE_CANONICAL_SECONDS ) );
202202
final CachePolicy cachePolicy = CachePolicy.makePolicyWithExpiration( TimeDuration.of( cacheSeconds, TimeDuration.Unit.SECONDS ) );
203203
pwmDomain.getCacheService().put( cacheKey, cachePolicy, canonicalValue );
204204
}

server/src/main/java/password/pwm/health/ConfigurationChecker.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
package password.pwm.health;
2222

2323
import lombok.Value;
24-
import password.pwm.AppProperty;
24+
import password.pwm.DomainProperty;
2525
import password.pwm.PwmApplication;
2626
import password.pwm.PwmApplicationMode;
2727
import password.pwm.PwmConstants;
@@ -91,10 +91,10 @@ public class ConfigurationChecker implements HealthSupplier
9191
VerifyIfDeprecatedJsFormOptionUsed.class,
9292
VerifyNewUserLdapProfile.class,
9393
VerifyPasswordWaitTimes.class,
94+
VerifyBasicSystemConfigs.class,
9495
VerifyUserPermissionSettings.class );
9596

9697
private static final List<Class<? extends ConfigSystemHealthCheck>> SYSTEM_CHECKS = List.of(
97-
VerifyBasicSystemConfigs.class,
9898
VerifyDbConfiguredIfNeededSystem.class );
9999

100100
@Override
@@ -214,20 +214,20 @@ public List<HealthRecord> healthCheck( final DomainHealthCheckRequest domainHeal
214214
}
215215
}
216216

217-
static class VerifyBasicSystemConfigs implements ConfigSystemHealthCheck
217+
static class VerifyBasicSystemConfigs implements ConfigDomainHealthCheck
218218
{
219219
@Override
220-
public List<HealthRecord> healthCheck( final SystemHealthCheckRequest systemHealthCheckRequest )
220+
public List<HealthRecord> healthCheck( final DomainHealthCheckRequest domainHealthCheckRequest )
221221
{
222-
final AppConfig config = systemHealthCheckRequest.getDomainConfig();
223-
final Locale locale = systemHealthCheckRequest.getLocale();
222+
final DomainConfig config = domainHealthCheckRequest.getDomainConfig();
223+
final Locale locale = domainHealthCheckRequest.getLocale();
224224

225225
final String separator = LocaleHelper.getLocalizedMessage( locale, Config.Display_SettingNavigationSeparator, null );
226226
final List<HealthRecord> records = new ArrayList<>();
227227

228-
if ( Boolean.parseBoolean( config.readAppProperty( AppProperty.LDAP_PROMISCUOUS_ENABLE ) ) )
228+
if ( Boolean.parseBoolean( config.readDomainProperty( DomainProperty.LDAP_PROMISCUOUS_ENABLE ) ) )
229229
{
230-
final String appPropertyKey = "AppProperty" + separator + AppProperty.LDAP_PROMISCUOUS_ENABLE.getKey();
230+
final String appPropertyKey = "AppProperty" + separator + DomainProperty.LDAP_PROMISCUOUS_ENABLE.getKey();
231231
records.add( HealthRecord.forMessage(
232232
DomainID.systemId(),
233233
HealthMessage.Config_PromiscuousLDAP,

server/src/main/java/password/pwm/http/PwmHttpRequestWrapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ public List<String> parameterNames( )
388388

389389
return CollectionUtil.iteratorToStream( getHttpServletRequest().getParameterNames().asIterator() )
390390
.map( s -> Validator.sanitizeInputValue( appConfig, s, maxChars ) )
391-
.collect( Collectors.toUnmodifiableList() );
391+
.toList();
392392

393393
}
394394

0 commit comments

Comments
 (0)