1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-08-06 06:02:40 +03:00

Add instance privacy policy, TOS and imprint, and loads of design cleanups

This commit is contained in:
Quentin Gliech
2023-10-24 19:02:28 +02:00
parent 10e31f03fa
commit 8984cc703b
50 changed files with 1077 additions and 604 deletions

View File

@@ -14,6 +14,8 @@
//! Contexts used in templates
mod branding;
use std::fmt::Formatter;
use chrono::{DateTime, Utc};
@@ -29,6 +31,7 @@ use serde::{ser::SerializeStruct, Deserialize, Serialize};
use ulid::Ulid;
use url::Url;
pub use self::branding::SiteBranding;
use crate::{FormField, FormState};
/// Helper trait to construct context wrappers

View File

@@ -0,0 +1,89 @@
use std::sync::Arc;
use minijinja::{value::StructObject, Value};
/// Site branding information.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SiteBranding {
server_name: Arc<str>,
service_name: Option<Arc<str>>,
policy_uri: Option<Arc<str>>,
tos_uri: Option<Arc<str>>,
imprint: Option<Arc<str>>,
logo_uri: Option<Arc<str>>,
}
impl SiteBranding {
/// Create a new site branding based on the given server name.
#[must_use]
pub fn new(server_name: impl Into<Arc<str>>) -> Self {
Self {
server_name: server_name.into(),
service_name: None,
policy_uri: None,
tos_uri: None,
imprint: None,
logo_uri: None,
}
}
/// Set the service name.
#[must_use]
pub fn with_service_name(mut self, service_name: impl Into<Arc<str>>) -> Self {
self.service_name = Some(service_name.into());
self
}
/// Set the policy URI.
#[must_use]
pub fn with_policy_uri(mut self, policy_uri: impl Into<Arc<str>>) -> Self {
self.policy_uri = Some(policy_uri.into());
self
}
/// Set the terms of service URI.
#[must_use]
pub fn with_tos_uri(mut self, tos_uri: impl Into<Arc<str>>) -> Self {
self.tos_uri = Some(tos_uri.into());
self
}
/// Set the imprint.
#[must_use]
pub fn with_imprint(mut self, imprint: impl Into<Arc<str>>) -> Self {
self.imprint = Some(imprint.into());
self
}
/// Set the logo URI.
#[must_use]
pub fn with_logo_uri(mut self, logo_uri: impl Into<Arc<str>>) -> Self {
self.logo_uri = Some(logo_uri.into());
self
}
}
impl StructObject for SiteBranding {
fn get_field(&self, name: &str) -> Option<Value> {
match name {
"server_name" => Some(self.server_name.clone().into()),
"service_name" => self.service_name.clone().map(Value::from),
"policy_uri" => self.policy_uri.clone().map(Value::from),
"tos_uri" => self.tos_uri.clone().map(Value::from),
"imprint" => self.imprint.clone().map(Value::from),
"logo_uri" => self.logo_uri.clone().map(Value::from),
_ => None,
}
}
fn static_fields(&self) -> Option<&'static [&'static str]> {
Some(&[
"server_name",
"service_name",
"policy_uri",
"tos_uri",
"imprint",
"logo_uri",
])
}
}

View File

@@ -32,6 +32,7 @@ use camino::{Utf8Path, Utf8PathBuf};
use mas_i18n::Translator;
use mas_router::UrlBuilder;
use mas_spa::ViteManifest;
use minijinja::Value;
use rand::Rng;
use serde::Serialize;
use thiserror::Error;
@@ -52,8 +53,8 @@ pub use self::{
EmailVerificationPageContext, EmptyContext, ErrorContext, FormPostContext, IndexContext,
LoginContext, LoginFormField, NotFoundContext, PolicyViolationContext, PostAuthContext,
PostAuthContextInner, ReauthContext, ReauthFormField, RegisterContext, RegisterFormField,
TemplateContext, UpstreamExistingLinkContext, UpstreamRegister, UpstreamSuggestLink,
WithCsrf, WithLanguage, WithOptionalSession, WithSession,
SiteBranding, TemplateContext, UpstreamExistingLinkContext, UpstreamRegister,
UpstreamSuggestLink, WithCsrf, WithLanguage, WithOptionalSession, WithSession,
},
forms::{FieldError, FormError, FormField, FormState, ToFormState},
};
@@ -73,6 +74,7 @@ pub struct Templates {
environment: Arc<ArcSwap<minijinja::Environment<'static>>>,
translator: Arc<ArcSwap<Translator>>,
url_builder: UrlBuilder,
branding: SiteBranding,
vite_manifest_path: Utf8PathBuf,
translations_path: Utf8PathBuf,
path: Utf8PathBuf,
@@ -151,12 +153,14 @@ impl Templates {
url_builder: UrlBuilder,
vite_manifest_path: Utf8PathBuf,
translations_path: Utf8PathBuf,
branding: SiteBranding,
) -> Result<Self, TemplateLoadingError> {
let (translator, environment) = Self::load_(
&path,
url_builder.clone(),
&vite_manifest_path,
&translations_path,
branding.clone(),
)
.await?;
Ok(Self {
@@ -166,6 +170,7 @@ impl Templates {
url_builder,
vite_manifest_path,
translations_path,
branding,
})
}
@@ -174,6 +179,7 @@ impl Templates {
url_builder: UrlBuilder,
vite_manifest_path: &Utf8Path,
translations_path: &Utf8Path,
branding: SiteBranding,
) -> Result<(Arc<Translator>, Arc<minijinja::Environment<'static>>), TemplateLoadingError> {
let path = path.to_owned();
let span = tracing::Span::current();
@@ -226,6 +232,8 @@ impl Templates {
})
.await??;
env.add_global("branding", Value::from_struct_object(branding));
self::functions::register(
&mut env,
url_builder,
@@ -259,6 +267,7 @@ impl Templates {
self.url_builder.clone(),
&self.vite_manifest_path,
&self.translations_path,
self.branding.clone(),
)
.await?;
@@ -409,13 +418,20 @@ mod tests {
let path = Utf8Path::new(env!("CARGO_MANIFEST_DIR")).join("../../templates/");
let url_builder = UrlBuilder::new("https://example.com/".parse().unwrap(), None, None);
let branding = SiteBranding::new("example.com").with_service_name("Example");
let vite_manifest_path =
Utf8Path::new(env!("CARGO_MANIFEST_DIR")).join("../../frontend/dist/manifest.json");
let translations_path =
Utf8Path::new(env!("CARGO_MANIFEST_DIR")).join("../../translations");
let templates = Templates::load(path, url_builder, vite_manifest_path, translations_path)
.await
.unwrap();
let templates = Templates::load(
path,
url_builder,
vite_manifest_path,
translations_path,
branding,
)
.await
.unwrap();
templates.check_render(now, &mut rng).unwrap();
}
}