aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/errors.rs21
-rw-r--r--src/handlers/auth.rs55
2 files changed, 64 insertions, 12 deletions
diff --git a/src/errors.rs b/src/errors.rs
index cbec046..f6e00e2 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -1,3 +1,5 @@
+use hex::FromHexError;
+use ring::error::KeyRejected;
use thiserror::Error;
use axum::response::{Response, IntoResponse};
@@ -5,6 +7,8 @@ use axum::http::StatusCode;
use axum::body;
use axum::Json;
+use ring::error::Unspecified as RingUnspecified;
+
#[derive(Debug, Error)]
pub enum ServiceError {
#[error("Solarlib error: {0}")]
@@ -28,12 +32,25 @@ pub enum ServiceError {
#[error("Generic: {0}")]
Generic(String),
- #[error("Paseto: {0}")]
- Paseto(#[from] pasetors::errors::Error),
+ #[error("Invalid PASETO Key: {0}")]
+ PasetoInvalid(#[from] KeyRejected),
+}
+
+impl From<FromHexError> for ServiceError {
+ fn from(_: FromHexError) -> Self {
+ ServiceError::Generic(String::from("Could not convert from hex"))
+ }
}
+impl From<RingUnspecified> for ServiceError {
+ fn from(_: RingUnspecified) -> Self {
+ ServiceError::Generic("Unspecified RNG error".to_string())
+ }
+}
pub type StringResult<T = &'static str> = std::result::Result<T, ServiceError>;
+pub type TokenResult<T = String> = std::result::Result<T, ServiceError>;
+
pub type JsonResult<T> = std::result::Result<T, ServiceError>;
pub type NoneResult = std::result::Result<(), ServiceError>;
diff --git a/src/handlers/auth.rs b/src/handlers/auth.rs
index a9ac394..8d65b05 100644
--- a/src/handlers/auth.rs
+++ b/src/handlers/auth.rs
@@ -1,11 +1,14 @@
-use std::collections::HashMap;
+use std::{collections::HashMap, fs::{self, File}};
use axum::{extract::Query, Extension};
use axum_macros::debug_handler;
-use pasetors::{claims::Claims, keys::{AsymmetricKeyPair, Generate}, version4::V4};
+use chrono::{Utc, TimeZone, Datelike};
+use ring::{rand::SystemRandom, signature::Ed25519KeyPair};
use uuid::Uuid;
-use crate::{errors::{NoneResult, ServiceError}, State};
+use std::io::Write;
+
+use crate::{errors::{NoneResult, ServiceError, StringResult, TokenResult}, State};
/**
@@ -14,21 +17,53 @@ use crate::{errors::{NoneResult, ServiceError}, State};
* for future authentication
*/
#[debug_handler]
-pub async fn begin(Query(params): Query<HashMap<String, String>>, Extension(state): Extension<State>) -> NoneResult {
+pub async fn begin(Query(params): Query<HashMap<String, String>>, Extension(state): Extension<State>) -> TokenResult {
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 dt = Utc::now();
+ let exp = Utc
+ .ymd(dt.year() + 1, dt.month(), dt.day())
+ .and_hms(0, 0, 0);
+ let kp = load_or_gen_keypair()?;
+
+ let token = match paseto::tokens::PasetoBuilder::new()
+ .set_ed25519_key(&kp)
+ .set_issued_at(Some(dt))
+ .set_expiration(&exp)
+ .set_issuer("solard")
+ .set_audience("solard")
+ .set_not_before(&Utc::now())
+ .build() {
+ Ok(token) => token,
+ Err(_) => {
+ return Err(ServiceError::Generic(String::from("could not generate paseto key")));
+ }
+ };
- let kp = AsymmetricKeyPair::<V4>::generate()?;
+ return Ok(token.to_string());
+
} else {
return Err(ServiceError::NotAuthorized);
}
} else {
return Err(ServiceError::Generic("No key supplied".to_string()));
}
+}
+
+
+fn load_or_gen_keypair() -> Result<Ed25519KeyPair, ServiceError> {
+ let kp: Ed25519KeyPair;
+ if let Ok(c) = fs::read_to_string(".keypair") {
+ kp = Ed25519KeyPair::from_pkcs8(&hex::decode(c)?)?;
+ } else {
+ let srand = SystemRandom::new();
+ let pkcs8 = Ed25519KeyPair::generate_pkcs8(&srand)?;
+
+ let mut file = File::open(".keypair").unwrap();
+ file.write(pkcs8.as_ref());
+
+ kp = Ed25519KeyPair::from_pkcs8(pkcs8.as_ref())?;
+ }
- Ok(())
+ Ok(kp)
}