Skip to content

Commit b770192

Browse files
committed
Add readonly parameter to game_data_token
To prevent modified servers to try to save player data with a dev token
1 parent b0669cc commit b770192

3 files changed

Lines changed: 42 additions & 7 deletions

File tree

src/data/game_data_token.rs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,16 @@ use std::time::Duration;
33
use serde::{Deserialize, Serialize};
44
use uuid::Uuid;
55

6+
fn default_as_false() -> bool {
7+
false
8+
}
9+
610
#[derive(Debug, Serialize, Deserialize)]
711
pub struct GameDataToken {
812
pub player_db_id: i32,
913
pub player_uuid: Uuid,
14+
#[serde(default = "default_as_false")]
15+
pub is_readonly: bool,
1016
// JWT fields
1117
pub exp: u64,
1218
pub iat: u64,
@@ -15,22 +21,39 @@ pub struct GameDataToken {
1521

1622
impl GameDataToken {
1723
#[inline]
18-
pub fn new_access(player_db_id: i32, player_uuid: Uuid, duration: Duration) -> Self {
19-
Self::new("access", player_db_id, player_uuid, duration)
24+
pub fn new_access(
25+
player_db_id: i32,
26+
player_uuid: Uuid,
27+
duration: Duration,
28+
is_readonly: bool,
29+
) -> Self {
30+
Self::new("access", player_db_id, player_uuid, duration, is_readonly)
2031
}
2132

2233
#[inline]
23-
pub fn new_refresh(player_db_id: i32, player_uuid: Uuid, duration: Duration) -> Self {
24-
Self::new("refresh", player_db_id, player_uuid, duration)
34+
pub fn new_refresh(
35+
player_db_id: i32,
36+
player_uuid: Uuid,
37+
duration: Duration,
38+
is_readonly: bool,
39+
) -> Self {
40+
Self::new("refresh", player_db_id, player_uuid, duration, is_readonly)
2541
}
2642

27-
fn new(token_type: &str, player_db_id: i32, player_uuid: Uuid, duration: Duration) -> Self {
43+
fn new(
44+
token_type: &str,
45+
player_db_id: i32,
46+
player_uuid: Uuid,
47+
duration: Duration,
48+
is_readonly: bool,
49+
) -> Self {
2850
debug_assert!(valid_token_type(token_type));
2951

3052
let now = jsonwebtoken::get_current_timestamp();
3153
Self {
3254
player_db_id,
3355
player_uuid,
56+
is_readonly,
3457
exp: now + duration.as_secs(),
3558
iat: now,
3659
sub: token_type.to_string(),

src/routes/connection.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,12 @@ async fn game_connect(
7676

7777
let player_data = PlayerData::new(uuid, nickname, permissions);
7878

79-
let refresh_token =
80-
GameDataToken::new_refresh(player_id, uuid, config.game_api_refresh_token_duration);
79+
let refresh_token = GameDataToken::new_refresh(
80+
player_id,
81+
uuid,
82+
config.game_api_refresh_token_duration,
83+
is_dev,
84+
);
8185
let refresh_token_jwt = jsonwebtoken::encode(
8286
&Header::default(),
8387
&refresh_token,

src/routes/game_server.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,13 @@ async fn refresh_access_token(
7777
refresh_token.player_db_id,
7878
refresh_token.player_uuid,
7979
config.game_api_access_token_duration,
80+
refresh_token.is_readonly,
8081
);
8182
let refresh_token = GameDataToken::new_refresh(
8283
refresh_token.player_db_id,
8384
refresh_token.player_uuid,
8485
config.game_api_refresh_token_duration,
86+
refresh_token.is_readonly,
8587
);
8688

8789
let access_token_jwt = jsonwebtoken::encode(
@@ -150,6 +152,12 @@ async fn player_ship_patch(
150152
pg_pool: web::Data<deadpool_postgres::Pool>,
151153
) -> Result<impl Responder, RouteError> {
152154
let access_token = validate_token(&req, &config, "access")?;
155+
if access_token.is_readonly {
156+
return Err(RouteError::InvalidRequest(
157+
ServerErrorCode::InvalidToken(Some("Token is readonly".into())),
158+
"Token only allows for readonly access to the player data".to_string(),
159+
));
160+
}
153161

154162
let pg_client = pg_pool.get().await?;
155163
let insert_player_ship = pg_client

0 commit comments

Comments
 (0)