This commit is contained in:
Tyler Murphy 2023-01-29 19:34:59 -05:00
parent ac58a612a3
commit 8af75aef17
8 changed files with 58 additions and 43 deletions

View file

@ -3,7 +3,10 @@ use lazy_static::lazy_static;
use rand::{distributions::Alphanumeric, Rng}; use rand::{distributions::Alphanumeric, Rng};
use tokio::sync::Mutex; use tokio::sync::Mutex;
use crate::{types::{user::User, http::ResponseCode, post::Post, session::Session}, console::{self, sanatize}}; use crate::{
console::{self, sanatize},
types::{http::ResponseCode, post::Post, session::Session, user::User},
};
lazy_static! { lazy_static! {
static ref SECRET: Mutex<String> = Mutex::new(String::new()); static ref SECRET: Mutex<String> = Mutex::new(String::new());
@ -22,17 +25,16 @@ pub async fn get_secret() -> String {
if secret.is_empty() { if secret.is_empty() {
*secret = new_secret(); *secret = new_secret();
} }
return secret.clone(); secret.clone()
} }
pub async fn regen_secret() -> String { pub async fn regen_secret() -> String {
let mut secret = SECRET.lock().await; let mut secret = SECRET.lock().await;
*secret = new_secret(); *secret = new_secret();
return secret.clone(); secret.clone()
} }
pub fn generate_users() -> Response { pub fn generate_users() -> Response {
let users = match User::reterieve_all() { let users = match User::reterieve_all() {
Ok(users) => users, Ok(users) => users,
Err(err) => return err, Err(err) => return err,
@ -51,7 +53,8 @@ pub fn generate_users() -> Response {
<th>Month</th> <th>Month</th>
<th>Year</th> <th>Year</th>
</tr> </tr>
"#.to_string(); "#
.to_string();
for user in users { for user in users {
html.push_str( html.push_str(
@ -66,7 +69,6 @@ pub fn generate_users() -> Response {
} }
pub fn generate_posts() -> Response { pub fn generate_posts() -> Response {
let posts = match Post::reterieve_all() { let posts = match Post::reterieve_all() {
Ok(posts) => posts, Ok(posts) => posts,
Err(err) => return err, Err(err) => return err,
@ -81,26 +83,28 @@ pub fn generate_posts() -> Response {
<th>Comments</th> <th>Comments</th>
<th>Date</th> <th>Date</th>
</tr> </tr>
"#.to_string(); "#
.to_string();
for post in posts { for post in posts {
let Ok(likes) = serde_json::to_string(&post.likes) else { continue }; let Ok(likes) = serde_json::to_string(&post.likes) else { continue };
let Ok(comments) = serde_json::to_string(&post.comments) else { continue }; let Ok(comments) = serde_json::to_string(&post.comments) else { continue };
html.push_str( html.push_str(&format!(
&format!("<tr><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td></tr>", "<tr><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td></tr>",
post.post_id, post.user_id, sanatize(post.content), console::beautify(likes), post.post_id,
console::beautify(comments), post.date post.user_id,
) sanatize(post.content),
); console::beautify(likes),
console::beautify(comments),
post.date
));
} }
ResponseCode::Success.text(&html) ResponseCode::Success.text(&html)
} }
pub fn generate_sessions() -> Response { pub fn generate_sessions() -> Response {
let sessions = match Session::reterieve_all() { let sessions = match Session::reterieve_all() {
Ok(sessions) => sessions, Ok(sessions) => sessions,
Err(err) => return err, Err(err) => return err,
@ -111,15 +115,15 @@ pub fn generate_sessions() -> Response {
<th>User ID</th> <th>User ID</th>
<th>Token</th> <th>Token</th>
</tr> </tr>
"#.to_string(); "#
.to_string();
for session in sessions { for session in sessions {
html.push_str( html.push_str(&format!(
&format!("<tr><td>{}</td><td>{}</td></tr>", "<tr><td>{}</td><td>{}</td></tr>",
session.user_id, session.token session.user_id, session.token
) ));
);
} }
ResponseCode::Success.text(&html) ResponseCode::Success.text(&html)
} }

View file

@ -1,10 +1,16 @@
use std::env; use std::env;
use axum::{response::Response, Router, routing::post}; use axum::{response::Response, routing::post, Router};
use serde::Deserialize; use serde::Deserialize;
use tower_cookies::{Cookies, Cookie}; use tower_cookies::{Cookie, Cookies};
use crate::{types::{extract::{Check, CheckResult, Json, AdminUser, Log}, http::ResponseCode}, admin, database}; use crate::{
admin, database,
types::{
extract::{AdminUser, Check, CheckResult, Json, Log},
http::ResponseCode,
},
};
#[derive(Deserialize)] #[derive(Deserialize)]
struct AdminAuthRequest { struct AdminAuthRequest {
@ -17,11 +23,10 @@ impl Check for AdminAuthRequest {
} }
} }
async fn auth(cookies: Cookies, Json(body) : Json<AdminAuthRequest>) -> Response { async fn auth(cookies: Cookies, Json(body): Json<AdminAuthRequest>) -> Response {
let check = env::var("SECRET").unwrap_or_else(|_| "admin".to_string());
let check = env::var("SECRET").unwrap_or("admin".to_string());
if check != body.secret { if check != body.secret {
return ResponseCode::BadRequest.text("Invalid admin secret") return ResponseCode::BadRequest.text("Invalid admin secret");
} }
let mut cookie = Cookie::new("admin", admin::regen_secret().await); let mut cookie = Cookie::new("admin", admin::regen_secret().await);
@ -45,10 +50,12 @@ impl Check for QueryRequest {
} }
} }
async fn query(_: AdminUser, Json(body) : Json<QueryRequest>) -> Response { async fn query(_: AdminUser, Json(body): Json<QueryRequest>) -> Response {
match database::query(body.query) { match database::query(body.query) {
Ok(changes) => ResponseCode::Success.text(&format!("Query executed successfully. {} lines changed.", changes)), Ok(changes) => ResponseCode::Success.text(&format!(
Err(err) => ResponseCode::InternalServerError.text(&format!("{}", err)) "Query executed successfully. {changes} lines changed."
)),
Err(err) => ResponseCode::InternalServerError.text(&format!("{err}")),
} }
} }

View file

@ -1,5 +1,5 @@
pub mod admin;
pub mod auth; pub mod auth;
pub mod pages; pub mod pages;
pub mod posts; pub mod posts;
pub mod users; pub mod users;
pub mod admin;

View file

@ -6,7 +6,10 @@ use axum::{
use crate::{ use crate::{
console, console,
types::{extract::{AuthorizedUser, Log}, http::ResponseCode}, types::{
extract::{AuthorizedUser, Log},
http::ResponseCode,
},
}; };
async fn root(user: Option<AuthorizedUser>, _: Log) -> Response { async fn root(user: Option<AuthorizedUser>, _: Log) -> Response {

View file

@ -46,7 +46,6 @@ lazy_static! {
} }
pub async fn log(ip: IpAddr, method: Method, uri: Uri, path: Option<String>, body: Option<String>) { pub async fn log(ip: IpAddr, method: Method, uri: Uri, path: Option<String>, body: Option<String>) {
let path = path.unwrap_or_default(); let path = path.unwrap_or_default();
let body = body.unwrap_or_default(); let body = body.unwrap_or_default();
@ -202,11 +201,13 @@ impl Formatter for HtmlFormatter {
} }
pub fn sanatize(input: String) -> String { pub fn sanatize(input: String) -> String {
input.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;") input
.replace('&', "&amp;")
.replace('<', "&lt;")
.replace('>', "&gt;")
} }
pub fn beautify(body: String) -> String { pub fn beautify(body: String) -> String {
let body = sanatize(body); let body = sanatize(body);
if body.is_empty() { if body.is_empty() {

View file

@ -20,4 +20,4 @@ pub fn query(query: String) -> Result<usize, rusqlite::Error> {
tracing::trace!("Running custom query"); tracing::trace!("Running custom query");
let conn = connect()?; let conn = connect()?;
conn.execute(&query, []) conn.execute(&query, [])
} }

View file

@ -19,11 +19,11 @@ use crate::{
types::extract::RouterURI, types::extract::RouterURI,
}; };
mod admin;
mod api; mod api;
mod console; mod console;
mod database; mod database;
mod types; mod types;
mod admin;
async fn serve<B>(req: Request<B>, next: Next<B>) -> Response async fn serve<B>(req: Request<B>, next: Next<B>) -> Response
where where

View file

@ -14,12 +14,12 @@ use bytes::Bytes;
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use crate::{ use crate::{
console, admin, console,
types::{ types::{
http::{ResponseCode, Result}, http::{ResponseCode, Result},
session::Session, session::Session,
user::User, user::User,
}, admin, },
}; };
pub struct AuthorizedUser(pub User); pub struct AuthorizedUser(pub User);
@ -71,12 +71,12 @@ where
return Err(ResponseCode::Forbidden.text("No admin secret provided")) return Err(ResponseCode::Forbidden.text("No admin secret provided"))
}; };
println!("{}", secret); println!("{secret}");
let check = admin::get_secret().await; let check = admin::get_secret().await;
if check != secret { if check != secret {
return Err(ResponseCode::Unauthorized.text("Auth token invalid")) return Err(ResponseCode::Unauthorized.text("Auth token invalid"));
} }
Ok(Self) Ok(Self)