Jelajahi Sumber

Refactored cli module to use RunArgs.

Kestrel 1 tahun lalu
induk
melakukan
4267d8abd2
6 mengubah file dengan 83 tambahan dan 178 penghapusan
  1. 7 7
      Cargo.lock
  2. 53 65
      src/cli.rs
  3. 6 13
      src/client_management.rs
  4. 6 22
      src/key.rs
  5. 1 23
      src/server.rs
  6. 10 48
      src/user_management.rs

+ 7 - 7
Cargo.lock

@@ -2105,7 +2105,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
 
 [[package]]
-name = "uauth2"
+name = "ucd-trie"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
+
+[[package]]
+name = "uidc"
 version = "0.1.0"
 dependencies = [
  "base64 0.13.1",
@@ -2126,12 +2132,6 @@ dependencies = [
  "toml",
 ]
 
-[[package]]
-name = "ucd-trie"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
-
 [[package]]
 name = "unicode-bidi"
 version = "0.3.13"

+ 53 - 65
src/cli.rs

@@ -43,7 +43,7 @@ enum Command {
 
 struct RunArgs {
     db: microrm::DB,
-    realm: RealmID,
+    realm_id: RealmID,
 }
 
 impl RootArgs {
@@ -52,18 +52,22 @@ impl RootArgs {
             return self.init().await;
         }
 
-        let storage = microrm::DB::new(schema::schema(), &self.db, microrm::CreateMode::MustExist).map_err(|_| UIDCError::Abort("Error accessing database"))?;
+        let db = microrm::DB::new(schema::schema(), &self.db, microrm::CreateMode::MustExist).map_err(|_| UIDCError::Abort("Error accessing database"))?;
+
+        let realm_id = db.query_interface().get().by(schema::Realm::Shortname, self.realm.as_str()).one()?.ok_or(UIDCError::Abort("no such realm"))?.id();
+
+        let ra = RunArgs { db: db, realm_id };
 
         match &self.command {
             Command::Init => unreachable!(),
-            Command::Config(v) => v.run(&self, storage).await,
-            Command::Client(v) => v.run(&self, storage).await,
-            Command::Group(v) => v.run(&self, storage).await,
-            Command::Key(v) => v.run(&self, storage).await,
-            Command::Server(v) => v.run(&self, storage).await,
-            Command::Token(v) => v.run(&self, storage).await,
-            Command::Role(v) => v.run(&self, storage).await,
-            Command::User(v) => v.run(&self, storage).await,
+            Command::Config(v) => v.run(ra).await,
+            Command::Client(v) => v.run(ra).await,
+            Command::Group(v) => v.run(ra).await,
+            Command::Key(v) => v.run(ra).await,
+            Command::Server(v) => v.run(ra).await,
+            Command::Token(v) => v.run(ra).await,
+            Command::Role(v) => v.run(ra).await,
+            Command::User(v) => v.run(ra).await,
         }
     }
 
@@ -106,13 +110,13 @@ struct KeyArgs {
 }
 
 impl KeyArgs {
-    async fn run(&self, root: &RootArgs, db: microrm::DB) -> Result<(), UIDCError> {
+    async fn run(&self, args: RunArgs) -> Result<(), UIDCError> {
         match &self.command {
             KeyCommand::Inspect => {
-                key::inspect(&db, &root.realm);
+                key::inspect(&args.db, args.realm_id);
             }
             KeyCommand::Generate => {
-                key::generate(&db, &root.realm);
+                key::generate(&args.db, args.realm_id);
             }
         }
         Ok(())
@@ -133,14 +137,14 @@ struct ClientArgs {
 }
 
 impl ClientArgs {
-    async fn run(&self, root: &RootArgs, db: microrm::DB) -> Result<(), UIDCError> {
+    async fn run(&self, args: RunArgs) -> Result<(), UIDCError> {
         match &self.command {
             ClientCommand::Create { name } => {
-                client_management::create(&db, root.realm.as_str(), name);
+                client_management::create(&args.db, args.realm_id, name);
             }
             ClientCommand::List => {}
             ClientCommand::Inspect { name } => {
-                client_management::inspect(&db, name);
+                client_management::inspect(&args.db, args.realm_id, name);
             }
         }
         Ok(())
@@ -161,10 +165,11 @@ struct ConfigArgs {
 }
 
 impl ConfigArgs {
-    async fn run(&self, root: &RootArgs, db: microrm::DB) -> Result<(), UIDCError> {
+    async fn run(&self, args: RunArgs) -> Result<(), UIDCError> {
+        let qi = args.db.query_interface();
+
         match &self.command {
             ConfigCommand::Dump => {
-                let qi = db.query_interface();
                 let config = config::Config::build_from(&qi, None);
                 println!("config: {:?}", config);
             }
@@ -172,15 +177,8 @@ impl ConfigArgs {
                 todo!()
             }
             ConfigCommand::Load { toml_path } => {
-                let config = {
-                    let qi = db.query_interface();
-                    config::Config::build_from(&qi, Some(toml_path))
-                };
-                {
-                    let qi = db.query_interface();
-                    config.save(&qi);
-                    drop(config);
-                }
+                let config = config::Config::build_from(&qi, Some(toml_path));
+                config.save(&qi);
             }
         }
         Ok(())
@@ -204,13 +202,12 @@ struct GroupArgs {
 }
 
 impl GroupArgs {
-    async fn run(&self, root: &RootArgs, db: microrm::DB) -> Result<(), UIDCError> {
-        let qi = db.query_interface();
-        let realm_id = qi.get().by(schema::Realm::Shortname, root.realm.as_str()).one().unwrap().expect("no such realm").id();
+    async fn run(&self, args: RunArgs) -> Result<(), UIDCError> {
+        let qi = args.db.query_interface();
         match &self.command {
             GroupCommand::Create { group_name } => {
                 match qi.add(&schema::Group {
-                    realm: realm_id,
+                    realm: args.realm_id,
                     shortname: group_name.clone(),
                 }) {
                     Ok(_) => {
@@ -225,8 +222,8 @@ impl GroupArgs {
                 todo!()
             },
             GroupCommand::AttachRole { group_name, role_name } => {
-                let group = qi.get().by(schema::Group::Realm, &realm_id).by(schema::Group::Shortname, group_name).one().unwrap();
-                let role = qi.get().by(schema::Role::Realm, &realm_id).by(schema::Role::Shortname, role_name).one().unwrap();
+                let group = qi.get().by(schema::Group::Realm, &args.realm_id).by(schema::Group::Shortname, group_name).one().unwrap();
+                let role = qi.get().by(schema::Role::Realm, &args.realm_id).by(schema::Role::Shortname, role_name).one().unwrap();
 
                 match (group, role) {
                     (None, _) => {
@@ -255,8 +252,8 @@ impl GroupArgs {
                 
             },
             GroupCommand::AttachUser { group_name, username } => {
-                let group = qi.get().by(schema::Group::Realm, &realm_id).by(schema::Group::Shortname, group_name).one().unwrap();
-                let user = qi.get().by(schema::User::Realm, &realm_id).by(schema::User::Username, username).one().unwrap();
+                let group = qi.get().by(schema::Group::Realm, &args.realm_id).by(schema::Group::Shortname, group_name).one().unwrap();
+                let user = qi.get().by(schema::User::Realm, &args.realm_id).by(schema::User::Username, username).one().unwrap();
 
                 match (group, user) {
                     (None, _) => {
@@ -295,9 +292,9 @@ struct ServerArgs {
 }
 
 impl ServerArgs {
-    async fn run(&self, root: &RootArgs, db: microrm::DB) -> Result<(), UIDCError> {
-        let config = config::Config::build_from(&db.query_interface(), None);
-        server::run_server(db, config, self.port.unwrap_or(2114)).await
+    async fn run(&self, args: RunArgs) -> Result<(), UIDCError> {
+        let config = config::Config::build_from(&args.db.query_interface(), None);
+        server::run_server(args.db, config, self.port.unwrap_or(2114)).await
     }
 }
 
@@ -331,35 +328,28 @@ struct TokenArgs {
 }
 
 impl TokenArgs {
-    async fn run(&self, root: &RootArgs, db: microrm::DB) -> Result<(), UIDCError> {
-        let config = config::Config::build_from(&db.query_interface(), None);
+    async fn run(&self, args: RunArgs) -> Result<(), UIDCError> {
+        let config = config::Config::build_from(&args.db.query_interface(), None);
         match &self.command {
             TokenCommand::GenerateAuth {
                 client,
                 username,
                 scopes,
             } => {
-                let qi = db.query_interface();
-                let realm_id = qi
-                    .get()
-                    .by(schema::Realm::Shortname, &root.realm)
-                    .one()
-                    .unwrap()
-                    .expect("no such realm")
-                    .id();
+                let qi = args.db.query_interface();
                 let token = token::generate_auth_token(
                     &config,
                     &qi,
-                    realm_id,
+                    args.realm_id,
                     qi.get()
-                        .by(schema::Client::Realm, &realm_id)
+                        .by(schema::Client::Realm, &args.realm_id)
                         .by(schema::Client::Shortname, client.as_str())
                         .one()
                         .unwrap()
                         .expect("no such client")
                         .id(),
                     qi.get()
-                        .by(schema::User::Realm, &realm_id)
+                        .by(schema::User::Realm, &args.realm_id)
                         .by(schema::User::Username, username.as_str())
                         .one()
                         .unwrap()
@@ -401,17 +391,16 @@ struct RoleArgs {
 }
 
 impl RoleArgs {
-    async fn run(&self, root: &RootArgs, db: microrm::DB) -> Result<(), UIDCError> {
-        let config = config::Config::build_from(&db.query_interface(), None);
+    async fn run(&self, args: RunArgs) -> Result<(), UIDCError> {
+        let qi = args.db.query_interface();
+        // let config = config::Config::build_from(&qi, None);
         match &self.command {
             RoleCommand::List => {
                 todo!()
             },
             RoleCommand::Create { name } => {
-                let qi = db.query_interface();
-                let realm = qi.get().by(schema::Realm::Shortname, &root.realm).one().unwrap().unwrap();
                 let add_result = qi.add(&schema::Role {
-                    realm: realm.id(),
+                    realm: args.realm_id,
                     shortname: name.clone()
                 });
 
@@ -425,9 +414,7 @@ impl RoleArgs {
                 }
             },
             RoleCommand::Delete { name } => {
-                let qi = db.query_interface();
-                let realm = qi.get().by(schema::Realm::Shortname, &root.realm).one().unwrap().unwrap();
-                qi.delete().by(schema::Role::Realm, &realm.id()).by(schema::Role::Shortname, name.as_str()).exec().unwrap();
+                qi.delete().by(schema::Role::Realm, &args.realm_id).by(schema::Role::Shortname, name.as_str()).exec().unwrap();
             },
         }
         Ok(())
@@ -458,19 +445,20 @@ struct UserArgs {
 }
 
 impl UserArgs {
-    async fn run(&self, root: &RootArgs, db: microrm::DB) -> Result<(), UIDCError> {
+    async fn run(&self, args: RunArgs) -> Result<(), UIDCError> {
+        let qi = args.db.query_interface();
         match &self.command {
-            UserCommand::List => user_management::list(&root.realm, db),
+            UserCommand::List => user_management::list(&qi, args.realm_id),
             UserCommand::Create { username } => {
-                user_management::create(&root.realm, db, username.as_str())
+                user_management::create(&qi, args.realm_id, username.as_str())
             }
             UserCommand::Auth { username, change_password } => user_management::change_auth(
-                &root.realm,
-                db,
+                &qi,
+                args.realm_id,
                 username.as_str(),
                 *change_password > 0,
             ),
-            UserCommand::Inspect { username } => user_management::inspect(&root.realm, db, username.as_str()),
+            UserCommand::Inspect { username } => user_management::inspect(&qi, args.realm_id, username.as_str()),
         }
     }
 }

+ 6 - 13
src/client_management.rs

@@ -1,22 +1,15 @@
-use crate::schema;
+use crate::{schema, UIDCError};
 use microrm::prelude::*;
 
-pub fn create(db: &microrm::DB, realm: &str, name: &str) {
+pub fn create(db: &microrm::DB, realm_id: schema::RealmID, name: &str) -> Result<(), UIDCError> {
     let qi = db.query_interface();
 
-    let realm = qi
-        .get()
-        .by(schema::Realm::Shortname, realm)
-        .one()
-        .expect("couldn't query db")
-        .expect("no such realm");
-
     qi.add(&schema::Client {
-        realm: realm.id(),
+        realm: realm_id,
         shortname: name.into(),
         secret: "".into(),
-    })
-    .expect("couldn't add client");
+    })?;
+    Ok(())
 }
 
-pub fn inspect(db: &microrm::DB, name: &str) {}
+pub fn inspect(db: &microrm::DB, realm_id: schema::RealmID, name: &str) {}

+ 6 - 22
src/key.rs

@@ -24,21 +24,10 @@ impl<'a> KeyStore<'a> {
         }
     }
 
-    fn realm_id(&self, realm_name: &str) -> Result<schema::RealmID, UIDCError> {
-        self.qi
-            .get()
-            .by(schema::Realm::Shortname, realm_name)
-            .one()?
-            .map(|r| r.id())
-            .ok_or(KeyError::Plain("no such realm").into())
-    }
-
-    pub fn generate_in(&self, realm_name: &str) -> Result<String, UIDCError> {
+    pub fn generate_in(&self, realm_id: schema::RealmID) -> Result<String, UIDCError> {
         let mut rng = ring::rand::SystemRandom::new();
         let sign_generated = Ed25519KeyPair::generate_pkcs8(&mut rng);
 
-        let realm_id = self.realm_id(realm_name)?;
-
         if let Err(_) = sign_generated {
             return Err(KeyError::Plain("Failed to generate key").into())
         }
@@ -65,20 +54,15 @@ impl<'a> KeyStore<'a> {
     }
 }
 
-pub fn inspect(db: &microrm::DB, realm_name: &str) -> Result<(), UIDCError> {
+pub fn inspect(db: &microrm::DB, realm_id: schema::RealmID) -> Result<(), UIDCError> {
     let qi = db.query_interface();
     let cs = KeyStore::new(db);
     println!("Keystore loaded.");
-    let realm = qi
-        .get()
-        .by(schema::Realm::Shortname, realm_name)
-        .one()?
-        .ok_or(UIDCError::Abort("no such realm"))?;
 
-    println!("Retrieving keys for {} realm...", realm_name);
+    println!("Retrieving keys realm...");
     let keys = qi
         .get()
-        .by(schema::Key::Realm, &realm.id())
+        .by(schema::Key::Realm, &realm_id)
         .all()?;
 
     for key in keys {
@@ -87,10 +71,10 @@ pub fn inspect(db: &microrm::DB, realm_name: &str) -> Result<(), UIDCError> {
     Ok(())
 }
 
-pub fn generate(db: &microrm::DB, realm_name: &str) -> Result<(), UIDCError> {
+pub fn generate(db: &microrm::DB, realm_id: schema::RealmID) -> Result<(), UIDCError> {
     let qi = db.query_interface();
     let cs = KeyStore::new(db);
-    match cs.generate_in(realm_name) {
+    match cs.generate_in(realm_id) {
         Ok(_) => (),
         Err(e) => {
             println!("Failed to generate key: {}", e);

+ 1 - 23
src/server.rs

@@ -1,5 +1,4 @@
-use crate::{config, schema, UIDCError};
-use microrm::prelude::*;
+use crate::{config, UIDCError};
 
 mod oidc;
 mod session;
@@ -15,21 +14,6 @@ struct ServerStateWrapper {
     core: &'static ServerState,
 }
 
-fn is_auth_valid<T>(core: &'static ServerState, of: &tide::Request<T>) -> Option<bool> {
-    let cookie = of.cookie("vogt_session")?;
-    let session_id = cookie.value();
-
-    Some(
-        core.pool
-            .query_interface()
-            .get()
-            .by(schema::Session::Key, &session_id)
-            .one()
-            .expect("couldn't query db")
-            .is_some(),
-    )
-}
-
 async fn index(req: tide::Request<ServerStateWrapper>) -> tide::Result<tide::Response> {
     let shelper = session::SessionHelper::new(&req);
 
@@ -67,12 +51,6 @@ pub async fn run_server(db: microrm::DB, config: config::Config, port: u16) -> R
         .templates
         .register_templates_directory(".tmpl", "tmpl/")
         .expect("Couldn't open templates directory?");
-    println!("registered templates:");
-    for tmpl in core_state.templates.get_templates() {
-        println!("- {}", tmpl.0);
-    }
-
-    core_state.templates.render("id_v1_login", &()).unwrap();
 
     let state = ServerStateWrapper { core: core_state };
 

+ 10 - 48
src/user_management.rs

@@ -1,17 +1,7 @@
 use crate::{schema, user, UIDCError};
 use microrm::prelude::*;
 
-pub fn list(realm: &str, db: microrm::DB) -> Result<(), UIDCError> {
-    // get realm ID
-    let qi = db.query_interface();
-
-    let realm_id = qi
-        .get()
-        .by(schema::Realm::Shortname, realm)
-        .one()?
-        .ok_or(UIDCError::Abort("no such realm"))?
-        .id();
-
+pub fn list(qi: &microrm::QueryInterface, realm_id: schema::RealmID) -> Result<(), UIDCError> {
     let users = qi
         .get()
         .by(schema::User::Realm, &realm_id)
@@ -33,17 +23,7 @@ pub fn list(realm: &str, db: microrm::DB) -> Result<(), UIDCError> {
     Ok(())
 }
 
-pub fn create(realm: &str, db: microrm::DB, username: &str) -> Result<(), UIDCError> {
-    // get realm ID
-    let qi = db.query_interface();
-
-    let realm_id = qi
-        .get()
-        .by(schema::Realm::Shortname, realm)
-        .one()?
-        .expect("No such realm")
-        .id();
-
+pub fn create(qi: &microrm::QueryInterface, realm_id: schema::RealmID, username: &str) -> Result<(), UIDCError> {
     // check that the user doesn't exist already
     let existing_user = qi
         .get()
@@ -53,9 +33,8 @@ pub fn create(realm: &str, db: microrm::DB, username: &str) -> Result<(), UIDCEr
 
     if existing_user.is_some() {
         log::error!(
-            "Can't create user {} in {} realm, as a user with that username already exists",
+            "Can't create user {} in realm, as a user with that username already exists",
             username,
-            realm
         );
         return Ok(());
     }
@@ -67,30 +46,16 @@ pub fn create(realm: &str, db: microrm::DB, username: &str) -> Result<(), UIDCEr
     Ok(())
 }
 
-pub fn change_auth(realm: &str, db: microrm::DB, username: &str, change_password: bool) -> Result<(), UIDCError> {
-    // get realm ID
-    let qi = db.query_interface();
-
-    let realm_id = qi
-        .get()
-        .by(schema::Realm::Shortname, realm)
-        .one()
-        .expect("couldn't query db")
-        .expect("No such realm")
-        .id();
+pub fn change_auth(qi: &microrm::QueryInterface, realm_id: schema::RealmID, username: &str, change_password: bool) -> Result<(), UIDCError> {
     // check that the user exists
     let existing_user = qi
         .get()
         .by(schema::User::Realm, &realm_id)
         .by(schema::User::Username, &username)
-        .one()
-        .expect("couldn't query db");
-    if existing_user.is_none() {
-        log::error!("User {} does not exist in the {} realm!", username, realm);
-        return Ok(());
-    }
+        .one()?
+        .ok_or(UIDCError::Abort("no such user"))?;
 
-    let user = user::User::from_model(existing_user.unwrap());
+    let user = user::User::from_model(existing_user);
 
     if change_password {
         let raw_pass = rpassword::prompt_password("Enter new user password: ").unwrap();
@@ -99,11 +64,8 @@ pub fn change_auth(realm: &str, db: microrm::DB, username: &str, change_password
     Ok(())
 }
 
-pub fn inspect(realm: &str, db: microrm::DB, username: &str) -> Result<(), UIDCError> {
-    let qi = db.query_interface();
-
-    let realm = qi.get().by(schema::Realm::Shortname, realm).one()?.expect("no such realm");
-    let user = qi.get().by(schema::User::Realm, &realm.id()).by(schema::User::Username, username).one()?;
+pub fn inspect(qi: &microrm::QueryInterface, realm_id: schema::RealmID, username: &str) -> Result<(), UIDCError> {
+    let user = qi.get().by(schema::User::Realm, &realm_id).by(schema::User::Username, username).one()?;
 
     if let Some(user) = user {
         println!("User found: {}", username);
@@ -114,7 +76,7 @@ pub fn inspect(realm: &str, db: microrm::DB, username: &str) -> Result<(), UIDCE
         }
     }
     else {
-        println!("No such user {} in {} realm", username, realm.shortname);
+        println!("No such user {} in realm", username);
     }
 
     Ok(())