124 lines
4.7 KiB
Rust
124 lines
4.7 KiB
Rust
/*
|
|
* asklyphe-auth-frontend main.rs
|
|
* - entrypoint for the asklyphe authentication frontend
|
|
*
|
|
* 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 register;
|
|
mod verify;
|
|
mod login;
|
|
|
|
use std::{env, process};
|
|
use std::collections::HashMap;
|
|
use std::net::SocketAddr;
|
|
use std::ops::Deref;
|
|
use std::sync::Arc;
|
|
use std::sync::atomic::{AtomicU64, Ordering};
|
|
use std::time::Duration;
|
|
use argon2::{Argon2, PasswordHasher};
|
|
use argon2::password_hash::rand_core::OsRng;
|
|
use argon2::password_hash::SaltString;
|
|
use askama::Template;
|
|
use asklyphe_common::nats;
|
|
use asklyphe_common::nats::authservice::{AuthServiceQuery, AuthServiceRequest, AuthServiceResponse, EmailError, PasswordError, RegisterError, RegisterRequest, RegisterResponse, UsernameError};
|
|
use asklyphe_common::nats::comms;
|
|
use asklyphe_common::nats::comms::ServiceResponse;
|
|
use async_nats::jetstream;
|
|
use axum::{Extension, Form, Router};
|
|
use axum::extract::Query;
|
|
use axum::response::IntoResponse;
|
|
use axum::routing::get;
|
|
use serde::Deserialize;
|
|
use tokio::sync::Mutex;
|
|
use tracing::error;
|
|
use tracing_loki::url::Url;
|
|
use tracing_subscriber::layer::SubscriberExt;
|
|
use tracing_subscriber::util::SubscriberInitExt;
|
|
use crate::login::{login_get, login_post};
|
|
use crate::register::{register_get, register_post};
|
|
use crate::verify::verify_get;
|
|
|
|
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
|
const GIT_COMMIT: &str = env!("GIT_COMMIT");
|
|
const BUILT_ON: &str = env!("BUILT_ON");
|
|
const YEAR: &str = env!("YEAR");
|
|
|
|
#[derive(Clone)]
|
|
struct Opts {
|
|
bind_addr: SocketAddr,
|
|
nats_addr: SocketAddr,
|
|
nats_cert: String,
|
|
nats_key: String,
|
|
asklyphe_url: String,
|
|
loki_addr: Option<Url>,
|
|
datacenter_id: i64,
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
env_logger::init();
|
|
let opts = Opts {
|
|
bind_addr: env::var("BIND_ADDR").unwrap_or("0.0.0.0:5843".to_string()).parse().expect("Badly formed BIND_ADDR (Needs to be SocketAddr)"),
|
|
nats_addr: env::var("NATS_ADDR").unwrap_or("127.0.0.1:4222".to_string()).parse().expect("Badly formed NATS_ADDR (Needs to be SocketAddr)"),
|
|
nats_cert: env::var("NATS_CERT").expect("NATS_CERT needs to be set"),
|
|
nats_key: env::var("NATS_KEY").expect("NATS_KEY needs to be set"),
|
|
asklyphe_url: env::var("ASKLYPHE_URL").unwrap_or("https://asklyphe.com".to_string()),
|
|
loki_addr: match env::var("LOKI_ADDR") {
|
|
Ok(url) => {
|
|
Some(Url::parse(&url).expect("Badly formed LOKI_ADDR (Needs to be Url)"))
|
|
}
|
|
Err(_) => {
|
|
None
|
|
}
|
|
},
|
|
datacenter_id: env::var("DATACENTER_ID").unwrap_or("1".to_string()).parse().expect("Badly formed DATACENTER_ID (Need to be i64)"),
|
|
};
|
|
|
|
//if opts.loki_addr.is_some() {
|
|
// let (layer, task) = tracing_loki::builder()
|
|
// .label("environment", "dev").unwrap()
|
|
// .extra_field("pid", process::id().to_string()).unwrap()
|
|
// .extra_field("run_id", snowflake_factory.generate().to_string()).unwrap()
|
|
// .build_url(opts.loki_addr.clone().unwrap()).unwrap();
|
|
|
|
// // Register Loki layer
|
|
// tracing_subscriber::registry()
|
|
// .with(layer)
|
|
// .init();
|
|
|
|
// // Spawn Loki background task
|
|
// tokio::spawn(task);
|
|
//} else {
|
|
// tracing_subscriber::fmt::init()
|
|
//}
|
|
|
|
let nats = async_nats::ConnectOptions::new()
|
|
.add_client_certificate(opts.nats_cert.as_str().into(), opts.nats_key.as_str().into())
|
|
.connect(opts.nats_addr.to_string())
|
|
.await;
|
|
if let Err(e) = nats {
|
|
eprintln!("FATAL ERROR, COULDN'T CONNECT TO NATS: {}", e);
|
|
return;
|
|
}
|
|
let nats = nats.unwrap();
|
|
let nats = jetstream::new(nats);
|
|
let nats = Arc::new(Mutex::new(nats));
|
|
|
|
let app = Router::new()
|
|
.route("/register", get(register_get).post(register_post))
|
|
.route("/login", get(login_get).post(login_post))
|
|
.route("/verify", get(verify_get))
|
|
.layer(Extension(nats.clone()))
|
|
.layer(Extension(opts.clone()));
|
|
|
|
let listener = tokio::net::TcpListener::bind(opts.bind_addr).await.expect("Failed to get listener");
|
|
axum::serve(listener, app).await.expect("Failed to serve");
|
|
}
|
|
|