public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Arthur Bied-Charreton <a.bied-charreton@proxmox.com>
To: Lukas Wagner <l.wagner@proxmox.com>
Cc: pve-devel@lists.proxmox.com
Subject: Re: [PATCH proxmox 4/5] notify: smtp: add OAuth2/XOAUTH2 authentication support
Date: Wed, 11 Feb 2026 14:00:40 +0100	[thread overview]
Message-ID: <5opeuvrpig43irxubo5gvck2zugj3uhhwc2dv6tb3bgvu5zcc3@ghsoa2l7ovt4> (raw)
In-Reply-To: <DGBEI9OJJZ92.10Q7MFGSTOWEV@proxmox.com>

On Tue, Feb 10, 2026 at 04:52:51PM +0100, Lukas Wagner wrote:
> Hey Arthur!
> 
> Great work, looking really good so far. Left some comments inline.
> 
> On Wed Feb 4, 2026 at 5:13 PM CET, Arthur Bied-Charreton wrote:
> > Add Google & Microsoft OAuth2 support for SMTP notification targets. The
> > SmtpEndpoint implements refresh_state() to allow proactively refreshing
> > tokens through pveupdate.
> >
> > The SMTP API functions are updated to handle OAuth2 state. The refresh
> > token initially comes from the frontend, and it is more state than it is
> > configuration, therefore it is passed as a single parameter in
> > {add,update}_endpoint and persisted separately.
> >
> > Signed-off-by: Arthur Bied-Charreton <a.bied-charreton@proxmox.com>
> > [...]
> > +    update_state(
> > +        &endpoint_config.name,
> > +        Some(SmtpState {
> > +            oauth2_refresh_token,
> > +            last_refreshed: SystemTime::now()
> > +                .duration_since(UNIX_EPOCH)
> 
> We already have a nice helper for this - proxmox_time::epoch_i64
> 
I was looking for something like that, thanks :)

> > +                .unwrap() +                .as_secs(),
> > +        }),
> > +    )?;
> > +
> >      config
> >          .config
> >          .set_data(&endpoint_config.name, SMTP_TYPENAME, &endpoint_config)
> > @@ -76,6 +119,28 @@ pub fn add_endpoint(
> >          })
> >  }
> >  
> > +/// Apply `updater` to the private config identified by `name`, and set
> > +/// the private config entry afterwards.
> > +pub fn update_private_config(
> 
> 
> This function does not need to be `pub`, I think?
> 

> 
> > +    config: &mut Config,
> > +    name: &str,
> > +    updater: impl FnOnce(&mut SmtpPrivateConfig),
> 
> nice idea btw, using a closure like this
> 
> > [...]
> > +    update_state(
> > +        name,
> > +        Some(SmtpState {
> > +            oauth2_refresh_token,
> > +            last_refreshed: SystemTime::now()
> > +                .duration_since(UNIX_EPOCH)
> > +                .unwrap()
> > +                .as_secs(),
> 
> same here regarding proxmox_time::epoch_i64
> 
> > [...]
> > +/// Authentication mode to use for SMTP.
> > +#[api]
> > +#[derive(Serialize, Deserialize, Clone, Debug, Default)]
> 
> You could also derive `Copy` here, then you don't need to clone it in
> some places in the code.
> 

[...]
> Same here regarding proxmox_time::epoch_i64
> 
> > +
> > +                transport_builder
> > +                    .credentials(Credentials::new(
> > +                        self.config.from_address.clone(),
> > +                        token_exchange_result.access_token.into_secret(),
> > +                    ))
> > +                    .authentication(vec![Mechanism::Xoauth2])
> >              }
> > -        }
> > +        };
> >  
> >          let transport = transport_builder.build();
> 
> I think it could be nice to move everything above this line to a
> separate method `build_smtp_tansport` - this method is getting rather
> long and this part is a very distinct step of the things performed here.
> 
Thanks for all the feedback, I will address all of it in v2

> > +        {
> > +            return Ok(false);
> > +        }
> > +
> > +        let Some(auth_method) = self.config.auth_method.as_ref() else {
> > +            return Ok(false);
> > +        };
> > +
> > +        let new_state = match self
> > +            .get_access_token(&refresh_token, auth_method)?
> > +            .refresh_token
> > +        {
> > +            // Microsoft OAuth2, new token was returned
> > +            Some(new_refresh_token) => SmtpState {
> > +                oauth2_refresh_token: Some(new_refresh_token.into_secret()),
> > +                last_refreshed: SystemTime::now()
> > +                    .duration_since(UNIX_EPOCH)
> > +                    .unwrap()
> > +                    .as_secs(),
> > +            },
> > +            // Google OAuth2, refresh token's lifetime was extended
> > +            None => SmtpState {
> > +                oauth2_refresh_token: Some(refresh_token),
> > +                last_refreshed: SystemTime::now()
> > +                    .duration_since(UNIX_EPOCH)
> > +                    .unwrap()
> > +                    .as_secs(),
> > +            },
> > +        };
> > +
> > +        state.set(self.name(), &new_state)?;
> > +        Ok(true)
> 
> It seems like you return Ok(true) in case that the state changed (token
> was refreshed) and Ok(false) if nothing changed, is this correct?
> 
> The boolean parameter should be documented in the trait doc-comments.
> Also at the moment you don't seem to use the boolean part anywhere? I
> guess we could use it to determine whether we need to replace the
> existing state file at all (we don't if all endpoints returned `false`).
> 
The plan was originally to be able to only persist the state if
something changed yes, however with the new approach we discussed
off-list, each endpoint will only be passed its own state (as opposed to 
currently, getting the state for all endpoints and being responsible for 
looking up its own).

I was thinking about changing send() and refresh_state() to return an
Option<S> instead, that way we avoid the output parameter and the bus
can determine whether it needs to update the global state itself.




  reply	other threads:[~2026-02-11 13:00 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-04 16:13 [RFC cluster/docs/manager/proxmox{,-perl-rs,-widget-toolkit} 00/15] fix #7238: Add XOAUTH2 authentication support for SMTP notification targets Arthur Bied-Charreton
2026-02-04 16:13 ` [PATCH proxmox 1/5] notify: Introduce xoauth2 module Arthur Bied-Charreton
2026-02-06 15:00   ` Lukas Wagner
2026-02-09  8:34     ` Arthur Bied-Charreton
2026-02-10  8:24       ` Lukas Wagner
2026-02-10 10:23         ` Arthur Bied-Charreton
2026-02-04 16:13 ` [PATCH proxmox 2/5] notify: Add state file handling Arthur Bied-Charreton
2026-02-10 15:51   ` Lukas Wagner
2026-02-04 16:13 ` [PATCH proxmox 3/5] notify: Update Endpoint trait and Bus to use State Arthur Bied-Charreton
2026-02-10 15:52   ` Lukas Wagner
2026-02-12  8:26     ` Arthur Bied-Charreton
2026-02-04 16:13 ` [PATCH proxmox 4/5] notify: smtp: add OAuth2/XOAUTH2 authentication support Arthur Bied-Charreton
2026-02-10 15:52   ` Lukas Wagner
2026-02-11 13:00     ` Arthur Bied-Charreton [this message]
2026-02-04 16:13 ` [PATCH proxmox 5/5] notify: Add test for State Arthur Bied-Charreton
2026-02-04 16:13 ` [PATCH proxmox-perl-rs 1/1] notify: update bindings with new OAuth2 parameters Arthur Bied-Charreton
2026-02-04 16:13 ` [PATCH proxmox-widget-toolkit 1/2] utils: Add OAuth2 flow handlers Arthur Bied-Charreton
2026-02-04 16:13 ` [PATCH proxmox-widget-toolkit 2/2] notifications: Add opt-in OAuth2 support for SMTP targets Arthur Bied-Charreton
2026-02-04 16:13 ` [PATCH pve-manager 1/5] notifications: Add OAuth2 parameters to schema and add/update endpoints Arthur Bied-Charreton
2026-02-11  8:55   ` Lukas Wagner
2026-02-11 12:47     ` Arthur Bied-Charreton
2026-02-04 16:13 ` [PATCH pve-manager 2/5] notifications: Add refresh-targets endpoint Arthur Bied-Charreton
2026-02-11  9:49   ` Lukas Wagner
2026-02-11 12:44     ` Arthur Bied-Charreton
2026-02-04 16:13 ` [PATCH pve-manager 3/5] notifications: Trigger notification target refresh in pveupdate Arthur Bied-Charreton
2026-02-04 16:13 ` [PATCH pve-manager 4/5] notifications: Handle OAuth2 callback in login handler Arthur Bied-Charreton
2026-02-11  9:00   ` Lukas Wagner
2026-02-04 16:13 ` [PATCH pve-manager 5/5] notifications: Opt into OAuth2 authentication Arthur Bied-Charreton
2026-02-04 16:13 ` [PATCH pve-cluster 1/1] notifications: Add refresh_targets subroutine to PVE::Notify Arthur Bied-Charreton
2026-02-04 16:13 ` [PATCH pve-docs 1/1] notifications: Add section about OAuth2 to SMTP targets docs Arthur Bied-Charreton
2026-02-11 10:06   ` Lukas Wagner
2026-02-11 13:15     ` Arthur Bied-Charreton
2026-02-13 16:06 ` superseded: [RFC cluster/docs/manager/proxmox{,-perl-rs,-widget-toolkit} 00/15] fix #7238: Add XOAUTH2 authentication support for SMTP notification targets 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=5opeuvrpig43irxubo5gvck2zugj3uhhwc2dv6tb3bgvu5zcc3@ghsoa2l7ovt4 \
    --to=a.bied-charreton@proxmox.com \
    --cc=l.wagner@proxmox.com \
    --cc=pve-devel@lists.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
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal