validation: upload new scripts

This commit is contained in:
Quaternions 2024-12-14 00:15:05 -08:00
parent 64e9e2b263
commit 332578ec94
9 changed files with 117 additions and 27 deletions

View File

@ -952,7 +952,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]] [[package]]
name = "submissions-api" name = "submissions-api"
version = "0.2.2" version = "0.2.3-pre1"
dependencies = [ dependencies = [
"reqwest", "reqwest",
"serde", "serde",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "submissions-api" name = "submissions-api"
version = "0.2.2" version = "0.2.3-pre1"
edition = "2021" edition = "2021"
publish = ["strafesnet"] publish = ["strafesnet"]
repository = "https://git.itzana.me/StrafesNET/maps-service" repository = "https://git.itzana.me/StrafesNET/maps-service"

View File

@ -16,8 +16,13 @@ impl Context{
self.client.get(url) self.client.get(url)
.send().await .send().await
} }
pub async fn post(&self,url:impl reqwest::IntoUrl)->Result<reqwest::Response,reqwest::Error>{ pub async fn post_empty_body(&self,url:impl reqwest::IntoUrl)->Result<reqwest::Response,reqwest::Error>{
self.client.post(url) self.client.post(url)
.send().await .send().await
} }
pub async fn post(&self,url:impl reqwest::IntoUrl,body:impl Into<reqwest::Body>)->Result<reqwest::Response,reqwest::Error>{
self.client.post(url)
.body(body)
.send().await
}
} }

View File

