182 lines
7.0 KiB
Rust
182 lines
7.0 KiB
Rust
use std::sync::Arc;
|
|
|
|
use async_graphql::dynamic::{ResolverContext, ValueAccessor};
|
|
use sea_orm::EntityTrait;
|
|
use seaography::{BuilderContext, FnGuard, GuardAction};
|
|
|
|
use super::util::{get_column_key, get_entity_key};
|
|
use crate::auth::{AuthError, AuthUserInfo};
|
|
|
|
fn guard_data_object_accessor_with_subscriber_id(
|
|
value: ValueAccessor<'_>,
|
|
column_name: &str,
|
|
subscriber_id: i32,
|
|
) -> async_graphql::Result<()> {
|
|
let obj = value.object()?;
|
|
|
|
let subscriber_id_value = obj.try_get(column_name)?;
|
|
|
|
let id = subscriber_id_value.i64()?;
|
|
|
|
if id == subscriber_id as i64 {
|
|
Ok(())
|
|
} else {
|
|
Err(async_graphql::Error::new("subscriber not match"))
|
|
}
|
|
}
|
|
|
|
fn guard_data_object_accessor_with_optional_subscriber_id(
|
|
value: ValueAccessor<'_>,
|
|
column_name: &str,
|
|
subscriber_id: i32,
|
|
) -> async_graphql::Result<()> {
|
|
if value.is_null() {
|
|
return Ok(());
|
|
}
|
|
let obj = value.object()?;
|
|
|
|
if let Some(subscriber_id_value) = obj.get(column_name) {
|
|
let id = subscriber_id_value.i64()?;
|
|
if id == subscriber_id as i64 {
|
|
Ok(())
|
|
} else {
|
|
Err(async_graphql::Error::new("subscriber not match"))
|
|
}
|
|
} else {
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
pub fn guard_entity_with_subscriber_id<T>(_context: &BuilderContext, _column: &T::Column) -> FnGuard
|
|
where
|
|
T: EntityTrait,
|
|
<T as EntityTrait>::Model: Sync,
|
|
{
|
|
Box::new(move |context: &ResolverContext| -> GuardAction {
|
|
match context.ctx.data::<AuthUserInfo>() {
|
|
Ok(_) => GuardAction::Allow,
|
|
Err(err) => GuardAction::Block(Some(err.message)),
|
|
}
|
|
})
|
|
}
|
|
|
|
pub fn guard_field_with_subscriber_id<T>(context: &BuilderContext, column: &T::Column) -> FnGuard
|
|
where
|
|
T: EntityTrait,
|
|
<T as EntityTrait>::Model: Sync,
|
|
{
|
|
let entity_key = get_entity_key::<T>(context);
|
|
let entity_name = context.entity_query_field.type_name.as_ref()(&entity_key);
|
|
let column_key = get_column_key::<T>(context, column);
|
|
let column_name = Arc::new(context.entity_object.column_name.as_ref()(
|
|
&entity_key,
|
|
&column_key,
|
|
));
|
|
let entity_create_one_mutation_field_name = Arc::new(format!(
|
|
"{}{}",
|
|
entity_name, context.entity_create_one_mutation.mutation_suffix
|
|
));
|
|
let entity_create_one_mutation_data_field_name =
|
|
Arc::new(context.entity_create_one_mutation.data_field.clone());
|
|
let entity_create_batch_mutation_field_name = Arc::new(format!(
|
|
"{}{}",
|
|
entity_name,
|
|
context.entity_create_batch_mutation.mutation_suffix.clone()
|
|
));
|
|
let entity_create_batch_mutation_data_field_name =
|
|
Arc::new(context.entity_create_batch_mutation.data_field.clone());
|
|
let entity_update_mutation_field_name = Arc::new(format!(
|
|
"{}{}",
|
|
entity_name, context.entity_update_mutation.mutation_suffix
|
|
));
|
|
let entity_update_mutation_data_field_name =
|
|
Arc::new(context.entity_update_mutation.data_field.clone());
|
|
|
|
Box::new(move |context: &ResolverContext| -> GuardAction {
|
|
match context.ctx.data::<AuthUserInfo>() {
|
|
Ok(user_info) => {
|
|
let subscriber_id = user_info.subscriber_auth.subscriber_id;
|
|
let validation_result = match context.field().name() {
|
|
field if field == entity_create_one_mutation_field_name.as_str() => {
|
|
if let Some(data_value) = context
|
|
.args
|
|
.get(&entity_create_one_mutation_data_field_name)
|
|
{
|
|
guard_data_object_accessor_with_subscriber_id(
|
|
data_value,
|
|
&column_name,
|
|
subscriber_id,
|
|
)
|
|
.map_err(|inner_error| {
|
|
AuthError::from_graphql_subscribe_id_guard(
|
|
inner_error,
|
|
context,
|
|
&entity_create_one_mutation_data_field_name,
|
|
&column_name,
|
|
)
|
|
})
|
|
} else {
|
|
Ok(())
|
|
}
|
|
}
|
|
field if field == entity_create_batch_mutation_field_name.as_str() => {
|
|
if let Some(data_value) = context
|
|
.args
|
|
.get(&entity_create_batch_mutation_data_field_name)
|
|
{
|
|
data_value
|
|
.list()
|
|
.and_then(|data_list| {
|
|
data_list.iter().try_for_each(|data_item_value| {
|
|
guard_data_object_accessor_with_optional_subscriber_id(
|
|
data_item_value,
|
|
&column_name,
|
|
subscriber_id,
|
|
)
|
|
})
|
|
})
|
|
.map_err(|inner_error| {
|
|
AuthError::from_graphql_subscribe_id_guard(
|
|
inner_error,
|
|
context,
|
|
&entity_create_batch_mutation_data_field_name,
|
|
&column_name,
|
|
)
|
|
})
|
|
} else {
|
|
Ok(())
|
|
}
|
|
}
|
|
field if field == entity_update_mutation_field_name.as_str() => {
|
|
if let Some(data_value) =
|
|
context.args.get(&entity_update_mutation_data_field_name)
|
|
{
|
|
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,
|
|
)
|
|
})
|
|
} else {
|
|
Ok(())
|
|
}
|
|
}
|
|
_ => Ok(()),
|
|
};
|
|
match validation_result {
|
|
Ok(_) => GuardAction::Allow,
|
|
Err(err) => GuardAction::Block(Some(err.to_string())),
|
|
}
|
|
}
|
|
Err(err) => GuardAction::Block(Some(err.message)),
|
|
}
|
|
})
|
|
}
|