Files
3fc0ef2506 feat: added xoauth for smtp (#11239)
# Which Problems Are Solved

- Some mail providers (e.g.: MS Exchange) have deprecated plain auth

# How the Problems Are Solved

Adds XOauth2 auth option to SMPT
- SMTP config now can contain XOAuth2 auth config
- Proto files are updated to have a oneof for configuration selection.
Old fields for configuring plain auth are still available not to create
a breaking change. These can be removed in the future.
- Columns are added to the database to persist the config

# Additional Changes

none

# Additional Context

Replace this example with links to related issues, discussions, discord
threads, or other sources with more context.
Use the Closing #issue syntax for issues that are resolved with this PR.
- Closes #8042

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: Tim Möhlmann <[email protected]>
2026-01-27 15:11:56 +01:00

151 lines
5.2 KiB
Go

package admin
import (
"context"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/api/grpc/object"
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
admin_pb "github.com/zitadel/zitadel/pkg/grpc/admin"
)
// Deprecated: use [GetEmailProvider] instead.
func (s *Server) GetSMTPConfig(ctx context.Context, req *admin_pb.GetSMTPConfigRequest) (*admin_pb.GetSMTPConfigResponse, error) {
smtp, err := s.query.SMTPConfigActive(ctx, authz.GetInstance(ctx).InstanceID())
if err != nil {
return nil, err
}
return &admin_pb.GetSMTPConfigResponse{
SmtpConfig: SMTPConfigToPb(smtp),
}, nil
}
// Deprecated: use [GetEmailProviderById] instead.
func (s *Server) GetSMTPConfigById(ctx context.Context, req *admin_pb.GetSMTPConfigByIdRequest) (*admin_pb.GetSMTPConfigByIdResponse, error) {
smtp, err := s.query.SMTPConfigByID(ctx, authz.GetInstance(ctx).InstanceID(), req.Id)
if err != nil {
return nil, err
}
return &admin_pb.GetSMTPConfigByIdResponse{
SmtpConfig: SMTPConfigToPb(smtp),
}, nil
}
// Deprecated: use [AddEmailProviderSMTP] instead.
func (s *Server) AddSMTPConfig(ctx context.Context, req *admin_pb.AddSMTPConfigRequest) (*admin_pb.AddSMTPConfigResponse, error) {
config := addSMTPToConfig(ctx, req)
if err := s.command.AddSMTPConfig(ctx, config); err != nil {
return nil, err
}
return &admin_pb.AddSMTPConfigResponse{
Details: object.DomainToChangeDetailsPb(config.Details),
Id: config.ID,
}, nil
}
// Deprecated: use [UpdateEmailProviderSMTP] instead.
func (s *Server) UpdateSMTPConfig(ctx context.Context, req *admin_pb.UpdateSMTPConfigRequest) (*admin_pb.UpdateSMTPConfigResponse, error) {
config := updateSMTPToConfig(ctx, req)
if err := s.command.ChangeSMTPConfig(ctx, config); err != nil {
return nil, err
}
return &admin_pb.UpdateSMTPConfigResponse{
Details: object.DomainToChangeDetailsPb(config.Details),
}, nil
}
// Deprecated: use [RemoveEmailProviderSMTP] instead.
func (s *Server) RemoveSMTPConfig(ctx context.Context, req *admin_pb.RemoveSMTPConfigRequest) (*admin_pb.RemoveSMTPConfigResponse, error) {
details, err := s.command.RemoveSMTPConfig(ctx, authz.GetInstance(ctx).InstanceID(), req.Id)
if err != nil {
return nil, err
}
return &admin_pb.RemoveSMTPConfigResponse{
Details: object.DomainToChangeDetailsPb(details),
}, nil
}
// Deprecated: use [UpdateEmailProviderSMTPPassword] instead.
func (s *Server) UpdateSMTPConfigPassword(ctx context.Context, req *admin_pb.UpdateSMTPConfigPasswordRequest) (*admin_pb.UpdateSMTPConfigPasswordResponse, error) {
details, err := s.command.ChangeSMTPConfigPassword(ctx, authz.GetInstance(ctx).InstanceID(), req.Id, req.Password)
if err != nil {
return nil, err
}
return &admin_pb.UpdateSMTPConfigPasswordResponse{
Details: object.DomainToChangeDetailsPb(details),
}, nil
}
// Deprecated: use [ListEmailProviders] instead.
func (s *Server) ListSMTPConfigs(ctx context.Context, req *admin_pb.ListSMTPConfigsRequest) (*admin_pb.ListSMTPConfigsResponse, error) {
queries, err := listSMTPConfigsToModel(req)
if err != nil {
return nil, err
}
result, err := s.query.SearchSMTPConfigs(ctx, queries)
if err != nil {
return nil, err
}
return &admin_pb.ListSMTPConfigsResponse{
Details: object.ToListDetails(result.Count, result.Sequence, result.LastRun),
Result: SMTPConfigsToPb(result.Configs),
}, nil
}
// Deprecated: use [ActivateEmailProvider] instead.
func (s *Server) ActivateSMTPConfig(ctx context.Context, req *admin_pb.ActivateSMTPConfigRequest) (*admin_pb.ActivateSMTPConfigResponse, error) {
result, err := s.command.ActivateSMTPConfig(ctx, authz.GetInstance(ctx).InstanceID(), req.Id)
if err != nil {
return nil, err
}
return &admin_pb.ActivateSMTPConfigResponse{
Details: object.DomainToAddDetailsPb(result),
}, nil
}
// Deprecated: use [DeactivateEmailProvider] instead.
func (s *Server) DeactivateSMTPConfig(ctx context.Context, req *admin_pb.DeactivateSMTPConfigRequest) (*admin_pb.DeactivateSMTPConfigResponse, error) {
result, err := s.command.DeactivateSMTPConfig(ctx, authz.GetInstance(ctx).InstanceID(), req.Id)
if err != nil {
return nil, err
}
return &admin_pb.DeactivateSMTPConfigResponse{
Details: object.DomainToAddDetailsPb(result),
}, nil
}
// Deprecated: use [TestEmailProviderSMTPById] instead.
func (s *Server) TestSMTPConfigById(ctx context.Context, req *admin_pb.TestSMTPConfigByIdRequest) (*admin_pb.TestSMTPConfigByIdResponse, error) {
err := s.command.TestSMTPConfigById(ctx, authz.GetInstance(ctx).InstanceID(), req.Id, req.ReceiverAddress)
if err != nil {
return nil, err
}
return &admin_pb.TestSMTPConfigByIdResponse{}, nil
}
// Deprecated: use [TestEmailProviderSMTP] instead.
func (s *Server) TestSMTPConfig(ctx context.Context, req *admin_pb.TestSMTPConfigRequest) (*admin_pb.TestSMTPConfigResponse, error) {
config := smtp.Config{
Tls: req.Tls,
From: req.SenderAddress,
FromName: req.SenderName,
SMTP: smtp.SMTP{
Host: req.Host,
PlainAuth: &smtp.PlainAuthConfig{
User: req.User,
Password: req.Password,
},
},
}
err := s.command.TestSMTPConfig(ctx, authz.GetInstance(ctx).InstanceID(), req.Id, req.ReceiverAddress, &config)
if err != nil {
return nil, err
}
return &admin_pb.TestSMTPConfigResponse{}, nil
}