@ -1,7 +1,9 @@
use crate::Error; use crate::Error;
#[derive(serde::Deserialize)] #[derive(Clone,Copy,serde::Serialize,serde::Deserialize)]
pub struct ScriptID(pub(crate) i64); pub struct ScriptID(i64);
#[derive(Clone,Copy,serde::Serialize,serde::Deserialize)]
pub struct ScriptPolicyID(i64);
#[allow(nonstandard_style)] #[allow(nonstandard_style)]
pub struct GetScriptRequest{ pub struct GetScriptRequest{
@ -15,8 +17,19 @@ pub struct ScriptResponse{
pub Source:String, pub Source:String,
pub SubmissionID:i64, pub SubmissionID:i64,
} }
#[allow(nonstandard_style)]
#[derive(serde::Serialize)]
pub struct CreateScriptRequest{
pub Source:String,
pub SubmissionID:Option<i64>,
}
#[allow(nonstandard_style)]
#[derive(serde::Deserialize)] #[derive(serde::Deserialize)]
pub struct ScriptIDResponse{
pub ID:ScriptID,
}
#[derive(serde::Serialize,serde::Deserialize)]
#[repr(i32)] #[repr(i32)]
pub enum Policy{ pub enum Policy{
None=0, // not yet reviewed None=0, // not yet reviewed
@ -37,6 +50,18 @@ pub struct ScriptPolicyResponse{
pub ToScriptID:ScriptID, pub ToScriptID:ScriptID,
pub Policy:Policy 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)] #[allow(nonstandard_style)]
pub struct UpdateSubmissionModelRequest{ pub struct UpdateSubmissionModelRequest{
@ -60,6 +85,16 @@ impl Context{
.error_for_status().map_err(Error::Reqwest)? .error_for_status().map_err(Error::Reqwest)?
.json().await.map_err(Error::Reqwest) .json().await.map_err(Error::Reqwest)
} }
pub async fn create_script(&self,config:CreateScriptRequest)->Result<ScriptIDResponse,Error>{
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<ScriptPolicyResponse,Error>{ pub async fn get_script_policy_from_hash(&self,config:ScriptPolicyHashRequest)->Result<ScriptPolicyResponse,Error>{
let url_raw=format!("{}/script-policy/hash/{}",self.0.base_url,config.hash); 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)?; 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)? .error_for_status().map_err(Error::Reqwest)?
.json().await.map_err(Error::Reqwest) .json().await.map_err(Error::Reqwest)
} }
pub async fn create_script_policy(&self,config:CreateScriptPolicyRequest)->Result<ScriptPolicyIDResponse,Error>{
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>{ pub async fn update_submission_model(&self,config:UpdateSubmissionModelRequest)->Result<(),Error>{
let url_raw=format!("{}/submissions/{}/model",self.0.base_url,config.SubmissionID); 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)?; 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()); .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)?; .error_for_status().map_err(Error::Reqwest)?;
Ok(()) Ok(())

View File

@ -18,7 +18,7 @@ macro_rules! action{
let url_raw=format!(concat!("{}/submissions/{}/status/",$action),self.0.base_url,config.0); 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)?; 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)?; .error_for_status().map_err(Error::Reqwest)?;
Ok(()) Ok(())
@ -38,7 +38,7 @@ impl Context{
.append_pair("TargetAssetID",target_asset_id.to_string().as_str()); .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)?; .error_for_status().map_err(Error::Reqwest)?;
Ok(()) Ok(())

View File

@ -13,6 +13,7 @@ pub type ReqwestError=reqwest::Error;
pub enum Error{ pub enum Error{
ParseError(url::ParseError), ParseError(url::ParseError),
Reqwest(reqwest::Error), Reqwest(reqwest::Error),
JSON(serde_json::Error),
} }
impl std::fmt::Display for Error{ impl std::fmt::Display for Error{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{

4
validation/Cargo.lock generated
View File

@ -1804,9 +1804,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]] [[package]]
name = "submissions-api" name = "submissions-api"
version = "0.2.2" version = "0.2.3-pre1"
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/" source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
checksum = "e7a29fd61d2421c5c1a2923465a611aa84177a0f312fc11d81e4298bfee4aeea" checksum = "6f5f7afe0137bd065c750f6d8c05892532cd50b9feba588847c10df37e660ad2"
dependencies = [ dependencies = [
"reqwest", "reqwest",
"serde", "serde",

View File

@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [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" async-nats = "0.38.0"
futures = "0.3.31" futures = "0.3.31"
rbx_asset = { version = "0.2.5", registry = "strafesnet" } rbx_asset = { version = "0.2.5", registry = "strafesnet" }

View File

@ -2,6 +2,8 @@ use futures::TryStreamExt;
use crate::nats_types::ValidateRequest; use crate::nats_types::ValidateRequest;
use submissions_api::external::ScriptPolicyResponse;
const SCRIPT_CONCURRENCY:usize=16; const SCRIPT_CONCURRENCY:usize=16;
enum Policy{ enum Policy{
@ -12,6 +14,24 @@ enum Policy{
Replace(String), Replace(String),
} }
// this is awful
fn interpret_get_script_policy_response(reponse:Result<ScriptPolicyResponse,submissions_api::Error>)->Result<Option<ScriptPolicyResponse>,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)] #[allow(dead_code)]
#[derive(Debug)] #[derive(Debug)]
pub enum ValidateError{ pub enum ValidateError{
@ -22,6 +42,8 @@ pub enum ValidateError{
ReadDom(ReadDomError), ReadDom(ReadDomError),
ApiGetScriptPolicy(submissions_api::Error), ApiGetScriptPolicy(submissions_api::Error),
ApiGetScript(submissions_api::Error), ApiGetScript(submissions_api::Error),
ApiCreateScript(submissions_api::Error),
ApiCreateScriptPolicy(submissions_api::Error),
ApiUpdateSubmissionModel(submissions_api::Error), ApiUpdateSubmissionModel(submissions_api::Error),
ApiActionSubmissionValidate(submissions_api::Error), ApiActionSubmissionValidate(submissions_api::Error),
WriteDom(rbx_binary::EncodeError), WriteDom(rbx_binary::EncodeError),
@ -89,23 +111,40 @@ impl Validator{
let hash=std::hash::Hasher::finish(&hasher); let hash=std::hash::Hasher::finish(&hasher);
// fetch the script policy // fetch the script policy
let script_policy=self.api.get_script_policy_from_hash(submissions_api::external::ScriptPolicyHashRequest{ let script_policy=interpret_get_script_policy_response(
hash:format!("{:x}",hash), self.api.get_script_policy_from_hash(submissions_api::external::ScriptPolicyHashRequest{
}).await.map_err(ValidateError::ApiGetScriptPolicy)?; hash:format!("{:x}",hash),
}).await
).map_err(ValidateError::ApiGetScriptPolicy)?;
// write the policy to the script_map, fetching the replacement code if necessary // write the policy to the script_map, fetching the replacement code if necessary
*replacement=match script_policy.Policy{ if let Some(script_policy)=script_policy{
submissions_api::external::Policy::None=>Policy::None, *replacement=match script_policy.Policy{
submissions_api::external::Policy::Allowed=>Policy::Allowed, submissions_api::external::Policy::None=>Policy::None,
submissions_api::external::Policy::Blocked=>Policy::Blocked, submissions_api::external::Policy::Allowed=>Policy::Allowed,
submissions_api::external::Policy::Delete=>Policy::Delete, submissions_api::external::Policy::Blocked=>Policy::Blocked,
submissions_api::external::Policy::Replace=>{ submissions_api::external::Policy::Delete=>Policy::Delete,
let script=self.api.get_script(submissions_api::external::GetScriptRequest{ submissions_api::external::Policy::Replace=>{
ScriptID:script_policy.ToScriptID, let script=self.api.get_script(submissions_api::external::GetScriptRequest{
}).await.map_err(ValidateError::ApiGetScript)?; ScriptID:script_policy.ToScriptID,
Policy::Replace(script.Source) }).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(()) Ok(())
}) })