use std::{error::Error, time::SystemTime}; use jsonwebtoken::{encode, Algorithm, EncodingKey}; use serde::{Deserialize, Serialize}; use tokio::{fs::File, io::AsyncReadExt}; use toml::Table; use crate::{ messages::authentication::{AuthenticationTokenRequest, AuthenticationTokenResponse}, model::{instance::Instance, user::User}, }; #[derive(Debug, Serialize, Deserialize)] struct UserTokenMetadata { user: User, generated_for: Instance, exp: u64, } pub struct AuthenticationTokenGranter { pub config: Table, } impl AuthenticationTokenGranter { pub async fn token_request( &mut self, request: AuthenticationTokenRequest, ) -> Result> { let secret_key = self.config["authentication"]["secret_key"] .as_str() .unwrap(); let private_key = { let mut file = File::open(self.config["keys"]["private"].as_str().unwrap()) .await .unwrap(); let mut key = vec![]; file.read_to_end(&mut key).await.unwrap(); key }; if request.secret_key != secret_key { error!("Incorrect secret key!"); panic!() } let encoding_key = EncodingKey::from_rsa_pem(&private_key).unwrap(); let claims = UserTokenMetadata { user: User { username: String::from("ambee"), instance: Instance { url: String::from("giterated.dev"), }, }, generated_for: Instance { url: String::from("giterated.dev"), }, exp: (SystemTime::UNIX_EPOCH.elapsed().unwrap() + std::time::Duration::from_secs(24 * 60 * 60)) .as_secs(), }; let token = encode( &jsonwebtoken::Header::new(Algorithm::RS256), &claims, &encoding_key, ) .unwrap(); Ok(AuthenticationTokenResponse { token }) } }