add admin setup token i love admin setup token

This commit is contained in:
WaveringAna 2025-01-27 22:32:49 -05:00
parent 660da70666
commit ac13e77dc4
15 changed files with 136 additions and 21 deletions

View file

@ -189,6 +189,27 @@ pub async fn register(
state: web::Data<AppState>,
payload: web::Json<RegisterRequest>,
) -> Result<impl Responder, AppError> {
// Check if any users exist
let user_count = sqlx::query!("SELECT COUNT(*) as count FROM users")
.fetch_one(&state.db)
.await?
.count
.unwrap_or(0);
// If users exist, registration is closed - no exceptions
if user_count > 0 {
return Err(AppError::Auth("Registration is closed".to_string()));
}
// Verify admin token for first user
match (&state.admin_token, &payload.admin_token) {
(Some(stored_token), Some(provided_token)) if stored_token == provided_token => {
// Token matches, proceed with registration
}
_ => return Err(AppError::Auth("Invalid admin setup token".to_string())),
}
// Check if email already exists
let exists = sqlx::query!("SELECT id FROM users WHERE email = $1", payload.email)
.fetch_optional(&state.db)
.await?;

View file

@ -1,4 +1,8 @@
use rand::Rng;
use sqlx::PgPool;
use std::fs::File;
use std::io::Write;
use tracing::info;
pub mod auth;
pub mod error;
@ -8,4 +12,41 @@ pub mod models;
#[derive(Clone)]
pub struct AppState {
pub db: PgPool,
pub admin_token: Option<String>,
}
pub async fn check_and_generate_admin_token(pool: &sqlx::PgPool) -> anyhow::Result<Option<String>> {
// Check if any users exist
let user_count = sqlx::query!("SELECT COUNT(*) as count FROM users")
.fetch_one(pool)
.await?
.count
.unwrap_or(0);
if user_count == 0 {
// Generate a random token using simple characters
let token: String = (0..32)
.map(|_| {
let idx = rand::thread_rng().gen_range(0..62);
match idx {
0..=9 => (b'0' + idx as u8) as char,
10..=35 => (b'a' + (idx - 10) as u8) as char,
_ => (b'A' + (idx - 36) as u8) as char,
}
})
.collect();
// Save token to file
let mut file = File::create("admin-setup-token.txt")?;
writeln!(file, "{}", token)?;
info!("No users found - generated admin setup token");
info!("Token has been saved to admin-setup-token.txt");
info!("Use this token to create the admin user");
info!("Admin setup token: {}", token);
Ok(Some(token))
} else {
Ok(None)
}
}

View file

@ -2,6 +2,7 @@ use actix_cors::Cors;
use actix_files as fs;
use actix_web::{web, App, HttpServer};
use anyhow::Result;
use simplelink::check_and_generate_admin_token;
use simplelink::{handlers, AppState};
use sqlx::postgres::PgPoolOptions;
use tracing::info;
@ -27,7 +28,12 @@ async fn main() -> Result<()> {
// Run database migrations
sqlx::migrate!("./migrations").run(&pool).await?;
let state = AppState { db: pool };
let admin_token = check_and_generate_admin_token(&pool).await?;
let state = AppState {
db: pool,
admin_token,
};
let host = std::env::var("SERVER_HOST").unwrap_or_else(|_| "127.0.0.1".to_string());
let port = std::env::var("SERVER_PORT").unwrap_or_else(|_| "8080".to_string());

View file

@ -49,6 +49,7 @@ pub struct LoginRequest {
pub struct RegisterRequest {
pub email: String,
pub password: String,
pub admin_token: Option<String>,
}
#[derive(Serialize)]