Create Missing Allowed Policies #3

Merged
Quaternions merged 8 commits from repair into master 2025-07-05 10:20:06 +00:00
2 changed files with 94 additions and 27 deletions

29
Cargo.lock generated
View File

@@ -135,9 +135,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
[[package]]
name = "cc"
version = "1.2.27"
version = "1.2.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc"
checksum = "4ad45f4f74e4e20eaa392913b7b33a7091c87e59628f4dd27888205ad888843c"
dependencies = [
"shlex",
]
@@ -705,6 +705,17 @@ dependencies = [
"hashbrown",
]
[[package]]
name = "io-uring"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013"
dependencies = [
"bitflags",
"cfg-if",
"libc",
]
[[package]]
name = "ipnet"
version = "2.11.0"
@@ -987,9 +998,9 @@ dependencies = [
[[package]]
name = "reqwest"
version = "0.12.21"
version = "0.12.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c8cea6b35bcceb099f30173754403d2eba0a5dc18cea3630fccd88251909288"
checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531"
dependencies = [
"base64",
"bytes",
@@ -1250,9 +1261,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "submissions-api"
version = "0.8.1"
version = "0.8.2"
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
checksum = "a08deea49e9e34f2f2f23219f4a565681b4c1ae46f8012496d9a8fe10897efd3"
checksum = "ced7fba3c9851f2ee97e4be939a544b92794c234ab090b76e8f2cef540f5c92f"
dependencies = [
"chrono",
"reqwest",
@@ -1345,15 +1356,17 @@ dependencies = [
[[package]]
name = "tokio"
version = "1.45.1"
version = "1.46.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779"
checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17"
dependencies = [
"backtrace",
"bytes",
"io-uring",
"libc",
"mio",
"pin-project-lite",
"slab",
"socket2",
"tokio-macros",
"windows-sys 0.52.0",

View File

@@ -1,7 +1,7 @@
use clap::{Args,Parser,Subcommand};
use futures::{StreamExt,TryStreamExt};
use rand::seq::SliceRandom;
use submissions_api::types::{ScriptResponse,ScriptPolicyResponse};
use submissions_api::types::{Policy,ScriptResponse,ScriptPolicyResponse};
use std::io::Write;
use std::path::PathBuf;
@@ -134,7 +134,7 @@ async fn review(config:ReviewConfig)->Result<(),ReviewError>{
Limit:100,
FromScriptHash:None,
ToScriptID:None,
Policy:Some(submissions_api::types::Policy::None),
Policy:Some(Policy::None),
}).await.map_err(ReviewError::GetPolicies)?;
let unreviewed_policy_count=unreviewed_policies.len();
@@ -186,7 +186,7 @@ async fn review(config:ReviewConfig)->Result<(),ReviewError>{
//if current.lua was updated, create an allowed and replace file and set script_action to replace(new_id)
let modified_source=tokio::fs::read_to_string("current.lua").await.map_err(ReviewError::ReadCurrent)?;
if modified_source==source{
submissions_api::types::Policy::Allowed
Policy::Allowed
}else{
// compute hash
let hash=hash_source(modified_source.as_str());
@@ -213,7 +213,7 @@ async fn review(config:ReviewConfig)->Result<(),ReviewError>{
api.create_script_policy(submissions_api::types::CreateScriptPolicyRequest{
FromScriptID:new_script.ScriptID,
ToScriptID:new_script.ScriptID,
Policy:submissions_api::types::Policy::Allowed,
Policy:Policy::Allowed,
}).await.map_err(ReviewError::UploadModifiedPolicy)?;
new_script.ScriptID
@@ -221,12 +221,12 @@ async fn review(config:ReviewConfig)->Result<(),ReviewError>{
});
// use replace policy
submissions_api::types::Policy::Replace
Policy::Replace
}
},
ScriptActionParseResult::Block=>submissions_api::types::Policy::Blocked,
ScriptActionParseResult::Block=>Policy::Blocked,
ScriptActionParseResult::Exit=>break,
ScriptActionParseResult::Delete=>submissions_api::types::Policy::Delete,
ScriptActionParseResult::Delete=>Policy::Delete,
ScriptActionParseResult::Skip=>continue,
};
@@ -437,7 +437,7 @@ async fn upload_scripts(config:UploadConfig)->Result<(),ScriptUploadError>{
submissions_api::types::CreateScriptPolicyRequest{
FromScriptID:script_ids[source.as_str()],
ToScriptID:script_ids[allowed_map[id].as_str()],
Policy:submissions_api::types::Policy::Replace,
Policy:Policy::Replace,
}
).await.map_err(ScriptUploadError::GetOrCreatePolicyReplace)
});
@@ -451,7 +451,7 @@ async fn upload_scripts(config:UploadConfig)->Result<(),ScriptUploadError>{
submissions_api::types::CreateScriptPolicyRequest{
FromScriptID:script_ids[source.as_str()],
ToScriptID:script_ids[source.as_str()],
Policy:submissions_api::types::Policy::Allowed,
Policy:Policy::Allowed,
}
).await.map_err(ScriptUploadError::GetOrCreatePolicyAllowed)
});
@@ -465,7 +465,7 @@ async fn upload_scripts(config:UploadConfig)->Result<(),ScriptUploadError>{
submissions_api::types::CreateScriptPolicyRequest{
FromScriptID:script_ids[source.as_str()],
ToScriptID:script_ids[source.as_str()],
Policy:submissions_api::types::Policy::Blocked,
Policy:Policy::Blocked,
}
).await.map_err(ScriptUploadError::GetOrCreatePolicyBlocked)
});
@@ -487,6 +487,7 @@ enum RepairError{
UpdateScriptPolicy(submissions_api::Error),
DeleteScript(submissions_api::Error),
DeleteScriptPolicy(submissions_api::Error),
CreateScriptPolicy(submissions_api::Error),
}
struct RepairConfig{
session_id:String,
@@ -532,7 +533,7 @@ async fn download_policies(api:&submissions_api::external::Context)->Result<Vec<
Limit:LIMIT,
FromScriptHash:None,
ToScriptID:None,
Policy:Some(submissions_api::types::Policy::Replace),
Policy:None,
}).await.map_err(RepairError::GetPolicies)?;
let done=new_policies.len()<LIMIT as usize;
@@ -557,7 +558,8 @@ async fn repair(config:RepairConfig)->Result<(),RepairError>{
download_policies(api),
)?;
let mut script_id_from_hash=std::collections::HashMap::new();
let mut script_from_id=std::collections::HashMap::new();
let mut script_from_hash=std::collections::HashMap::new();
let mut unique_sources=std::collections::HashSet::new();
let mut duplicate_scripts=Vec::new();
@@ -570,7 +572,8 @@ async fn repair(config:RepairConfig)->Result<(),RepairError>{
ScriptID:script.ID,
});
}else{
script_id_from_hash.insert(script.Hash.as_str(),script);
script_from_id.insert(script.ID,script);
script_from_hash.insert(script.Hash.as_str(),script);
}
}
@@ -593,32 +596,40 @@ async fn repair(config:RepairConfig)->Result<(),RepairError>{
}).await.map_err(RepairError::DeleteScript)?;
}
let mut unique_policies=std::collections::HashSet::new();
let mut policy_from_hash=std::collections::HashMap::new();
let mut update_policies=Vec::new();
let mut policies_not_unique=Vec::new();
let mut policies_missing_from_script=Vec::new();
let mut check_policy_exists=Vec::new();
for policy in &policies{
let from_script=script_id_from_hash.get(policy.FromScriptHash.as_str());
let from_script=script_from_hash.get(policy.FromScriptHash.as_str());
if let Some(&from_script)=from_script{
if policy.ToScriptID==from_script.ID{
if policy.Policy==Policy::Replace&&policy.ToScriptID==from_script.ID{
// invalid policy. Reset the policy to None
println!("Invalid policy {:?}, queueing update...",policy.ID);
update_policies.push(submissions_api::types::UpdateScriptPolicyRequest{
ID:policy.ID,
FromScriptID:None,
ToScriptID:None,
Policy:Some(submissions_api::types::Policy::None),
Policy:Some(Policy::None),
});
}else{
// if not unique
if !unique_policies.insert(policy.FromScriptHash.as_str()){
println!("Policy is not unique! hash={} id={:?}",policy.FromScriptHash,policy.ID);
if let Some(old_policy)=policy_from_hash.insert(policy.FromScriptHash.as_str(),policy){
println!("Policy is not unique! hash={} {:?} {:?}",policy.FromScriptHash,policy.ID,old_policy.ID);
policies_not_unique.push(submissions_api::types::GetScriptPolicyRequest{
ScriptPolicyID:policy.ID,
});
}else{
// if policy is replace, but destination script is not allowed
if let Some(&to_script)=script_from_id.get(&policy.ToScriptID){
check_policy_exists.push((policy,to_script));
}else{
println!("ToScript does not exist! {:?} {:?} DOING NOTHING",policy.ToScriptID,policy.ID);
}
}
}
}else{
@@ -629,6 +640,27 @@ async fn repair(config:RepairConfig)->Result<(),RepairError>{
}
}
let mut create_allow_policy=std::collections::HashSet::new();
for (policy,to_script) in check_policy_exists{
if let Some(&allow_policy)=policy_from_hash.get(to_script.Hash.as_str()){
if policy.Policy==Policy::Replace&&allow_policy.Policy!=Policy::Allowed{
println!("Policy {:?} ToScript {:?} Policy {:?} was expected to be Allowed, but was {:?}!",policy.ID,to_script.ID,allow_policy.ID,allow_policy.Policy);
}
}else{
if policy.Policy==Policy::Replace{
println!("Policy {:?} ToScript {:?} has no Allowed policy!",policy.ID,to_script.ID);
create_allow_policy.insert(to_script.ID);
}
}
}
// All scripts should have exactly one policy
for script in &scripts{
if !policy_from_hash.contains_key(script.Hash.as_str()){
println!("Script {:?} has no policy!",script.ID);
}
}
if !update_policies.is_empty(){
print!("Update {} policies? [y/N]: ",update_policies.len());
std::io::stdout().flush().map_err(RepairError::Io)?;
@@ -680,6 +712,28 @@ async fn repair(config:RepairConfig)->Result<(),RepairError>{
api.delete_script_policy(request)
}).await.map_err(RepairError::DeleteScriptPolicy)?;
}
if !create_allow_policy.is_empty(){
print!("Create {} missing Allowed policies? [y/N]: ",create_allow_policy.len());
std::io::stdout().flush().map_err(RepairError::Io)?;
let mut input=String::new();
std::io::stdin().read_line(&mut input).map_err(RepairError::Io)?;
match input.trim(){
"y"|"Y"=>(),
_=>{
println!("Quitting.");
return Ok(());
},
}
futures::stream::iter(create_allow_policy).map(Ok).try_for_each_concurrent(REMOTE_CONCURRENCY,async|script_id|{
api.create_script_policy(submissions_api::types::CreateScriptPolicyRequest{
FromScriptID:script_id,
ToScriptID:script_id,
Policy:Policy::Allowed,
}).await?;
Ok(())
}).await.map_err(RepairError::CreateScriptPolicy)?;
}
Ok(())
}