database connectivity
This commit is contained in:
parent
83982551ca
commit
757d324db6
|
@ -0,0 +1 @@
|
||||||
|
target
|
File diff suppressed because it is too large
Load Diff
|
@ -9,3 +9,8 @@ edition = "2021"
|
||||||
rocket = { version = "0.5.0-rc.2", features = ["json"] }
|
rocket = { version = "0.5.0-rc.2", features = ["json"] }
|
||||||
base64 = "0.21.0"
|
base64 = "0.21.0"
|
||||||
log = "0.4.17"
|
log = "0.4.17"
|
||||||
|
sqlx = { version = "0.6", features = [ "runtime-tokio-native-tls" , "postgres" ] }
|
||||||
|
tokio = { version = "1", features = ["full"] }
|
||||||
|
toml = "0.7.1"
|
||||||
|
serde = "1.0.152"
|
||||||
|
dotenvy = "0.15.6"
|
|
@ -0,0 +1,2 @@
|
||||||
|
listen_port = 8000
|
||||||
|
db_url = "postgres://postgres@localhost/trifidapi"
|
|
@ -0,0 +1,7 @@
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct TFConfig {
|
||||||
|
pub listen_port: u16,
|
||||||
|
pub db_url: String
|
||||||
|
}
|
|
@ -1,12 +1,23 @@
|
||||||
use rocket::{routes, post};
|
use std::error::Error;
|
||||||
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
|
use dotenvy::dotenv;
|
||||||
|
use log::{error, info};
|
||||||
|
use rocket::{routes, post, State, Rocket, Ignite};
|
||||||
use rocket::{serde::Serialize};
|
use rocket::{serde::Serialize};
|
||||||
use rocket::http::{ContentType, Status};
|
use rocket::http::{ContentType, Status};
|
||||||
use rocket::serde::Deserialize;
|
use rocket::serde::Deserialize;
|
||||||
use rocket::serde::json::Json;
|
use rocket::serde::json::Json;
|
||||||
|
use sqlx::migrate::Migrator;
|
||||||
|
use sqlx::PgPool;
|
||||||
|
use sqlx::postgres::PgPoolOptions;
|
||||||
|
use crate::config::TFConfig;
|
||||||
use crate::format::{validate_dh_pubkey_base64, validate_ed_pubkey_base64};
|
use crate::format::{validate_dh_pubkey_base64, validate_ed_pubkey_base64};
|
||||||
|
|
||||||
pub mod format;
|
pub mod format;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
|
pub mod db;
|
||||||
|
pub mod config;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
#[serde(crate = "rocket::serde")]
|
#[serde(crate = "rocket::serde")]
|
||||||
|
@ -63,7 +74,7 @@ pub const ERR_MSG_MALFORMED_REQUEST: &str = "unable to parse the request body -
|
||||||
pub const ERR_MSG_MALFORMED_REQUEST_CODE: &str = "ERR_MALFORMED_REQUEST";
|
pub const ERR_MSG_MALFORMED_REQUEST_CODE: &str = "ERR_MALFORMED_REQUEST";
|
||||||
|
|
||||||
#[post("/v2/enroll", data = "<request>")]
|
#[post("/v2/enroll", data = "<request>")]
|
||||||
fn enroll_endpoint(request: String) -> Result<(ContentType, Json<EnrollResponse>), (Status, Json<APIError>)> {
|
fn enroll_endpoint(request: String, pool: &State<PgPool>) -> Result<(ContentType, Json<EnrollResponse>), (Status, Json<APIError>)> {
|
||||||
let request: EnrollRequest = match rocket::serde::json::from_str(request.as_str()) {
|
let request: EnrollRequest = match rocket::serde::json::from_str(request.as_str()) {
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -94,8 +105,72 @@ fn dnclient_endpoint() -> &'static str {
|
||||||
"DNClient functionality is not yet implemented"
|
"DNClient functionality is not yet implemented"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MIGRATOR: Migrator = sqlx::migrate!();
|
||||||
|
|
||||||
#[rocket::main]
|
#[rocket::main]
|
||||||
async fn main() {
|
async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let _ = rocket::build().mount("/", routes![enroll_endpoint, dnclient_endpoint]).launch().await;
|
let _ = rocket::build();
|
||||||
|
|
||||||
|
info!("[tfapi] loading config");
|
||||||
|
|
||||||
|
let _ = dotenv();
|
||||||
|
|
||||||
|
if std::env::var("CONFIG_FILE").is_err() && !Path::new("config.toml").exists() {
|
||||||
|
error!("[tfapi] fatal: the environment variable CONFIG_FILE is not set");
|
||||||
|
error!("[tfapi] help: try creating a .env file that sets it");
|
||||||
|
error!("[tfapi] help: or, create a file config.toml with your config, as it is loaded automatically");
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let config_file;
|
||||||
|
if Path::new("config.toml").exists() {
|
||||||
|
config_file = "config.toml".to_string();
|
||||||
|
} else {
|
||||||
|
config_file = std::env::var("CONFIG_FILE").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let config_data = match fs::read_to_string(&config_file) {
|
||||||
|
Ok(d) => d,
|
||||||
|
Err(e) => {
|
||||||
|
error!("[tfapi] fatal: unable to read config from {}", config_file);
|
||||||
|
error!("[tfapi] fatal: {}", e);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let config: TFConfig = match toml::from_str(&config_data) {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(e) => {
|
||||||
|
error!("[tfapi] fatal: unable to parse config from {}", config_file);
|
||||||
|
error!("[tfapi] fatal: {}", e);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
info!("[tfapi] connecting to database pool");
|
||||||
|
|
||||||
|
let pool = match PgPoolOptions::new().max_connections(5).connect(&config.db_url).await {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(e) => {
|
||||||
|
error!("[tfapi] fatal: unable to connect to database pool");
|
||||||
|
error!("[tfapi] fatal: {}", e);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
info!("[tfapi] running database migrations");
|
||||||
|
|
||||||
|
MIGRATOR.run(&pool).await?;
|
||||||
|
|
||||||
|
info!("[tfapi] building rocket config");
|
||||||
|
|
||||||
|
let figment = rocket::Config::figment().merge(("port", config.listen_port));
|
||||||
|
|
||||||
|
let _ = rocket::custom(figment)
|
||||||
|
.mount("/", routes![enroll_endpoint, dnclient_endpoint])
|
||||||
|
.manage(pool)
|
||||||
|
.manage(config)
|
||||||
|
.launch().await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
Loading…
Reference in New Issue