diff --git a/.sqlx/query-beb8e02f9025879aa08de5ce2b55f17e3645f682a474d72eabb2f5bce8403b98.json b/.sqlx/query-beb8e02f9025879aa08de5ce2b55f17e3645f682a474d72eabb2f5bce8403b98.json new file mode 100644 index 0000000000..082e75d539 --- /dev/null +++ b/.sqlx/query-beb8e02f9025879aa08de5ce2b55f17e3645f682a474d72eabb2f5bce8403b98.json @@ -0,0 +1,12 @@ +{ + "db_name": "MySQL", + "query": "\nUPDATE beta_keys\nSET\n is_distributed = ?\nWHERE\n token = ?\nLIMIT 1\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 2 + }, + "nullable": [] + }, + "hash": "beb8e02f9025879aa08de5ce2b55f17e3645f682a474d72eabb2f5bce8403b98" +} diff --git a/crates/lib/mysql_queries/src/queries/beta_keys/edit_beta_key_distributed_flag.rs b/crates/lib/mysql_queries/src/queries/beta_keys/edit_beta_key_distributed_flag.rs new file mode 100644 index 0000000000..4c27c04826 --- /dev/null +++ b/crates/lib/mysql_queries/src/queries/beta_keys/edit_beta_key_distributed_flag.rs @@ -0,0 +1,30 @@ +use sqlx::{Executor, MySql}; + +use errors::AnyhowResult; +use tokens::tokens::beta_keys::BetaKeyToken; + +pub async fn edit_beta_key_distributed_flag<'a, 'e, E>( + token: &'a BetaKeyToken, + is_distributed: bool, + mysql_executor: E +) + -> AnyhowResult<()> + where E: 'a + Executor<'e, Database = MySql> +{ + sqlx::query!( + r#" +UPDATE beta_keys +SET + is_distributed = ? +WHERE + token = ? +LIMIT 1 + "#, + is_distributed, + token.as_str(), + ) + .execute(mysql_executor) + .await?; + + Ok(()) +} diff --git a/crates/lib/mysql_queries/src/queries/beta_keys/mod.rs b/crates/lib/mysql_queries/src/queries/beta_keys/mod.rs index 14b4de59eb..a64815a931 100644 --- a/crates/lib/mysql_queries/src/queries/beta_keys/mod.rs +++ b/crates/lib/mysql_queries/src/queries/beta_keys/mod.rs @@ -1,5 +1,6 @@ +pub mod edit_beta_key_distributed_flag; +pub mod edit_beta_key_note; pub mod get_beta_key_by_value; pub mod insert_batch_beta_keys; pub mod list_beta_keys; -pub mod redeem_beta_key; -pub mod edit_beta_key_note; \ No newline at end of file +pub mod redeem_beta_key; \ No newline at end of file diff --git a/crates/service/web/storyteller_web/src/api_doc.rs b/crates/service/web/storyteller_web/src/api_doc.rs index a2858ebb72..ce06dc42c7 100644 --- a/crates/service/web/storyteller_web/src/api_doc.rs +++ b/crates/service/web/storyteller_web/src/api_doc.rs @@ -51,6 +51,7 @@ use crate::http_server::common_responses::simple_entity_stats::SimpleEntityStats use crate::http_server::common_responses::weights_cover_image_details::*; use crate::http_server::endpoints::analytics::log_browser_session_handler::*; use crate::http_server::endpoints::beta_keys::create_beta_keys_handler::*; +use crate::http_server::endpoints::beta_keys::edit_beta_key_distributed_flag_handler::*; use crate::http_server::endpoints::beta_keys::edit_beta_key_note_handler::*; use crate::http_server::endpoints::beta_keys::list_beta_keys_handler::*; use crate::http_server::endpoints::beta_keys::redeem_beta_key_handler::*; @@ -124,6 +125,7 @@ use crate::http_server::web_utils::response_success_helpers::*; billing_component::stripe::http_endpoints::checkout::create::stripe_create_checkout_session_json_handler::stripe_create_checkout_session_json_handler, crate::http_server::endpoints::analytics::log_browser_session_handler::log_browser_session_handler, crate::http_server::endpoints::beta_keys::create_beta_keys_handler::create_beta_keys_handler, + crate::http_server::endpoints::beta_keys::edit_beta_key_distributed_flag_handler::edit_beta_key_distributed_flag_handler, crate::http_server::endpoints::beta_keys::edit_beta_key_note_handler::edit_beta_key_note_handler, crate::http_server::endpoints::beta_keys::list_beta_keys_handler::list_beta_keys_handler, crate::http_server::endpoints::beta_keys::redeem_beta_key_handler::redeem_beta_key_handler, @@ -302,6 +304,10 @@ use crate::http_server::web_utils::response_success_helpers::*; DeleteWeightError, DeleteWeightPathInfo, DeleteWeightRequest, + EditBetaKeyDistributedFlagError, + EditBetaKeyDistributedFlagPathInfo, + EditBetaKeyDistributedFlagRequest, + EditBetaKeyDistributedFlagSuccessResponse, EditBetaKeyNoteError, EditBetaKeyNotePathInfo, EditBetaKeyNoteRequest, diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/beta_keys/edit_beta_key_distributed_flag_handler.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/beta_keys/edit_beta_key_distributed_flag_handler.rs new file mode 100644 index 0000000000..b17d55f9e3 --- /dev/null +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/beta_keys/edit_beta_key_distributed_flag_handler.rs @@ -0,0 +1,138 @@ +use std::fmt; +use std::sync::Arc; + +use actix_web::{HttpRequest, HttpResponse, web}; +use actix_web::error::ResponseError; +use actix_web::http::StatusCode; +use actix_web::web::Path; +use log::warn; +use utoipa::ToSchema; + +use crockford::crockford_entropy_lower; +use enums::by_table::beta_keys::beta_key_product::BetaKeyProduct; +use enums::by_table::comments::comment_entity_type::CommentEntityType; +use http_server_common::request::get_request_ip::get_request_ip; +use mysql_queries::queries::beta_keys::edit_beta_key_distributed_flag::edit_beta_key_distributed_flag; +use mysql_queries::queries::beta_keys::edit_beta_key_note::edit_beta_key_note; +use mysql_queries::queries::beta_keys::insert_batch_beta_keys::{insert_batch_beta_keys, InsertBatchArgs}; +use mysql_queries::queries::comments::comment_entity_token::CommentEntityToken; +use mysql_queries::queries::comments::insert_comment::{insert_comment, InsertCommentArgs}; +use mysql_queries::queries::users::user_profiles::get_user_profile_by_username::get_user_profile_by_username; +use tokens::tokens::beta_keys::BetaKeyToken; +use tokens::tokens::comments::CommentToken; +use tokens::tokens::media_files::MediaFileToken; +use tokens::tokens::model_weights::ModelWeightToken; +use tokens::tokens::tts_models::TtsModelToken; +use tokens::tokens::tts_results::TtsResultToken; +use tokens::tokens::users::UserToken; +use tokens::tokens::w2l_results::W2lResultToken; +use tokens::tokens::w2l_templates::W2lTemplateToken; +use user_input_common::check_for_slurs::contains_slurs; +use user_input_common::markdown_to_html::markdown_to_html; + +use crate::http_server::endpoints::media_files::get::get_media_file_handler::GetMediaFilePathInfo; +use crate::http_server::endpoints::moderation::user_feature_flags::edit_user_feature_flags_handler::EditUserFeatureFlagsError; +use crate::http_server::web_utils::require_moderator::{require_moderator, RequireModeratorError, UseDatabase}; +use crate::http_server::web_utils::response_error_helpers::to_simple_json_error; +use crate::server_state::ServerState; + +/// For the URL PathInfo +#[derive(Deserialize, ToSchema)] +pub struct EditBetaKeyDistributedFlagPathInfo { + token: BetaKeyToken, +} + +#[derive(Deserialize, ToSchema)] +pub struct EditBetaKeyDistributedFlagRequest { + /// Whether to mark the flag as "distributed", i.e. we gave the key to someone. + /// This will help us not to give out the same key twice. + is_distributed: bool, +} + +#[derive(Serialize, ToSchema)] +pub struct EditBetaKeyDistributedFlagSuccessResponse { + pub success: bool, +} + +#[derive(Debug, ToSchema)] +pub enum EditBetaKeyDistributedFlagError { + BadInput(String), + NotAuthorized, + ServerError, +} + +impl ResponseError for EditBetaKeyDistributedFlagError { + fn status_code(&self) -> StatusCode { + match *self { + EditBetaKeyDistributedFlagError::BadInput(_) => StatusCode::BAD_REQUEST, + EditBetaKeyDistributedFlagError::NotAuthorized => StatusCode::UNAUTHORIZED, + EditBetaKeyDistributedFlagError::ServerError => StatusCode::INTERNAL_SERVER_ERROR, + } + } + + fn error_response(&self) -> HttpResponse { + let error_reason = match self { + EditBetaKeyDistributedFlagError::BadInput(reason) => reason.to_string(), + EditBetaKeyDistributedFlagError::NotAuthorized => "unauthorized".to_string(), + EditBetaKeyDistributedFlagError::ServerError => "server error".to_string(), + }; + + to_simple_json_error(&error_reason, self.status_code()) + } +} + +// NB: Not using derive_more::Display since Clion doesn't understand it. +impl fmt::Display for EditBetaKeyDistributedFlagError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self) + } +} + +/// Edit the "distributed" flag on a beta key to mark it as shared +#[utoipa::path( + post, + tag = "Beta Keys", + path = "/v1/beta_keys/{token}/distributed", + responses( + (status = 200, description = "Success", body = EditBetaKeyDistributedFlagSuccessResponse), + (status = 400, description = "Bad input", body = EditBetaKeyDistributedFlagError), + (status = 401, description = "Not authorized", body = EditBetaKeyDistributedFlagError), + (status = 500, description = "Server error", body = EditBetaKeyDistributedFlagError), + ), + params( + ("request" = EditBetaKeyDistributedFlagRequest, description = "Payload for Request"), + ("path" = EditBetaKeyDistributedFlagPathInfo, description = "Path for Request") + ) +)] +pub async fn edit_beta_key_distributed_flag_handler( + http_request: HttpRequest, + request: web::Json, + path: Path, + server_state: web::Data>, +) -> Result +{ + let user_session = require_moderator(&http_request, &server_state, UseDatabase::Implicit) + .await + .map_err(|err| match err { + RequireModeratorError::ServerError => EditBetaKeyDistributedFlagError::ServerError, + RequireModeratorError::NotAuthorized => EditBetaKeyDistributedFlagError::NotAuthorized, + })?; + + edit_beta_key_distributed_flag(&path.token, request.is_distributed, &server_state.mysql_pool) + .await + .map_err(|err| { + warn!("Error editing beta key note: {:?}", err); + EditBetaKeyDistributedFlagError::ServerError + })?; + + let response = EditBetaKeyDistributedFlagSuccessResponse { + success: true, + }; + + let body = serde_json::to_string(&response) + .map_err(|_e| EditBetaKeyDistributedFlagError::ServerError)?; + + Ok(HttpResponse::Ok() + .content_type("application/json") + .body(body)) +} diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/beta_keys/mod.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/beta_keys/mod.rs index debea7fffa..e98ff1a4b8 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/beta_keys/mod.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/beta_keys/mod.rs @@ -1,4 +1,5 @@ pub mod create_beta_keys_handler; +pub mod edit_beta_key_distributed_flag_handler; pub mod edit_beta_key_note_handler; pub mod list_beta_keys_handler; pub mod redeem_beta_key_handler; \ No newline at end of file diff --git a/crates/service/web/storyteller_web/src/routes/beta_key_routes.rs b/crates/service/web/storyteller_web/src/routes/beta_key_routes.rs index 0132831354..f632d1a998 100644 --- a/crates/service/web/storyteller_web/src/routes/beta_key_routes.rs +++ b/crates/service/web/storyteller_web/src/routes/beta_key_routes.rs @@ -4,6 +4,7 @@ use actix_web::{App, Error, HttpResponse, web}; use actix_web::dev::{ServiceRequest, ServiceResponse}; use crate::http_server::endpoints::beta_keys::create_beta_keys_handler::create_beta_keys_handler; +use crate::http_server::endpoints::beta_keys::edit_beta_key_distributed_flag_handler::edit_beta_key_distributed_flag_handler; use crate::http_server::endpoints::beta_keys::edit_beta_key_note_handler::edit_beta_key_note_handler; use crate::http_server::endpoints::beta_keys::list_beta_keys_handler::list_beta_keys_handler; use crate::http_server::endpoints::beta_keys::redeem_beta_key_handler::redeem_beta_key_handler; @@ -36,5 +37,9 @@ pub fn add_beta_key_routes (app: App) -> App .route(web::post().to(edit_beta_key_note_handler)) .route(web::head().to(|| HttpResponse::Ok())) ) + .service(web::resource("/{token}/distributed") + .route(web::post().to(edit_beta_key_distributed_flag_handler)) + .route(web::head().to(|| HttpResponse::Ok())) + ) ) }