Server/src/main/java/de/towerdefence/server/session/SessionsService.java

64 lines
2.4 KiB
Java
Raw Normal View History

package de.towerdefence.server.session;
import de.towerdefence.server.player.Player;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.*;
@Service
@AllArgsConstructor
public class SessionsService {
private static final int TIME_TO_LIVE_SECONDS = 30;
private final Map<String, Channel> tokenGrants = new ConcurrentHashMap<>();
private final Map<String, Player> sessions = new ConcurrentHashMap<>();
private final Map<String, ScheduledFuture<?>> tokenGarbageCollectors = new ConcurrentHashMap<>();
@Autowired
private final JwtService jwtService;
private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public String createSession(Player player, Channel channel){
String jwt = jwtService.generateToken(player.getUsername(), channel, TIME_TO_LIVE_SECONDS);
if(tokenGrants.containsKey(jwt)){
throw new IllegalStateException("The exact same JWT allready exists");
}
tokenGrants.put(jwt, channel);
sessions.put(jwt, player);
this.tokenGarbageCollectors.put(jwt, scheduler.schedule(() -> {
tokenGrants.remove(jwt);
sessions.remove(jwt);
tokenGarbageCollectors.remove(jwt);
}, TIME_TO_LIVE_SECONDS, TimeUnit.SECONDS));
return jwt;
}
public Optional<Player> getSession(String jwt, Channel channel){
Channel grantedChannel = tokenGrants.get(jwt);
if (grantedChannel == null || !grantedChannel.equals(channel)) {
return Optional.empty();
}
Optional<String> username = jwtService.verifyToken(jwt, channel);
if (username.isEmpty()) {
return Optional.empty();
}
Player player = sessions.get(jwt);
if (!Objects.equals(player.getUsername(), username.get())) {
return Optional.empty();
}
ScheduledFuture<?> garbageCollector = tokenGarbageCollectors.get(jwt);
if (garbageCollector != null && !garbageCollector.isCancelled() && !garbageCollector.isDone()) {
garbageCollector.cancel(false);
}
tokenGarbageCollectors.remove(jwt);
tokenGrants.remove(jwt);
sessions.remove(jwt);
return Optional.of(player);
}
}