Skip to content

Commit 4390cfb

Browse files
committed
🎨 fixing the mess about password length resolution
Signed-off-by: dseurotech <[email protected]>
1 parent 72c8f63 commit 4390cfb

File tree

12 files changed

+300
-173
lines changed

12 files changed

+300
-173
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2016, 2022 Eurotech and/or its affiliates and others
3+
*
4+
* This program and the accompanying materials are made
5+
* available under the terms of the Eclipse Public License 2.0
6+
* which is available at https://www.eclipse.org/legal/epl-2.0/
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*
10+
* Contributors:
11+
* Eurotech - initial API and implementation
12+
*******************************************************************************/
13+
package org.eclipse.kapua.service.authentication.credential.shiro;
14+
15+
import org.eclipse.kapua.KapuaException;
16+
import org.eclipse.kapua.model.id.KapuaId;
17+
import org.eclipse.kapua.storage.TxContext;
18+
19+
public interface AccountPasswordLengthProvider {
20+
21+
int getMinimumPasswordLength(TxContext txContext, KapuaId scopeId) throws KapuaException;
22+
23+
int getMaximumPasswordLength(TxContext txContext, KapuaId scopeId) throws KapuaException;
24+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2016, 2022 Eurotech and/or its affiliates and others
3+
*
4+
* This program and the accompanying materials are made
5+
* available under the terms of the Eclipse Public License 2.0
6+
* which is available at https://www.eclipse.org/legal/epl-2.0/
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*
10+
* Contributors:
11+
* Eurotech - initial API and implementation
12+
*******************************************************************************/
13+
package org.eclipse.kapua.service.authentication.credential.shiro;
14+
15+
import java.util.Map;
16+
17+
import org.eclipse.kapua.KapuaException;
18+
import org.eclipse.kapua.commons.configuration.ServiceConfigurationManager;
19+
import org.eclipse.kapua.commons.util.ArgumentValidator;
20+
import org.eclipse.kapua.model.id.KapuaId;
21+
import org.eclipse.kapua.service.authentication.shiro.SystemPasswordLengthProvider;
22+
import org.eclipse.kapua.storage.TxContext;
23+
24+
public class AccountPasswordLengthProviderImpl implements AccountPasswordLengthProvider {
25+
26+
private final SystemPasswordLengthProvider systemPasswordLengthProvider;
27+
private final ServiceConfigurationManager credentialServiceConfigurationManager;
28+
public static final String PASSWORD_MIN_LENGTH_ACCOUNT_CONFIG_KEY = "password.minLength";
29+
30+
public AccountPasswordLengthProviderImpl(SystemPasswordLengthProvider systemPasswordLengthProvider, ServiceConfigurationManager credentialServiceConfigurationManager) {
31+
this.systemPasswordLengthProvider = systemPasswordLengthProvider;
32+
this.credentialServiceConfigurationManager = credentialServiceConfigurationManager;
33+
}
34+
35+
@Override
36+
public int getMinimumPasswordLength(TxContext txContext, KapuaId scopeId) throws KapuaException {
37+
// Argument Validation
38+
ArgumentValidator.notNull(scopeId, "scopeId");
39+
40+
// Check access
41+
// None
42+
43+
// Get system minimum password length
44+
int minPasswordLength = systemPasswordLengthProvider.getSystemMinimumPasswordLength();
45+
46+
if (!KapuaId.ANY.equals(scopeId)) {
47+
Object minPasswordLengthAccountConfigValue = getConfigValues(txContext, scopeId).get(PASSWORD_MIN_LENGTH_ACCOUNT_CONFIG_KEY);
48+
if (minPasswordLengthAccountConfigValue != null) {
49+
minPasswordLength = Integer.parseInt(minPasswordLengthAccountConfigValue.toString());
50+
}
51+
}
52+
return minPasswordLength;
53+
}
54+
55+
@Override
56+
public int getMaximumPasswordLength(TxContext txContext, KapuaId scopeId) throws KapuaException {
57+
return systemPasswordLengthProvider.getSystemMaximumPasswordLength();
58+
}
59+
60+
private Map<String, Object> getConfigValues(TxContext tx, KapuaId scopeId) throws KapuaException {
61+
return credentialServiceConfigurationManager.getConfigValues(tx, scopeId, true);
62+
}
63+
}

service/security/shiro/src/main/java/org/eclipse/kapua/service/authentication/credential/shiro/CredentialServiceImpl.java

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,19 @@
1212
*******************************************************************************/
1313
package org.eclipse.kapua.service.authentication.credential.shiro;
1414

15+
import java.security.NoSuchAlgorithmException;
16+
import java.security.SecureRandom;
17+
import java.util.concurrent.atomic.AtomicReference;
18+
19+
import javax.inject.Singleton;
20+
1521
import org.apache.shiro.codec.Base64;
1622
import org.eclipse.kapua.KapuaEntityNotFoundException;
1723
import org.eclipse.kapua.KapuaException;
1824
import org.eclipse.kapua.KapuaIllegalArgumentException;
1925
import org.eclipse.kapua.KapuaRuntimeException;
2026
import org.eclipse.kapua.commons.configuration.KapuaConfigurableServiceBase;
27+
import org.eclipse.kapua.commons.configuration.ServiceConfigurationManager;
2128
import org.eclipse.kapua.commons.model.domains.Domains;
2229
import org.eclipse.kapua.commons.util.ArgumentValidator;
2330
import org.eclipse.kapua.event.ServiceEvent;
@@ -39,7 +46,6 @@
3946
import org.eclipse.kapua.service.authentication.credential.CredentialService;
4047
import org.eclipse.kapua.service.authentication.credential.CredentialType;
4148
import org.eclipse.kapua.service.authentication.exception.DuplicatedPasswordCredentialException;
42-
import org.eclipse.kapua.service.authentication.shiro.CredentialServiceConfigurationManager;
4349
import org.eclipse.kapua.service.authentication.shiro.setting.KapuaAuthenticationSetting;
4450
import org.eclipse.kapua.service.authentication.shiro.setting.KapuaAuthenticationSettingKeys;
4551
import org.eclipse.kapua.service.authentication.user.PasswordResetRequest;
@@ -49,11 +55,6 @@
4955
import org.slf4j.Logger;
5056
import org.slf4j.LoggerFactory;
5157

52-
import javax.inject.Singleton;
53-
import java.security.NoSuchAlgorithmException;
54-
import java.security.SecureRandom;
55-
import java.util.concurrent.atomic.AtomicReference;
56-
5758
/**
5859
* {@link CredentialService} implementation.
5960
*
@@ -69,11 +70,12 @@ public class CredentialServiceImpl extends KapuaConfigurableServiceBase implemen
6970
private final CredentialFactory credentialFactory;
7071
private final KapuaAuthenticationSetting kapuaAuthenticationSetting;
7172
private final CredentialMapper credentialMapper;
73+
private final AccountPasswordLengthProvider accountPasswordLengthProvider;
7274
private final PasswordValidator passwordValidator;
7375
private final PasswordResetter passwordResetter;
7476

7577
public CredentialServiceImpl(
76-
CredentialServiceConfigurationManager serviceConfigurationManager,
78+
ServiceConfigurationManager serviceConfigurationManager,
7779
AuthorizationService authorizationService,
7880
PermissionFactory permissionFactory,
7981
TxManager txManager,
@@ -82,11 +84,13 @@ public CredentialServiceImpl(
8284
CredentialMapper credentialMapper,
8385
PasswordValidator passwordValidator,
8486
KapuaAuthenticationSetting kapuaAuthenticationSetting,
87+
AccountPasswordLengthProvider accountPasswordLengthProvider,
8588
PasswordResetter passwordResetter) {
8689
super(txManager, serviceConfigurationManager, Domains.CREDENTIAL, authorizationService, permissionFactory);
8790
this.credentialRepository = credentialRepository;
8891
this.credentialFactory = credentialFactory;
8992
this.kapuaAuthenticationSetting = kapuaAuthenticationSetting;
93+
this.accountPasswordLengthProvider = accountPasswordLengthProvider;
9094
this.passwordResetter = passwordResetter;
9195
try {
9296
random = SecureRandom.getInstance("SHA1PRNG");
@@ -134,31 +138,31 @@ public Credential create(CredentialCreator credentialCreatorer)
134138
// Do create
135139
// Do pre persist magic on key values
136140
switch (credentialCreator.getCredentialType()) {
137-
case API_KEY: // Generate new api key
138-
int preLength = kapuaAuthenticationSetting.getInt(KapuaAuthenticationSettingKeys.AUTHENTICATION_CREDENTIAL_APIKEY_PRE_LENGTH);
139-
int keyLength = kapuaAuthenticationSetting.getInt(KapuaAuthenticationSettingKeys.AUTHENTICATION_CREDENTIAL_APIKEY_KEY_LENGTH);
140-
141-
byte[] bPre = new byte[preLength];
142-
random.nextBytes(bPre);
143-
String pre = Base64.encodeToString(bPre).substring(0, preLength);
144-
145-
byte[] bKey = new byte[keyLength];
146-
random.nextBytes(bKey);
147-
String key = Base64.encodeToString(bKey);
148-
149-
fullKey.set(pre + key);
150-
151-
credentialCreator = new CredentialCreatorImpl(credentialCreator.getScopeId(),
152-
credentialCreator.getUserId(),
153-
credentialCreator.getCredentialType(),
154-
fullKey.get(),
155-
credentialCreator.getCredentialStatus(),
156-
credentialCreator.getExpirationDate());
157-
break;
158-
case PASSWORD:
159-
default:
160-
// Don't do anything special
161-
break;
141+
case API_KEY: // Generate new api key
142+
int preLength = kapuaAuthenticationSetting.getInt(KapuaAuthenticationSettingKeys.AUTHENTICATION_CREDENTIAL_APIKEY_PRE_LENGTH);
143+
int keyLength = kapuaAuthenticationSetting.getInt(KapuaAuthenticationSettingKeys.AUTHENTICATION_CREDENTIAL_APIKEY_KEY_LENGTH);
144+
145+
byte[] bPre = new byte[preLength];
146+
random.nextBytes(bPre);
147+
String pre = Base64.encodeToString(bPre).substring(0, preLength);
148+
149+
byte[] bKey = new byte[keyLength];
150+
random.nextBytes(bKey);
151+
String key = Base64.encodeToString(bKey);
152+
153+
fullKey.set(pre + key);
154+
155+
credentialCreator = new CredentialCreatorImpl(credentialCreator.getScopeId(),
156+
credentialCreator.getUserId(),
157+
credentialCreator.getCredentialType(),
158+
fullKey.get(),
159+
credentialCreator.getCredentialStatus(),
160+
credentialCreator.getExpirationDate());
161+
break;
162+
case PASSWORD:
163+
default:
164+
// Don't do anything special
165+
break;
162166
}
163167
// Create Credential
164168
Credential newCredential = credentialMapper.map(credentialCreator);
@@ -325,7 +329,7 @@ public void unlock(KapuaId scopeId, KapuaId credentialId) throws KapuaException
325329

326330
@Override
327331
public int getMinimumPasswordLength(KapuaId scopeId) throws KapuaException {
328-
return txManager.execute(tx -> passwordValidator.getMinimumPasswordLength(tx, scopeId));
332+
return txManager.execute(tx -> accountPasswordLengthProvider.getMinimumPasswordLength(tx, scopeId));
329333
}
330334

331335
private long countExistingCredentials(CredentialType credentialType, KapuaId scopeId, KapuaId userId) throws KapuaException {

service/security/shiro/src/main/java/org/eclipse/kapua/service/authentication/credential/shiro/PasswordValidator.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import org.eclipse.kapua.storage.TxContext;
1818

1919
public interface PasswordValidator {
20-
void validatePassword(TxContext txContext, KapuaId scopeId, String plainPassword) throws KapuaException;
2120

22-
int getMinimumPasswordLength(TxContext txContext, KapuaId scopeId) throws KapuaException;
21+
void validatePassword(TxContext txContext, KapuaId scopeId, String plainPassword) throws KapuaException;
2322
}

service/security/shiro/src/main/java/org/eclipse/kapua/service/authentication/credential/shiro/PasswordValidatorImpl.java

Lines changed: 7 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,14 @@
1717
import org.eclipse.kapua.commons.util.CommonsValidationRegex;
1818
import org.eclipse.kapua.model.id.KapuaId;
1919
import org.eclipse.kapua.service.authentication.exception.PasswordLengthException;
20-
import org.eclipse.kapua.service.authentication.shiro.CredentialServiceConfigurationManager;
21-
import org.eclipse.kapua.service.authentication.shiro.CredentialServiceConfigurationManagerImpl;
2220
import org.eclipse.kapua.storage.TxContext;
2321

24-
import java.util.Map;
25-
2622
public class PasswordValidatorImpl implements PasswordValidator {
2723

28-
private final CredentialServiceConfigurationManager credentialServiceConfigurationManager;
24+
private final AccountPasswordLengthProvider accountPasswordLengthProvider;
2925

30-
public PasswordValidatorImpl(CredentialServiceConfigurationManager credentialServiceConfigurationManager) {
31-
this.credentialServiceConfigurationManager = credentialServiceConfigurationManager;
26+
public PasswordValidatorImpl(AccountPasswordLengthProvider accountPasswordLengthProvider) {
27+
this.accountPasswordLengthProvider = accountPasswordLengthProvider;
3228
}
3329

3430
@Override
@@ -38,35 +34,13 @@ public void validatePassword(TxContext txContext, KapuaId scopeId, String plainP
3834
ArgumentValidator.notEmptyOrNull(plainPassword, "plainPassword");
3935

4036
// Validate Password length
41-
int minPasswordLength = getMinimumPasswordLength(txContext, scopeId);
42-
if (plainPassword.length() < minPasswordLength || plainPassword.length() > CredentialServiceConfigurationManagerImpl.SYSTEM_MAXIMUM_PASSWORD_LENGTH) {
43-
throw new PasswordLengthException(minPasswordLength, CredentialServiceConfigurationManagerImpl.SYSTEM_MAXIMUM_PASSWORD_LENGTH);
37+
int minPasswordLength = accountPasswordLengthProvider.getMinimumPasswordLength(txContext, scopeId);
38+
int maxPasswordLenght = accountPasswordLengthProvider.getMaximumPasswordLength(txContext, scopeId);
39+
if (plainPassword.length() < minPasswordLength || plainPassword.length() > maxPasswordLenght) {
40+
throw new PasswordLengthException(minPasswordLength, maxPasswordLenght);
4441
}
4542
// Validate Password regex
4643
ArgumentValidator.match(plainPassword, CommonsValidationRegex.PASSWORD_REGEXP, "plainPassword");
4744
}
4845

49-
@Override
50-
public int getMinimumPasswordLength(TxContext txContext, KapuaId scopeId) throws KapuaException {
51-
// Argument Validation
52-
ArgumentValidator.notNull(scopeId, "scopeId");
53-
54-
// Check access
55-
// None
56-
57-
// Get system minimum password length
58-
int minPasswordLength = credentialServiceConfigurationManager.getSystemMinimumPasswordLength();
59-
60-
if (!KapuaId.ANY.equals(scopeId)) {
61-
Object minPasswordLengthAccountConfigValue = getConfigValues(txContext, scopeId).get(CredentialServiceConfigurationManagerImpl.PASSWORD_MIN_LENGTH_ACCOUNT_CONFIG_KEY);
62-
if (minPasswordLengthAccountConfigValue != null) {
63-
minPasswordLength = Integer.parseInt(minPasswordLengthAccountConfigValue.toString());
64-
}
65-
}
66-
return minPasswordLength;
67-
}
68-
69-
private Map<String, Object> getConfigValues(TxContext tx, KapuaId scopeId) throws KapuaException {
70-
return credentialServiceConfigurationManager.getConfigValues(tx, scopeId, true);
71-
}
7246
}

0 commit comments

Comments
 (0)