initial config schema

This commit is contained in:
Quentin Gliech
2021-07-16 11:19:03 +02:00
parent 555b659df9
commit ad136e757d
8 changed files with 100 additions and 32 deletions

44
Cargo.lock generated
View File

@@ -908,6 +908,12 @@ version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0"
[[package]]
name = "dyn-clone"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf"
[[package]]
name = "either"
version = "1.6.1"
@@ -1496,6 +1502,7 @@ dependencies = [
"figment",
"mime",
"oauth2-types",
"schemars",
"serde",
"serde_with",
"sqlx",
@@ -2059,6 +2066,32 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "schemars"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc6ab463ae35acccb5cba66c0084c985257b797d288b6050cc2f6ac1b266cb78"
dependencies = [
"chrono",
"dyn-clone",
"schemars_derive",
"serde",
"serde_json",
"url",
]
[[package]]
name = "schemars_derive"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "902fdfbcf871ae8f653bddf4b2c05905ddaabc08f69d32a915787e3be0d31356"
dependencies = [
"proc-macro2",
"quote",
"serde_derive_internals",
"syn",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
@@ -2110,6 +2143,17 @@ dependencies = [
"syn",
]
[[package]]
name = "serde_derive_internals"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.64"

View File

@@ -25,3 +25,4 @@ tide-tracing = "0.0.11"
mime = "0.3.16"
sqlx = { version = "0.5.5", features = ["runtime-async-std-rustls", "postgres", "migrate", "chrono"] }
serde_with = { version = "1.9.4", features = ["hex", "chrono"] }
schemars = { version = "0.8.3", features = ["url", "chrono"] }

View File

@@ -15,7 +15,8 @@
use std::time::Duration;
use csrf::{AesGcmCsrfProtection, CsrfProtection};
use serde::Deserialize;
use schemars::{gen::SchemaGenerator, schema::Schema, JsonSchema};
use serde::{Deserialize, Serialize};
use serde_with::serde_as;
use tide::Middleware;
@@ -29,21 +30,31 @@ fn default_cookie_name() -> String {
"csrf".to_string()
}
fn key_schema(gen: &mut SchemaGenerator) -> Schema {
String::json_schema(gen)
}
fn ttl_schema(gen: &mut SchemaGenerator) -> Schema {
u64::json_schema(gen)
}
#[serde_as]
#[derive(Debug, Clone, Deserialize)]
pub struct Config {
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct CsrfConfig {
#[schemars(schema_with = "key_schema")]
#[serde_as(as = "serde_with::hex::Hex")]
key: [u8; 32],
#[serde(default = "default_cookie_name")]
cookie_name: String,
#[schemars(schema_with = "ttl_schema")]
#[serde(default = "default_ttl")]
#[serde_as(as = "serde_with::DurationSeconds<u64>")]
ttl: Duration,
}
impl Config {
impl CsrfConfig {
pub fn into_protection(self) -> impl CsrfProtection {
AesGcmCsrfProtection::from_key(self.key)
}

View File

@@ -14,7 +14,9 @@
use std::time::Duration;
use serde::Deserialize;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
use sqlx::postgres::{PgPool, PgPoolOptions};
fn default_uri() -> String {
@@ -39,7 +41,7 @@ fn default_max_lifetime() -> Option<Duration> {
Some(Duration::from_secs(30 * 60))
}
impl Default for Config {
impl Default for DatabaseConfig {
fn default() -> Self {
Self {
uri: default_uri(),
@@ -52,8 +54,9 @@ impl Default for Config {
}
}
#[derive(Debug, Deserialize)]
pub struct Config {
#[skip_serializing_none]
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct DatabaseConfig {
#[serde(default = "default_uri")]
uri: String,
@@ -73,7 +76,7 @@ pub struct Config {
max_lifetime: Option<Duration>,
}
impl Config {
impl DatabaseConfig {
#[tracing::instrument(err)]
pub async fn connect(&self) -> Result<PgPool, sqlx::Error> {
PgPoolOptions::new()

View File

@@ -12,21 +12,22 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use serde::Deserialize;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
fn default_http_address() -> String {
"[::]:8080".into()
}
#[derive(Debug, Deserialize)]
pub struct Config {
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct HttpConfig {
#[serde(default = "default_http_address")]
pub address: String,
}
impl Default for Config {
impl Default for HttpConfig {
fn default() -> Self {
Config {
Self {
address: default_http_address(),
}
}

View File

@@ -17,7 +17,8 @@ use figment::{
providers::{Env, Format, Yaml},
Figment,
};
use serde::Deserialize;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
mod csrf;
mod database;
@@ -26,14 +27,14 @@ mod oauth2;
mod session;
pub use self::{
csrf::Config as CsrfConfig,
database::Config as DatabaseConfig,
http::Config as HttpConfig,
oauth2::{ClientConfig as OAuth2ClientConfig, Config as OAuth2Config},
session::Config as SessionConfig,
csrf::CsrfConfig,
database::DatabaseConfig,
http::HttpConfig,
oauth2::{OAuth2ClientConfig, OAuth2Config},
session::SessionConfig,
};
#[derive(Debug, Deserialize)]
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct RootConfig {
#[serde(default)]
pub oauth2: OAuth2Config,

View File

@@ -12,11 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use serde::Deserialize;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use url::Url;
#[derive(Debug, Deserialize)]
pub struct ClientConfig {
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct OAuth2ClientConfig {
pub client_id: String,
#[serde(default)]
@@ -27,16 +28,16 @@ fn default_oauth2_issuer() -> Url {
"http://[::]:8080".parse().unwrap()
}
#[derive(Debug, Deserialize)]
pub struct Config {
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct OAuth2Config {
#[serde(default = "default_oauth2_issuer")]
pub issuer: Url,
#[serde(default)]
pub clients: Vec<ClientConfig>,
pub clients: Vec<OAuth2ClientConfig>,
}
impl Default for Config {
impl Default for OAuth2Config {
fn default() -> Self {
Self {
issuer: default_oauth2_issuer(),

View File

@@ -12,21 +12,27 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use serde::Deserialize;
use schemars::{gen::SchemaGenerator, schema::Schema, JsonSchema};
use serde::{Deserialize, Serialize};
use serde_with::serde_as;
use tide::{
sessions::{SessionMiddleware, SessionStore},
Middleware,
};
fn secret_schema(gen: &mut SchemaGenerator) -> Schema {
String::json_schema(gen)
}
#[serde_as]
#[derive(Debug, Deserialize)]
pub struct Config {
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct SessionConfig {
#[schemars(schema_with = "secret_schema")]
#[serde_as(as = "serde_with::hex::Hex")]
secret: Vec<u8>,
}
impl Config {
impl SessionConfig {
pub fn to_middleware<State: Clone + Send + Sync + 'static>(
&self,
store: impl SessionStore,