Skip to content

Commit e1ba91d

Browse files
feat(rest): introduce AuthManager/AuthSession with OAuth2 and SigV4 managers
1 parent d1b8eac commit e1ba91d

10 files changed

Lines changed: 1682 additions & 256 deletions

File tree

Cargo.lock

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

crates/catalog/rest/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@ chrono = { workspace = true }
3535
http = { workspace = true }
3636
iceberg = { workspace = true }
3737
itertools = { workspace = true }
38+
reqsign-core = "3.0.0"
3839
reqwest = { workspace = true }
3940
serde = { workspace = true }
4041
serde_derive = { workspace = true }
4142
serde_json = { workspace = true }
43+
sha2 = "0.10"
4244
tokio = { workspace = true }
4345
typed-builder = { workspace = true }
4446
uuid = { workspace = true, features = ["v4"] }

crates/catalog/rest/public-api.txt

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,22 @@
11
pub mod iceberg_catalog_rest
2+
pub enum iceberg_catalog_rest::PayloadHashMode
3+
pub iceberg_catalog_rest::PayloadHashMode::IcebergRest
4+
pub iceberg_catalog_rest::PayloadHashMode::StandardAws
5+
impl core::clone::Clone for iceberg_catalog_rest::PayloadHashMode
6+
pub fn iceberg_catalog_rest::PayloadHashMode::clone(&self) -> iceberg_catalog_rest::PayloadHashMode
7+
impl core::cmp::Eq for iceberg_catalog_rest::PayloadHashMode
8+
impl core::cmp::PartialEq for iceberg_catalog_rest::PayloadHashMode
9+
pub fn iceberg_catalog_rest::PayloadHashMode::eq(&self, other: &iceberg_catalog_rest::PayloadHashMode) -> bool
10+
impl core::fmt::Debug for iceberg_catalog_rest::PayloadHashMode
11+
pub fn iceberg_catalog_rest::PayloadHashMode::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
12+
impl core::marker::Copy for iceberg_catalog_rest::PayloadHashMode
13+
impl core::marker::StructuralPartialEq for iceberg_catalog_rest::PayloadHashMode
14+
pub struct iceberg_catalog_rest::AwsCredentials
15+
pub iceberg_catalog_rest::AwsCredentials::access_key_id: alloc::string::String
16+
pub iceberg_catalog_rest::AwsCredentials::secret_access_key: alloc::string::String
17+
pub iceberg_catalog_rest::AwsCredentials::session_token: core::option::Option<alloc::string::String>
18+
impl core::clone::Clone for iceberg_catalog_rest::AwsCredentials
19+
pub fn iceberg_catalog_rest::AwsCredentials::clone(&self) -> iceberg_catalog_rest::AwsCredentials
220
pub struct iceberg_catalog_rest::CommitTableRequest
321
pub iceberg_catalog_rest::CommitTableRequest::identifier: core::option::Option<iceberg::catalog::TableIdent>
422
pub iceberg_catalog_rest::CommitTableRequest::requirements: alloc::vec::Vec<iceberg::catalog::TableRequirement>
@@ -175,6 +193,25 @@ impl serde_core::ser::Serialize for iceberg_catalog_rest::NamespaceResponse
175193
pub fn iceberg_catalog_rest::NamespaceResponse::serialize<__S>(&self, __serializer: __S) -> core::result::Result<<__S as serde_core::ser::Serializer>::Ok, <__S as serde_core::ser::Serializer>::Error> where __S: serde_core::ser::Serializer
176194
impl<'de> serde_core::de::Deserialize<'de> for iceberg_catalog_rest::NamespaceResponse
177195
pub fn iceberg_catalog_rest::NamespaceResponse::deserialize<__D>(__deserializer: __D) -> core::result::Result<Self, <__D as serde_core::de::Deserializer>::Error> where __D: serde_core::de::Deserializer<'de>
196+
pub struct iceberg_catalog_rest::NoopAuthManager
197+
impl core::fmt::Debug for iceberg_catalog_rest::NoopAuthManager
198+
pub fn iceberg_catalog_rest::NoopAuthManager::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
199+
impl iceberg_catalog_rest::AuthManager for iceberg_catalog_rest::NoopAuthManager
200+
pub fn iceberg_catalog_rest::NoopAuthManager::catalog_session<'life0, 'life1, 'async_trait>(&'life0 self, _props: &'life1 std::collections::hash::map::HashMap<alloc::string::String, alloc::string::String>) -> core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = iceberg::error::Result<alloc::sync::Arc<dyn iceberg_catalog_rest::AuthSession>>> + core::marker::Send + 'async_trait)>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait
201+
pub fn iceberg_catalog_rest::NoopAuthManager::init_session<'life0, 'async_trait>(&'life0 self) -> core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = iceberg::error::Result<alloc::sync::Arc<dyn iceberg_catalog_rest::AuthSession>>> + core::marker::Send + 'async_trait)>> where Self: 'async_trait, 'life0: 'async_trait
202+
pub struct iceberg_catalog_rest::OAuth2Manager
203+
impl iceberg_catalog_rest::OAuth2Manager
204+
pub fn iceberg_catalog_rest::OAuth2Manager::new(token_endpoint: impl core::convert::Into<alloc::string::String>) -> Self
205+
pub fn iceberg_catalog_rest::OAuth2Manager::with_client(self, client: reqwest::async_impl::client::Client) -> Self
206+
pub fn iceberg_catalog_rest::OAuth2Manager::with_credential(self, client_id: core::option::Option<alloc::string::String>, client_secret: alloc::string::String) -> Self
207+
pub fn iceberg_catalog_rest::OAuth2Manager::with_extra_headers(self, headers: http::header::map::HeaderMap) -> Self
208+
pub fn iceberg_catalog_rest::OAuth2Manager::with_extra_oauth_params(self, params: std::collections::hash::map::HashMap<alloc::string::String, alloc::string::String>) -> Self
209+
pub fn iceberg_catalog_rest::OAuth2Manager::with_token(self, token: impl core::convert::Into<alloc::string::String>) -> Self
210+
impl core::fmt::Debug for iceberg_catalog_rest::OAuth2Manager
211+
pub fn iceberg_catalog_rest::OAuth2Manager::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
212+
impl iceberg_catalog_rest::AuthManager for iceberg_catalog_rest::OAuth2Manager
213+
pub fn iceberg_catalog_rest::OAuth2Manager::catalog_session<'life0, 'life1, 'async_trait>(&'life0 self, props: &'life1 std::collections::hash::map::HashMap<alloc::string::String, alloc::string::String>) -> core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = iceberg::error::Result<alloc::sync::Arc<dyn iceberg_catalog_rest::AuthSession>>> + core::marker::Send + 'async_trait)>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait
214+
pub fn iceberg_catalog_rest::OAuth2Manager::init_session<'life0, 'async_trait>(&'life0 self) -> core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = iceberg::error::Result<alloc::sync::Arc<dyn iceberg_catalog_rest::AuthSession>>> + core::marker::Send + 'async_trait)>> where Self: 'async_trait, 'life0: 'async_trait
178215
pub struct iceberg_catalog_rest::RegisterTableRequest
179216
pub iceberg_catalog_rest::RegisterTableRequest::metadata_location: alloc::string::String
180217
pub iceberg_catalog_rest::RegisterTableRequest::name: alloc::string::String
@@ -230,6 +267,7 @@ pub fn iceberg_catalog_rest::RestCatalog::update_namespace<'life0, 'life1, 'asyn
230267
pub fn iceberg_catalog_rest::RestCatalog::update_table<'life0, 'async_trait>(&'life0 self, commit: iceberg::catalog::TableCommit) -> core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = iceberg::error::Result<iceberg::table::Table>> + core::marker::Send + 'async_trait)>> where Self: 'async_trait, 'life0: 'async_trait
231268
pub struct iceberg_catalog_rest::RestCatalogBuilder
232269
impl iceberg_catalog_rest::RestCatalogBuilder
270+
pub fn iceberg_catalog_rest::RestCatalogBuilder::with_auth_manager(self, auth_manager: alloc::sync::Arc<dyn iceberg_catalog_rest::AuthManager>) -> Self
233271
pub fn iceberg_catalog_rest::RestCatalogBuilder::with_client(self, client: reqwest::async_impl::client::Client) -> Self
234272
impl core::default::Default for iceberg_catalog_rest::RestCatalogBuilder
235273
pub fn iceberg_catalog_rest::RestCatalogBuilder::default() -> Self
@@ -241,6 +279,22 @@ pub fn iceberg_catalog_rest::RestCatalogBuilder::load(self, name: impl core::con
241279
pub fn iceberg_catalog_rest::RestCatalogBuilder::with_kms_client_factory(self, kms_client_factory: alloc::sync::Arc<dyn iceberg::encryption::kms::factory::KmsClientFactory>) -> Self
242280
pub fn iceberg_catalog_rest::RestCatalogBuilder::with_runtime(self, runtime: iceberg::runtime::Runtime) -> Self
243281
pub fn iceberg_catalog_rest::RestCatalogBuilder::with_storage_factory(self, storage_factory: alloc::sync::Arc<dyn iceberg::io::storage::StorageFactory>) -> Self
282+
pub struct iceberg_catalog_rest::SigV4AuthManager
283+
impl iceberg_catalog_rest::SigV4AuthManager
284+
pub fn iceberg_catalog_rest::SigV4AuthManager::new(delegate: alloc::sync::Arc<dyn iceberg_catalog_rest::AuthManager>, signer: iceberg_catalog_rest::SigV4Signer) -> Self
285+
impl core::fmt::Debug for iceberg_catalog_rest::SigV4AuthManager
286+
pub fn iceberg_catalog_rest::SigV4AuthManager::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
287+
impl iceberg_catalog_rest::AuthManager for iceberg_catalog_rest::SigV4AuthManager
288+
pub fn iceberg_catalog_rest::SigV4AuthManager::catalog_session<'life0, 'life1, 'async_trait>(&'life0 self, props: &'life1 std::collections::hash::map::HashMap<alloc::string::String, alloc::string::String>) -> core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = iceberg::error::Result<alloc::sync::Arc<dyn iceberg_catalog_rest::AuthSession>>> + core::marker::Send + 'async_trait)>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait
289+
pub fn iceberg_catalog_rest::SigV4AuthManager::init_session<'life0, 'async_trait>(&'life0 self) -> core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = iceberg::error::Result<alloc::sync::Arc<dyn iceberg_catalog_rest::AuthSession>>> + core::marker::Send + 'async_trait)>> where Self: 'async_trait, 'life0: 'async_trait
290+
pub struct iceberg_catalog_rest::SigV4Signer
291+
impl iceberg_catalog_rest::SigV4Signer
292+
pub fn iceberg_catalog_rest::SigV4Signer::new(credentials: iceberg_catalog_rest::AwsCredentials, region: alloc::string::String, service: alloc::string::String, mode: iceberg_catalog_rest::PayloadHashMode) -> Self
293+
pub fn iceberg_catalog_rest::SigV4Signer::sign(&self, request: &mut reqwest::async_impl::request::Request) -> iceberg::error::Result<()>
294+
impl core::clone::Clone for iceberg_catalog_rest::SigV4Signer
295+
pub fn iceberg_catalog_rest::SigV4Signer::clone(&self) -> iceberg_catalog_rest::SigV4Signer
296+
impl core::fmt::Debug for iceberg_catalog_rest::SigV4Signer
297+
pub fn iceberg_catalog_rest::SigV4Signer::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
244298
pub struct iceberg_catalog_rest::StorageCredential
245299
pub iceberg_catalog_rest::StorageCredential::config: std::collections::hash::map::HashMap<alloc::string::String, alloc::string::String>
246300
pub iceberg_catalog_rest::StorageCredential::prefix: alloc::string::String
@@ -287,6 +341,33 @@ impl serde_core::ser::Serialize for iceberg_catalog_rest::UpdateNamespacePropert
287341
pub fn iceberg_catalog_rest::UpdateNamespacePropertiesResponse::serialize<__S>(&self, __serializer: __S) -> core::result::Result<<__S as serde_core::ser::Serializer>::Ok, <__S as serde_core::ser::Serializer>::Error> where __S: serde_core::ser::Serializer
288342
impl<'de> serde_core::de::Deserialize<'de> for iceberg_catalog_rest::UpdateNamespacePropertiesResponse
289343
pub fn iceberg_catalog_rest::UpdateNamespacePropertiesResponse::deserialize<__D>(__deserializer: __D) -> core::result::Result<Self, <__D as serde_core::de::Deserializer>::Error> where __D: serde_core::de::Deserializer<'de>
344+
pub const iceberg_catalog_rest::AUTH_TYPE_NONE: &str
345+
pub const iceberg_catalog_rest::AUTH_TYPE_OAUTH2: &str
346+
pub const iceberg_catalog_rest::AUTH_TYPE_SIGV4: &str
347+
pub const iceberg_catalog_rest::REST_CATALOG_PROP_AUTH_TYPE: &str
290348
pub const iceberg_catalog_rest::REST_CATALOG_PROP_DISABLE_HEADER_REDACTION: &str
349+
pub const iceberg_catalog_rest::REST_CATALOG_PROP_SIGNING_ACCESS_KEY: &str
350+
pub const iceberg_catalog_rest::REST_CATALOG_PROP_SIGNING_NAME: &str
351+
pub const iceberg_catalog_rest::REST_CATALOG_PROP_SIGNING_REGION: &str
352+
pub const iceberg_catalog_rest::REST_CATALOG_PROP_SIGNING_SECRET_KEY: &str
353+
pub const iceberg_catalog_rest::REST_CATALOG_PROP_SIGNING_SESSION_TOKEN: &str
354+
pub const iceberg_catalog_rest::REST_CATALOG_PROP_SIGV4_DELEGATE_AUTH_TYPE: &str
355+
pub const iceberg_catalog_rest::REST_CATALOG_PROP_SIGV4_ENABLED: &str
291356
pub const iceberg_catalog_rest::REST_CATALOG_PROP_URI: &str
292357
pub const iceberg_catalog_rest::REST_CATALOG_PROP_WAREHOUSE: &str
358+
pub trait iceberg_catalog_rest::AuthManager: core::fmt::Debug + core::marker::Send + core::marker::Sync
359+
pub fn iceberg_catalog_rest::AuthManager::catalog_session<'life0, 'life1, 'async_trait>(&'life0 self, props: &'life1 std::collections::hash::map::HashMap<alloc::string::String, alloc::string::String>) -> core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = iceberg::error::Result<alloc::sync::Arc<dyn iceberg_catalog_rest::AuthSession>>> + core::marker::Send + 'async_trait)>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait
360+
pub fn iceberg_catalog_rest::AuthManager::init_session<'life0, 'async_trait>(&'life0 self) -> core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = iceberg::error::Result<alloc::sync::Arc<dyn iceberg_catalog_rest::AuthSession>>> + core::marker::Send + 'async_trait)>> where Self: 'async_trait, 'life0: 'async_trait
361+
impl iceberg_catalog_rest::AuthManager for iceberg_catalog_rest::NoopAuthManager
362+
pub fn iceberg_catalog_rest::NoopAuthManager::catalog_session<'life0, 'life1, 'async_trait>(&'life0 self, _props: &'life1 std::collections::hash::map::HashMap<alloc::string::String, alloc::string::String>) -> core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = iceberg::error::Result<alloc::sync::Arc<dyn iceberg_catalog_rest::AuthSession>>> + core::marker::Send + 'async_trait)>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait
363+
pub fn iceberg_catalog_rest::NoopAuthManager::init_session<'life0, 'async_trait>(&'life0 self) -> core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = iceberg::error::Result<alloc::sync::Arc<dyn iceberg_catalog_rest::AuthSession>>> + core::marker::Send + 'async_trait)>> where Self: 'async_trait, 'life0: 'async_trait
364+
impl iceberg_catalog_rest::AuthManager for iceberg_catalog_rest::OAuth2Manager
365+
pub fn iceberg_catalog_rest::OAuth2Manager::catalog_session<'life0, 'life1, 'async_trait>(&'life0 self, props: &'life1 std::collections::hash::map::HashMap<alloc::string::String, alloc::string::String>) -> core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = iceberg::error::Result<alloc::sync::Arc<dyn iceberg_catalog_rest::AuthSession>>> + core::marker::Send + 'async_trait)>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait
366+
pub fn iceberg_catalog_rest::OAuth2Manager::init_session<'life0, 'async_trait>(&'life0 self) -> core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = iceberg::error::Result<alloc::sync::Arc<dyn iceberg_catalog_rest::AuthSession>>> + core::marker::Send + 'async_trait)>> where Self: 'async_trait, 'life0: 'async_trait
367+
impl iceberg_catalog_rest::AuthManager for iceberg_catalog_rest::SigV4AuthManager
368+
pub fn iceberg_catalog_rest::SigV4AuthManager::catalog_session<'life0, 'life1, 'async_trait>(&'life0 self, props: &'life1 std::collections::hash::map::HashMap<alloc::string::String, alloc::string::String>) -> core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = iceberg::error::Result<alloc::sync::Arc<dyn iceberg_catalog_rest::AuthSession>>> + core::marker::Send + 'async_trait)>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait
369+
pub fn iceberg_catalog_rest::SigV4AuthManager::init_session<'life0, 'async_trait>(&'life0 self) -> core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = iceberg::error::Result<alloc::sync::Arc<dyn iceberg_catalog_rest::AuthSession>>> + core::marker::Send + 'async_trait)>> where Self: 'async_trait, 'life0: 'async_trait
370+
pub trait iceberg_catalog_rest::AuthSession: core::fmt::Debug + core::marker::Send + core::marker::Sync
371+
pub fn iceberg_catalog_rest::AuthSession::authenticate<'life0, 'life1, 'async_trait>(&'life0 self, request: &'life1 mut reqwest::async_impl::request::Request) -> core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = iceberg::error::Result<()>> + core::marker::Send + 'async_trait)>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait
372+
pub fn iceberg_catalog_rest::AuthSession::invalidate<'life0, 'async_trait>(&'life0 self) -> core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = iceberg::error::Result<()>> + core::marker::Send + 'async_trait)>> where Self: 'async_trait, 'life0: 'async_trait
373+
pub fn iceberg_catalog_rest::AuthSession::refresh<'life0, 'async_trait>(&'life0 self) -> core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = iceberg::error::Result<()>> + core::marker::Send + 'async_trait)>> where Self: 'async_trait, 'life0: 'async_trait
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
//! Pluggable authentication for the REST catalog, mirroring Iceberg Java's
19+
//! `AuthManager`/`AuthSession` API.
20+
21+
mod oauth2;
22+
mod sigv4;
23+
24+
use std::collections::HashMap;
25+
use std::fmt::Debug;
26+
use std::sync::Arc;
27+
28+
use async_trait::async_trait;
29+
use iceberg::Result;
30+
pub use oauth2::OAuth2Manager;
31+
use reqwest::Request;
32+
pub use sigv4::SigV4AuthManager;
33+
34+
/// `rest.auth.type` value disabling authentication.
35+
pub const AUTH_TYPE_NONE: &str = "none";
36+
/// `rest.auth.type` value selecting OAuth2 token authentication.
37+
pub const AUTH_TYPE_OAUTH2: &str = "oauth2";
38+
/// `rest.auth.type` value selecting AWS SigV4 request signing.
39+
pub const AUTH_TYPE_SIGV4: &str = "sigv4";
40+
41+
/// Creates the [`AuthSession`]s used to authenticate REST catalog requests.
42+
///
43+
/// A manager is created once per catalog, either from the `rest.auth.type`
44+
/// property or injected through `RestCatalogBuilder::with_auth_manager`, and
45+
/// lives for the lifetime of the catalog.
46+
#[async_trait]
47+
pub trait AuthManager: Debug + Send + Sync {
48+
/// Session used for the initial `/v1/config` handshake, built from the
49+
/// user-supplied configuration.
50+
async fn init_session(&self) -> Result<Arc<dyn AuthSession>>;
51+
52+
/// Session used for all subsequent catalog requests, given the properties
53+
/// merged from the user configuration and the server's config response.
54+
///
55+
/// Implementations may carry state (e.g. a cached token) over from the
56+
/// init session.
57+
async fn catalog_session(
58+
&self,
59+
props: &HashMap<String, String>,
60+
) -> Result<Arc<dyn AuthSession>>;
61+
}
62+
63+
/// Authenticates outgoing REST catalog requests.
64+
#[async_trait]
65+
pub trait AuthSession: Debug + Send + Sync {
66+
/// Applies authentication to the request (adds headers, signs, ...).
67+
async fn authenticate(&self, request: &mut Request) -> Result<()>;
68+
69+
/// Drops any cached credentials so the next request re-authenticates.
70+
async fn invalidate(&self) -> Result<()> {
71+
Ok(())
72+
}
73+
74+
/// Proactively refreshes cached credentials (e.g. re-exchanges an OAuth2
75+
/// client credential for a new token), leaving them intact on failure.
76+
async fn refresh(&self) -> Result<()> {
77+
Ok(())
78+
}
79+
}
80+
81+
/// [`AuthManager`] that performs no authentication.
82+
#[derive(Debug)]
83+
pub struct NoopAuthManager;
84+
85+
/// [`AuthSession`] that performs no authentication.
86+
#[derive(Debug)]
87+
struct NoopSession;
88+
89+
#[async_trait]
90+
impl AuthManager for NoopAuthManager {
91+
async fn init_session(&self) -> Result<Arc<dyn AuthSession>> {
92+
Ok(Arc::new(NoopSession))
93+
}
94+
95+
async fn catalog_session(
96+
&self,
97+
_props: &HashMap<String, String>,
98+
) -> Result<Arc<dyn AuthSession>> {
99+
Ok(Arc::new(NoopSession))
100+
}
101+
}
102+
103+
#[async_trait]
104+
impl AuthSession for NoopSession {
105+
async fn authenticate(&self, _request: &mut Request) -> Result<()> {
106+
Ok(())
107+
}
108+
}

0 commit comments

Comments
 (0)