64 lines
2.4 KiB
Java
64 lines
2.4 KiB
Java
|
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);
|
||
|
}
|
||
|
}
|