feat: add custom types for subscriber id input filter
This commit is contained in:
parent
c2f74dc369
commit
4f9e74ceb4
@ -91,7 +91,7 @@ bollard = { version = "0.18", optional = true }
|
|||||||
async-graphql = { version = "7.0.15", features = [] }
|
async-graphql = { version = "7.0.15", features = [] }
|
||||||
async-graphql-axum = "7.0.15"
|
async-graphql-axum = "7.0.15"
|
||||||
fastrand = "2.3.0"
|
fastrand = "2.3.0"
|
||||||
seaography = "1.1"
|
seaography = { version = "1.1" }
|
||||||
quirks_path = "0.1.1"
|
quirks_path = "0.1.1"
|
||||||
base64 = "0.22.1"
|
base64 = "0.22.1"
|
||||||
tower = "0.5.2"
|
tower = "0.5.2"
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use async_graphql::{
|
|
||||||
ServerResult, Value,
|
|
||||||
extensions::{Extension, ExtensionContext, ExtensionFactory, NextResolve, ResolveInfo},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct GraphqlAuthExtension;
|
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
|
||||||
impl Extension for GraphqlAuthExtension {
|
|
||||||
async fn resolve(
|
|
||||||
&self,
|
|
||||||
ctx: &ExtensionContext<'_>,
|
|
||||||
info: ResolveInfo<'_>,
|
|
||||||
next: NextResolve<'_>,
|
|
||||||
) -> ServerResult<Option<Value>> {
|
|
||||||
dbg!(info.field);
|
|
||||||
next.run(ctx, info).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ExtensionFactory for GraphqlAuthExtension {
|
|
||||||
fn create(&self) -> Arc<dyn Extension> {
|
|
||||||
Arc::new(GraphqlAuthExtension)
|
|
||||||
}
|
|
||||||
}
|
|
46
apps/recorder/src/graphql/filter.rs
Normal file
46
apps/recorder/src/graphql/filter.rs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
use async_graphql::dynamic::{ObjectAccessor, TypeRef};
|
||||||
|
use maplit::btreeset;
|
||||||
|
use once_cell::sync::OnceCell;
|
||||||
|
use sea_orm::{ColumnTrait, Condition, EntityTrait, Value};
|
||||||
|
use seaography::{BuilderContext, FilterInfo, FilterOperation, SeaResult};
|
||||||
|
|
||||||
|
pub static SUBSCRIBER_ID_FILTER_INFO: OnceCell<FilterInfo> = OnceCell::new();
|
||||||
|
|
||||||
|
pub fn init_custom_filter_info() {
|
||||||
|
SUBSCRIBER_ID_FILTER_INFO.get_or_init(|| FilterInfo {
|
||||||
|
type_name: String::from("SubscriberIdFilterInput"),
|
||||||
|
base_type: TypeRef::INT.into(),
|
||||||
|
supported_operations: btreeset! { FilterOperation::Equals },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type FnFilterCondition =
|
||||||
|
Box<dyn Fn(Condition, &ObjectAccessor) -> SeaResult<Condition> + Send + Sync>;
|
||||||
|
|
||||||
|
pub fn subscriber_id_condition_function<T>(
|
||||||
|
_context: &BuilderContext,
|
||||||
|
column: &T::Column,
|
||||||
|
) -> FnFilterCondition
|
||||||
|
where
|
||||||
|
T: EntityTrait,
|
||||||
|
<T as EntityTrait>::Model: Sync,
|
||||||
|
{
|
||||||
|
let column = *column;
|
||||||
|
Box::new(move |mut condition, filter| {
|
||||||
|
let subscriber_id_filter_info = SUBSCRIBER_ID_FILTER_INFO.get().unwrap();
|
||||||
|
let operations = &subscriber_id_filter_info.supported_operations;
|
||||||
|
for operation in operations {
|
||||||
|
match operation {
|
||||||
|
FilterOperation::Equals => {
|
||||||
|
if let Some(value) = filter.get("eq") {
|
||||||
|
let value: i32 = value.i64()?.try_into()?;
|
||||||
|
let value = Value::Int(Some(value));
|
||||||
|
condition = condition.add(column.eq(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!("unreachable filter operation for subscriber_id"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(condition)
|
||||||
|
})
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod extention;
|
|
||||||
pub mod guard;
|
pub mod guard;
|
||||||
pub mod schema_root;
|
pub mod schema_root;
|
||||||
pub mod service;
|
pub mod service;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
|
pub mod filter;
|
||||||
|
|
||||||
pub use schema_root::schema;
|
pub use schema_root::schema;
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
use async_graphql::dynamic::*;
|
use async_graphql::dynamic::*;
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use sea_orm::{DatabaseConnection, EntityTrait, Iterable};
|
use sea_orm::{DatabaseConnection, EntityTrait, Iterable};
|
||||||
use seaography::{Builder, BuilderContext, FilterType, FnGuard};
|
use seaography::{Builder, BuilderContext, FilterType, FilterTypesMapHelper};
|
||||||
|
|
||||||
use super::util::{get_entity_column_key, get_entity_key};
|
use super::{
|
||||||
use crate::graphql::guard::guard_entity_with_subscriber_id;
|
filter::{SUBSCRIBER_ID_FILTER_INFO, subscriber_id_condition_function},
|
||||||
|
util::{get_entity_column_key, get_entity_key},
|
||||||
|
};
|
||||||
|
use crate::graphql::{filter::init_custom_filter_info, guard::guard_entity_with_subscriber_id};
|
||||||
|
|
||||||
static CONTEXT: OnceCell<BuilderContext> = OnceCell::new();
|
static CONTEXT: OnceCell<BuilderContext> = OnceCell::new();
|
||||||
|
|
||||||
@ -20,19 +23,27 @@ fn restrict_filter_input_for_entity<T>(
|
|||||||
context.filter_types.overwrites.insert(key, filter_type);
|
context.filter_types.overwrites.insert(key, filter_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn restrict_subscriber_for_entity<T>(
|
fn restrict_subscriber_for_entity<T>(context: &mut BuilderContext, column: &T::Column)
|
||||||
context: &mut BuilderContext,
|
where
|
||||||
column: &T::Column,
|
|
||||||
entity_guard: impl FnOnce(&BuilderContext, &T::Column) -> FnGuard,
|
|
||||||
) where
|
|
||||||
T: EntityTrait,
|
T: EntityTrait,
|
||||||
<T as EntityTrait>::Model: Sync,
|
<T as EntityTrait>::Model: Sync,
|
||||||
{
|
{
|
||||||
let entity_key = get_entity_key::<T>(context);
|
let entity_key = get_entity_key::<T>(context);
|
||||||
context
|
let entity_column_key = get_entity_column_key::<T>(context, column);
|
||||||
.guards
|
context.guards.entity_guards.insert(
|
||||||
.entity_guards
|
entity_key,
|
||||||
.insert(entity_key, entity_guard(context, column));
|
guard_entity_with_subscriber_id::<T>(context, column),
|
||||||
|
);
|
||||||
|
context.filter_types.overwrites.insert(
|
||||||
|
entity_column_key.clone(),
|
||||||
|
Some(FilterType::Custom(
|
||||||
|
SUBSCRIBER_ID_FILTER_INFO.get().unwrap().type_name.clone(),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
context.filter_types.condition_functions.insert(
|
||||||
|
entity_column_key,
|
||||||
|
subscriber_id_condition_function::<T>(context, column),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn schema(
|
pub fn schema(
|
||||||
@ -41,47 +52,41 @@ pub fn schema(
|
|||||||
complexity: Option<usize>,
|
complexity: Option<usize>,
|
||||||
) -> Result<Schema, SchemaError> {
|
) -> Result<Schema, SchemaError> {
|
||||||
use crate::models::*;
|
use crate::models::*;
|
||||||
|
init_custom_filter_info();
|
||||||
let context = CONTEXT.get_or_init(|| {
|
let context = CONTEXT.get_or_init(|| {
|
||||||
let mut context = BuilderContext::default();
|
let mut context = BuilderContext::default();
|
||||||
|
|
||||||
restrict_subscriber_for_entity::<bangumi::Entity>(
|
restrict_subscriber_for_entity::<bangumi::Entity>(
|
||||||
&mut context,
|
&mut context,
|
||||||
&bangumi::Column::SubscriberId,
|
&bangumi::Column::SubscriberId,
|
||||||
guard_entity_with_subscriber_id::<bangumi::Entity>,
|
|
||||||
);
|
);
|
||||||
restrict_subscriber_for_entity::<downloaders::Entity>(
|
restrict_subscriber_for_entity::<downloaders::Entity>(
|
||||||
&mut context,
|
&mut context,
|
||||||
&downloaders::Column::SubscriberId,
|
&downloaders::Column::SubscriberId,
|
||||||
guard_entity_with_subscriber_id::<downloaders::Entity>,
|
|
||||||
);
|
);
|
||||||
restrict_subscriber_for_entity::<downloads::Entity>(
|
restrict_subscriber_for_entity::<downloads::Entity>(
|
||||||
&mut context,
|
&mut context,
|
||||||
&downloads::Column::SubscriberId,
|
&downloads::Column::SubscriberId,
|
||||||
guard_entity_with_subscriber_id::<downloads::Entity>,
|
|
||||||
);
|
);
|
||||||
restrict_subscriber_for_entity::<episodes::Entity>(
|
restrict_subscriber_for_entity::<episodes::Entity>(
|
||||||
&mut context,
|
&mut context,
|
||||||
&episodes::Column::SubscriberId,
|
&episodes::Column::SubscriberId,
|
||||||
guard_entity_with_subscriber_id::<episodes::Entity>,
|
|
||||||
);
|
);
|
||||||
restrict_subscriber_for_entity::<subscriptions::Entity>(
|
restrict_subscriber_for_entity::<subscriptions::Entity>(
|
||||||
&mut context,
|
&mut context,
|
||||||
&subscriptions::Column::SubscriberId,
|
&subscriptions::Column::SubscriberId,
|
||||||
guard_entity_with_subscriber_id::<subscriptions::Entity>,
|
|
||||||
);
|
);
|
||||||
restrict_subscriber_for_entity::<subscribers::Entity>(
|
restrict_subscriber_for_entity::<subscribers::Entity>(
|
||||||
&mut context,
|
&mut context,
|
||||||
&subscribers::Column::Id,
|
&subscribers::Column::Id,
|
||||||
guard_entity_with_subscriber_id::<subscribers::Entity>,
|
|
||||||
);
|
);
|
||||||
restrict_subscriber_for_entity::<subscription_bangumi::Entity>(
|
restrict_subscriber_for_entity::<subscription_bangumi::Entity>(
|
||||||
&mut context,
|
&mut context,
|
||||||
&subscription_bangumi::Column::SubscriberId,
|
&subscription_bangumi::Column::SubscriberId,
|
||||||
guard_entity_with_subscriber_id::<subscription_bangumi::Entity>,
|
|
||||||
);
|
);
|
||||||
restrict_subscriber_for_entity::<subscription_episode::Entity>(
|
restrict_subscriber_for_entity::<subscription_episode::Entity>(
|
||||||
&mut context,
|
&mut context,
|
||||||
&subscription_episode::Column::SubscriberId,
|
&subscription_episode::Column::SubscriberId,
|
||||||
guard_entity_with_subscriber_id::<subscription_episode::Entity>,
|
|
||||||
);
|
);
|
||||||
for column in subscribers::Column::iter() {
|
for column in subscribers::Column::iter() {
|
||||||
if !matches!(column, subscribers::Column::Id) {
|
if !matches!(column, subscribers::Column::Id) {
|
||||||
@ -96,6 +101,14 @@ pub fn schema(
|
|||||||
});
|
});
|
||||||
let mut builder = Builder::new(context, database.clone());
|
let mut builder = Builder::new(context, database.clone());
|
||||||
|
|
||||||
|
{
|
||||||
|
let filter_types_map_helper = FilterTypesMapHelper { context };
|
||||||
|
|
||||||
|
builder.schema = builder.schema.register(
|
||||||
|
filter_types_map_helper.generate_filter_input(SUBSCRIBER_ID_FILTER_INFO.get().unwrap()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
builder.register_entity::<subscribers::Entity>(
|
builder.register_entity::<subscribers::Entity>(
|
||||||
<subscribers::RelatedEntity as sea_orm::Iterable>::iter()
|
<subscribers::RelatedEntity as sea_orm::Iterable>::iter()
|
||||||
|
Loading…
Reference in New Issue
Block a user