Backend initial admin setup
This commit is contained in:
@@ -304,6 +304,84 @@ pub async fn update_user(
|
||||
Ok(Json(response))
|
||||
}
|
||||
|
||||
pub async fn check_admin_exists(
|
||||
State(data): State<Arc<AppState>>,
|
||||
) -> Result<impl IntoResponse, (StatusCode, Json<serde_json::Value>)> {
|
||||
let admin_count = sqlx::query_scalar::<_, i64>(r#"SELECT COUNT(*) FROM users WHERE is_admin = true"#)
|
||||
.fetch_one(&data.db)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Json(json!({"status": "error", "message": format!("{:?}", e)})),
|
||||
)
|
||||
})?;
|
||||
|
||||
let has_admin = admin_count > 0;
|
||||
Ok(Json(json!({"has_admin": has_admin})))
|
||||
}
|
||||
|
||||
pub async fn setup_initial_admin(
|
||||
State(data): State<Arc<AppState>>,
|
||||
Json(request): Json<UserCreateScheme>,
|
||||
) -> Result<impl IntoResponse, (StatusCode, Json<serde_json::Value>)> {
|
||||
// Check if any admin already exists
|
||||
let admin_count = sqlx::query_scalar::<_, i64>(r#"SELECT COUNT(*) FROM users WHERE is_admin = true"#)
|
||||
.fetch_one(&data.db)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Json(json!({"status": "error", "message": format!("{:?}", e)})),
|
||||
)
|
||||
})?;
|
||||
|
||||
if admin_count > 0 {
|
||||
return Err((
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(json!({"status": "error", "message": "Admin user already exists"})),
|
||||
));
|
||||
}
|
||||
|
||||
if request.username.is_empty() || request.pwd.is_empty() {
|
||||
return Err((
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(json!({"status": "error", "message": "Missing credential"})),
|
||||
));
|
||||
}
|
||||
|
||||
let argon = Argon2::default();
|
||||
let salt = SaltString::generate(&mut OsRng);
|
||||
let hashed_pwd = match argon.hash_password(request.pwd.clone().as_bytes(), &salt) {
|
||||
Ok(h) => h.to_string(),
|
||||
Err(e) => panic!("Error hashing {:}", e),
|
||||
};
|
||||
|
||||
let user = sqlx::query("INSERT INTO users (username, pwd, first_name, last_name, is_admin) VALUES ($1, $2, $3, $4, $5)")
|
||||
.bind(request.username)
|
||||
.bind(&hashed_pwd)
|
||||
.bind(request.first_name)
|
||||
.bind(request.last_name)
|
||||
.bind(true)
|
||||
.execute(&data.db)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Json(json!({"status": "error", "message": format!("{}", e)})),
|
||||
)
|
||||
})?;
|
||||
|
||||
if user.rows_affected() < 1 {
|
||||
return Err((
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Json(json!({"status": "error", "message": "Error creating admin user"})),
|
||||
));
|
||||
} else {
|
||||
Ok(Json(json!({"status": "success", "result": "Admin user created"})))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn filter_user(user: &User) -> FilteredUser {
|
||||
FilteredUser {
|
||||
id: user.id,
|
||||
|
||||
@@ -10,8 +10,8 @@ use crate::{
|
||||
cookie::validation::{validate_admin, validate_token},
|
||||
handlers::{
|
||||
auth::{
|
||||
create_user, delete_user, get_current_user, get_user_by_id, get_users, login, logout,
|
||||
update_user,
|
||||
check_admin_exists, create_user, delete_user, get_current_user, get_user_by_id, get_users, login, logout,
|
||||
setup_initial_admin, update_user,
|
||||
},
|
||||
ticket::{create_ticket, delete_ticket, edit_ticket, get_ticket_by_id, get_tickets},
|
||||
},
|
||||
@@ -50,5 +50,7 @@ pub fn create_router(state: Arc<AppState>) -> Router {
|
||||
Router::new()
|
||||
.merge(protected_routes)
|
||||
.route("/api/login", post(login))
|
||||
.route("/api/check-admin", get(check_admin_exists))
|
||||
.route("/api/setup-admin", post(setup_initial_admin))
|
||||
.with_state(state)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user