Adds basic structure

This commit is contained in:
2026-07-05 10:24:47 +02:00
parent ee79500c87
commit aef4abc72c
4 changed files with 139 additions and 2 deletions
+47
View File
@@ -0,0 +1,47 @@
use rocket::fairing::{Fairing, Info, Kind};
use rocket::http::{Header, Status};
use rocket::request::{FromRequest, Outcome};
use rocket::{Request, Response};
use std::env;
pub struct Authenticated;
#[rocket::async_trait]
impl<'r> FromRequest<'r> for Authenticated {
type Error = ();
async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error> {
let token = req.headers().get_one("Authorization");
if let Some(token) = token {
if token == env::var("API_KEY").unwrap().as_str() {
Outcome::Success(Authenticated)
} else {
Outcome::Error((Status::Unauthorized, ()))
}
} else {
Outcome::Error((Status::Unauthorized, ()))
}
}
}
pub struct CORS;
#[rocket::async_trait]
impl Fairing for CORS {
fn info(&self) -> Info {
Info {
name: "Add CORS headers to responses",
kind: Kind::Response,
}
}
async fn on_response<'r>(&self, _request: &'r Request<'_>, response: &mut Response<'r>) {
response.set_header(Header::new("Access-Control-Allow-Origin", "*"));
response.set_header(Header::new(
"Access-Control-Allow-Methods",
"GET, POST, PUT, PATCH, DELETE, OPTIONS",
));
response.set_header(Header::new("Access-Control-Allow-Headers", "*"));
response.set_header(Header::new("Access-Control-Allow-Credentials", "true"));
}
}
+62 -2
View File
@@ -1,5 +1,65 @@
mod auth;
mod models;
mod schema; mod schema;
fn main() { #[macro_use]
println!("Hello, world!"); extern crate rocket;
extern crate fern;
extern crate log;
use auth::CORS;
use chrono::Local;
use diesel::{Connection, PgConnection};
use models::AppState;
use rocket::State;
use std::env;
use std::str::FromStr;
fn setup_logging(log_file: Option<String>) -> Result<(), fern::InitError> {
let level_raw = env::var("LOG_LEVEL").unwrap_or("INFO".to_string());
let level = log::LevelFilter::from_str(&level_raw).expect("LOG_LEVEL invalid");
let log = fern::Dispatch::new()
.format(|out, message, record| {
out.finish(format_args!(
"{} {} [{}] {}",
Local::now().format("%Y-%m-%d %H:%M:%S"),
record.level(),
record.target(),
message
))
})
.level(level)
.chain(std::io::stdout());
if let Some(log_file) = log_file {
log.chain(fern::log_file(log_file)?).apply()?;
} else {
log.apply()?;
}
Ok(())
}
#[get("/")]
fn index(state: &State<AppState>) -> String {
"Hello world!".to_string()
}
#[launch]
fn rocket() -> _ {
dotenv::dotenv().ok();
let log_file = env::var("LOG_FILE").ok();
setup_logging(log_file).expect("Failed to setup logging");
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
let db = PgConnection::establish(&database_url)
.expect(&format!("Error connecting to {}", database_url));
let app_data = AppState::new(db);
rocket::build()
.manage(app_data)
.attach(CORS {})
.mount("/", routes![index])
} }
+14
View File
@@ -0,0 +1,14 @@
use chrono::NaiveDateTime;
use diesel::{Queryable, Selectable};
use uuid::Uuid;
#[derive(Queryable, Selectable)]
#[diesel(table_name = crate::schema::actions)]
#[diesel(check_for_backend(diesel::pg::Pg))]
pub struct Action {
pub id: Uuid,
pub name: String,
pub source: String,
pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime,
}
+16
View File
@@ -0,0 +1,16 @@
use diesel::PgConnection;
use std::sync::{Arc, Mutex};
mod action;
pub struct AppState {
pub db: Arc<Mutex<PgConnection>>,
}
impl AppState {
pub fn new(db: PgConnection) -> Self {
Self {
db: Arc::new(Mutex::new(db)),
}
}
}