Skip to content

Commit 6d391e2

Browse files
committed
#28: update - check credentialsExpired during login
1 parent e20e9e8 commit 6d391e2

File tree

12 files changed

+168
-71
lines changed

12 files changed

+168
-71
lines changed

admin-tools-security/admin-tools-security-dbuser/README.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
> Integrates Spring Security and overrides the menu to use admintool.*.securityRoles to check if menu entries could be shown
33
44
## Features
5-
* `simple user view`: a view where you can manage user states, passwords and roles and add new users(since 1.1.5)
5+
* `database user view`: a view where you can manage user states, passwords and roles and add new users(since 1.2.0)
66

77
![Preview image](doc/screen_userview_org.png?raw=true "AdminTool User-View UI")
88

99
## Introduced with
10-
* admin-tools-core:1.1.7
10+
* admin-tools-core:1.2.0
1111

1212
## Requirements, Dependencies
1313
* spring-framework (core, security, spring-data, spring-mvc)
@@ -16,17 +16,17 @@
1616

1717

1818
## Usage
19-
Until version 1.1.7 the following dependencies must be used.
19+
Until version 1.2.0 the following dependencies must be used.
2020
```xml
2121
<dependency>
2222
<groupId>de.chandre.admin-tools</groupId>
2323
<artifactId>admin-tools-core</artifactId>
24-
<version>1.1.7</version>
24+
<version>1.2.0</version>
2525
</dependency>
2626
<dependency>
2727
<groupId>de.chandre.admin-tools.security</groupId>
2828
<artifactId>admin-tools-security-dbuser</artifactId>
29-
<version>1.1.7</version>
29+
<version>1.2.0</version>
3030
</dependency>
3131
```
3232

