use std::sync::Arc;
use axum::{
http::{
StatusCode,
Uri,
header::HeaderMap,
},
Json,
routing::{get,post},
Extension,
response::{IntoResponse,Response,Redirect},
Router,
};
use tower_cookies::Cookies;
use crate::{
route,
defs::{
AppDBs,
User,
UserItem,
UserStatus,
ReqHandler,
ReqHeaderMap,
},
handlers::{
add_session_cookie,
get_auth_state,
},
};
pub fn admin_router_handlers() -> Router {
async fn users_handler(
header: HeaderMap,
uri: Uri,
Extension(app_dbs): Extension<Arc<AppDBs>>,
Extension(cookies): Extension<Cookies>,
) -> Response {
let auth_state = get_auth_state(true, &cookies, &app_dbs).await;
if !auth_state.is_admin() {
return Redirect::temporary( &format!("/login?o={}",uri.path().to_string())).into_response();
}
let mut req_handler = ReqHandler::new(
ReqHeaderMap::new(header, &format!("{}",&uri.path().to_string())),
&app_dbs,
&uri,
&auth_state,
"user_handler"
);
let usrs = match User::list(&app_dbs.user_store, true, false, "").await {
Ok(data) => data,
Err(e) => {
println!("Error list users: {}",e);
Vec::new()
},
};
req_handler.context.insert("usrs", &usrs);
req_handler.context.insert("total_usrs", &usrs.len());
req_handler.context.insert("with_menu", "1");
let mut res_headers = HeaderMap::new();
if req_handler.req_header.is_browser() {
res_headers.append(axum::http::header::CONTENT_TYPE,"text/html; charset=utf-8".parse().unwrap());
}
let result = if let Some(tpl) = app_dbs.config.tpls.get("users") {
req_handler.render_template(&tpl,"Users")
} else {
String::from("Users")
};
(
res_headers,
result.to_owned()
).into_response()
}
async fn user_get_handler(
header: HeaderMap,
Extension(app_dbs): Extension<Arc<AppDBs>>,
Extension(cookies): Extension<Cookies>,
Json(user_item): Json<UserItem>,
) -> Response {
let auth_state = get_auth_state(true, &cookies, &app_dbs).await;
if auth_state.session.is_none() {
return (
StatusCode::UNAUTHORIZED,
header,
"Error"
).into_response();
}
let mut res_headers = HeaderMap::new();
res_headers.append(axum::http::header::CONTENT_TYPE,"application/json; charset=utf-8".parse().unwrap());
let user_id = auth_state.user_id();
if user_id.is_empty() {
return (
StatusCode::UNAUTHORIZED,
res_headers,
"Error"
).into_response();
}
if !auth_state.is_admin() {
return (
StatusCode::UNAUTHORIZED,
res_headers,
"Error"
).into_response();
}
let mut user_sel = User::select(&user_item.name, &user_item.value, true,&app_dbs.user_store).await.unwrap_or_default();
if user_sel.name.is_empty() {
return (
StatusCode::BAD_REQUEST,
res_headers,
"Error"
).into_response();
}
user_sel.password = String::from("");
user_sel.otp_base32 = String::from("");
let result = serde_json::to_string(&user_sel).unwrap_or_else(|e|{
println!("Error to convert user items to json: {}",e);
String::from("")
});
(
res_headers,
result.to_owned()
).into_response()
}
async fn user_save_handler(
header: HeaderMap,
uri: Uri,
Extension(app_dbs): Extension<Arc<AppDBs>>,
Extension(cookies): Extension<Cookies>,
Json(new_user): Json<User>,
) -> Response {
let auth_state = get_auth_state(true, &cookies, &app_dbs).await;
if auth_state.session.is_none() {
return (
StatusCode::UNAUTHORIZED,
header,
"Error"
).into_response();
}
let req_handler = ReqHandler::new(
ReqHeaderMap::new(header, &format!("{}",&uri.path().to_string())),
&app_dbs,
&uri,
&auth_state,
"update_user_handler"
);
let mut res_headers = HeaderMap::new();
res_headers.append(axum::http::header::CONTENT_TYPE,"text/plain; charset=utf-8".parse().unwrap());
let user_id = auth_state.user_id();
if user_id.is_empty() {
return (
StatusCode::UNAUTHORIZED,
res_headers,
"Error"
).into_response();
}
if !auth_state.is_admin() {
return (
StatusCode::UNAUTHORIZED,
res_headers,
"Error"
).into_response();
}
let mut user_sel = User::select("id", &format!("{}",&new_user.id), false,&app_dbs.user_store).await.unwrap_or_default();
if user_sel.name.is_empty() {
return (
StatusCode::BAD_REQUEST,
res_headers,
"Error"
).into_response();
}
user_sel.from_user(new_user);
let user_data = user_sel.session_data();
if user_sel.update(&app_dbs.user_store).await.is_err() {
return (
StatusCode::BAD_REQUEST,
req_handler.req_header.header,
"Error"
).into_response();
}
let session_token = req_handler.new_token();
let session_cookie = add_session_cookie(true,&cookies, &session_token, &user_data, 0, &app_dbs, "/").await;
if app_dbs.config.verbose > 1 {
println!("session cookie: {}", &session_cookie)
};
let result = String::from("Ok");
(
res_headers,
result
).into_response()
}
async fn user_delete_handler(
header: HeaderMap,
Extension(app_dbs): Extension<Arc<AppDBs>>,
Extension(cookies): Extension<Cookies>,
Json(user_item): Json<UserItem>,
) -> Response {
let auth_state = get_auth_state(true, &cookies, &app_dbs).await;
if auth_state.session.is_none() {
return (
StatusCode::UNAUTHORIZED,
header,
"Error"
).into_response();
}
let mut res_headers = HeaderMap::new();
res_headers.append(axum::http::header::CONTENT_TYPE,"application/json; charset=utf-8".parse().unwrap());
let user_id = auth_state.user_id();
if user_id.is_empty() {
return (
StatusCode::UNAUTHORIZED,
res_headers,
"Error"
).into_response();
}
if !auth_state.is_admin() {
return (
StatusCode::UNAUTHORIZED,
res_headers,
"Error"
).into_response();
}
let user_sel = User::select(&user_item.name, &user_item.value, true,&app_dbs.user_store).await.unwrap_or_default();
if user_sel.name.is_empty() {
return (
StatusCode::BAD_REQUEST,
res_headers,
"Error"
).into_response();
}
let result = match User::delete(user_sel.id,&app_dbs.user_store).await {
Ok(val) => if val {
format!("Ok")
} else {
format!("Error user not deleted")
},
Err(e) => {
println!("Error delete user: {}", e);
format!("Error on delete user")
}
};
(
res_headers,
result.to_owned()
).into_response()
}
async fn user_as_admin_handler(
header: HeaderMap,
uri: Uri,
Extension(app_dbs): Extension<Arc<AppDBs>>,
Extension(cookies): Extension<Cookies>,
Json(user_item): Json<UserItem>,
) -> Response {
let auth_state = get_auth_state(true, &cookies, &app_dbs).await;
if auth_state.session.is_none() {
return (
StatusCode::UNAUTHORIZED,
header,
"Error"
).into_response();
}
let req_handler = ReqHandler::new(
ReqHeaderMap::new(header, &format!("{}",&uri.path().to_string())),
&app_dbs,
&uri,
&auth_state,
"update_user_handler"
);
let mut res_headers = HeaderMap::new();
res_headers.append(axum::http::header::CONTENT_TYPE,"application/json; charset=utf-8".parse().unwrap());
let user_id = auth_state.user_id();
if user_id.is_empty() {
return (
StatusCode::UNAUTHORIZED,
res_headers,
"Error"
).into_response();
}
if !auth_state.is_admin() {
return (
StatusCode::UNAUTHORIZED,
res_headers,
"Error"
).into_response();
}
let mut user_sel = User::select(&user_item.name, &user_item.value, true,&app_dbs.user_store).await.unwrap_or_default();
if user_sel.name.is_empty() {
return (
StatusCode::BAD_REQUEST,
res_headers,
"Error"
).into_response();
}
let result = if user_sel.isadmin {
format!("User already admin")
} else {
user_sel.isadmin = true;
let user_data = user_sel.session_data();
if user_sel.update(&app_dbs.user_store).await.is_err() {
return (
StatusCode::BAD_REQUEST,
req_handler.req_header.header,
"Error"
).into_response();
}
let session_token = req_handler.new_token();
let session_cookie = add_session_cookie(true,&cookies, &session_token, &user_data, 0, &app_dbs, "/").await;
if app_dbs.config.verbose > 1 {
println!("session cookie: {}", &session_cookie)
};
String::from("Ok")
};
(
res_headers,
result.to_owned()
).into_response()
}
async fn user_disable_totp_handler(
header: HeaderMap,
uri: Uri,
Extension(app_dbs): Extension<Arc<AppDBs>>,
Extension(cookies): Extension<Cookies>,
Json(user_item): Json<UserItem>,
) -> Response {
let auth_state = get_auth_state(true, &cookies, &app_dbs).await;
if auth_state.session.is_none() {
return (
StatusCode::UNAUTHORIZED,
header,
"Error"
).into_response();
}
let req_handler = ReqHandler::new(
ReqHeaderMap::new(header, &format!("{}",&uri.path().to_string())),
&app_dbs,
&uri,
&auth_state,
"update_user_handler"
);
let mut res_headers = HeaderMap::new();
res_headers.append(axum::http::header::CONTENT_TYPE,"application/json; charset=utf-8".parse().unwrap());
let user_id = auth_state.user_id();
if user_id.is_empty() {
return (
StatusCode::UNAUTHORIZED,
res_headers,
"Error"
).into_response();
}
if !auth_state.is_admin() {
return (
StatusCode::UNAUTHORIZED,
res_headers,
"Error"
).into_response();
}
let mut user_sel = User::select(&user_item.name, &user_item.value, true,&app_dbs.user_store).await.unwrap_or_default();
if user_sel.name.is_empty() {
return (
StatusCode::BAD_REQUEST,
res_headers,
"Error"
).into_response();
}
let result = if user_sel.otp_enabled && !user_sel.otp_base32.is_empty() {
user_sel.disable_totp();
let user_data = user_sel.session_data();
if user_sel.update(&app_dbs.user_store).await.is_err() {
return (
StatusCode::BAD_REQUEST,
req_handler.req_header.header,
"Error"
).into_response();
}
let session_token = req_handler.new_token();
let session_cookie = add_session_cookie(true,&cookies, &session_token, &user_data, 0, &app_dbs, "/").await;
if app_dbs.config.verbose > 1 {
println!("session cookie: {}", &session_cookie)
};
String::from("Ok")
} else {
format!("User does not have TOTP enabled")
};
(
res_headers,
result.to_owned()
).into_response()
}
async fn user_passwd_reset_handler(
header: HeaderMap,
uri: Uri,
Extension(app_dbs): Extension<Arc<AppDBs>>,
Extension(cookies): Extension<Cookies>,
Json(user_item): Json<UserItem>,
) -> Response {
dbg!(&user_item);
let auth_state = get_auth_state(true, &cookies, &app_dbs).await;
if auth_state.session.is_none() {
return (
StatusCode::UNAUTHORIZED,
header,
"Error"
).into_response();
}
let req_handler = ReqHandler::new(
ReqHeaderMap::new(header, &format!("{}",&uri.path().to_string())),
&app_dbs,
&uri,
&auth_state,
"update_user_handler"
);
let mut res_headers = HeaderMap::new();
res_headers.append(axum::http::header::CONTENT_TYPE,"application/json; charset=utf-8".parse().unwrap());
let user_id = auth_state.user_id();
if user_id.is_empty() {
return (
StatusCode::UNAUTHORIZED,
res_headers,
"Error"
).into_response();
}
if !auth_state.is_admin() {
return (
StatusCode::UNAUTHORIZED,
res_headers,
"Error"
).into_response();
}
let mut user_sel = User::select(&user_item.name, &user_item.value, true,&app_dbs.user_store).await.unwrap_or_default();
if user_sel.name.is_empty() {
return (
StatusCode::BAD_REQUEST,
res_headers,
"Error"
).into_response();
}
dbg!(&user_item);
let result = if user_sel.status != UserStatus::Active {
return (
StatusCode::BAD_REQUEST,
res_headers,
"Error User not active !!"
).into_response()
} else {
user_sel.status = UserStatus::Pending;
let user_data = user_sel.session_data();
if user_sel.update(&app_dbs.user_store).await.is_err() {
return (
StatusCode::BAD_REQUEST,
req_handler.req_header.header,
"Error"
).into_response();
}
let session_token = req_handler.new_token();
let session_cookie = add_session_cookie(true,&cookies, &session_token, &user_data, 0, &app_dbs, "/").await;
if app_dbs.config.verbose > 1 {
println!("session cookie: {}", &session_cookie)
};
String::from("Ok")
};
(
res_headers,
result.to_owned()
).into_response()
}
route("/users", get(users_handler))
.route("/userget", post(user_get_handler))
.route("/usersave", post(user_save_handler))
.route("/userdelete", post(user_delete_handler))
.route("/userdisabletotp", post(user_disable_totp_handler))
.route("/userasadmin", post(user_as_admin_handler))
.route("/passwdreset", post(user_passwd_reset_handler))
}