From a50cce38e99d17adf7fe819a60b6f40b5d8230de Mon Sep 17 00:00:00 2001 From: shockrah Date: Mon, 27 Sep 2021 14:46:46 -0700 Subject: [PATCH] + FromRequest on ApiKey With this we should get some easy coupling with the web server --- dblib/Cargo.toml | 1 + dblib/src/lib.rs | 10 +++---- dblib/src/request.rs | 56 +++++++++++++++++++++++++++++++++++++++ dblib/target/CACHEDIR.TAG | 3 +++ 4 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 dblib/src/request.rs create mode 100644 dblib/target/CACHEDIR.TAG diff --git a/dblib/Cargo.toml b/dblib/Cargo.toml index 5caf219..cd6d690 100644 --- a/dblib/Cargo.toml +++ b/dblib/Cargo.toml @@ -8,3 +8,4 @@ edition = "2018" [dependencies] serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0" } +rocket = "0.4" diff --git a/dblib/src/lib.rs b/dblib/src/lib.rs index 937295d..75a8b8e 100644 --- a/dblib/src/lib.rs +++ b/dblib/src/lib.rs @@ -6,6 +6,9 @@ use std::io::prelude::*; use serde::{Serialize, Deserialize}; +pub mod request; +use request::ApiKey; + fn dev_urandom() -> std::io::Result { let mut file = File::open("/dev/urandom")?; let mut buf: [u8;48] = [0;48]; @@ -21,13 +24,6 @@ fn dev_urandom() -> std::io::Result { } -#[derive(Clone, Serialize, Deserialize)] -pub struct ApiKey { - // Owner of the key - name: String, - // The secret value of the key itself - key: String, -} #[derive(Serialize, Deserialize)] pub struct DB { keys: Vec diff --git a/dblib/src/request.rs b/dblib/src/request.rs new file mode 100644 index 0000000..60f9f75 --- /dev/null +++ b/dblib/src/request.rs @@ -0,0 +1,56 @@ +use std::env; +use crate::DB; + +use rocket::request::{self, Request, FromRequest}; +use rocket::http::Status; +use rocket::Outcome; +use serde::{Serialize, Deserialize}; + +#[derive(Clone, Serialize, Deserialize)] +pub struct ApiKey { + // Owner of the key + pub name: String, + // The secret value of the key itself + pub key: String, +} + + +#[derive(Debug)] +pub enum ApiKeyError { + BadCount, + Missing, + Invalid +} + +fn verify_api_key(key: &str, name: &str) -> request::Outcome { + let storage_target = match env::var("CLIP_KEY_STORE") { + Ok(val) => val, + Err(_) => "store.json".to_string() + }; + // yolo unwrap because i cba to deal w/ edge cases and shit + match DB::get_entry(storage_target, name.to_string()).unwrap() { + Some(db_key) => { + if db_key == key { + Outcome::Success( + ApiKey { name: name.to_string(), key: key.to_string()} + ) + } else{ + Outcome::Failure((Status::Unauthorized, ApiKeyError::Invalid)) + } + }, + None => Outcome::Failure((Status::Unauthorized, ApiKeyError::Invalid)) + } +} + +impl<'a, 'r> FromRequest<'a, 'r> for ApiKey { + type Error = ApiKeyError; + + fn from_request(request: &'a Request<'r>) -> request::Outcome { + let key = request.headers().get_one("x-api-key"); + let name = request.headers().get_one("x-api-name"); + match (key, name) { + (Some(key), Some(name)) => verify_api_key(key, name), + _ => Outcome::Failure((Status::BadRequest, ApiKeyError::Missing)) + } + } +} diff --git a/dblib/target/CACHEDIR.TAG b/dblib/target/CACHEDIR.TAG new file mode 100644 index 0000000..20d7c31 --- /dev/null +++ b/dblib/target/CACHEDIR.TAG @@ -0,0 +1,3 @@ +Signature: 8a477f597d28d172789f06886806bc55 +# This file is a cache directory tag created by cargo. +# For information about cache directory tags see https://bford.info/cachedir/