mirror of
https://gitlab.com/fabinfra/fabaccess/bffh.git
synced 2024-11-23 23:27:57 +01:00
start on some SQLite code
This commit is contained in:
parent
a9143b0cdd
commit
a4f6c77b26
46
Cargo.lock
generated
46
Cargo.lock
generated
@ -1085,6 +1085,7 @@ dependencies = [
|
|||||||
"rkyv_typename",
|
"rkyv_typename",
|
||||||
"rsasl",
|
"rsasl",
|
||||||
"rumqttc",
|
"rumqttc",
|
||||||
|
"rusqlite",
|
||||||
"rust-argon2",
|
"rust-argon2",
|
||||||
"rustls",
|
"rustls",
|
||||||
"rustls-native-certs",
|
"rustls-native-certs",
|
||||||
@ -1215,6 +1216,18 @@ dependencies = [
|
|||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fallible-iterator"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fallible-streaming-iterator"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fastrand"
|
name = "fastrand"
|
||||||
version = "1.8.0"
|
version = "1.8.0"
|
||||||
@ -1514,6 +1527,15 @@ dependencies = [
|
|||||||
"ahash",
|
"ahash",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashlink"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa"
|
||||||
|
dependencies = [
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hdrhistogram"
|
name = "hdrhistogram"
|
||||||
version = "7.5.2"
|
version = "7.5.2"
|
||||||
@ -1799,6 +1821,16 @@ dependencies = [
|
|||||||
"pkg-config",
|
"pkg-config",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libsqlite3-sys"
|
||||||
|
version = "0.25.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "29f835d03d717946d28b1d1ed632eb6f0e24a299388ee623d0c23118d3e8a7fa"
|
||||||
|
dependencies = [
|
||||||
|
"pkg-config",
|
||||||
|
"vcpkg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libz-sys"
|
name = "libz-sys"
|
||||||
version = "1.1.8"
|
version = "1.1.8"
|
||||||
@ -2633,6 +2665,20 @@ dependencies = [
|
|||||||
"webpki",
|
"webpki",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rusqlite"
|
||||||
|
version = "0.28.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"fallible-iterator",
|
||||||
|
"fallible-streaming-iterator",
|
||||||
|
"hashlink",
|
||||||
|
"libsqlite3-sys",
|
||||||
|
"smallvec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-argon2"
|
name = "rust-argon2"
|
||||||
version = "0.8.3"
|
version = "0.8.3"
|
||||||
|
@ -112,6 +112,8 @@ rustls-native-certs = "0.6.1"
|
|||||||
|
|
||||||
shadow-rs = "0.11"
|
shadow-rs = "0.11"
|
||||||
|
|
||||||
|
rusqlite = "0.28"
|
||||||
|
|
||||||
[dependencies.rsasl]
|
[dependencies.rsasl]
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
default_features = false
|
default_features = false
|
||||||
|
@ -15,6 +15,7 @@ use std::sync::Arc;
|
|||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
pub mod db;
|
pub mod db;
|
||||||
|
mod sqlite;
|
||||||
|
|
||||||
use crate::users::db::UserData;
|
use crate::users::db::UserData;
|
||||||
use crate::UserDB;
|
use crate::UserDB;
|
||||||
@ -211,3 +212,12 @@ impl Users {
|
|||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait UserDb {
|
||||||
|
type User;
|
||||||
|
type Error: std::error::Error + miette::Diagnostic;
|
||||||
|
|
||||||
|
fn lookup(&self, userid: &str) -> Result<Option<Self::User>, Self::Error>;
|
||||||
|
|
||||||
|
fn get_roles(&self, user: &Self::User) -> Result<Vec<String>, Self::Error>;
|
||||||
|
}
|
93
bffhd/users/sqlite.rs
Normal file
93
bffhd/users/sqlite.rs
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
use std::path::Path;
|
||||||
|
use rusqlite::{Connection, OptionalExtension};
|
||||||
|
use crate::users::db::{User, UserData};
|
||||||
|
|
||||||
|
pub struct UserSqliteDB {
|
||||||
|
conn: Connection,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UserSqliteDB {
|
||||||
|
pub fn open(path: impl AsRef<Path>) -> rusqlite::Result<Self> {
|
||||||
|
let conn = Connection::open(path)?;
|
||||||
|
|
||||||
|
conn.execute("CREATE TABLE IF NOT EXISTS users (\
|
||||||
|
id INTEGER PRIMARY KEY,\
|
||||||
|
name TEXT NOT NULL,\
|
||||||
|
password TEXT\
|
||||||
|
)", ())?;
|
||||||
|
conn.execute("CREATE TABLE IF NOT EXISTS user_kv (\
|
||||||
|
id INTEGER PRIMARY KEY,\
|
||||||
|
user INTEGER,\
|
||||||
|
key TEXT NOT NULL,\
|
||||||
|
value TEXT NOT NULL,\
|
||||||
|
FOREIGN KEY(user) REFERENCES users(id)\
|
||||||
|
)", ())?;
|
||||||
|
conn.execute("CREATE TABLE IF NOT EXISTS user_roles (\
|
||||||
|
id INTEGER PRIMARY KEY,\
|
||||||
|
user INTEGER,\
|
||||||
|
role TEXT NOT NULL,\
|
||||||
|
FOREIGN KEY(user) REFERENCES users(id)\
|
||||||
|
)", ())?;
|
||||||
|
|
||||||
|
Ok(Self { conn })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, uid: &str) -> rusqlite::Result<Option<User>> {
|
||||||
|
let sqlite_user = self.conn.query_row("SELECT id, name, password FROM users WHERE name = ?1", [uid], |row| {
|
||||||
|
Ok(SqliteUser {
|
||||||
|
id: row.get(0)?,
|
||||||
|
name: row.get(1)?,
|
||||||
|
password: row.get(2)?,
|
||||||
|
})
|
||||||
|
}).optional()?;
|
||||||
|
if let Some(SqliteUser { name, password, .. }) = sqlite_user {
|
||||||
|
let mut kv_stmt = self.conn.prepare("SELECT key, value FROM user_kv WHERE user_id = :id")?;
|
||||||
|
let kv: HashMap<String, String> = kv_stmt
|
||||||
|
.query_map(&[(":id", &name)], |row| Ok((row.get(0)?, row.get(1)?)))?
|
||||||
|
.filter_map(|fields| fields.ok())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut roles_stmt = self.conn.prepare("SELECT role FROM user_roles WHERE user_id = :id")?;
|
||||||
|
let roles: Vec<String> = roles_stmt
|
||||||
|
.query_map(&[(":id", &name)], |row| row.get(0))?
|
||||||
|
.filter_map(|fields| fields.ok())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let passwd = if password.is_empty() { None } else { Some(password) };
|
||||||
|
Ok(Some(User {
|
||||||
|
id: name,
|
||||||
|
userdata: UserData {
|
||||||
|
roles,
|
||||||
|
passwd,
|
||||||
|
kv,
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn put(&self, uid: &str, user: &SqliteUser) -> rusqlite::Result<()> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct SqliteUser {
|
||||||
|
id: i32,
|
||||||
|
name: String,
|
||||||
|
password: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SqliteUserKv {
|
||||||
|
id: i32,
|
||||||
|
user_id: i32,
|
||||||
|
key: String,
|
||||||
|
value: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SqliteRoles {
|
||||||
|
id: i32,
|
||||||
|
user_id: i32,
|
||||||
|
role: String,
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user