Skip to content

Commit 8e3ff2d

Browse files
authored
feat(router): OnGraphqlAnalysis hook and shared OperationFilter for authorization and plugins (#1279)
1 parent a9da97a commit 8e3ff2d

32 files changed

Lines changed: 2086 additions & 1496 deletions
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
hive-router-plan-executor: minor
3+
hive-router: patch
4+
---
5+
6+
## Add an `on_graphql_analysis` plugin hook with safe operation filtering
7+
8+
Plugin authors can now inspect and filter operation fields after normalization and immediately before query planning. Fields can be kept or nulled with a GraphQL error while the router consistently updates the operation and response projection plan, making the hook suitable for authorization, rate limiting, progressive overrides, and similar policies.

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bin/router/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ ulid = "1.2.1"
8484
tokio-util = { workspace = true }
8585
cookie = "0.18.1"
8686
arc-swap = { workspace = true }
87-
lasso2 = "0.8.2"
8887
anyhow = { workspace = true }
8988
combine = { workspace = true }
9089
strum = { workspace = true }

bin/router/benches/router_benches.rs

Lines changed: 99 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,17 @@ fn authorization_benchmark(c: &mut Criterion) {
9292
b.iter(|| {
9393
let jwt_req_details = JwtRequestDetails::Unauthenticated;
9494

95-
black_box(apply_authorization_to_operation(
96-
bubble_up.normalized_payload,
97-
bubble_up.auth_metadata,
98-
bubble_up.schema_metadata,
99-
bubble_up.variable_payload,
100-
&jwt_req_details,
101-
false,
102-
));
95+
black_box(
96+
apply_authorization_to_operation(
97+
bubble_up.normalized_payload,
98+
bubble_up.auth_metadata,
99+
bubble_up.schema_metadata,
100+
bubble_up.variable_payload,
101+
&jwt_req_details,
102+
false,
103+
)
104+
.unwrap(),
105+
);
103106
})
104107
});
105108

@@ -122,14 +125,17 @@ fn authorization_benchmark(c: &mut Criterion) {
122125
b.iter(|| {
123126
let jwt_req_details = JwtRequestDetails::Unauthenticated;
124127

125-
black_box(apply_authorization_to_operation(
126-
complex.normalized_payload,
127-
complex.auth_metadata,
128-
complex.schema_metadata,
129-
complex.variable_payload,
130-
&jwt_req_details,
131-
false,
132-
));
128+
black_box(
129+
apply_authorization_to_operation(
130+
complex.normalized_payload,
131+
complex.auth_metadata,
132+
complex.schema_metadata,
133+
complex.variable_payload,
134+
&jwt_req_details,
135+
false,
136+
)
137+
.unwrap(),
138+
);
133139
})
134140
});
135141

@@ -157,14 +163,17 @@ fn authorization_benchmark(c: &mut Criterion) {
157163
scopes: Some(vec!["read:shipping".to_string()]),
158164
};
159165

160-
black_box(apply_authorization_to_operation(
161-
complex_partially.normalized_payload,
162-
complex_partially.auth_metadata,
163-
complex_partially.schema_metadata,
164-
complex_partially.variable_payload,
165-
&jwt_req_details,
166-
false,
167-
));
166+
black_box(
167+
apply_authorization_to_operation(
168+
complex_partially.normalized_payload,
169+
complex_partially.auth_metadata,
170+
complex_partially.schema_metadata,
171+
complex_partially.variable_payload,
172+
&jwt_req_details,
173+
false,
174+
)
175+
.unwrap(),
176+
);
168177
})
169178
});
170179

@@ -238,14 +247,17 @@ fn authorization_benchmark(c: &mut Criterion) {
238247
]),
239248
};
240249

241-
black_box(apply_authorization_to_operation(
242-
large_mostly_auth.normalized_payload,
243-
large_mostly_auth.auth_metadata,
244-
large_mostly_auth.schema_metadata,
245-
large_mostly_auth.variable_payload,
246-
&jwt_req_details,
247-
false,
248-
));
250+
black_box(
251+
apply_authorization_to_operation(
252+
large_mostly_auth.normalized_payload,
253+
large_mostly_auth.auth_metadata,
254+
large_mostly_auth.schema_metadata,
255+
large_mostly_auth.variable_payload,
256+
&jwt_req_details,
257+
false,
258+
)
259+
.unwrap(),
260+
);
249261
})
250262
});
251263

