Database setup stage 1 done
This commit is contained in:
parent
194b564e43
commit
679cc2ce1a
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
||||
/target
|
||||
*.db
|
||||
126
Cargo.lock
generated
126
Cargo.lock
generated
@ -2,6 +2,18 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "argon2"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
"blake2",
|
||||
"cpufeatures",
|
||||
"password-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atomic-waker"
|
||||
version = "1.1.2"
|
||||
@ -60,12 +72,36 @@ dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64ct"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
|
||||
|
||||
[[package]]
|
||||
name = "blake2"
|
||||
version = "0.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
|
||||
dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.11.0"
|
||||
@ -78,6 +114,36 @@ version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fallible-iterator"
|
||||
version = "0.3.0"
|
||||
@ -144,6 +210,27 @@ dependencies = [
|
||||
"pin-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.5"
|
||||
@ -249,6 +336,7 @@ dependencies = [
|
||||
name = "identity"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"argon2",
|
||||
"axum",
|
||||
"log",
|
||||
"rusqlite",
|
||||
@ -369,6 +457,17 @@ dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "password-hash"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
"rand_core",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.2"
|
||||
@ -411,6 +510,15 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.18"
|
||||
@ -553,6 +661,12 @@ dependencies = [
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.110"
|
||||
@ -707,6 +821,12 @@ dependencies = [
|
||||
"tracing-log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.22"
|
||||
@ -725,6 +845,12 @@ version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.1+wasi-snapshot-preview1"
|
||||
|
||||
BIN
identity.db
BIN
identity.db
Binary file not shown.
@ -12,3 +12,4 @@ tracing = "0.1.41"
|
||||
tracing-subscriber = "0.3.19"
|
||||
sigma = { path = "../sigma" }
|
||||
rusqlite = "0.37.0"
|
||||
argon2 = { version = "0.5.3", features = ["std"] }
|
||||
@ -1,25 +1,42 @@
|
||||
use axum::{Json, Router, http::StatusCode, routing::get};
|
||||
#[allow(unused)]
|
||||
use log::{info, debug, warn, error, trace};
|
||||
use rusqlite::Connection;
|
||||
use rusqlite::{Connection, params};
|
||||
use sigma::repsonse::SigmaInformation;
|
||||
use tracing::instrument;
|
||||
|
||||
mod user;
|
||||
|
||||
const NAME: &str = "TinyIdentity";
|
||||
const VERSION: &str = "0.0.0.1";
|
||||
|
||||
const DB_PATH: &str = "identity.db";
|
||||
const DB_CREATE_USER_TABLE: &str =
|
||||
"CREATE TABLE IF NOT EXISTS users (
|
||||
const DB_CREATE_USER_TABLE: &str = "
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
pass TEXT NOT NULL
|
||||
)";
|
||||
const DB_CREATE_META_TABLE: &str =
|
||||
"CREATE TABLE IF NOT EXISTS meta (
|
||||
key VARCHAR(16) PRIMARY KEY,
|
||||
pass BLOB NOT NULL
|
||||
);
|
||||
";
|
||||
const DB_CREATE_SETTINGS_TABLE: &str = "
|
||||
CREATE TABLE IF NOT EXISTS settings (
|
||||
key VARCHAR(16) PRIMARY KEY NOT NULL,
|
||||
value TEXT NOT NULL
|
||||
)";
|
||||
);
|
||||
";
|
||||
const DB_INSERT_SETUP_STAGE_SETTING: &str = "
|
||||
INSERT INTO settings (key, value) VALUES ('setupStage', 0)
|
||||
";
|
||||
const UPDATE_SETUP_STATUS: &str = "
|
||||
UPDATE settings
|
||||
SET value = ?1
|
||||
WHERE key = 'setupStage';
|
||||
";
|
||||
const SELECT_SETUP_STATUS: &str = "
|
||||
SELECT value
|
||||
FROM settings
|
||||
WHERE key = 'setupStage'
|
||||
";
|
||||
|
||||
|
||||
pub fn router() -> Router {
|
||||
@ -38,19 +55,49 @@ async fn setup() -> Result<StatusCode, StatusCode> {
|
||||
error!("{:?}", e);
|
||||
return Err(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
}
|
||||
let connection = connection.expect("Connection cannot be an error here.");
|
||||
let connection = connection.expect("Connection always exists here.");
|
||||
info!("Connected to identity database");
|
||||
|
||||
if let Err(e) = connection.execute(DB_CREATE_USER_TABLE, [],) {
|
||||
error!("{:?}", e);
|
||||
return Err(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
}
|
||||
info!("Created user table");
|
||||
|
||||
if let Err(e) = connection.execute(DB_CREATE_META_TABLE, [],) {
|
||||
if let Err(e) = connection.execute(DB_CREATE_SETTINGS_TABLE, [],) {
|
||||
error!("{:?}", e);
|
||||
return Err(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
}
|
||||
info!("Created settings table");
|
||||
|
||||
Ok(StatusCode::OK)
|
||||
let stage = match SetupStage::get(&connection) {
|
||||
Ok(stage) => stage,
|
||||
Err(_) => {
|
||||
error!("Coud, not retrieve setup status");
|
||||
return Err(StatusCode::INTERNAL_SERVER_ERROR);
|
||||
},
|
||||
};
|
||||
info!("Retreived setup status setting: {stage:?}");
|
||||
|
||||
if stage != SetupStage::New {
|
||||
error!("{NAME} is already set up");
|
||||
return Err(StatusCode::CONFLICT)
|
||||
}
|
||||
info!("Proceeding with setup steps because setup status is {stage:?}");
|
||||
|
||||
if let Err(e) = connection.execute(DB_INSERT_SETUP_STAGE_SETTING, [],) {
|
||||
error!("{:?}", e);
|
||||
return Err(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
}
|
||||
info!("Updated setup stage setting");
|
||||
|
||||
if let Err(_) = user::create(&connection, "admin", "changeme") {
|
||||
Err(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
} else if let Err(_) = stage.next().set(&connection) {
|
||||
Err(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
} else {
|
||||
Ok(StatusCode::OK)
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
@ -62,3 +109,60 @@ async fn dummy() -> Json<()> {
|
||||
async fn information() -> Json<SigmaInformation> {
|
||||
Json(SigmaInformation::new(NAME, VERSION))
|
||||
}
|
||||
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum SetupStage {
|
||||
New,
|
||||
Finished
|
||||
}
|
||||
impl SetupStage {
|
||||
fn get(connection: &Connection) -> Result<Self, ()> {
|
||||
let result = connection.query_one(SELECT_SETUP_STATUS, [], |row| {
|
||||
row.get::<&str, String>("value")
|
||||
});
|
||||
match result {
|
||||
Ok(value) => SetupStage::try_from(value),
|
||||
Err(rusqlite::Error::QueryReturnedNoRows) => return Ok(SetupStage::New),
|
||||
Err(e) => {
|
||||
error!("{e:}");
|
||||
return Err(())
|
||||
},
|
||||
}
|
||||
}
|
||||
fn set(&self, connection: &Connection) -> Result<(), ()>{
|
||||
let value = format!("{}", *self as u32);
|
||||
if let Err(e) = connection.execute(UPDATE_SETUP_STATUS, params![value]) {
|
||||
error!("{e:?}");
|
||||
Err(())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn next(&self) -> Self {
|
||||
match &self {
|
||||
Self::New => Self::Finished,
|
||||
Self::Finished => Self::Finished,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl TryFrom<String> for SetupStage {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: String) -> Result<Self, ()> {
|
||||
if let Ok(value) = value.parse::<u32>() {
|
||||
match value {
|
||||
0 => Ok(Self::New),
|
||||
1 => Ok(Self::Finished),
|
||||
_ => {
|
||||
error!("Unknown setup stage value {value}");
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error!("Could not parse server status '{value}' to u32 (SetupStage)");
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
47
identity/src/user.rs
Normal file
47
identity/src/user.rs
Normal file
@ -0,0 +1,47 @@
|
||||
use argon2::password_hash::SaltString;
|
||||
use argon2::PasswordHasher;
|
||||
use argon2::password_hash::rand_core::OsRng;
|
||||
use log::{error, info};
|
||||
use rusqlite::{Connection, params};
|
||||
|
||||
const CREATE_USER: &str = "
|
||||
INSERT INTO users (name, pass) VALUES (?1, ?2)
|
||||
";
|
||||
|
||||
const SELECT_USER: &str ="
|
||||
SELECT * FROM users WHERE name = ?1
|
||||
";
|
||||
|
||||
struct User {
|
||||
id: u64,
|
||||
name: String,
|
||||
pass: String
|
||||
}
|
||||
|
||||
pub fn create(connection: &Connection, name: &str, pass: &str) -> Result<(), ()> {
|
||||
let argon2 = argon2::Argon2::default();
|
||||
let salt = SaltString::generate(&mut OsRng);
|
||||
|
||||
let pass = match argon2.hash_password(pass.as_bytes(), &salt) {
|
||||
Ok(pass) => pass.to_string(),
|
||||
Err(e) => {
|
||||
error!("{e:?}");
|
||||
return Err(());
|
||||
},
|
||||
};
|
||||
info!("Hashed password for user {}", name);
|
||||
|
||||
match connection.execute(CREATE_USER, params![name, pass]) {
|
||||
Ok(_) => return Ok(()),
|
||||
Err(e) => {
|
||||
error!("{e:?}");
|
||||
return Err(())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn verify(connection: &Connection, name: &str, pass: &str) {
|
||||
// match connection.query_one(SELECT_USER, params![name], |row| {})) {
|
||||
|
||||
// }
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user