mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 21:27:40 +00:00
GUACAMOLE-36: Record and maintain password history.
This commit is contained in:
@@ -72,6 +72,20 @@ public interface PasswordPolicy {
|
||||
*/
|
||||
int getMaximumAge() throws GuacamoleException;
|
||||
|
||||
/**
|
||||
* Returns the number of previous passwords remembered for each user. If
|
||||
* greater than zero, users will be prohibited from reusing their past
|
||||
* passwords.
|
||||
*
|
||||
* @return
|
||||
* The number of previous passwords remembered for each user.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If the password history size cannot be parsed from
|
||||
* guacamole.properties.
|
||||
*/
|
||||
int getHistorySize() throws GuacamoleException;
|
||||
|
||||
/**
|
||||
* Returns whether both uppercase and lowercase characters must be present
|
||||
* in new passwords. If true, passwords which do not have at least one
|
||||
|
@@ -26,6 +26,7 @@ import java.util.regex.Pattern;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.auth.jdbc.JDBCEnvironment;
|
||||
import org.apache.guacamole.auth.jdbc.user.ModeledUser;
|
||||
import org.apache.guacamole.auth.jdbc.user.PasswordRecordMapper;
|
||||
import org.apache.guacamole.auth.jdbc.user.PasswordRecordModel;
|
||||
|
||||
/**
|
||||
@@ -42,6 +43,12 @@ public class PasswordPolicyService {
|
||||
@Inject
|
||||
private JDBCEnvironment environment;
|
||||
|
||||
/**
|
||||
* Mapper for creating/retrieving previously-set passwords.
|
||||
*/
|
||||
@Inject
|
||||
private PasswordRecordMapper passwordRecordMapper;
|
||||
|
||||
/**
|
||||
* Regular expression which matches only if the string contains at least one
|
||||
* lowercase character.
|
||||
@@ -235,4 +242,32 @@ public class PasswordPolicyService {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Records the password that was associated with the given user at the time
|
||||
* the user was queried, such that future attempts to set that same password
|
||||
* for that user will be denied. The number of passwords remembered for each
|
||||
* user is limited by the password policy.
|
||||
*
|
||||
* @param user
|
||||
* The user whose previous password should be recorded.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If the password policy cannot be parsed.
|
||||
*/
|
||||
public void recordPreviousPassword(ModeledUser user)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Retrieve password policy from environment
|
||||
PasswordPolicy policy = environment.getPasswordPolicy();
|
||||
|
||||
// Nothing to do if history is not being recorded
|
||||
int historySize = policy.getHistorySize();
|
||||
if (historySize <= 0)
|
||||
return;
|
||||
|
||||
// Store previous password in history
|
||||
passwordRecordMapper.insert(user.getPreviousPassword(), historySize);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -242,6 +242,9 @@ public class UserService extends ModeledDirectoryObjectService<ModeledUser, User
|
||||
// Always verify password complexity
|
||||
passwordPolicyService.verifyPassword(object.getIdentifier(), object.getPassword());
|
||||
|
||||
// Store previous password in history
|
||||
passwordPolicyService.recordPreviousPassword(object);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -71,6 +71,19 @@ public class MySQLPasswordPolicy implements PasswordPolicy {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The property which specifies the number of previous passwords remembered
|
||||
* for each user. If set to zero, the default, then this restriction does
|
||||
* not apply.
|
||||
*/
|
||||
private static final IntegerGuacamoleProperty HISTORY_SIZE =
|
||||
new IntegerGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "mysql-user-password-history-size"; }
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The property which specifies whether all user passwords must have at
|
||||
* least one lowercase character and one uppercase character. By default,
|
||||
@@ -155,6 +168,11 @@ public class MySQLPasswordPolicy implements PasswordPolicy {
|
||||
return environment.getProperty(MAX_AGE, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHistorySize() throws GuacamoleException {
|
||||
return environment.getProperty(HISTORY_SIZE, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMultipleCaseRequired() throws GuacamoleException {
|
||||
return environment.getProperty(REQUIRE_MULTIPLE_CASE, false);
|
||||
|
@@ -63,7 +63,19 @@
|
||||
#{record.passwordHash,jdbcType=BINARY},
|
||||
#{record.passwordSalt,jdbcType=BINARY},
|
||||
#{record.passwordDate,jdbcType=TIMESTAMP}
|
||||
)
|
||||
);
|
||||
|
||||
DELETE FROM guacamole_user_password_history
|
||||
WHERE password_history_id <= (
|
||||
SELECT password_history_id
|
||||
FROM (
|
||||
SELECT password_history_id
|
||||
FROM guacamole_user_password_history
|
||||
WHERE user_id = #{record.userID,jdbcType=INTEGER}
|
||||
ORDER BY password_date DESC
|
||||
LIMIT 1 OFFSET #{maxHistorySize}
|
||||
) old_password_record
|
||||
);
|
||||
|
||||
</insert>
|
||||
|
||||
|
@@ -71,6 +71,19 @@ public class PostgreSQLPasswordPolicy implements PasswordPolicy {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The property which specifies the number of previous passwords remembered
|
||||
* for each user. If set to zero, the default, then this restriction does
|
||||
* not apply.
|
||||
*/
|
||||
private static final IntegerGuacamoleProperty HISTORY_SIZE =
|
||||
new IntegerGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "postgresql-user-password-history-size"; }
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The property which specifies whether all user passwords must have at
|
||||
* least one lowercase character and one uppercase character. By default,
|
||||
@@ -155,6 +168,11 @@ public class PostgreSQLPasswordPolicy implements PasswordPolicy {
|
||||
return environment.getProperty(MAX_AGE, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHistorySize() throws GuacamoleException {
|
||||
return environment.getProperty(HISTORY_SIZE, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMultipleCaseRequired() throws GuacamoleException {
|
||||
return environment.getProperty(REQUIRE_MULTIPLE_CASE, false);
|
||||
|
@@ -63,7 +63,16 @@
|
||||
#{record.passwordHash,jdbcType=BINARY},
|
||||
#{record.passwordSalt,jdbcType=BINARY},
|
||||
#{record.passwordDate,jdbcType=TIMESTAMP}
|
||||
)
|
||||
);
|
||||
|
||||
DELETE FROM guacamole_user_password_history
|
||||
WHERE password_history_id IN (
|
||||
SELECT password_history_id
|
||||
FROM guacamole_user_password_history
|
||||
WHERE user_id = #{record.userID,jdbcType=INTEGER}
|
||||
ORDER BY password_date DESC
|
||||
OFFSET #{maxHistorySize}
|
||||
);
|
||||
|
||||
</insert>
|
||||
|
||||
|
Reference in New Issue
Block a user