Authentication how handled as seperate router
This commit is contained in:
parent
0cf00faf78
commit
e47ad30a10
4 changed files with 24 additions and 27 deletions
14
src/auth.rs
14
src/auth.rs
|
|
@ -1,4 +1,8 @@
|
||||||
use axum::{http::HeaderMap, http::StatusCode, response::IntoResponse, response::Json};
|
use axum::body::Body;
|
||||||
|
use axum::{
|
||||||
|
http::HeaderMap, http::Request, http::StatusCode, middleware::Next, response::IntoResponse,
|
||||||
|
response::Json, response::Response,
|
||||||
|
};
|
||||||
use base64::{Engine, engine::general_purpose};
|
use base64::{Engine, engine::general_purpose};
|
||||||
use jsonwebtoken::{DecodingKey, EncodingKey, Header, Validation, decode, encode};
|
use jsonwebtoken::{DecodingKey, EncodingKey, Header, Validation, decode, encode};
|
||||||
use pam::Client;
|
use pam::Client;
|
||||||
|
|
@ -114,6 +118,14 @@ pub fn verify_system_credentials(username: &str, password: &str) -> bool {
|
||||||
client.authenticate().is_ok()
|
client.authenticate().is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn require_auth(headers: HeaderMap, request: Request<Body>, next: Next) -> Response {
|
||||||
|
if verify_token(&headers) {
|
||||||
|
next.run(request).await
|
||||||
|
} else {
|
||||||
|
(StatusCode::UNAUTHORIZED, "Unauthorized").into_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// POST /auth/login
|
// POST /auth/login
|
||||||
pub async fn post_login(headers: HeaderMap) -> impl IntoResponse {
|
pub async fn post_login(headers: HeaderMap) -> impl IntoResponse {
|
||||||
let (username, password) = match decode_basic_auth(&headers) {
|
let (username, password) = match decode_basic_auth(&headers) {
|
||||||
|
|
|
||||||
13
src/main.rs
13
src/main.rs
|
|
@ -1,3 +1,4 @@
|
||||||
|
use axum::middleware;
|
||||||
use axum::response::Redirect;
|
use axum::response::Redirect;
|
||||||
use axum::{Router, routing::get, routing::post};
|
use axum::{Router, routing::get, routing::post};
|
||||||
|
|
||||||
|
|
@ -8,10 +9,8 @@ mod routes;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let app = Router::new()
|
let protected = Router::new()
|
||||||
.route("/", get(|| async { Redirect::permanent("/stats") }))
|
|
||||||
.route("/stats", get(routes::stats::get_stats))
|
.route("/stats", get(routes::stats::get_stats))
|
||||||
.route("/auth/login", post(auth::post_login))
|
|
||||||
.route(
|
.route(
|
||||||
"/services/{service}/restart",
|
"/services/{service}/restart",
|
||||||
post(routes::services::restart_service),
|
post(routes::services::restart_service),
|
||||||
|
|
@ -28,7 +27,13 @@ async fn main() {
|
||||||
"/services/{service}/logs",
|
"/services/{service}/logs",
|
||||||
get(routes::services::service_logs),
|
get(routes::services::service_logs),
|
||||||
)
|
)
|
||||||
.route("/system/reboot", post(routes::system::system_reboot));
|
.route("/system/reboot", post(routes::system::system_reboot))
|
||||||
|
.route_layer(middleware::from_fn(auth::require_auth));
|
||||||
|
|
||||||
|
let app = Router::new()
|
||||||
|
.route("/", get(|| async { Redirect::permanent("/stats") }))
|
||||||
|
.route("/auth/login", post(auth::post_login))
|
||||||
|
.merge(protected);
|
||||||
|
|
||||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3001")
|
let listener = tokio::net::TcpListener::bind("127.0.0.1:3001")
|
||||||
.await
|
.await
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::Path, http::HeaderMap, http::StatusCode, response::IntoResponse,
|
extract::Path, http::HeaderMap, http::StatusCode, response::IntoResponse, response::Json,
|
||||||
response::Json,
|
|
||||||
};
|
};
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
use zbus::Connection;
|
use zbus::Connection;
|
||||||
|
|
@ -46,9 +45,6 @@ async fn systemd_action(action: &str, service: &str) -> (StatusCode, Json<Action
|
||||||
|
|
||||||
// POST /services/:service/restart
|
// POST /services/:service/restart
|
||||||
pub async fn restart_service(headers: HeaderMap, Path(service): Path<String>) -> impl IntoResponse {
|
pub async fn restart_service(headers: HeaderMap, Path(service): Path<String>) -> impl IntoResponse {
|
||||||
if !auth::verify_token(&headers) {
|
|
||||||
return ActionResponse::err(StatusCode::UNAUTHORIZED, "Unauthorized").into_response();
|
|
||||||
}
|
|
||||||
if !config::ALLOWED_SERVICES.contains(&service.as_str()) {
|
if !config::ALLOWED_SERVICES.contains(&service.as_str()) {
|
||||||
return ActionResponse::err(StatusCode::BAD_REQUEST, "Service not allowed").into_response();
|
return ActionResponse::err(StatusCode::BAD_REQUEST, "Service not allowed").into_response();
|
||||||
}
|
}
|
||||||
|
|
@ -57,9 +53,6 @@ pub async fn restart_service(headers: HeaderMap, Path(service): Path<String>) ->
|
||||||
|
|
||||||
// POST /services/:service/start
|
// POST /services/:service/start
|
||||||
pub async fn start_service(headers: HeaderMap, Path(service): Path<String>) -> impl IntoResponse {
|
pub async fn start_service(headers: HeaderMap, Path(service): Path<String>) -> impl IntoResponse {
|
||||||
if !auth::verify_token(&headers) {
|
|
||||||
return ActionResponse::err(StatusCode::UNAUTHORIZED, "Unauthorized").into_response();
|
|
||||||
}
|
|
||||||
if !config::ALLOWED_SERVICES.contains(&service.as_str()) {
|
if !config::ALLOWED_SERVICES.contains(&service.as_str()) {
|
||||||
return ActionResponse::err(StatusCode::BAD_REQUEST, "Service not allowed").into_response();
|
return ActionResponse::err(StatusCode::BAD_REQUEST, "Service not allowed").into_response();
|
||||||
}
|
}
|
||||||
|
|
@ -68,9 +61,6 @@ pub async fn start_service(headers: HeaderMap, Path(service): Path<String>) -> i
|
||||||
|
|
||||||
// POST /services/:service/stop
|
// POST /services/:service/stop
|
||||||
pub async fn stop_service(headers: HeaderMap, Path(service): Path<String>) -> impl IntoResponse {
|
pub async fn stop_service(headers: HeaderMap, Path(service): Path<String>) -> impl IntoResponse {
|
||||||
if !auth::verify_token(&headers) {
|
|
||||||
return ActionResponse::err(StatusCode::UNAUTHORIZED, "Unauthorized").into_response();
|
|
||||||
}
|
|
||||||
if !config::ALLOWED_SERVICES.contains(&service.as_str()) {
|
if !config::ALLOWED_SERVICES.contains(&service.as_str()) {
|
||||||
return ActionResponse::err(StatusCode::BAD_REQUEST, "Service not allowed").into_response();
|
return ActionResponse::err(StatusCode::BAD_REQUEST, "Service not allowed").into_response();
|
||||||
}
|
}
|
||||||
|
|
@ -79,9 +69,6 @@ pub async fn stop_service(headers: HeaderMap, Path(service): Path<String>) -> im
|
||||||
|
|
||||||
// GET /services/:service/logs
|
// GET /services/:service/logs
|
||||||
pub async fn service_logs(headers: HeaderMap, Path(service): Path<String>) -> impl IntoResponse {
|
pub async fn service_logs(headers: HeaderMap, Path(service): Path<String>) -> impl IntoResponse {
|
||||||
if !auth::verify_token(&headers) {
|
|
||||||
return ActionResponse::err(StatusCode::UNAUTHORIZED, "Unauthorized").into_response();
|
|
||||||
}
|
|
||||||
if !config::ALLOWED_SERVICES.contains(&service.as_str()) {
|
if !config::ALLOWED_SERVICES.contains(&service.as_str()) {
|
||||||
return ActionResponse::err(StatusCode::BAD_REQUEST, "Service not allowed").into_response();
|
return ActionResponse::err(StatusCode::BAD_REQUEST, "Service not allowed").into_response();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
use axum::{
|
use axum::{http::HeaderMap, http::StatusCode, response::IntoResponse};
|
||||||
http::HeaderMap, http::StatusCode, response::IntoResponse,
|
|
||||||
};
|
|
||||||
use zbus::Connection;
|
use zbus::Connection;
|
||||||
|
|
||||||
use crate::auth;
|
use crate::auth;
|
||||||
|
|
@ -8,11 +6,6 @@ use crate::models;
|
||||||
|
|
||||||
// POST /system/reboot
|
// POST /system/reboot
|
||||||
pub async fn system_reboot(headers: HeaderMap) -> impl IntoResponse {
|
pub async fn system_reboot(headers: HeaderMap) -> impl IntoResponse {
|
||||||
if !auth::verify_token(&headers) {
|
|
||||||
return models::ActionResponse::err(StatusCode::UNAUTHORIZED, "Unauthorized")
|
|
||||||
.into_response();
|
|
||||||
}
|
|
||||||
|
|
||||||
let conn = match Connection::system().await {
|
let conn = match Connection::system().await {
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue