[Fix] Fixed updating sessions on changes of user or roles
This commit is contained in:
parent
76d38e9af0
commit
d00b00d234
|
@ -30,7 +30,6 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.xml.sax.SAXParseException;
|
import org.xml.sax.SAXParseException;
|
||||||
|
|
||||||
import javax.crypto.SecretKey;
|
|
||||||
import javax.xml.stream.XMLStreamException;
|
import javax.xml.stream.XMLStreamException;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -292,14 +291,6 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
||||||
() -> crudHandler.removeRole(certificate, roleName));
|
() -> crudHandler.removeRole(certificate, roleName));
|
||||||
}
|
}
|
||||||
|
|
||||||
void invalidSessionsFor(User user) {
|
|
||||||
List<PrivilegeContext> contexts = new ArrayList<>(this.privilegeContextMap.values());
|
|
||||||
for (PrivilegeContext ctx : contexts) {
|
|
||||||
if (ctx.getUserRep().getUsername().equals(user.getUsername()))
|
|
||||||
invalidate(ctx.getCertificate());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initiateChallengeFor(Usage usage, String username) {
|
public void initiateChallengeFor(Usage usage, String username) {
|
||||||
initiateChallengeFor(usage, username, SOURCE_UNKNOWN);
|
initiateChallengeFor(usage, username, SOURCE_UNKNOWN);
|
||||||
|
@ -355,8 +346,8 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
||||||
false).getCertificate();
|
false).getCertificate();
|
||||||
|
|
||||||
if (!source.equals("unknown") && !source.equals(userChallenge.getSource())) {
|
if (!source.equals("unknown") && !source.equals(userChallenge.getSource())) {
|
||||||
logger.warn("Challenge request and response source's are different: request: " + userChallenge.getSource() +
|
logger.warn(format("Challenge request and response source''s are different: request: {0} to {1}",
|
||||||
" to " + source);
|
userChallenge.getSource(), source));
|
||||||
}
|
}
|
||||||
|
|
||||||
persistSessionsAsync();
|
persistSessionsAsync();
|
||||||
|
@ -444,9 +435,12 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
||||||
* @return a stream of role names
|
* @return a stream of role names
|
||||||
*/
|
*/
|
||||||
public static Stream<String> streamAllRolesForUser(PersistenceHandler persistenceHandler, User user) {
|
public static Stream<String> streamAllRolesForUser(PersistenceHandler persistenceHandler, User user) {
|
||||||
return Stream.concat(user.getRoles().stream(),
|
return Stream.concat(user.getRoles().stream(), user
|
||||||
user.groups().stream().map(persistenceHandler::getGroup).filter(Objects::nonNull)
|
.groups()
|
||||||
.flatMap(g -> g.roles().stream()));
|
.stream()
|
||||||
|
.map(persistenceHandler::getGroup)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.flatMap(g -> g.roles().stream()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -559,8 +553,11 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
||||||
// get sessions reference
|
// get sessions reference
|
||||||
AtomicReference<List<Certificate>> sessions = new AtomicReference<>();
|
AtomicReference<List<Certificate>> sessions = new AtomicReference<>();
|
||||||
this.lockingHandler.lockedExecute("persist-sessions", () -> sessions.set(
|
this.lockingHandler.lockedExecute("persist-sessions", () -> sessions.set(
|
||||||
new ArrayList<>(this.privilegeContextMap.values()).stream().map(PrivilegeContext::getCertificate)
|
new ArrayList<>(this.privilegeContextMap.values())
|
||||||
.filter(c -> !c.getUserState().isSystem()).collect(toList())));
|
.stream()
|
||||||
|
.map(PrivilegeContext::getCertificate)
|
||||||
|
.filter(c -> !c.getUserState().isSystem())
|
||||||
|
.collect(toList())));
|
||||||
|
|
||||||
// write the sessions
|
// write the sessions
|
||||||
try (OutputStream out = Files.newOutputStream(this.persistSessionsPath.toPath());
|
try (OutputStream out = Files.newOutputStream(this.persistSessionsPath.toPath());
|
||||||
|
@ -573,8 +570,8 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Failed to persist sessions!", e);
|
logger.error("Failed to persist sessions!", e);
|
||||||
if (this.persistSessionsPath.exists() && !this.persistSessionsPath.delete()) {
|
if (this.persistSessionsPath.exists() && !this.persistSessionsPath.delete()) {
|
||||||
logger.error("Failed to delete sessions file after failing to write to it, at " +
|
logger.error("Failed to delete sessions file after failing to write to it, at "
|
||||||
this.persistSessionsPath.getAbsolutePath());
|
+ this.persistSessionsPath.getAbsolutePath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 1, TimeUnit.SECONDS);
|
}, 1, TimeUnit.SECONDS);
|
||||||
|
@ -694,8 +691,9 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
||||||
PasswordCrypt requestPasswordCrypt;
|
PasswordCrypt requestPasswordCrypt;
|
||||||
if (userPasswordCrypt.salt() == null) {
|
if (userPasswordCrypt.salt() == null) {
|
||||||
requestPasswordCrypt = this.encryptionHandler.hashPasswordWithoutSalt(password);
|
requestPasswordCrypt = this.encryptionHandler.hashPasswordWithoutSalt(password);
|
||||||
} else if (userPasswordCrypt.hashAlgorithm() == null || userPasswordCrypt.hashIterations() == -1 ||
|
} else if (userPasswordCrypt.hashAlgorithm() == null
|
||||||
userPasswordCrypt.hashKeyLength() == -1) {
|
|| userPasswordCrypt.hashIterations() == -1
|
||||||
|
|| userPasswordCrypt.hashKeyLength() == -1) {
|
||||||
requestPasswordCrypt = this.encryptionHandler.hashPassword(password, userPasswordCrypt.salt());
|
requestPasswordCrypt = this.encryptionHandler.hashPassword(password, userPasswordCrypt.salt());
|
||||||
} else {
|
} else {
|
||||||
requestPasswordCrypt = this.encryptionHandler.hashPassword(password, userPasswordCrypt.salt(),
|
requestPasswordCrypt = this.encryptionHandler.hashPassword(password, userPasswordCrypt.salt(),
|
||||||
|
@ -1075,12 +1073,27 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidates all the sessions for the given user and persists the sessions async
|
||||||
|
*
|
||||||
|
* @param user the user for which to invalidate the sessions
|
||||||
|
*/
|
||||||
|
void invalidateSessionsFor(User user) {
|
||||||
|
List<PrivilegeContext> contexts = new ArrayList<>(this.privilegeContextMap.values());
|
||||||
|
for (PrivilegeContext ctx : contexts) {
|
||||||
|
if (ctx.getUserRep().getUsername().equals(user.getUsername()))
|
||||||
|
invalidate(ctx.getCertificate());
|
||||||
|
}
|
||||||
|
|
||||||
|
persistSessionsAsync();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replaces any existing {@link PrivilegeContext} for the given user by updating with the new user object
|
* Replaces any existing {@link PrivilegeContext} for the given user by updating with the new user object
|
||||||
*
|
*
|
||||||
* @param newUser the new user to update with
|
* @param newUser the new user to update with
|
||||||
*/
|
*/
|
||||||
void updateExistingSessionsForUser(User newUser) {
|
void updateExistingSessionsForUser(User newUser, boolean persistSessions) {
|
||||||
List<PrivilegeContext> contexts = new ArrayList<>(this.privilegeContextMap.values());
|
List<PrivilegeContext> contexts = new ArrayList<>(this.privilegeContextMap.values());
|
||||||
for (PrivilegeContext ctx : contexts) {
|
for (PrivilegeContext ctx : contexts) {
|
||||||
if (!ctx.getUserRep().getUsername().equals(newUser.getUsername()))
|
if (!ctx.getUserRep().getUsername().equals(newUser.getUsername()))
|
||||||
|
@ -1088,7 +1101,8 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
||||||
replacePrivilegeContextForCert(newUser, ctx.getCertificate());
|
replacePrivilegeContextForCert(newUser, ctx.getCertificate());
|
||||||
}
|
}
|
||||||
|
|
||||||
persistSessionsAsync();
|
if (persistSessions)
|
||||||
|
persistSessionsAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -172,8 +172,15 @@ public class PrivilegeCrudHandler {
|
||||||
// properties
|
// properties
|
||||||
propertySelected = isSelectedByProperty(selPropertyMap, user.getProperties());
|
propertySelected = isSelectedByProperty(selPropertyMap, user.getProperties());
|
||||||
|
|
||||||
boolean selected = userIdSelected && usernameSelected && firstNameSelected && lastNameSelected &&
|
boolean selected = userIdSelected
|
||||||
userStateSelected && localeSelected && groupSelected && roleSelected && propertySelected;
|
&& usernameSelected
|
||||||
|
&& firstNameSelected
|
||||||
|
&& lastNameSelected
|
||||||
|
&& userStateSelected
|
||||||
|
&& localeSelected
|
||||||
|
&& groupSelected
|
||||||
|
&& roleSelected
|
||||||
|
&& propertySelected;
|
||||||
|
|
||||||
if (selected)
|
if (selected)
|
||||||
result.add(user.asUserRep());
|
result.add(user.asUserRep());
|
||||||
|
@ -376,7 +383,10 @@ public class PrivilegeCrudHandler {
|
||||||
|
|
||||||
// delegate to persistence handler
|
// delegate to persistence handler
|
||||||
toCreate.forEach(this.persistenceHandler::addUser);
|
toCreate.forEach(this.persistenceHandler::addUser);
|
||||||
toUpdate.forEach(this.persistenceHandler::replaceUser);
|
for (User user : toUpdate) {
|
||||||
|
this.persistenceHandler.replaceUser(user);
|
||||||
|
this.privilegeHandler.updateExistingSessionsForUser(user, false);
|
||||||
|
}
|
||||||
this.privilegeHandler.persistModelAsync();
|
this.privilegeHandler.persistModelAsync();
|
||||||
|
|
||||||
DefaultPrivilegeHandler.logger.info("Created " + toCreate.size() + " users");
|
DefaultPrivilegeHandler.logger.info("Created " + toCreate.size() + " users");
|
||||||
|
@ -530,7 +540,7 @@ public class PrivilegeCrudHandler {
|
||||||
|
|
||||||
// delegate to persistence handler
|
// delegate to persistence handler
|
||||||
this.persistenceHandler.replaceUser(newUser);
|
this.persistenceHandler.replaceUser(newUser);
|
||||||
this.privilegeHandler.persistModelAsync();
|
this.privilegeHandler.updateExistingSessionsForUser(newUser, true);
|
||||||
|
|
||||||
DefaultPrivilegeHandler.logger.info("Replaced user " + newUser.getUsername());
|
DefaultPrivilegeHandler.logger.info("Replaced user " + newUser.getUsername());
|
||||||
|
|
||||||
|
@ -559,9 +569,8 @@ public class PrivilegeCrudHandler {
|
||||||
new SimpleRestrictable(DefaultPrivilegeHandler.PRIVILEGE_REMOVE_USER, new Tuple(null, existingUser)));
|
new SimpleRestrictable(DefaultPrivilegeHandler.PRIVILEGE_REMOVE_USER, new Tuple(null, existingUser)));
|
||||||
|
|
||||||
// delegate user removal to persistence handler
|
// delegate user removal to persistence handler
|
||||||
this.privilegeHandler.invalidSessionsFor(existingUser);
|
this.privilegeHandler.invalidateSessionsFor(existingUser);
|
||||||
this.persistenceHandler.removeUser(username);
|
this.persistenceHandler.removeUser(username);
|
||||||
this.privilegeHandler.persistModelAsync();
|
|
||||||
|
|
||||||
DefaultPrivilegeHandler.logger.info("Removed user " + username);
|
DefaultPrivilegeHandler.logger.info("Removed user " + username);
|
||||||
|
|
||||||
|
@ -715,7 +724,7 @@ public class PrivilegeCrudHandler {
|
||||||
|
|
||||||
// delegate user replacement to persistence handler
|
// delegate user replacement to persistence handler
|
||||||
this.persistenceHandler.replaceUser(newUser);
|
this.persistenceHandler.replaceUser(newUser);
|
||||||
this.privilegeHandler.persistModelAsync();
|
this.privilegeHandler.invalidateSessionsFor(newUser);
|
||||||
|
|
||||||
DefaultPrivilegeHandler.logger.info("Set state of user " + newUser.getUsername() + " to " + state);
|
DefaultPrivilegeHandler.logger.info("Set state of user " + newUser.getUsername() + " to " + state);
|
||||||
|
|
||||||
|
@ -789,11 +798,11 @@ public class PrivilegeCrudHandler {
|
||||||
this.persistenceHandler.replaceRole(newRole);
|
this.persistenceHandler.replaceRole(newRole);
|
||||||
this.privilegeHandler.persistModelAsync();
|
this.privilegeHandler.persistModelAsync();
|
||||||
|
|
||||||
DefaultPrivilegeHandler.logger.info("Replaced role " + newRole.getName());
|
|
||||||
|
|
||||||
// update any existing certificates with new role
|
// update any existing certificates with new role
|
||||||
this.privilegeHandler.updateExistingSessionsWithNewRole(newRole);
|
this.privilegeHandler.updateExistingSessionsWithNewRole(newRole);
|
||||||
|
|
||||||
|
DefaultPrivilegeHandler.logger.info("Replaced role " + newRole.getName());
|
||||||
|
|
||||||
return newRole.asRoleRep();
|
return newRole.asRoleRep();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue