You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-31 09:24:31 +03:00
Switch to camino's Utf8Path* instead of std::path::Path*
This commit is contained in:
5
Cargo.lock
generated
5
Cargo.lock
generated
@ -2500,6 +2500,7 @@ dependencies = [
|
|||||||
"argon2",
|
"argon2",
|
||||||
"atty",
|
"atty",
|
||||||
"axum 0.6.0-rc.4",
|
"axum 0.6.0-rc.4",
|
||||||
|
"camino",
|
||||||
"clap",
|
"clap",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
@ -2549,6 +2550,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
"camino",
|
||||||
"chrono",
|
"chrono",
|
||||||
"figment",
|
"figment",
|
||||||
"indoc",
|
"indoc",
|
||||||
@ -2719,6 +2721,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
"camino",
|
||||||
"convert_case",
|
"convert_case",
|
||||||
"csv",
|
"csv",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
@ -2862,6 +2865,7 @@ name = "mas-static-files"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"axum 0.6.0-rc.4",
|
"axum 0.6.0-rc.4",
|
||||||
|
"camino",
|
||||||
"headers",
|
"headers",
|
||||||
"http",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
@ -2915,6 +2919,7 @@ name = "mas-templates"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"camino",
|
||||||
"chrono",
|
"chrono",
|
||||||
"mas-data-model",
|
"mas-data-model",
|
||||||
"mas-router",
|
"mas-router",
|
||||||
|
@ -9,4 +9,6 @@ disallowed-methods = [
|
|||||||
|
|
||||||
disallowed-types = [
|
disallowed-types = [
|
||||||
"rand::OsRng",
|
"rand::OsRng",
|
||||||
|
{ path = "std::path::PathBuf", reason = "use camino::Utf8PathBuf instead" },
|
||||||
|
{ path = "std::path::Path", reason = "use camino::Utf8Path instead" },
|
||||||
]
|
]
|
||||||
|
@ -10,6 +10,7 @@ anyhow = "1.0.66"
|
|||||||
argon2 = { version = "0.4.1", features = ["password-hash"] }
|
argon2 = { version = "0.4.1", features = ["password-hash"] }
|
||||||
atty = "0.2.14"
|
atty = "0.2.14"
|
||||||
axum = "0.6.0-rc.4"
|
axum = "0.6.0-rc.4"
|
||||||
|
camino = "1.1.1"
|
||||||
clap = { version = "4.0.26", features = ["derive"] }
|
clap = { version = "4.0.26", features = ["derive"] }
|
||||||
dotenv = "0.15.0"
|
dotenv = "0.15.0"
|
||||||
futures-util = "0.3.25"
|
futures-util = "0.3.25"
|
||||||
|
@ -12,9 +12,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
|
use camino::Utf8PathBuf;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use mas_config::ConfigurationSection;
|
use mas_config::ConfigurationSection;
|
||||||
|
|
||||||
@ -50,7 +49,7 @@ enum Subcommand {
|
|||||||
pub struct Options {
|
pub struct Options {
|
||||||
/// Path to the configuration file
|
/// Path to the configuration file
|
||||||
#[arg(short, long, global = true, action = clap::ArgAction::Append)]
|
#[arg(short, long, global = true, action = clap::ArgAction::Append)]
|
||||||
config: Vec<PathBuf>,
|
config: Vec<Utf8PathBuf>,
|
||||||
|
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
subcommand: Option<Subcommand>,
|
subcommand: Option<Subcommand>,
|
||||||
@ -78,7 +77,7 @@ impl Options {
|
|||||||
.unwrap_or_else(|_| "config.yaml".to_owned())
|
.unwrap_or_else(|_| "config.yaml".to_owned())
|
||||||
// Split the file list on `:`
|
// Split the file list on `:`
|
||||||
.split(':')
|
.split(':')
|
||||||
.map(PathBuf::from)
|
.map(Utf8PathBuf::from)
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
self.config.clone()
|
self.config.clone()
|
||||||
|
@ -12,8 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use camino::Utf8PathBuf;
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use mas_storage::Clock;
|
use mas_storage::Clock;
|
||||||
use mas_templates::Templates;
|
use mas_templates::Templates;
|
||||||
@ -29,7 +28,7 @@ enum Subcommand {
|
|||||||
/// Save the builtin templates to a folder
|
/// Save the builtin templates to a folder
|
||||||
Save {
|
Save {
|
||||||
/// Where the templates should be saved
|
/// Where the templates should be saved
|
||||||
path: PathBuf,
|
path: Utf8PathBuf,
|
||||||
|
|
||||||
/// Overwrite existing template files
|
/// Overwrite existing template files
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
|
@ -17,8 +17,6 @@
|
|||||||
#![warn(clippy::pedantic)]
|
#![warn(clippy::pedantic)]
|
||||||
#![allow(clippy::module_name_repetitions)]
|
#![allow(clippy::module_name_repetitions)]
|
||||||
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use mas_config::TelemetryConfig;
|
use mas_config::TelemetryConfig;
|
||||||
@ -44,7 +42,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
async fn try_main() -> anyhow::Result<()> {
|
async fn try_main() -> anyhow::Result<()> {
|
||||||
// Load environment variables from .env files
|
// Load environment variables from .env files
|
||||||
// We keep the path to log it afterwards
|
// We keep the path to log it afterwards
|
||||||
let dotenv_path: Result<Option<PathBuf>, _> = dotenv::dotenv()
|
let dotenv_path: Result<Option<_>, _> = dotenv::dotenv()
|
||||||
.map(Some)
|
.map(Some)
|
||||||
// Display the error if it is something other than the .env file not existing
|
// Display the error if it is something other than the .env file not existing
|
||||||
.or_else(|e| if e.not_found() { Ok(None) } else { Err(e) });
|
.or_else(|e| if e.not_found() { Ok(None) } else { Err(e) });
|
||||||
|
@ -60,7 +60,7 @@ where
|
|||||||
router.merge(mas_handlers::graphql_router::<AppState, B>(*playground))
|
router.merge(mas_handlers::graphql_router::<AppState, B>(*playground))
|
||||||
}
|
}
|
||||||
mas_config::HttpResource::Static { web_root } => {
|
mas_config::HttpResource::Static { web_root } => {
|
||||||
let handler = mas_static_files::service(web_root);
|
let handler = mas_static_files::service(web_root.as_deref());
|
||||||
router.nest_service(mas_router::StaticAsset::route(), handler)
|
router.nest_service(mas_router::StaticAsset::route(), handler)
|
||||||
}
|
}
|
||||||
mas_config::HttpResource::OAuth => {
|
mas_config::HttpResource::OAuth => {
|
||||||
@ -91,11 +91,8 @@ where
|
|||||||
"root": app_base,
|
"root": app_base,
|
||||||
});
|
});
|
||||||
|
|
||||||
let index_service = ViteManifestService::new(
|
let index_service =
|
||||||
manifest.clone().try_into().unwrap(),
|
ViteManifestService::new(manifest.clone(), assets_base.into(), config);
|
||||||
assets_base.into(),
|
|
||||||
config,
|
|
||||||
);
|
|
||||||
|
|
||||||
let static_service = ServeDir::new(assets).append_index_html_on_directories(false);
|
let static_service = ServeDir::new(assets).append_index_html_on_directories(false);
|
||||||
|
|
||||||
|
@ -13,11 +13,12 @@ async-trait = "0.1.58"
|
|||||||
thiserror = "1.0.37"
|
thiserror = "1.0.37"
|
||||||
anyhow = "1.0.66"
|
anyhow = "1.0.66"
|
||||||
|
|
||||||
schemars = { version = "0.8.11", features = ["url", "chrono"] }
|
camino = { version = "1.1.1", features = ["serde1"] }
|
||||||
figment = { version = "0.10.8", features = ["env", "yaml", "test"] }
|
|
||||||
chrono = { version = "0.4.23", features = ["serde"] }
|
chrono = { version = "0.4.23", features = ["serde"] }
|
||||||
url = { version = "2.3.1", features = ["serde"] }
|
figment = { version = "0.10.8", features = ["env", "yaml", "test"] }
|
||||||
|
schemars = { version = "0.8.11", features = ["url", "chrono"] }
|
||||||
ulid = { version = "1.0.0", features = ["serde"] }
|
ulid = { version = "1.0.0", features = ["serde"] }
|
||||||
|
url = { version = "2.3.1", features = ["serde"] }
|
||||||
|
|
||||||
serde = { version = "1.0.147", features = ["derive"] }
|
serde = { version = "1.0.147", features = ["derive"] }
|
||||||
serde_with = { version = "2.1.0", features = ["hex", "chrono"] }
|
serde_with = { version = "2.1.0", features = ["hex", "chrono"] }
|
||||||
|
@ -12,10 +12,11 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use std::{num::NonZeroU32, path::PathBuf, time::Duration};
|
use std::{num::NonZeroU32, time::Duration};
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use camino::Utf8PathBuf;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -85,7 +86,8 @@ enum ConnectConfig {
|
|||||||
|
|
||||||
/// Directory containing the UNIX socket to connect to
|
/// Directory containing the UNIX socket to connect to
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
socket: Option<PathBuf>,
|
#[schemars(with = "Option<String>")]
|
||||||
|
socket: Option<Utf8PathBuf>,
|
||||||
|
|
||||||
/// PostgreSQL user name to connect as
|
/// PostgreSQL user name to connect as
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
@ -12,10 +12,11 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use std::{borrow::Cow, io::Cursor, ops::Deref, path::PathBuf};
|
use std::{borrow::Cow, io::Cursor, ops::Deref};
|
||||||
|
|
||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use camino::Utf8PathBuf;
|
||||||
use mas_keystore::PrivateKey;
|
use mas_keystore::PrivateKey;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
@ -99,7 +100,8 @@ pub enum BindConfig {
|
|||||||
/// Listen on a UNIX domain socket
|
/// Listen on a UNIX domain socket
|
||||||
Unix {
|
Unix {
|
||||||
/// Path to the socket
|
/// Path to the socket
|
||||||
socket: PathBuf,
|
#[schemars(with = "String")]
|
||||||
|
socket: Utf8PathBuf,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Accept connections on file descriptors passed by the parent process.
|
/// Accept connections on file descriptors passed by the parent process.
|
||||||
@ -125,14 +127,16 @@ pub enum BindConfig {
|
|||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum KeyOrFile {
|
pub enum KeyOrFile {
|
||||||
Key(String),
|
Key(String),
|
||||||
KeyFile(PathBuf),
|
#[schemars(with = "String")]
|
||||||
|
KeyFile(Utf8PathBuf),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(JsonSchema, Serialize, Deserialize, Clone, Debug)]
|
#[derive(JsonSchema, Serialize, Deserialize, Clone, Debug)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum CertificateOrFile {
|
pub enum CertificateOrFile {
|
||||||
Certificate(String),
|
Certificate(String),
|
||||||
CertificateFile(PathBuf),
|
#[schemars(with = "String")]
|
||||||
|
CertificateFile(Utf8PathBuf),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Configuration related to TLS on a listener
|
/// Configuration related to TLS on a listener
|
||||||
@ -252,7 +256,8 @@ pub enum Resource {
|
|||||||
/// Path from which to serve static files. If not specified, it will
|
/// Path from which to serve static files. If not specified, it will
|
||||||
/// serve the static files embedded in the server binary
|
/// serve the static files embedded in the server binary
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
web_root: Option<PathBuf>,
|
#[schemars(with = "Option<String>")]
|
||||||
|
web_root: Option<Utf8PathBuf>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Mount a "/connection-info" handler which helps debugging informations on
|
/// Mount a "/connection-info" handler which helps debugging informations on
|
||||||
@ -263,10 +268,12 @@ pub enum Resource {
|
|||||||
/// Mount the single page app
|
/// Mount the single page app
|
||||||
Spa {
|
Spa {
|
||||||
/// Path to the vite manifest
|
/// Path to the vite manifest
|
||||||
manifest: PathBuf,
|
#[schemars(with = "String")]
|
||||||
|
manifest: Utf8PathBuf,
|
||||||
|
|
||||||
/// Path to the assets to server
|
/// Path to the assets to server
|
||||||
assets: PathBuf,
|
#[schemars(with = "String")]
|
||||||
|
assets: Utf8PathBuf,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,9 +12,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use camino::Utf8PathBuf;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -40,7 +39,8 @@ fn default_authorization_grant_endpoint() -> String {
|
|||||||
pub struct PolicyConfig {
|
pub struct PolicyConfig {
|
||||||
/// Path to the WASM module
|
/// Path to the WASM module
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub wasm_module: Option<PathBuf>,
|
#[schemars(with = "Option<String>")]
|
||||||
|
pub wasm_module: Option<Utf8PathBuf>,
|
||||||
|
|
||||||
/// Entrypoint to use when evaluating client registrations
|
/// Entrypoint to use when evaluating client registrations
|
||||||
#[serde(default = "default_client_registration_endpoint")]
|
#[serde(default = "default_client_registration_endpoint")]
|
||||||
|
@ -12,10 +12,11 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use std::{borrow::Cow, path::PathBuf};
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use camino::Utf8PathBuf;
|
||||||
use mas_jose::jwk::{JsonWebKey, JsonWebKeySet};
|
use mas_jose::jwk::{JsonWebKey, JsonWebKeySet};
|
||||||
use mas_keystore::{Encrypter, Keystore, PrivateKey};
|
use mas_keystore::{Encrypter, Keystore, PrivateKey};
|
||||||
use rand::{
|
use rand::{
|
||||||
@ -38,14 +39,16 @@ fn example_secret() -> &'static str {
|
|||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum KeyOrFile {
|
pub enum KeyOrFile {
|
||||||
Key(String),
|
Key(String),
|
||||||
KeyFile(PathBuf),
|
#[schemars(with = "String")]
|
||||||
|
KeyFile(Utf8PathBuf),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(JsonSchema, Serialize, Deserialize, Clone, Debug)]
|
#[derive(JsonSchema, Serialize, Deserialize, Clone, Debug)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum PasswordOrFile {
|
pub enum PasswordOrFile {
|
||||||
Password(String),
|
Password(String),
|
||||||
PasswordFile(PathBuf),
|
#[schemars(with = "String")]
|
||||||
|
PasswordFile(Utf8PathBuf),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(JsonSchema, Serialize, Deserialize, Clone, Debug)]
|
#[derive(JsonSchema, Serialize, Deserialize, Clone, Debug)]
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use camino::Utf8PathBuf;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -28,7 +29,8 @@ fn default_builtin() -> bool {
|
|||||||
pub struct TemplatesConfig {
|
pub struct TemplatesConfig {
|
||||||
/// Path to the folder that holds the custom templates
|
/// Path to the folder that holds the custom templates
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub path: Option<String>,
|
#[schemars(with = "Option<String>")]
|
||||||
|
pub path: Option<Utf8PathBuf>,
|
||||||
|
|
||||||
/// Load the templates embedded in the binary
|
/// Load the templates embedded in the binary
|
||||||
#[serde(default = "default_builtin")]
|
#[serde(default = "default_builtin")]
|
||||||
|
@ -12,10 +12,9 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use camino::Utf8Path;
|
||||||
use figment::{
|
use figment::{
|
||||||
error::Error as FigmentError,
|
error::Error as FigmentError,
|
||||||
providers::{Env, Format, Serialized, Yaml},
|
providers::{Env, Format, Serialized, Yaml},
|
||||||
@ -65,20 +64,20 @@ pub trait ConfigurationSection<'a>: Sized + Deserialize<'a> + Serialize {
|
|||||||
/// Load configuration from a list of files and environment variables.
|
/// Load configuration from a list of files and environment variables.
|
||||||
fn load_from_files<P>(paths: &[P]) -> Result<Self, FigmentError>
|
fn load_from_files<P>(paths: &[P]) -> Result<Self, FigmentError>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Utf8Path>,
|
||||||
{
|
{
|
||||||
let base = Figment::new().merge(Env::prefixed("MAS_").split("_"));
|
let base = Figment::new().merge(Env::prefixed("MAS_").split("_"));
|
||||||
|
|
||||||
paths
|
paths
|
||||||
.iter()
|
.iter()
|
||||||
.fold(base, |f, path| f.merge(Yaml::file(path)))
|
.fold(base, |f, path| f.merge(Yaml::file(path.as_ref())))
|
||||||
.extract_inner(Self::path())
|
.extract_inner(Self::path())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load configuration from a file and environment variables.
|
/// Load configuration from a file and environment variables.
|
||||||
fn load_from_file<P>(path: P) -> Result<Self, FigmentError>
|
fn load_from_file<P>(path: P) -> Result<Self, FigmentError>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Utf8Path>,
|
||||||
{
|
{
|
||||||
Self::load_from_files(&[path])
|
Self::load_from_files(&[path])
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ license = "Apache-2.0"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.66"
|
anyhow = "1.0.66"
|
||||||
async-trait = "0.1.58"
|
async-trait = "0.1.58"
|
||||||
|
camino = "1.1.1"
|
||||||
convert_case = "0.6.0"
|
convert_case = "0.6.0"
|
||||||
csv = "1.1.6"
|
csv = "1.1.6"
|
||||||
futures-util = "0.3.25"
|
futures-util = "0.3.25"
|
||||||
|
@ -16,8 +16,9 @@
|
|||||||
#![deny(clippy::all, clippy::str_to_string, rustdoc::broken_intra_doc_links)]
|
#![deny(clippy::all, clippy::str_to_string, rustdoc::broken_intra_doc_links)]
|
||||||
#![warn(clippy::pedantic)]
|
#![warn(clippy::pedantic)]
|
||||||
|
|
||||||
use std::{collections::HashMap, fmt::Display, path::PathBuf, sync::Arc};
|
use std::{collections::HashMap, fmt::Display, sync::Arc};
|
||||||
|
|
||||||
|
use camino::{Utf8Path, Utf8PathBuf};
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
use tokio::io::AsyncWriteExt;
|
use tokio::io::AsyncWriteExt;
|
||||||
use tracing::Level;
|
use tracing::Level;
|
||||||
@ -35,8 +36,8 @@ struct File {
|
|||||||
items: HashMap<&'static str, Vec<EnumMember>>,
|
items: HashMap<&'static str, Vec<EnumMember>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_path(relative: PathBuf) -> PathBuf {
|
fn resolve_path(relative: impl AsRef<Utf8Path>) -> Utf8PathBuf {
|
||||||
let crate_root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
let crate_root = Utf8Path::new(env!("CARGO_MANIFEST_DIR"));
|
||||||
let workspace_root = crate_root.parent().unwrap().parent().unwrap();
|
let workspace_root = crate_root.parent().unwrap().parent().unwrap();
|
||||||
workspace_root.join(relative)
|
workspace_root.join(relative)
|
||||||
}
|
}
|
||||||
@ -65,12 +66,12 @@ impl File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
async fn write(&self, path: PathBuf) -> anyhow::Result<()> {
|
async fn write(&self, path: impl AsRef<Utf8Path>) -> anyhow::Result<()> {
|
||||||
let mut file = tokio::fs::OpenOptions::new()
|
let mut file = tokio::fs::OpenOptions::new()
|
||||||
.create(true)
|
.create(true)
|
||||||
.truncate(true)
|
.truncate(true)
|
||||||
.write(true)
|
.write(true)
|
||||||
.open(path)
|
.open(path.as_ref())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
tracing::info!("Writing file");
|
tracing::info!("Writing file");
|
||||||
@ -180,8 +181,11 @@ pub enum {} {{"#,
|
|||||||
|
|
||||||
use self::traits::{EnumEntry, EnumMember, Section};
|
use self::traits::{EnumEntry, EnumMember, Section};
|
||||||
|
|
||||||
#[tracing::instrument(skip(client))]
|
#[tracing::instrument(skip_all, fields(%path))]
|
||||||
async fn generate_jose(client: &Arc<Client>, path: PathBuf) -> anyhow::Result<()> {
|
async fn generate_jose(
|
||||||
|
client: &Arc<Client>,
|
||||||
|
path: impl AsRef<Utf8Path> + std::fmt::Display,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
let path = resolve_path(path);
|
let path = resolve_path(path);
|
||||||
let client = client.clone();
|
let client = client.clone();
|
||||||
|
|
||||||
@ -208,8 +212,11 @@ async fn generate_jose(client: &Arc<Client>, path: PathBuf) -> anyhow::Result<()
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip(client))]
|
#[tracing::instrument(skip_all, fields(%path))]
|
||||||
async fn generate_oauth(client: &Arc<Client>, path: PathBuf) -> anyhow::Result<()> {
|
async fn generate_oauth(
|
||||||
|
client: &Arc<Client>,
|
||||||
|
path: impl AsRef<Utf8Path> + std::fmt::Display,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
let path = resolve_path(path);
|
let path = resolve_path(path);
|
||||||
let client = client.clone();
|
let client = client.clone();
|
||||||
|
|
||||||
@ -244,7 +251,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
let client = Client::builder().user_agent("iana-parser/0.0.1").build()?;
|
let client = Client::builder().user_agent("iana-parser/0.0.1").build()?;
|
||||||
let client = Arc::new(client);
|
let client = Arc::new(client);
|
||||||
|
|
||||||
let iana_crate_root = PathBuf::from("crates/iana/");
|
let iana_crate_root = Utf8Path::new("crates/iana/");
|
||||||
|
|
||||||
generate_jose(&client, iana_crate_root.join("src/jose.rs")).await?;
|
generate_jose(&client, iana_crate_root.join("src/jose.rs")).await?;
|
||||||
generate_oauth(&client, iana_crate_root.join("src/oauth.rs")).await?;
|
generate_oauth(&client, iana_crate_root.join("src/oauth.rs")).await?;
|
||||||
|
@ -10,6 +10,7 @@ dev = []
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
axum = { version = "0.6.0-rc.4", features = ["headers"] }
|
axum = { version = "0.6.0-rc.4", features = ["headers"] }
|
||||||
|
camino = "1.1.1"
|
||||||
headers = "0.3.8"
|
headers = "0.3.8"
|
||||||
http = "0.2.8"
|
http = "0.2.8"
|
||||||
http-body = "0.4.5"
|
http-body = "0.4.5"
|
||||||
|
@ -25,6 +25,9 @@
|
|||||||
|
|
||||||
#[cfg(not(feature = "dev"))]
|
#[cfg(not(feature = "dev"))]
|
||||||
mod builtin {
|
mod builtin {
|
||||||
|
// the RustEmbed derive uses std::path::Path
|
||||||
|
#![allow(clippy::disallowed_types)]
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
fmt::Write,
|
fmt::Write,
|
||||||
future::{ready, Ready},
|
future::{ready, Ready},
|
||||||
@ -127,25 +130,25 @@ mod builtin {
|
|||||||
|
|
||||||
#[cfg(feature = "dev")]
|
#[cfg(feature = "dev")]
|
||||||
mod builtin {
|
mod builtin {
|
||||||
use std::path::PathBuf;
|
use camnio::Utf8Path;
|
||||||
|
|
||||||
use tower_http::services::ServeDir;
|
use tower_http::services::ServeDir;
|
||||||
|
|
||||||
/// Serve static files in dev mode
|
/// Serve static files in dev mode
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn service() -> ServeDir {
|
pub fn service() -> ServeDir {
|
||||||
let path = PathBuf::from(format!("{}/public", env!("CARGO_MANIFEST_DIR")));
|
let path = Utf8Path::new(format!("{}/public", env!("CARGO_MANIFEST_DIR")));
|
||||||
ServeDir::new(path).append_index_html_on_directories(false)
|
ServeDir::new(path).append_index_html_on_directories(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use std::{convert::Infallible, future::ready, path::PathBuf};
|
use std::{convert::Infallible, future::ready};
|
||||||
|
|
||||||
use axum::{
|
use axum::{
|
||||||
body::HttpBody,
|
body::HttpBody,
|
||||||
response::Response,
|
response::Response,
|
||||||
routing::{on_service, MethodFilter},
|
routing::{on_service, MethodFilter},
|
||||||
};
|
};
|
||||||
|
use camino::Utf8Path;
|
||||||
use http::{Request, StatusCode};
|
use http::{Request, StatusCode};
|
||||||
use tower::{util::BoxCloneService, ServiceExt};
|
use tower::{util::BoxCloneService, ServiceExt};
|
||||||
use tower_http::services::ServeDir;
|
use tower_http::services::ServeDir;
|
||||||
@ -153,7 +156,7 @@ use tower_http::services::ServeDir;
|
|||||||
/// Serve static files
|
/// Serve static files
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn service<B: HttpBody + Send + 'static>(
|
pub fn service<B: HttpBody + Send + 'static>(
|
||||||
path: &Option<PathBuf>,
|
path: Option<&Utf8Path>,
|
||||||
) -> BoxCloneService<Request<B>, Response, Infallible> {
|
) -> BoxCloneService<Request<B>, Response, Infallible> {
|
||||||
let svc = if let Some(path) = path {
|
let svc = if let Some(path) = path {
|
||||||
let handler = ServeDir::new(path).append_index_html_on_directories(false);
|
let handler = ServeDir::new(path).append_index_html_on_directories(false);
|
||||||
|
@ -20,6 +20,7 @@ serde = { version = "1.0.147", features = ["derive"] }
|
|||||||
serde_json = "1.0.88"
|
serde_json = "1.0.88"
|
||||||
serde_urlencoded = "0.7.1"
|
serde_urlencoded = "0.7.1"
|
||||||
|
|
||||||
|
camino = "1.1.1"
|
||||||
chrono = "0.4.23"
|
chrono = "0.4.23"
|
||||||
url = "2.3.1"
|
url = "2.3.1"
|
||||||
ulid = { version = "1.0.0", features = ["serde"] }
|
ulid = { version = "1.0.0", features = ["serde"] }
|
||||||
|
@ -227,8 +227,8 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let form = TestForm {
|
let form = TestForm {
|
||||||
foo: "".to_owned(),
|
foo: String::new(),
|
||||||
bar: "".to_owned(),
|
bar: String::new(),
|
||||||
};
|
};
|
||||||
let state = form
|
let state = form
|
||||||
.to_form_state()
|
.to_form_state()
|
||||||
|
@ -24,15 +24,10 @@
|
|||||||
|
|
||||||
//! Templates rendering
|
//! Templates rendering
|
||||||
|
|
||||||
use std::{
|
use std::{collections::HashSet, io::Cursor, string::ToString, sync::Arc};
|
||||||
collections::HashSet,
|
|
||||||
io::Cursor,
|
|
||||||
path::{Path, PathBuf},
|
|
||||||
string::ToString,
|
|
||||||
sync::Arc,
|
|
||||||
};
|
|
||||||
|
|
||||||
use anyhow::{bail, Context as _};
|
use anyhow::{bail, Context as _};
|
||||||
|
use camino::{Utf8Path, Utf8PathBuf};
|
||||||
use mas_data_model::StorageBackend;
|
use mas_data_model::StorageBackend;
|
||||||
use mas_router::UrlBuilder;
|
use mas_router::UrlBuilder;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
@ -64,7 +59,7 @@ pub use self::{
|
|||||||
pub struct Templates {
|
pub struct Templates {
|
||||||
tera: Arc<RwLock<Tera>>,
|
tera: Arc<RwLock<Tera>>,
|
||||||
url_builder: UrlBuilder,
|
url_builder: UrlBuilder,
|
||||||
path: Option<String>,
|
path: Option<Utf8PathBuf>,
|
||||||
builtin: bool,
|
builtin: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +86,7 @@ pub enum TemplateLoadingError {
|
|||||||
|
|
||||||
impl Templates {
|
impl Templates {
|
||||||
/// List directories to watch
|
/// List directories to watch
|
||||||
pub async fn watch_roots(&self) -> Vec<PathBuf> {
|
pub async fn watch_roots(&self) -> Vec<Utf8PathBuf> {
|
||||||
Self::roots(self.path.as_deref(), self.builtin)
|
Self::roots(self.path.as_deref(), self.builtin)
|
||||||
.await
|
.await
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -99,18 +94,21 @@ impl Templates {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn roots(path: Option<&str>, builtin: bool) -> Vec<Result<PathBuf, std::io::Error>> {
|
async fn roots(
|
||||||
|
path: Option<&Utf8Path>,
|
||||||
|
builtin: bool,
|
||||||
|
) -> Vec<Result<Utf8PathBuf, std::io::Error>> {
|
||||||
let mut paths = Vec::new();
|
let mut paths = Vec::new();
|
||||||
if builtin && cfg!(feature = "dev") {
|
if builtin && cfg!(feature = "dev") {
|
||||||
paths.push(
|
paths.push(
|
||||||
Path::new(env!("CARGO_MANIFEST_DIR"))
|
Utf8Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||||
.join("src")
|
.join("src")
|
||||||
.join("res"),
|
.join("res"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(path) = path {
|
if let Some(path) = path {
|
||||||
paths.push(PathBuf::from(path));
|
paths.push(Utf8PathBuf::from(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut ret = Vec::new();
|
let mut ret = Vec::new();
|
||||||
@ -137,7 +135,7 @@ impl Templates {
|
|||||||
|
|
||||||
/// Load the templates from the given config
|
/// Load the templates from the given config
|
||||||
pub async fn load(
|
pub async fn load(
|
||||||
path: Option<String>,
|
path: Option<Utf8PathBuf>,
|
||||||
builtin: bool,
|
builtin: bool,
|
||||||
url_builder: UrlBuilder,
|
url_builder: UrlBuilder,
|
||||||
) -> Result<Self, TemplateLoadingError> {
|
) -> Result<Self, TemplateLoadingError> {
|
||||||
@ -151,7 +149,7 @@ impl Templates {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn load_(
|
async fn load_(
|
||||||
path: Option<&str>,
|
path: Option<&Utf8Path>,
|
||||||
builtin: bool,
|
builtin: bool,
|
||||||
url_builder: UrlBuilder,
|
url_builder: UrlBuilder,
|
||||||
) -> Result<Tera, TemplateLoadingError> {
|
) -> Result<Tera, TemplateLoadingError> {
|
||||||
@ -169,8 +167,7 @@ impl Templates {
|
|||||||
|
|
||||||
// This uses blocking I/Os, do that in a blocking task
|
// This uses blocking I/Os, do that in a blocking task
|
||||||
let tera = tokio::task::spawn_blocking(move || {
|
let tera = tokio::task::spawn_blocking(move || {
|
||||||
// Using `to_string_lossy` here is probably fine
|
let path = format!("{}/**/*.{{html,txt,subject}}", root);
|
||||||
let path = format!("{}/**/*.{{html,txt,subject}}", root.to_string_lossy());
|
|
||||||
info!(%path, "Loading templates from filesystem");
|
info!(%path, "Loading templates from filesystem");
|
||||||
Tera::parse(&path)
|
Tera::parse(&path)
|
||||||
})
|
})
|
||||||
@ -223,7 +220,7 @@ impl Templates {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Save the builtin templates to a folder
|
/// Save the builtin templates to a folder
|
||||||
pub async fn save(path: &Path, overwrite: bool) -> anyhow::Result<()> {
|
pub async fn save(path: &Utf8Path, overwrite: bool) -> anyhow::Result<()> {
|
||||||
if cfg!(feature = "dev") {
|
if cfg!(feature = "dev") {
|
||||||
bail!("Builtin templates are not included in dev binaries")
|
bail!("Builtin templates are not included in dev binaries")
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user