Expose endpoint under /cluster/notifications/smtp-oauth2-token to exchange the initial authorization code for a refresh token.
Azure AD's "Web" client type, which we require in order to be able to keep getting new access tokens in the backend without requiring re-authorization by users, rejects browser-originated token requests, so this must run on the backend. Signed-off-by: Arthur Bied-Charreton <[email protected]> --- PVE/API2/Cluster/Notifications.pm | 77 +++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/PVE/API2/Cluster/Notifications.pm b/PVE/API2/Cluster/Notifications.pm index 8e118483..830070e9 100644 --- a/PVE/API2/Cluster/Notifications.pm +++ b/PVE/API2/Cluster/Notifications.pm @@ -81,6 +81,7 @@ __PACKAGE__->register_method({ { name => 'targets' }, { name => 'matcher-fields' }, { name => 'matcher-field-values' }, + { name => 'smtp-oauth2-token' }, ]; return $result; @@ -321,6 +322,82 @@ __PACKAGE__->register_method({ }, }); +__PACKAGE__->register_method({ + name => 'smtp_oauth2_token', + path => 'smtp-oauth2-token', + protected => 1, + method => 'POST', + description => 'Exchanges the initial OAuth2 authorization code for a refresh token', + permissions => { + check => [ + 'and', + ['perm', '/mapping/notifications', ['Mapping.Modify']], + [ + 'or', + ['perm', '/', ['Sys.Audit', 'Sys.Modify']], + ['perm', '/', ['Sys.AccessNetwork']], + ], + ], + }, + parameters => { + additionalProperties => 0, + properties => { + 'auth-method' => { + description => 'Authentication method', + type => 'string', + enum => [qw(google-oauth2 microsoft-oauth2)], + }, + 'client-id' => { + description => 'OAuth2 client ID', + type => 'string', + }, + 'client-secret' => { + description => 'OAuth2 client secret', + type => 'string', + }, + 'tenant-id' => { + description => 'OAuth2 tenant ID, only required for Microsoft OAuth2 endpoints', + type => 'string', + optional => 1, + }, + 'authorization-code' => { + description => 'Initial OAuth2 authorization code', + type => 'string', + }, + 'redirect-uri' => { + description => "OAuth2 redirect URI", + type => 'string', + }, + }, + }, + returns => { type => 'string' }, + code => sub { + my ($param) = @_; + + my $auth_method = extract_param($param, 'auth-method'); + my $client_id = extract_param($param, 'client-id'); + my $client_secret = extract_param($param, 'client-secret'); + my $tenant_id = extract_param($param, 'tenant-id'); + my $authorization_code = extract_param($param, 'authorization-code'); + my $redirect_uri = extract_param($param, 'redirect-uri'); + + my $refresh_token = eval { + my $config = PVE::Notify::read_config(); + $config->exchange_smtp_oauth2_code( + $auth_method, + $client_id, + $client_secret, + $tenant_id, + $authorization_code, + $redirect_uri, + ); + }; + raise_api_error($@) if $@; + + return $refresh_token; + }, +}); + __PACKAGE__->register_method({ name => 'test_target', path => 'targets/{name}/test', -- 2.47.3
