aboutsummaryrefslogblamecommitdiff
path: root/src/handlers/auth.rs
blob: 8d65b05f7178d53ab290b7cbb2626b238baac3a5 (plain) (tree)
1
2
3
4
5
6
7
8
                                                  


                                      

                                                          

               


                                                                                  







                                                                               
                                                                                                                      

                                        


















                                                                                                         
 

                                         





                                                                         















                                                                  
 
          
 
use std::{collections::HashMap, fs::{self, File}};

use axum::{extract::Query, Extension};
use axum_macros::debug_handler;
use chrono::{Utc, TimeZone, Datelike};
use ring::{rand::SystemRandom, signature::Ed25519KeyPair};
use uuid::Uuid;

use std::io::Write;

use crate::{errors::{NoneResult, ServiceError, StringResult, TokenResult}, 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>) -> TokenResult {
    if let Some(k) = params.get("key") {
        if k == &state.gen_key {
            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")));
                    }
                };

            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(kp)
}