@@ -306,14 +318,17 @@ fn authorization_benchmark(c: &mut Criterion) {
306318
scopes: Some(vec![]),
307319
};
308320

309-
black_box(apply_authorization_to_operation(
310-
large_partially_denied.normalized_payload,
311-
large_partially_denied.auth_metadata,
312-
large_partially_denied.schema_metadata,
313-
large_partially_denied.variable_payload,
314-
&jwt_req_details,
315-
false,
316-
));
321+
black_box(
322+
apply_authorization_to_operation(
323+
large_partially_denied.normalized_payload,
324+
large_partially_denied.auth_metadata,
325+
large_partially_denied.schema_metadata,
326+
large_partially_denied.variable_payload,
327+
&jwt_req_details,
328+
false,
329+
)
330+
.unwrap(),
331+
);
317332
})
318333
});
319334

@@ -385,14 +400,17 @@ fn authorization_benchmark(c: &mut Criterion) {
385400
scopes: Some(vec!["read:price".to_string(), "read:shipping".to_string()]),
386401
};
387402

388-
black_box(apply_authorization_to_operation(
389-
deep_nested.normalized_payload,
390-
deep_nested.auth_metadata,
391-
deep_nested.schema_metadata,
392-
deep_nested.variable_payload,
393-
&jwt_req_details,
394-
false,
395-
));
403+
black_box(
404+
apply_authorization_to_operation(
405+
deep_nested.normalized_payload,
406+
deep_nested.auth_metadata,
407+
deep_nested.schema_metadata,
408+
deep_nested.variable_payload,
409+
&jwt_req_details,
410+
false,
411+
)
412+
.unwrap(),
413+
);
396414
})
397415
});
398416

@@ -440,14 +458,17 @@ fn authorization_benchmark(c: &mut Criterion) {
440458
b.iter(|| {
441459
let jwt_req_details = JwtRequestDetails::Unauthenticated;
442460

443-
black_box(apply_authorization_to_operation(
444-
large_unauth.normalized_payload,
445-
large_unauth.auth_metadata,
446-
large_unauth.schema_metadata,
447-
large_unauth.variable_payload,
448-
&jwt_req_details,
449-
false,
450-
));
461+
black_box(
462+
apply_authorization_to_operation(
463+
large_unauth.normalized_payload,
464+
large_unauth.auth_metadata,
465+
large_unauth.schema_metadata,
466+
large_unauth.variable_payload,
467+
&jwt_req_details,
468+
false,
469+
)
470+
.unwrap(),
471+
);
451472
})
452473
});
453474

@@ -484,14 +505,17 @@ fn authorization_benchmark(c: &mut Criterion) {
484505
b.iter(|| {
485506
let jwt_req_details = JwtRequestDetails::Unauthenticated;
486507

487-
black_box(apply_authorization_to_operation(
488-
interface_auth_inline_unauth.normalized_payload,
489-
interface_auth_inline_unauth.auth_metadata,
490-
interface_auth_inline_unauth.schema_metadata,
491-
interface_auth_inline_unauth.variable_payload,
492-
&jwt_req_details,
493-
false,
494-
));
508+
black_box(
509+
apply_authorization_to_operation(
510+
interface_auth_inline_unauth.normalized_payload,
511+
interface_auth_inline_unauth.auth_metadata,
512+
interface_auth_inline_unauth.schema_metadata,
513+
interface_auth_inline_unauth.variable_payload,
514+
&jwt_req_details,
515+
false,
516+
)
517+
.unwrap(),
518+
);
495519
})
496520
});
497521

@@ -534,14 +558,17 @@ fn authorization_benchmark(c: &mut Criterion) {
534558
scopes: Some(vec![]),
535559
};
536560

537-
black_box(apply_authorization_to_operation(
538-
interface_auth_inline_auth.normalized_payload,
539-
interface_auth_inline_auth.auth_metadata,
540-
interface_auth_inline_auth.schema_metadata,
541-
interface_auth_inline_auth.variable_payload,
542-
&jwt_req_details,
543-
false,
544-
));
561+
black_box(
562+
apply_authorization_to_operation(
563+
interface_auth_inline_auth.normalized_payload,
564+
interface_auth_inline_auth.auth_metadata,
565+
interface_auth_inline_auth.schema_metadata,
566+
interface_auth_inline_auth.variable_payload,
567+
&jwt_req_details,
568+
false,
569+
)
570+
.unwrap(),
571+
);
545572
})
546573
});
547574
}

0 commit comments

Comments
 (0)