aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCara Salter <cara@devcara.com>2022-06-28 07:07:34 -0400
committerCara Salter <cara@devcara.com>2022-06-28 07:07:34 -0400
commit8de1eae2b49d763dcac55b8a2a84673475a35e63 (patch)
tree3b2d385b590c4211cf311042122563b89dcc6e51
parentf516a9616b7160be149ef4ba8726557e019bf621 (diff)
downloadsolard-8de1eae2b49d763dcac55b8a2a84673475a35e63.tar.gz
solard-8de1eae2b49d763dcac55b8a2a84673475a35e63.zip
auth: Scaffold auth/begin [WIP]
-rw-r--r--.envrc1
-rw-r--r--Cargo.lock269
-rw-r--r--Cargo.toml10
-rw-r--r--flake.nix5
-rw-r--r--src/errors.rs12
-rw-r--r--src/handlers/auth.rs34
-rw-r--r--src/handlers/mod.rs1
-rw-r--r--src/main.rs21
8 files changed, 345 insertions, 8 deletions
diff --git a/.envrc b/.envrc
deleted file mode 100644
index 3550a30..0000000
--- a/.envrc
+++ /dev/null
@@ -1 +0,0 @@
-use flake
diff --git a/Cargo.lock b/Cargo.lock
index a23cdeb..7242c13 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -18,6 +18,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
+name = "aead"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
name = "ansi_term"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -128,6 +137,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
+name = "blake2"
+version = "0.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a4e37d16930f5459780f5621038b6382b9bb37c19016f39fb6b5808d831f174"
+dependencies = [
+ "crypto-mac",
+ "digest",
+ "opaque-debug",
+]
+
+[[package]]
name = "bumpalo"
version = "3.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -158,6 +178,54 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
+name = "chacha20"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f08493fa7707effc63254c66c6ea908675912493cd67952eda23c09fae2610b1"
+dependencies = [
+ "cfg-if",
+ "cipher",
+ "cpufeatures",
+ "zeroize",
+]
+
+[[package]]
+name = "chacha20poly1305"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6547abe025f4027edacd9edaa357aded014eecec42a5070d9b885c3c334aba2"
+dependencies = [
+ "aead",
+ "chacha20",
+ "cipher",
+ "poly1305",
+ "zeroize",
+]
+
+[[package]]
+name = "chrono"
+version = "0.4.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
+dependencies = [
+ "libc",
+ "num-integer",
+ "num-traits",
+ "serde",
+ "time",
+ "winapi",
+]
+
+[[package]]
+name = "cipher"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
name = "color-eyre"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -201,6 +269,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
[[package]]
+name = "cpufeatures"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "crypto-mac"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab"
+dependencies = [
+ "generic-array",
+ "subtle",
+]
+
+[[package]]
+name = "digest"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -226,6 +322,28 @@ dependencies = [
]
[[package]]
+name = "failure"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86"
+dependencies = [
+ "backtrace",
+ "failure_derive",
+]
+
+[[package]]
+name = "failure_derive"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
+[[package]]
name = "fastrand"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -314,6 +432,16 @@ dependencies = [
]
[[package]]
+name = "generic-array"
+version = "0.14.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
name = "getrandom"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -697,6 +825,25 @@ dependencies = [
]
[[package]]
+name = "num-integer"
+version = "0.1.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
+dependencies = [
+ "autocfg",
+ "num-traits",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
name = "num_cpus"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -722,6 +869,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
[[package]]
+name = "opaque-debug"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
+
+[[package]]
name = "openssl"
version = "0.10.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -796,6 +949,23 @@ dependencies = [
]
[[package]]
+name = "paseto"
+version = "2.0.2+1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04a17c4dbcb8f4a6b17b390aa66ac8e335349f829488950e95617f4b28d72b1f"
+dependencies = [
+ "base64",
+ "blake2",
+ "chacha20poly1305",
+ "chrono",
+ "failure",
+ "failure_derive",
+ "openssl",
+ "ring",
+ "serde_json",
+]
+
+[[package]]
name = "percent-encoding"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -840,6 +1010,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
[[package]]
+name = "poly1305"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede"
+dependencies = [
+ "cpufeatures",
+ "opaque-debug",
+ "universal-hash",
+]
+
+[[package]]
name = "ppv-lite86"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -972,6 +1153,21 @@ dependencies = [
]
[[package]]
+name = "ring"
+version = "0.16.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
+dependencies = [
+ "cc",
+ "libc",
+ "once_cell",
+ "spin",
+ "untrusted",
+ "web-sys",
+ "winapi",
+]
+
+[[package]]
name = "ructe"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1128,6 +1324,8 @@ dependencies = [
"eyre",
"hyper",
"kankyo",
+ "paseto",
+ "rand",
"reqwest",
"serde",
"solarlib",
@@ -1137,12 +1335,13 @@ dependencies = [
"tower-http 0.3.0",
"tracing",
"tracing-subscriber",
+ "uuid",
]
[[package]]
name = "solarlib"
version = "1.5.0"
-source = "git+https://git.carathe.dev/solard/solarlib?branch=master#373f5f25375d6eb563e5c75f432d78ee7d37672c"
+source = "git+https://git.carathe.dev/solard/solarlib?branch=master#945991ae5227bf3de7d715e4d256e11f1753e4fa"
dependencies = [
"mac_address",
"rand",
@@ -1155,6 +1354,18 @@ dependencies = [
]
[[package]]
+name = "spin"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
+
+[[package]]
+name = "subtle"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
+
+[[package]]
name = "syn"
version = "1.0.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1172,6 +1383,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8"
[[package]]
+name = "synstructure"
+version = "0.12.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "unicode-xid",
+]
+
+[[package]]
name = "tempfile"
version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1215,6 +1438,16 @@ dependencies = [
]
[[package]]
+name = "time"
+version = "0.1.43"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
name = "tinyvec"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1431,6 +1664,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
[[package]]
+name = "typenum"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
+
+[[package]]
name = "unicode-bidi"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1452,6 +1691,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
+name = "universal-hash"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05"
+dependencies = [
+ "generic-array",
+ "subtle",
+]
+
+[[package]]
+name = "untrusted"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
+
+[[package]]
name = "url"
version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1486,6 +1741,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
name = "virt"
version = "0.2.11"
source = "git+https://gitlab.com/libvirt/libvirt-rust.git?rev=10456b6e59ec73e8ef418cf0a29a9bf33be8ded6#10456b6e59ec73e8ef418cf0a29a9bf33be8ded6"
@@ -1707,3 +1968,9 @@ checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
dependencies = [
"winapi",
]
+
+[[package]]
+name = "zeroize"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd"
diff --git a/Cargo.toml b/Cargo.toml
index c1a8255..0b2ead9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -21,6 +21,10 @@ kankyo = "0.3"
axum-macros = "0.2"
+paseto = "2"
+
+rand = "0.8"
+
[dependencies.solarlib]
git = "https://git.carathe.dev/solard/solarlib"
branch = "master"
@@ -52,3 +56,9 @@ features = [
"json",
"blocking"
]
+
+[dependencies.uuid]
+version = "1"
+features = [
+ "v4"
+]
diff --git a/flake.nix b/flake.nix
index e2a9595..e7abd18 100644
--- a/flake.nix
+++ b/flake.nix
@@ -90,11 +90,6 @@
};
};
-
- # `nix develop`
- devShell = pkgs.mkShell {
- nativeBuildInputs = with pkgs; [ rustc cargo ] ++ deps;
- };
}
);
}
diff --git a/src/errors.rs b/src/errors.rs
index e0a6df9..cbec046 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -20,7 +20,16 @@ pub enum ServiceError {
Reqwest(#[from] reqwest::Error),
#[error("Command error: {0}")]
- Command(#[from] std::io::Error)
+ Command(#[from] std::io::Error),
+
+ #[error("Not authorized")]
+ NotAuthorized,
+
+ #[error("Generic: {0}")]
+ Generic(String),
+
+ #[error("Paseto: {0}")]
+ Paseto(#[from] pasetors::errors::Error),
}
pub type StringResult<T = &'static str> = std::result::Result<T, ServiceError>;
@@ -35,6 +44,7 @@ impl IntoResponse for ServiceError {
let status = match self {
ServiceError::NotFound => StatusCode::NOT_FOUND,
+ ServiceError::NotAuthorized => StatusCode::UNAUTHORIZED,
_ => StatusCode::INTERNAL_SERVER_ERROR,
};
Response::builder()
diff --git a/src/handlers/auth.rs b/src/handlers/auth.rs
new file mode 100644
index 0000000..a9ac394
--- /dev/null
+++ b/src/handlers/auth.rs
@@ -0,0 +1,34 @@
+use std::collections::HashMap;
+
+use axum::{extract::Query, Extension};
+use axum_macros::debug_handler;
+use pasetors::{claims::Claims, keys::{AsymmetricKeyPair, Generate}, version4::V4};
+use uuid::Uuid;
+
+use crate::{errors::{NoneResult, ServiceError}, State};
+
+
+/**
+ * Takes in a request to create a new token with a secret key that gets printed
+ * to stdout and, if it matches, returns a valid PASETO token that can be used
+ * for future authentication
+ */
+#[debug_handler]
+pub async fn begin(Query(params): Query<HashMap<String, String>>, Extension(state): Extension<State>) -> NoneResult {
+ if let Some(k) = params.get("key") {
+ if k == &state.gen_key {
+ let mut claims = Claims::new()?;
+ claims.non_expiring();
+ claims.audience("solard")?;
+ claims.add_additional("uuid", Uuid::new_v4().to_string())?;
+
+ let kp = AsymmetricKeyPair::<V4>::generate()?;
+ } else {
+ return Err(ServiceError::NotAuthorized);
+ }
+ } else {
+ return Err(ServiceError::Generic("No key supplied".to_string()));
+ }
+
+ Ok(())
+}
diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs
index 591f76e..8f8224e 100644
--- a/src/handlers/mod.rs
+++ b/src/handlers/mod.rs
@@ -1 +1,2 @@
pub mod planets;
+pub mod auth;
diff --git a/src/main.rs b/src/main.rs
index 4dc78a6..3f889cd 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -7,6 +7,7 @@ use axum::{
Json, Router, Extension
};
+use rand::{thread_rng, Rng, distributions::Alphanumeric};
use serde::{Deserialize, Serialize};
use solarlib::star::Star;
use std::{net::SocketAddr, time::Duration, str::FromStr, sync::Arc};
@@ -20,8 +21,11 @@ mod errors;
mod handlers;
+#[derive(Clone)]
pub struct State {
pub hw_url: String,
+ pub secret_key: String,
+ pub gen_key: String,
}
#[tokio::main]
@@ -36,10 +40,25 @@ async fn main() {
.with(tracing_subscriber::fmt::layer())
.init();
+ let rand_key: String = thread_rng()
+ .sample_iter(&Alphanumeric)
+ .take(30)
+ .map(char::from)
+ .collect();
+
let shared_state = Arc::new(State {
hw_url: std::env::var("HOMEWORLD_URL").expect("No Homeworld URL set"),
+ secret_key: std::env::var("SECRET_KEY").unwrap_or("bad-key".to_string()),
+ gen_key: rand_key,
});
+ if shared_state.secret_key == "bad-key" {
+ tracing::warn!("No secret key set! This is a bad idea.");
+ tracing::warn!("Using default of `bad-key`");
+ }
+
+ tracing::info!("Random Key: {}", shared_state.gen_key);
+
let app = Router::new()
.route("/health", get(health_check))
.route("/planets/list", get(handlers::planets::list))
@@ -52,6 +71,8 @@ async fn main() {
.route("/planets/:uuid/reboot", post(handlers::planets::reboot))
.route("/planets/:uuid/reboot/hard", post(handlers::planets::force_reboot))
.route("/planets/:uuid/destroy", post(handlers::planets::no_planet))
+ // Authentication
+ .route("/auth/begin", post(handlers::auth::begin))
.layer( ServiceBuilder::new()
.layer(HandleErrorLayer::new(|error: BoxError| async move {
if error.is::<tower::timeout::error::Elapsed>() {