all lists on lists.proxmox.com
 help / color / mirror / Atom feed
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 03/24] notify: smtp: Introduce state management
Date: Fri, 24 Apr 2026 09:47:52 +0200	[thread overview]
Message-ID: <nh5pf5gl2z57q5kxzsyfsxpmypocefiawhrxondq5kzei6g4up@bb5v2jdkxqk2> (raw)
In-Reply-To: <DI0J626B8G1B.YILW4N9QF4LF@proxmox.com>

On Thu, Apr 23, 2026 at 02:24:37PM +0200, Shannon Sterz wrote:
> On Tue Apr 21, 2026 at 1:59 PM CEST, Arthur Bied-Charreton wrote:
> > Export a new State struct in the xoauth2 module with associated
> > functionality for loading, updating, and persisting the OAuth2 state
> > for SMTP endpoints.
> >
> > The API for loading and saving the state is exposed through the
> > Context trait, in order to make migration as easy as possible in
> > a future where we might want to move towards KV storage instead
> > of files for secret management. It is made specific to oauth state,
> > because this implementation assumes invariants that hold for oauth2
> > refresh tokens (documented in the smtp::xoauth2 module's doc comments),
> > but are likely to be incorrect for other kinds of state that may be added
> > in the future.
> >
> > The State struct is public in order to support the long-term goal for
> > the Context trait to be implemented by the products themselves.
> >
> > The nix crate is added for the sys::stat::Mode struct, and
> > proxmox-sys is now pulled in unconditionally since it is used in the
> > Context implementations.
> >
> >
[...]
> > @@ -32,6 +34,21 @@ pub trait Context: Send + Sync + Debug {
> >          namespace: Option<&str>,
> >          source: TemplateSource,
> >      ) -> Result<Option<String>, Error>;
> > +    /// Load OAuth state for `endpoint_name`.
> > +    ///
> > +    /// The state file does not need to be locked, it is okay to just let the faster node "win"
> > +    /// as long as the invariants documented by [`smtp::xoauth2::get_microsoft_token`] and
> > +    /// [`smtp::xoauth2::get_google_token`] hold, see those functions' doc comments for details.
> > +    #[cfg(feature = "smtp")]
> > +    fn load_oauth_state(&self, endpoint_name: &str) -> Result<State, Error>;
> > +    /// Save OAuth state `state` for `endpoint_name`. Passing `None` deletes
> > +    /// the state file for `endpoint_name`.
> > +    ///
> > +    /// The state file does not need to be locked, it is okay to just let the faster node "win"
> > +    /// as long as the invariants documented by [`smtp::xoauth2::get_microsoft_token`] and
> > +    /// [`smtp::xoauth2::get_google_token`] hold, see those functions' doc comments for details.
> > +    #[cfg(feature = "smtp")]
> > +    fn save_oauth_state(&self, endpoint_name: &str, state: Option<State>) -> Result<(), Error>;
> 
> i'm not sure the no-locking approach here works. if i understand
> correctly, the following example is possible:
> 
> A: calls `trigger_state_refresh`, does not lock the notification config
> B: calls `delete_smtp_endpoint`, locks the notification config
> A: reads the refresh token
> B: removes the endpoint and state file
> A: finishes refreshing the token and safes it out
> 
> if we extend that example with a C that adds an endpoint with the same
> name after B finishes, then it would suddenly be left with a state file
> from the previous endpoint. similar examples can also happen when
> calling `build_transport` since that also includes a read & write cycle
> of the state file.
> 
Yes you are right, I may have been too focused on refresh token validity
and overlooked this - thanks a lot for catching it!

> if the state file were locked properly, B would fail to acquire the lock
> when trying to delete it (or have to wait until A finishes).
> 
> if this behaviour is fine, maybe this would benefit from some
> documentation.
> 
I will add locks in v5, I don't think we are gaining that much from a
lock-free approach here, per-endpoint locking will be pretty cheap
anyway.

[...]
> > +
> > +    /// Persist the state at `path` with `options`.
> > +    ///
> > +    /// # Errors
> > +    /// An [`Error`] is returned if serialization of the state object, or the final write, fail.
> > +    pub fn save<P: AsRef<Path>>(
> > +        self,
> > +        path: P,
> > +        options: proxmox_sys::fs::CreateOptions,
> > +    ) -> Result<(), Error> {
> > +        let path_str = path.as_ref().to_string_lossy();
> > +        let parent = path.as_ref().parent().unwrap();
> > +
> 
> imo returning an error here might be nicer. while this isn't likely to
> happen, this would panic if called with `path` set to an empty string or
> similar. if you want to not error out here, at least turn that into an
> `expect` and document the panic in the comment above.
> 
That unwrap is uncalled for yes, looking at the code again I realized
this could just be 

if let Some(parent) = path.as_ref().parent() {
    create_path(parent, ...);
}

- thanks!

> side note: thanks for the extensive documentation here in general!
> 
:)
> > +        debug!("attempting to persist state at {path_str}");
> > +
> > +        proxmox_sys::fs::create_path(parent, Some(options), Some(options))
> > +            .map_err(|e| Error::StatePersistence(path_str.to_string(), e.into()))?;
> > +
> > +        let s = serde_json::to_string_pretty(&self)
> > +            .map_err(|e| Error::StatePersistence(path_str.to_string(), e.into()))?;
> > +
> > +        proxmox_sys::fs::replace_file(&path, s.as_bytes(), options, false)
> > +            .map_err(|e| Error::StatePersistence(path_str.to_string(), e.into()))
> > +    }
[...]




  reply	other threads:[~2026-04-24  7:48 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 [this message]
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
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=nh5pf5gl2z57q5kxzsyfsxpmypocefiawhrxondq5kzei6g4up@bb5v2jdkxqk2 \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal