From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <pdm-devel-bounces@lists.proxmox.com>
Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68])
	by lore.proxmox.com (Postfix) with ESMTPS id C4A9F1FF168
	for <inbox@lore.proxmox.com>; Tue,  4 Mar 2025 13:05:53 +0100 (CET)
Received: from firstgate.proxmox.com (localhost [127.0.0.1])
	by firstgate.proxmox.com (Proxmox) with ESMTP id 72EE41DAD8;
	Tue,  4 Mar 2025 13:05:50 +0100 (CET)
From: Shannon Sterz <s.sterz@proxmox.com>
To: pdm-devel@lists.proxmox.com
Date: Tue,  4 Mar 2025 13:04:54 +0100
Message-Id: <20250304120506.135617-10-s.sterz@proxmox.com>
X-Mailer: git-send-email 2.39.5
In-Reply-To: <20250304120506.135617-1-s.sterz@proxmox.com>
References: <20250304120506.135617-1-s.sterz@proxmox.com>
MIME-Version: 1.0
X-SPAM-LEVEL: Spam detection results:  0
 AWL -0.069 Adjusted score from AWL reputation of From: address
 BAYES_00                 -1.9 Bayes spam probability is 0 to 1%
 DMARC_MISSING             0.1 Missing DMARC policy
 KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment
 PROLO_LEO2                0.1 Meta Catches all Leo drug variations so far
 SPF_HELO_NONE           0.001 SPF: HELO does not publish an SPF Record
 SPF_PASS               -0.001 SPF: sender matches SPF record
Subject: [pdm-devel] [PATCH proxmox v4 09/21] auth-api: add logout method
X-BeenThere: pdm-devel@lists.proxmox.com
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: Proxmox Datacenter Manager development discussion
 <pdm-devel.lists.proxmox.com>
List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pdm-devel>, 
 <mailto:pdm-devel-request@lists.proxmox.com?subject=unsubscribe>
List-Archive: <http://lists.proxmox.com/pipermail/pdm-devel/>
List-Post: <mailto:pdm-devel@lists.proxmox.com>
List-Help: <mailto:pdm-devel-request@lists.proxmox.com?subject=help>
List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel>, 
 <mailto:pdm-devel-request@lists.proxmox.com?subject=subscribe>
Reply-To: Proxmox Datacenter Manager development discussion
 <pdm-devel@lists.proxmox.com>
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Errors-To: pdm-devel-bounces@lists.proxmox.com
Sender: "pdm-devel" <pdm-devel-bounces@lists.proxmox.com>

adds a new endpoint that is useful when dealing with HttpOnly cookies
that cannot be removed by client-side javascript (and by extension
wasm) code. the logout handle simply removes the cookie that is used
for storing the current ticket. this works the same way as it does in
the front-end: by setting an expired cookie with the same name.

as cookies are now prefixed with `__Host-` by default, the cookie here
also needs to be `Secure` and have the same `Path` to not be rejected
by the browser before it can remove the old cookie.

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 proxmox-auth-api/src/api/access.rs | 29 ++++++++++++++++++++++++++++-
 proxmox-auth-api/src/api/mod.rs    |  2 +-
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/proxmox-auth-api/src/api/access.rs b/proxmox-auth-api/src/api/access.rs
index 260440bf..411ac5b5 100644
--- a/proxmox-auth-api/src/api/access.rs
+++ b/proxmox-auth-api/src/api/access.rs
@@ -11,7 +11,7 @@ use proxmox_rest_server::{extract_cookie, RestEnvironment};
 use proxmox_router::{
     http_err, ApiHandler, ApiMethod, ApiResponseFuture, Permission, RpcEnvironment,
 };
-use proxmox_schema::{api, AllOfSchema, ApiType, ParameterSchema, ReturnType};
+use proxmox_schema::{api, AllOfSchema, ApiType, ObjectSchema, ParameterSchema, ReturnType};
 use proxmox_tfa::api::TfaChallenge;
 
 use super::ApiTicket;
@@ -63,6 +63,33 @@ pub async fn create_ticket(
     handle_ticket_creation(create_params, env).await
 }
 
+pub const API_METHOD_LOGOUT: ApiMethod = ApiMethod::new(
+    &ApiHandler::AsyncHttpBodyParameters(&logout_handler),
+    &ObjectSchema::new("", &[]),
+)
+.protected(true)
+.access(None, &Permission::World);
+
+fn logout_handler(
+    _parts: Parts,
+    _param: Value,
+    _info: &ApiMethod,
+    _rpcenv: Box<dyn RpcEnvironment>,
+) -> ApiResponseFuture {
+    Box::pin(async move {
+        // unset authentication cookie by setting an invalid one. needs the same `Path` and
+        // `Secure` parameter to not be rejected by some browsers. also use the same `HttpOnly` and
+        // `SameSite` parameters just in case.
+        let host_cookie = format!(
+            "{}=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Secure; SameSite=Lax; HttpOnly; Path=/;",
+            auth_context()?.prefixed_auth_cookie_name()
+        );
+
+        Ok(Response::builder()
+            .header(hyper::header::SET_COOKIE, host_cookie)
+            .body(Body::empty())?)
+    })
+}
 
 pub const API_METHOD_CREATE_TICKET_HTTP_ONLY: ApiMethod = ApiMethod::new_full(
     &ApiHandler::AsyncHttpBodyParameters(&create_ticket_http_only),
diff --git a/proxmox-auth-api/src/api/mod.rs b/proxmox-auth-api/src/api/mod.rs
index 3ee2d0e1..e176ea01 100644
--- a/proxmox-auth-api/src/api/mod.rs
+++ b/proxmox-auth-api/src/api/mod.rs
@@ -20,7 +20,7 @@ use access::verify_csrf_prevention_token;
 
 pub use access::{
     assemble_csrf_prevention_token, create_ticket, API_METHOD_CREATE_TICKET,
-    API_METHOD_CREATE_TICKET_HTTP_ONLY,
+    API_METHOD_CREATE_TICKET_HTTP_ONLY, API_METHOD_LOGOUT,
 };
 pub use ticket::{ApiTicket, PartialTicket};
 
-- 
2.39.5



_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel