You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-29 22:01:14 +03:00
Move templates to their own crate
This commit is contained in:
117
crates/data-model/src/errors.rs
Normal file
117
crates/data-model/src/errors.rs
Normal file
@ -0,0 +1,117 @@
|
||||
// Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::{collections::HashMap, fmt::Debug, hash::Hash};
|
||||
|
||||
use serde::{ser::SerializeMap, Serialize};
|
||||
|
||||
pub trait HtmlError: Debug + Send + Sync + 'static {
|
||||
fn html_display(&self) -> String;
|
||||
}
|
||||
|
||||
pub trait WrapFormError<FieldType> {
|
||||
fn on_form(self) -> ErroredForm<FieldType>;
|
||||
fn on_field(self, field: FieldType) -> ErroredForm<FieldType>;
|
||||
}
|
||||
|
||||
impl<E, FieldType> WrapFormError<FieldType> for E
|
||||
where
|
||||
E: HtmlError,
|
||||
{
|
||||
fn on_form(self) -> ErroredForm<FieldType> {
|
||||
let mut f = ErroredForm::new();
|
||||
f.form.push(FormError {
|
||||
error: Box::new(self),
|
||||
});
|
||||
f
|
||||
}
|
||||
|
||||
fn on_field(self, field: FieldType) -> ErroredForm<FieldType> {
|
||||
let mut f = ErroredForm::new();
|
||||
f.fields.push(FieldError {
|
||||
field,
|
||||
error: Box::new(self),
|
||||
});
|
||||
f
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct FormError {
|
||||
error: Box<dyn HtmlError>,
|
||||
}
|
||||
|
||||
impl Serialize for FormError {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.error.html_display())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct FieldError<FieldType> {
|
||||
field: FieldType,
|
||||
error: Box<dyn HtmlError>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ErroredForm<FieldType> {
|
||||
form: Vec<FormError>,
|
||||
fields: Vec<FieldError<FieldType>>,
|
||||
}
|
||||
|
||||
impl<T> Default for ErroredForm<T> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
form: Vec::new(),
|
||||
fields: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ErroredForm<T> {
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
form: Vec::new(),
|
||||
fields: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<FieldType: Copy + Serialize + Hash + Eq> Serialize for ErroredForm<FieldType> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
let mut map = serializer.serialize_map(Some(2))?;
|
||||
let has_errors = !self.form.is_empty() || !self.fields.is_empty();
|
||||
map.serialize_entry("has_errors", &has_errors)?;
|
||||
map.serialize_entry("form_errors", &self.form)?;
|
||||
|
||||
let fields: HashMap<FieldType, Vec<String>> =
|
||||
self.fields.iter().fold(HashMap::new(), |mut map, err| {
|
||||
map.entry(err.field)
|
||||
.or_default()
|
||||
.push(err.error.html_display());
|
||||
map
|
||||
});
|
||||
|
||||
map.serialize_entry("fields_errors", &fields)?;
|
||||
|
||||
map.end()
|
||||
}
|
||||
}
|
@ -16,6 +16,10 @@ use chrono::{DateTime, Duration, Utc};
|
||||
use oauth2_types::{pkce::CodeChallengeMethod, scope::Scope};
|
||||
use serde::Serialize;
|
||||
|
||||
pub mod errors;
|
||||
|
||||
pub trait StorageBackendMarker: StorageBackend {}
|
||||
|
||||
pub trait StorageBackend {
|
||||
type UserData: Clone + std::fmt::Debug + PartialEq;
|
||||
type AuthenticationData: Clone + std::fmt::Debug + PartialEq;
|
||||
@ -26,7 +30,18 @@ pub trait StorageBackend {
|
||||
type AccessTokenData: Clone + std::fmt::Debug + PartialEq;
|
||||
}
|
||||
|
||||
impl StorageBackend for () {
|
||||
type AccessTokenData = ();
|
||||
type AuthenticationData = ();
|
||||
type AuthorizationCodeData = ();
|
||||
type BrowserSessionData = ();
|
||||
type ClientData = ();
|
||||
type SessionData = ();
|
||||
type UserData = ();
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize)]
|
||||
#[serde(bound = "T: StorageBackend")]
|
||||
pub struct User<T: StorageBackend> {
|
||||
#[serde(skip_serializing)]
|
||||
pub data: T::UserData,
|
||||
@ -47,14 +62,35 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: StorageBackendMarker> From<User<S>> for User<()> {
|
||||
fn from(u: User<S>) -> Self {
|
||||
User {
|
||||
data: (),
|
||||
username: u.username,
|
||||
sub: u.sub,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize)]
|
||||
#[serde(bound = "T: StorageBackend")]
|
||||
pub struct Authentication<T: StorageBackend> {
|
||||
#[serde(skip_serializing)]
|
||||
pub data: T::AuthenticationData,
|
||||
pub created_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
impl<S: StorageBackendMarker> From<Authentication<S>> for Authentication<()> {
|
||||
fn from(a: Authentication<S>) -> Self {
|
||||
Authentication {
|
||||
data: (),
|
||||
created_at: a.created_at,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize)]
|
||||
#[serde(bound = "T: StorageBackend")]
|
||||
pub struct BrowserSession<T: StorageBackend> {
|
||||
#[serde(skip_serializing)]
|
||||
pub data: T::BrowserSessionData,
|
||||
@ -63,6 +99,17 @@ pub struct BrowserSession<T: StorageBackend> {
|
||||
pub last_authentication: Option<Authentication<T>>,
|
||||
}
|
||||
|
||||
impl<S: StorageBackendMarker> From<BrowserSession<S>> for BrowserSession<()> {
|
||||
fn from(s: BrowserSession<S>) -> Self {
|
||||
BrowserSession {
|
||||
data: (),
|
||||
user: s.user.into(),
|
||||
created_at: s.created_at,
|
||||
last_authentication: s.last_authentication.map(Into::into),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: StorageBackend> BrowserSession<T>
|
||||
where
|
||||
T::BrowserSessionData: Default,
|
||||
@ -82,13 +129,24 @@ where
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize)]
|
||||
#[serde(bound = "T: StorageBackend")]
|
||||
pub struct Client<T: StorageBackend> {
|
||||
#[serde(skip_serializing)]
|
||||
pub data: T::ClientData,
|
||||
pub client_id: String,
|
||||
}
|
||||
|
||||
impl<S: StorageBackendMarker> From<Client<S>> for Client<()> {
|
||||
fn from(c: Client<S>) -> Self {
|
||||
Client {
|
||||
data: (),
|
||||
client_id: c.client_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize)]
|
||||
#[serde(bound = "T: StorageBackend")]
|
||||
pub struct Session<T: StorageBackend> {
|
||||
#[serde(skip_serializing)]
|
||||
pub data: T::SessionData,
|
||||
@ -97,6 +155,17 @@ pub struct Session<T: StorageBackend> {
|
||||
pub scope: Scope,
|
||||
}
|
||||
|
||||
impl<S: StorageBackendMarker> From<Session<S>> for Session<()> {
|
||||
fn from(s: Session<S>) -> Self {
|
||||
Session {
|
||||
data: (),
|
||||
browser_session: s.browser_session.map(Into::into),
|
||||
client: s.client.into(),
|
||||
scope: s.scope,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
|
||||
pub struct Pkce {
|
||||
challenge_method: CodeChallengeMethod,
|
||||
@ -117,6 +186,7 @@ impl Pkce {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
|
||||
#[serde(bound = "T: StorageBackend")]
|
||||
pub struct AuthorizationCode<T: StorageBackend> {
|
||||
#[serde(skip_serializing)]
|
||||
pub data: T::AuthorizationCodeData,
|
||||
@ -124,6 +194,16 @@ pub struct AuthorizationCode<T: StorageBackend> {
|
||||
pub pkce: Pkce,
|
||||
}
|
||||
|
||||
impl<S: StorageBackendMarker> From<AuthorizationCode<S>> for AuthorizationCode<()> {
|
||||
fn from(c: AuthorizationCode<S>) -> Self {
|
||||
AuthorizationCode {
|
||||
data: (),
|
||||
code: c.code,
|
||||
pkce: c.pkce,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct AccessToken<T: StorageBackend> {
|
||||
pub data: T::AccessTokenData,
|
||||
@ -132,3 +212,15 @@ pub struct AccessToken<T: StorageBackend> {
|
||||
pub expires_after: Duration,
|
||||
pub created_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
impl<S: StorageBackendMarker> From<AccessToken<S>> for AccessToken<()> {
|
||||
fn from(t: AccessToken<S>) -> Self {
|
||||
AccessToken {
|
||||
data: (),
|
||||
jti: t.jti,
|
||||
token: t.token,
|
||||
expires_after: t.expires_after,
|
||||
created_at: t.created_at,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user