diff --git a/apps/recorder/src/graphql/guard.rs b/apps/recorder/src/graphql/guard.rs index 14b3482..2263a0d 100644 --- a/apps/recorder/src/graphql/guard.rs +++ b/apps/recorder/src/graphql/guard.rs @@ -4,11 +4,8 @@ use async_graphql::dynamic::{ResolverContext, ValueAccessor}; use sea_orm::EntityTrait; use seaography::{BuilderContext, FnGuard, GuardAction}; -use super::util::get_entity_key; -use crate::{ - auth::{AuthError, AuthUserInfo}, - graphql::util::get_column_key, -}; +use super::util::{get_column_key, get_entity_key}; +use crate::auth::{AuthError, AuthUserInfo}; fn guard_data_object_accessor_with_subscriber_id( value: ValueAccessor<'_>, @@ -50,27 +47,20 @@ fn guard_data_object_accessor_with_optional_subscriber_id( } } -fn guard_filter_object_accessor_with_subscriber_id( - value: ValueAccessor<'_>, - column_name: &str, - subscriber_id: i32, -) -> async_graphql::Result<()> { - let obj = value.object()?; - let subscriber_id_filter_input_value = obj.try_get(column_name)?; - - let subscriber_id_filter_input_obj = subscriber_id_filter_input_value.object()?; - - let subscriber_id_value = subscriber_id_filter_input_obj.try_get("eq")?; - - let id = subscriber_id_value.i64()?; - if id == subscriber_id as i64 { - Ok(()) - } else { - Err(async_graphql::Error::new("subscriber not match")) - } +pub fn guard_entity_with_subscriber_id(_context: &BuilderContext, _column: &T::Column) -> FnGuard +where + T: EntityTrait, + ::Model: Sync, +{ + Box::new(move |context: &ResolverContext| -> GuardAction { + match context.ctx.data::() { + Ok(_) => GuardAction::Allow, + Err(err) => GuardAction::Block(Some(err.message)), + } + }) } -pub fn guard_entity_with_subscriber_id(context: &BuilderContext, column: &T::Column) -> FnGuard +pub fn guard_field_with_subscriber_id(context: &BuilderContext, column: &T::Column) -> FnGuard where T: EntityTrait, ::Model: Sync, @@ -95,23 +85,13 @@ where )); let entity_create_batch_mutation_data_field_name = Arc::new(context.entity_create_batch_mutation.data_field.clone()); - let entity_delete_mutation_field_name = Arc::new(format!( - "{}{}", - entity_name, - context.entity_delete_mutation.mutation_suffix.clone() - )); - let entity_delete_mutation_filter_field_name = - Arc::new(context.entity_delete_mutation.filter_field.clone()); let entity_update_mutation_field_name = Arc::new(format!( "{}{}", entity_name, context.entity_update_mutation.mutation_suffix )); - let entity_update_mutation_filter_field_name = - Arc::new(context.entity_update_mutation.filter_field.clone()); let entity_update_mutation_data_field_name = Arc::new(context.entity_update_mutation.data_field.clone()); - let entity_query_field_name = Arc::new(entity_name); - let entity_query_filter_field_name = Arc::new(context.entity_query_field.filters.clone()); + Box::new(move |context: &ResolverContext| -> GuardAction { match context.ctx.data::() { Ok(user_info) => { @@ -157,80 +137,26 @@ where &column_name, ) }), - field if field == entity_delete_mutation_field_name.as_str() => context - .args - .try_get(&entity_delete_mutation_filter_field_name) - .and_then(|filter_value| { - guard_filter_object_accessor_with_subscriber_id( - filter_value, - &column_name, - subscriber_id, - ) - }) - .map_err(|inner_error| { - AuthError::from_graphql_subscribe_id_guard( - inner_error, - context, - &entity_delete_mutation_filter_field_name, - &column_name, - ) - }), - field if field == entity_update_mutation_field_name.as_str() => context - .args - .try_get(&entity_update_mutation_filter_field_name) - .and_then(|filter_value| { - guard_filter_object_accessor_with_subscriber_id( - filter_value, - &column_name, - subscriber_id, - ) - }) - .map_err(|inner_error| { - AuthError::from_graphql_subscribe_id_guard( - inner_error, - context, - &entity_update_mutation_filter_field_name, - &column_name, - ) - }) - .and_then(|_| { - match context.args.get(&entity_update_mutation_data_field_name) { - Some(data_value) => { - guard_data_object_accessor_with_optional_subscriber_id( - data_value, + field if field == entity_update_mutation_field_name.as_str() => { + match context.args.get(&entity_update_mutation_data_field_name) { + Some(data_value) => { + guard_data_object_accessor_with_optional_subscriber_id( + data_value, + &column_name, + subscriber_id, + ) + .map_err(|inner_error| { + AuthError::from_graphql_subscribe_id_guard( + inner_error, + context, + &entity_update_mutation_data_field_name, &column_name, - subscriber_id, ) - .map_err(|inner_error| { - AuthError::from_graphql_subscribe_id_guard( - inner_error, - context, - &entity_update_mutation_data_field_name, - &column_name, - ) - }) - } - None => Ok(()), + }) } - }), - field if field == entity_query_field_name.as_str() => context - .args - .try_get(&entity_query_filter_field_name) - .and_then(|filter_value| { - guard_filter_object_accessor_with_subscriber_id( - filter_value, - &column_name, - subscriber_id, - ) - }) - .map_err(|inner_error| { - AuthError::from_graphql_subscribe_id_guard( - inner_error, - context, - &entity_query_filter_field_name, - &column_name, - ) - }), + None => Ok(()), + } + } field => Err(AuthError::from_graphql_subscribe_id_guard( async_graphql::Error::new("unsupport graphql field"), context, diff --git a/apps/recorder/src/graphql/mod.rs b/apps/recorder/src/graphql/mod.rs index 5b07576..cb0b690 100644 --- a/apps/recorder/src/graphql/mod.rs +++ b/apps/recorder/src/graphql/mod.rs @@ -4,6 +4,7 @@ pub mod guard; pub mod schema_root; pub mod service; pub mod subscriptions; +pub mod transformer; pub mod util; pub use config::GraphQLConfig; diff --git a/apps/recorder/src/graphql/schema_root.rs b/apps/recorder/src/graphql/schema_root.rs index a7c518e..d51ad03 100644 --- a/apps/recorder/src/graphql/schema_root.rs +++ b/apps/recorder/src/graphql/schema_root.rs @@ -3,12 +3,12 @@ use once_cell::sync::OnceCell; use sea_orm::{DatabaseConnection, EntityTrait, Iterable}; use seaography::{Builder, BuilderContext, FilterType, FilterTypesMapHelper}; +use super::transformer::filter_condition_transformer; use crate::graphql::{ - extentions::AuthExtensionFactory, filter::{ SUBSCRIBER_ID_FILTER_INFO, init_custom_filter_info, subscriber_id_condition_function, }, - guard::guard_entity_with_subscriber_id, + guard::{guard_entity_with_subscriber_id, guard_field_with_subscriber_id}, util::{get_entity_column_key, get_entity_key}, }; @@ -34,9 +34,13 @@ where let entity_key = get_entity_key::(context); let entity_column_key = get_entity_column_key::(context, column); context.guards.entity_guards.insert( - entity_key, + entity_key.clone(), guard_entity_with_subscriber_id::(context, column), ); + context.guards.field_guards.insert( + entity_column_key.clone(), + guard_field_with_subscriber_id::(context, column), + ); context.filter_types.overwrites.insert( entity_column_key.clone(), Some(FilterType::Custom( @@ -47,6 +51,10 @@ where entity_column_key, subscriber_id_condition_function::(context, column), ); + context.transformers.filter_conditions_transformers.insert( + entity_key, + filter_condition_transformer::(context, column), + ); } pub fn schema( @@ -156,9 +164,6 @@ pub fn schema( }; schema .data(database) - .extension(AuthExtensionFactory { - builder_context: context, - }) .finish() .inspect_err(|e| tracing::error!(e = ?e)) } diff --git a/apps/recorder/src/graphql/transformer.rs b/apps/recorder/src/graphql/transformer.rs new file mode 100644 index 0000000..ab1f03f --- /dev/null +++ b/apps/recorder/src/graphql/transformer.rs @@ -0,0 +1,27 @@ +use async_graphql::dynamic::ResolverContext; +use sea_orm::{ColumnTrait, Condition, EntityTrait}; +use seaography::{BuilderContext, FnFilterConditionsTransformer}; + +use crate::auth::AuthUserInfo; + +pub fn filter_condition_transformer( + _context: &BuilderContext, + column: &T::Column, +) -> FnFilterConditionsTransformer +where + T: EntityTrait, + ::Model: Sync, +{ + let column = *column; + Box::new( + move |context: &ResolverContext, condition: Condition| -> Condition { + match context.ctx.data::() { + Ok(user_info) => { + let subscriber_id = user_info.subscriber_auth.subscriber_id; + condition.add(column.eq(subscriber_id)) + } + Err(err) => unreachable!("auth user info must be guarded: {:?}", err), + } + }, + ) +}