diff --git a/crates/lib/database_queries/src/queries/twitch/twitch_event_rules/list_twitch_event_rules_for_user.rs b/crates/lib/database_queries/src/queries/twitch/twitch_event_rules/list_twitch_event_rules_for_user.rs index a3c6b42a01..f8290809d9 100644 --- a/crates/lib/database_queries/src/queries/twitch/twitch_event_rules/list_twitch_event_rules_for_user.rs +++ b/crates/lib/database_queries/src/queries/twitch/twitch_event_rules/list_twitch_event_rules_for_user.rs @@ -5,8 +5,8 @@ use crate::column_types::twitch_event_category::TwitchEventCategory; use crate::helpers::boolean_converters::i8_to_bool; use sqlx::MySqlPool; -/// table: api_tokens -#[derive(Debug)] +// TODO: This is exposed to the frontend. Write a different struct. +#[derive(Debug, Serialize)] pub struct TwitchEventRule { pub token: String, pub event_category: TwitchEventCategory, diff --git a/crates/lib/database_queries/src/tokens.rs b/crates/lib/database_queries/src/tokens.rs index 20fb8abef8..b99f06bae2 100644 --- a/crates/lib/database_queries/src/tokens.rs +++ b/crates/lib/database_queries/src/tokens.rs @@ -68,7 +68,7 @@ impl Tokens { } pub fn new_api_token_internal_token() -> AnyhowResult { - random_prefix_crockford_token("AIT:", 32, false) + random_prefix_crockford_token("INT_API:", 32, false) } // ========== [Twitch] Tokens not typically visible to users ========== diff --git a/crates/service/storyteller_web/src/http_server/endpoints/api_tokens/create_api_token.rs b/crates/service/storyteller_web/src/http_server/endpoints/api_tokens/create_api_token.rs index c45016a671..7d8169f506 100644 --- a/crates/service/storyteller_web/src/http_server/endpoints/api_tokens/create_api_token.rs +++ b/crates/service/storyteller_web/src/http_server/endpoints/api_tokens/create_api_token.rs @@ -12,6 +12,7 @@ use crate::http_server::web_utils::response_success_helpers::simple_json_success use crate::server_state::ServerState; use crate::util::email_to_gravatar::email_to_gravatar; use crate::util::markdown_to_html::markdown_to_html; +use database_queries::queries::api_tokens::create_api_token::create_api_token_for_user; use database_queries::tokens::Tokens; use http_server_common::response::serialize_as_json_error::serialize_as_json_error; use log::{info, warn, log}; @@ -22,7 +23,6 @@ use sqlx::error::Error::Database; use sqlx::mysql::MySqlDatabaseError; use std::fmt; use std::sync::Arc; -use database_queries::queries::api_tokens::create_api_token::create_api_token_for_user; // =============== Request =============== diff --git a/crates/service/storyteller_web/src/http_server/endpoints/twitch/event_rules/create_event_rule.rs b/crates/service/storyteller_web/src/http_server/endpoints/twitch/event_rules/create_event_rule.rs index e69de29bb2..b8315be056 100644 --- a/crates/service/storyteller_web/src/http_server/endpoints/twitch/event_rules/create_event_rule.rs +++ b/crates/service/storyteller_web/src/http_server/endpoints/twitch/event_rules/create_event_rule.rs @@ -0,0 +1,135 @@ +use actix_http::Error; +use actix_http::http::header; +use actix_web::HttpResponseBuilder; +use actix_web::cookie::Cookie; +use actix_web::error::ResponseError; +use actix_web::http::StatusCode; +use actix_web::web::{Path, Json}; +use actix_web::{Responder, web, HttpResponse, error, HttpRequest}; +use crate::http_server::web_utils::ip_address::get_request_ip; +use crate::http_server::web_utils::response_error_helpers::to_simple_json_error; +use crate::http_server::web_utils::response_success_helpers::simple_json_success; +use crate::server_state::ServerState; +use database_queries::column_types::twitch_event_category::TwitchEventCategory; +use database_queries::queries::twitch::twitch_event_rules::insert_twitch_event_rule_builder::InsertTwitchEventRuleBuilder; +use database_queries::tokens::Tokens; +use http_server_common::response::serialize_as_json_error::serialize_as_json_error; +use log::{info, warn, log}; +use sqlx::MySqlPool; +use sqlx::error::DatabaseError; +use sqlx::error::Error::Database; +use sqlx::mysql::MySqlDatabaseError; +use std::fmt; +use std::sync::Arc; + +// =============== Request =============== + +#[derive(Deserialize)] +pub struct CreateTwitchEventRuleRequest { + pub idempotency_token: String, + pub event_category: TwitchEventCategory, + pub event_match_predicate: String, + pub event_response: String, + pub user_specified_rule_order: u32, + pub rule_is_disabled: bool, +} + +// =============== Success Response =============== + +#[derive(Serialize)] +pub struct CreateTwitchEventRuleResponse { + pub success: bool, + pub twitch_event_rule_token: String, +} + +// =============== Error Response =============== + +#[derive(Debug, Serialize)] +pub enum CreateTwitchEventRuleError { + BadInput(String), + NotAuthorized, + ServerError, +} + +impl ResponseError for CreateTwitchEventRuleError { + fn status_code(&self) -> StatusCode { + match *self { + CreateTwitchEventRuleError::BadInput(_) => StatusCode::BAD_REQUEST, + CreateTwitchEventRuleError::NotAuthorized => StatusCode::UNAUTHORIZED, + CreateTwitchEventRuleError::ServerError => StatusCode::INTERNAL_SERVER_ERROR, + } + } + + fn error_response(&self) -> HttpResponse { + serialize_as_json_error(self) + } +} + +// NB: Not using DeriveMore since Clion doesn't understand it. +impl fmt::Display for CreateTwitchEventRuleError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self) + } +} + +// =============== Handler =============== + +pub async fn create_twitch_event_rule_handler( + http_request: HttpRequest, + request: web::Json, + server_state: web::Data>) -> Result +{ + let maybe_user_session = server_state + .session_checker + .maybe_get_user_session(&http_request, &server_state.mysql_pool) + .await + .map_err(|e| { + warn!("Session checker error: {:?}", e); + CreateTwitchEventRuleError::ServerError + })?; + + let user_session = match maybe_user_session { + Some(session) => session, + None => { + warn!("not logged in"); + return Err(CreateTwitchEventRuleError::NotAuthorized); + } + }; + + if user_session.is_banned { + warn!("banned users cannot use"); + return Err(CreateTwitchEventRuleError::NotAuthorized); + } + + let creator_ip_address = get_request_ip(&http_request); + + let insert_builder = InsertTwitchEventRuleBuilder { + uuid_idempotency_token: request.idempotency_token.clone(), + user_token: user_session.user_token, + event_category: request.event_category, + event_match_predicate: request.event_match_predicate.clone(), + event_response: request.event_response.clone(), + user_specified_rule_order: request.user_specified_rule_order, + rule_is_disabled: request.rule_is_disabled, + ip_address_creation: creator_ip_address, + }; + + let twitch_event_rule_token = insert_builder.insert(&server_state.mysql_pool) + .await + .map_err(|e| { + warn!("creation error: {:?}", e); + CreateTwitchEventRuleError::ServerError + })?; + + let response = CreateTwitchEventRuleResponse { + success: true, + twitch_event_rule_token + }; + + let body = serde_json::to_string(&response) + .map_err(|e| CreateTwitchEventRuleError::ServerError)?; + + Ok(HttpResponse::Ok() + .content_type("application/json") + .body(body)) +} diff --git a/crates/service/storyteller_web/src/http_server/endpoints/twitch/event_rules/delete_event_rule.rs b/crates/service/storyteller_web/src/http_server/endpoints/twitch/event_rules/delete_event_rule.rs index e69de29bb2..14e3048706 100644 --- a/crates/service/storyteller_web/src/http_server/endpoints/twitch/event_rules/delete_event_rule.rs +++ b/crates/service/storyteller_web/src/http_server/endpoints/twitch/event_rules/delete_event_rule.rs @@ -0,0 +1,134 @@ +use actix_http::Error; +use actix_http::http::header; +use actix_web::HttpResponseBuilder; +use actix_web::cookie::Cookie; +use actix_web::error::ResponseError; +use actix_web::http::StatusCode; +use actix_web::web::{Path, Json}; +use actix_web::{Responder, web, HttpResponse, error, HttpRequest}; +use crate::http_server::web_utils::ip_address::get_request_ip; +use crate::http_server::web_utils::response_error_helpers::to_simple_json_error; +use crate::http_server::web_utils::response_success_helpers::simple_json_success; +use crate::server_state::ServerState; +use database_queries::queries::twitch::twitch_event_rules::delete_twitch_event_rule::delete_twitch_event_rule; +use database_queries::queries::twitch::twitch_event_rules::get_twitch_event_rule_for_user::get_twitch_event_rules_for_user; +use http_server_common::response::serialize_as_json_error::serialize_as_json_error; +use log::{info, warn, log, error}; +use sqlx::MySqlPool; +use sqlx::error::DatabaseError; +use sqlx::error::Error::Database; +use sqlx::mysql::MySqlDatabaseError; +use std::fmt; +use std::sync::Arc; + +// =============== Request =============== + +#[derive(Deserialize)] +pub struct DeleteTwitchEventRulePathInfo { + token: String, +} + +// =============== Success Response =============== + +#[derive(Serialize)] +pub struct DeleteTwitchEventRuleResponse { + pub success: bool, +} + +// =============== Error Response =============== + +#[derive(Debug, Serialize)] +pub enum DeleteTwitchEventRuleError { + BadInput(String), + NotFound, + NotAuthorized, + ServerError, +} + +impl ResponseError for DeleteTwitchEventRuleError { + fn status_code(&self) -> StatusCode { + match *self { + DeleteTwitchEventRuleError::BadInput(_) => StatusCode::BAD_REQUEST, + DeleteTwitchEventRuleError::NotFound => StatusCode::NOT_FOUND, + DeleteTwitchEventRuleError::NotAuthorized => StatusCode::UNAUTHORIZED, + DeleteTwitchEventRuleError::ServerError => StatusCode::INTERNAL_SERVER_ERROR, + } + } + + fn error_response(&self) -> HttpResponse { + serialize_as_json_error(self) + } +} + +// NB: Not using derive_more::Display since Clion doesn't understand it. +impl fmt::Display for DeleteTwitchEventRuleError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self) + } +} + +// =============== Handler =============== + +pub async fn delete_twitch_event_rule_handler( + http_request: HttpRequest, + path: Path, + server_state: web::Data>) -> Result +{ + let maybe_user_session = server_state + .session_checker + .maybe_get_user_session(&http_request, &server_state.mysql_pool) + .await + .map_err(|e| { + warn!("Session checker error: {:?}", e); + DeleteTwitchEventRuleError::ServerError + })?; + + let user_session = match maybe_user_session { + Some(session) => session, + None => { + warn!("not logged in"); + return Err(DeleteTwitchEventRuleError::NotAuthorized); + } + }; + + if user_session.is_banned { + warn!("banned users cannot delete"); + return Err(DeleteTwitchEventRuleError::NotAuthorized); + } + + let twitch_event_rule = get_twitch_event_rules_for_user( + &path.token, &user_session.user_token, &server_state.mysql_pool) + .await + .map_err(|e| { + error!("Error with query: {:?}", e); + return DeleteTwitchEventRuleError::ServerError; + })?; + + if twitch_event_rule.is_none() { + info!("event rule not found"); + return Err(DeleteTwitchEventRuleError::NotFound); + } + + let creator_ip_address = get_request_ip(&http_request); + + let _r = delete_twitch_event_rule( + &path.token, + &creator_ip_address, + &server_state.mysql_pool) + .await + .map_err(|e| { + error!("Error with query: {:?}", e); + return DeleteTwitchEventRuleError::ServerError; + }); + + let response = DeleteTwitchEventRuleResponse { + success: true, + }; + + let body = serde_json::to_string(&response) + .map_err(|e| DeleteTwitchEventRuleError::ServerError)?; + + Ok(HttpResponse::Ok() + .content_type("application/json") + .body(body)) +} diff --git a/crates/service/storyteller_web/src/http_server/endpoints/twitch/event_rules/edit_event_rule.rs b/crates/service/storyteller_web/src/http_server/endpoints/twitch/event_rules/edit_event_rule.rs index e69de29bb2..aca1d71c87 100644 --- a/crates/service/storyteller_web/src/http_server/endpoints/twitch/event_rules/edit_event_rule.rs +++ b/crates/service/storyteller_web/src/http_server/endpoints/twitch/event_rules/edit_event_rule.rs @@ -0,0 +1,150 @@ +use actix_http::Error; +use actix_http::http::header; +use actix_web::HttpResponseBuilder; +use actix_web::cookie::Cookie; +use actix_web::error::ResponseError; +use actix_web::http::StatusCode; +use actix_web::web::{Path, Json}; +use actix_web::{Responder, web, HttpResponse, error, HttpRequest}; +use crate::http_server::web_utils::ip_address::get_request_ip; +use crate::http_server::web_utils::response_error_helpers::to_simple_json_error; +use crate::http_server::web_utils::response_success_helpers::simple_json_success; +use crate::server_state::ServerState; +use database_queries::queries::twitch::twitch_event_rules::get_twitch_event_rule_for_user::get_twitch_event_rules_for_user; +use database_queries::queries::twitch::twitch_event_rules::update_twitch_event_rule_builder::UpdateTwitchEventRuleBuilder; +use http_server_common::response::serialize_as_json_error::serialize_as_json_error; +use log::{info, warn, log, error}; +use sqlx::MySqlPool; +use sqlx::error::DatabaseError; +use sqlx::error::Error::Database; +use sqlx::mysql::MySqlDatabaseError; +use std::fmt; +use std::sync::Arc; + +// =============== Request =============== + +#[derive(Deserialize)] +pub struct EditTwitchEventRulePathInfo { + token: String, +} + +// These are not sparse updates! +#[derive(Deserialize)] +pub struct EditTwitchEventRuleRequest { + pub event_match_predicate: String, + pub event_response: String, + pub user_specified_rule_order: u32, + pub rule_is_disabled: bool, +} + +// =============== Success Response =============== + +#[derive(Serialize)] +pub struct EditTwitchEventRuleResponse { + pub success: bool, +} + +// =============== Error Response =============== + +#[derive(Debug, Serialize)] +pub enum EditTwitchEventRuleError { + BadInput(String), + NotFound, + NotAuthorized, + ServerError, +} + +impl ResponseError for EditTwitchEventRuleError { + fn status_code(&self) -> StatusCode { + match *self { + EditTwitchEventRuleError::BadInput(_) => StatusCode::BAD_REQUEST, + EditTwitchEventRuleError::NotFound => StatusCode::NOT_FOUND, + EditTwitchEventRuleError::NotAuthorized => StatusCode::UNAUTHORIZED, + EditTwitchEventRuleError::ServerError => StatusCode::INTERNAL_SERVER_ERROR, + } + } + + fn error_response(&self) -> HttpResponse { + serialize_as_json_error(self) + } +} + +// NB: Not using derive_more::Display since Clion doesn't understand it. +impl fmt::Display for EditTwitchEventRuleError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self) + } +} + +// =============== Handler =============== + +pub async fn edit_twitch_event_rule_handler( + http_request: HttpRequest, + path: Path, + request: web::Json, + server_state: web::Data>) -> Result +{ + let maybe_user_session = server_state + .session_checker + .maybe_get_user_session(&http_request, &server_state.mysql_pool) + .await + .map_err(|e| { + warn!("Session checker error: {:?}", e); + EditTwitchEventRuleError::ServerError + })?; + + let user_session = match maybe_user_session { + Some(session) => session, + None => { + warn!("not logged in"); + return Err(EditTwitchEventRuleError::NotAuthorized); + } + }; + + if user_session.is_banned { + warn!("banned users cannot edit"); + return Err(EditTwitchEventRuleError::NotAuthorized); + } + + let twitch_event_rule = get_twitch_event_rules_for_user( + &path.token, &user_session.user_token, &server_state.mysql_pool) + .await + .map_err(|e| { + error!("Error with query: {:?}", e); + return EditTwitchEventRuleError::ServerError; + })?; + + if twitch_event_rule.is_none() { + info!("event rule not found"); + return Err(EditTwitchEventRuleError::NotFound); + } + + let creator_ip_address = get_request_ip(&http_request); + + let update_builder = UpdateTwitchEventRuleBuilder { + token: path.token.clone(), + event_match_predicate: request.event_match_predicate.clone(), + event_response: request.event_response.clone(), + user_specified_rule_order: request.user_specified_rule_order, + rule_is_disabled: request.rule_is_disabled, + ip_address_update: creator_ip_address, + }; + + let _r = update_builder.update(&server_state.mysql_pool) + .await + .map_err(|e| { + error!("Error with query: {:?}", e); + return EditTwitchEventRuleError::ServerError; + }); + + let response = EditTwitchEventRuleResponse { + success: true, + }; + + let body = serde_json::to_string(&response) + .map_err(|e| EditTwitchEventRuleError::ServerError)?; + + Ok(HttpResponse::Ok() + .content_type("application/json") + .body(body)) +} diff --git a/crates/service/storyteller_web/src/http_server/endpoints/twitch/event_rules/list_event_rules_for_user.rs b/crates/service/storyteller_web/src/http_server/endpoints/twitch/event_rules/list_event_rules_for_user.rs index e69de29bb2..aa42025c28 100644 --- a/crates/service/storyteller_web/src/http_server/endpoints/twitch/event_rules/list_event_rules_for_user.rs +++ b/crates/service/storyteller_web/src/http_server/endpoints/twitch/event_rules/list_event_rules_for_user.rs @@ -0,0 +1,109 @@ +use actix_http::Error; +use actix_http::http::header; +use actix_web::HttpResponseBuilder; +use actix_web::cookie::Cookie; +use actix_web::error::ResponseError; +use actix_web::http::StatusCode; +use actix_web::web::{Path, Json}; +use actix_web::{Responder, web, HttpResponse, error, HttpRequest}; +use chrono::{DateTime, Utc}; +use crate::http_server::web_utils::ip_address::get_request_ip; +use crate::http_server::web_utils::response_error_helpers::to_simple_json_error; +use crate::http_server::web_utils::response_success_helpers::simple_json_success; +use crate::server_state::ServerState; +use database_queries::queries::twitch::twitch_event_rules::list_twitch_event_rules_for_user::{TwitchEventRule, list_twitch_event_rules_for_user}; +use http_server_common::response::serialize_as_json_error::serialize_as_json_error; +use lexical_sort::natural_lexical_cmp; +use log::{info, warn, log}; +use sqlx::MySqlPool; +use sqlx::error::DatabaseError; +use sqlx::error::Error::Database; +use sqlx::mysql::MySqlDatabaseError; +use std::fmt; +use std::sync::Arc; + +// =============== Success Response =============== + +#[derive(Serialize)] +pub struct ListTwitchEventRulesResponse { + pub success: bool, + pub twitch_event_rules: Vec, +} + + +// =============== Error Response =============== + +#[derive(Debug, Serialize)] +pub enum ListTwitchEventRulesError { + NotAuthorized, + ServerError, +} + +impl ResponseError for ListTwitchEventRulesError { + fn status_code(&self) -> StatusCode { + match *self { + ListTwitchEventRulesError::NotAuthorized => StatusCode::UNAUTHORIZED, + ListTwitchEventRulesError::ServerError => StatusCode::INTERNAL_SERVER_ERROR, + } + } + + fn error_response(&self) -> HttpResponse { + serialize_as_json_error(self) + } +} + +// NB: Not using derive_more::Display since Clion doesn't understand it. +impl fmt::Display for ListTwitchEventRulesError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self) + } +} + +// =============== Handler =============== + +pub async fn list_twitch_event_rules_for_user_handler( + http_request: HttpRequest, + server_state: web::Data>) -> Result +{ + let maybe_user_session = server_state + .session_checker + .maybe_get_user_session(&http_request, &server_state.mysql_pool) + .await + .map_err(|e| { + warn!("Session checker error: {:?}", e); + ListTwitchEventRulesError::ServerError + })?; + + let user_session = match maybe_user_session { + Some(session) => session, + None => { + warn!("not logged in"); + return Err(ListTwitchEventRulesError::NotAuthorized); + } + }; + + if user_session.is_banned { + warn!("banned users cannot use"); + return Err(ListTwitchEventRulesError::NotAuthorized); + } + + let twitch_event_rules = list_twitch_event_rules_for_user( + &user_session.user_token, &server_state.mysql_pool) + .await + .map_err(|e| { + warn!("query error: {:?}", e); + ListTwitchEventRulesError::ServerError + })?; + + let response = ListTwitchEventRulesResponse { + success: true, + twitch_event_rules, + }; + + let body = serde_json::to_string(&response) + .map_err(|e| ListTwitchEventRulesError::ServerError)?; + + Ok(HttpResponse::Ok() + .content_type("application/json") + .body(body)) +} diff --git a/crates/service/storyteller_web/src/http_server/endpoints/twitch/mod.rs b/crates/service/storyteller_web/src/http_server/endpoints/twitch/mod.rs index 1d15747836..8ad19b93b8 100644 --- a/crates/service/storyteller_web/src/http_server/endpoints/twitch/mod.rs +++ b/crates/service/storyteller_web/src/http_server/endpoints/twitch/mod.rs @@ -1,4 +1,2 @@ pub mod event_rules; -pub mod oauth_begin_json; -pub mod oauth_begin_redirect; -pub mod oauth_end; +pub mod oauth; diff --git a/crates/service/storyteller_web/src/http_server/endpoints/twitch/oauth/mod.rs b/crates/service/storyteller_web/src/http_server/endpoints/twitch/oauth/mod.rs new file mode 100644 index 0000000000..0b47d3ca95 --- /dev/null +++ b/crates/service/storyteller_web/src/http_server/endpoints/twitch/oauth/mod.rs @@ -0,0 +1,3 @@ +pub mod oauth_begin_json; +pub mod oauth_begin_redirect; +pub mod oauth_end; diff --git a/crates/service/storyteller_web/src/http_server/endpoints/twitch/oauth_begin_json.rs b/crates/service/storyteller_web/src/http_server/endpoints/twitch/oauth/oauth_begin_json.rs similarity index 100% rename from crates/service/storyteller_web/src/http_server/endpoints/twitch/oauth_begin_json.rs rename to crates/service/storyteller_web/src/http_server/endpoints/twitch/oauth/oauth_begin_json.rs diff --git a/crates/service/storyteller_web/src/http_server/endpoints/twitch/oauth_begin_redirect.rs b/crates/service/storyteller_web/src/http_server/endpoints/twitch/oauth/oauth_begin_redirect.rs similarity index 100% rename from crates/service/storyteller_web/src/http_server/endpoints/twitch/oauth_begin_redirect.rs rename to crates/service/storyteller_web/src/http_server/endpoints/twitch/oauth/oauth_begin_redirect.rs diff --git a/crates/service/storyteller_web/src/http_server/endpoints/twitch/oauth_end.rs b/crates/service/storyteller_web/src/http_server/endpoints/twitch/oauth/oauth_end.rs similarity index 100% rename from crates/service/storyteller_web/src/http_server/endpoints/twitch/oauth_end.rs rename to crates/service/storyteller_web/src/http_server/endpoints/twitch/oauth/oauth_end.rs diff --git a/crates/service/storyteller_web/src/routes.rs b/crates/service/storyteller_web/src/routes.rs index d1854b5e7b..ac29eebd4e 100644 --- a/crates/service/storyteller_web/src/routes.rs +++ b/crates/service/storyteller_web/src/routes.rs @@ -48,9 +48,9 @@ use crate::http_server::endpoints::tts::get_tts_model_use_count::get_tts_model_u use crate::http_server::endpoints::tts::get_tts_result::get_tts_inference_result_handler; use crate::http_server::endpoints::tts::get_tts_upload_model_job_status::get_tts_upload_model_job_status_handler; use crate::http_server::endpoints::tts::list_tts_models::list_tts_models_handler; -use crate::http_server::endpoints::twitch::oauth_begin_json::oauth_begin_enroll_json; -use crate::http_server::endpoints::twitch::oauth_begin_redirect::oauth_begin_enroll_redirect; -use crate::http_server::endpoints::twitch::oauth_end::oauth_end_enroll_from_redirect; +use crate::http_server::endpoints::twitch::oauth::oauth_begin_json::oauth_begin_enroll_json; +use crate::http_server::endpoints::twitch::oauth::oauth_begin_redirect::oauth_begin_enroll_redirect; +use crate::http_server::endpoints::twitch::oauth::oauth_end::oauth_end_enroll_from_redirect; use crate::http_server::endpoints::users::create_account::create_account_handler; use crate::http_server::endpoints::users::edit_profile::edit_profile_handler; use crate::http_server::endpoints::users::get_profile::get_profile_handler; @@ -75,6 +75,10 @@ use crate::http_server::endpoints::w2l::get_w2l_template_use_count::get_w2l_temp use crate::http_server::endpoints::w2l::get_w2l_upload_template_job_status::get_w2l_upload_template_job_status_handler; use crate::http_server::endpoints::w2l::list_w2l_templates::list_w2l_templates_handler; use crate::http_server::endpoints::w2l::set_w2l_template_mod_approval::set_w2l_template_mod_approval_handler; +use crate::http_server::endpoints::twitch::event_rules::create_event_rule::create_twitch_event_rule_handler; +use crate::http_server::endpoints::twitch::event_rules::list_event_rules_for_user::list_twitch_event_rules_for_user_handler; +use crate::http_server::endpoints::twitch::event_rules::delete_event_rule::delete_twitch_event_rule_handler; +use crate::http_server::endpoints::twitch::event_rules::edit_event_rule::edit_twitch_event_rule_handler; pub fn add_routes (app: App) -> App where @@ -583,6 +587,7 @@ fn add_twitch_oauth_routes (app: App) -> App InitError = (), >, { + // TODO: Move oauth endpoints under /twitch/oauth (requires updating Twitch configs too.) app.service(web::scope("/twitch") .service(web::resource("/oauth_enroll_json") .route(web::get().to(oauth_begin_enroll_json)) @@ -596,5 +601,23 @@ fn add_twitch_oauth_routes (app: App) -> App .route(web::get().to(oauth_end_enroll_from_redirect)) .route(web::head().to(|| HttpResponse::Ok())) ) + .service(web::scope("/event_rule") + .service(web::resource("/create") + .route(web::post().to(create_twitch_event_rule_handler)) + .route(web::head().to(|| HttpResponse::Ok())) + ) + .service(web::resource("/list") + .route(web::get().to(list_twitch_event_rules_for_user_handler)) + .route(web::head().to(|| HttpResponse::Ok())) + ) + .service(web::resource("/update/{token}") + .route(web::post().to(edit_twitch_event_rule_handler)) + .route(web::head().to(|| HttpResponse::Ok())) + ) + .service(web::resource("/delete/{token}") + .route(web::delete().to(delete_twitch_event_rule_handler)) + .route(web::head().to(|| HttpResponse::Ok())) + ) + ) ) }