fix: fix credential3rd graphql
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
use async_graphql::Error as AsyncGraphQLError;
|
||||
use seaography::SeaographyError;
|
||||
|
||||
#[derive(Debug, snafu::Snafu)]
|
||||
pub enum CryptoError {
|
||||
#[snafu(transparent)]
|
||||
@@ -9,3 +12,9 @@ pub enum CryptoError {
|
||||
#[snafu(transparent)]
|
||||
SerdeJsonError { source: serde_json::Error },
|
||||
}
|
||||
|
||||
impl From<CryptoError> for SeaographyError {
|
||||
fn from(error: CryptoError) -> Self {
|
||||
SeaographyError::AsyncGraphQLError(AsyncGraphQLError::new(error.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
use std::{collections::BTreeMap, sync::Arc};
|
||||
|
||||
use async_graphql::dynamic::ResolverContext;
|
||||
use sea_orm::{ColumnTrait, Condition, EntityTrait, Value};
|
||||
use seaography::{BuilderContext, FnFilterConditionsTransformer, FnMutationInputObjectTransformer};
|
||||
use async_graphql::dynamic::{ResolverContext, ValueAccessor};
|
||||
use sea_orm::{ColumnTrait, Condition, EntityTrait, Value as SeaValue};
|
||||
use seaography::{
|
||||
BuilderContext, FnFilterConditionsTransformer, FnMutationInputObjectTransformer, SeaResult,
|
||||
};
|
||||
|
||||
use super::util::{get_column_key, get_entity_key};
|
||||
use crate::auth::AuthUserInfo;
|
||||
use crate::{app::AppContextTrait, auth::AuthUserInfo, models::credential_3rd};
|
||||
|
||||
pub fn filter_condition_transformer<T>(
|
||||
pub fn build_filter_condition_transformer<T>(
|
||||
_context: &BuilderContext,
|
||||
column: &T::Column,
|
||||
) -> FnFilterConditionsTransformer
|
||||
@@ -29,7 +31,7 @@ where
|
||||
)
|
||||
}
|
||||
|
||||
pub fn mutation_input_object_transformer<T>(
|
||||
pub fn build_mutation_input_object_transformer<T>(
|
||||
context: &BuilderContext,
|
||||
column: &T::Column,
|
||||
) -> FnMutationInputObjectTransformer
|
||||
@@ -55,8 +57,8 @@ where
|
||||
));
|
||||
Box::new(
|
||||
move |context: &ResolverContext,
|
||||
mut input: BTreeMap<String, Value>|
|
||||
-> BTreeMap<String, Value> {
|
||||
mut input: BTreeMap<String, SeaValue>|
|
||||
-> BTreeMap<String, SeaValue> {
|
||||
let field_name = context.field().name();
|
||||
if field_name == entity_create_one_mutation_field_name.as_str()
|
||||
|| field_name == entity_create_batch_mutation_field_name.as_str()
|
||||
@@ -68,7 +70,7 @@ where
|
||||
if value.is_none() {
|
||||
input.insert(
|
||||
column_name.as_str().to_string(),
|
||||
Value::Int(Some(subscriber_id)),
|
||||
SeaValue::Int(Some(subscriber_id)),
|
||||
);
|
||||
}
|
||||
input
|
||||
@@ -81,3 +83,91 @@ where
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn add_crypto_column_input_conversion<T>(
|
||||
context: &mut BuilderContext,
|
||||
ctx: Arc<dyn AppContextTrait>,
|
||||
column: &T::Column,
|
||||
) where
|
||||
T: EntityTrait,
|
||||
<T as EntityTrait>::Model: Sync,
|
||||
{
|
||||
let entity_key = get_entity_key::<T>(context);
|
||||
let column_name = get_column_key::<T>(context, column);
|
||||
let entity_name = context.entity_object.type_name.as_ref()(&entity_key);
|
||||
let column_name = context.entity_object.column_name.as_ref()(&entity_key, &column_name);
|
||||
|
||||
context.types.input_conversions.insert(
|
||||
format!("{entity_name}.{column_name}"),
|
||||
Box::new(move |value: &ValueAccessor| -> SeaResult<sea_orm::Value> {
|
||||
let source = value.string()?;
|
||||
let encrypted = ctx.crypto().encrypt_string(source.into())?;
|
||||
Ok(encrypted.into())
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
fn add_crypto_column_output_conversion<T>(
|
||||
context: &mut BuilderContext,
|
||||
ctx: Arc<dyn AppContextTrait>,
|
||||
column: &T::Column,
|
||||
) where
|
||||
T: EntityTrait,
|
||||
<T as EntityTrait>::Model: Sync,
|
||||
{
|
||||
let entity_key = get_entity_key::<T>(context);
|
||||
let column_name = get_column_key::<T>(context, column);
|
||||
let entity_name = context.entity_object.type_name.as_ref()(&entity_key);
|
||||
let column_name = context.entity_object.column_name.as_ref()(&entity_key, &column_name);
|
||||
|
||||
context.types.output_conversions.insert(
|
||||
format!("{entity_name}.{column_name}"),
|
||||
Box::new(
|
||||
move |value: &sea_orm::Value| -> SeaResult<async_graphql::Value> {
|
||||
if let SeaValue::String(s) = value {
|
||||
if let Some(s) = s {
|
||||
let decrypted = ctx.crypto().decrypt_string(s)?;
|
||||
Ok(async_graphql::Value::String(decrypted))
|
||||
} else {
|
||||
Ok(async_graphql::Value::Null)
|
||||
}
|
||||
} else {
|
||||
Err(async_graphql::Error::new("crypto column must be string column").into())
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn crypto_transformer(context: &mut BuilderContext, ctx: Arc<dyn AppContextTrait>) {
|
||||
add_crypto_column_input_conversion::<credential_3rd::Entity>(
|
||||
context,
|
||||
ctx.clone(),
|
||||
&credential_3rd::Column::Cookies,
|
||||
);
|
||||
add_crypto_column_input_conversion::<credential_3rd::Entity>(
|
||||
context,
|
||||
ctx.clone(),
|
||||
&credential_3rd::Column::Username,
|
||||
);
|
||||
add_crypto_column_output_conversion::<credential_3rd::Entity>(
|
||||
context,
|
||||
ctx.clone(),
|
||||
&credential_3rd::Column::Password,
|
||||
);
|
||||
add_crypto_column_output_conversion::<credential_3rd::Entity>(
|
||||
context,
|
||||
ctx.clone(),
|
||||
&credential_3rd::Column::Cookies,
|
||||
);
|
||||
add_crypto_column_output_conversion::<credential_3rd::Entity>(
|
||||
context,
|
||||
ctx.clone(),
|
||||
&credential_3rd::Column::Username,
|
||||
);
|
||||
add_crypto_column_output_conversion::<credential_3rd::Entity>(
|
||||
context,
|
||||
ctx,
|
||||
&credential_3rd::Column::Password,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
pub mod config;
|
||||
pub mod infra;
|
||||
pub mod schema_root;
|
||||
mod schema;
|
||||
pub mod service;
|
||||
pub mod views;
|
||||
|
||||
pub use config::GraphQLConfig;
|
||||
pub use schema_root::schema;
|
||||
pub use schema::build_schema;
|
||||
pub use service::GraphQLService;
|
||||
|
||||
@@ -10,7 +10,9 @@ use crate::graphql::{
|
||||
register_jsonb_input_filter_to_dynamic_schema, subscriber_id_condition_function,
|
||||
},
|
||||
guard::{guard_entity_with_subscriber_id, guard_field_with_subscriber_id},
|
||||
transformer::{filter_condition_transformer, mutation_input_object_transformer},
|
||||
transformer::{
|
||||
build_filter_condition_transformer, build_mutation_input_object_transformer,
|
||||
},
|
||||
util::{get_entity_column_key, get_entity_key},
|
||||
},
|
||||
views::register_subscriptions_to_schema,
|
||||
@@ -69,14 +71,14 @@ where
|
||||
);
|
||||
context.transformers.filter_conditions_transformers.insert(
|
||||
entity_key.clone(),
|
||||
filter_condition_transformer::<T>(context, column),
|
||||
build_filter_condition_transformer::<T>(context, column),
|
||||
);
|
||||
context
|
||||
.transformers
|
||||
.mutation_input_object_transformers
|
||||
.insert(
|
||||
entity_key,
|
||||
mutation_input_object_transformer::<T>(context, column),
|
||||
build_mutation_input_object_transformer::<T>(context, column),
|
||||
);
|
||||
context
|
||||
.entity_input
|
||||
@@ -85,7 +87,7 @@ where
|
||||
context.entity_input.update_skips.push(entity_column_key);
|
||||
}
|
||||
|
||||
pub fn schema(
|
||||
pub fn build_schema(
|
||||
database: DatabaseConnection,
|
||||
depth: Option<usize>,
|
||||
complexity: Option<usize>,
|
||||
@@ -138,6 +140,10 @@ pub fn schema(
|
||||
&mut context,
|
||||
&subscriber_tasks::Column::SubscriberId,
|
||||
);
|
||||
restrict_subscriber_for_entity::<credential_3rd::Entity>(
|
||||
&mut context,
|
||||
&credential_3rd::Column::SubscriberId,
|
||||
);
|
||||
restrict_jsonb_filter_input_for_entity::<subscriber_tasks::Entity>(
|
||||
&mut context,
|
||||
&subscriber_tasks::Column::Job,
|
||||
@@ -185,6 +191,7 @@ pub fn schema(
|
||||
subscription_episode,
|
||||
subscriptions,
|
||||
subscriber_tasks,
|
||||
credential_3rd
|
||||
]
|
||||
);
|
||||
|
||||
@@ -193,6 +200,7 @@ pub fn schema(
|
||||
builder.register_enumeration::<subscriptions::SubscriptionCategory>();
|
||||
builder.register_enumeration::<downloaders::DownloaderCategory>();
|
||||
builder.register_enumeration::<downloads::DownloadMime>();
|
||||
builder.register_enumeration::<credential_3rd::Credential3rdType>();
|
||||
}
|
||||
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
use async_graphql::dynamic::Schema;
|
||||
use sea_orm::DatabaseConnection;
|
||||
|
||||
use super::{config::GraphQLConfig, schema_root};
|
||||
use super::{build_schema, config::GraphQLConfig};
|
||||
use crate::errors::RecorderResult;
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -14,7 +14,7 @@ impl GraphQLService {
|
||||
config: GraphQLConfig,
|
||||
db: DatabaseConnection,
|
||||
) -> RecorderResult<Self> {
|
||||
let schema = schema_root::schema(
|
||||
let schema = build_schema(
|
||||
db,
|
||||
config.depth_limit.and_then(|l| l.into()),
|
||||
config.complexity_limit.and_then(|l| l.into()),
|
||||
|
||||
@@ -66,6 +66,14 @@ impl Related<super::subscriptions::Entity> for Entity {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelatedEntity)]
|
||||
pub enum RelatedEntity {
|
||||
#[sea_orm(entity = "super::subscribers::Entity")]
|
||||
Subscriber,
|
||||
#[sea_orm(entity = "super::subscriptions::Entity")]
|
||||
Subscription,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ pub enum Relation {
|
||||
Episode,
|
||||
#[sea_orm(has_many = "super::auth::Entity")]
|
||||
Auth,
|
||||
#[sea_orm(has_many = "super::credential_3rd::Entity")]
|
||||
Credential3rd,
|
||||
}
|
||||
|
||||
impl Related<super::subscriptions::Entity> for Entity {
|
||||
@@ -71,6 +73,12 @@ impl Related<super::auth::Entity> for Entity {
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::credential_3rd::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Credential3rd.def()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelatedEntity)]
|
||||
pub enum RelatedEntity {
|
||||
#[sea_orm(entity = "super::subscriptions::Entity")]
|
||||
@@ -81,6 +89,8 @@ pub enum RelatedEntity {
|
||||
Bangumi,
|
||||
#[sea_orm(entity = "super::episodes::Entity")]
|
||||
Episode,
|
||||
#[sea_orm(entity = "super::credential_3rd::Entity")]
|
||||
Credential3rd,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
@@ -103,7 +113,7 @@ impl Model {
|
||||
let subscriber = Entity::find_by_id(id)
|
||||
.one(db)
|
||||
.await?
|
||||
.ok_or_else(|| RecorderError::from_db_record_not_found("subscriptions::find_by_id"))?;
|
||||
.ok_or_else(|| RecorderError::from_db_record_not_found("subscribers::find_by_id"))?;
|
||||
Ok(subscriber)
|
||||
}
|
||||
|
||||
|
||||
@@ -141,6 +141,8 @@ pub enum RelatedEntity {
|
||||
SubscriptionEpisode,
|
||||
#[sea_orm(entity = "super::subscription_bangumi::Entity")]
|
||||
SubscriptionBangumi,
|
||||
#[sea_orm(entity = "super::credential_3rd::Entity")]
|
||||
Credential3rd,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
|
||||
Reference in New Issue
Block a user