Skip to content

Commit 42f4501

Browse files
committed
blop
1 parent 94b575a commit 42f4501

File tree

19 files changed

+209
-28
lines changed

19 files changed

+209
-28
lines changed

quickwit/Cargo.lock

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

quickwit/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ tikv-jemalloc-ctl = "0.5"
240240
tikv-jemallocator = "0.5"
241241
time = { version = "0.3", features = ["std", "formatting", "macros"] }
242242
tokio = { version = "1.40", features = ["full"] }
243+
tokio-inherit-task-local = "0.2"
243244
tokio-metrics = { version = "0.3.1", features = ["rt"] }
244245
tokio-stream = { version = "0.1", features = ["sync"] }
245246
tokio-util = { version = "0.7", features = ["full"] }

quickwit/quickwit-authorize/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ tower = { workspace = true}
1313
biscuit-auth = { workspace = true, optional=true }
1414
futures = { workspace = true }
1515
http = { workspace = true }
16+
tokio-inherit-task-local = { workspace = true }
1617
serde = { workspace = true }
1718
thiserror = { workspace = true }
1819
tonic = { workspace = true }

quickwit/quickwit-authorize/src/authorization_layer.rs renamed to quickwit/quickwit-authorize/src/enterprise/authorization_layer.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,22 @@
1+
// Copyright (C) 2024 Quickwit, Inc.
2+
//
3+
// Quickwit is offered under the AGPL v3.0 and as commercial software.
4+
// For commercial licensing, contact us at [email protected].
5+
//
6+
// AGPL:
7+
// This program is free software: you can redistribute it and/or modify
8+
// it under the terms of the GNU Affero General Public License as
9+
// published by the Free Software Foundation, either version 3 of the
10+
// License, or (at your option) any later version.
11+
//
12+
// This program is distributed in the hope that it will be useful,
13+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
// GNU Affero General Public License for more details.
16+
//
17+
// You should have received a copy of the GNU Affero General Public License
18+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
120
use std::fmt;
221
use std::task::{Context, Poll};
322

@@ -7,6 +26,7 @@ use tower::{Layer, Service};
726

827
use crate::AuthorizationError;
928

29+
#[derive(Clone, Copy, Debug)]
1030
pub struct AuthorizationLayer;
1131

1232
impl<S: Clone> Layer<S> for AuthorizationLayer {
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright (C) 2024 Quickwit, Inc.
2+
//
3+
// Quickwit is offered under the AGPL v3.0 and as commercial software.
4+
// For commercial licensing, contact us at [email protected].
5+
//
6+
// AGPL:
7+
// This program is free software: you can redistribute it and/or modify
8+
// it under the terms of the GNU Affero General Public License as
9+
// published by the Free Software Foundation, either version 3 of the
10+
// License, or (at your option) any later version.
11+
//
12+
// This program is distributed in the hope that it will be useful,
13+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
// GNU Affero General Public License for more details.
16+
//
17+
// You should have received a copy of the GNU Affero General Public License
18+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
20+
use std::task::{Context, Poll};
21+
22+
use futures::future::Either;
23+
use http::Request;
24+
use tokio::task::futures::TaskLocalFuture;
25+
use tokio_inherit_task_local::TaskLocalInheritableTable;
26+
use tower::{Layer, Service};
27+
28+
use super::AuthorizationToken;
29+
30+
#[derive(Clone, Copy, Debug)]
31+
pub struct AuthorizationTokenExtractionLayer;
32+
33+
impl<S: Clone> Layer<S> for AuthorizationTokenExtractionLayer {
34+
type Service = AuthorizationTokenExtractionService<S>;
35+
36+
fn layer(&self, service: S) -> Self::Service {
37+
AuthorizationTokenExtractionService { service }
38+
}
39+
}
40+
41+
#[derive(Clone)]
42+
pub struct AuthorizationTokenExtractionService<S> {
43+
service: S,
44+
}
45+
46+
fn get_authorization_token_opt(headers: &http::HeaderMap) -> Option<AuthorizationToken> {
47+
let authorization_header_value = headers.get("Authorization")?;
48+
let authorization_header_str = authorization_header_value.to_str().ok()?;
49+
crate::get_auth_token_from_str(authorization_header_str).ok()
50+
}
51+
52+
impl<B, S> Service<Request<B>> for AuthorizationTokenExtractionService<S>
53+
where S: Service<Request<B>>
54+
{
55+
type Response = S::Response;
56+
type Error = S::Error;
57+
type Future = Either<S::Future, TaskLocalFuture<TaskLocalInheritableTable, S::Future>>;
58+
59+
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
60+
self.service.poll_ready(cx)
61+
}
62+
63+
fn call(&mut self, request: Request<B>) -> Self::Future {
64+
let authorization_token_opt = get_authorization_token_opt(request.headers());
65+
let fut = self.service.call(request);
66+
if let Some(authorization_token) = authorization_token_opt {
67+
Either::Right(crate::execute_with_authorization(authorization_token, fut))
68+
} else {
69+
Either::Left(fut)
70+
}
71+
}
72+
}

quickwit/quickwit-authorize/src/enterprise.rs renamed to quickwit/quickwit-authorize/src/enterprise/mod.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,19 @@
1919
// components are licensed under the original license provided by the owner of the
2020
// applicable component.
2121

