From db52b1dcd4ad90b527f2763e01d86f7f968c9048 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Sat, 14 Dec 2024 12:31:31 -0800 Subject: [PATCH] scripts: name property --- openapi.yaml | 14 +++++ pkg/api/oas_json_gen.go | 83 ++++++++++++++++++++++++------ pkg/api/oas_schemas_gen.go | 33 ++++++++++++ pkg/api/oas_validators_gen.go | 64 +++++++++++++++++++++++ pkg/model/script.go | 1 + pkg/service/scripts.go | 5 ++ submissions-api-rs/Cargo.lock | 2 +- submissions-api-rs/Cargo.toml | 2 +- submissions-api-rs/src/external.rs | 14 ++--- validation/Cargo.lock | 4 +- validation/Cargo.toml | 2 +- validation/src/validator.rs | 23 ++++++--- 12 files changed, 213 insertions(+), 34 deletions(-) diff --git a/openapi.yaml b/openapi.yaml index 5288934..06dc6a9 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -613,6 +613,7 @@ components: Script: required: - ID + - Name - Hash - Source - SubmissionID @@ -621,6 +622,10 @@ components: ID: type: integer format: int64 + Name: + type: string + minLength: 64 + maxLength: 64 Hash: type: string minLength: 16 @@ -633,10 +638,15 @@ components: format: int64 ScriptCreate: required: + - Name - Source # - SubmissionID type: object properties: + Name: + type: string + minLength: 64 + maxLength: 64 Source: type: string maxLength: 1048576 @@ -651,6 +661,10 @@ components: ID: type: integer format: int64 + Name: + type: string + minLength: 64 + maxLength: 64 Source: type: string maxLength: 1048576 diff --git a/pkg/api/oas_json_gen.go b/pkg/api/oas_json_gen.go index 1ddcba3..0773f6e 100644 --- a/pkg/api/oas_json_gen.go +++ b/pkg/api/oas_json_gen.go @@ -740,6 +740,10 @@ func (s *Script) encodeFields(e *jx.Encoder) { e.FieldStart("ID") e.Int64(s.ID) } + { + e.FieldStart("Name") + e.Str(s.Name) + } { e.FieldStart("Hash") e.Str(s.Hash) @@ -754,11 +758,12 @@ func (s *Script) encodeFields(e *jx.Encoder) { } } -var jsonFieldsNameOfScript = [4]string{ +var jsonFieldsNameOfScript = [5]string{ 0: "ID", - 1: "Hash", - 2: "Source", - 3: "SubmissionID", + 1: "Name", + 2: "Hash", + 3: "Source", + 4: "SubmissionID", } // Decode decodes Script from json. @@ -782,8 +787,20 @@ func (s *Script) Decode(d *jx.Decoder) error { }(); err != nil { return errors.Wrap(err, "decode field \"ID\"") } - case "Hash": + case "Name": requiredBitSet[0] |= 1 << 1 + if err := func() error { + v, err := d.Str() + s.Name = string(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"Name\"") + } + case "Hash": + requiredBitSet[0] |= 1 << 2 if err := func() error { v, err := d.Str() s.Hash = string(v) @@ -795,7 +812,7 @@ func (s *Script) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"Hash\"") } case "Source": - requiredBitSet[0] |= 1 << 2 + requiredBitSet[0] |= 1 << 3 if err := func() error { v, err := d.Str() s.Source = string(v) @@ -807,7 +824,7 @@ func (s *Script) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"Source\"") } case "SubmissionID": - requiredBitSet[0] |= 1 << 3 + requiredBitSet[0] |= 1 << 4 if err := func() error { v, err := d.Int64() s.SubmissionID = int64(v) @@ -828,7 +845,7 @@ func (s *Script) Decode(d *jx.Decoder) error { // Validate required fields. var failures []validate.FieldError for i, mask := range [1]uint8{ - 0b00001111, + 0b00011111, } { if result := (requiredBitSet[i] & mask) ^ mask; result != 0 { // Mask only required fields and check equality to mask using XOR. @@ -883,6 +900,10 @@ func (s *ScriptCreate) Encode(e *jx.Encoder) { // encodeFields encodes fields. func (s *ScriptCreate) encodeFields(e *jx.Encoder) { + { + e.FieldStart("Name") + e.Str(s.Name) + } { e.FieldStart("Source") e.Str(s.Source) @@ -895,9 +916,10 @@ func (s *ScriptCreate) encodeFields(e *jx.Encoder) { } } -var jsonFieldsNameOfScriptCreate = [2]string{ - 0: "Source", - 1: "SubmissionID", +var jsonFieldsNameOfScriptCreate = [3]string{ + 0: "Name", + 1: "Source", + 2: "SubmissionID", } // Decode decodes ScriptCreate from json. @@ -909,8 +931,20 @@ func (s *ScriptCreate) Decode(d *jx.Decoder) error { if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { switch string(k) { - case "Source": + case "Name": requiredBitSet[0] |= 1 << 0 + if err := func() error { + v, err := d.Str() + s.Name = string(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"Name\"") + } + case "Source": + requiredBitSet[0] |= 1 << 1 if err := func() error { v, err := d.Str() s.Source = string(v) @@ -941,7 +975,7 @@ func (s *ScriptCreate) Decode(d *jx.Decoder) error { // Validate required fields. var failures []validate.FieldError for i, mask := range [1]uint8{ - 0b00000001, + 0b00000011, } { if result := (requiredBitSet[i] & mask) ^ mask; result != 0 { // Mask only required fields and check equality to mask using XOR. @@ -1538,6 +1572,12 @@ func (s *ScriptUpdate) encodeFields(e *jx.Encoder) { e.FieldStart("ID") e.Int64(s.ID) } + { + if s.Name.Set { + e.FieldStart("Name") + s.Name.Encode(e) + } + } { if s.Source.Set { e.FieldStart("Source") @@ -1552,10 +1592,11 @@ func (s *ScriptUpdate) encodeFields(e *jx.Encoder) { } } -var jsonFieldsNameOfScriptUpdate = [3]string{ +var jsonFieldsNameOfScriptUpdate = [4]string{ 0: "ID", - 1: "Source", - 2: "SubmissionID", + 1: "Name", + 2: "Source", + 3: "SubmissionID", } // Decode decodes ScriptUpdate from json. @@ -1579,6 +1620,16 @@ func (s *ScriptUpdate) Decode(d *jx.Decoder) error { }(); err != nil { return errors.Wrap(err, "decode field \"ID\"") } + case "Name": + if err := func() error { + s.Name.Reset() + if err := s.Name.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"Name\"") + } case "Source": if err := func() error { s.Source.Reset() diff --git a/pkg/api/oas_schemas_gen.go b/pkg/api/oas_schemas_gen.go index b793b9d..ca71607 100644 --- a/pkg/api/oas_schemas_gen.go +++ b/pkg/api/oas_schemas_gen.go @@ -425,6 +425,7 @@ func (s *Pagination) SetLimit(val int32) { // Ref: #/components/schemas/Script type Script struct { ID int64 `json:"ID"` + Name string `json:"Name"` Hash string `json:"Hash"` Source string `json:"Source"` SubmissionID int64 `json:"SubmissionID"` @@ -435,6 +436,11 @@ func (s *Script) GetID() int64 { return s.ID } +// GetName returns the value of Name. +func (s *Script) GetName() string { + return s.Name +} + // GetHash returns the value of Hash. func (s *Script) GetHash() string { return s.Hash @@ -455,6 +461,11 @@ func (s *Script) SetID(val int64) { s.ID = val } +// SetName sets the value of Name. +func (s *Script) SetName(val string) { + s.Name = val +} + // SetHash sets the value of Hash. func (s *Script) SetHash(val string) { s.Hash = val @@ -472,10 +483,16 @@ func (s *Script) SetSubmissionID(val int64) { // Ref: #/components/schemas/ScriptCreate type ScriptCreate struct { + Name string `json:"Name"` Source string `json:"Source"` SubmissionID OptInt64 `json:"SubmissionID"` } +// GetName returns the value of Name. +func (s *ScriptCreate) GetName() string { + return s.Name +} + // GetSource returns the value of Source. func (s *ScriptCreate) GetSource() string { return s.Source @@ -486,6 +503,11 @@ func (s *ScriptCreate) GetSubmissionID() OptInt64 { return s.SubmissionID } +// SetName sets the value of Name. +func (s *ScriptCreate) SetName(val string) { + s.Name = val +} + // SetSource sets the value of Source. func (s *ScriptCreate) SetSource(val string) { s.Source = val @@ -680,6 +702,7 @@ func (s *ScriptPolicyUpdate) SetPolicy(val OptInt32) { // Ref: #/components/schemas/ScriptUpdate type ScriptUpdate struct { ID int64 `json:"ID"` + Name OptString `json:"Name"` Source OptString `json:"Source"` SubmissionID OptInt64 `json:"SubmissionID"` } @@ -689,6 +712,11 @@ func (s *ScriptUpdate) GetID() int64 { return s.ID } +// GetName returns the value of Name. +func (s *ScriptUpdate) GetName() OptString { + return s.Name +} + // GetSource returns the value of Source. func (s *ScriptUpdate) GetSource() OptString { return s.Source @@ -704,6 +732,11 @@ func (s *ScriptUpdate) SetID(val int64) { s.ID = val } +// SetName sets the value of Name. +func (s *ScriptUpdate) SetName(val OptString) { + s.Name = val +} + // SetSource sets the value of Source. func (s *ScriptUpdate) SetSource(val OptString) { s.Source = val diff --git a/pkg/api/oas_validators_gen.go b/pkg/api/oas_validators_gen.go index fd31926..6b76af3 100644 --- a/pkg/api/oas_validators_gen.go +++ b/pkg/api/oas_validators_gen.go @@ -148,6 +148,25 @@ func (s *Script) Validate() error { } var failures []validate.FieldError + if err := func() error { + if err := (validate.String{ + MinLength: 64, + MinLengthSet: true, + MaxLength: 64, + MaxLengthSet: true, + Email: false, + Hostname: false, + Regex: nil, + }).Validate(string(s.Name)); err != nil { + return errors.Wrap(err, "string") + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "Name", + Error: err, + }) + } if err := func() error { if err := (validate.String{ MinLength: 16, @@ -198,6 +217,25 @@ func (s *ScriptCreate) Validate() error { } var failures []validate.FieldError + if err := func() error { + if err := (validate.String{ + MinLength: 64, + MinLengthSet: true, + MaxLength: 64, + MaxLengthSet: true, + Email: false, + Hostname: false, + Regex: nil, + }).Validate(string(s.Name)); err != nil { + return errors.Wrap(err, "string") + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "Name", + Error: err, + }) + } if err := func() error { if err := (validate.String{ MinLength: 0, @@ -298,6 +336,32 @@ func (s *ScriptUpdate) Validate() error { } var failures []validate.FieldError + if err := func() error { + if value, ok := s.Name.Get(); ok { + if err := func() error { + if err := (validate.String{ + MinLength: 64, + MinLengthSet: true, + MaxLength: 64, + MaxLengthSet: true, + Email: false, + Hostname: false, + Regex: nil, + }).Validate(string(value)); err != nil { + return errors.Wrap(err, "string") + } + return nil + }(); err != nil { + return err + } + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "Name", + Error: err, + }) + } if err := func() error { if value, ok := s.Source.Get(); ok { if err := func() error { diff --git a/pkg/model/script.go b/pkg/model/script.go index 1383cf4..87e9ac0 100644 --- a/pkg/model/script.go +++ b/pkg/model/script.go @@ -4,6 +4,7 @@ import "time" type Script struct { ID int64 `gorm:"primaryKey"` + Name string Hash uint64 Source string SubmissionID int64 // which submission did this script first appear in diff --git a/pkg/service/scripts.go b/pkg/service/scripts.go index 185866d..bf46dd7 100644 --- a/pkg/service/scripts.go +++ b/pkg/service/scripts.go @@ -27,6 +27,7 @@ func (svc *Service) CreateScript(ctx context.Context, req *api.ScriptCreate) (*a script, err := svc.DB.Scripts().Create(ctx, model.Script{ ID: 0, + Name: req.Name, Hash: siphash.Hash(0, 0, []byte(req.Source)), Source: req.Source, SubmissionID: req.SubmissionID.Or(0), @@ -78,6 +79,7 @@ func (svc *Service) GetScript(ctx context.Context, params api.GetScriptParams) ( return &api.Script{ ID: script.ID, + Name: script.Name, Hash: fmt.Sprintf("%x", script.Hash), Source: script.Source, SubmissionID: script.SubmissionID, @@ -100,6 +102,9 @@ func (svc *Service) UpdateScript(ctx context.Context, req *api.ScriptUpdate, par } pmap := datastore.Optional() + if Name, ok := req.Name.Get(); ok { + pmap.Add("name", Name) + } if source, ok := req.Source.Get(); ok { pmap.Add("source", source) pmap.Add("hash", siphash.Hash(0, 0, []byte(source))) diff --git a/submissions-api-rs/Cargo.lock b/submissions-api-rs/Cargo.lock index 6dcea33..2a9dd6b 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.3-pre1" +version = "0.2.3-scriptname2" dependencies = [ "reqwest", "serde", diff --git a/submissions-api-rs/Cargo.toml b/submissions-api-rs/Cargo.toml index 5d5efce..2ab7981 100644 --- a/submissions-api-rs/Cargo.toml +++ b/submissions-api-rs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "submissions-api" -version = "0.2.3-pre1" +version = "0.2.3-scriptname2" edition = "2021" publish = ["strafesnet"] repository = "https://git.itzana.me/StrafesNET/maps-service" diff --git a/submissions-api-rs/src/external.rs b/submissions-api-rs/src/external.rs index 2c235cf..6d449f2 100644 --- a/submissions-api-rs/src/external.rs +++ b/submissions-api-rs/src/external.rs @@ -13,14 +13,16 @@ pub struct GetScriptRequest{ #[derive(serde::Deserialize)] pub struct ScriptResponse{ pub ID:i64, + pub Name:String, pub Hash:String, pub Source:String, pub SubmissionID:i64, } #[allow(nonstandard_style)] #[derive(serde::Serialize)] -pub struct CreateScriptRequest{ - pub Source:String, +pub struct CreateScriptRequest<'a>{ + pub Name:&'a str, + pub Source:&'a str, pub SubmissionID:Option, } #[allow(nonstandard_style)] @@ -39,8 +41,8 @@ pub enum Policy{ Replace=4, } -pub struct ScriptPolicyHashRequest{ - pub hash:String, +pub struct ScriptPolicyHashRequest<'a>{ + pub hash:&'a str, } #[allow(nonstandard_style)] #[derive(serde::Deserialize)] @@ -85,7 +87,7 @@ impl Context{ .error_for_status().map_err(Error::Reqwest)? .json().await.map_err(Error::Reqwest) } - pub async fn create_script(&self,config:CreateScriptRequest)->Result{ + pub async fn create_script<'a>(&self,config:CreateScriptRequest<'a>)->Result{ let url_raw=format!("{}/scripts",self.0.base_url); let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::ParseError)?; @@ -95,7 +97,7 @@ impl Context{ .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{ + pub async fn get_script_policy_from_hash<'a>(&self,config:ScriptPolicyHashRequest<'a>)->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)?; diff --git a/validation/Cargo.lock b/validation/Cargo.lock index 378a929..22a9b7d 100644 --- a/validation/Cargo.lock +++ b/validation/Cargo.lock @@ -1804,9 +1804,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "submissions-api" -version = "0.2.3-pre1" +version = "0.2.3-scriptname2" source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/" -checksum = "6f5f7afe0137bd065c750f6d8c05892532cd50b9feba588847c10df37e660ad2" +checksum = "b20db7cc0f6bda2b2ff4c413fe7bbdeddc2f6d88cf8ef9c2f8cd998d1f0b9b68" dependencies = [ "reqwest", "serde", diff --git a/validation/Cargo.toml b/validation/Cargo.toml index 471f0da..dbea0e9 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.3-pre1", features = ["internal","external"], registry = "strafesnet" } +submissions-api = { version = "0.2.3-scriptname2", 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 1a3611e..ab4995c 100644 --- a/validation/src/validator.rs +++ b/validation/src/validator.rs @@ -14,6 +14,11 @@ enum Policy{ Replace(String), } +struct NamePolicy{ + name:String, + policy:Policy, +} + // this is awful fn interpret_get_script_policy_response(reponse:Result)->Result,submissions_api::Error>{ match reponse{ @@ -93,18 +98,21 @@ impl Validator{ // collect unique scripts let script_refs=get_script_refs(&dom); - let mut script_map=std::collections::HashMap::::new(); + let mut script_map=std::collections::HashMap::::new(); for &script_ref in &script_refs{ if let Some(script)=dom.get_by_ref(script_ref){ if let Some(rbx_dom_weak::types::Variant::String(source))=script.properties.get("Source"){ - script_map.insert(source.clone(),Policy::None); + script_map.insert(source.clone(),NamePolicy{ + name:script.name.clone(), + policy:Policy::None, + }); } } } // send all script hashes to REST endpoint and retrieve the replacements futures::stream::iter(script_map.iter_mut().map(Ok)) - .try_for_each_concurrent(Some(SCRIPT_CONCURRENCY),|(source,replacement)|async{ + .try_for_each_concurrent(Some(SCRIPT_CONCURRENCY),|(source,NamePolicy{policy,name})|async{ // get the hash let mut hasher=siphasher::sip::SipHasher::new(); std::hash::Hasher::write(&mut hasher,source.as_bytes()); @@ -113,13 +121,13 @@ impl Validator{ // fetch the script policy let script_policy=interpret_get_script_policy_response( self.api.get_script_policy_from_hash(submissions_api::external::ScriptPolicyHashRequest{ - hash:format!("{:x}",hash), + hash:format!("{:x}",hash).as_str(), }).await ).map_err(ValidateError::ApiGetScriptPolicy)?; // write the policy to the script_map, fetching the replacement code if necessary if let Some(script_policy)=script_policy{ - *replacement=match script_policy.Policy{ + *policy=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, @@ -134,7 +142,8 @@ impl Validator{ }else{ // upload the script let script=self.api.create_script(submissions_api::external::CreateScriptRequest{ - Source:source.clone(), + Name:name.as_str(), + Source:source.as_str(), SubmissionID:Some(validate_info.SubmissionID), }).await.map_err(ValidateError::ApiCreateScript)?; @@ -155,7 +164,7 @@ impl Validator{ for &script_ref in &script_refs{ if let Some(script)=dom.get_by_ref_mut(script_ref){ if let Some(rbx_dom_weak::types::Variant::String(source))=script.properties.get_mut("Source"){ - match script_map.get(source.as_str()){ + match script_map.get(source.as_str()).map(|p|&p.policy){ Some(Policy::Blocked)=>return Err(ValidateError::Blocked), None |Some(Policy::None)