update rocket

main
Hannaeko 2022-04-22 19:16:57 +02:00
parent ede7a46a59
commit 06caf83e05
10 changed files with 776 additions and 591 deletions

1281
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
name = "nomilo"
version = "0.1.0-dev"
authors = ["Gaël Berthaud-Müller <blacksponge@tuta.io>"]
edition = "2018"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -11,8 +11,8 @@ trust-dns-client = "0.20.1"
trust-dns-proto = "0.20.1"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
rocket = { git = "https://github.com/SergioBenitez/Rocket", rev = "0654890", version = "0.5.0-dev" }
rocket_contrib = { git = "https://github.com/SergioBenitez/Rocket", rev = "0654890", default-features = false, features = ["json", "diesel_sqlite_pool"], version = "0.5.0-dev"}
rocket = { git = "https://github.com/SergioBenitez/Rocket", rev = "6bdd2f8", version = "0.5.0-rc.1", features = ["json"] }
rocket_sync_db_pools = { git = "https://github.com/SergioBenitez/Rocket", rev = "6bdd2f8", default-features = false, features = ["diesel_sqlite_pool"], version = "0.1.0-rc.1"}
toml = "0.5"
base64 = "0.13.0"
uuid = { version = "0.8.2", features = ["v4", "serde"] }

View File

@ -8,12 +8,12 @@ use chrono::Duration;
#[derive(Debug, Deserialize)]
pub struct Config {
pub dns: DnsConfig,
pub dns: DnsClientConfig,
pub web_app: WebAppConfig,
}
#[derive(Debug, Deserialize)]
pub struct DnsConfig {
pub struct DnsClientConfig {
pub server: SocketAddr
}

View File

@ -1,7 +1,9 @@
use std::{future::Future, pin::Pin, task::{Context, Poll}};
use std::net::SocketAddr;
use std::ops::{Deref, DerefMut};
use rocket::{Request, State, http::Status, request::{FromRequest, Outcome}};
use rocket::outcome::try_outcome;
use tokio::{net::TcpStream as TokioTcpStream, task};
use trust_dns_client::{client::AsyncClient, error::ClientError, op::DnsResponse, tcp::TcpClientStream};
use trust_dns_proto::error::ProtoError;
@ -10,7 +12,6 @@ use trust_dns_proto::iocompat::AsyncIoTokioAsStd;
use crate::config::Config;
pub struct DnsClient(AsyncClient);
impl Deref for DnsClient {
@ -27,27 +28,33 @@ impl DerefMut for DnsClient {
}
}
#[rocket::async_trait]
impl<'r> FromRequest<'r> for DnsClient {
type Error = ();
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
let config = try_outcome!(request.guard::<State<Config>>().await);
let (stream, handle) = TcpClientStream::<AsyncIoTokioAsStd<TokioTcpStream>>::new(config.dns.server);
impl DnsClient {
pub async fn new(addr: SocketAddr) -> Result<Self, ProtoError> {
let (stream, handle) = TcpClientStream::<AsyncIoTokioAsStd<TokioTcpStream>>::new(addr);
let client = AsyncClient::with_timeout(
stream,
handle,
std::time::Duration::from_secs(5),
None);
let (client, bg) = match client.await {
let (client, bg) = client.await?;
task::spawn(bg);
return Ok(DnsClient(client))
}
}
#[rocket::async_trait]
impl<'r> FromRequest<'r> for DnsClient {
type Error = ();
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
let config = try_outcome!(request.guard::<&State<Config>>().await);
match DnsClient::new(config.dns.server).await {
Err(e) => {
println!("Failed to connect to DNS server {:#?}", e);
return Outcome::Failure((Status::InternalServerError, ()))
Outcome::Failure((Status::InternalServerError, ()))
},
Ok(c) => c
};
task::spawn(bg);
Outcome::Success(DnsClient(client))
Ok(c) => Outcome::Success(c)
}
}
}

View File

@ -1,7 +1,6 @@
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use] extern crate rocket;
#[macro_use] extern crate rocket_contrib;
#[macro_use] extern crate diesel;
mod models;
@ -12,17 +11,18 @@ mod dns;
use routes::users::*;
use routes::zones::*;
use rocket_sync_db_pools::database;
#[database("db")]
pub struct DbConn(diesel::SqliteConnection);
#[launch]
async fn rocket() -> rocket::Rocket {
async fn rocket() -> _ {
let app_config = config::load("config.toml".into());
println!("{:#?}", app_config);
rocket::ignite()
rocket::build()
.manage(app_config)
.attach(DbConn::fairing())
.mount("/api/v1", routes![

View File

@ -1,8 +1,9 @@
use serde::Serialize;
use serde_json::json;
use rocket::http::Status;
use rocket::request::{Request, Outcome};
use rocket::response::{self, Response, Responder};
use rocket_contrib::json::Json;
use rocket::serde::json::Json;
use serde_json::Value;
use djangohashers::{HasherError};
use diesel::result::Error as DieselError;
@ -50,8 +51,8 @@ pub struct ErrorResponse {
#[serde(remote = "Status")]
struct StatusDef {
code: u16,
#[serde(rename = "status")]
reason: &'static str,
#[serde(rename = "status", getter = "Status::reason")]
reason: Option<&'static str>,
}
impl ErrorResponse {

View File

@ -95,7 +95,7 @@ pub enum RData {
},
// ZERO,
// TODO: DS
// TODO: DS (added in https://github.com/bluejekyll/trust-dns/pull/1635)
// TODO: TLSA
}
@ -254,7 +254,7 @@ impl TryFrom<RData> for dns::RData {
struct CAAValue<'a>(&'a dns::caa::Value);
// trust_dns Display implementation panics if no parameters
// trust_dns Display implementation panics if no parameters (fixed in https://github.com/bluejekyll/trust-dns/pull/1631)
// Implementation based on caa::emit_value
// Also the quotes are strips to render in JSON
impl<'a> fmt::Display for CAAValue<'a> {

View File

@ -3,6 +3,7 @@ use diesel::prelude::*;
use diesel::result::Error as DieselError;
use diesel_derive_enum::DbEnum;
use rocket::{State, request::{FromRequest, Request, Outcome}};
use rocket::outcome::try_outcome;
use serde::{Deserialize};
// TODO: Maybe just use argon2 crate directly
use djangohashers::{make_password_with_algorithm, check_password, Algorithm};
@ -129,7 +130,7 @@ impl<'r> FromRequest<'r> for UserInfo {
return ErrorResponse::from(UserError::MalformedHeader).into()
};
let config = try_outcome!(request.guard::<State<Config>>().await.map_failure(make_500));
let config = try_outcome!(request.guard::<&State<Config>>().await.map_failure(make_500));
let conn = try_outcome!(request.guard::<DbConn>().await.map_failure(make_500));
let token_data = AuthClaims::decode(

View File

@ -1,5 +1,5 @@
use rocket_contrib::json::Json;
use rocket::{Response, State};
use rocket::serde::json::Json;
use rocket::State;
use rocket::http::Status;
use crate::config::Config;
@ -10,7 +10,7 @@ use crate::models;
#[post("/users/me/token", data = "<auth_request>")]
pub async fn create_auth_token(
conn: DbConn,
config: State<'_, Config>,
config: &State<Config>,
auth_request: Json<models::AuthTokenRequest>
) -> Result<Json<models::AuthTokenResponse>, models::ErrorResponse> {
@ -26,13 +26,11 @@ pub async fn create_auth_token(
}
#[post("/users", data = "<user_request>")]
pub async fn create_user<'r>(conn: DbConn, user_request: Json<models::CreateUserRequest>) -> Result<Response<'r>, models::ErrorResponse> {
pub async fn create_user<'r>(conn: DbConn, user_request: Json<models::CreateUserRequest>) -> Result<Status, models::ErrorResponse> {
// TODO: Check current user if any to check if user has permission to create users (with or without role)
conn.run(|c| {
models::LocalUser::create_user(&c, user_request.into_inner())
}).await?;
Response::build()
.status(Status::Created)
.ok()
Ok(Status::Created)
}

View File

@ -1,7 +1,6 @@
use rocket::Response;
use rocket::http::Status;
use rocket_contrib::json::Json;
use rocket::serde::json::Json;
use crate::DbConn;
use crate::dns::{DnsClient, DnsConnectorClient, RecordConnector, ZoneConnector};
@ -176,7 +175,7 @@ pub async fn add_member_to_zone<'r>(
zone: models::AbsoluteName,
user_info: Result<models::UserInfo, models::ErrorResponse>,
zone_member_request: Json<models::AddZoneMemberRequest>
) -> Result<Response<'r>, models::ErrorResponse> {
) -> Result<Status, models::ErrorResponse> {
let user_info = user_info?;
let zone_name = zone.to_utf8();
@ -191,7 +190,5 @@ pub async fn add_member_to_zone<'r>(
zone.add_member(&c, &new_member)
}).await?;
Response::build()
.status(Status::Created) // TODO: change this?
.ok()
Ok(Status::Created) // TODO: change this?
}