[Major] Added user history to privilege
- firstLogin - lastLogin - lastPasswordChange
This commit is contained in:
parent
2ea91eb5d3
commit
fd7362b2c1
|
@ -13,6 +13,7 @@ import li.strolch.privilege.base.AccessDeniedException;
|
|||
import li.strolch.privilege.base.InvalidCredentialsException;
|
||||
import li.strolch.privilege.model.UserState;
|
||||
import li.strolch.privilege.model.internal.User;
|
||||
import li.strolch.privilege.model.internal.UserHistory;
|
||||
import li.strolch.privilege.policy.PrivilegePolicy;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -139,7 +140,7 @@ public abstract class BaseLdapPrivilegeHandler extends DefaultPrivilegeHandler {
|
|||
Map<String, String> properties = buildProperties(username, attrs, ldapGroups, strolchRoles);
|
||||
|
||||
return new User(username, username, null, null, null, -1, -1, firstName, lastName, UserState.REMOTE,
|
||||
strolchRoles, locale, properties);
|
||||
strolchRoles, locale, properties, new UserHistory());
|
||||
}
|
||||
|
||||
protected abstract Map<String, String> buildProperties(String username, Attributes attrs, Set<String> ldapGroups,
|
||||
|
|
|
@ -21,7 +21,7 @@ import java.io.InputStream;
|
|||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.text.MessageFormat;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -29,10 +29,7 @@ import java.util.stream.Stream;
|
|||
|
||||
import li.strolch.privilege.base.*;
|
||||
import li.strolch.privilege.model.*;
|
||||
import li.strolch.privilege.model.internal.PrivilegeImpl;
|
||||
import li.strolch.privilege.model.internal.Role;
|
||||
import li.strolch.privilege.model.internal.User;
|
||||
import li.strolch.privilege.model.internal.UserChallenge;
|
||||
import li.strolch.privilege.model.internal.*;
|
||||
import li.strolch.privilege.policy.PrivilegePolicy;
|
||||
import li.strolch.privilege.xml.CertificateStubsDomWriter;
|
||||
import li.strolch.privilege.xml.CertificateStubsSaxReader;
|
||||
|
@ -396,6 +393,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
throw new PrivilegeModelException(MessageFormat.format(msg, userRep.getUsername()));
|
||||
}
|
||||
|
||||
UserHistory history = new UserHistory();
|
||||
byte[] passwordHash = null;
|
||||
byte[] salt = null;
|
||||
if (password != null) {
|
||||
|
@ -408,10 +406,12 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
|
||||
// hash password
|
||||
passwordHash = this.encryptionHandler.hashPassword(password, salt);
|
||||
|
||||
history.setLastPasswordChange(ZonedDateTime.now());
|
||||
}
|
||||
|
||||
// create new user
|
||||
User newUser = createUser(userRep, passwordHash, salt);
|
||||
User newUser = createUser(userRep, history, passwordHash, salt);
|
||||
|
||||
// detect privilege conflicts
|
||||
assertNoPrivilegeConflict(newUser);
|
||||
|
@ -458,6 +458,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
throw new PrivilegeModelException(MessageFormat.format(msg, userRep.getUsername()));
|
||||
}
|
||||
|
||||
UserHistory history = existingUser.getHistory().getClone();
|
||||
byte[] passwordHash = null;
|
||||
byte[] salt = null;
|
||||
if (password != null) {
|
||||
|
@ -470,9 +471,11 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
|
||||
// hash password
|
||||
passwordHash = this.encryptionHandler.hashPassword(password, salt);
|
||||
|
||||
history.setLastPasswordChange(ZonedDateTime.now());
|
||||
}
|
||||
|
||||
User newUser = createUser(userRep, passwordHash, salt);
|
||||
User newUser = createUser(userRep, history, passwordHash, salt);
|
||||
|
||||
// detect privilege conflicts
|
||||
assertNoPrivilegeConflict(newUser);
|
||||
|
@ -503,7 +506,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
}
|
||||
}
|
||||
|
||||
private User createUser(UserRep userRep, byte[] passwordHash, byte[] salt) {
|
||||
private User createUser(UserRep userRep, UserHistory history, byte[] passwordHash, byte[] salt) {
|
||||
String userId = userRep.getUserId();
|
||||
String userName = userRep.getUsername();
|
||||
String firstName = userRep.getFirstname();
|
||||
|
@ -514,7 +517,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
Map<String, String> properties = userRep.getProperties();
|
||||
return new User(userId, userName, passwordHash, salt, this.encryptionHandler.getAlgorithm(),
|
||||
this.encryptionHandler.getIterations(), this.encryptionHandler.getKeyLength(), firstName, lastName,
|
||||
state, roles, locale, properties);
|
||||
state, roles, locale, properties, history);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -573,7 +576,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
|
||||
// create new user
|
||||
User newUser = new User(userId, username, password, salt, hashAlgorithm, hashIterations, hashKeyLength,
|
||||
firstName, lastName, userState, roles, locale, propertyMap);
|
||||
firstName, lastName, userState, roles, locale, propertyMap, existingUser.getHistory().getClone());
|
||||
|
||||
// detect privilege conflicts
|
||||
assertNoPrivilegeConflict(newUser);
|
||||
|
@ -654,7 +657,8 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
User newUser = new User(existingUser.getUserId(), existingUser.getUsername(), existingUser.getPassword(),
|
||||
existingUser.getSalt(), existingUser.getHashAlgorithm(), existingUser.getHashIterations(),
|
||||
existingUser.getHashKeyLength(), existingUser.getFirstname(), existingUser.getLastname(),
|
||||
existingUser.getUserState(), newRoles, existingUser.getLocale(), existingUser.getProperties());
|
||||
existingUser.getUserState(), newRoles, existingUser.getLocale(), existingUser.getProperties(),
|
||||
existingUser.getHistory().getClone());
|
||||
|
||||
// detect privilege conflicts
|
||||
assertNoPrivilegeConflict(newUser);
|
||||
|
@ -701,7 +705,8 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
User newUser = new User(existingUser.getUserId(), existingUser.getUsername(), existingUser.getPassword(),
|
||||
existingUser.getSalt(), existingUser.getHashAlgorithm(), existingUser.getHashIterations(),
|
||||
existingUser.getHashKeyLength(), existingUser.getFirstname(), existingUser.getLastname(),
|
||||
existingUser.getUserState(), newRoles, existingUser.getLocale(), existingUser.getProperties());
|
||||
existingUser.getUserState(), newRoles, existingUser.getLocale(), existingUser.getProperties(),
|
||||
existingUser.getHistory().getClone());
|
||||
|
||||
// delegate user replacement to persistence handler
|
||||
this.persistenceHandler.replaceUser(newUser);
|
||||
|
@ -731,7 +736,8 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
User newUser = new User(existingUser.getUserId(), existingUser.getUsername(), existingUser.getPassword(),
|
||||
existingUser.getSalt(), existingUser.getHashAlgorithm(), existingUser.getHashIterations(),
|
||||
existingUser.getHashKeyLength(), existingUser.getFirstname(), existingUser.getLastname(),
|
||||
existingUser.getUserState(), existingUser.getRoles(), locale, existingUser.getProperties());
|
||||
existingUser.getUserState(), existingUser.getRoles(), locale, existingUser.getProperties(),
|
||||
existingUser.getHistory().getClone());
|
||||
|
||||
// if the user is not setting their own locale, then make sure this user may set this user's locale
|
||||
if (!certificate.getUsername().equals(username)) {
|
||||
|
@ -766,6 +772,8 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
MessageFormat.format("User {0} does not exist!", username)); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
UserHistory history = existingUser.getHistory().getClone();
|
||||
|
||||
byte[] passwordHash = null;
|
||||
byte[] salt = null;
|
||||
if (password != null) {
|
||||
|
@ -778,6 +786,8 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
|
||||
// hash password
|
||||
passwordHash = this.encryptionHandler.hashPassword(password, salt);
|
||||
|
||||
history.setLastPasswordChange(ZonedDateTime.now());
|
||||
}
|
||||
|
||||
// create new user
|
||||
|
@ -785,7 +795,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
this.encryptionHandler.getAlgorithm(), this.encryptionHandler.getIterations(),
|
||||
this.encryptionHandler.getKeyLength(), existingUser.getFirstname(), existingUser.getLastname(),
|
||||
existingUser.getUserState(), existingUser.getRoles(), existingUser.getLocale(),
|
||||
existingUser.getProperties());
|
||||
existingUser.getProperties(), history);
|
||||
|
||||
if (!certificate.getUsername().equals(username)) {
|
||||
// check that the user may change their own password
|
||||
|
@ -821,15 +831,15 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
|
||||
// get User
|
||||
User existingUser = this.persistenceHandler.getUser(username);
|
||||
if (existingUser == null) {
|
||||
if (existingUser == null)
|
||||
throw new PrivilegeModelException(MessageFormat.format("User {0} does not exist!", username)); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
// create new user
|
||||
User newUser = new User(existingUser.getUserId(), existingUser.getUsername(), existingUser.getPassword(),
|
||||
existingUser.getSalt(), existingUser.getHashAlgorithm(), existingUser.getHashIterations(),
|
||||
existingUser.getHashKeyLength(), existingUser.getFirstname(), existingUser.getLastname(), state,
|
||||
existingUser.getRoles(), existingUser.getLocale(), existingUser.getProperties());
|
||||
existingUser.getRoles(), existingUser.getLocale(), existingUser.getProperties(),
|
||||
existingUser.getHistory().getClone());
|
||||
|
||||
// validate that this user may modify this user's state
|
||||
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_SET_USER_STATE, new Tuple(existingUser, newUser)));
|
||||
|
@ -1159,7 +1169,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
// create a new certificate, with details of the user
|
||||
Usage usage = userChallenge.getUsage();
|
||||
Certificate certificate = buildCertificate(usage, user, authToken, sessionId, userChallenge.getSource(),
|
||||
LocalDateTime.now(), false);
|
||||
ZonedDateTime.now(), false);
|
||||
|
||||
PrivilegeContext privilegeContext = buildPrivilegeContext(certificate, user);
|
||||
this.privilegeContextMap.put(sessionId, privilegeContext);
|
||||
|
@ -1197,10 +1207,9 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
|
||||
// validate user has at least one role
|
||||
Set<String> userRoles = user.getRoles();
|
||||
if (userRoles.isEmpty()) {
|
||||
if (userRoles.isEmpty())
|
||||
throw new InvalidCredentialsException(
|
||||
MessageFormat.format("User {0} does not have any roles defined!", username)); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
// get 2 auth tokens
|
||||
String authToken = this.encryptionHandler.nextToken();
|
||||
|
@ -1209,7 +1218,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
String sessionId = UUID.randomUUID().toString();
|
||||
|
||||
// create a new certificate, with details of the user
|
||||
Certificate certificate = buildCertificate(usage, user, authToken, sessionId, source, LocalDateTime.now(),
|
||||
Certificate certificate = buildCertificate(usage, user, authToken, sessionId, source, ZonedDateTime.now(),
|
||||
keepAlive);
|
||||
|
||||
PrivilegeContext privilegeContext = buildPrivilegeContext(certificate, user);
|
||||
|
@ -1217,6 +1226,14 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
|
||||
persistSessions();
|
||||
|
||||
// save last login
|
||||
if (user.getHistory().isFirstLoginEmpty())
|
||||
user.getHistory().setFirstLogin(ZonedDateTime.now());
|
||||
user.getHistory().setLastLogin(ZonedDateTime.now());
|
||||
this.persistenceHandler.replaceUser(user);
|
||||
if (this.autoPersistOnUserChangesData)
|
||||
this.persistenceHandler.persist();
|
||||
|
||||
// log
|
||||
logger.info(MessageFormat.format("User {0} authenticated: {1}", username, certificate)); //$NON-NLS-1$
|
||||
|
||||
|
@ -1249,13 +1266,17 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
|
||||
User user = this.ssoHandler.authenticateSingleSignOn(data);
|
||||
DBC.PRE.assertEquals("SSO Users must have UserState.REMOTE!", UserState.REMOTE, user.getUserState());
|
||||
user.getHistory().setLastLogin(ZonedDateTime.now());
|
||||
|
||||
// persist this user
|
||||
User internalUser = this.persistenceHandler.getUser(user.getUsername());
|
||||
if (internalUser == null)
|
||||
if (internalUser == null) {
|
||||
user.getHistory().setFirstLogin(ZonedDateTime.now());
|
||||
this.persistenceHandler.addUser(user);
|
||||
else
|
||||
} else {
|
||||
user.getHistory().setFirstLogin(internalUser.getHistory().getFirstLogin());
|
||||
this.persistenceHandler.replaceUser(user);
|
||||
}
|
||||
|
||||
if (this.autoPersistOnUserChangesData)
|
||||
this.persistenceHandler.persist();
|
||||
|
@ -1267,7 +1288,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
String sessionId = UUID.randomUUID().toString();
|
||||
|
||||
// create a new certificate, with details of the user
|
||||
Certificate certificate = buildCertificate(Usage.ANY, user, authToken, sessionId, source, LocalDateTime.now(),
|
||||
Certificate certificate = buildCertificate(Usage.ANY, user, authToken, sessionId, source, ZonedDateTime.now(),
|
||||
keepAlive);
|
||||
|
||||
PrivilegeContext privilegeContext = buildPrivilegeContext(certificate, user);
|
||||
|
@ -1311,7 +1332,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
|
||||
// create a new certificate, with details of the user
|
||||
Certificate refreshedCert = buildCertificate(certificate.getUsage(), user, authToken, sessionId, source,
|
||||
LocalDateTime.now(), true);
|
||||
ZonedDateTime.now(), true);
|
||||
|
||||
PrivilegeContext privilegeContext = buildPrivilegeContext(refreshedCert, user);
|
||||
this.privilegeContextMap.put(sessionId, privilegeContext);
|
||||
|
@ -1339,7 +1360,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
}
|
||||
|
||||
private Certificate buildCertificate(Usage usage, User user, String authToken, String sessionId, String source,
|
||||
LocalDateTime loginTime, boolean keepAlive) {
|
||||
ZonedDateTime loginTime, boolean keepAlive) {
|
||||
DBC.PRE.assertNotEmpty("source must not be empty!", source);
|
||||
Set<String> userRoles = user.getRoles();
|
||||
return new Certificate(usage, sessionId, user.getUsername(), user.getFirstname(), user.getLastname(),
|
||||
|
@ -1527,7 +1548,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
User newUser = new User(user.getUserId(), user.getUsername(), passwordHash, salt,
|
||||
this.encryptionHandler.getAlgorithm(), this.encryptionHandler.getIterations(),
|
||||
this.encryptionHandler.getKeyLength(), user.getFirstname(), user.getLastname(), user.getUserState(),
|
||||
user.getRoles(), user.getLocale(), user.getProperties());
|
||||
user.getRoles(), user.getLocale(), user.getProperties(), user.getHistory().getClone());
|
||||
|
||||
// delegate user replacement to persistence handler
|
||||
this.persistenceHandler.replaceUser(newUser);
|
||||
|
@ -1685,7 +1706,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
throw new PrivilegeException(msg);
|
||||
}
|
||||
|
||||
certificate.setLastAccess(LocalDateTime.now());
|
||||
certificate.setLastAccess(ZonedDateTime.now());
|
||||
|
||||
if (!certificate.getSource().equals(this.identifier))
|
||||
throw new IllegalStateException(
|
||||
|
@ -1717,14 +1738,14 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
|
||||
// validate that challenge certificate is not expired (1 hour only)
|
||||
if (sessionCertificate.getUsage() != Usage.ANY) {
|
||||
LocalDateTime dateTime = sessionCertificate.getLoginTime();
|
||||
if (dateTime.plusHours(1).isBefore(LocalDateTime.now())) {
|
||||
ZonedDateTime dateTime = sessionCertificate.getLoginTime();
|
||||
if (dateTime.plusHours(1).isBefore(ZonedDateTime.now())) {
|
||||
invalidate(sessionCertificate);
|
||||
throw new NotAuthenticatedException("Certificate has already expired!"); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
certificate.setLastAccess(LocalDateTime.now());
|
||||
certificate.setLastAccess(ZonedDateTime.now());
|
||||
|
||||
// TODO decide if we want to assert source did not change!
|
||||
// if (!source.equals(SOURCE_UNKNOWN) && !certificate.getSource().equals(source)) {
|
||||
|
@ -2150,7 +2171,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
|||
|
||||
// create a new certificate, with details of the user
|
||||
Certificate systemUserCertificate = buildCertificate(Usage.ANY, user, authToken, sessionId, this.identifier,
|
||||
LocalDateTime.now(), false);
|
||||
ZonedDateTime.now(), false);
|
||||
|
||||
// create and save a new privilege context
|
||||
PrivilegeContext privilegeContext = buildPrivilegeContext(systemUserCertificate, user);
|
||||
|
|
|
@ -108,6 +108,26 @@ public class XmlConstants {
|
|||
*/
|
||||
public static final String XML_USER = "User";
|
||||
|
||||
/**
|
||||
* XML_USER = "User"
|
||||
*/
|
||||
public static final String XML_HISTORY = "History";
|
||||
|
||||
/**
|
||||
* XML_USER = "User"
|
||||
*/
|
||||
public static final String XML_FIRST_LOGIN = "FirstLogin";
|
||||
|
||||
/**
|
||||
* XML_USER = "User"
|
||||
*/
|
||||
public static final String XML_LAST_LOGIN = "LastLogin";
|
||||
|
||||
/**
|
||||
* XML_USER = "User"
|
||||
*/
|
||||
public static final String XML_LAST_PASSWORD_CHANGE = "LastPasswordChange";
|
||||
|
||||
/**
|
||||
* XML_PRIVILEGE = "Privilege" :
|
||||
*/
|
||||
|
|
|
@ -18,7 +18,7 @@ package li.strolch.privilege.model;
|
|||
import static li.strolch.privilege.base.PrivilegeConstants.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
@ -47,14 +47,14 @@ public final class Certificate implements Serializable {
|
|||
private final UserState userState;
|
||||
private final String authToken;
|
||||
private final String source;
|
||||
private final LocalDateTime loginTime;
|
||||
private final ZonedDateTime loginTime;
|
||||
private final boolean keepAlive;
|
||||
|
||||
private final Set<String> userRoles;
|
||||
private final Map<String, String> propertyMap;
|
||||
|
||||
private Locale locale;
|
||||
private LocalDateTime lastAccess;
|
||||
private ZonedDateTime lastAccess;
|
||||
|
||||
/**
|
||||
* Default constructor initializing with all information needed for this certificate
|
||||
|
@ -85,7 +85,7 @@ public final class Certificate implements Serializable {
|
|||
* edited and can be used for the user to change settings of this session
|
||||
*/
|
||||
public Certificate(Usage usage, String sessionId, String username, String firstName, String lastName,
|
||||
UserState userState, String authToken, String source, LocalDateTime loginTime, boolean keepAlive,
|
||||
UserState userState, String authToken, String source, ZonedDateTime loginTime, boolean keepAlive,
|
||||
Locale locale, Set<String> userRoles, Map<String, String> propertyMap) {
|
||||
|
||||
// validate arguments are not null
|
||||
|
@ -131,7 +131,7 @@ public final class Certificate implements Serializable {
|
|||
this.propertyMap = Collections.unmodifiableMap(propertyMap);
|
||||
|
||||
this.userRoles = Collections.unmodifiableSet(userRoles);
|
||||
this.lastAccess = LocalDateTime.now();
|
||||
this.lastAccess = ZonedDateTime.now();
|
||||
}
|
||||
|
||||
public Usage getUsage() {
|
||||
|
@ -239,7 +239,7 @@ public final class Certificate implements Serializable {
|
|||
return userState;
|
||||
}
|
||||
|
||||
public LocalDateTime getLoginTime() {
|
||||
public ZonedDateTime getLoginTime() {
|
||||
return this.loginTime;
|
||||
}
|
||||
|
||||
|
@ -255,11 +255,11 @@ public final class Certificate implements Serializable {
|
|||
return this.source;
|
||||
}
|
||||
|
||||
public LocalDateTime getLastAccess() {
|
||||
public ZonedDateTime getLastAccess() {
|
||||
return this.lastAccess;
|
||||
}
|
||||
|
||||
public void setLastAccess(LocalDateTime lastAccess) {
|
||||
public void setLastAccess(ZonedDateTime lastAccess) {
|
||||
this.lastAccess = lastAccess;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,14 +50,14 @@ public final class User {
|
|||
private final String firstname;
|
||||
private final String lastname;
|
||||
|
||||
private final UserState userState;
|
||||
|
||||
private final Set<String> roles;
|
||||
|
||||
private final UserState userState;
|
||||
private final Map<String, String> propertyMap;
|
||||
|
||||
private final Locale locale;
|
||||
|
||||
private final UserHistory history;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
|
@ -90,26 +90,24 @@ public final class User {
|
|||
*/
|
||||
public User(String userId, String username, byte[] password, byte[] salt, String hashAlgorithm, int hashIterations,
|
||||
int hashKeyLength, String firstname, String lastname, UserState userState, Set<String> roles, Locale locale,
|
||||
Map<String, String> propertyMap) {
|
||||
Map<String, String> propertyMap, UserHistory history) {
|
||||
|
||||
if (StringHelper.isEmpty(userId)) {
|
||||
if (StringHelper.isEmpty(userId))
|
||||
throw new PrivilegeException("No UserId defined!"); //$NON-NLS-1$
|
||||
}
|
||||
if (userState == null) {
|
||||
if (userState == null)
|
||||
throw new PrivilegeException("No userState defined!"); //$NON-NLS-1$
|
||||
}
|
||||
if (StringHelper.isEmpty(username)) {
|
||||
if (StringHelper.isEmpty(username))
|
||||
throw new PrivilegeException("No username defined!"); //$NON-NLS-1$
|
||||
}
|
||||
if (userState != UserState.SYSTEM) {
|
||||
if (StringHelper.isEmpty(lastname)) {
|
||||
if (StringHelper.isEmpty(lastname))
|
||||
throw new PrivilegeException("No lastname defined!"); //$NON-NLS-1$
|
||||
}
|
||||
if (StringHelper.isEmpty(firstname)) {
|
||||
if (StringHelper.isEmpty(firstname))
|
||||
throw new PrivilegeException("No firstname defined!"); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
if (history == null)
|
||||
throw new PrivilegeException("History must not be null!");
|
||||
|
||||
// password, salt and hash* may be null, meaning not able to login
|
||||
// roles may be null, meaning not able to login and must be added later
|
||||
// locale may be null, meaning use system default
|
||||
|
@ -133,7 +131,7 @@ public final class User {
|
|||
if (roles == null)
|
||||
this.roles = Collections.emptySet();
|
||||
else
|
||||
this.roles = Collections.unmodifiableSet(new HashSet<>(roles));
|
||||
this.roles = Set.copyOf(roles);
|
||||
|
||||
if (locale == null)
|
||||
this.locale = Locale.getDefault();
|
||||
|
@ -143,7 +141,9 @@ public final class User {
|
|||
if (propertyMap == null)
|
||||
this.propertyMap = Collections.emptyMap();
|
||||
else
|
||||
this.propertyMap = Collections.unmodifiableMap(new HashMap<>(propertyMap));
|
||||
this.propertyMap = Map.copyOf(propertyMap);
|
||||
|
||||
this.history = history;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -252,6 +252,24 @@ public final class User {
|
|||
return this.locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the History object
|
||||
*
|
||||
* @return the History object
|
||||
*/
|
||||
public UserHistory getHistory() {
|
||||
return this.history;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the history for this user is empty
|
||||
*
|
||||
* @return true if the history for this user is empty
|
||||
*/
|
||||
public boolean isHistoryEmpty() {
|
||||
return this.history.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the property with the given key
|
||||
*
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
package li.strolch.privilege.model.internal;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
import li.strolch.utils.iso8601.ISO8601;
|
||||
|
||||
public class UserHistory {
|
||||
|
||||
private ZonedDateTime firstLogin;
|
||||
private ZonedDateTime lastLogin;
|
||||
private ZonedDateTime lastPasswordChange;
|
||||
|
||||
public UserHistory() {
|
||||
this.firstLogin = ISO8601.EMPTY_VALUE_ZONED_DATE;
|
||||
this.lastLogin = ISO8601.EMPTY_VALUE_ZONED_DATE;
|
||||
this.lastPasswordChange = ISO8601.EMPTY_VALUE_ZONED_DATE;
|
||||
}
|
||||
|
||||
public ZonedDateTime getFirstLogin() {
|
||||
return this.firstLogin;
|
||||
}
|
||||
|
||||
public boolean isFirstLoginEmpty() {
|
||||
return this.firstLogin.equals(ISO8601.EMPTY_VALUE_ZONED_DATE);
|
||||
}
|
||||
|
||||
public void setFirstLogin(ZonedDateTime firstLogin) {
|
||||
this.firstLogin = firstLogin;
|
||||
}
|
||||
|
||||
public ZonedDateTime getLastLogin() {
|
||||
return this.lastLogin;
|
||||
}
|
||||
|
||||
public boolean isLastLoginEmpty() {
|
||||
return this.lastLogin.equals(ISO8601.EMPTY_VALUE_ZONED_DATE);
|
||||
}
|
||||
|
||||
public void setLastLogin(ZonedDateTime lastLogin) {
|
||||
this.lastLogin = lastLogin;
|
||||
}
|
||||
|
||||
public ZonedDateTime getLastPasswordChange() {
|
||||
return this.lastPasswordChange;
|
||||
}
|
||||
|
||||
public boolean isLastPasswordChangeEmpty() {
|
||||
return this.lastPasswordChange.equals(ISO8601.EMPTY_VALUE_ZONED_DATE);
|
||||
}
|
||||
|
||||
public void setLastPasswordChange(ZonedDateTime lastPasswordChange) {
|
||||
this.lastPasswordChange = lastPasswordChange;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return isFirstLoginEmpty() && isLastLoginEmpty() && isLastPasswordChangeEmpty();
|
||||
}
|
||||
|
||||
public UserHistory getClone() {
|
||||
UserHistory clone = new UserHistory();
|
||||
clone.firstLogin = this.firstLogin;
|
||||
clone.lastLogin = this.lastLogin;
|
||||
clone.lastPasswordChange = this.lastPasswordChange;
|
||||
return clone;
|
||||
}
|
||||
}
|
|
@ -20,7 +20,7 @@ import static li.strolch.privilege.helper.XmlConstants.*;
|
|||
import static li.strolch.utils.helper.StringHelper.isEmpty;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
@ -67,8 +67,8 @@ public class CertificateStubsSaxReader extends DefaultHandler {
|
|||
stub.authToken = attributes.getValue(XML_ATTR_AUTH_TOKEN);
|
||||
stub.source = attributes.getValue(XML_ATTR_SOURCE);
|
||||
stub.locale = Locale.forLanguageTag(attributes.getValue(XML_ATTR_LOCALE));
|
||||
stub.loginTime = ISO8601.parseToZdt(attributes.getValue(XML_ATTR_LOGIN_TIME)).toLocalDateTime();
|
||||
stub.lastAccess = ISO8601.parseToZdt(attributes.getValue(XML_ATTR_LAST_ACCESS)).toLocalDateTime();
|
||||
stub.loginTime = ISO8601.parseToZdt(attributes.getValue(XML_ATTR_LOGIN_TIME));
|
||||
stub.lastAccess = ISO8601.parseToZdt(attributes.getValue(XML_ATTR_LAST_ACCESS));
|
||||
stub.keepAlive = Boolean.parseBoolean(attributes.getValue(XML_ATTR_KEEP_ALIVE));
|
||||
|
||||
DBC.INTERIM.assertNotEmpty("sessionId missing on sessions data!", stub.sessionId);
|
||||
|
@ -93,8 +93,8 @@ public class CertificateStubsSaxReader extends DefaultHandler {
|
|||
private String authToken;
|
||||
private String source;
|
||||
private Locale locale;
|
||||
private LocalDateTime loginTime;
|
||||
private LocalDateTime lastAccess;
|
||||
private ZonedDateTime loginTime;
|
||||
private ZonedDateTime lastAccess;
|
||||
private boolean keepAlive;
|
||||
|
||||
public Usage getUsage() {
|
||||
|
@ -121,11 +121,11 @@ public class CertificateStubsSaxReader extends DefaultHandler {
|
|||
return locale;
|
||||
}
|
||||
|
||||
public LocalDateTime getLoginTime() {
|
||||
public ZonedDateTime getLoginTime() {
|
||||
return loginTime;
|
||||
}
|
||||
|
||||
public LocalDateTime getLastAccess() {
|
||||
public ZonedDateTime getLastAccess() {
|
||||
return lastAccess;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,16 +16,18 @@
|
|||
package li.strolch.privilege.xml;
|
||||
|
||||
import static java.util.Comparator.comparing;
|
||||
import static li.strolch.privilege.helper.CryptHelper.buildPasswordString;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import li.strolch.privilege.helper.CryptHelper;
|
||||
import li.strolch.privilege.helper.XmlConstants;
|
||||
import li.strolch.privilege.model.internal.User;
|
||||
import li.strolch.privilege.model.internal.UserHistory;
|
||||
import li.strolch.utils.helper.StringHelper;
|
||||
import li.strolch.utils.helper.XmlHelper;
|
||||
import li.strolch.utils.iso8601.ISO8601;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
|
@ -34,8 +36,8 @@ import org.w3c.dom.Element;
|
|||
*/
|
||||
public class PrivilegeUsersDomWriter {
|
||||
|
||||
private List<User> users;
|
||||
private File modelFile;
|
||||
private final List<User> users;
|
||||
private final File modelFile;
|
||||
|
||||
public PrivilegeUsersDomWriter(List<User> users, File modelFile) {
|
||||
this.users = users;
|
||||
|
@ -98,13 +100,37 @@ public class PrivilegeUsersDomWriter {
|
|||
if (!user.getProperties().isEmpty()) {
|
||||
Element parametersElement = doc.createElement(XmlConstants.XML_PROPERTIES);
|
||||
userElement.appendChild(parametersElement);
|
||||
user.getProperties().entrySet().stream().sorted(comparing(Map.Entry::getKey)).forEach(entry -> {
|
||||
user.getProperties().entrySet().stream().sorted(Map.Entry.comparingByKey()).forEach(entry -> {
|
||||
Element paramElement = doc.createElement(XmlConstants.XML_PROPERTY);
|
||||
paramElement.setAttribute(XmlConstants.XML_ATTR_NAME, entry.getKey());
|
||||
paramElement.setAttribute(XmlConstants.XML_ATTR_VALUE, entry.getValue());
|
||||
parametersElement.appendChild(paramElement);
|
||||
});
|
||||
}
|
||||
|
||||
if (!user.isHistoryEmpty()) {
|
||||
UserHistory history = user.getHistory();
|
||||
Element historyElement = doc.createElement(XmlConstants.XML_HISTORY);
|
||||
userElement.appendChild(historyElement);
|
||||
|
||||
if (!history.isFirstLoginEmpty()) {
|
||||
Element element = doc.createElement(XmlConstants.XML_FIRST_LOGIN);
|
||||
element.setTextContent(ISO8601.toString(history.getFirstLogin()));
|
||||
historyElement.appendChild(element);
|
||||
}
|
||||
|
||||
if (!history.isLastLoginEmpty()) {
|
||||
Element element = doc.createElement(XmlConstants.XML_LAST_LOGIN);
|
||||
element.setTextContent(ISO8601.toString(history.getLastLogin()));
|
||||
historyElement.appendChild(element);
|
||||
}
|
||||
|
||||
if (!history.isLastPasswordChangeEmpty()) {
|
||||
Element element = doc.createElement(XmlConstants.XML_LAST_PASSWORD_CHANGE);
|
||||
element.setTextContent(ISO8601.toString(history.getLastPasswordChange()));
|
||||
historyElement.appendChild(element);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// write the container file to disk
|
||||
|
@ -112,15 +138,10 @@ public class PrivilegeUsersDomWriter {
|
|||
}
|
||||
|
||||
private void writePassword(User user, Element userElement) {
|
||||
|
||||
if (user.getPassword() != null && user.getSalt() != null && user.getHashAlgorithm() != null
|
||||
&& user.getHashIterations() != -1 && user.getHashKeyLength() != -1) {
|
||||
|
||||
String passwordS = CryptHelper.buildPasswordString(user);
|
||||
userElement.setAttribute(XmlConstants.XML_ATTR_PASSWORD, passwordS);
|
||||
|
||||
userElement.setAttribute(XmlConstants.XML_ATTR_PASSWORD, buildPasswordString(user));
|
||||
} else {
|
||||
|
||||
if (user.getPassword() != null)
|
||||
userElement.setAttribute(XmlConstants.XML_ATTR_PASSWORD, StringHelper.toHexString(user.getPassword()));
|
||||
if (user.getSalt() != null)
|
||||
|
|
|
@ -15,13 +15,16 @@
|
|||
*/
|
||||
package li.strolch.privilege.xml;
|
||||
|
||||
import static li.strolch.privilege.helper.XmlConstants.*;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
|
||||
import li.strolch.privilege.helper.XmlConstants;
|
||||
import li.strolch.privilege.model.UserState;
|
||||
import li.strolch.privilege.model.internal.User;
|
||||
import li.strolch.privilege.model.internal.UserHistory;
|
||||
import li.strolch.utils.helper.StringHelper;
|
||||
import li.strolch.utils.iso8601.ISO8601;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.xml.sax.Attributes;
|
||||
|
@ -35,9 +38,9 @@ public class PrivilegeUsersSaxReader extends DefaultHandler {
|
|||
|
||||
protected static final Logger logger = LoggerFactory.getLogger(PrivilegeUsersSaxReader.class);
|
||||
|
||||
private Deque<ElementParser> buildersStack = new ArrayDeque<>();
|
||||
private final Deque<ElementParser> buildersStack = new ArrayDeque<>();
|
||||
|
||||
private List<User> users;
|
||||
private final List<User> users;
|
||||
|
||||
public PrivilegeUsersSaxReader() {
|
||||
this.users = new ArrayList<>();
|
||||
|
@ -52,9 +55,9 @@ public class PrivilegeUsersSaxReader extends DefaultHandler {
|
|||
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||
if (qName.equals(XmlConstants.XML_USER)) {
|
||||
if (qName.equals(XML_USER)) {
|
||||
this.buildersStack.push(new UserParser());
|
||||
} else if (qName.equals(XmlConstants.XML_PROPERTIES)) {
|
||||
} else if (qName.equals(XML_PROPERTIES)) {
|
||||
this.buildersStack.push(new PropertyParser());
|
||||
}
|
||||
|
||||
|
@ -75,9 +78,9 @@ public class PrivilegeUsersSaxReader extends DefaultHandler {
|
|||
this.buildersStack.peek().endElement(uri, localName, qName);
|
||||
|
||||
ElementParser elementParser = null;
|
||||
if (qName.equals(XmlConstants.XML_USER)) {
|
||||
if (qName.equals(XML_USER)) {
|
||||
elementParser = this.buildersStack.pop();
|
||||
} else if (qName.equals(XmlConstants.XML_PROPERTIES)) {
|
||||
} else if (qName.equals(XML_PROPERTIES)) {
|
||||
elementParser = this.buildersStack.pop();
|
||||
}
|
||||
|
||||
|
@ -98,6 +101,11 @@ public class PrivilegeUsersSaxReader extends DefaultHandler {
|
|||
// <Property name="organization" value="eitchnet.ch" />
|
||||
// <Property name="organizationalUnit" value="Development" />
|
||||
// </Properties>
|
||||
// <History>
|
||||
// <FirstLogin>2021-02-19T15:32:09.592+01:00</FirstLogin>
|
||||
// <LastLogin>2021-02-19T15:32:09.592+01:00</LastLogin>
|
||||
// <LastPasswordChange>2021-02-19T15:32:09.592+01:00</LastPasswordChange>
|
||||
// </History>
|
||||
// </User>
|
||||
|
||||
public class UserParser extends ElementParserAdapter {
|
||||
|
@ -117,6 +125,7 @@ public class PrivilegeUsersSaxReader extends DefaultHandler {
|
|||
Locale locale;
|
||||
Set<String> userRoles;
|
||||
Map<String, String> parameters;
|
||||
UserHistory history;
|
||||
|
||||
public UserParser() {
|
||||
this.userRoles = new HashSet<>();
|
||||
|
@ -128,13 +137,15 @@ public class PrivilegeUsersSaxReader extends DefaultHandler {
|
|||
|
||||
this.text = new StringBuilder();
|
||||
|
||||
if (qName.equals(XmlConstants.XML_USER)) {
|
||||
this.userId = attributes.getValue(XmlConstants.XML_ATTR_USER_ID);
|
||||
this.username = attributes.getValue(XmlConstants.XML_ATTR_USERNAME);
|
||||
if (qName.equals(XML_USER)) {
|
||||
this.userId = attributes.getValue(XML_ATTR_USER_ID);
|
||||
this.username = attributes.getValue(XML_ATTR_USERNAME);
|
||||
|
||||
String password = attributes.getValue(XmlConstants.XML_ATTR_PASSWORD);
|
||||
String salt = attributes.getValue(XmlConstants.XML_ATTR_SALT);
|
||||
String password = attributes.getValue(XML_ATTR_PASSWORD);
|
||||
String salt = attributes.getValue(XML_ATTR_SALT);
|
||||
parsePassword(password, salt);
|
||||
} else if (qName.equals(XML_HISTORY)) {
|
||||
this.history = new UserHistory();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,36 +194,54 @@ public class PrivilegeUsersSaxReader extends DefaultHandler {
|
|||
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||
|
||||
switch (qName) {
|
||||
case XmlConstants.XML_FIRSTNAME:
|
||||
case XML_FIRSTNAME:
|
||||
|
||||
this.firstName = this.text.toString().trim();
|
||||
break;
|
||||
|
||||
case XmlConstants.XML_LASTNAME:
|
||||
case XML_LASTNAME:
|
||||
|
||||
this.lastname = this.text.toString().trim();
|
||||
break;
|
||||
|
||||
case XmlConstants.XML_STATE:
|
||||
case XML_STATE:
|
||||
|
||||
this.userState = UserState.valueOf(this.text.toString().trim());
|
||||
break;
|
||||
|
||||
case XmlConstants.XML_LOCALE:
|
||||
case XML_LOCALE:
|
||||
|
||||
this.locale = Locale.forLanguageTag(this.text.toString().trim());
|
||||
break;
|
||||
|
||||
case XmlConstants.XML_ROLE:
|
||||
case XML_FIRST_LOGIN:
|
||||
|
||||
this.history.setFirstLogin(ISO8601.parseToZdt(this.text.toString().trim()));
|
||||
break;
|
||||
|
||||
case XML_LAST_LOGIN:
|
||||
|
||||
this.history.setLastLogin(ISO8601.parseToZdt(this.text.toString().trim()));
|
||||
break;
|
||||
|
||||
case XML_LAST_PASSWORD_CHANGE:
|
||||
|
||||
this.history.setLastPasswordChange(ISO8601.parseToZdt(this.text.toString().trim()));
|
||||
break;
|
||||
|
||||
case XML_ROLE:
|
||||
|
||||
this.userRoles.add(this.text.toString().trim());
|
||||
break;
|
||||
|
||||
case XmlConstants.XML_USER:
|
||||
case XML_USER:
|
||||
|
||||
if (this.history == null)
|
||||
this.history = new UserHistory();
|
||||
|
||||
User user = new User(this.userId, this.username, this.password, this.salt, this.hashAlgorithm,
|
||||
hashIterations, hashKeyLength, this.firstName, this.lastname, this.userState, this.userRoles,
|
||||
this.locale, this.parameters);
|
||||
this.locale, this.parameters, this.history);
|
||||
logger.info(MessageFormat.format("New User: {0}", user)); //$NON-NLS-1$
|
||||
|
||||
getUsers().add(user);
|
||||
|
@ -220,9 +249,10 @@ public class PrivilegeUsersSaxReader extends DefaultHandler {
|
|||
|
||||
default:
|
||||
|
||||
if (!(qName.equals(XmlConstants.XML_ROLES) //
|
||||
|| qName.equals(XmlConstants.XML_PARAMETER) //
|
||||
|| qName.equals(XmlConstants.XML_PARAMETERS))) {
|
||||
if (!(qName.equals(XML_ROLES) //
|
||||
|| qName.equals(XML_PARAMETER) //
|
||||
|| qName.equals(XML_HISTORY) //
|
||||
|| qName.equals(XML_PARAMETERS))) {
|
||||
throw new IllegalArgumentException("Unhandled tag " + qName);
|
||||
}
|
||||
|
||||
|
@ -238,7 +268,7 @@ public class PrivilegeUsersSaxReader extends DefaultHandler {
|
|||
}
|
||||
}
|
||||
|
||||
class PropertyParser extends ElementParserAdapter {
|
||||
static class PropertyParser extends ElementParserAdapter {
|
||||
|
||||
// <Property name="organizationalUnit" value="Development" />
|
||||
|
||||
|
@ -249,16 +279,16 @@ public class PrivilegeUsersSaxReader extends DefaultHandler {
|
|||
throws SAXException {
|
||||
|
||||
switch (qName) {
|
||||
case XmlConstants.XML_PROPERTY:
|
||||
case XML_PROPERTY:
|
||||
|
||||
String key = attributes.getValue(XmlConstants.XML_ATTR_NAME);
|
||||
String value = attributes.getValue(XmlConstants.XML_ATTR_VALUE);
|
||||
String key = attributes.getValue(XML_ATTR_NAME);
|
||||
String value = attributes.getValue(XML_ATTR_VALUE);
|
||||
this.parameterMap.put(key, value);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
if (!qName.equals(XmlConstants.XML_PROPERTIES)) {
|
||||
if (!qName.equals(XML_PROPERTIES)) {
|
||||
throw new IllegalArgumentException("Unhandled tag " + qName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,9 @@ import static org.hamcrest.Matchers.containsInAnyOrder;
|
|||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.*;
|
||||
|
||||
import li.strolch.privilege.handler.DefaultEncryptionHandler;
|
||||
|
@ -27,10 +30,7 @@ import li.strolch.privilege.handler.PrivilegeHandler;
|
|||
import li.strolch.privilege.handler.XmlPersistenceHandler;
|
||||
import li.strolch.privilege.model.IPrivilege;
|
||||
import li.strolch.privilege.model.UserState;
|
||||
import li.strolch.privilege.model.internal.PrivilegeContainerModel;
|
||||
import li.strolch.privilege.model.internal.PrivilegeImpl;
|
||||
import li.strolch.privilege.model.internal.Role;
|
||||
import li.strolch.privilege.model.internal.User;
|
||||
import li.strolch.privilege.model.internal.*;
|
||||
import li.strolch.privilege.test.model.DummySsoHandler;
|
||||
import li.strolch.privilege.xml.*;
|
||||
import li.strolch.utils.helper.FileHelper;
|
||||
|
@ -316,16 +316,21 @@ public class XmlTest {
|
|||
propertyMap.put("prop1", "value1");
|
||||
userRoles = new HashSet<>();
|
||||
userRoles.add("role1");
|
||||
UserHistory history = new UserHistory();
|
||||
history.setFirstLogin(ZonedDateTime.of(LocalDateTime.of(2020, 1, 2, 2, 3, 4, 5), ZoneId.systemDefault()));
|
||||
User user1 = new User("1", "user1", "blabla".getBytes(), "blabla".getBytes(), "PBKDF2WithHmacSHA512", 10000,
|
||||
256, "Bob", "White", UserState.DISABLED, userRoles, Locale.ENGLISH, propertyMap);
|
||||
256, "Bob", "White", UserState.DISABLED, userRoles, Locale.ENGLISH, propertyMap, history);
|
||||
users.add(user1);
|
||||
|
||||
propertyMap = new HashMap<>();
|
||||
propertyMap.put("prop2", "value2");
|
||||
userRoles = new HashSet<>();
|
||||
userRoles.add("role2");
|
||||
history = new UserHistory();
|
||||
history.setFirstLogin(ZonedDateTime.of(LocalDateTime.of(2020, 1, 2, 2, 3, 4, 5), ZoneId.systemDefault()));
|
||||
history.setLastLogin(ZonedDateTime.of(LocalDateTime.of(2020, 1, 5, 2, 3, 4, 5), ZoneId.systemDefault()));
|
||||
User user2 = new User("2", "user2", "haha".getBytes(), "haha".getBytes(), null, -1, -1, "Leonard", "Sheldon",
|
||||
UserState.ENABLED, userRoles, Locale.ENGLISH, propertyMap);
|
||||
UserState.ENABLED, userRoles, Locale.ENGLISH, propertyMap, history);
|
||||
users.add(user2);
|
||||
|
||||
File modelFile = new File(TARGET_TEST + "PrivilegeUsersTest.xml");
|
||||
|
|
|
@ -7,6 +7,7 @@ import li.strolch.privilege.base.PrivilegeException;
|
|||
import li.strolch.privilege.handler.SingleSignOnHandler;
|
||||
import li.strolch.privilege.model.UserState;
|
||||
import li.strolch.privilege.model.internal.User;
|
||||
import li.strolch.privilege.model.internal.UserHistory;
|
||||
|
||||
public class DummySsoHandler implements SingleSignOnHandler {
|
||||
|
||||
|
@ -31,6 +32,6 @@ public class DummySsoHandler implements SingleSignOnHandler {
|
|||
Set<String> roles = Arrays.stream(map.get("roles").split(",")).map(String::trim).collect(Collectors.toSet());
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
return new User(map.get("userId"), map.get("username"), null, null, null, -1, -1, map.get("firstName"),
|
||||
map.get("lastName"), UserState.REMOTE, roles, Locale.ENGLISH, properties);
|
||||
map.get("lastName"), UserState.REMOTE, roles, Locale.ENGLISH, properties, new UserHistory());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ import static li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants.PRIV
|
|||
import static li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants.PRIVILEGE_INVALIDATE_SESSION;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Future;
|
||||
|
@ -313,8 +313,8 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St
|
|||
certificateMap = new HashMap<>(this.certificateMap);
|
||||
}
|
||||
|
||||
LocalDateTime maxKeepAliveTime = LocalDateTime.now().minus(this.maxKeepAliveMinutes, ChronoUnit.MINUTES);
|
||||
LocalDateTime timeOutTime = LocalDateTime.now().minus(this.sessionTtlMinutes, ChronoUnit.MINUTES);
|
||||
ZonedDateTime maxKeepAliveTime = ZonedDateTime.now().minus(this.maxKeepAliveMinutes, ChronoUnit.MINUTES);
|
||||
ZonedDateTime timeOutTime = ZonedDateTime.now().minus(this.sessionTtlMinutes, ChronoUnit.MINUTES);
|
||||
|
||||
for (Certificate certificate : certificateMap.values()) {
|
||||
if (certificate.isKeepAlive()) {
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
package li.strolch.rest.model;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -28,14 +28,14 @@ public class UserSession {
|
|||
|
||||
private final boolean keepAlive;
|
||||
private final String sessionId;
|
||||
private final LocalDateTime loginTime;
|
||||
private final ZonedDateTime loginTime;
|
||||
private final String username;
|
||||
private final String firstName;
|
||||
private final String lastName;
|
||||
private final String source;
|
||||
private final Set<String> userRoles;
|
||||
private final Locale locale;
|
||||
private final LocalDateTime lastAccess;
|
||||
private final ZonedDateTime lastAccess;
|
||||
|
||||
public UserSession(Certificate certificate) {
|
||||
this.sessionId = certificate.getSessionId();
|
||||
|
@ -54,7 +54,7 @@ public class UserSession {
|
|||
return locale;
|
||||
}
|
||||
|
||||
public LocalDateTime getLastAccess() {
|
||||
public ZonedDateTime getLastAccess() {
|
||||
return lastAccess;
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ public class UserSession {
|
|||
return sessionId;
|
||||
}
|
||||
|
||||
public LocalDateTime getLoginTime() {
|
||||
public ZonedDateTime getLoginTime() {
|
||||
return loginTime;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
|
|||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.HashSet;
|
||||
|
||||
import li.strolch.privilege.base.AccessDeniedException;
|
||||
|
@ -45,7 +45,7 @@ public class ServiceTest extends AbstractServiceTest {
|
|||
assertThrows(PrivilegeException.class, () -> {
|
||||
TestService testService = new TestService();
|
||||
getServiceHandler().doService(
|
||||
new Certificate(null, null, null, null, null, null, null, null, LocalDateTime.now(), false, null,
|
||||
new Certificate(null, null, null, null, null, null, null, null, ZonedDateTime.now(), false, null,
|
||||
new HashSet<>(), null), testService);
|
||||
});
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ public class ServiceTest extends AbstractServiceTest {
|
|||
public void shouldFailInvalidCertificate2() {
|
||||
TestService testService = new TestService();
|
||||
Certificate badCert = new Certificate(Usage.ANY, "1", "bob", "Bob", "Brown", UserState.ENABLED, "dsdf", "asd",
|
||||
LocalDateTime.now(), false, null, new HashSet<>(), null);
|
||||
ZonedDateTime.now(), false, null, new HashSet<>(), null);
|
||||
ServiceResult svcResult = getServiceHandler().doService(badCert, testService);
|
||||
assertThat(svcResult.getThrowable(), instanceOf(NotAuthenticatedException.class));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue