refactor: Use PublicKey
and Signature
as parameters #33
3 changed files with 164 additions and 29 deletions
|
@ -24,15 +24,6 @@
|
|||
use std::{fmt, str::FromStr};
|
||||
|
||||
use base58::{FromBase58, ToBase58};
|
||||
#[cfg(feature = "openapi")]
|
||||
use salvo_oapi::{
|
||||
schema::{
|
||||
Schema as OapiSchema,
|
||||
SchemaFormat as OapiSchemaFormat,
|
||||
SchemaType as OapiSchemaType,
|
||||
},
|
||||
ToSchema,
|
||||
};
|
||||
|
||||
use crate::cipher::{hmac_sha256, CipherError};
|
||||
|
||||
|
@ -206,23 +197,3 @@ impl From<[u8; 56]> for Signature {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "openapi")]
|
||||
impl ToSchema for PublicKey {
|
||||
fn to_schema(_components: &mut salvo_oapi::Components) -> salvo_oapi::RefOr<OapiSchema> {
|
||||
salvo_oapi::Object::new()
|
||||
.schema_type(OapiSchemaType::String)
|
||||
.format(OapiSchemaFormat::Custom("base58".to_owned()))
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "openapi")]
|
||||
impl ToSchema for Signature {
|
||||
fn to_schema(_components: &mut salvo_oapi::Components) -> salvo_oapi::RefOr<OapiSchema> {
|
||||
salvo_oapi::Object::new()
|
||||
.schema_type(OapiSchemaType::String)
|
||||
.format(OapiSchemaFormat::Custom("hex".to_owned()))
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
|
162
crates/oxidetalis_core/src/types/impl_openapi.rs
Normal file
162
crates/oxidetalis_core/src/types/impl_openapi.rs
Normal file
|
@ -0,0 +1,162 @@
|
|||
// OxideTalis Messaging Protocol homeserver core implementation
|
||||
// Copyright (C) 2024 Awiteb <a@4rs.nl>, OxideTalis Contributors
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
//! OpenAPI schema for some core types.
|
||||
|
||||
use std::str::FromStr;
|
||||
|
||||
use salvo_core::{extract::Metadata as ExtractMetadata, http::StatusError, Extractible, Request};
|
||||
use salvo_oapi::{
|
||||
schema::{
|
||||
Schema as OapiSchema,
|
||||
SchemaFormat as OapiSchemaFormat,
|
||||
SchemaType as OapiSchemaType,
|
||||
},
|
||||
Components as OapiComponents,
|
||||
EndpointArgRegister,
|
||||
Parameter,
|
||||
ParameterIn,
|
||||
Parameters,
|
||||
ToParameters,
|
||||
ToSchema,
|
||||
};
|
||||
|
||||
use super::{PublicKey as CorePublicKey, Signature};
|
||||
|
||||
impl ToSchema for CorePublicKey {
|
||||
fn to_schema(_components: &mut salvo_oapi::Components) -> salvo_oapi::RefOr<OapiSchema> {
|
||||
salvo_oapi::Object::new()
|
||||
.name(crate::PUBLIC_KEY_HEADER)
|
||||
.description("User's public key")
|
||||
.schema_type(OapiSchemaType::String)
|
||||
.format(OapiSchemaFormat::Custom("base58".to_owned()))
|
||||
.required(crate::PUBLIC_KEY_HEADER)
|
||||
// A 33-byte base58 string can be either 44 or 45 characters long
|
||||
.example("rW8FMG5D75NVNJV3Wd498dEh65BgUuhwY1Yk5zYJPpRe".into())
|
||||
.max_length(45)
|
||||
.min_length(44)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSchema for Signature {
|
||||
fn to_schema(_components: &mut salvo_oapi::Components) -> salvo_oapi::RefOr<OapiSchema> {
|
||||
salvo_oapi::Object::new()
|
||||
.name(crate::SIGNATURE_HEADER)
|
||||
.description("Signature of the request")
|
||||
.schema_type(OapiSchemaType::String)
|
||||
.format(OapiSchemaFormat::Custom("hex".to_owned()))
|
||||
.required(crate::SIGNATURE_HEADER)
|
||||
// 56 bytes in hex (valid signature)
|
||||
.example("0".repeat(112).into())
|
||||
.max_length(112)
|
||||
.min_length(112)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ex> Extractible<'ex> for CorePublicKey {
|
||||
fn metadata() -> &'ex ExtractMetadata {
|
||||
static METADATA: ExtractMetadata = ExtractMetadata::new("");
|
||||
&METADATA
|
||||
}
|
||||
|
||||
#[allow(refining_impl_trait)]
|
||||
async fn extract(req: &'ex mut Request) -> Result<Self, StatusError> {
|
||||
extract_header(req, crate::PUBLIC_KEY_HEADER).and_then(|public_key| {
|
||||
CorePublicKey::from_str(public_key).map_err(|err| {
|
||||
StatusError::bad_request()
|
||||
.brief("Invalid public key")
|
||||
.cause(err.to_string())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(refining_impl_trait)]
|
||||
async fn extract_with_arg(req: &'ex mut Request, _: &str) -> Result<Self, StatusError> {
|
||||
Self::extract(req).await
|
||||
}
|
||||
}
|
||||
|
||||
impl EndpointArgRegister for CorePublicKey {
|
||||
fn register(components: &mut OapiComponents, operation: &mut salvo_oapi::Operation, _: &str) {
|
||||
operation.parameters.insert(
|
||||
Parameter::new(crate::PUBLIC_KEY_HEADER)
|
||||
.parameter_in(ParameterIn::Header)
|
||||
.required(true)
|
||||
.description("User's public key")
|
||||
.example("2BiUSWkJUy5bcdJB8qszq9K6a5EXVHvK41vQWZVkUBUM8".into())
|
||||
.schema(CorePublicKey::to_schema(components)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ex> Extractible<'ex> for Signature {
|
||||
fn metadata() -> &'ex ExtractMetadata {
|
||||
unreachable!(
|
||||
"
|
||||
`Extractible` is required to implement `ToParameters` for `Signature`, but \
|
||||
Salvo does not need it actually, see https://github.com/salvo-rs/salvo/issues/838"
|
||||
)
|
||||
}
|
||||
|
||||
#[allow(refining_impl_trait)]
|
||||
async fn extract(_: &'ex mut Request) -> Result<Self, StatusError> {
|
||||
unreachable!(
|
||||
"
|
||||
`Extractible` is required to implement `ToParameters` for `Signature`, but \
|
||||
Salvo does not need it actually, see https://github.com/salvo-rs/salvo/issues/838"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToParameters<'_> for Signature {
|
||||
fn to_parameters(components: &mut OapiComponents) -> Parameters {
|
||||
Parameters::new().parameter(
|
||||
Parameter::new(crate::SIGNATURE_HEADER)
|
||||
.parameter_in(ParameterIn::Header)
|
||||
.required(true)
|
||||
.description("Signature of the request")
|
||||
.example("0".repeat(112).into())
|
||||
.schema(Self::to_schema(components)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_header<'req>(req: &'req Request, name: &str) -> Result<&'req str, StatusError> {
|
||||
req.headers()
|
||||
.get(name)
|
||||
.map(|v| {
|
||||
v.to_str().map_err(|_| {
|
||||
StatusError::bad_request()
|
||||
.brief("Invalid header value")
|
||||
.cause("Header value must be a valid ascii string")
|
||||
})
|
||||
})
|
||||
.transpose()?
|
||||
.ok_or_else(|| {
|
||||
StatusError::bad_request()
|
||||
.brief(format!("Could not find {name} in headers"))
|
||||
.cause(format!(
|
||||
"{name} is required to authenication and authorization"
|
||||
))
|
||||
})
|
||||
}
|
|
@ -22,6 +22,8 @@
|
|||
//! Oxidetalis server types
|
||||
|
||||
mod cipher;
|
||||
#[cfg(feature = "openapi")]
|
||||
mod impl_openapi;
|
||||
#[cfg(feature = "sea-orm")]
|
||||
mod impl_sea_orm;
|
||||
#[cfg(feature = "serde")]
|
||||
|
|
Loading…
Reference in a new issue