22+
mod authorization_layer;
23+
mod authorization_token_extraction_layer;
24+
2225
use std::future::Future;
2326
use std::str::FromStr;
2427
use std::sync::{Arc, OnceLock};
2528

29+
pub use authorization_layer::AuthorizationLayer;
30+
pub use authorization_token_extraction_layer::AuthorizationTokenExtractionLayer;
2631
use biscuit_auth::macros::authorizer;
2732
use biscuit_auth::{Authorizer, Biscuit, RootKeyProvider};
33+
use tokio::task::futures::TaskLocalFuture;
34+
use tokio_inherit_task_local::TaskLocalInheritableTable;
2835

2936
use crate::AuthorizationError;
3037

@@ -79,7 +86,7 @@ impl FromStr for AuthorizationToken {
7986
}
8087
}
8188

82-
tokio::task_local! {
89+
tokio_inherit_task_local::inheritable_task_local! {
8390
pub static AUTHORIZATION_TOKEN: AuthorizationToken;
8491
}
8592

@@ -146,6 +153,16 @@ impl From<biscuit_auth::error::Token> for AuthorizationError {
146153
}
147154
}
148155

156+
pub fn get_auth_token_from_str(
157+
authorization_header_value: &str,
158+
) -> Result<AuthorizationToken, AuthorizationError> {
159+
let authorization_token_str: &str = authorization_header_value
160+
.strip_prefix(AUTHORIZATION_VALUE_PREFIX)
161+
.ok_or(AuthorizationError::InvalidToken)?;
162+
let biscuit: Biscuit = Biscuit::from_base64(authorization_token_str, get_root_key_provider())?;
163+
Ok(AuthorizationToken(biscuit))
164+
}
165+
149166
pub fn get_auth_token(
150167
req_metadata: &tonic::metadata::MetadataMap,
151168
) -> Result<AuthorizationToken, AuthorizationError> {
@@ -154,11 +171,7 @@ pub fn get_auth_token(
154171
.ok_or(AuthorizationError::AuthorizationTokenMissing)?
155172
.to_str()
156173
.map_err(|_| AuthorizationError::InvalidToken)?;
157-
let authorization_token_str: &str = authorization_header_value
158-
.strip_prefix(AUTHORIZATION_VALUE_PREFIX)
159-
.ok_or(AuthorizationError::InvalidToken)?;
160-
let biscuit: Biscuit = Biscuit::from_base64(authorization_token_str, get_root_key_provider())?;
161-
Ok(AuthorizationToken(biscuit))
174+
get_auth_token_from_str(authorization_header_value)
162175
}
163176

164177
pub fn set_auth_token(
@@ -224,7 +237,7 @@ pub fn authorize_request<R: Authorization>(req: &R) -> Result<(), AuthorizationE
224237
pub fn execute_with_authorization<F, O>(
225238
token: AuthorizationToken,
226239
f: F,
227-
) -> impl Future<Output = O>
240+
) -> TaskLocalFuture<TaskLocalInheritableTable, F>
228241
where
229242
F: Future<Output = O>,
230243
{

quickwit/quickwit-authorize/src/lib.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,12 @@
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-
mod authorization_layer;
21-
2220
#[cfg(not(feature = "enterprise"))]
23-
#[path = "community.rs"]
21+
#[path = "community/mod.rs"]
2422
mod implementation;
2523

2624
#[cfg(feature = "enterprise")]
27-
#[path = "enterprise.rs"]
25+
#[path = "enterprise/mod.rs"]
2826
mod implementation;
2927

3028
pub use implementation::*;

quickwit/quickwit-cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ quickwit-metastore = { workspace = true, features = ["testsuite"] }
7979
quickwit-storage = { workspace = true, features = ["testsuite"] }
8080

8181
[features]
82-
enterprise = ["quickwit-config/enterprise", "quickwit-ingest/enterprise", "quickwit-proto/enterprise"]
82+
enterprise = ["quickwit-config/enterprise", "quickwit-ingest/enterprise", "quickwit-proto/enterprise", "quickwit-serve/enterprise"]
8383
jemalloc = ["dep:tikv-jemalloc-ctl", "dep:tikv-jemallocator"]
8484
ci-test = []
8585
pprof = ["quickwit-serve/pprof"]

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1616
// SOFTWARE.
1717

18-
use quickwit_authorize::{Authorization, AuthorizationError, AuthorizationToken, StreamAuthorization};
18+
use quickwit_authorize::{
19+
Authorization, AuthorizationError, AuthorizationToken, StreamAuthorization,
20+
};
1921

2022
use crate::{GoodbyeRequest, HelloRequest, PingRequest};
2123

@@ -38,9 +40,7 @@ impl Authorization for GoodbyeRequest {
3840
}
3941

4042
impl StreamAuthorization for PingRequest {
41-
fn attenuate(
42-
auth_token: AuthorizationToken,
43-
) -> Result<AuthorizationToken, AuthorizationError> {
43+
fn attenuate(auth_token: AuthorizationToken) -> Result<AuthorizationToken, AuthorizationError> {
4444
Ok(auth_token)
4545
}
4646
}

0 commit comments

Comments
 (0)