Allow local access tokens to be used with OIDC backends (closes #1311 closes stalwartlabs/webadmin#52)
This commit is contained in:
@@ -4,16 +4,15 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use common::auth::AccessToken;
|
||||
use common::{HttpAuthCache, Server, auth::AuthRequest, listener::limiter::InFlight};
|
||||
use http_proto::{HttpRequest, HttpSessionData};
|
||||
use hyper::header;
|
||||
use mail_parser::decoders::base64::base64_decode;
|
||||
use mail_send::Credentials;
|
||||
|
||||
use common::auth::AccessToken;
|
||||
use std::future::Future;
|
||||
use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
pub trait Authenticator: Sync + Send {
|
||||
fn authenticate_headers(
|
||||
@@ -34,19 +33,20 @@ impl Authenticator for Server {
|
||||
if let Some((mechanism, token)) = req.authorization() {
|
||||
// Check if the credentials are cached
|
||||
if let Some(http_cache) = self.inner.cache.http_auth.get(token) {
|
||||
let access_token = self.get_access_token(http_cache.account_id).await?;
|
||||
|
||||
// Make sure the revision is still valid
|
||||
if access_token.revision == http_cache.revision {
|
||||
// Enforce authenticated rate limit
|
||||
return self
|
||||
.is_http_authenticated_request_allowed(&access_token)
|
||||
.await
|
||||
.map(|in_flight| (in_flight, access_token));
|
||||
} else {
|
||||
// If the revision is not valid, remove the cached credentials
|
||||
self.inner.cache.http_auth.remove(token);
|
||||
if http_cache.expires <= Instant::now() {
|
||||
let access_token = self.get_access_token(http_cache.account_id).await?;
|
||||
if access_token.revision == http_cache.revision {
|
||||
// Enforce authenticated rate limit
|
||||
return self
|
||||
.is_http_authenticated_request_allowed(&access_token)
|
||||
.await
|
||||
.map(|in_flight| (in_flight, access_token));
|
||||
}
|
||||
}
|
||||
|
||||
// If the revision is not valid, remove the cached credentials
|
||||
self.inner.cache.http_auth.remove(token);
|
||||
}
|
||||
|
||||
let credentials = if mechanism.eq_ignore_ascii_case("basic") {
|
||||
@@ -100,6 +100,8 @@ impl Authenticator for Server {
|
||||
HttpAuthCache {
|
||||
account_id: access_token.primary_id(),
|
||||
revision: access_token.revision,
|
||||
expires: Instant::now()
|
||||
+ Duration::from_secs(self.core.oauth.oauth_expiry_token),
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ use common::{
|
||||
};
|
||||
|
||||
use directory::{
|
||||
Permission, QueryBy, Type,
|
||||
Permission, QueryParams, Type,
|
||||
backend::internal::{
|
||||
PrincipalField, PrincipalSet, lookup::DirectoryStore, manage::ManageDirectory,
|
||||
},
|
||||
@@ -113,7 +113,7 @@ impl ClientRegistrationHandler for Server {
|
||||
// Fetch client registration
|
||||
let found_registration = if let Some(client) = self
|
||||
.store()
|
||||
.query(QueryBy::Name(client_id), false)
|
||||
.query(QueryParams::name(client_id).with_return_member_of(false))
|
||||
.await
|
||||
.caused_by(trc::location!())?
|
||||
.filter(|p| p.typ() == Type::OauthClient)
|
||||
|
||||
Reference in New Issue
Block a user