get stuff ready for deployment!
This commit is contained in:
parent
00a584c8f0
commit
66b14ed855
4 changed files with 87 additions and 55 deletions
|
@ -1,44 +1,49 @@
|
||||||
use std::io;
|
// use std::io;
|
||||||
|
|
||||||
use app::App;
|
// use app::App;
|
||||||
use crossterm::event::{self, KeyCode, KeyEventKind};
|
// use crossterm::event::{self, KeyCode, KeyEventKind};
|
||||||
use ratatui::{style::Stylize, widgets::Paragraph, DefaultTerminal};
|
// use ratatui::{style::Stylize, widgets::Paragraph, DefaultTerminal};
|
||||||
|
|
||||||
fn main() -> io::Result<()> {
|
fn main() -> io::Result<()> {
|
||||||
let mut term = ratatui::init();
|
// let mut term = ratatui::init();
|
||||||
term.clear()?;
|
// term.clear()?;
|
||||||
|
|
||||||
let r = App::default().run(&mut term);
|
// let r = App::default().run(&mut term);
|
||||||
ratatui::restore();
|
// ratatui::restore();
|
||||||
r
|
// r
|
||||||
|
let mut teststr = String::from("Hello! ää");
|
||||||
}
|
}
|
||||||
|
|
||||||
mod app {
|
fn rev_in_place(s: &mut String) {
|
||||||
|
s.ch
|
||||||
use std::io;
|
|
||||||
|
|
||||||
use ratatui::{DefaultTerminal, Frame};
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct App {
|
|
||||||
exit: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl App {
|
|
||||||
pub fn run(&mut self, terminal: &mut DefaultTerminal) -> io::Result<()> {
|
|
||||||
while !self.exit {
|
|
||||||
terminal.draw(|frame| self.draw(frame))?;
|
|
||||||
self.handle_events()?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn draw(&self, frame: &mut Frame) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_events(&mut self) -> io::Result<()> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mod app {
|
||||||
|
|
||||||
|
// use std::io;
|
||||||
|
|
||||||
|
// use ratatui::{DefaultTerminal, Frame};
|
||||||
|
|
||||||
|
// #[derive(Default)]
|
||||||
|
// pub struct App {
|
||||||
|
// exit: bool,
|
||||||
|
// }
|
||||||
|
|
||||||
|
// impl App {
|
||||||
|
// pub fn run(&mut self, terminal: &mut DefaultTerminal) -> io::Result<()> {
|
||||||
|
// while !self.exit {
|
||||||
|
// terminal.draw(|frame| self.draw(frame))?;
|
||||||
|
// self.handle_events()?;
|
||||||
|
// }
|
||||||
|
// Ok(())
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn draw(&self, frame: &mut Frame) {
|
||||||
|
// todo!()
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn handle_events(&mut self) -> io::Result<()> {
|
||||||
|
// todo!()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
|
@ -1,19 +1,62 @@
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, Request, State},
|
||||||
|
middleware::{self, Next},
|
||||||
|
response::{IntoResponse, Response},
|
||||||
routing::get,
|
routing::get,
|
||||||
Json, Router,
|
Json, Router,
|
||||||
};
|
};
|
||||||
|
use http::{HeaderMap, HeaderValue, StatusCode};
|
||||||
use rand::distributions::{Alphanumeric, DistString};
|
use rand::distributions::{Alphanumeric, DistString};
|
||||||
use sqlx::{Pool, Postgres, QueryBuilder};
|
use sqlx::{Pool, Postgres, QueryBuilder};
|
||||||
|
|
||||||
use crate::{model::Chat, state::AppState};
|
use crate::{markup_response::simple_error_page, model::Chat, state::AppState, ADMIN_TOK};
|
||||||
|
|
||||||
pub fn router(state: AppState) -> Router {
|
pub fn router(state: AppState) -> Router {
|
||||||
Router::new()
|
Router::new()
|
||||||
.route("/new/:amount", get(create))
|
.route("/new/:amount", get(create))
|
||||||
|
.nest("/stat", stat::router(state.clone()))
|
||||||
|
.route_layer(middleware::from_fn_with_state(
|
||||||
|
state.clone(),
|
||||||
|
auth_middleware,
|
||||||
|
))
|
||||||
.with_state(state)
|
.with_state(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn auth_middleware(
|
||||||
|
State(state): State<AppState>,
|
||||||
|
headers: HeaderMap,
|
||||||
|
req: Request,
|
||||||
|
next: Next,
|
||||||
|
) -> Response {
|
||||||
|
let admin_tok = headers.get("x-admin-tok");
|
||||||
|
if headers.get("x-admin-tok") == Some(&HeaderValue::from_static(ADMIN_TOK)) {
|
||||||
|
let res = next.run(req).await;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
simple_error_page(StatusCode::UNAUTHORIZED).into_response()
|
||||||
|
}
|
||||||
|
|
||||||
|
mod stat {
|
||||||
|
use axum::{extract::State, routing::get, Json, Router};
|
||||||
|
|
||||||
|
use crate::{model::Chat, state::AppState};
|
||||||
|
|
||||||
|
// TODO: /stat/* should require authentication
|
||||||
|
pub fn router(state: AppState) -> Router<AppState> {
|
||||||
|
Router::new().route("/chats", get(chats)).with_state(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn chats(State(state): State<AppState>) -> Json<Vec<Chat>> {
|
||||||
|
let r = sqlx::query_as!(Chat, "select * from chats;")
|
||||||
|
.fetch_all(state.pool())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Json(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn create(Path(amount): Path<u8>, State(state): State<AppState>) -> Json<Vec<Chat>> {
|
async fn create(Path(amount): Path<u8>, State(state): State<AppState>) -> Json<Vec<Chat>> {
|
||||||
let paths: Vec<String> = (0..amount)
|
let paths: Vec<String> = (0..amount)
|
||||||
.map(|_| Alphanumeric.sample_string(&mut rand::thread_rng(), 6))
|
.map(|_| Alphanumeric.sample_string(&mut rand::thread_rng(), 6))
|
||||||
|
|
|
@ -10,7 +10,6 @@ mod admin;
|
||||||
mod chat;
|
mod chat;
|
||||||
mod markup_response;
|
mod markup_response;
|
||||||
mod model;
|
mod model;
|
||||||
mod stat;
|
|
||||||
mod state;
|
mod state;
|
||||||
mod ws;
|
mod ws;
|
||||||
|
|
||||||
|
@ -28,7 +27,6 @@ async fn main() -> anyhow::Result<()> {
|
||||||
.route("/:path", get(chat::get).post(chat::post))
|
.route("/:path", get(chat::get).post(chat::post))
|
||||||
.route("/poll/:msg", get(chat::poll))
|
.route("/poll/:msg", get(chat::poll))
|
||||||
.with_state(state.clone())
|
.with_state(state.clone())
|
||||||
.nest("/stat", stat::router(state.clone()))
|
|
||||||
.nest("/admin", admin::router(state.clone()))
|
.nest("/admin", admin::router(state.clone()))
|
||||||
.nest("/static", axum_static::static_router("static"));
|
.nest("/static", axum_static::static_router("static"));
|
||||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await.unwrap();
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await.unwrap();
|
||||||
|
|
|
@ -4,17 +4,3 @@ use axum::{extract::State, routing::get, Json, Router};
|
||||||
use sqlx::{types::Uuid, Pool, Postgres};
|
use sqlx::{types::Uuid, Pool, Postgres};
|
||||||
|
|
||||||
use crate::{model::Chat, state::AppState};
|
use crate::{model::Chat, state::AppState};
|
||||||
|
|
||||||
// TODO: /stat/* should require authentication
|
|
||||||
pub fn router(state: AppState) -> Router {
|
|
||||||
Router::new().route("/chats", get(chats)).with_state(state)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn chats(State(state): State<AppState>) -> Json<Vec<Chat>> {
|
|
||||||
let r = sqlx::query_as!(Chat, "select * from chats;")
|
|
||||||
.fetch_all(state.pool())
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
Json(r)
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue