Skip to content

Commit

Permalink
use rocket's built-in config infrastructure
Browse files Browse the repository at this point in the history
  • Loading branch information
huangcheng committed Nov 28, 2023
1 parent fadf5d5 commit f3dbec4
Show file tree
Hide file tree
Showing 13 changed files with 59 additions and 25 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ bcrypt = "0.15.0"
chrono = { version = "0.4.31", features = ["serde"] }
cookie = "0.18.0"
derive_more = "0.99.17"
dotenvy = "0.15.7"
fern = "0.6.2"
hashes = "0.1.9"
jsonwebtoken = { version = "9.1.0", default-features = false }
log = "0.4.20"
regex = "1.10.2"
Expand Down
27 changes: 16 additions & 11 deletions src/bin/server.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use dotenvy::dotenv;
use rocket::fairing::AdHoc;
use rocket::figment::providers::{Format, Serialized, Toml};
use rocket::figment::{Figment, Profile};
use rocket::{self, routes};
use rocket_db_pools::Database;
use startpage::config::Config;

use startpage::routes::upload::upload;
use startpage::routes::{auth, category, site, user};
Expand Down Expand Up @@ -40,20 +43,21 @@ async fn main() -> Result<(), rocket::Error> {
setup_logger().expect("Failed to setup logger");
}

dotenv().expect("Failed to read .env file");
let figment = Figment::from(rocket::Config::default())
.merge(Serialized::defaults(Config::default()))
.merge(Toml::file("Rocket.toml").nested())
.select(Profile::from_env_or("ROCKET_PROFILE", "default"));

let jwt_secret = std::env::var("JWT_SECRET").expect("JWT_SECRET");
let config = figment
.extract::<Config>()
.expect("Failed to extract app config");

let jwt_expire_in = std::env::var("JWT_EXPIRES_IN").expect("JWT_EXPIRES_IN");
let jwt_expiration =
calculate_expires(&config.jwt.expires_in).expect("Failed to parse duration");

let jwt_expiration = calculate_expires(&jwt_expire_in).expect("Failed to calculate expires");
let state = AppState { jwt_expiration };

let state = AppState {
jwt_secret,
jwt_expiration,
};

let _rok = rocket::build()
let _rok = rocket::custom(figment)
.manage(state)
.attach(Db::init())
.mount(
Expand All @@ -74,6 +78,7 @@ async fn main() -> Result<(), rocket::Error> {
.mount("/api/sites", routes![site::all])
.mount("/api/site", routes![site::add, site::update, site::delete])
.mount("/api/upload", routes![upload])
.attach(AdHoc::config::<Config>())
.launch()
.await?;

Expand Down
21 changes: 21 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub struct Jwt {
pub secret: String,
pub expires_in: String,
}

impl Default for Jwt {
fn default() -> Self {
Self {
secret: String::from("StartPage"),
expires_in: String::from("1h"),
}
}
}

#[derive(Debug, Default, Serialize, Deserialize)]
pub struct Config {
pub jwt: Jwt,
}
1 change: 1 addition & 0 deletions src/handlers.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod auth;
pub mod category;
pub mod site;
mod upload;
pub mod user;
4 changes: 3 additions & 1 deletion src/handlers/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use log::error;
use rocket_db_pools::Connection;
use sqlx::query_as;

use crate::config::Config;
use crate::errors::ServiceError;
use crate::request;
use crate::state::AppState;
Expand All @@ -13,6 +14,7 @@ use crate::{models, Db};
pub async fn login(
user: &request::auth::User<'_>,
state: &AppState,
config: &Config,
db: &mut Connection<Db>,
) -> Result<String, ServiceError> {
let record = query_as::<_, models::user::User>(
Expand Down Expand Up @@ -43,7 +45,7 @@ pub async fn login(
let token = encode(
&Header::default(),
&claims,
&EncodingKey::from_secret(state.jwt_secret.as_bytes()),
&EncodingKey::from_secret(config.jwt.secret.as_bytes()),
)
.map_err(|e| {
error!("Failed to encode token: {}", e);
Expand Down
2 changes: 0 additions & 2 deletions src/handlers/category.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ use sqlx::{query, query_as, Row};

use crate::errors::ServiceError;
use crate::models::category::Category;
use crate::models::site::Site;
use crate::request::category::{CreateCategory, UpdateCategory};
use crate::request::site::{CreateSite, UpdateSite};
use crate::response;
use crate::response::WithTotal;
use crate::Db;
Expand Down
1 change: 1 addition & 0 deletions src/handlers/upload.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub mod models;
pub mod routes;
pub mod state;

pub mod config;
pub mod request;
pub mod response;
pub mod utils;
7 changes: 4 additions & 3 deletions src/middlewares.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation};
use rocket::http::Status;
use rocket::request::{FromRequest, Outcome};

use crate::config::Config;
use crate::Claims;

pub struct JwtMiddleware {
Expand All @@ -21,8 +22,8 @@ impl<'r> FromRequest<'r> for JwtMiddleware {
type Error = JwtError;

async fn from_request(request: &'r rocket::Request<'_>) -> Outcome<Self, Self::Error> {
let secret = match std::env::var("JWT_SECRET") {
Ok(secret) => secret,
let config = match request.rocket().figment().extract::<Config>() {
Ok(config) => config,
Err(_) => return Outcome::Error((Status::InternalServerError, JwtError::ConfigError)),
};

Expand All @@ -38,7 +39,7 @@ impl<'r> FromRequest<'r> for JwtMiddleware {

let token = match decode::<Claims>(
token,
&DecodingKey::from_secret(secret.as_bytes()),
&DecodingKey::from_secret(config.jwt.secret.as_bytes()),
&Validation::new(Algorithm::HS256),
) {
Ok(token) => token,
Expand Down
4 changes: 3 additions & 1 deletion src/routes/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use rocket::serde::json::Json;
use rocket::State;
use rocket_db_pools::Connection;

use crate::config::Config;
use crate::middlewares::JwtMiddleware;
use crate::request;
use crate::response;
Expand All @@ -18,9 +19,10 @@ use crate::{handlers, Db};
pub async fn login(
user: Json<request::auth::User<'_>>,
state: &State<AppState>,
config: &State<Config>,
mut db: Connection<Db>,
) -> Result<response::auth::JwtToken, Status> {
let token = handlers::auth::login(user.deref(), state, &mut db)
let token = handlers::auth::login(user.deref(), state, config, &mut db)
.await
.map_err(|e| {
error!("{}", e);
Expand Down
1 change: 0 additions & 1 deletion src/routes/category.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use crate::handlers::category::{
};
use crate::middlewares::JwtMiddleware;
use crate::request::category::{CreateCategory, UpdateCategory};
use crate::request::site::{CreateSite, UpdateSite};
use crate::response::category::Category;
use crate::response::site::Site;
use crate::response::WithTotal;
Expand Down
12 changes: 8 additions & 4 deletions src/routes/upload.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use rocket::form::DataField;
use crate::config::Config;
use rocket::form::Form;
use rocket::fs::TempFile;
use rocket::http::{ContentType, Status};
use rocket::http::Status;
use rocket::serde::json::Json;
use rocket::{post, Data, FromForm};
use rocket::{post, FromForm, State};

use crate::middlewares::JwtMiddleware;

Expand All @@ -14,7 +14,11 @@ pub struct Upload<'r> {
}

#[post("/", data = "<data>")]
pub async fn upload(data: Form<Upload<'_>>, _jwt: JwtMiddleware) -> Result<Json<String>, Status> {
pub async fn upload(
data: Form<Upload<'_>>,
config: &State<Config>,
_jwt: JwtMiddleware,
) -> Result<Json<String>, Status> {
println!("{:?}", data.file.content_type().unwrap().extension());
Ok(Json(String::from("Hello")))
}
1 change: 0 additions & 1 deletion src/state.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
pub struct AppState {
pub jwt_secret: String,
pub jwt_expiration: i64,
}

0 comments on commit f3dbec4

Please sign in to comment.