chore: config module

This commit is contained in:
Zack Fu Zi Xiang 2024-02-08 14:19:57 +08:00
parent c826f00e9a
commit 7428fdbe33
No known key found for this signature in database
GPG Key ID: 39DE600AFEEED522
10 changed files with 68 additions and 27 deletions

View File

@ -0,0 +1,26 @@
use tracing::warn;
#[derive(Debug, Clone)]
pub struct Config {
pub redis_url: String,
pub gotrue_url: String,
}
impl Config {
pub fn from_env() -> Self {
Config {
redis_url: get_or_default("ADMIN_FRONTEND_REDIS_URL", "redis://localhost:6379"),
gotrue_url: get_or_default("ADMIN_FRONTEND_GOTRUE_URL", "http://localhost:9999"),
}
}
}
fn get_or_default(key: &str, default: &str) -> String {
std::env::var(key).unwrap_or_else(|e| {
warn!(
"failed to get env var: {}, err: {}, using default: {}",
key, e, default
);
default.to_string()
})
}

View File

@ -1,3 +1,4 @@
mod config;
mod error; mod error;
mod models; mod models;
mod response; mod response;
@ -16,6 +17,8 @@ use tower_http::{
}; };
use tracing::info; use tracing::info;
use crate::config::Config;
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
// load from .env // load from .env
@ -27,16 +30,23 @@ async fn main() {
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) .with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
.init(); .init();
let gotrue_client = gotrue::api::Client::new( let config = Config::from_env();
reqwest::Client::new(), info!("config loaded: {:?}", &config);
&std::env::var("GOTRUE_URL").unwrap_or("http://gotrue:9999".to_string()),
); let gotrue_client = gotrue::api::Client::new(reqwest::Client::new(), &config.gotrue_url);
let redis_client = gotrue_client
redis::Client::open(std::env::var("REDIS_URL").unwrap_or("redis://redis:6379".to_string())) .health()
.unwrap() .await
.get_tokio_connection_manager() .expect("gotrue health check failed");
.await info!("Gotrue client initialized.");
.unwrap();
let redis_client = redis::Client::open(config.redis_url)
.expect("failed to create redis client")
.get_tokio_connection_manager()
.await
.expect("failed to get redis connection manager");
info!("Redis client initialized.");
let session_store = session::SessionStorage::new(redis_client); let session_store = session::SessionStorage::new(redis_client);
let state = AppState { let state = AppState {
@ -64,9 +74,13 @@ async fn main() {
.nest_service("/web-api", web_api_router) .nest_service("/web-api", web_api_router)
.nest_service("/assets", ServeDir::new("assets")); .nest_service("/assets", ServeDir::new("assets"));
let listener = TcpListener::bind("0.0.0.0:3000").await.unwrap(); let listener = TcpListener::bind("0.0.0.0:3000")
.await
.expect("failed to bind to port");
info!("listening on: {:?}", listener); info!("listening on: {:?}", listener);
axum::serve(listener, app).await.unwrap(); axum::serve(listener, app)
.await
.expect("failed to run server");
} }
#[derive(Clone)] #[derive(Clone)]

View File

@ -376,16 +376,14 @@ async fn send_magic_link(
State(state): State<AppState>, State(state): State<AppState>,
email: &str, email: &str,
) -> Result<WebApiResponse<()>, WebApiError<'static>> { ) -> Result<WebApiResponse<()>, WebApiError<'static>> {
Ok( state
state .gotrue_client
.gotrue_client .magic_link(&MagicLinkParams {
.magic_link(&MagicLinkParams { email: email.to_owned(),
email: email.to_owned(), ..Default::default()
..Default::default() })
}) .await?;
.await? Ok(WebApiResponse::<()>::from_str("Magic Link Sent".into()))
.into(),
)
} }
fn get_base_url(header_map: &HeaderMap) -> String { fn get_base_url(header_map: &HeaderMap) -> String {

View File

@ -1,6 +1,6 @@
<div> <div>
<h4>Please enter the following information to create new SSO</h4> <h4>Please enter the following information to create new SSO</h4>
<form hx-post="/web-api/admin/sso"> <form hx-post="/web-api/admin/sso" hx-target="#none">
<table> <table>
<tr> <tr>
<td>Email</td> <td>Email</td>

View File

@ -2,7 +2,7 @@
{% include "user_details.html" %} {% include "user_details.html" %}
<div> <div>
<form hx-put="/web-api/admin/user/{{ user.id|escape }}"> <form hx-put="/web-api/admin/user/{{ user.id|escape }}" hx-target="#none">
<table> <table>
<tr> <tr>
<td>Set Password:</td> <td>Set Password:</td>

View File

@ -1,6 +1,6 @@
<div> <div>
<h3>Password Change</h3> <h3>Password Change</h3>
<form hx-post="/web-api/change_password"> <form hx-post="/web-api/change_password" hx-target="#none">
<table> <table>
<tr> <tr>
<td>New Password:</td> <td>New Password:</td>

View File

@ -1,6 +1,6 @@
<div id="create-user"> <div id="create-user">
<h4>Please enter the following information to create a new user</h4> <h4>Please enter the following information to create a new user</h4>
<form hx-post="/web-api/admin/user"> <form hx-post="/web-api/admin/user" hx-target="#none">
<table> <table>
<tr> <tr>
<td>Email:</td> <td>Email:</td>

View File

@ -1,6 +1,6 @@
<div id="invite-user"> <div id="invite-user">
<h4>Please enter the following email invite a new user</h4> <h4>Please enter the following email invite a new user</h4>
<form hx-post="/web-api/invite"> <form hx-post="/web-api/invite" hx-target="#none">
<table> <table>
<tr> <tr>
<td>Email:</td> <td>Email:</td>

View File

@ -19,6 +19,7 @@
<div id="content">{% block content %}{% endblock %}</div> <div id="content">{% block content %}{% endblock %}</div>
<!-- place for htmx result that are not updating document --> <!-- place for htmx result that are not updating document -->
<!-- hx-target="#none" -->
<div id="none" style="display: none"></div> <div id="none" style="display: none"></div>
</body> </body>
</html> </html>

View File

@ -58,6 +58,7 @@
<div style="display: flex; margin: 8px 0px"> <div style="display: flex; margin: 8px 0px">
<button <button
hx-post="/web-api/signin" hx-post="/web-api/signin"
hx-target="#none"
class="button cyan" class="button cyan"
type="submit" type="submit"
style="width: 100%; padding: 8px 8px" style="width: 100%; padding: 8px 8px"
@ -66,6 +67,7 @@
</button> </button>
<button <button
hx-post="/web-api/signup" hx-post="/web-api/signup"
hx-target="#none"
class="button purple" class="button purple"
type="submit" type="submit"
style="width: 100%; padding: 8px 8px" style="width: 100%; padding: 8px 8px"