api-tokens

This commit is contained in:
2025-11-01 21:42:52 +01:00
parent f6ceff5444
commit 00f5d3adea
16 changed files with 999 additions and 556 deletions
+28 -20
View File
@@ -16,9 +16,9 @@ use quick_xml::events::{BytesDecl, BytesEnd, BytesStart, BytesText, Event};
use quick_xml::Writer;
use uuid::Uuid;
use crate::auth::webdav_tokens::{find_active_token_by_secret, touch_webdav_token};
use crate::auth::api_tokens::{find_active_token_by_secret, touch_api_token};
use crate::error::{AppError, AppResult};
use crate::models::{Document, DocumentVersion, Folder, User};
use crate::models::{ApiTokenCapability, Document, DocumentVersion, Folder, User};
use crate::schema::{
document_versions::dsl as document_versions_dsl, documents::dsl as documents_dsl,
folders::dsl as folders_dsl, user_memberships::dsl as memberships_dsl, users::dsl as users_dsl,
@@ -425,34 +425,40 @@ fn authenticate(state: &AppState, headers: &HeaderMap) -> Result<Option<WebDavCo
}
};
let (username, secret) = match credential_str.split_once(':') {
let (presented_username, secret) = match credential_str.split_once(':') {
Some((username, secret)) if !username.is_empty() => (username, secret),
_ => return Ok(None),
};
tracing::debug!(%username, "attempting webdav login");
tracing::debug!(presented_username = %presented_username, "attempting webdav login");
let mut conn = state.db_unscoped()?;
let user: User = match users_dsl::users
.filter(users_dsl::username.eq(username))
.first(&mut conn)
{
let token = match find_active_token_by_secret(
&mut conn,
None,
secret,
ApiTokenCapability::Webdav,
)? {
Some(token) => token,
None => {
tracing::warn!(presented_username = %presented_username, "webdav token invalid or expired");
return Ok(None);
}
};
let user: User = match users_dsl::users.find(token.user_id).first(&mut conn) {
Ok(user) => user,
Err(diesel::result::Error::NotFound) => {
tracing::warn!(%username, "webdav user not found");
tracing::warn!(
presented_username = %presented_username,
user_id = %token.user_id,
"webdav token user missing"
);
return Ok(None);
}
Err(err) => return Err(AppError::from(err)),
};
let token = match find_active_token_by_secret(&mut conn, user.id, None, secret)? {
Some(token) => token,
None => {
tracing::warn!(%username, "webdav token invalid or expired");
return Ok(None);
}
};
apply_user_guc(&mut conn, user.id)?;
let membership_exists = memberships_dsl::user_memberships
@@ -468,7 +474,8 @@ fn authenticate(state: &AppState, headers: &HeaderMap) -> Result<Option<WebDavCo
Some(id) => id,
None => {
tracing::warn!(
%username,
presented_username = %presented_username,
username = %user.username,
tenant_id = %token.tenant_id,
"webdav token tenant membership missing"
);
@@ -477,10 +484,11 @@ fn authenticate(state: &AppState, headers: &HeaderMap) -> Result<Option<WebDavCo
};
apply_tenant_guc(&mut conn, tenant_id)?;
touch_webdav_token(&mut conn, token.id)?;
touch_api_token(&mut conn, token.id)?;
tracing::debug!(
%username,
presented_username = %presented_username,
username = %user.username,
tenant_id = %tenant_id,
token_id = %token.id,
"webdav token login success"