Skip to content

Commit fb2cfcf

Browse files
committed
authorization as a layer
1 parent afa80fb commit fb2cfcf

File tree

16 files changed

+168
-197
lines changed

16 files changed

+168
-197
lines changed

quickwit/Cargo.lock

+4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

quickwit/quickwit-auth/Cargo.toml

+5
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,18 @@ authors.workspace = true
99
license.workspace = true
1010

1111
[dependencies]
12+
tower = { workspace = true}
1213
biscuit-auth = { workspace = true, optional=true }
14+
futures = { workspace = true }
1315
http = { workspace = true }
1416
serde = { workspace = true }
1517
thiserror = { workspace = true }
1618
tonic = { workspace = true }
1719
tokio = { workspace = true }
1820
tracing = { workspace = true }
21+
pin-project = { workspace = true }
22+
23+
quickwit-common = { workspace = true }
1924

2025
[features]
2126
enterprise = ["biscuit-auth"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
use std::fmt;
2+
use std::task::{Context, Poll};
3+
4+
use futures::future::Either;
5+
use quickwit_common::tower::RpcName;
6+
use tower::{Layer, Service};
7+
8+
use crate::AuthorizationError;
9+
10+
pub struct AuthorizationLayer;
11+
12+
impl<S: Clone> Layer<S> for AuthorizationLayer {
13+
type Service = AuthorizationService<S>;
14+
15+
fn layer(&self, service: S) -> Self::Service {
16+
AuthorizationService { service }
17+
}
18+
}
19+
20+
#[derive(Clone)]
21+
pub struct AuthorizationService<S> {
22+
service: S,
23+
}
24+
25+
impl<S, Request> Service<Request> for AuthorizationService<S>
26+
where
27+
S: Service<Request>,
28+
S::Future: Send + 'static,
29+
S::Response: Send + 'static,
30+
S::Error: From<AuthorizationError> + Send + 'static,
31+
Request: fmt::Debug + Send + RpcName + crate::Authorization + 'static,
32+
{
33+
type Response = S::Response;
34+
type Error = S::Error;
35+
type Future =
36+
futures::future::Either<futures::future::Ready<Result<S::Response, S::Error>>, S::Future>;
37+
38+
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
39+
self.service.poll_ready(cx)
40+
}
41+
42+
fn call(&mut self, request: Request) -> Self::Future {
43+
if let Err(authorization_err) = crate::authorize_request(&request) {
44+
let err = S::Error::from(authorization_err);
45+
let result: Result<S::Response, S::Error> = Err(err);
46+
return Either::Left(futures::future::ready(result));
47+
}
48+
let service_fut = self.service.call(request);
49+
Either::Right(service_fut)
50+
}
51+
}

quickwit/quickwit-auth/src/community.rs

+4
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,7 @@ pub fn execute_with_authorization<F, O>(_: AuthorizationToken, f: F) -> impl Fut
8585
where F: Future<Output = O> {
8686
f
8787
}
88+
89+
pub fn authorize_request<R: Authorization>(_req: &R) -> Result<(), AuthorizationError> {
90+
Ok(())
91+
}

quickwit/quickwit-auth/src/enterprise.rs

+6
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,12 @@ pub fn authorize_stream<R: StreamAuthorization>(
215215
Ok(())
216216
}
217217

218+
pub fn authorize_request<R: Authorization>(req: &R) -> Result<(), AuthorizationError> {
219+
AUTHORIZATION_TOKEN
220+
.try_with(|auth_token| authorize(req, auth_token))
221+
.unwrap_or(Err(AuthorizationError::AuthorizationTokenMissing))
222+
}
223+
218224
pub fn execute_with_authorization<F, O>(
219225
token: AuthorizationToken,
220226
f: F,

quickwit/quickwit-auth/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
// You should have received a copy of the GNU Affero General Public License
1818
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1919

20-
use serde::{Deserialize, Serialize};
20+
mod authorization_layer;
2121

2222
#[cfg(not(feature = "enterprise"))]
2323
#[path = "community.rs"]
@@ -28,6 +28,7 @@ mod implementation;
2828
mod implementation;
2929

3030
pub use implementation::*;
31+
use serde::{Deserialize, Serialize};
3132

3233
#[derive(thiserror::Error, Debug, Clone, Copy, Serialize, Deserialize, Eq, PartialEq)]
3334
pub enum AuthorizationError {

quickwit/quickwit-codegen/example/src/codegen/hello.rs

+18-12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

quickwit/quickwit-codegen/src/codegen.rs

+2-16
Original file line numberDiff line numberDiff line change
@@ -1246,9 +1246,7 @@ fn generate_grpc_server_adapter_methods(context: &CodegenContext) -> TokenStream
12461246
}
12471247
}
12481248
} else {
1249-
quote! {
1250-
request.into_inner()
1251-
}
1249+
quote! { request.into_inner() }
12521250
};
12531251
let response_type = if syn_method.server_streaming {
12541252
let associated_type_name = quote::format_ident!("{}Stream", syn_method.proto_name);
@@ -1271,24 +1269,12 @@ fn generate_grpc_server_adapter_methods(context: &CodegenContext) -> TokenStream
12711269
quote! { tonic::Response::new }
12721270
};
12731271

1274-
let authorize_block = if syn_method.client_streaming {
1275-
let stream_item = &syn_method.request_type;
1276-
quote! {
1277-
quickwit_auth::authorize_stream::<#stream_item>(&auth_token)?;
1278-
}
1279-
} else {
1280-
quote! {
1281-
quickwit_auth::authorize(&req, &auth_token)?;
1282-
}
1283-
};
12841272
let method = quote! {
12851273
#associated_type
12861274

12871275
async fn #method_name(&self, request: tonic::Request<#request_type>) -> Result<tonic::Response<#response_type>, tonic::Status> {
12881276
let auth_token = quickwit_auth::get_auth_token(request.metadata())?;
1289-
let req = #method_arg;
1290-
#authorize_block;
1291-
quickwit_auth::execute_with_authorization(auth_token, self.inner.0.#method_name(req)).await
1277+
quickwit_auth::execute_with_authorization(auth_token, self.inner.0.#method_name(#method_arg)).await
12921278
.map(#into_response_type)
12931279
.map_err(crate::error::grpc_error_to_grpc_status)
12941280
}

quickwit/quickwit-ingest/src/codegen/ingest_service.rs

+12-9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

quickwit/quickwit-proto/src/codegen/quickwit/quickwit.cluster.rs

+1-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

quickwit/quickwit-proto/src/codegen/quickwit/quickwit.control_plane.rs

+9-27
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

quickwit/quickwit-proto/src/codegen/quickwit/quickwit.developer.rs

+1-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)