Allow local access tokens to be used with OIDC backends (closes #1311 closes stalwartlabs/webadmin#52)

This commit is contained in:
mdecimus
2025-07-25 21:06:23 +02:00
parent 02f6a114e0
commit 654f296d45
37 changed files with 369 additions and 278 deletions

View File

@@ -7,24 +7,20 @@
use trc::AddContext;
use crate::{
Directory, DirectoryInner, Principal, QueryBy,
Directory, DirectoryInner, Principal, QueryParams,
backend::{RcptType, internal::lookup::DirectoryStore},
};
impl Directory {
pub async fn query(
&self,
by: QueryBy<'_>,
return_member_of: bool,
) -> trc::Result<Option<Principal>> {
pub async fn query(&self, by: QueryParams<'_>) -> trc::Result<Option<Principal>> {
match &self.store {
DirectoryInner::Internal(store) => store.query(by, return_member_of).await,
DirectoryInner::Ldap(store) => store.query(by, return_member_of).await,
DirectoryInner::Sql(store) => store.query(by, return_member_of).await,
DirectoryInner::Imap(store) => store.query(by).await,
DirectoryInner::Smtp(store) => store.query(by).await,
DirectoryInner::Internal(store) => store.query(by).await,
DirectoryInner::Ldap(store) => store.query(by).await,
DirectoryInner::Sql(store) => store.query(by).await,
DirectoryInner::Imap(store) => store.query(by.by).await,
DirectoryInner::Smtp(store) => store.query(by.by).await,
DirectoryInner::Memory(store) => store.query(by).await,
DirectoryInner::OpenId(store) => store.query(by, return_member_of).await,
DirectoryInner::OpenId(store) => store.query(by).await,
}
.caused_by(trc::location!())
}

View File

@@ -4,8 +4,11 @@
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
use std::{collections::hash_map::Entry, fmt, str::FromStr};
use crate::{
ArchivedPrincipal, FALLBACK_ADMIN_ID, Permission, PermissionGrant, Principal, PrincipalData,
ROLE_ADMIN, Type,
backend::internal::{PrincipalField, PrincipalSet, PrincipalUpdate, PrincipalValue},
};
use ahash::AHashSet;
use nlp::tokenizers::word::WordTokenizer;
use serde::{
@@ -13,17 +16,13 @@ use serde::{
de::{self, IgnoredAny, Visitor},
ser::SerializeMap,
};
use std::{collections::hash_map::Entry, fmt, str::FromStr};
use store::{
U64_LEN,
backend::MAX_TOKEN_LENGTH,
write::{BatchBuilder, DirectoryClass},
};
use crate::{
ArchivedPrincipal, Permission, PermissionGrant, Principal, PrincipalData, ROLE_ADMIN, Type,
backend::internal::{PrincipalField, PrincipalSet, PrincipalUpdate, PrincipalValue},
};
impl Principal {
pub fn new(id: u32, typ: Type) -> Self {
Self {
@@ -313,7 +312,7 @@ impl Principal {
pub fn fallback_admin(fallback_pass: impl Into<String>) -> Self {
Principal {
id: u32::MAX,
id: FALLBACK_ADMIN_ID,
typ: Type::Individual,
name: "Fallback Administrator".into(),
secrets: vec![fallback_pass.into()],

View File

@@ -23,7 +23,7 @@ use crate::Principal;
use crate::backend::internal::SpecialSecrets;
impl Principal {
pub async fn verify_secret(&self, mut code: &str) -> trc::Result<bool> {
pub async fn verify_secret(&self, mut code: &str, only_app_pass: bool) -> trc::Result<bool> {
let mut totp_token = None;
let mut is_totp_token_missing = false;
let mut is_totp_required = false;
@@ -68,7 +68,7 @@ impl Principal {
secret.strip_prefix("$app$").and_then(|s| s.split_once('$'))
{
is_app_authenticated = verify_secret_hash(app_secret, code).await?;
} else {
} else if !only_app_pass {
is_authenticated = verify_secret_hash(secret, code).await?;
}
}