@@ -99,7 +99,7 @@ public class SecurityBeans {
9999
```
100100

101101
### Security-Config
102-
This is just an example configuration, role names depending on your own!
102+
This is just an example configuration, role names for your own modules depending on your own!
103103

104104
```java
105105
@EnableWebSecurity

admin-tools-security/admin-tools-security-dbuser/src/main/java/de/chandre/admintool/security/dbuser/ATSecDBAdminUserCreator.java

+25-11
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
import org.apache.commons.logging.Log;
1313
import org.apache.commons.logging.LogFactory;
1414
import org.springframework.beans.factory.annotation.Autowired;
15+
import org.springframework.util.CollectionUtils;
1516

1617
import de.chandre.admintool.core.sec.ATInitRole;
18+
import de.chandre.admintool.core.ui.ATError;
1719
import de.chandre.admintool.security.dbuser.domain.ATRole;
1820
import de.chandre.admintool.security.dbuser.domain.ATUser;
1921
import de.chandre.admintool.security.dbuser.domain.ATUserGroup;
@@ -59,12 +61,11 @@ public void createOrUpdateAdminUserAndGroup(String username, String password, St
5961
if (StringUtils.isEmpty(username)) {
6062
LOGGER.info("set admin username to: admin");
6163
username = "admin";
62-
} else {
63-
user = userDetailsService.getUser(username);
6464
}
65+
user = userDetailsService.getUser(username);
6566
if (null == user && StringUtils.isEmpty(password)) {
6667
LOGGER.info("set admin password to: admin");
67-
username = "admin";
68+
password = "admin";
6869
}
6970
if (null == user && null == locale) locale = Locale.getDefault();
7071
if (null == user && null == timeZone) timeZone = TimeZone.getDefault();
@@ -94,11 +95,15 @@ public void createOrUpdateAdminUserAndGroup(String username, String password, St
9495
}
9596

9697
LOGGER.info("addRolesIfNotExists");
97-
roleService.addRolesIfNotExists(new HashSet<>(roles.getRoles()));
98-
Set<String> allAccessMgmtRoleNames = roles.getRoles().stream().map(ATInitRole::getNamePrefixed).collect(Collectors.toSet());
99-
98+
Set<ATError> errors = roleService.addRolesIfNotExists(new HashSet<>(roles.getRoles()));
99+
if (!CollectionUtils.isEmpty(errors)) {
100+
for (ATError atError : errors) {
101+
LOGGER.error(atError.getKey() + ": " + atError.getMessage());
102+
}
103+
}
100104
List<ATRole> assignableRoles = null;
101105
if (onlyAccessManagementRoles) {
106+
Set<String> allAccessMgmtRoleNames = roles.getRoles().stream().map(ATInitRole::getNamePrefixed).collect(Collectors.toSet());
102107
assignableRoles = roleRepository.findByNameIn(allAccessMgmtRoleNames);
103108
} else {
104109
assignableRoles = roleRepository.findAll();
@@ -113,21 +118,30 @@ public void createOrUpdateAdminUserAndGroup(String username, String password, St
113118

114119
private void createOrUpdateUser(ATUser user, String username, String password, String firstName, String lastName,
115120
Locale locale, TimeZone timeZone, Set<ATUserGroup> userGroupAd) {
121+
boolean newUser = null == user;
116122
if (null == user) {
117123
LOGGER.info("creating user: " + username);
118124
user = new ATUser(username, password);
119125
user.setAccountExpiredSince(LocalDateTime.now());
120126
} else {
121127
LOGGER.info("updating user: " + username);
122128
}
123-
user.setFirstName(firstName);
124-
user.setLastName(lastName);
125-
user.setLocale(locale);
126-
user.setTimeZone(timeZone);
129+
if (null != firstName) {
130+
user.setFirstName(firstName);
131+
}
132+
if (null != lastName) {
133+
user.setLastName(lastName);
134+
}
135+
if (null != locale) {
136+
user.setLocale(locale);
137+
}
138+
if (null != timeZone) {
139+
user.setTimeZone(timeZone);
140+
}
127141
for (ATUserGroup atUserGroup : userGroupAd) {
128142
user.getUserGroups().add(atUserGroup);
129143
}
130-
user = userDetailsService.saveUser(user, true);
144+
user = userDetailsService.saveUser(user, newUser);
131145
}
132146

133147
private ATUserGroup createOrUpdateGroup(String groupName, String displayName, String desc, boolean active, List<ATRole> roles) {

admin-tools-security/admin-tools-security-dbuser/src/main/java/de/chandre/admintool/security/dbuser/AdminToolSecDBProperties.java

+32-8
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,11 @@ public static class Users {
136136
private boolean directPasswordChangeAllowed = true;
137137
private boolean directPasswordChangeInProfileAllowed = true;
138138

139-
private String passwordHashPeriod = "P7D";
139+
private String passwordHashPeriodStr = "P7D";
140140

141-
private String maxPasswordAge= "";
141+
private String maxLoginAttemptPeriodStr = "P7D";
142+
143+
private String maxPasswordAgePeriodStr = "P3M";
142144

143145
public List<String> getAvailableLocales() {
144146
return availableLocales;
@@ -194,13 +196,33 @@ public boolean isDirectPasswordChangeInProfileAllowed() {
194196
public void setDirectPasswordChangeInProfileAllowed(boolean directPasswordChangeInProfileAllowed) {
195197
this.directPasswordChangeInProfileAllowed = directPasswordChangeInProfileAllowed;
196198
}
197-
public void setPasswordHashPeriod(String passwordHashPeriod) {
198-
this.passwordHashPeriod = passwordHashPeriod;
199+
public String getPasswordHashPeriodStr() {
200+
return passwordHashPeriodStr;
201+
}
202+
public void setPasswordHashPeriodStr(String passwordHashPeriodStr) {
203+
this.passwordHashPeriodStr = passwordHashPeriodStr;
204+
}
205+
public String getMaxLoginAttemptPeriodStr() {
206+
return maxLoginAttemptPeriodStr;
207+
}
208+
public void setMaxLoginAttemptPeriodStr(String maxLoginAttemptPeriodStr) {
209+
this.maxLoginAttemptPeriodStr = maxLoginAttemptPeriodStr;
210+
}
211+
public String getMaxPasswordAgePeriodStr() {
212+
return maxPasswordAgePeriodStr;
213+
}
214+
public void setMaxPasswordAgePeriodStr(String maxPasswordAgePeriodStr) {
215+
this.maxPasswordAgePeriodStr = maxPasswordAgePeriodStr;
199216
}
200217
public Period getPasswordHashPeriod() {
201-
return Period.parse(passwordHashPeriod);
218+
return null != this.passwordHashPeriodStr ? Period.parse(this.passwordHashPeriodStr) : null;
219+
}
220+
public Period getMaxLoginAttemptPeriod() {
221+
return null != this.maxLoginAttemptPeriodStr ? Period.parse(this.maxLoginAttemptPeriodStr) : null;
222+
}
223+
public Period getMaxPasswordAgePeriod() {
224+
return null != this.maxPasswordAgePeriodStr ? Period.parse(this.maxPasswordAgePeriodStr) : null;
202225
}
203-
204226
@Override
205227
public String toString() {
206228
StringBuilder builder = new StringBuilder();
@@ -209,7 +231,9 @@ public String toString() {
209231
.append(", lastName=").append(lastName).append(", email=").append(email).append(", phone=")
210232
.append(phone).append(", directPasswordChangeAllowed=").append(directPasswordChangeAllowed)
211233
.append(", directPasswordChangeInProfileAllowed=").append(directPasswordChangeInProfileAllowed)
212-
.append(", passwordHashPeriod=").append(passwordHashPeriod).append("]");
234+
.append(", passwordHashPeriodStr=").append(passwordHashPeriodStr)
235+
.append(", maxLoginAttemptPeriodStr=").append(maxLoginAttemptPeriodStr)
236+
.append(", maxPasswordAgePeriodStr=").append(maxPasswordAgePeriodStr).append("]");
213237
return builder.toString();
214238
}
215239
}
@@ -329,7 +353,7 @@ public static class Validations {
329353
private Pattern pattern;
330354

331355
@PostConstruct
332-
private void init() {
356+
public void init() {
333357
if(minLength > 0 && minLength > maxLength) {
334358
throw new IllegalArgumentException("The minLength of validation config should be smaller than or equals to maxLegth!");
335359
}

admin-tools-security/admin-tools-security-dbuser/src/main/java/de/chandre/admintool/security/dbuser/domain/ATUser.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,10 @@ public Locale getLocaleAsLocale() {
244244
}
245245

246246
public void setLocale(Locale locale) {
247-
this.locale = locale.toString();
247+
if (null != locale) {
248+
this.locale = locale.toString();
249+
}
250+
locale = null;
248251
}
249252

250253
public void setLocale(String locale) {
@@ -266,7 +269,10 @@ public void setTimeZone(String timeZone) {
266269
}
267270

268271
public void setTimeZone(TimeZone timeZone) {
269-
this.timeZone = timeZone.getID();
272+
if (null != timeZone) {
273+
this.timeZone = timeZone.getID();
274+
}
275+
this.timeZone = null;
270276
}
271277

272278
public void setTimeZone(ZoneId zoneId) {

admin-tools-security/admin-tools-security-dbuser/src/main/java/de/chandre/admintool/security/dbuser/service/AdminToolSecDBRoleServiceImpl.java

+17-5
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,10 @@ public Set<ATError> updateRole(AccessRelationTO accessRelationTO) {
112112
ATRole role = getRole(StringUtils.trimToNull(accessRelationTO.getName()));
113113
if (null == role) {
114114
errors = new HashSet<>();
115-
errors.add(new ATError(Constants.MSG_KEY_PREFIX + "role.notFound",
116-
validator.getMessageWithSuffix("notFound", null, "No user foud"), "name"));
115+
errors.add(new ATError(Constants.MSG_KEY_PREFIX + "role.notFound",
116+
validator.getMessageWithSuffix("notFound", new Object[] { accessRelationTO.getName() },
117+
"No role found with name: " + accessRelationTO.getName()),
118+
"name"));
117119
return errors;
118120
}
119121
if (LOGGER.isDebugEnabled()) {
@@ -130,8 +132,10 @@ public Set<ATError> updateRole(AccessRelationTO accessRelationTO) {
130132
saveRole(role);
131133
} catch (Exception e) {
132134
LOGGER.debug(e.getMessage(), e);
133-
errors.add(new ATError(Constants.MSG_KEY_PREFIX + "role.save",
134-
validator.getMessageWithSuffix("save", null, "Exception during save"), "generic"));
135+
errors.add(new ATError(Constants.MSG_KEY_PREFIX + "role.save",
136+
validator.getMessageWithSuffix("save", new Object[] { accessRelationTO.getName() },
137+
"Exception saving role: " + accessRelationTO.getName()),
138+
"generic"));
135139
}
136140

137141
}
@@ -144,7 +148,15 @@ public Set<ATError> addRole(String name, String displayName, String description,
144148
role.setDisplayName(displayName);
145149
role.setDescription(description);
146150
role.setActive(active);
147-
return addRole(role);
151+
try {
152+
return addRole(role);
153+
} catch (Exception e) {
154+
LOGGER.debug(e.getMessage(), e);
155+
Set<ATError> errors = new HashSet<>();
156+
errors.add(new ATError(Constants.MSG_KEY_PREFIX + "role.save",
157+
validator.getMessageWithSuffix("save", new Object[] {name}, "Exception saving role: " +name), "generic"));
158+
return errors;
159+
}
148160
}
149161

150162
public Set<ATError> addRole(ATRole role) {

admin-tools-security/admin-tools-security-dbuser/src/main/java/de/chandre/admintool/security/dbuser/service/AdminToolSecDBUserDetailsService.java

+15
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import de.chandre.admintool.core.ui.ATError;
77
import de.chandre.admintool.security.commons.auth.AdminToolUserDetailsService;
88
import de.chandre.admintool.security.commons.auth.UserTO;
9+
import de.chandre.admintool.security.dbuser.AdminToolSecDBProperties;
10+
import de.chandre.admintool.security.dbuser.AdminToolSecDBProperties.Users;
911
import de.chandre.admintool.security.dbuser.Constants.CommunicationProcess;
1012
import de.chandre.admintool.security.dbuser.domain.ATUser;
1113
import de.chandre.admintool.security.dbuser.service.comm.SendException;
@@ -84,6 +86,19 @@ public interface AdminToolSecDBUserDetailsService extends AdminToolUserDetailsSe
8486
*/
8587
void resetPassword(String username, String password);
8688

89+
/**
90+
* returns all users assigned to userGroupName
91+
* @param userGroupId
92+
* @return
93+
*/
8794
List<ATUser> getUsersByUserGroupName(String userGroupId);
8895

96+
/**
97+
* checks if last password change ins older than now minus {@link Users#getPasswordHashPeriod()}.
98+
* set credentials expired to user if check results in true
99+
* @param user
100+
* @return
101+
*/
102+
ATUser checkIfPasswordExpired(ATUser user);
103+
89104
}

0 commit comments

Comments
 (0)