From 3b0e9fddc071facfa4859b4929b18b0ec02ad955 Mon Sep 17 00:00:00 2001
From: Maxime Augier <max@xolus.net>
Date: Fri, 11 Nov 2022 10:00:41 +0100
Subject: [PATCH] Add -l option for dumping existing allow/block lists

---
 src/args.rs |  7 +++++++
 src/db.rs   | 12 ++++++++++++
 src/main.rs | 10 ++++++++++
 3 files changed, 29 insertions(+)

diff --git a/src/args.rs b/src/args.rs
index a778f6d..61e093f 100644
--- a/src/args.rs
+++ b/src/args.rs
@@ -11,6 +11,9 @@ pub(crate) struct Args {
 
     #[arg(short, long, help = "Undo allowing or blocking domains")]
     undo: bool,
+
+    #[arg(short, long, help = "List allowed and blocked domains")]
+    list: bool,
 }
 
 impl Args {
@@ -29,4 +32,8 @@ impl Args {
     pub(crate) fn undo(&self) -> bool {
         self.undo
     }
+
+    pub(crate) fn list(&self) -> bool {
+        self.list
+    }
 }
diff --git a/src/db.rs b/src/db.rs
index 4968526..48160fa 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -142,6 +142,14 @@ impl Inner {
             .map(|s| String::from_utf8_lossy(&s).to_string())
     }
 
+    fn allows(&self) -> impl DoubleEndedIterator<Item = String> {
+        self.allowed_domains
+            .iter()
+            .values()
+            .filter_map(|res| res.ok())
+            .map(|s| String::from_utf8_lossy(&s).to_string())
+    }
+
     fn connected(&self) -> impl DoubleEndedIterator<Item = IriString> {
         self.connected_actor_ids
             .iter()
@@ -452,6 +460,10 @@ impl Db {
         self.unblock(|inner| Ok(inner.blocks().collect())).await
     }
 
+    pub(crate) async fn allows(&self) -> Result<Vec<String>, Error> {
+        self.unblock(|inner| Ok(inner.allows().collect())).await
+    }
+
     pub(crate) async fn inboxes(&self) -> Result<Vec<IriString>, Error> {
         self.unblock(|inner| Ok(inner.connected_actors().map(|actor| actor.inbox).collect()))
             .await
diff --git a/src/main.rs b/src/main.rs
index b35c5f1..3302bc4 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -101,6 +101,16 @@ async fn main() -> Result<(), anyhow::Error> {
 
     let args = Args::new();
 
+    if args.list() {
+        for domain in db.blocks().await? {
+            println!("block {}", domain);
+        }
+        for domain in db.allows().await? {
+            println!("allow {}", domain);
+        }
+        return Ok(());
+    }
+
     if !args.blocks().is_empty() || !args.allowed().is_empty() {
         if args.undo() {
             db.remove_blocks(args.blocks().to_vec()).await?;