Implemented deleting games as admin.
This commit is contained in:
@@ -201,9 +201,21 @@ paths:
|
||||
$ref: '#/components/requestBodies/AddGameRequest'
|
||||
security:
|
||||
- JWT-Auth: []
|
||||
delete:
|
||||
responses:
|
||||
'200':
|
||||
description: "Ok"
|
||||
'401':
|
||||
$ref: '#/components/responses/FailureResponse'
|
||||
'422':
|
||||
$ref: '#/components/responses/FailureResponse'
|
||||
requestBody:
|
||||
$ref: '#/components/requestBodies/RemoveGameRequest'
|
||||
security:
|
||||
- JWT-Auth: [ ]
|
||||
/rename_game:
|
||||
post:
|
||||
responses:
|
||||
responses:
|
||||
'200':
|
||||
description: "OK"
|
||||
'401':
|
||||
@@ -315,9 +327,6 @@ paths:
|
||||
$ref: '#/components/requestBodies/AuthorizedLocationUserIdsRequest'
|
||||
security:
|
||||
- JWT-Auth: []
|
||||
|
||||
|
||||
|
||||
components:
|
||||
schemas:
|
||||
Gamenight:
|
||||
@@ -590,6 +599,11 @@ components:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenameGameRequestBody'
|
||||
RemoveGameRequest:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GameId'
|
||||
OwnGameRequest:
|
||||
content:
|
||||
application/json:
|
||||
|
||||
@@ -56,6 +56,7 @@ async fn main() -> std::io::Result<()> {
|
||||
.service(post_own_game)
|
||||
.service(post_disown_game)
|
||||
.service(get_owned_games)
|
||||
.service(delete_game)
|
||||
.service(get_locations)
|
||||
.service(post_location)
|
||||
.service(post_location_authorize)
|
||||
|
||||
@@ -21,13 +21,6 @@ pub struct Claims {
|
||||
|
||||
pub struct AuthUser(pub User);
|
||||
|
||||
// pub struct AuthUser {
|
||||
// pub id: Uuid,
|
||||
// pub username: String,
|
||||
// pub email: String,
|
||||
// pub role: Role,
|
||||
// }
|
||||
|
||||
impl From<User> for AuthUser {
|
||||
fn from(value: User) -> Self {
|
||||
Self(value)
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
use actix_web::{get, http::header::ContentType, post, web, HttpResponse, Responder};
|
||||
use crate::game::rename_game;
|
||||
use crate::owned_game::own_game;
|
||||
use crate::owned_game::owned_games;
|
||||
use crate::owned_game::disown_game;
|
||||
use crate::owned_game::OwnedGame;
|
||||
use gamenight_database::game::load_game;
|
||||
use crate::game::insert_game;
|
||||
use uuid::Uuid;
|
||||
use crate::game::remove_game;
|
||||
use actix_web::{delete, get, http::header::ContentType, post, web, HttpResponse, Responder};
|
||||
use gamenight_database::{
|
||||
game::{insert_game, load_game, rename_game},
|
||||
owned_game::{disown_game, own_game, owned_games, OwnedGame},
|
||||
user::Role,
|
||||
DbPool, GetConnection,
|
||||
};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
models::{
|
||||
@@ -77,6 +84,22 @@ pub async fn post_game(
|
||||
.body(serde_json::to_string(&GameId{game_id: game.id.to_string()})?))
|
||||
}
|
||||
|
||||
#[delete("/game")]
|
||||
pub async fn delete_game(
|
||||
pool: web::Data<DbPool>,
|
||||
user: AuthUser,
|
||||
game_id: web::Json<GameId>,
|
||||
) -> Result<impl Responder, ApiError> {
|
||||
if user.0.role != Role::Admin {
|
||||
Ok(HttpResponse::Unauthorized())
|
||||
} else {
|
||||
let mut conn = pool.get_conn();
|
||||
remove_game(&mut conn, Uuid::parse_str(&game_id.0.game_id)?)?;
|
||||
|
||||
Ok(HttpResponse::Ok())
|
||||
}
|
||||
}
|
||||
|
||||
#[post("/rename_game")]
|
||||
pub async fn post_rename_game(
|
||||
pool: web::Data<DbPool>,
|
||||
|
||||
@@ -15,6 +15,7 @@ pub use game::post_disown_game;
|
||||
pub use game::post_game;
|
||||
pub use game::post_own_game;
|
||||
pub use game::post_rename_game;
|
||||
pub use game::delete_game;
|
||||
pub use gamenight_handlers::gamenight_get;
|
||||
pub use gamenight_handlers::gamenight_post;
|
||||
pub use gamenight_handlers::gamenights;
|
||||
|
||||
@@ -29,6 +29,7 @@ Class | Method | HTTP request | Description
|
||||
------------ | ------------- | ------------- | -------------
|
||||
*DefaultApi* | [**authorized_location_user_ids_get**](docs/DefaultApi.md#authorized_location_user_ids_get) | **GET** /authorized_location_user_ids |
|
||||
*DefaultApi* | [**disown_post**](docs/DefaultApi.md#disown_post) | **POST** /disown |
|
||||
*DefaultApi* | [**game_delete**](docs/DefaultApi.md#game_delete) | **DELETE** /game |
|
||||
*DefaultApi* | [**game_get**](docs/DefaultApi.md#game_get) | **GET** /game |
|
||||
*DefaultApi* | [**game_post**](docs/DefaultApi.md#game_post) | **POST** /game |
|
||||
*DefaultApi* | [**games_get**](docs/DefaultApi.md#games_get) | **GET** /games |
|
||||
|
||||
@@ -6,6 +6,7 @@ Method | HTTP request | Description
|
||||
------------- | ------------- | -------------
|
||||
[**authorized_location_user_ids_get**](DefaultApi.md#authorized_location_user_ids_get) | **GET** /authorized_location_user_ids |
|
||||
[**disown_post**](DefaultApi.md#disown_post) | **POST** /disown |
|
||||
[**game_delete**](DefaultApi.md#game_delete) | **DELETE** /game |
|
||||
[**game_get**](DefaultApi.md#game_get) | **GET** /game |
|
||||
[**game_post**](DefaultApi.md#game_post) | **POST** /game |
|
||||
[**games_get**](DefaultApi.md#games_get) | **GET** /games |
|
||||
@@ -86,6 +87,34 @@ Name | Type | Description | Required | Notes
|
||||
[[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)
|
||||
|
||||
|
||||
## game_delete
|
||||
|
||||
> game_delete(game_id)
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Required | Notes
|
||||
------------- | ------------- | ------------- | ------------- | -------------
|
||||
**game_id** | Option<[**GameId**](GameId.md)> | | |
|
||||
|
||||
### Return type
|
||||
|
||||
(empty response body)
|
||||
|
||||
### Authorization
|
||||
|
||||
[JWT-Auth](../README.md#JWT-Auth)
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **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)
|
||||
|
||||
|
||||
## game_get
|
||||
|
||||
> models::Game game_get(game_id)
|
||||
|
||||
@@ -33,6 +33,15 @@ pub enum DisownPostError {
|
||||
UnknownValue(serde_json::Value),
|
||||
}
|
||||
|
||||
/// struct for typed errors of method [`game_delete`]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum GameDeleteError {
|
||||
Status401(models::Failure),
|
||||
Status422(models::Failure),
|
||||
UnknownValue(serde_json::Value),
|
||||
}
|
||||
|
||||
/// struct for typed errors of method [`game_get`]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
@@ -290,6 +299,35 @@ pub async fn disown_post(configuration: &configuration::Configuration, game_id:
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn game_delete(configuration: &configuration::Configuration, game_id: Option<models::GameId>) -> Result<(), Error<GameDeleteError>> {
|
||||
// add a prefix to parameters to efficiently prevent name collisions
|
||||
let p_body_game_id = game_id;
|
||||
|
||||
let uri_str = format!("{}/game", configuration.base_path);
|
||||
let mut req_builder = configuration.client.request(reqwest::Method::DELETE, &uri_str);
|
||||
|
||||
if let Some(ref user_agent) = configuration.user_agent {
|
||||
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
|
||||
}
|
||||
if let Some(ref token) = configuration.bearer_access_token {
|
||||
req_builder = req_builder.bearer_auth(token.to_owned());
|
||||
};
|
||||
req_builder = req_builder.json(&p_body_game_id);
|
||||
|
||||
let req = req_builder.build()?;
|
||||
let resp = configuration.client.execute(req).await?;
|
||||
|
||||
let status = resp.status();
|
||||
|
||||
if !status.is_client_error() && !status.is_server_error() {
|
||||
Ok(())
|
||||
} else {
|
||||
let content = resp.text().await?;
|
||||
let entity: Option<GameDeleteError> = serde_json::from_str(&content).ok();
|
||||
Err(Error::ResponseError(ResponseContent { status, content, entity }))
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn game_get(configuration: &configuration::Configuration, game_id: Option<models::GameId>) -> Result<models::Game, Error<GameGetError>> {
|
||||
// add a prefix to parameters to efficiently prevent name collisions
|
||||
let p_body_game_id = game_id;
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use gamenight_api_client_rs::{apis::default_api::game_post, models::AddGameRequestBody, models::OwnGameRequestBody};
|
||||
use gamenight_api_client_rs::apis::default_api::{locations_get, own_post};
|
||||
use inquire::{Confirm, Select, Text};
|
||||
use crate::flows::flow_helpers::LocationSelectData;
|
||||
use crate::flows::own::Own;
|
||||
use super::*;
|
||||
use crate::flows::own::Own;
|
||||
use async_trait::async_trait;
|
||||
use gamenight_api_client_rs::{apis::default_api::game_post, models::AddGameRequestBody};
|
||||
use inquire::Text;
|
||||
|
||||
|
||||
#[derive(Clone)]
|
||||
|
||||
@@ -36,6 +36,7 @@ mod view_location;
|
||||
mod add_location;
|
||||
mod location_authorize;
|
||||
mod flow_helpers;
|
||||
mod remove_game;
|
||||
|
||||
pub struct GamenightState {
|
||||
api_configuration: Configuration,
|
||||
@@ -140,7 +141,7 @@ impl From<jsonwebtoken::errors::Error> for FlowError {
|
||||
pub enum FlowOutcome {
|
||||
Successful,
|
||||
Cancelled,
|
||||
Abort
|
||||
Abort,
|
||||
}
|
||||
|
||||
type FlowResult<'a> = Result<(FlowOutcome, &'a mut GamenightState), FlowError>;
|
||||
|
||||
38
gamenight-cli/src/flows/remove_game.rs
Normal file
38
gamenight-cli/src/flows/remove_game.rs
Normal file
@@ -0,0 +1,38 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use gamenight_api_client_rs::models::GameId;
|
||||
|
||||
use super::{Flow, FlowResult, GamenightState};
|
||||
use crate::domain::game::Game;
|
||||
use crate::flows::list_games::ListGames;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct RemoveGame {
|
||||
pub game: Game
|
||||
}
|
||||
|
||||
impl RemoveGame {
|
||||
pub fn new(game: Game) -> Self {
|
||||
Self{
|
||||
game
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<'a> Flow<'a> for RemoveGame {
|
||||
async fn run(&self, state: &'a mut GamenightState) -> FlowResult<'a> {
|
||||
let req = GameId {
|
||||
game_id: self.game.id.to_string()
|
||||
};
|
||||
gamenight_api_client_rs::apis::default_api::game_delete(&state.api_configuration, Some(req)).await?;
|
||||
self.continue_with(state, &ListGames::new()).await
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for RemoveGame {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "Remove")
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ use inquire::Select;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{domain::game::Game, flows::{disown::Disown, exit::Exit, own::Own, rename_game::RenameGame}};
|
||||
|
||||
use crate::flows::remove_game::RemoveGame;
|
||||
use super::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -45,6 +45,7 @@ impl<'a> Flow<'a> for ViewGame {
|
||||
|
||||
let options: Vec<Box<dyn Flow<'a> + Send>> = vec![
|
||||
own_or_disown,
|
||||
Box::new(RemoveGame::new(game.clone())),
|
||||
Box::new(RenameGame::new(game.clone())),
|
||||
Box::new(Exit::new())
|
||||
];
|
||||
|
||||
@@ -35,3 +35,10 @@ pub fn rename_game(
|
||||
.set(game::name.eq(&name))
|
||||
.execute(conn)?)
|
||||
}
|
||||
|
||||
pub fn remove_game(
|
||||
conn: &mut DbConnection,
|
||||
id: Uuid,
|
||||
) -> Result<usize, DatabaseError> {
|
||||
Ok(diesel::delete(game::table.filter(game::id.eq(id))).execute(conn)?)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user