From 71fcdd615ba1fb5600ff233c981f6324b0f99959 Mon Sep 17 00:00:00 2001 From: GideonBature Date: Sat, 28 Sep 2024 03:54:09 +0100 Subject: [PATCH 1/4] add custom_api directory with create and update --- src/endpoints/admin/balance/create_balance.rs | 2 + src/endpoints/admin/custom/create_custom.rs | 2 + .../admin/custom_api/create_custom_api.rs | 89 +++++++++++++++++++ src/endpoints/admin/custom_api/mod.rs | 2 + .../admin/custom_api/update_custom_api.rs | 87 ++++++++++++++++++ src/endpoints/admin/discord/create_discord.rs | 2 + src/endpoints/admin/domain/create_domain.rs | 2 + src/endpoints/admin/quiz/create_quiz.rs | 2 + .../admin/twitter/create_twitter_fw.rs | 2 + .../admin/twitter/create_twitter_rw.rs | 2 + src/models.rs | 2 + 11 files changed, 194 insertions(+) create mode 100644 src/endpoints/admin/custom_api/create_custom_api.rs create mode 100644 src/endpoints/admin/custom_api/mod.rs create mode 100644 src/endpoints/admin/custom_api/update_custom_api.rs diff --git a/src/endpoints/admin/balance/create_balance.rs b/src/endpoints/admin/balance/create_balance.rs index 4de3928..7436259 100644 --- a/src/endpoints/admin/balance/create_balance.rs +++ b/src/endpoints/admin/balance/create_balance.rs @@ -72,6 +72,8 @@ pub async fn handler( discord_guild_id: None, quiz_name: None, contracts: Some(parsed_contracts), + api_url: None, + regex: None, }; // insert document to boost collection diff --git a/src/endpoints/admin/custom/create_custom.rs b/src/endpoints/admin/custom/create_custom.rs index 2180d7e..08155f3 100644 --- a/src/endpoints/admin/custom/create_custom.rs +++ b/src/endpoints/admin/custom/create_custom.rs @@ -63,6 +63,8 @@ pub async fn handler( discord_guild_id: None, quiz_name: None, contracts: None, + api_url: None, + regex: None, }; // insert document to boost collection diff --git a/src/endpoints/admin/custom_api/create_custom_api.rs b/src/endpoints/admin/custom_api/create_custom_api.rs new file mode 100644 index 0000000..7ff4470 --- /dev/null +++ b/src/endpoints/admin/custom_api/create_custom_api.rs @@ -0,0 +1,89 @@ +use crate::models::{QuestDocument, QuestTaskDocument}; +use crate::utils::verify_quest_auth; +use crate::{models::AppState, utils::get_error}; +use crate::middleware::auth::auth_middleware; +use axum::{ + extract::{Extension, State}, + http::StatusCode, + response::{IntoResponse, Json} +}; +use axum_auto_routes::route; +use mongodb::bson::doc; +use mongodb::options::FindOneOptions; +use serde::Deserialize; +use serde_json::json; +use starknet::core::types::FieldElement; +use std::str::FromStr; +use std::sync::Arc; + +pub_struct!(Deserialize; CreateCustomAPI { + quest_id: i64, + name: String, + desc: String, + href: String, + cta: String, + api_url: String, + regex: String, +}); + +#[route(post, "/admin/tasks/custom_api/create", auth_middleware)] +pub async fn handler( + State(state): State>, + Extension(sub): Extension, + Json(body): Json, +) -> impl IntoResponse { + let collection = state.db.collection::("tasks"); + // Get the last id in increasing order + let last_id_filter = doc! {}; + let options = FindOneOptions::builder().sort(doc! {"id": -1}).build(); + let last_doc = &collection.find_one(last_id_filter, options).await.unwrap(); + + let quests_collection = state.db.collection::("quests"); + + let res = verify_quest_auth(sub, &quests_collection, &(body.quest_id as i64)).await; + if !res { + return get_error("Error creating task".to_string()); + }; + + let mut next_id = 1; + if let Some(doc) = last_doc { + let last_id = doc.id; + next_id = last_id + 1; + } + + // Build a vector of FieldElement from the comma separated contracts string + let parsed_contracts: Vec = body + .contracts + .split(",") + .map(|x| FieldElement::from_str(&x).unwrap()) + .collect(); + + let new_document = QuestTaskDocument { + name: body.name.clone(), + desc: body.desc.clone(), + verify_redirect: None, + href: body.href.clone(), + total_amount: None, + quest_id: body.quest_id, + id: next_id, + cta: body.cta.clone(), + verify_endpoint: "quests/verify_custom_api".to_string(), + verify_endpoint_type: "default".to_string(), + task_type: Some("custom_api".to_string()), + discord_guild_id: None, + quiz_name: None, + contracts: None, + api_url: Some(body.api_url.clone()), + regex: Some(body.regex.clone()), + }; + + // insert document to boost collection + return match collection.insert_one(new_document, None).await { + Ok(_) => ( + StatusCode::OK, + Json(json!({"message": "Task created successfully"})).into_response(), + ) + .into_response(), + Err(_e) => get_error("Error creating tasks".to_string()), + }; +} diff --git a/src/endpoints/admin/custom_api/mod.rs b/src/endpoints/admin/custom_api/mod.rs new file mode 100644 index 0000000..59c8d4f --- /dev/null +++ b/src/endpoints/admin/custom_api/mod.rs @@ -0,0 +1,2 @@ +pub mod create_custom_api; +pub mod update_custom_api; \ No newline at end of file diff --git a/src/endpoints/admin/custom_api/update_custom_api.rs b/src/endpoints/admin/custom_api/update_custom_api.rs new file mode 100644 index 0000000..afc363b --- /dev/null +++ b/src/endpoints/admin/custom_api/update_custom_api.rs @@ -0,0 +1,87 @@ +use crate::models::QuestTaskDocument; +use crate::{models::AppState, utils::get_error}; +use crate::middleware::auth::auth_middleware; +use crate::utils::verify_task_auth; + +use axum::{ + extract::{Extension, State}, + http::StatusCode, + response::{IntoResponse, Json}, +}; +use axum_auto_routes::route; +use mongodb::bson::doc; +use serde::Deserialize; +use serde_json::json; +use starknet::core::types::FieldElement; +use std::str::FromStr; +use std::sync::Arc; + +pub_struct!(Deserialize; UpdateCustomAPI { + id: i64, + name: Option, + desc: Option, + href: Option, + cta: Option, + api_url: Option, + regex: Option, +}); + +// Helper function to convert FieldElement to Bson +fn field_element_to_bson(fe: &FieldElement) -> mongodb::bson::Bson { + mongodb::bson::Bson::String(fe.to_string()) +} + +#[route(post, "/admin/tasks/custom_api/update", auth_middleware)] +pub async fn handler( + State(state): State>, + Extension(sub): Extension, + Json(body): Json, +) -> impl IntoResponse { + let collection = state.db.collection::("tasks"); + + let res = verify_task_auth(sub, &collection, &(body.id as i32)).await; + if !res { + return get_error("Error updating tasks".to_string()); + } + + // filter to get existing quest + let filter = doc! { + "id": &body.id, + }; + + let mut update_doc = doc! {}; + + if let Some(name) = &body.name { + update_doc.insert("name", name); + } + if let Some(desc) = &body.desc { + update_doc.insert("desc", desc); + } + if let Some(href) = &body.href { + update_doc.insert("href", href); + } + if let Some(cta) = &body.cta { + update_doc.insert("cta", cta); + } + if let Some(api_url) = &body.api_url { + update_doc.insert("api_url", api_url); + } + if let Some(regex) = &body.regex { + update_doc.insert("regex", regex); + } + + // update quest query + let update = doc! { + "$set": update_doc + }; + + // insert document to boost collection + return match collection.find_one_and_update(filter, update, None).await { + Ok(_) => ( + StatusCode::OK, + Json(json!({"message": "Task updated successfully"})).into_response(), + ) + .into_response(), + Err(_e) => get_error("Error updating tasks".to_string()), + }; +} diff --git a/src/endpoints/admin/discord/create_discord.rs b/src/endpoints/admin/discord/create_discord.rs index 6f6c7ef..895ec26 100644 --- a/src/endpoints/admin/discord/create_discord.rs +++ b/src/endpoints/admin/discord/create_discord.rs @@ -62,6 +62,8 @@ pub async fn handler( quiz_name: None, verify_redirect: None, contracts: None, + api_url: None, + regex: None, }; // insert document to boost collection diff --git a/src/endpoints/admin/domain/create_domain.rs b/src/endpoints/admin/domain/create_domain.rs index 586e1fb..0080f4d 100644 --- a/src/endpoints/admin/domain/create_domain.rs +++ b/src/endpoints/admin/domain/create_domain.rs @@ -59,6 +59,8 @@ pub async fn handler( quiz_name: None, verify_redirect: None, contracts: None, + api_url: None, + regex: None, }; // insert document to boost collection diff --git a/src/endpoints/admin/quiz/create_quiz.rs b/src/endpoints/admin/quiz/create_quiz.rs index 4f9b41e..d382e2b 100644 --- a/src/endpoints/admin/quiz/create_quiz.rs +++ b/src/endpoints/admin/quiz/create_quiz.rs @@ -90,6 +90,8 @@ pub async fn handler( discord_guild_id: None, verify_redirect: None, contracts: None, + api_url: None, + regex: None, }; return match tasks_collection.insert_one(new_document, None).await { diff --git a/src/endpoints/admin/twitter/create_twitter_fw.rs b/src/endpoints/admin/twitter/create_twitter_fw.rs index a2348a6..5337c05 100644 --- a/src/endpoints/admin/twitter/create_twitter_fw.rs +++ b/src/endpoints/admin/twitter/create_twitter_fw.rs @@ -63,6 +63,8 @@ pub async fn handler( discord_guild_id: None, quiz_name: None, contracts: None, + api_url: None, + regex: None, }; // insert document to boost collection diff --git a/src/endpoints/admin/twitter/create_twitter_rw.rs b/src/endpoints/admin/twitter/create_twitter_rw.rs index 8b1106e..99b2312 100644 --- a/src/endpoints/admin/twitter/create_twitter_rw.rs +++ b/src/endpoints/admin/twitter/create_twitter_rw.rs @@ -61,6 +61,8 @@ pub async fn handler( discord_guild_id: None, quiz_name: None, contracts: None, + api_url: None, + regex: None, }; // insert document to boost collection diff --git a/src/models.rs b/src/models.rs index 9451b66..6c0b884 100644 --- a/src/models.rs +++ b/src/models.rs @@ -128,6 +128,8 @@ pub struct QuestTaskDocument { pub(crate) discord_guild_id: Option, #[serde(default)] pub(crate) contracts: Option>, + pub api_url: Option, + pub regex: Option, } pub_struct!(Serialize; Reward { From d7b081e709c3c7c599fc826c5376b1f9b0807104 Mon Sep 17 00:00:00 2001 From: GideonBature Date: Sat, 28 Sep 2024 20:10:26 +0100 Subject: [PATCH 2/4] add mod custom_api to admin/mod.rs and removed unused code --- src/endpoints/admin/custom_api/create_custom_api.rs | 7 ------- src/endpoints/mod.rs | 1 + 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/endpoints/admin/custom_api/create_custom_api.rs b/src/endpoints/admin/custom_api/create_custom_api.rs index 7ff4470..8b8245d 100644 --- a/src/endpoints/admin/custom_api/create_custom_api.rs +++ b/src/endpoints/admin/custom_api/create_custom_api.rs @@ -51,13 +51,6 @@ pub async fn handler( next_id = last_id + 1; } - // Build a vector of FieldElement from the comma separated contracts string - let parsed_contracts: Vec = body - .contracts - .split(",") - .map(|x| FieldElement::from_str(&x).unwrap()) - .collect(); - let new_document = QuestTaskDocument { name: body.name.clone(), desc: body.desc.clone(), diff --git a/src/endpoints/mod.rs b/src/endpoints/mod.rs index 0882292..0c85a6d 100644 --- a/src/endpoints/mod.rs +++ b/src/endpoints/mod.rs @@ -17,3 +17,4 @@ pub mod leaderboard; pub mod quest_boost; pub mod quests; pub mod unique_page_visit; +pub mod custom_api; From be4806f89106448b4fa73c9fe2536bc0ea4e64e4 Mon Sep 17 00:00:00 2001 From: GideonBature Date: Sat, 28 Sep 2024 22:37:48 +0100 Subject: [PATCH 3/4] mod for custom_url set up properly --- src/endpoints/admin/mod.rs | 1 + src/endpoints/mod.rs | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/endpoints/admin/mod.rs b/src/endpoints/admin/mod.rs index da45ab3..ebafdef 100644 --- a/src/endpoints/admin/mod.rs +++ b/src/endpoints/admin/mod.rs @@ -10,3 +10,4 @@ pub mod quest_boost; pub mod quiz; pub mod twitter; pub mod user; +pub mod custom_api; diff --git a/src/endpoints/mod.rs b/src/endpoints/mod.rs index 0c85a6d..4181eb6 100644 --- a/src/endpoints/mod.rs +++ b/src/endpoints/mod.rs @@ -16,5 +16,4 @@ pub mod has_completed_quest; pub mod leaderboard; pub mod quest_boost; pub mod quests; -pub mod unique_page_visit; -pub mod custom_api; +pub mod unique_page_visit; \ No newline at end of file From 33a9fa67f60781e111acbb9a1f1a11da06a30f61 Mon Sep 17 00:00:00 2001 From: GideonBature Date: Sat, 28 Sep 2024 23:04:19 +0100 Subject: [PATCH 4/4] remove unused import in custom_url --- src/endpoints/admin/custom_api/create_custom_api.rs | 3 +-- src/endpoints/admin/custom_api/update_custom_api.rs | 7 ------- src/models.rs | 2 -- 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/endpoints/admin/custom_api/create_custom_api.rs b/src/endpoints/admin/custom_api/create_custom_api.rs index 8b8245d..7b33631 100644 --- a/src/endpoints/admin/custom_api/create_custom_api.rs +++ b/src/endpoints/admin/custom_api/create_custom_api.rs @@ -12,8 +12,6 @@ use mongodb::bson::doc; use mongodb::options::FindOneOptions; use serde::Deserialize; use serde_json::json; -use starknet::core::types::FieldElement; -use std::str::FromStr; use std::sync::Arc; pub_struct!(Deserialize; CreateCustomAPI { @@ -62,6 +60,7 @@ pub async fn handler( cta: body.cta.clone(), verify_endpoint: "quests/verify_custom_api".to_string(), verify_endpoint_type: "default".to_string(), + calls: None, task_type: Some("custom_api".to_string()), discord_guild_id: None, quiz_name: None, diff --git a/src/endpoints/admin/custom_api/update_custom_api.rs b/src/endpoints/admin/custom_api/update_custom_api.rs index afc363b..2128f26 100644 --- a/src/endpoints/admin/custom_api/update_custom_api.rs +++ b/src/endpoints/admin/custom_api/update_custom_api.rs @@ -12,8 +12,6 @@ use axum_auto_routes::route; use mongodb::bson::doc; use serde::Deserialize; use serde_json::json; -use starknet::core::types::FieldElement; -use std::str::FromStr; use std::sync::Arc; pub_struct!(Deserialize; UpdateCustomAPI { @@ -26,11 +24,6 @@ pub_struct!(Deserialize; UpdateCustomAPI { regex: Option, }); -// Helper function to convert FieldElement to Bson -fn field_element_to_bson(fe: &FieldElement) -> mongodb::bson::Bson { - mongodb::bson::Bson::String(fe.to_string()) -} - #[route(post, "/admin/tasks/custom_api/update", auth_middleware)] pub async fn handler( State(state): State>, diff --git a/src/models.rs b/src/models.rs index a2b45e9..19f6e9f 100644 --- a/src/models.rs +++ b/src/models.rs @@ -126,8 +126,6 @@ pub struct QuestTaskDocument { pub verify_endpoint: String, pub href: String, pub verify_endpoint_type: String, - pub api_url: Option, - pub regex: Option, pub calls: Option>, #[serde(default)] pub verify_redirect: Option,