From 0e89bca12681fbc8ffa0d11c34cee7f30578f26e Mon Sep 17 00:00:00 2001 From: Dennis Brentjes Date: Sun, 13 Jul 2025 13:30:25 +0200 Subject: [PATCH] Small rewrite to allow fetching owned game of users --- backend-actix/gamenight-api.yaml | 7 ++++++ gamenight-api-client-rs/docs/DefaultApi.md | 9 +++++--- .../src/apis/default_api.rs | 5 +++- gamenight-cli/src/flows/mod.rs | 21 +++++++++++++++++ gamenight-cli/src/flows/view_game.rs | 11 +++++---- gamenight-cli/src/flows/view_gamenight.rs | 23 +++---------------- 6 files changed, 48 insertions(+), 28 deletions(-) diff --git a/backend-actix/gamenight-api.yaml b/backend-actix/gamenight-api.yaml index 2e2c40e..6c155ea 100644 --- a/backend-actix/gamenight-api.yaml +++ b/backend-actix/gamenight-api.yaml @@ -238,6 +238,8 @@ paths: $ref: '#/components/responses/FailureResponse' '422': $ref: '#/components/responses/FailureResponse' + requestBody: + $ref: '#/components/requestBodies/OwnedGamesRequest' security: - JWT-Auth: [] @@ -466,6 +468,11 @@ components: application/json: schema: $ref: '#/components/schemas/GameId' + OwnedGamesRequest: + content: + application/json: + schema: + $ref: '#/components/schemas/UserId' responses: TokenResponse: description: Example response diff --git a/gamenight-api-client-rs/docs/DefaultApi.md b/gamenight-api-client-rs/docs/DefaultApi.md index 85ed454..250d4b2 100644 --- a/gamenight-api-client-rs/docs/DefaultApi.md +++ b/gamenight-api-client-rs/docs/DefaultApi.md @@ -304,12 +304,15 @@ Name | Type | Description | Required | Notes ## owned_games_get -> Vec owned_games_get() +> Vec owned_games_get(user_id) ### Parameters -This endpoint does not need any parameter. + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**user_id** | Option<[**UserId**](UserId.md)> | | | ### Return type @@ -321,7 +324,7 @@ This endpoint does not need any parameter. ### HTTP request headers -- **Content-Type**: Not defined +- **Content-Type**: application/json - **Accept**: application/json [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) diff --git a/gamenight-api-client-rs/src/apis/default_api.rs b/gamenight-api-client-rs/src/apis/default_api.rs index 1e0af90..d14550f 100644 --- a/gamenight-api-client-rs/src/apis/default_api.rs +++ b/gamenight-api-client-rs/src/apis/default_api.rs @@ -505,7 +505,9 @@ pub async fn own_post(configuration: &configuration::Configuration, game_id: Opt } } -pub async fn owned_games_get(configuration: &configuration::Configuration, ) -> Result, Error> { +pub async fn owned_games_get(configuration: &configuration::Configuration, user_id: Option) -> Result, Error> { + // add a prefix to parameters to efficiently prevent name collisions + let p_user_id = user_id; let uri_str = format!("{}/owned_games", configuration.base_path); let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str); @@ -516,6 +518,7 @@ pub async fn owned_games_get(configuration: &configuration::Configuration, ) -> if let Some(ref token) = configuration.bearer_access_token { req_builder = req_builder.bearer_auth(token.to_owned()); }; + req_builder = req_builder.json(&p_user_id); let req = req_builder.build()?; let resp = configuration.client.execute(req).await?; diff --git a/gamenight-cli/src/flows/mod.rs b/gamenight-cli/src/flows/mod.rs index 7315655..7606f59 100644 --- a/gamenight-cli/src/flows/mod.rs +++ b/gamenight-cli/src/flows/mod.rs @@ -6,6 +6,9 @@ use gamenight_api_client_rs::apis::{configuration::Configuration, Error}; use inquire::InquireError; use dyn_clone::DynClone; pub use clear_screen; +use jsonwebtoken::{decode, DecodingKey, Validation}; +use serde::{Deserialize, Serialize}; +use uuid::Uuid; use crate::domain::config::{Config, ConfigError}; @@ -33,6 +36,12 @@ pub struct GamenightState { gamenight_configuration: Config, } +#[derive(Debug, Serialize, Deserialize)] +pub struct Claims { + exp: i64, + uid: Uuid +} + impl GamenightState { pub fn new() -> Self{ Self { @@ -40,6 +49,18 @@ impl GamenightState { gamenight_configuration: Config::new() } } + + pub fn get_user_id(&self) -> Result { + let decoding_key = DecodingKey::from_secret(b""); + let mut validation = Validation::default(); + validation.insecure_disable_signature_validation(); + let claims = decode::( + self.api_configuration.bearer_access_token.as_ref().unwrap(), + &decoding_key, + &validation)?.claims; + + Ok(claims.uid) + } } impl Default for GamenightState { diff --git a/gamenight-cli/src/flows/view_game.rs b/gamenight-cli/src/flows/view_game.rs index 89a6fc8..d869bdf 100644 --- a/gamenight-cli/src/flows/view_game.rs +++ b/gamenight-cli/src/flows/view_game.rs @@ -1,5 +1,5 @@ -use gamenight_api_client_rs::{apis::default_api::{game_get, owned_games_get}, models::GameId}; +use gamenight_api_client_rs::{apis::default_api::{game_get, owned_games_get}, models::{GameId, UserId}}; use inquire::Select; use uuid::Uuid; @@ -28,10 +28,13 @@ impl<'a> Flow<'a> for ViewGame { println!("{}", game); - let owned_games: Vec = owned_games_get(&state.api_configuration).await?.iter().map(|x| -> Result { Ok(Uuid::parse_str(x)?) }).collect::, FlowError>>()?; + let my_uid = state.get_user_id()?; + let request = UserId{ user_id: my_uid.to_string() }; + let owned_games: Vec = owned_games_get(&state.api_configuration, Some(request)).await? + .iter().map(|x| -> Result { + Ok(Uuid::parse_str(x)?) + }).collect::, FlowError>>()?; - println!("game_id {:?}, owned_games {:?}", game.id, owned_games); - let own_or_disown: Box + Send> = if owned_games.into_iter().any(|x| x == game.id) { Box::new(Disown::new(self.game.id)) diff --git a/gamenight-cli/src/flows/view_gamenight.rs b/gamenight-cli/src/flows/view_gamenight.rs index 22c3c4d..a2757e6 100644 --- a/gamenight-cli/src/flows/view_gamenight.rs +++ b/gamenight-cli/src/flows/view_gamenight.rs @@ -1,8 +1,6 @@ use gamenight_api_client_rs::{apis::default_api::{participants_get, user_get}, models::{GamenightId, UserId}}; use inquire::Select; -use jsonwebtoken::{decode, DecodingKey, Validation}; -use serde::{Deserialize, Serialize}; use uuid::Uuid; use crate::{domain::{gamenight::Gamenight, participants::Participants, user::User}, flows::{exit::Exit, join::Join, leave::Leave}}; @@ -22,15 +20,6 @@ impl ViewGamenight { } } - - - -#[derive(Debug, Serialize, Deserialize)] -pub struct Claims { - exp: i64, - uid: Uuid -} - impl From for FlowError { fn from(value: jsonwebtoken::errors::Error) -> Self { Self { @@ -54,16 +43,10 @@ impl<'a> Flow<'a> for ViewGamenight { } println!("{}\nwho: {}", self.gamenight, Participants(&users)); - let decoding_key = DecodingKey::from_secret(b""); - let mut validation = Validation::default(); - validation.insecure_disable_signature_validation(); - let claims = decode::( - state.api_configuration.bearer_access_token.as_ref().unwrap(), - &decoding_key, - &validation)?.claims; - + + let my_uid = state.get_user_id()?; let join_or_leave: Box + Send> = - if users.iter().map(|x| {x.id}).any(|x| x == claims.uid) { + if users.iter().map(|x| {x.id}).any(|x| x == my_uid) { Box::new(Leave::new(self.gamenight.id)) } else {