From: Arthur Bied-Charreton <a.bied-charreton@proxmox.com>
To: Shannon Sterz <s.sterz@proxmox.com>
Cc: pbs-devel@lists.proxmox.com, pve-devel@lists.proxmox.com
Subject: Re: [PATCH proxmox v4 07/24] notify: smtp: Add state handling logic
Date: Fri, 24 Apr 2026 09:50:56 +0200 [thread overview]
Message-ID: <jqu246lmirvi4v7cjlo452uo74ns4cmp5mst2yjmet4ticwyww@g4lazm64mtbb> (raw)
In-Reply-To: <DI0J612BNHWZ.28X3SSEDVR4YE@proxmox.com>
On Thu, Apr 23, 2026 at 02:24:35PM +0200, Shannon Sterz wrote:
> On Tue Apr 21, 2026 at 1:59 PM CEST, Arthur Bied-Charreton wrote:
> > Create new state file in add_endpoint, create/update existing one in
> > update_endpoint and delete it in delete_endpoint.
> >
> > Add trigger_state_refresh to the Endpoint trait, with no-op default
> > implementation. Implement it in SmtpEndpoint's Endpoint impl to trigger
> > an OAuth2 token exchange, in order to rotate an existing token, or
> > extend its lifetime.
> >
> > Since trigger_state_refresh is called in pveupdate, it may be called
> > multiple times in quick succession by the different nodes in a
> > cluster. In order to avoid unnecessary churn on the state files, the
> > last_refreshed field is used to check if the state has been refreshed
> > shortly before, and skip the update if that is the case.
[...]
> > @@ -335,6 +375,43 @@ impl Endpoint for SmtpEndpoint {
> > fn disabled(&self) -> bool {
> > self.config.disable.unwrap_or_default()
> > }
> > +
> > + fn trigger_state_refresh(&self) -> Result<(), Error> {
> > + let state = context().load_oauth_state(self.name())?;
> > +
> > + let Some(refresh_token) = &state.oauth2_refresh_token else {
> > + return Ok(());
> > + };
> > +
> > + // The refresh job is configured in pveupdate, which runs once for each node.
> > + // Don't refresh if we already did it recently.
> > + if SystemTime::now()
> > + .duration_since(UNIX_EPOCH + Duration::from_secs(state.last_refreshed as u64))
> > + .map_err(|e| Error::Generic(e.to_string()))?
> > + < SMTP_STATE_REFRESH_CUTOFF_SECONDS
>
> if im not mistaken, this may not work as inteded. since no lock is held
> between the `load` and `save` calls, this scenario could happen:
>
> A: triggers a refresh, reads the old timestamp, triggers a proper
> refresh
> B: triggers a refresh, reads the old timestamp, triggers a proper
> refresh
> A: writes the refreshed token and timestamp
> B: writes the refreshed token and timestamp
>
> since multiple tokens can be valid at the same time (from what i can
> tell), it doesn't really matter which thread wins the race here in terms
> of the token being valid after the refresh. however, this mechanism may
> be less effective than intended when it comes to stopping refreshes in
> quick succession.
>
> this would also be fixed by locking i suggested in a previous message.
>
That is true, thanks! I will add locks in v5, as mentioned in my
response to your previous message [0].
[0] https://lore.proxmox.com/pve-devel/nh5pf5gl2z57q5kxzsyfsxpmypocefiawhrxondq5kzei6g4up@bb5v2jdkxqk2/T/#u
> > + {
> > + return Ok(());
> > + }
> > +
> > + let Some(auth_method) = self.config.auth_method.as_ref() else {
> > + return Ok(());
> > + };
> > +
> > + let state = match self
> > + .get_access_token(refresh_token, auth_method)?
> > + .refresh_token
> > + {
> > + Some(tok) => state.set_oauth2_refresh_token(Some(tok.into_secret())), // New token was returned, rotate
> > + None => state,
> > + }
> > + .set_last_refreshed(proxmox_time::epoch_i64());
> > +
> > + context().save_oauth_state(self.name(), Some(state))?;
> > +
> > + info!("OAuth2 state refreshed for endpoint `{}`", self.name());
> > +
> > + Ok(())
> > + }
> > }
[...]
next prev parent reply other threads:[~2026-04-24 7:51 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-21 11:59 [PATCH docs/manager/proxmox{,-perl-rs,-widget-toolkit,-backup} v4 00/24] fix #7238: Add XOAUTH2 authentication support for SMTP notification targets Arthur Bied-Charreton
2026-04-21 11:59 ` [PATCH proxmox v4 01/24] Add oauth2 and ureq to workspace dependencies Arthur Bied-Charreton
2026-04-21 11:59 ` [PATCH proxmox v4 02/24] notify: smtp: Introduce xoauth2 module Arthur Bied-Charreton
2026-04-21 11:59 ` [PATCH proxmox v4 03/24] notify: smtp: Introduce state management Arthur Bied-Charreton
2026-04-23 12:24 ` Shannon Sterz
2026-04-24 7:47 ` Arthur Bied-Charreton
2026-04-24 8:04 ` Shannon Sterz
2026-04-24 8:54 ` Arthur Bied-Charreton
2026-04-24 8:59 ` Shannon Sterz
2026-04-21 11:59 ` [PATCH proxmox v4 04/24] notify: smtp: Factor out transport building logic Arthur Bied-Charreton
2026-04-21 11:59 ` [PATCH proxmox v4 05/24] notify: smtp: Update API with OAuth2 parameters Arthur Bied-Charreton
2026-04-21 11:59 ` [PATCH proxmox v4 06/24] notify: smtp: Infer auth method for backwards compatibility Arthur Bied-Charreton
2026-04-21 11:59 ` [PATCH proxmox v4 07/24] notify: smtp: Add state handling logic Arthur Bied-Charreton
2026-04-23 12:24 ` Shannon Sterz
2026-04-24 7:50 ` Arthur Bied-Charreton [this message]
2026-04-21 11:59 ` [PATCH proxmox v4 08/24] notify: smtp: Add XOAUTH2 authentication support Arthur Bied-Charreton
2026-04-21 11:59 ` [PATCH proxmox-perl-rs v4 09/24] pve-rs: notify: smtp: add OAuth2 parameters to bindings Arthur Bied-Charreton
2026-04-21 11:59 ` [PATCH proxmox-perl-rs v4 10/24] pve-rs: notify: Add binding for triggering state refresh Arthur Bied-Charreton
2026-04-21 11:59 ` [PATCH proxmox-widget-toolkit v4 11/24] utils: Add OAuth2 flow handlers Arthur Bied-Charreton
2026-04-23 12:24 ` Shannon Sterz
2026-04-24 8:44 ` Arthur Bied-Charreton
2026-04-24 8:53 ` Shannon Sterz
2026-04-21 11:59 ` [PATCH proxmox-widget-toolkit v4 12/24] utils: oauth2: Add callback handler Arthur Bied-Charreton
2026-04-21 11:59 ` [PATCH proxmox-widget-toolkit v4 13/24] notifications: Add opt-in OAuth2 support for SMTP targets Arthur Bied-Charreton
2026-04-21 11:59 ` [PATCH pve-manager v4 14/24] notifications: smtp: api: Add XOAUTH2 parameters Arthur Bied-Charreton
2026-04-21 11:59 ` [PATCH pve-manager v4 15/24] notifications: Add trigger-state-refresh endpoint Arthur Bied-Charreton
2026-04-21 11:59 ` [PATCH pve-manager v4 16/24] notifications: Trigger notification target refresh in pveupdate Arthur Bied-Charreton
2026-04-21 11:59 ` [PATCH pve-manager v4 17/24] login: Handle OAuth2 callback Arthur Bied-Charreton
2026-04-21 11:59 ` [PATCH pve-manager v4 18/24] fix #7238: notifications: smtp: Add XOAUTH2 support Arthur Bied-Charreton
2026-04-21 11:59 ` [PATCH proxmox-backup v4 19/24] notifications: Add XOAUTH2 parameters to endpoints Arthur Bied-Charreton
2026-04-21 11:59 ` [PATCH proxmox-backup v4 20/24] login: Handle OAuth2 callback Arthur Bied-Charreton
2026-04-21 11:59 ` [PATCH proxmox-backup v4 21/24] fix #7238: notifications: smtp: Add XOAUTH2 support Arthur Bied-Charreton
2026-04-21 11:59 ` [PATCH proxmox-backup v4 22/24] daily-update: Refresh OAuth2 state for SMTP notification endpoints Arthur Bied-Charreton
2026-04-21 11:59 ` [PATCH proxmox-backup v4 23/24] notifications: Add OAuth2 section to SMTP target docs Arthur Bied-Charreton
2026-04-23 12:24 ` Shannon Sterz
2026-04-24 7:59 ` Arthur Bied-Charreton
2026-04-24 8:18 ` Shannon Sterz
2026-04-24 8:46 ` Arthur Bied-Charreton
2026-04-21 11:59 ` [PATCH pve-docs v4 24/24] notifications: Add OAuth2 section to SMTP targets docs Arthur Bied-Charreton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=jqu246lmirvi4v7cjlo452uo74ns4cmp5mst2yjmet4ticwyww@g4lazm64mtbb \
--to=a.bied-charreton@proxmox.com \
--cc=pbs-devel@lists.proxmox.com \
--cc=pve-devel@lists.proxmox.com \
--cc=s.sterz@proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox