mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2026-03-04 02:20:19 +01:00
refactor(core,common,proprietary): Replace Date with Instant/modern Date API alternative for improved time handling (#4497)
This commit is contained in:
@@ -4,7 +4,6 @@ import static stirling.software.common.util.ProviderUtils.validateProvider;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@@ -218,7 +217,7 @@ public class AccountWebController {
|
||||
Map<String, String> roleDetails = Role.getAllRoleDetails();
|
||||
// Map to store session information and user activity status
|
||||
Map<String, Boolean> userSessions = new HashMap<>();
|
||||
Map<String, Date> userLastRequest = new HashMap<>();
|
||||
Map<String, Instant> userLastRequest = new HashMap<>();
|
||||
int activeUsers = 0;
|
||||
int disabledUsers = 0;
|
||||
while (iterator.hasNext()) {
|
||||
@@ -249,27 +248,29 @@ public class AccountWebController {
|
||||
// Determine the user's session status and last request time
|
||||
int maxInactiveInterval = sessionPersistentRegistry.getMaxInactiveInterval();
|
||||
boolean hasActiveSession = false;
|
||||
Date lastRequest = null;
|
||||
Instant lastRequest = null;
|
||||
Optional<SessionEntity> latestSession =
|
||||
sessionPersistentRegistry.findLatestSession(user.getUsername());
|
||||
if (latestSession.isPresent()) {
|
||||
SessionEntity sessionEntity = latestSession.get();
|
||||
Date lastAccessedTime = sessionEntity.getLastRequest();
|
||||
// sessionEntity stores Instant directly
|
||||
Instant lastAccessedTime =
|
||||
Optional.ofNullable(sessionEntity.getLastRequest())
|
||||
.orElse(Instant.EPOCH);
|
||||
|
||||
Instant now = Instant.now();
|
||||
// Calculate session expiration and update session status accordingly
|
||||
Instant expirationTime =
|
||||
lastAccessedTime
|
||||
.toInstant()
|
||||
.plus(maxInactiveInterval, ChronoUnit.SECONDS);
|
||||
lastAccessedTime.plus(maxInactiveInterval, ChronoUnit.SECONDS);
|
||||
if (now.isAfter(expirationTime)) {
|
||||
sessionPersistentRegistry.expireSession(sessionEntity.getSessionId());
|
||||
} else {
|
||||
hasActiveSession = !sessionEntity.isExpired();
|
||||
}
|
||||
lastRequest = sessionEntity.getLastRequest();
|
||||
lastRequest = lastAccessedTime;
|
||||
} else {
|
||||
// No session, set default last request time
|
||||
lastRequest = new Date(0);
|
||||
lastRequest = Instant.EPOCH;
|
||||
}
|
||||
userSessions.put(user.getUsername(), hasActiveSession);
|
||||
userLastRequest.put(user.getUsername(), lastRequest);
|
||||
@@ -286,19 +287,21 @@ public class AccountWebController {
|
||||
allUsers.stream()
|
||||
.sorted(
|
||||
(u1, u2) -> {
|
||||
boolean u1Active = userSessions.get(u1.getUsername());
|
||||
boolean u2Active = userSessions.get(u2.getUsername());
|
||||
boolean u1Active =
|
||||
userSessions.getOrDefault(u1.getUsername(), false);
|
||||
boolean u2Active =
|
||||
userSessions.getOrDefault(u2.getUsername(), false);
|
||||
if (u1Active && !u2Active) {
|
||||
return -1;
|
||||
} else if (!u1Active && u2Active) {
|
||||
return 1;
|
||||
} else {
|
||||
Date u1LastRequest =
|
||||
Instant u1LastRequest =
|
||||
userLastRequest.getOrDefault(
|
||||
u1.getUsername(), new Date(0));
|
||||
Date u2LastRequest =
|
||||
u1.getUsername(), Instant.EPOCH);
|
||||
Instant u2LastRequest =
|
||||
userLastRequest.getOrDefault(
|
||||
u2.getUsername(), new Date(0));
|
||||
u2.getUsername(), Instant.EPOCH);
|
||||
return u2LastRequest.compareTo(u1LastRequest);
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package stirling.software.proprietary.security.controller.web;
|
||||
|
||||
import java.util.Date;
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -44,17 +44,17 @@ public class TeamWebController {
|
||||
// Filter out the Internal team
|
||||
List<TeamWithUserCountDTO> teamsWithCounts =
|
||||
allTeamsWithCounts.stream()
|
||||
.filter(team -> !team.getName().equals(TeamService.INTERNAL_TEAM_NAME))
|
||||
.filter(team -> !TeamService.INTERNAL_TEAM_NAME.equals(team.getName()))
|
||||
.toList();
|
||||
|
||||
// Get the latest activity for each team
|
||||
List<Object[]> teamActivities = sessionRepository.findLatestActivityByTeam();
|
||||
|
||||
// Convert the query results to a map for easy access in the view
|
||||
Map<Long, Date> teamLastRequest = new HashMap<>();
|
||||
Map<Long, Instant> teamLastRequest = new HashMap<>();
|
||||
for (Object[] result : teamActivities) {
|
||||
Long teamId = (Long) result[0]; // teamId alias
|
||||
Date lastActivity = (Date) result[1]; // lastActivity alias
|
||||
Instant lastActivity = (Instant) result[1]; // lastActivity alias
|
||||
teamLastRequest.put(teamId, lastActivity);
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ public class TeamWebController {
|
||||
.orElseThrow(() -> new RuntimeException("Team not found"));
|
||||
|
||||
// Prevent access to Internal team
|
||||
if (team.getName().equals(TeamService.INTERNAL_TEAM_NAME)) {
|
||||
if (TeamService.INTERNAL_TEAM_NAME.equals(team.getName())) {
|
||||
return "redirect:/teams?error=internalTeamNotAccessible";
|
||||
}
|
||||
|
||||
@@ -114,21 +114,18 @@ public class TeamWebController {
|
||||
(user.getTeam() == null
|
||||
|| !user.getTeam().getId().equals(id))
|
||||
&& (user.getTeam() == null
|
||||
|| !user.getTeam()
|
||||
.getName()
|
||||
.equals(
|
||||
TeamService
|
||||
.INTERNAL_TEAM_NAME)))
|
||||
|| !TeamService.INTERNAL_TEAM_NAME.equals(
|
||||
user.getTeam().getName())))
|
||||
.toList();
|
||||
|
||||
// Get the latest session for each user in the team
|
||||
List<Object[]> userSessions = sessionRepository.findLatestSessionByTeamId(id);
|
||||
|
||||
// Create a map of username to last request date
|
||||
Map<String, Date> userLastRequest = new HashMap<>();
|
||||
Map<String, Instant> userLastRequest = new HashMap<>();
|
||||
for (Object[] result : userSessions) {
|
||||
String username = (String) result[0]; // username alias
|
||||
Date lastRequest = (Date) result[1]; // lastRequest alias
|
||||
Instant lastRequest = (Instant) result[1]; // lastRequest alias
|
||||
userLastRequest.put(username, lastRequest);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ public class JPATokenRepositoryImpl implements PersistentTokenRepository {
|
||||
newToken.setSeries(token.getSeries());
|
||||
newToken.setUsername(token.getUsername());
|
||||
newToken.setToken(token.getTokenValue());
|
||||
newToken.setLastUsed(token.getDate());
|
||||
newToken.setLastUsed(token.getDate().toInstant());
|
||||
persistentLoginRepository.save(newToken);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public class JPATokenRepositoryImpl implements PersistentTokenRepository {
|
||||
PersistentLogin existingToken = persistentLoginRepository.findById(series).orElse(null);
|
||||
if (existingToken != null) {
|
||||
existingToken.setToken(tokenValue);
|
||||
existingToken.setLastUsed(lastUsed);
|
||||
existingToken.setLastUsed(lastUsed.toInstant());
|
||||
persistentLoginRepository.save(existingToken);
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,10 @@ public class JPATokenRepositoryImpl implements PersistentTokenRepository {
|
||||
PersistentLogin token = persistentLoginRepository.findById(seriesId).orElse(null);
|
||||
if (token != null) {
|
||||
return new PersistentRememberMeToken(
|
||||
token.getUsername(), token.getSeries(), token.getToken(), token.getLastUsed());
|
||||
token.getUsername(),
|
||||
token.getSeries(),
|
||||
token.getToken(),
|
||||
Date.from(token.getLastUsed()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package stirling.software.proprietary.security.database.repository;
|
||||
|
||||
import java.util.Date;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
@@ -27,7 +27,7 @@ public interface SessionRepository extends JpaRepository<SessionEntity, String>
|
||||
"UPDATE SessionEntity s SET s.expired = :expired, s.lastRequest = :lastRequest WHERE s.principalName = :principalName")
|
||||
void saveByPrincipalName(
|
||||
@Param("expired") boolean expired,
|
||||
@Param("lastRequest") Date lastRequest,
|
||||
@Param("lastRequest") Instant lastRequest,
|
||||
@Param("principalName") String principalName);
|
||||
|
||||
@Query(
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package stirling.software.proprietary.security.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
@@ -60,8 +61,12 @@ public class FirstLoginFilter extends OncePerRequestFilter {
|
||||
}
|
||||
if (log.isDebugEnabled()) {
|
||||
HttpSession session = request.getSession(true);
|
||||
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
|
||||
String creationTime = timeFormat.format(new Date(session.getCreationTime()));
|
||||
DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("HH:mm:ss");
|
||||
String creationTime =
|
||||
timeFormat.format(
|
||||
Instant.ofEpochMilli(session.getCreationTime())
|
||||
.atZone(ZoneId.systemDefault())
|
||||
.toLocalTime());
|
||||
log.debug(
|
||||
"Request Info - New: {}, creationTimeSession {}, ID: {}, IP: {}, User-Agent: {}, Referer: {}, Request URL: {}",
|
||||
session.isNew(),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package stirling.software.proprietary.security.model;
|
||||
|
||||
import java.util.Date;
|
||||
import java.time.Instant;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
@@ -25,5 +25,5 @@ public class PersistentLogin {
|
||||
private String token;
|
||||
|
||||
@Column(name = "last_used", nullable = false)
|
||||
private Date lastUsed;
|
||||
private Instant lastUsed;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package stirling.software.proprietary.security.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.time.Instant;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
@@ -17,7 +17,7 @@ public class SessionEntity implements Serializable {
|
||||
|
||||
private String principalName;
|
||||
|
||||
private Date lastRequest;
|
||||
private Instant lastRequest;
|
||||
|
||||
private boolean expired;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.security.KeyPair;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
@@ -92,8 +93,8 @@ public class JwtService implements JwtServiceInterface {
|
||||
.claims(claims)
|
||||
.subject(username)
|
||||
.issuer(ISSUER)
|
||||
.issuedAt(new Date())
|
||||
.expiration(new Date(System.currentTimeMillis() + EXPIRATION))
|
||||
.issuedAt(Date.from(Instant.now()))
|
||||
.expiration(Date.from(Instant.now().plusMillis(EXPIRATION)))
|
||||
.signWith(keyPair.getPrivate(), Jwts.SIG.RS256);
|
||||
|
||||
String keyId = activeKey.getKeyId();
|
||||
@@ -129,7 +130,7 @@ public class JwtService implements JwtServiceInterface {
|
||||
|
||||
@Override
|
||||
public boolean isTokenExpired(String token) {
|
||||
return extractExpiration(token).before(new Date());
|
||||
return extractExpiration(token).before(Date.from(Instant.now()));
|
||||
}
|
||||
|
||||
private Date extractExpiration(String token) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package stirling.software.proprietary.security.session;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
@@ -67,7 +68,7 @@ public class SessionPersistentRegistry implements SessionRegistry {
|
||||
new SessionInformation(
|
||||
sessionEntity.getPrincipalName(),
|
||||
sessionEntity.getSessionId(),
|
||||
sessionEntity.getLastRequest()));
|
||||
Date.from(sessionEntity.getLastRequest())));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -101,7 +102,7 @@ public class SessionPersistentRegistry implements SessionRegistry {
|
||||
SessionEntity sessionEntity = new SessionEntity();
|
||||
sessionEntity.setSessionId(sessionId);
|
||||
sessionEntity.setPrincipalName(principalName);
|
||||
sessionEntity.setLastRequest(new Date()); // Set lastRequest to the current date
|
||||
sessionEntity.setLastRequest(Instant.now()); // Set lastRequest to the current date
|
||||
sessionEntity.setExpired(false);
|
||||
sessionRepository.save(sessionEntity);
|
||||
}
|
||||
@@ -119,7 +120,7 @@ public class SessionPersistentRegistry implements SessionRegistry {
|
||||
Optional<SessionEntity> sessionEntityOpt = sessionRepository.findById(sessionId);
|
||||
if (sessionEntityOpt.isPresent()) {
|
||||
SessionEntity sessionEntity = sessionEntityOpt.get();
|
||||
sessionEntity.setLastRequest(new Date()); // Update lastRequest to the current date
|
||||
sessionEntity.setLastRequest(Instant.now()); // Update lastRequest to the current date
|
||||
sessionRepository.save(sessionEntity);
|
||||
}
|
||||
}
|
||||
@@ -132,7 +133,7 @@ public class SessionPersistentRegistry implements SessionRegistry {
|
||||
return new SessionInformation(
|
||||
sessionEntity.getPrincipalName(),
|
||||
sessionEntity.getSessionId(),
|
||||
sessionEntity.getLastRequest());
|
||||
Date.from(sessionEntity.getLastRequest()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -170,7 +171,7 @@ public class SessionPersistentRegistry implements SessionRegistry {
|
||||
// Update session details by principal name
|
||||
public void updateSessionByPrincipalName(
|
||||
String principalName, boolean expired, Date lastRequest) {
|
||||
sessionRepository.saveByPrincipalName(expired, lastRequest, principalName);
|
||||
sessionRepository.saveByPrincipalName(expired, lastRequest.toInstant(), principalName);
|
||||
}
|
||||
|
||||
// Find the latest session for a given principal name
|
||||
|
||||
Reference in New Issue
Block a user