diff --git a/crates/service/web/storyteller_web/src/docs/api_doc.rs b/crates/service/web/storyteller_web/src/docs/api_doc.rs index ac7e2ea306..d39ed64263 100644 --- a/crates/service/web/storyteller_web/src/docs/api_doc.rs +++ b/crates/service/web/storyteller_web/src/docs/api_doc.rs @@ -86,6 +86,7 @@ use crate::http_server::endpoints::media_files::upsert_upload::write_error::Medi use crate::http_server::endpoints::media_files::upsert_upload::write_scene_file::write_scene_file_media_file_handler::*; use crate::http_server::endpoints::model_download::enqueue_gptsovits_model_download_handler::*; use crate::http_server::endpoints::moderation::user_feature_flags::moderator_edit_user_feature_flags_handler::*; +use crate::http_server::endpoints::moderation::user_feature_flags::moderator_list_user_feature_flags_handler::*; use crate::http_server::endpoints::moderation::staff_audit_logs::moderator_list_staff_audit_logs_handler::*; use crate::http_server::endpoints::moderation::user_bans::moderation_ban_user_handler::*; use crate::http_server::endpoints::moderation::user_sessions::moderator_list_user_session_impersonation_requests_for_user_handler::*; @@ -398,6 +399,7 @@ use crate::http_server::endpoints::media_files::list::list_batch_generated_redux crate::http_server::endpoints::media_files::upsert_upload::write_scene_file::write_scene_file_media_file_handler::write_scene_file_media_file_handler, crate::http_server::endpoints::model_download::enqueue_gptsovits_model_download_handler::enqueue_gptsovits_model_download_handler, crate::http_server::endpoints::moderation::user_feature_flags::moderator_edit_user_feature_flags_handler::moderator_edit_user_feature_flags_handler, + crate::http_server::endpoints::moderation::user_feature_flags::moderator_list_user_feature_flags_handler::moderator_list_user_feature_flags_handler, crate::http_server::endpoints::prompts::create_prompt_handler::create_prompt_handler, crate::http_server::endpoints::prompts::get_prompt_handler::get_prompt_handler, crate::http_server::endpoints::service::status_alert_handler::status_alert_handler, diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/moderation/user_feature_flags/mod.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/moderation/user_feature_flags/mod.rs index e67776faf2..15514cf2aa 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/moderation/user_feature_flags/mod.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/moderation/user_feature_flags/mod.rs @@ -1 +1,2 @@ pub mod moderator_edit_user_feature_flags_handler; +pub mod moderator_list_user_feature_flags_handler; diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/moderation/user_feature_flags/moderator_list_user_feature_flags_handler.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/moderation/user_feature_flags/moderator_list_user_feature_flags_handler.rs new file mode 100644 index 0000000000..bb491e7c6c --- /dev/null +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/moderation/user_feature_flags/moderator_list_user_feature_flags_handler.rs @@ -0,0 +1,74 @@ +use std::sync::Arc; + +use actix_web::web::Json; +use actix_web::{web, HttpRequest}; +use log::warn; +use utoipa::ToSchema; + +use enums::by_table::users::user_feature_flag::UserFeatureFlag; + +use crate::http_server::common_responses::advanced_common_web_error::AdvancedCommonWebError; +use crate::http_server::web_utils::user_session::require_moderator::{ + require_moderator, UseDatabase, +}; +use crate::state::server_state::ServerState; + +// ── Response ── + +#[derive(Serialize, ToSchema)] +pub struct ModeratorListUserFeatureFlagsResponse { + pub success: bool, + pub feature_flags: Vec, +} + +#[derive(Serialize, ToSchema)] +pub struct FeatureFlagDescriptor { + /// Full name of the flag + pub full_name: String, + + /// Description of the flag + pub description: String, + + /// Key the flag is identified by + pub key: String, +} + +// ── Handler ── + +/// List all available user feature flags. +#[utoipa::path( + get, + tag = "Moderation", + path = "/v1/moderation/user_feature_flags/list", + responses( + (status = 200, description = "Success", body = ModeratorListUserFeatureFlagsResponse), + (status = 401, description = "Unauthorized"), + ), +)] +pub async fn moderator_list_user_feature_flags_handler( + http_request: HttpRequest, + server_state: web::Data>, +) -> Result, AdvancedCommonWebError> { + let _user_session = require_moderator( + &http_request, + &server_state, + UseDatabase::GrabNewConnection, + ).await.map_err(|err| { + warn!("Moderator check failed: {:?}", err); + AdvancedCommonWebError::NotAuthorized + })?; + + let feature_flags: Vec = UserFeatureFlag::all_variants() + .into_iter() + .map(|flag| FeatureFlagDescriptor { + full_name: flag.name().to_string(), + description: flag.description().to_string(), + key: flag.to_str().to_string(), + }) + .collect(); + + Ok(Json(ModeratorListUserFeatureFlagsResponse { + success: true, + feature_flags, + })) +} diff --git a/crates/service/web/storyteller_web/src/http_server/routes/application_routes/moderation_routes.rs b/crates/service/web/storyteller_web/src/http_server/routes/application_routes/moderation_routes.rs index 62afce2112..cf999104c1 100644 --- a/crates/service/web/storyteller_web/src/http_server/routes/application_routes/moderation_routes.rs +++ b/crates/service/web/storyteller_web/src/http_server/routes/application_routes/moderation_routes.rs @@ -37,6 +37,7 @@ use crate::http_server::endpoints::moderation::user::moderator_user_lookup_handl use crate::http_server::endpoints::moderation::alerts::moderation_send_alert_handler::moderation_send_alert_handler; use crate::http_server::endpoints::moderation::staff_audit_logs::moderator_list_staff_audit_logs_handler::moderator_list_staff_audit_logs_handler; use crate::http_server::endpoints::moderation::user_feature_flags::moderator_edit_user_feature_flags_handler::moderator_edit_user_feature_flags_handler; +use crate::http_server::endpoints::moderation::user_feature_flags::moderator_list_user_feature_flags_handler::moderator_list_user_feature_flags_handler; use crate::http_server::endpoints::moderation::user_sessions::moderator_list_user_session_impersonation_requests_for_user_handler::moderator_list_user_session_impersonation_requests_for_user_handler; use crate::http_server::endpoints::moderation::user_sessions::moderator_list_user_session_impersonation_requests_handler::moderator_list_user_session_impersonation_requests_handler; use crate::http_server::endpoints::moderation::user_sessions::moderator_user_session_impersonation_request_handler::moderator_user_session_impersonation_request_handler; @@ -59,6 +60,10 @@ pub fn add_moderator_routes (app: App) -> App .route(web::head().to(|| HttpResponse::Ok())) ) ) + .service(web::resource("/user_feature_flags/list") + .route(web::get().to(moderator_list_user_feature_flags_handler)) + .route(web::head().to(|| HttpResponse::Ok())) + ) .service(web::resource("/user_feature_flags/user/{username_or_token}") .route(web::post().to(moderator_edit_user_feature_flags_handler)) .route(web::head().to(|| HttpResponse::Ok()))