grafbase_sdk/extension/
authorization.rs1use crate::{
2 component::AnyExtension,
3 host::SubgraphHeaders,
4 types::{AuthorizationDecisions, Configuration, ErrorResponse, QueryElements, ResponseElements},
5 Error, Token,
6};
7
8#[allow(unused_variables)]
10pub trait AuthorizationExtension: Sized + 'static {
11 fn new(config: Configuration) -> Result<Self, Error>;
21
22 fn authorize_query(
31 &mut self,
32 headers: &mut SubgraphHeaders,
33 token: Token,
34 elements: QueryElements<'_>,
35 ) -> Result<impl IntoQueryAuthorization, ErrorResponse>;
36
37 fn authorize_response(
38 &mut self,
39 state: Vec<u8>,
40 elements: ResponseElements<'_>,
41 ) -> Result<AuthorizationDecisions, Error> {
42 Err("Response authorization not implemented".into())
43 }
44}
45
46pub trait IntoQueryAuthorization {
47 fn into_query_authorization(self) -> (AuthorizationDecisions, Vec<u8>);
48}
49
50impl IntoQueryAuthorization for AuthorizationDecisions {
51 fn into_query_authorization(self) -> (AuthorizationDecisions, Vec<u8>) {
52 (self, Vec::new())
53 }
54}
55
56impl IntoQueryAuthorization for (AuthorizationDecisions, Vec<u8>) {
57 fn into_query_authorization(self) -> (AuthorizationDecisions, Vec<u8>) {
58 self
59 }
60}
61
62#[doc(hidden)]
63pub fn register<T: AuthorizationExtension>() {
64 pub(super) struct Proxy<T: AuthorizationExtension>(T);
65
66 impl<T: AuthorizationExtension> AnyExtension for Proxy<T> {
67 fn authorize_query(
68 &mut self,
69 headers: &mut SubgraphHeaders,
70 token: Token,
71 elements: QueryElements<'_>,
72 ) -> Result<(AuthorizationDecisions, Vec<u8>), ErrorResponse> {
73 AuthorizationExtension::authorize_query(&mut self.0, headers, token, elements)
74 .map(IntoQueryAuthorization::into_query_authorization)
75 }
76
77 fn authorize_response(
78 &mut self,
79 state: Vec<u8>,
80 elements: ResponseElements<'_>,
81 ) -> Result<AuthorizationDecisions, Error> {
82 AuthorizationExtension::authorize_response(&mut self.0, state, elements)
83 }
84 }
85
86 crate::component::register_extension(Box::new(|_, config| {
87 <T as AuthorizationExtension>::new(config).map(|extension| Box::new(Proxy(extension)) as Box<dyn AnyExtension>)
88 }))
89}