diff --git a/src/cmd/acl.rs b/src/cmd/acl.rs
index dee722842ce30a35aed69b346967350111c6df00..db7fd496898d35aea79a763c5b72cdd304d111be 100644
--- a/src/cmd/acl.rs
+++ b/src/cmd/acl.rs
@@ -1,6 +1,8 @@
 use crate::bool_to_result;
+use log::{error, warn};
 use matrix_sdk::{room::Room, ruma::UserId};
-use std::result::Result;
+use std::fmt;
+use std::{process::abort, result::Result};
 
 #[allow(dead_code)]
 pub enum CmdAcl {
@@ -14,6 +16,24 @@ pub struct CmdAdminRegister {
     admins: Vec<UserId>,
 }
 
+impl fmt::Display for CmdAdminRegister {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        if self.admins.len() != 0 {
+            write!(
+                f,
+                "CmdAdminRegister({})",
+                self.admins
+                    .iter()
+                    .map(|x| x.to_string())
+                    .reduce(|x1, x2| x1 + ", " + &x2)
+                    .unwrap()
+            )
+        } else {
+            write!(f, "CmdAdminRegister()")
+        }
+    }
+}
+
 impl CmdAdminRegister {
     fn is_admin(&self, user_id: UserId) -> bool {
         return self.admins.iter().position(|x| *x == user_id).is_some();
@@ -43,6 +63,29 @@ impl CmdAdminRegister {
     }
 }
 
+impl fmt::Display for CmdAcl {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self {
+            CmdAcl::AdminOnly => write!(f, "AdminOnly"),
+            CmdAcl::RoomOnly(room) => write!(f, "Room{}", room),
+            CmdAcl::List(vec) => {
+                if vec.len() != 0 {
+                    write!(
+                        f,
+                        "[{}]",
+                        vec.iter()
+                            .map(|x| x.to_string())
+                            .reduce(|x1, x2| x1 + ", " + &x2)
+                            .unwrap()
+                    )
+                } else {
+                    write!(f, "[]")
+                }
+            }
+        }
+    }
+}
+
 impl CmdAcl {
     #[allow(dead_code)]
     pub fn action_permited(
@@ -75,8 +118,31 @@ impl CmdAcl {
         };
     }
 
+    fn from_string_item(string: &str) -> CmdAcl {
+        if string == "ADMINONLY" {
+            CmdAcl::AdminOnly
+        } else if string.starts_with("ROOM!") {
+            let room = string.strip_prefix("ROOM").unwrap().to_string();
+            CmdAcl::RoomOnly(room)
+        } else {
+            error!("Unknown ACL: {}", string);
+            abort();
+        }
+    }
+
     #[allow(dead_code)]
     pub fn from_string(string: String) -> CmdAcl {
-        CmdAcl::AdminOnly
+        let acl_list = string
+            .to_uppercase()
+            .split(",")
+            .map(|x| CmdAcl::from_string_item(x.trim()))
+            .collect::<Vec<CmdAcl>>();
+
+        if acl_list.len() == 0 {
+            warn!("Default initialize CmdAcl, will only be AdminOnly");
+            CmdAcl::AdminOnly
+        } else {
+            CmdAcl::List(acl_list)
+        }
     }
 }
diff --git a/src/cmd/package.rs b/src/cmd/package.rs
index cbb5115a70d61fbe29e50b03439a1838976c83d5..98f440421bd93d9de2b488afd5e1815905489bc8 100644
--- a/src/cmd/package.rs
+++ b/src/cmd/package.rs
@@ -3,9 +3,8 @@ use crate::cmd::{
     cmd::Cmd,
 };
 use ini::Properties as IniSection;
-use log::{error, info, warn};
 use matrix_sdk::{room::Room, ruma::UserId};
-use std::convert::TryFrom;
+use std::{convert::TryFrom, fmt};
 
 pub struct CmdPackage {
     name: String,
@@ -51,3 +50,13 @@ impl CmdPackage {
         }
     }
 }
+
+impl fmt::Display for CmdPackage {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(
+            f,
+            "CmdPackage({}, acls({}), admins({}))",
+            self.name, self.acl, self.admin_register
+        )
+    }
+}