Compare commits

..

1 commit

Author SHA1 Message Date
e5cf6d291a
NOTICKET: Setup and Sepcify Websocket Structure
Some checks failed
Quality Check / Validate OAS (pull_request) Successful in 36s
Quality Check / Validate OAS (push) Successful in 39s
Quality Check / Static Analysis (push) Failing after 1m7s
Quality Check / Linting (push) Successful in 1m16s
Quality Check / Testing (push) Successful in 1m17s
Quality Check / Static Analysis (pull_request) Failing after 58s
Quality Check / Linting (pull_request) Successful in 1m0s
Quality Check / Testing (pull_request) Successful in 44s
2025-02-17 10:43:52 +01:00
7 changed files with 43 additions and 9 deletions

View file

@ -41,7 +41,7 @@ public abstract class JsonWebsocketHandler extends TextWebSocketHandler {
try{
session.close(reason);
} catch (Exception exception) {
logger.debug("Unable to Close the Session", exception);
logger.info("Unable to Close the Session", exception);
}
}
}

View file

@ -22,11 +22,12 @@ public class ConnectionWebsocketHandler extends JsonWebsocketHandler {
protected void handleTextMessage(WebSocketSession session, TextMessage message) {
try{
String payload = message.getPayload();
switch ( objectMapper.readTree(payload).get("$id").asText()) {
case "RequestConnectionToken" -> handleRequestConnectionToken(session, payload);
switch ( objectMapper.readTree(payload).get("$id").asText().toLowerCase()) {
case "requestconnectiontoken" -> handleRequestConnectionToken(session, payload);
default -> this.closeSession(session, CloseStatus.BAD_DATA);
}
} catch (Exception exception) {
System.out.println(exception.getMessage());
this.closeSession(session, CloseStatus.BAD_DATA);
}
}
@ -35,6 +36,6 @@ public class ConnectionWebsocketHandler extends JsonWebsocketHandler {
RequestConnectionTokenMessage msg = objectMapper.readValue(payload, RequestConnectionTokenMessage.class);
Player player = this.sessionPlayers.get(session);
String jwt = this.sessionsService.createSession(player, msg.getChannel());
new ProvidedConnectionTokenMessage(channel, jwt).send(session);
new ProvidedConnectionTokenMessage(msg.getChannel(), jwt).send(session);
}
}

View file

@ -1,5 +1,6 @@
package de.towerdefence.server.server.channels.connection.in;
import com.fasterxml.jackson.annotation.JsonProperty;
import de.towerdefence.server.session.Channel;
import jakarta.validation.constraints.NotNull;
import lombok.*;
@ -7,6 +8,7 @@ import lombok.*;
@Data
@NotNull
public class RequestConnectionTokenMessage {
private String $id;
@JsonProperty("$id")
private String messageId;
private Channel channel;
}

View file

@ -21,20 +21,21 @@ public class JwtService {
this.secretKey = Keys.hmacShaKeyFor(config.getSecret().getBytes(StandardCharsets.UTF_8));
}
public String generateToken(String username, long ttl) {
public String generateToken(String username, Channel channel, long ttl) {
long now = System.currentTimeMillis();
Date issueDate = new Date(now);
Date expirationDate = new Date(now + ttl * 1000);
return Jwts.builder()
.subject(username)
.claim("channel", channel.getJsonName())
.issuedAt(issueDate)
.expiration(expirationDate)
.signWith(secretKey)
.compact();
}
public Optional<String> verifyToken(String token) {
public Optional<String> verifyToken(String token, Channel channel) {
Claims claims = Jwts.parser()
.verifyWith(secretKey)
.build()
@ -45,6 +46,16 @@ public class JwtService {
return Optional.empty();
}
Channel tokenChannel;
try {
tokenChannel = Channel.fromJsonName(claims.get("channel", String.class));
} catch (IllegalArgumentException ignored) {
return Optional.empty();
}
if(!channel.equals(tokenChannel)) {
return Optional.empty();
}
return Optional.of(claims.getSubject());
}
}

View file

@ -24,7 +24,7 @@ public class SessionsService {
private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public String createSession(Player player, Channel channel){
String jwt = jwtService.generateToken(player.getUsername(), TIME_TO_LIVE_SECONDS);
String jwt = jwtService.generateToken(player.getUsername(), channel, TIME_TO_LIVE_SECONDS);
if(tokenGrants.containsKey(jwt)){
throw new IllegalStateException("The exact same JWT allready exists");
}
@ -43,7 +43,7 @@ public class SessionsService {
if (grantedChannel == null || !grantedChannel.equals(channel)) {
return Optional.empty();
}
Optional<String> username = jwtService.verifyToken(jwt);
Optional<String> username = jwtService.verifyToken(jwt, channel);
if (username.isEmpty()) {
return Optional.empty();
}

17
ws/example/time_channel.sh Executable file
View file

@ -0,0 +1,17 @@
#!/bin/sh
response=$(curl -s -X 'POST' \
'http://localhost:8080/api/v1/player/login' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"username": "Player1",
"password": "1234"
}')
token=$(echo "$response" | jq -r .token)
payload='{"$id": "RequestConnectionToken", "channel": "time"}'
response=$(echo "$payload" | websocat ws://localhost:8080/ws/connection -H "Authorization: $token")
time_token=$(echo "$response" | jq -r .token)
websocat ws://localhost:8080/ws/time -H "Authorization: $time_token"

View file

@ -33,6 +33,7 @@ channels:
Specific Channel
payload:
type: object
additionalProperties: false
properties:
$id:
type: string
@ -51,6 +52,7 @@ channels:
Specific Channel
payload:
type: object
additionalProperties: false
properties:
$id:
type: string
@ -75,6 +77,7 @@ channels:
description: The Current time in Unix Time
payload:
type: object
additionalProperties: false
properties:
$id:
type: string