chore: update everything to work with utoipa
This commit is contained in:
@@ -15,7 +15,7 @@ mongodb = ["dep:mongodb", "bson", "authifier/database-mongodb"]
|
||||
# ... Other
|
||||
tasks = ["isahc", "linkify", "url-escape"]
|
||||
async-std-runtime = ["async-std", "authifier/async-std-runtime"]
|
||||
rocket-impl = ["rocket", "schemars", "revolt_okapi", "revolt_rocket_okapi", "authifier/rocket_impl"]
|
||||
rocket-impl = ["rocket"]
|
||||
axum-impl = ["axum"]
|
||||
redis-is-patched = ["revolt-presence/redis-is-patched"]
|
||||
|
||||
@@ -46,7 +46,7 @@ ulid = "1.0.0"
|
||||
nanoid = "0.4.0"
|
||||
base64 = "0.21.3"
|
||||
once_cell = "1.17"
|
||||
indexmap = "1.9.1"
|
||||
indexmap = "2.12.0"
|
||||
decancer = "1.6.2"
|
||||
deadqueue = "0.2.4"
|
||||
linkify = { optional = true, version = "0.8.1" }
|
||||
@@ -58,7 +58,7 @@ isahc = { optional = true, version = "1.7", features = ["json"] }
|
||||
serde_json = "1"
|
||||
revolt_optional_struct = "0.2.0"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
iso8601-timestamp = { version = "0.2.10", features = ["serde", "bson"] }
|
||||
iso8601-timestamp = { version = "0.4.0", features = ["serde", "bson"] }
|
||||
|
||||
# Events
|
||||
redis-kiss = { version = "0.1.4" }
|
||||
@@ -81,15 +81,15 @@ async-recursion = "1.0.4"
|
||||
async-std = { version = "1.8.0", features = ["attributes"], optional = true }
|
||||
|
||||
# Axum Impl
|
||||
axum = { version = "0.7.5", optional = true }
|
||||
axum = { version = "0.8.6", optional = true }
|
||||
|
||||
# Rocket Impl
|
||||
schemars = { version = "0.8.8", optional = true }
|
||||
rocket = { version = "0.5.1", default-features = false, features = [
|
||||
"json",
|
||||
], optional = true }
|
||||
revolt_okapi = { version = "0.9.1", optional = true }
|
||||
revolt_rocket_okapi = { version = "0.10.0", optional = true }
|
||||
|
||||
# Openapi Schema
|
||||
utoipa = { version = "5.4.0", optional = true }
|
||||
|
||||
# Authifier
|
||||
authifier = { version = "1.0.15" }
|
||||
|
||||
@@ -247,7 +247,7 @@ impl AbstractMessages for ReferenceDb {
|
||||
let mut messages = self.messages.lock().await;
|
||||
if let Some(message) = messages.get_mut(id) {
|
||||
if let Some(users) = message.reactions.get_mut(emoji) {
|
||||
users.remove(&user.to_string());
|
||||
users.swap_remove(&user.to_string());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -260,7 +260,7 @@ impl AbstractMessages for ReferenceDb {
|
||||
async fn clear_reaction(&self, id: &str, emoji: &str) -> Result<()> {
|
||||
let mut messages = self.messages.lock().await;
|
||||
if let Some(message) = messages.get_mut(id) {
|
||||
message.reactions.remove(emoji);
|
||||
message.reactions.swap_remove(emoji);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(create_error!(NotFound))
|
||||
|
||||
@@ -4,7 +4,6 @@ use revolt_result::{create_error, Error, Result};
|
||||
|
||||
use crate::{Database, User};
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<S> FromRequestParts<S> for User
|
||||
where
|
||||
Database: FromRef<S>,
|
||||
|
||||
@@ -4,8 +4,6 @@ mod model;
|
||||
mod ops;
|
||||
#[cfg(feature = "rocket-impl")]
|
||||
mod rocket;
|
||||
#[cfg(feature = "rocket-impl")]
|
||||
mod schema;
|
||||
|
||||
pub use model::*;
|
||||
pub use ops::*;
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
use revolt_okapi::openapi3::{SecurityScheme, SecuritySchemeData};
|
||||
use revolt_rocket_okapi::{
|
||||
gen::OpenApiGenerator,
|
||||
request::{OpenApiFromRequest, RequestHeaderInput},
|
||||
};
|
||||
|
||||
use crate::User;
|
||||
|
||||
impl OpenApiFromRequest<'_> for User {
|
||||
fn from_request_input(
|
||||
_gen: &mut OpenApiGenerator,
|
||||
_name: String,
|
||||
_required: bool,
|
||||
) -> revolt_rocket_okapi::Result<RequestHeaderInput> {
|
||||
let mut requirements = schemars::Map::new();
|
||||
requirements.insert("Session Token".to_owned(), vec![]);
|
||||
|
||||
Ok(RequestHeaderInput::Security(
|
||||
"Session Token".to_owned(),
|
||||
SecurityScheme {
|
||||
data: SecuritySchemeData::ApiKey {
|
||||
name: "x-session-token".to_owned(),
|
||||
location: "header".to_owned(),
|
||||
},
|
||||
description: Some("Used to authenticate as a user.".to_owned()),
|
||||
extensions: schemars::Map::new(),
|
||||
},
|
||||
requirements,
|
||||
))
|
||||
}
|
||||
}
|
||||
@@ -43,45 +43,45 @@ impl IdempotencyKey {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rocket-impl")]
|
||||
use revolt_rocket_okapi::{
|
||||
gen::OpenApiGenerator,
|
||||
request::{OpenApiFromRequest, RequestHeaderInput},
|
||||
revolt_okapi::openapi3::{Parameter, ParameterValue},
|
||||
};
|
||||
// #[cfg(feature = "rocket-impl")]
|
||||
// use revolt_rocket_okapi::{
|
||||
// gen::OpenApiGenerator,
|
||||
// request::{OpenApiFromRequest, RequestHeaderInput},
|
||||
// revolt_okapi::openapi3::{Parameter, ParameterValue},
|
||||
// };
|
||||
|
||||
#[cfg(feature = "rocket-impl")]
|
||||
use schemars::schema::{InstanceType, SchemaObject, SingleOrVec};
|
||||
// #[cfg(feature = "rocket-impl")]
|
||||
// use schemars::schema::{InstanceType, SchemaObject, SingleOrVec};
|
||||
|
||||
#[cfg(feature = "rocket-impl")]
|
||||
impl OpenApiFromRequest<'_> for IdempotencyKey {
|
||||
fn from_request_input(
|
||||
_gen: &mut OpenApiGenerator,
|
||||
_name: String,
|
||||
_required: bool,
|
||||
) -> revolt_rocket_okapi::Result<RequestHeaderInput> {
|
||||
Ok(RequestHeaderInput::Parameter(Parameter {
|
||||
name: "Idempotency-Key".to_string(),
|
||||
description: Some("Unique key to prevent duplicate requests".to_string()),
|
||||
allow_empty_value: false,
|
||||
required: false,
|
||||
deprecated: false,
|
||||
extensions: schemars::Map::new(),
|
||||
location: "header".to_string(),
|
||||
value: ParameterValue::Schema {
|
||||
allow_reserved: false,
|
||||
example: None,
|
||||
examples: None,
|
||||
explode: None,
|
||||
style: None,
|
||||
schema: SchemaObject {
|
||||
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::String))),
|
||||
..Default::default()
|
||||
},
|
||||
},
|
||||
}))
|
||||
}
|
||||
}
|
||||
// #[cfg(feature = "rocket-impl")]
|
||||
// impl OpenApiFromRequest<'_> for IdempotencyKey {
|
||||
// fn from_request_input(
|
||||
// _gen: &mut OpenApiGenerator,
|
||||
// _name: String,
|
||||
// _required: bool,
|
||||
// ) -> revolt_rocket_okapi::Result<RequestHeaderInput> {
|
||||
// Ok(RequestHeaderInput::Parameter(Parameter {
|
||||
// name: "Idempotency-Key".to_string(),
|
||||
// description: Some("Unique key to prevent duplicate requests".to_string()),
|
||||
// allow_empty_value: false,
|
||||
// required: false,
|
||||
// deprecated: false,
|
||||
// extensions: schemars::Map::new(),
|
||||
// location: "header".to_string(),
|
||||
// value: ParameterValue::Schema {
|
||||
// allow_reserved: false,
|
||||
// example: None,
|
||||
// examples: None,
|
||||
// explode: None,
|
||||
// style: None,
|
||||
// schema: SchemaObject {
|
||||
// instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::String))),
|
||||
// ..Default::default()
|
||||
// },
|
||||
// },
|
||||
// }))
|
||||
// }
|
||||
// }
|
||||
|
||||
#[cfg(feature = "rocket-impl")]
|
||||
use rocket::{
|
||||
|
||||
@@ -4,3 +4,5 @@ pub mod idempotency;
|
||||
pub mod permissions;
|
||||
pub mod reference;
|
||||
pub mod test_fixtures;
|
||||
#[cfg(feature = "utoipa")]
|
||||
pub mod utoipa;
|
||||
@@ -3,10 +3,13 @@ use std::str::FromStr;
|
||||
use revolt_result::Result;
|
||||
#[cfg(feature = "rocket-impl")]
|
||||
use rocket::request::FromParam;
|
||||
#[cfg(feature = "rocket-impl")]
|
||||
use schemars::{
|
||||
schema::{InstanceType, Schema, SchemaObject, SingleOrVec},
|
||||
JsonSchema,
|
||||
#[cfg(feature = "utoipa")]
|
||||
use utoipa::{
|
||||
openapi::{
|
||||
path::{Parameter, ParameterBuilder, ParameterIn},
|
||||
Required,
|
||||
},
|
||||
IntoParams,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@@ -113,16 +116,14 @@ impl<'r> FromParam<'r> for Reference<'r> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rocket-impl")]
|
||||
impl<'a> JsonSchema for Reference<'a> {
|
||||
fn schema_name() -> String {
|
||||
"Id".to_string()
|
||||
}
|
||||
|
||||
fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> Schema {
|
||||
Schema::Object(SchemaObject {
|
||||
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::String))),
|
||||
..Default::default()
|
||||
})
|
||||
#[cfg(feature = "utoipa")]
|
||||
impl IntoParams for Reference<'_> {
|
||||
fn into_params(parameter_in_provider: impl Fn() -> Option<ParameterIn>) -> Vec<Parameter> {
|
||||
vec![ParameterBuilder::new()
|
||||
.name("id")
|
||||
.required(Required::True)
|
||||
.description(Some("An ID".to_string()))
|
||||
.parameter_in(parameter_in_provider().unwrap_or_default())
|
||||
.build()]
|
||||
}
|
||||
}
|
||||
|
||||
21
crates/core/database/src/util/utoipa.rs
Normal file
21
crates/core/database/src/util/utoipa.rs
Normal file
@@ -0,0 +1,21 @@
|
||||
use utoipa::{Modify, openapi::{OpenApi, security::{ApiKey, ApiKeyValue, SecurityScheme}}};
|
||||
|
||||
pub struct TokenSecurity;
|
||||
|
||||
impl Modify for TokenSecurity {
|
||||
fn modify(&self, openapi: &mut OpenApi) {
|
||||
let components = openapi.components.get_or_insert_default();
|
||||
|
||||
components.add_security_scheme(
|
||||
"Session-Token",
|
||||
SecurityScheme::ApiKey(ApiKey::Header(ApiKeyValue::new(
|
||||
"X-Session-Token".to_string(),
|
||||
))),
|
||||
);
|
||||
|
||||
components.add_security_scheme(
|
||||
"Bot-Token",
|
||||
SecurityScheme::ApiKey(ApiKey::Header(ApiKeyValue::new("X-Bot-Ticket".to_string()))),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -10,22 +10,22 @@ description = "Revolt Backend: API Models"
|
||||
|
||||
[features]
|
||||
serde = ["dep:serde", "revolt-permissions/serde", "indexmap/serde"]
|
||||
schemas = ["dep:schemars", "revolt-permissions/schemas"]
|
||||
utoipa = ["dep:utoipa"]
|
||||
validator = ["dep:validator"]
|
||||
rocket = ["dep:rocket"]
|
||||
partials = ["dep:revolt_optional_struct", "serde", "schemas", "utoipa"]
|
||||
partials = ["dep:revolt_optional_struct", "serde", "utoipa"]
|
||||
|
||||
default = ["serde", "partials", "rocket"]
|
||||
|
||||
[dependencies]
|
||||
# Core
|
||||
revolt-config = { version = "0.8.9", path = "../config" }
|
||||
revolt-permissions = { version = "0.8.9", path = "../permissions" }
|
||||
revolt-permissions = { version = "0.8.9", path = "../permissions", features = [
|
||||
"utoipa",
|
||||
] }
|
||||
|
||||
# Utility
|
||||
regex = "1.11"
|
||||
indexmap = "1.9.3"
|
||||
indexmap = "2.12.0"
|
||||
once_cell = "1.17.1"
|
||||
num_enum = "0.6.1"
|
||||
|
||||
@@ -35,11 +35,10 @@ rocket = { optional = true, version = "0.5.0-rc.2", default-features = false }
|
||||
# Serialisation
|
||||
revolt_optional_struct = { version = "0.2.0", optional = true }
|
||||
serde = { version = "1", features = ["derive"], optional = true }
|
||||
iso8601-timestamp = { version = "0.2.11", features = ["schema", "bson"] }
|
||||
iso8601-timestamp = { version = "0.4.0", features = ["utoipa", "bson"] }
|
||||
|
||||
# Spec Generation
|
||||
schemars = { version = "0.8.8", optional = true, features = ["indexmap1"] }
|
||||
utoipa = { version = "4.2.3", optional = true }
|
||||
utoipa = { version = "5.4.0", features = ["indexmap"], optional = true }
|
||||
|
||||
# Validation
|
||||
validator = { version = "0.16.0", optional = true, features = ["derive"] }
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
#[macro_use]
|
||||
extern crate serde;
|
||||
|
||||
#[cfg(feature = "schemas")]
|
||||
#[macro_use]
|
||||
extern crate schemars;
|
||||
|
||||
#[cfg(feature = "utoipa")]
|
||||
#[macro_use]
|
||||
extern crate utoipa;
|
||||
@@ -21,7 +17,6 @@ macro_rules! auto_derived {
|
||||
( $( $item:item )+ ) => {
|
||||
$(
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "schemas", derive(JsonSchema))]
|
||||
#[cfg_attr(feature = "utoipa", derive(ToSchema))]
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
$item
|
||||
@@ -32,19 +27,8 @@ macro_rules! auto_derived {
|
||||
#[cfg(feature = "partials")]
|
||||
macro_rules! auto_derived_partial {
|
||||
( $item:item, $name:expr ) => {
|
||||
#[derive(
|
||||
OptionalStruct, Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema,
|
||||
)]
|
||||
#[optional_derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Eq,
|
||||
PartialEq,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
JsonSchema,
|
||||
Default
|
||||
)]
|
||||
#[derive(OptionalStruct, Debug, Clone, Eq, PartialEq, Serialize, Deserialize, ToSchema)]
|
||||
#[optional_derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, ToSchema, Default)]
|
||||
#[optional_name = $name]
|
||||
#[opt_skip_serializing_none]
|
||||
#[opt_some_priority]
|
||||
@@ -55,7 +39,7 @@ macro_rules! auto_derived_partial {
|
||||
#[cfg(not(feature = "partials"))]
|
||||
macro_rules! auto_derived_partial {
|
||||
( $item:item, $name:expr ) => {
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, ToSchema)]
|
||||
$item
|
||||
};
|
||||
}
|
||||
|
||||
@@ -86,10 +86,10 @@ auto_derived!(
|
||||
/// Information for the webhook
|
||||
#[cfg_attr(feature = "validator", derive(Validate))]
|
||||
pub struct CreateWebhookBody {
|
||||
#[validate(length(min = 1, max = 32))]
|
||||
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 32)))]
|
||||
pub name: String,
|
||||
|
||||
#[validate(length(min = 1, max = 128))]
|
||||
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 128)))]
|
||||
pub avatar: Option<String>,
|
||||
}
|
||||
);
|
||||
|
||||
73
crates/core/models/src/v0/config.rs
Normal file
73
crates/core/models/src/v0/config.rs
Normal file
@@ -0,0 +1,73 @@
|
||||
auto_derived!(
|
||||
/// # hCaptcha Configuration
|
||||
pub struct CaptchaFeature {
|
||||
/// Whether captcha is enabled
|
||||
pub enabled: bool,
|
||||
/// Client key used for solving captcha
|
||||
pub key: String,
|
||||
}
|
||||
|
||||
/// # Generic Service Configuration
|
||||
pub struct Feature {
|
||||
/// Whether the service is enabled
|
||||
pub enabled: bool,
|
||||
/// URL pointing to the service
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
/// # Voice Server Configuration
|
||||
pub struct VoiceFeature {
|
||||
/// Whether voice is enabled
|
||||
pub enabled: bool,
|
||||
/// URL pointing to the voice API
|
||||
pub url: String,
|
||||
/// URL pointing to the voice WebSocket server
|
||||
pub ws: String,
|
||||
}
|
||||
|
||||
/// # Feature Configuration
|
||||
pub struct RevoltFeatures {
|
||||
/// hCaptcha configuration
|
||||
pub captcha: CaptchaFeature,
|
||||
/// Whether email verification is enabled
|
||||
pub email: bool,
|
||||
/// Whether this server is invite only
|
||||
pub invite_only: bool,
|
||||
/// File server service configuration
|
||||
pub autumn: Feature,
|
||||
/// Proxy service configuration
|
||||
pub january: Feature,
|
||||
/// Voice server configuration
|
||||
pub voso: VoiceFeature,
|
||||
}
|
||||
|
||||
/// # Build Information
|
||||
pub struct BuildInformation {
|
||||
/// Commit Hash
|
||||
pub commit_sha: String,
|
||||
/// Commit Timestamp
|
||||
pub commit_timestamp: String,
|
||||
/// Git Semver
|
||||
pub semver: String,
|
||||
/// Git Origin URL
|
||||
pub origin_url: String,
|
||||
/// Build Timestamp
|
||||
pub timestamp: String,
|
||||
}
|
||||
|
||||
/// # Server Configuration
|
||||
pub struct RevoltConfig {
|
||||
/// Revolt API Version
|
||||
pub revolt: String,
|
||||
/// Features enabled on this Revolt node
|
||||
pub features: RevoltFeatures,
|
||||
/// WebSocket URL
|
||||
pub ws: String,
|
||||
/// URL pointing to the client serving this node
|
||||
pub app: String,
|
||||
/// Web Push VAPID public key
|
||||
pub vapid: String,
|
||||
/// Build information
|
||||
pub build: BuildInformation,
|
||||
}
|
||||
);
|
||||
@@ -46,7 +46,7 @@ auto_derived!(
|
||||
#[cfg_attr(feature = "validator", derive(Validate))]
|
||||
pub struct DataCreateEmoji {
|
||||
/// Server name
|
||||
#[validate(length(min = 1, max = 32), regex = "RE_EMOJI")]
|
||||
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 32), regex = "RE_EMOJI"))]
|
||||
pub name: String,
|
||||
/// Parent information
|
||||
pub parent: EmojiParent,
|
||||
|
||||
@@ -139,17 +139,17 @@ auto_derived!(
|
||||
pub struct Masquerade {
|
||||
/// Replace the display name shown on this message
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[validate(length(min = 1, max = 32))]
|
||||
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 32)))]
|
||||
pub name: Option<String>,
|
||||
/// Replace the avatar shown on this message (URL to image file)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[validate(length(min = 1, max = 256))]
|
||||
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 256)))]
|
||||
pub avatar: Option<String>,
|
||||
/// Replace the display role colour shown on this message
|
||||
///
|
||||
/// Must have `ManageRole` permission to use
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[validate(length(min = 1, max = 128), regex = "RE_COLOUR")]
|
||||
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 128), regex = "RE_COLOUR"))]
|
||||
pub colour: Option<String>,
|
||||
}
|
||||
|
||||
@@ -351,7 +351,7 @@ auto_derived!(
|
||||
)]
|
||||
pub struct OptionsBulkDelete {
|
||||
/// Message IDs
|
||||
#[validate(length(min = 1, max = 100))]
|
||||
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 100)))]
|
||||
pub ids: Vec<String>,
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ mod channel_invites;
|
||||
mod channel_unreads;
|
||||
mod channel_webhooks;
|
||||
mod channels;
|
||||
mod config;
|
||||
mod embeds;
|
||||
mod emojis;
|
||||
mod files;
|
||||
@@ -20,6 +21,7 @@ pub use channel_invites::*;
|
||||
pub use channel_unreads::*;
|
||||
pub use channel_webhooks::*;
|
||||
pub use channels::*;
|
||||
pub use config::*;
|
||||
pub use embeds::*;
|
||||
pub use emojis::*;
|
||||
pub use files::*;
|
||||
|
||||
@@ -141,7 +141,7 @@ auto_derived!(
|
||||
#[cfg_attr(feature = "validator", derive(Validate))]
|
||||
pub struct UserStatus {
|
||||
/// Custom status text
|
||||
#[validate(length(min = 0, max = 128))]
|
||||
#[cfg_attr(feature = "validator", validate(length(min = 0, max = 128)))]
|
||||
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
|
||||
pub text: Option<String>,
|
||||
/// Current presence option
|
||||
@@ -154,7 +154,7 @@ auto_derived!(
|
||||
#[cfg_attr(feature = "validator", derive(Validate))]
|
||||
pub struct UserProfile {
|
||||
/// Text content on user's profile
|
||||
#[validate(length(min = 0, max = 2000))]
|
||||
#[cfg_attr(feature = "validator", validate(length(min = 0, max = 2000)))]
|
||||
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
|
||||
pub content: Option<String>,
|
||||
/// Background visible on user's profile
|
||||
|
||||
@@ -11,10 +11,8 @@ description = "Revolt Backend: Permission Logic"
|
||||
[features]
|
||||
bson = ["dep:bson"]
|
||||
serde = ["dep:serde"]
|
||||
schemas = ["dep:schemars"]
|
||||
try-from-primitive = ["dep:num_enum"]
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
# Async
|
||||
async-std = { version = "1.8.0", features = ["attributes"] }
|
||||
@@ -36,4 +34,4 @@ serde = { version = "1", features = ["derive"], optional = true }
|
||||
bson = { version = "2.1.0", optional = true }
|
||||
|
||||
# Spec Generation
|
||||
schemars = { version = "0.8.8", optional = true }
|
||||
utoipa = { version = "5.4.0", optional = true }
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#[cfg(feature = "schemas")]
|
||||
use schemars::JsonSchema;
|
||||
#[cfg(feature = "utoipa")]
|
||||
use utoipa::ToSchema;
|
||||
|
||||
/// Representation of a single permission override
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Default)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "schemas", derive(JsonSchema))]
|
||||
#[cfg_attr(feature = "utoipa", derive(ToSchema))]
|
||||
pub struct Override {
|
||||
/// Allow bit flags
|
||||
pub allow: u64,
|
||||
@@ -15,7 +15,7 @@ pub struct Override {
|
||||
/// Data permissions Field - contains both allow and deny
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "schemas", derive(JsonSchema))]
|
||||
#[cfg_attr(feature = "utoipa", derive(ToSchema))]
|
||||
pub struct DataPermissionsField {
|
||||
pub permissions: Override,
|
||||
}
|
||||
@@ -23,7 +23,7 @@ pub struct DataPermissionsField {
|
||||
/// Data permissions Value - contains allow
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "schemas", derive(JsonSchema))]
|
||||
#[cfg_attr(feature = "utoipa", derive(ToSchema))]
|
||||
pub struct DataPermissionsValue {
|
||||
pub permissions: u64,
|
||||
}
|
||||
@@ -31,7 +31,7 @@ pub struct DataPermissionsValue {
|
||||
/// Data permissions Poly - can contain either Value or Field
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "schemas", derive(JsonSchema))]
|
||||
#[cfg_attr(feature = "utoipa", derive(ToSchema))]
|
||||
#[cfg_attr(feature = "serde", serde(untagged))]
|
||||
pub enum DataPermissionPoly {
|
||||
Value {
|
||||
@@ -48,7 +48,7 @@ pub enum DataPermissionPoly {
|
||||
/// as it appears on models and in the database
|
||||
#[derive(Debug, Clone, Copy, Default, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "schemas", derive(JsonSchema))]
|
||||
#[cfg_attr(feature = "utoipa", derive(ToSchema))]
|
||||
pub struct OverrideField {
|
||||
/// Allow bit flags
|
||||
pub a: i64,
|
||||
|
||||
@@ -4,20 +4,24 @@ version = "0.8.9"
|
||||
edition = "2024"
|
||||
|
||||
[features]
|
||||
rocket = ["dep:rocket", "dep:revolt_rocket_okapi", "revolt-database/rocket-impl"]
|
||||
rocket = [
|
||||
"dep:rocket",
|
||||
"dep:revolt_rocket_okapi",
|
||||
"revolt-database/rocket-impl",
|
||||
]
|
||||
axum = ["dep:axum", "revolt-database/axum-impl"]
|
||||
|
||||
default = ["rocket", "axum"]
|
||||
|
||||
[dependencies]
|
||||
revolt-database = { version = "0.8.9", path = "../database"}
|
||||
revolt-database = { version = "0.8.9", path = "../database" }
|
||||
revolt-result = { version = "0.8.9", path = "../result" }
|
||||
revolt-config = { version = "0.8.9", path = "../config" }
|
||||
|
||||
rocket = { version = "0.5.1", optional = true }
|
||||
revolt_rocket_okapi = { version = "0.10.0", optional = true }
|
||||
|
||||
axum = { version = "0.7.5", optional = true, features = ["macros"] }
|
||||
axum = { version = "0.8.6", optional = true, features = ["macros"] }
|
||||
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
authifier = { version = "1.0.15" }
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use axum::{
|
||||
Json, RequestPartsExt, Router,
|
||||
body::Body,
|
||||
@@ -44,7 +43,6 @@ async fn to_real_ip(parts: &Parts) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<S: Send + Sync> FromRequestParts<S> for Ratelimiter
|
||||
where
|
||||
Database: FromRef<S>,
|
||||
@@ -82,7 +80,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<S: Send + Sync> FromRequestParts<S> for RatelimitInformation
|
||||
where
|
||||
Database: FromRef<S>,
|
||||
|
||||
@@ -10,11 +10,9 @@ description = "Revolt Backend: Result and Error types"
|
||||
|
||||
[features]
|
||||
serde = ["dep:serde"]
|
||||
schemas = ["dep:schemars"]
|
||||
utoipa = ["dep:utoipa"]
|
||||
rocket = ["dep:rocket", "dep:serde_json"]
|
||||
axum = ["dep:axum", "dep:serde_json"]
|
||||
okapi = ["dep:revolt_rocket_okapi", "dep:revolt_okapi", "schemas"]
|
||||
|
||||
default = ["serde"]
|
||||
|
||||
@@ -24,13 +22,10 @@ serde_json = { version = "1", optional = true }
|
||||
serde = { version = "1", features = ["derive"], optional = true }
|
||||
|
||||
# Spec Generation
|
||||
schemars = { version = "0.8.8", optional = true }
|
||||
utoipa = { version = "4.2.3", optional = true }
|
||||
utoipa = { version = "5.4.0", optional = true }
|
||||
|
||||
# Rocket
|
||||
rocket = { optional = true, version = "0.5.0-rc.2", default-features = false }
|
||||
revolt_rocket_okapi = { version = "0.10.0", optional = true }
|
||||
revolt_okapi = { version = "0.9.1", optional = true }
|
||||
|
||||
# Axum
|
||||
axum = { version = "0.7.5", optional = true }
|
||||
axum = { version = "0.8.6", optional = true }
|
||||
|
||||
@@ -4,10 +4,6 @@ use std::fmt::Display;
|
||||
#[macro_use]
|
||||
extern crate serde;
|
||||
|
||||
#[cfg(feature = "schemas")]
|
||||
#[macro_use]
|
||||
extern crate schemars;
|
||||
|
||||
#[cfg(feature = "utoipa")]
|
||||
#[macro_use]
|
||||
extern crate utoipa;
|
||||
@@ -18,15 +14,11 @@ pub mod rocket;
|
||||
#[cfg(feature = "axum")]
|
||||
pub mod axum;
|
||||
|
||||
#[cfg(feature = "okapi")]
|
||||
pub mod okapi;
|
||||
|
||||
/// Result type with custom Error
|
||||
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
||||
|
||||
/// Error information
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "schemas", derive(JsonSchema))]
|
||||
#[cfg_attr(feature = "utoipa", derive(ToSchema))]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Error {
|
||||
@@ -49,7 +41,6 @@ impl std::error::Error for Error {}
|
||||
/// Possible error types
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(tag = "type"))]
|
||||
#[cfg_attr(feature = "schemas", derive(JsonSchema))]
|
||||
#[cfg_attr(feature = "utoipa", derive(ToSchema))]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ErrorType {
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
use revolt_okapi::openapi3::SchemaObject;
|
||||
use revolt_rocket_okapi::revolt_okapi::openapi3;
|
||||
use schemars::schema::Schema;
|
||||
|
||||
use crate::Error;
|
||||
|
||||
impl revolt_rocket_okapi::response::OpenApiResponderInner for Error {
|
||||
fn responses(
|
||||
gen: &mut revolt_rocket_okapi::gen::OpenApiGenerator,
|
||||
) -> std::result::Result<openapi3::Responses, revolt_rocket_okapi::OpenApiError> {
|
||||
let mut content = revolt_okapi::Map::new();
|
||||
|
||||
let settings = schemars::gen::SchemaSettings::default().with(|s| {
|
||||
s.option_nullable = true;
|
||||
s.option_add_null_type = false;
|
||||
s.definitions_path = "#/components/schemas/".to_string();
|
||||
});
|
||||
|
||||
let mut schema_generator = settings.into_generator();
|
||||
let schema = schema_generator.root_schema_for::<Error>();
|
||||
|
||||
let definitions = gen.schema_generator().definitions_mut();
|
||||
for (key, value) in schema.definitions {
|
||||
definitions.insert(key, value);
|
||||
}
|
||||
|
||||
definitions.insert("Error".to_string(), Schema::Object(schema.schema));
|
||||
|
||||
content.insert(
|
||||
"application/json".to_string(),
|
||||
openapi3::MediaType {
|
||||
schema: Some(SchemaObject {
|
||||
reference: Some("#/components/schemas/Error".to_string()),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
Ok(openapi3::Responses {
|
||||
default: Some(openapi3::RefOr::Object(openapi3::Response {
|
||||
content,
|
||||
description: "An error occurred.".to_string(),
|
||||
..Default::default()
|
||||
})),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user