diff --git a/submissions-api-rs/Cargo.lock b/submissions-api-rs/Cargo.lock index 2da9616..6dcea33 100644 --- a/submissions-api-rs/Cargo.lock +++ b/submissions-api-rs/Cargo.lock @@ -952,7 +952,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "submissions-api" -version = "0.2.2" +version = "0.2.3-pre1" dependencies = [ "reqwest", "serde", diff --git a/submissions-api-rs/Cargo.toml b/submissions-api-rs/Cargo.toml index 5d9457b..5d5efce 100644 --- a/submissions-api-rs/Cargo.toml +++ b/submissions-api-rs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "submissions-api" -version = "0.2.2" +version = "0.2.3-pre1" edition = "2021" publish = ["strafesnet"] repository = "https://git.itzana.me/StrafesNET/maps-service" diff --git a/submissions-api-rs/src/context.rs b/submissions-api-rs/src/context.rs index a5e55cd..faeb2f3 100644 --- a/submissions-api-rs/src/context.rs +++ b/submissions-api-rs/src/context.rs @@ -16,8 +16,13 @@ impl Context{ self.client.get(url) .send().await } - pub async fn post(&self,url:impl reqwest::IntoUrl)->Result{ + pub async fn post_empty_body(&self,url:impl reqwest::IntoUrl)->Result{ self.client.post(url) .send().await } + pub async fn post(&self,url:impl reqwest::IntoUrl,body:impl Into)->Result{ + self.client.post(url) + .body(body) + .send().await + } } diff --git a/submissions-api-rs/src/external.rs b/submissions-api-rs/src/external.rs index 3f431c4..2c235cf 100644 --- a/submissions-api-rs/src/external.rs +++ b/submissions-api-rs/src/external.rs @@ -1,7 +1,9 @@ use crate::Error; -#[derive(serde::Deserialize)] -pub struct ScriptID(pub(crate) i64); +#[derive(Clone,Copy,serde::Serialize,serde::Deserialize)] +pub struct ScriptID(i64); +#[derive(Clone,Copy,serde::Serialize,serde::Deserialize)] +pub struct ScriptPolicyID(i64); #[allow(nonstandard_style)] pub struct GetScriptRequest{ @@ -15,8 +17,19 @@ pub struct ScriptResponse{ pub Source:String, pub SubmissionID:i64, } - +#[allow(nonstandard_style)] +#[derive(serde::Serialize)] +pub struct CreateScriptRequest{ + pub Source:String, + pub SubmissionID:Option, +} +#[allow(nonstandard_style)] #[derive(serde::Deserialize)] +pub struct ScriptIDResponse{ + pub ID:ScriptID, +} + +#[derive(serde::Serialize,serde::Deserialize)] #[repr(i32)] pub enum Policy{ None=0, // not yet reviewed @@ -37,6 +50,18 @@ pub struct ScriptPolicyResponse{ pub ToScriptID:ScriptID, pub Policy:Policy } +#[allow(nonstandard_style)] +#[derive(serde::Serialize)] +pub struct CreateScriptPolicyRequest{ + pub FromScriptID:ScriptID, + pub ToScriptID:ScriptID, + pub Policy:Policy, +} +#[allow(nonstandard_style)] +#[derive(serde::Deserialize)] +pub struct ScriptPolicyIDResponse{ + pub ID:ScriptPolicyID, +} #[allow(nonstandard_style)] pub struct UpdateSubmissionModelRequest{ @@ -60,6 +85,16 @@ impl Context{ .error_for_status().map_err(Error::Reqwest)? .json().await.map_err(Error::Reqwest) } + pub async fn create_script(&self,config:CreateScriptRequest)->Result{ + let url_raw=format!("{}/scripts",self.0.base_url); + let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::ParseError)?; + + let body=serde_json::to_string(&config).map_err(Error::JSON)?; + + self.0.post(url,body).await.map_err(Error::Reqwest)? + .error_for_status().map_err(Error::Reqwest)? + .json().await.map_err(Error::Reqwest) + } pub async fn get_script_policy_from_hash(&self,config:ScriptPolicyHashRequest)->Result{ let url_raw=format!("{}/script-policy/hash/{}",self.0.base_url,config.hash); let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::ParseError)?; @@ -68,6 +103,16 @@ impl Context{ .error_for_status().map_err(Error::Reqwest)? .json().await.map_err(Error::Reqwest) } + pub async fn create_script_policy(&self,config:CreateScriptPolicyRequest)->Result{ + let url_raw=format!("{}/script-policy",self.0.base_url); + let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::ParseError)?; + + let body=serde_json::to_string(&config).map_err(Error::JSON)?; + + self.0.post(url,body).await.map_err(Error::Reqwest)? + .error_for_status().map_err(Error::Reqwest)? + .json().await.map_err(Error::Reqwest) + } pub async fn update_submission_model(&self,config:UpdateSubmissionModelRequest)->Result<(),Error>{ let url_raw=format!("{}/submissions/{}/model",self.0.base_url,config.SubmissionID); let mut url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::ParseError)?; @@ -78,7 +123,7 @@ impl Context{ .append_pair("ModelVersion",config.ModelVersion.to_string().as_str()); } - self.0.post(url).await.map_err(Error::Reqwest)? + self.0.post_empty_body(url).await.map_err(Error::Reqwest)? .error_for_status().map_err(Error::Reqwest)?; Ok(()) diff --git a/submissions-api-rs/src/internal.rs b/submissions-api-rs/src/internal.rs index 7ed3c9d..28b8c40 100644 --- a/submissions-api-rs/src/internal.rs +++ b/submissions-api-rs/src/internal.rs @@ -18,7 +18,7 @@ macro_rules! action{ let url_raw=format!(concat!("{}/submissions/{}/status/",$action),self.0.base_url,config.0); let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::ParseError)?; - self.0.post(url).await.map_err(Error::Reqwest)? + self.0.post_empty_body(url).await.map_err(Error::Reqwest)? .error_for_status().map_err(Error::Reqwest)?; Ok(()) @@ -38,7 +38,7 @@ impl Context{ .append_pair("TargetAssetID",target_asset_id.to_string().as_str()); } - self.0.post(url).await.map_err(Error::Reqwest)? + self.0.post_empty_body(url).await.map_err(Error::Reqwest)? .error_for_status().map_err(Error::Reqwest)?; Ok(()) diff --git a/submissions-api-rs/src/lib.rs b/submissions-api-rs/src/lib.rs index c6666e9..262e017 100644 --- a/submissions-api-rs/src/lib.rs +++ b/submissions-api-rs/src/lib.rs @@ -13,6 +13,7 @@ pub type ReqwestError=reqwest::Error; pub enum Error{ ParseError(url::ParseError), Reqwest(reqwest::Error), + JSON(serde_json::Error), } impl std::fmt::Display for Error{ fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ diff --git a/validation/Cargo.lock b/validation/Cargo.lock index e2e057f..378a929 100644 --- a/validation/Cargo.lock +++ b/validation/Cargo.lock @@ -1804,9 +1804,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "submissions-api" -version = "0.2.2" +version = "0.2.3-pre1" source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/" -checksum = "e7a29fd61d2421c5c1a2923465a611aa84177a0f312fc11d81e4298bfee4aeea" +checksum = "6f5f7afe0137bd065c750f6d8c05892532cd50b9feba588847c10df37e660ad2" dependencies = [ "reqwest", "serde", diff --git a/validation/Cargo.toml b/validation/Cargo.toml index 5f2cd74..471f0da 100644 --- a/validation/Cargo.toml +++ b/validation/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -submissions-api = { version = "0.2.2", features = ["internal","external"], registry = "strafesnet" } +submissions-api = { version = "0.2.3-pre1", features = ["internal","external"], registry = "strafesnet" } async-nats = "0.38.0" futures = "0.3.31" rbx_asset = { version = "0.2.5", registry = "strafesnet" } diff --git a/validation/src/validator.rs b/validation/src/validator.rs index bcb3ae5..1a3611e 100644 --- a/validation/src/validator.rs +++ b/validation/src/validator.rs @@ -2,6 +2,8 @@ use futures::TryStreamExt; use crate::nats_types::ValidateRequest; +use submissions_api::external::ScriptPolicyResponse; + const SCRIPT_CONCURRENCY:usize=16; enum Policy{ @@ -12,6 +14,24 @@ enum Policy{ Replace(String), } +// this is awful +fn interpret_get_script_policy_response(reponse:Result)->Result,submissions_api::Error>{ + match reponse{ + Ok(script_policy)=>Ok(Some(script_policy)), + Err(e)=>{ + if let submissions_api::Error::Reqwest(error)=&e{ + if let Some(status_code)=error.status(){ + if status_code.as_u16()==404{ + // wew we figured out that the resource does not exist + return Ok(None); + } + } + } + return Err(e); + } + } +} + #[allow(dead_code)] #[derive(Debug)] pub enum ValidateError{ @@ -22,6 +42,8 @@ pub enum ValidateError{ ReadDom(ReadDomError), ApiGetScriptPolicy(submissions_api::Error), ApiGetScript(submissions_api::Error), + ApiCreateScript(submissions_api::Error), + ApiCreateScriptPolicy(submissions_api::Error), ApiUpdateSubmissionModel(submissions_api::Error), ApiActionSubmissionValidate(submissions_api::Error), WriteDom(rbx_binary::EncodeError), @@ -89,23 +111,40 @@ impl Validator{ let hash=std::hash::Hasher::finish(&hasher); // fetch the script policy - let script_policy=self.api.get_script_policy_from_hash(submissions_api::external::ScriptPolicyHashRequest{ - hash:format!("{:x}",hash), - }).await.map_err(ValidateError::ApiGetScriptPolicy)?; + let script_policy=interpret_get_script_policy_response( + self.api.get_script_policy_from_hash(submissions_api::external::ScriptPolicyHashRequest{ + hash:format!("{:x}",hash), + }).await + ).map_err(ValidateError::ApiGetScriptPolicy)?; // write the policy to the script_map, fetching the replacement code if necessary - *replacement=match script_policy.Policy{ - submissions_api::external::Policy::None=>Policy::None, - submissions_api::external::Policy::Allowed=>Policy::Allowed, - submissions_api::external::Policy::Blocked=>Policy::Blocked, - submissions_api::external::Policy::Delete=>Policy::Delete, - submissions_api::external::Policy::Replace=>{ - let script=self.api.get_script(submissions_api::external::GetScriptRequest{ - ScriptID:script_policy.ToScriptID, - }).await.map_err(ValidateError::ApiGetScript)?; - Policy::Replace(script.Source) - }, - }; + if let Some(script_policy)=script_policy{ + *replacement=match script_policy.Policy{ + submissions_api::external::Policy::None=>Policy::None, + submissions_api::external::Policy::Allowed=>Policy::Allowed, + submissions_api::external::Policy::Blocked=>Policy::Blocked, + submissions_api::external::Policy::Delete=>Policy::Delete, + submissions_api::external::Policy::Replace=>{ + let script=self.api.get_script(submissions_api::external::GetScriptRequest{ + ScriptID:script_policy.ToScriptID, + }).await.map_err(ValidateError::ApiGetScript)?; + Policy::Replace(script.Source) + }, + }; + }else{ + // upload the script + let script=self.api.create_script(submissions_api::external::CreateScriptRequest{ + Source:source.clone(), + SubmissionID:Some(validate_info.SubmissionID), + }).await.map_err(ValidateError::ApiCreateScript)?; + + // create a None policy (pending review by yours truly) + self.api.create_script_policy(submissions_api::external::CreateScriptPolicyRequest{ + ToScriptID:script.ID, + FromScriptID:script.ID, + Policy:submissions_api::external::Policy::None, + }).await.map_err(ValidateError::ApiCreateScriptPolicy)?; + } Ok(()) })