forked from asklyphe-public/asklyphe
		
	
		
			
	
	
		
			93 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
		
		
			
		
	
	
			93 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * authservice main.rs
							 | 
						||
| 
								 | 
							
								 * - entrypoint for the asklyphe authentication service
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Copyright (C) 2025 Real Microsoft, LLC
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								mod process;
							 | 
						||
| 
								 | 
							
								pub mod db;
							 | 
						||
| 
								 | 
							
								mod email;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								use std::string::ToString;
							 | 
						||
| 
								 | 
							
								use std::sync::Arc;
							 | 
						||
| 
								 | 
							
								use std::sync::atomic::{AtomicI64, AtomicU64, Ordering};
							 | 
						||
| 
								 | 
							
								use asklyphe_common::nats::authservice::AuthServiceResponse;
							 | 
						||
| 
								 | 
							
								use async_nats::jetstream;
							 | 
						||
| 
								 | 
							
								use log::{debug, error, info, warn};
							 | 
						||
| 
								 | 
							
								use once_cell::sync::Lazy;
							 | 
						||
| 
								 | 
							
								use asklyphe_common::nats::comms;
							 | 
						||
| 
								 | 
							
								use sea_orm::Database;
							 | 
						||
| 
								 | 
							
								use crate::email::email_init;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								pub static NATS_URL: Lazy<String> = Lazy::new(|| std::env::var("NATS_URL").expect("NO NATS DEFINED"));
							 | 
						||
| 
								 | 
							
								pub static NATS_CERT: Lazy<String> = Lazy::new(|| std::env::var("NATS_CERT").expect("NO NATS_CERT DEFINED"));
							 | 
						||
| 
								 | 
							
								pub static NATS_KEY: Lazy<String> = Lazy::new(|| std::env::var("NATS_KEY").expect("NO NATS_KEY DEFINED"));
							 | 
						||
| 
								 | 
							
								pub static DB_URL: Lazy<String> = Lazy::new(|| std::env::var("DB_URL").expect("NO DB_URL DEFINED"));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								pub static SMTP_DISABLE: Lazy<bool> = Lazy::new(|| std::env::var("SMTP_DISABLE").is_ok());
							 | 
						||
| 
								 | 
							
								pub static SMTP_URL: Lazy<String> = Lazy::new(|| std::env::var("SMTP_URL").expect("NO SMTP_URL DEFINED"));
							 | 
						||
| 
								 | 
							
								pub static SMTP_USERNAME: Lazy<String> = Lazy::new(|| std::env::var("SMTP_USERNAME").expect("NO SMTP_USERNAME DEFINED"));
							 | 
						||
| 
								 | 
							
								pub static SMTP_PASSWORD: Lazy<String> = Lazy::new(|| std::env::var("SMTP_PASSWORD").expect("NO SMTP_PASSWORD DEFINED"));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								pub static PROCESSES_HANDLED: AtomicU64 = AtomicU64::new(0);
							 | 
						||
| 
								 | 
							
								pub static LAST_MESSAGE: AtomicI64 = AtomicI64::new(0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#[tokio::main]
							 | 
						||
| 
								 | 
							
								async fn main() {
							 | 
						||
| 
								 | 
							
								    env_logger::init();
							 | 
						||
| 
								 | 
							
								    info!("authservice began at {}", chrono::Utc::now().to_string());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    let nats = async_nats::ConnectOptions::new()
							 | 
						||
| 
								 | 
							
								        .add_client_certificate(NATS_CERT.as_str().into(), NATS_KEY.as_str().into())
							 | 
						||
| 
								 | 
							
								        .connect(NATS_URL.as_str())
							 | 
						||
| 
								 | 
							
								        .await;
							 | 
						||
| 
								 | 
							
								    if let Err(e) = nats {
							 | 
						||
| 
								 | 
							
								        error!("FATAL ERROR, COULDN'T CONNECT TO NATS: {}", e);
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    let nats = nats.unwrap();
							 | 
						||
| 
								 | 
							
								    let nats = jetstream::new(nats);
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    email_init().await;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    info!("authservice thread spawned");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    async fn on_recv(query: comms::Query) -> comms::ServiceResponse {
							 | 
						||
| 
								 | 
							
								        debug!("recv");
							 | 
						||
| 
								 | 
							
								        let db = Database::connect(DB_URL.as_str()).await;
							 | 
						||
| 
								 | 
							
								        if let Err(e) = db {
							 | 
						||
| 
								 | 
							
								            error!("FATAL ERROR, COULDN'T CONNECT TO DATABASE: {e}");
							 | 
						||
| 
								 | 
							
								            return comms::ServiceResponse::AuthService(AuthServiceResponse::OtherError("FATAL ERROR, COULDN'T CONNECT TO DATABASE".to_string()));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        let db = db.unwrap();
							 | 
						||
| 
								 | 
							
								        let now = chrono::Utc::now().timestamp();
							 | 
						||
| 
								 | 
							
								        LAST_MESSAGE.store(now, Ordering::Relaxed);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        let response = match query {
							 | 
						||
| 
								 | 
							
								            comms::Query::AuthService(query) => {
							 | 
						||
| 
								 | 
							
								                process::process(query, db).await
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            _ => {
							 | 
						||
| 
								 | 
							
								                AuthServiceResponse::InvalidRequest
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if PROCESSES_HANDLED.load(Ordering::Relaxed) % 100 == 0 {
							 | 
						||
| 
								 | 
							
								            info!("handled {} requests!", PROCESSES_HANDLED.load(Ordering::Relaxed));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        PROCESSES_HANDLED.fetch_add(1, Ordering::Relaxed);
							 | 
						||
| 
								 | 
							
								        comms::ServiceResponse::AuthService(response)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if let Err(e) = comms::subscribe_service(comms::Service::AuthService, &nats, Arc::new(on_recv)).await {
							 | 
						||
| 
								 | 
							
								        error!("failed to subscribe to authservice nats! reason {:?}", e);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |