1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-07-31 09:24:31 +03:00

Tweak the schema generation and use a common definition for ULIDs

This commit is contained in:
Quentin Gliech
2024-07-30 11:34:57 +02:00
parent cdecac735e
commit 78e988b7cc
5 changed files with 116 additions and 92 deletions

View File

@ -37,6 +37,7 @@ mod call_context;
mod model; mod model;
mod params; mod params;
mod response; mod response;
mod schema;
mod v1; mod v1;
use self::call_context::CallContext; use self::call_context::CallContext;
@ -48,6 +49,10 @@ where
Templates: FromRef<S>, Templates: FromRef<S>,
UrlBuilder: FromRef<S>, UrlBuilder: FromRef<S>,
{ {
aide::gen::in_context(|ctx| {
ctx.schema = schemars::gen::SchemaGenerator::new(schemars::gen::SchemaSettings::openapi3());
});
let mut api = OpenApi::default(); let mut api = OpenApi::default();
let router = ApiRouter::<S>::new() let router = ApiRouter::<S>::new()
.nest("/api/admin/v1", self::v1::router()) .nest("/api/admin/v1", self::v1::router())

View File

@ -52,12 +52,8 @@ impl IntoResponse for UlidPathParamRejection {
#[derive(JsonSchema, Debug, Clone, Copy, Deserialize)] #[derive(JsonSchema, Debug, Clone, Copy, Deserialize)]
struct UlidInPath { struct UlidInPath {
#[schemars( /// # The ID of the resource
with = "String", #[schemars(with = "super::schema::Ulid")]
title = "ULID",
description = "A ULID as per https://github.com/ulid/spec",
regex(pattern = r"^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}$")
)]
id: Ulid, id: Ulid,
} }
@ -81,12 +77,12 @@ const DEFAULT_PAGE_SIZE: usize = 10;
struct PaginationParams { struct PaginationParams {
/// Retrieve the items before the given ID /// Retrieve the items before the given ID
#[serde(rename = "page[before]")] #[serde(rename = "page[before]")]
#[schemars(with = "Option<String>")] #[schemars(with = "Option<super::schema::Ulid>")]
before: Option<Ulid>, before: Option<Ulid>,
/// Retrieve the items after the given ID /// Retrieve the items after the given ID
#[serde(rename = "page[after]")] #[serde(rename = "page[after]")]
#[schemars(with = "Option<String>")] #[schemars(with = "Option<super::schema::Ulid>")]
after: Option<Ulid>, after: Option<Ulid>,
/// Retrieve the first N items /// Retrieve the first N items

View File

@ -143,7 +143,7 @@ struct SingleResource<T> {
type_: &'static str, type_: &'static str,
/// The ID of the resource /// The ID of the resource
#[schemars(with = "String")] #[schemars(with = "super::schema::Ulid")]
id: Ulid, id: Ulid,
/// The attributes of the resource /// The attributes of the resource

View File

@ -0,0 +1,56 @@
// Copyright 2024 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.
//! Common schema definitions
use schemars::{
gen::SchemaGenerator,
schema::{InstanceType, Metadata, Schema, SchemaObject, StringValidation},
JsonSchema,
};
/// A type to use for schema definitions of ULIDs
///
/// Use with `#[schemars(with = "crate::admin::schema::Ulid")]`
pub struct Ulid;
impl JsonSchema for Ulid {
fn schema_name() -> String {
"ULID".to_owned()
}
fn json_schema(_gen: &mut SchemaGenerator) -> Schema {
SchemaObject {
instance_type: Some(InstanceType::String.into()),
metadata: Some(Box::new(Metadata {
title: Some("ULID".into()),
description: Some("A ULID as per https://github.com/ulid/spec".into()),
examples: vec![
"01ARZ3NDEKTSV4RRFFQ69G5FAV".into(),
"01J41912SC8VGAQDD50F6APK91".into(),
],
..Metadata::default()
})),
string: Some(Box::new(StringValidation {
pattern: Some(r"^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}$".into()),
..StringValidation::default()
})),
..SchemaObject::default()
}
.into()
}
}

View File

@ -29,10 +29,8 @@
"description": "Retrieve the items before the given ID", "description": "Retrieve the items before the given ID",
"schema": { "schema": {
"description": "Retrieve the items before the given ID", "description": "Retrieve the items before the given ID",
"type": [ "$ref": "#/components/schemas/ULID",
"string", "nullable": true
"null"
]
}, },
"style": "form" "style": "form"
}, },
@ -42,10 +40,8 @@
"description": "Retrieve the items after the given ID", "description": "Retrieve the items after the given ID",
"schema": { "schema": {
"description": "Retrieve the items after the given ID", "description": "Retrieve the items after the given ID",
"type": [ "$ref": "#/components/schemas/ULID",
"string", "nullable": true
"null"
]
}, },
"style": "form" "style": "form"
}, },
@ -55,12 +51,10 @@
"description": "Retrieve the first N items", "description": "Retrieve the first N items",
"schema": { "schema": {
"description": "Retrieve the first N items", "description": "Retrieve the first N items",
"type": [ "type": "integer",
"integer",
"null"
],
"format": "uint", "format": "uint",
"minimum": 1.0 "minimum": 1.0,
"nullable": true
}, },
"style": "form" "style": "form"
}, },
@ -70,12 +64,10 @@
"description": "Retrieve the last N items", "description": "Retrieve the last N items",
"schema": { "schema": {
"description": "Retrieve the last N items", "description": "Retrieve the last N items",
"type": [ "type": "integer",
"integer",
"null"
],
"format": "uint", "format": "uint",
"minimum": 1.0 "minimum": 1.0,
"nullable": true
}, },
"style": "form" "style": "form"
}, },
@ -83,10 +75,8 @@
"in": "query", "in": "query",
"name": "filter[can_request_admin]", "name": "filter[can_request_admin]",
"schema": { "schema": {
"type": [ "type": "boolean",
"boolean", "nullable": true
"null"
]
}, },
"style": "form" "style": "form"
}, },
@ -94,14 +84,8 @@
"in": "query", "in": "query",
"name": "filter[status]", "name": "filter[status]",
"schema": { "schema": {
"anyOf": [ "$ref": "#/components/schemas/UserStatus",
{ "nullable": true
"$ref": "#/components/schemas/UserStatus"
},
{
"type": "null"
}
]
}, },
"style": "form" "style": "form"
} }
@ -182,13 +166,10 @@
{ {
"in": "path", "in": "path",
"name": "id", "name": "id",
"description": "A ULID as per https://github.com/ulid/spec",
"required": true, "required": true,
"schema": { "schema": {
"title": "ULID", "title": "The ID of the resource",
"description": "A ULID as per https://github.com/ulid/spec", "$ref": "#/components/schemas/ULID"
"type": "string",
"pattern": "^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}$"
}, },
"style": "simple" "style": "simple"
} }
@ -340,56 +321,50 @@
"properties": { "properties": {
"page[before]": { "page[before]": {
"description": "Retrieve the items before the given ID", "description": "Retrieve the items before the given ID",
"type": [ "$ref": "#/components/schemas/ULID",
"string", "nullable": true
"null"
]
}, },
"page[after]": { "page[after]": {
"description": "Retrieve the items after the given ID", "description": "Retrieve the items after the given ID",
"type": [ "$ref": "#/components/schemas/ULID",
"string", "nullable": true
"null"
]
}, },
"page[first]": { "page[first]": {
"description": "Retrieve the first N items", "description": "Retrieve the first N items",
"type": [ "type": "integer",
"integer",
"null"
],
"format": "uint", "format": "uint",
"minimum": 1.0 "minimum": 1.0,
"nullable": true
}, },
"page[last]": { "page[last]": {
"description": "Retrieve the last N items", "description": "Retrieve the last N items",
"type": [ "type": "integer",
"integer",
"null"
],
"format": "uint", "format": "uint",
"minimum": 1.0 "minimum": 1.0,
"nullable": true
} }
} }
}, },
"ULID": {
"title": "ULID",
"description": "A ULID as per https://github.com/ulid/spec",
"examples": [
"01ARZ3NDEKTSV4RRFFQ69G5FAV",
"01J41912SC8VGAQDD50F6APK91"
],
"type": "string",
"pattern": "^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}$"
},
"FilterParams": { "FilterParams": {
"type": "object", "type": "object",
"properties": { "properties": {
"filter[can_request_admin]": { "filter[can_request_admin]": {
"type": [ "type": "boolean",
"boolean", "nullable": true
"null"
]
}, },
"filter[status]": { "filter[status]": {
"anyOf": [ "$ref": "#/components/schemas/UserStatus",
{ "nullable": true
"$ref": "#/components/schemas/UserStatus"
},
{
"type": "null"
}
]
} }
} }
}, },
@ -467,7 +442,7 @@
}, },
"id": { "id": {
"description": "The ID of the resource", "description": "The ID of the resource",
"type": "string" "$ref": "#/components/schemas/ULID"
}, },
"attributes": { "attributes": {
"description": "The attributes of the resource", "description": "The attributes of the resource",
@ -499,11 +474,9 @@
}, },
"locked_at": { "locked_at": {
"description": "When the user was locked. If null, the user is not locked.", "description": "When the user was locked. If null, the user is not locked.",
"type": [ "type": "string",
"string", "format": "date-time",
"null" "nullable": true
],
"format": "date-time"
}, },
"can_request_admin": { "can_request_admin": {
"description": "Whether the user can request admin privileges.", "description": "Whether the user can request admin privileges.",
@ -547,17 +520,13 @@
}, },
"next": { "next": {
"description": "The link to the next page of results\n\nOnly present if there is a next page", "description": "The link to the next page of results\n\nOnly present if there is a next page",
"type": [ "type": "string",
"string", "nullable": true
"null"
]
}, },
"prev": { "prev": {
"description": "The link to the previous page of results\n\nOnly present if there is a previous page", "description": "The link to the previous page of results\n\nOnly present if there is a previous page",
"type": [ "type": "string",
"string", "nullable": true
"null"
]
} }
} }
}, },
@ -597,10 +566,8 @@
], ],
"properties": { "properties": {
"id": { "id": {
"title": "ULID", "title": "The ID of the resource",
"description": "A ULID as per https://github.com/ulid/spec", "$ref": "#/components/schemas/ULID"
"type": "string",
"pattern": "^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}$"
} }
} }
}, },