mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-10 08:05:12 +00:00
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]>
This commit is contained in:
co-authored by
Copilot
Tim Möhlmann
parent
96bbd6a65c
commit
3fc0ef2506
@@ -75,7 +75,7 @@ func httpToPb(http *query.HTTP) *settings_pb.EmailProvider_Http {
|
||||
}
|
||||
|
||||
func smtpToPb(config *query.SMTP) *settings_pb.EmailProvider_Smtp {
|
||||
return &settings_pb.EmailProvider_Smtp{
|
||||
ret := &settings_pb.EmailProvider_Smtp{
|
||||
Smtp: &settings_pb.EmailProviderSMTP{
|
||||
Tls: config.TLS,
|
||||
Host: config.Host,
|
||||
@@ -85,10 +85,34 @@ func smtpToPb(config *query.SMTP) *settings_pb.EmailProvider_Smtp {
|
||||
ReplyToAddress: config.ReplyToAddress,
|
||||
},
|
||||
}
|
||||
|
||||
if config.PlainAuth != nil {
|
||||
ret.Smtp.Auth = &settings_pb.EmailProviderSMTP_Plain{
|
||||
Plain: &settings_pb.SMTPPlainAuth{},
|
||||
}
|
||||
}
|
||||
if config.XOAuth2Auth != nil {
|
||||
xoauth2 := &settings_pb.EmailProviderSMTP_Xoauth2{
|
||||
Xoauth2: &settings_pb.SMTPXOAuth2Auth{
|
||||
TokenEndpoint: config.XOAuth2Auth.TokenEndpoint,
|
||||
Scopes: config.XOAuth2Auth.Scopes,
|
||||
},
|
||||
}
|
||||
if config.XOAuth2Auth.ClientCredentials != nil {
|
||||
xoauth2.Xoauth2.OAuth2Type = &settings_pb.SMTPXOAuth2Auth_ClientCredentials_{
|
||||
ClientCredentials: &settings_pb.SMTPXOAuth2Auth_ClientCredentials{
|
||||
ClientId: config.XOAuth2Auth.ClientCredentials.ClientId,
|
||||
},
|
||||
}
|
||||
}
|
||||
ret.Smtp.Auth = xoauth2
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func addEmailProviderSMTPToConfig(ctx context.Context, req *admin_pb.AddEmailProviderSMTPRequest) *command.AddSMTPConfig {
|
||||
return &command.AddSMTPConfig{
|
||||
cmd := &command.AddSMTPConfig{
|
||||
ResourceOwner: authz.GetInstance(ctx).InstanceID(),
|
||||
Description: req.Description,
|
||||
Tls: req.Tls,
|
||||
@@ -97,12 +121,41 @@ func addEmailProviderSMTPToConfig(ctx context.Context, req *admin_pb.AddEmailPro
|
||||
ReplyToAddress: req.ReplyToAddress,
|
||||
Host: req.Host,
|
||||
User: req.User,
|
||||
Password: req.Password,
|
||||
}
|
||||
|
||||
switch v := req.Auth.(type) {
|
||||
case *admin_pb.AddEmailProviderSMTPRequest_None:
|
||||
// Nothing to do, no auth is required
|
||||
case *admin_pb.AddEmailProviderSMTPRequest_Plain:
|
||||
cmd.PlainAuth = &command.PlainAuth{
|
||||
Password: v.Plain.Password,
|
||||
}
|
||||
case *admin_pb.AddEmailProviderSMTPRequest_Xoauth2:
|
||||
if xoauth2, ok := v.Xoauth2.OAuth2Type.(*admin_pb.SMTPXOAuth2Auth_ClientCredentials_); ok {
|
||||
cmd.XOAuth2Auth = &command.XOAuth2Auth{
|
||||
TokenEndpoint: v.Xoauth2.TokenEndpoint,
|
||||
Scopes: v.Xoauth2.Scopes,
|
||||
ClientCredentialsAuth: &command.OAuth2ClientCredentials{
|
||||
ClientId: xoauth2.ClientCredentials.ClientId,
|
||||
ClientSecret: xoauth2.ClientCredentials.ClientSecret,
|
||||
},
|
||||
}
|
||||
}
|
||||
default:
|
||||
// ensure backwards compatibility
|
||||
//nolint:staticcheck
|
||||
if req.User != "" || req.Password != "" {
|
||||
cmd.PlainAuth = &command.PlainAuth{
|
||||
Password: req.Password,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func updateEmailProviderSMTPToConfig(ctx context.Context, req *admin_pb.UpdateEmailProviderSMTPRequest) *command.ChangeSMTPConfig {
|
||||
return &command.ChangeSMTPConfig{
|
||||
cmd := &command.ChangeSMTPConfig{
|
||||
ResourceOwner: authz.GetInstance(ctx).InstanceID(),
|
||||
ID: req.Id,
|
||||
Description: req.Description,
|
||||
@@ -112,8 +165,41 @@ func updateEmailProviderSMTPToConfig(ctx context.Context, req *admin_pb.UpdateEm
|
||||
ReplyToAddress: req.ReplyToAddress,
|
||||
Host: req.Host,
|
||||
User: req.User,
|
||||
Password: req.Password,
|
||||
}
|
||||
|
||||
switch v := req.Auth.(type) {
|
||||
case *admin_pb.UpdateEmailProviderSMTPRequest_None:
|
||||
// Nothing to do, no auth is required
|
||||
case *admin_pb.UpdateEmailProviderSMTPRequest_Plain:
|
||||
cmd.PlainAuth = &command.PlainAuth{
|
||||
Password: v.Plain.Password,
|
||||
}
|
||||
case *admin_pb.UpdateEmailProviderSMTPRequest_Xoauth2:
|
||||
cmd.XOAuth2Auth = xoauth2ToCmd(v)
|
||||
default:
|
||||
// ensure backwards compatibility
|
||||
if req.User != "" || req.Password != "" {
|
||||
cmd.PlainAuth = &command.PlainAuth{
|
||||
Password: req.Password,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func xoauth2ToCmd(xoauth2 *admin_pb.UpdateEmailProviderSMTPRequest_Xoauth2) *command.XOAuth2Auth {
|
||||
cmd := &command.XOAuth2Auth{
|
||||
TokenEndpoint: xoauth2.Xoauth2.TokenEndpoint,
|
||||
Scopes: xoauth2.Xoauth2.Scopes,
|
||||
}
|
||||
if v, ok := xoauth2.Xoauth2.OAuth2Type.(*admin_pb.SMTPXOAuth2Auth_ClientCredentials_); ok {
|
||||
cmd.ClientCredentialsAuth = &command.OAuth2ClientCredentials{
|
||||
ClientId: v.ClientCredentials.ClientId,
|
||||
ClientSecret: v.ClientCredentials.ClientSecret,
|
||||
}
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
func addEmailProviderHTTPToConfig(ctx context.Context, req *admin_pb.AddEmailProviderHTTPRequest) *command.AddSMTPConfigHTTP {
|
||||
@@ -137,14 +223,49 @@ func updateEmailProviderHTTPToConfig(ctx context.Context, req *admin_pb.UpdateEm
|
||||
}
|
||||
|
||||
func testEmailProviderSMTPToConfig(req *admin_pb.TestEmailProviderSMTPRequest) *smtp.Config {
|
||||
return &smtp.Config{
|
||||
cfg := &smtp.Config{
|
||||
Tls: req.Tls,
|
||||
From: req.SenderAddress,
|
||||
FromName: req.SenderName,
|
||||
SMTP: smtp.SMTP{
|
||||
Host: req.Host,
|
||||
User: req.User,
|
||||
Password: req.Password,
|
||||
Host: req.Host,
|
||||
},
|
||||
}
|
||||
|
||||
switch v := req.Auth.(type) {
|
||||
case *admin_pb.TestEmailProviderSMTPRequest_None:
|
||||
// Nothing to do, no auth is required
|
||||
case *admin_pb.TestEmailProviderSMTPRequest_Plain:
|
||||
cfg.SMTP.PlainAuth = &smtp.PlainAuthConfig{
|
||||
User: req.User,
|
||||
Password: v.Plain.Password,
|
||||
}
|
||||
case *admin_pb.TestEmailProviderSMTPRequest_Xoauth2:
|
||||
cfg.SMTP.XOAuth2Auth = xoauth2ToSmtp(v, req.User)
|
||||
default:
|
||||
// ensure backwards compatibility
|
||||
if req.User != "" || req.Password != "" {
|
||||
cfg.SMTP.PlainAuth = &smtp.PlainAuthConfig{
|
||||
User: req.User,
|
||||
Password: req.Password,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
func xoauth2ToSmtp(xoauth2 *admin_pb.TestEmailProviderSMTPRequest_Xoauth2, user string) *smtp.XOAuth2AuthConfig {
|
||||
cfg := &smtp.XOAuth2AuthConfig{
|
||||
User: user,
|
||||
TokenEndpoint: xoauth2.Xoauth2.TokenEndpoint,
|
||||
Scopes: xoauth2.Xoauth2.Scopes,
|
||||
}
|
||||
if v, ok := xoauth2.Xoauth2.OAuth2Type.(*admin_pb.SMTPXOAuth2Auth_ClientCredentials_); ok {
|
||||
cfg.ClientCredentialsAuth = &smtp.OAuth2ClientCredentials{
|
||||
ClientId: v.ClientCredentials.ClientId,
|
||||
ClientSecret: v.ClientCredentials.ClientSecret,
|
||||
}
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
"github.com/zitadel/zitadel/internal/command"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
admin_pb "github.com/zitadel/zitadel/pkg/grpc/admin"
|
||||
object_pb "github.com/zitadel/zitadel/pkg/grpc/object"
|
||||
@@ -85,6 +86,7 @@ func Test_emailProvidersToPb(t *testing.T) {
|
||||
ReplyToAddress: "address",
|
||||
Host: "host",
|
||||
User: "user",
|
||||
PlainAuth: &query.PlainAuth{},
|
||||
},
|
||||
HTTPConfig: nil,
|
||||
State: 1,
|
||||
@@ -125,6 +127,9 @@ func Test_emailProvidersToPb(t *testing.T) {
|
||||
Host: "host",
|
||||
User: "user",
|
||||
ReplyToAddress: "address",
|
||||
Auth: &settings_pb.EmailProviderSMTP_Plain{
|
||||
Plain: &settings_pb.SMTPPlainAuth{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -184,6 +189,7 @@ func Test_emailProviderToProviderPb(t *testing.T) {
|
||||
ReplyToAddress: "address",
|
||||
Host: "host",
|
||||
User: "user",
|
||||
PlainAuth: &query.PlainAuth{},
|
||||
},
|
||||
HTTPConfig: &query.HTTP{
|
||||
Endpoint: "endpoint",
|
||||
@@ -210,6 +216,9 @@ func Test_emailProviderToProviderPb(t *testing.T) {
|
||||
Host: "host",
|
||||
User: "user",
|
||||
ReplyToAddress: "address",
|
||||
Auth: &settings_pb.EmailProviderSMTP_Plain{
|
||||
Plain: &settings_pb.SMTPPlainAuth{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -254,7 +263,7 @@ func Test_emailProviderToProviderPb(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := emailProviderToProviderPb(tt.args.req)
|
||||
assert.Equal(t, tt.res, got)
|
||||
assert.EqualValues(t, tt.res, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -363,6 +372,7 @@ func Test_smtpToPb(t *testing.T) {
|
||||
TLS: true,
|
||||
Host: "host",
|
||||
User: "user",
|
||||
PlainAuth: &query.PlainAuth{},
|
||||
ReplyToAddress: "address",
|
||||
},
|
||||
},
|
||||
@@ -374,6 +384,74 @@ func Test_smtpToPb(t *testing.T) {
|
||||
Host: "host",
|
||||
User: "user",
|
||||
ReplyToAddress: "address",
|
||||
Auth: &settings_pb.EmailProviderSMTP_Plain{
|
||||
Plain: &settings_pb.SMTPPlainAuth{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "legacy auth must still be supported",
|
||||
args: args{
|
||||
req: &query.SMTP{
|
||||
User: "user",
|
||||
PlainAuth: &query.PlainAuth{},
|
||||
},
|
||||
},
|
||||
res: &settings_pb.EmailProvider_Smtp{
|
||||
Smtp: &settings_pb.EmailProviderSMTP{
|
||||
User: "user",
|
||||
Auth: &settings_pb.EmailProviderSMTP_Plain{
|
||||
Plain: &settings_pb.SMTPPlainAuth{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "plain auth must map to plain",
|
||||
args: args{
|
||||
req: &query.SMTP{
|
||||
User: "plain-user",
|
||||
PlainAuth: &query.PlainAuth{},
|
||||
},
|
||||
},
|
||||
res: &settings_pb.EmailProvider_Smtp{
|
||||
Smtp: &settings_pb.EmailProviderSMTP{
|
||||
User: "plain-user",
|
||||
Auth: &settings_pb.EmailProviderSMTP_Plain{
|
||||
Plain: &settings_pb.SMTPPlainAuth{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "xoauth2 auth must map to xoauth2",
|
||||
args: args{
|
||||
req: &query.SMTP{
|
||||
User: "xoauth2-user",
|
||||
XOAuth2Auth: &query.XOAuth2Auth{
|
||||
TokenEndpoint: "auth.example.com/token",
|
||||
Scopes: []string{"scopes"},
|
||||
ClientCredentials: &query.XOAuthClientCredentials{
|
||||
ClientId: "my-client",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
res: &settings_pb.EmailProvider_Smtp{
|
||||
Smtp: &settings_pb.EmailProviderSMTP{
|
||||
User: "xoauth2-user",
|
||||
Auth: &settings_pb.EmailProviderSMTP_Xoauth2{
|
||||
Xoauth2: &settings_pb.SMTPXOAuth2Auth{
|
||||
TokenEndpoint: "auth.example.com/token",
|
||||
Scopes: []string{"scopes"},
|
||||
OAuth2Type: &settings_pb.SMTPXOAuth2Auth_ClientCredentials_{
|
||||
ClientCredentials: &settings_pb.SMTPXOAuth2Auth_ClientCredentials{
|
||||
ClientId: "my-client",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -412,17 +490,90 @@ func Test_addEmailProviderSMTPToConfig(t *testing.T) {
|
||||
},
|
||||
},
|
||||
res: &command.AddSMTPConfig{
|
||||
ResourceOwner: "instance",
|
||||
Description: "description",
|
||||
Host: "host",
|
||||
User: "user",
|
||||
Password: "password",
|
||||
ResourceOwner: "instance",
|
||||
Description: "description",
|
||||
Host: "host",
|
||||
User: "user",
|
||||
PlainAuth: &command.PlainAuth{
|
||||
Password: "password",
|
||||
},
|
||||
Tls: true,
|
||||
From: "sender",
|
||||
FromName: "sendername",
|
||||
ReplyToAddress: "address",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "legacy auth (username password) should map to plain",
|
||||
args: args{
|
||||
ctx: authz.WithInstanceID(context.Background(), "instance"),
|
||||
req: &admin_pb.AddEmailProviderSMTPRequest{
|
||||
User: "user",
|
||||
Password: "password",
|
||||
},
|
||||
},
|
||||
res: &command.AddSMTPConfig{
|
||||
ResourceOwner: "instance",
|
||||
User: "user",
|
||||
PlainAuth: &command.PlainAuth{
|
||||
Password: "password",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "plain auth should map to plain",
|
||||
args: args{
|
||||
ctx: authz.WithInstanceID(context.Background(), "instance"),
|
||||
req: &admin_pb.AddEmailProviderSMTPRequest{
|
||||
User: "plain-user",
|
||||
Auth: &admin_pb.AddEmailProviderSMTPRequest_Plain{
|
||||
Plain: &admin_pb.SMTPPlainAuth{
|
||||
Password: "other_password",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
res: &command.AddSMTPConfig{
|
||||
ResourceOwner: "instance",
|
||||
User: "plain-user",
|
||||
PlainAuth: &command.PlainAuth{
|
||||
Password: "other_password",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "xoauth2 auth should map to xoauth2",
|
||||
args: args{
|
||||
ctx: authz.WithInstanceID(context.Background(), "instance"),
|
||||
req: &admin_pb.AddEmailProviderSMTPRequest{
|
||||
User: "xoauth2-user",
|
||||
Auth: &admin_pb.AddEmailProviderSMTPRequest_Xoauth2{
|
||||
Xoauth2: &admin_pb.SMTPXOAuth2Auth{
|
||||
TokenEndpoint: "auth.example.com/token",
|
||||
Scopes: []string{"scopes"},
|
||||
OAuth2Type: &admin_pb.SMTPXOAuth2Auth_ClientCredentials_{
|
||||
ClientCredentials: &admin_pb.SMTPXOAuth2Auth_ClientCredentials{
|
||||
ClientId: "my-client",
|
||||
ClientSecret: "some-secret",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
res: &command.AddSMTPConfig{
|
||||
ResourceOwner: "instance",
|
||||
User: "xoauth2-user",
|
||||
XOAuth2Auth: &command.XOAuth2Auth{
|
||||
TokenEndpoint: "auth.example.com/token",
|
||||
Scopes: []string{"scopes"},
|
||||
ClientCredentialsAuth: &command.OAuth2ClientCredentials{
|
||||
ClientId: "my-client",
|
||||
ClientSecret: "some-secret",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
@@ -459,18 +610,97 @@ func Test_updateEmailProviderSMTPToConfig(t *testing.T) {
|
||||
},
|
||||
},
|
||||
res: &command.ChangeSMTPConfig{
|
||||
ResourceOwner: "instance",
|
||||
ID: "id",
|
||||
Description: "description",
|
||||
Host: "host",
|
||||
User: "user",
|
||||
Password: "password",
|
||||
ResourceOwner: "instance",
|
||||
ID: "id",
|
||||
Description: "description",
|
||||
Host: "host",
|
||||
User: "user",
|
||||
PlainAuth: &command.PlainAuth{
|
||||
Password: "password",
|
||||
},
|
||||
Tls: true,
|
||||
From: "sender",
|
||||
FromName: "sendername",
|
||||
ReplyToAddress: "address",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "legacy auth (username password) should map to plain",
|
||||
args: args{
|
||||
ctx: authz.WithInstanceID(context.Background(), "instance"),
|
||||
req: &admin_pb.UpdateEmailProviderSMTPRequest{
|
||||
User: "user",
|
||||
Password: "password",
|
||||
Id: "id",
|
||||
},
|
||||
},
|
||||
res: &command.ChangeSMTPConfig{
|
||||
ResourceOwner: "instance",
|
||||
ID: "id",
|
||||
User: "user",
|
||||
PlainAuth: &command.PlainAuth{
|
||||
Password: "password",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "plain auth should map to plain",
|
||||
args: args{
|
||||
ctx: authz.WithInstanceID(context.Background(), "instance"),
|
||||
req: &admin_pb.UpdateEmailProviderSMTPRequest{
|
||||
Id: "id",
|
||||
User: "plain-user",
|
||||
Auth: &admin_pb.UpdateEmailProviderSMTPRequest_Plain{
|
||||
Plain: &admin_pb.SMTPPlainAuth{
|
||||
Password: "other_password",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
res: &command.ChangeSMTPConfig{
|
||||
ResourceOwner: "instance",
|
||||
ID: "id",
|
||||
User: "plain-user",
|
||||
PlainAuth: &command.PlainAuth{
|
||||
Password: "other_password",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "xoauth2 auth should map to xoauth2",
|
||||
args: args{
|
||||
ctx: authz.WithInstanceID(context.Background(), "instance"),
|
||||
req: &admin_pb.UpdateEmailProviderSMTPRequest{
|
||||
Id: "id",
|
||||
User: "xoauth2-user",
|
||||
Auth: &admin_pb.UpdateEmailProviderSMTPRequest_Xoauth2{
|
||||
Xoauth2: &admin_pb.SMTPXOAuth2Auth{
|
||||
TokenEndpoint: "auth.example.com/token",
|
||||
Scopes: []string{"scopes"},
|
||||
OAuth2Type: &admin_pb.SMTPXOAuth2Auth_ClientCredentials_{
|
||||
ClientCredentials: &admin_pb.SMTPXOAuth2Auth_ClientCredentials{
|
||||
ClientId: "my-client",
|
||||
ClientSecret: "some-secret",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
res: &command.ChangeSMTPConfig{
|
||||
ResourceOwner: "instance",
|
||||
ID: "id",
|
||||
User: "xoauth2-user",
|
||||
XOAuth2Auth: &command.XOAuth2Auth{
|
||||
TokenEndpoint: "auth.example.com/token",
|
||||
Scopes: []string{"scopes"},
|
||||
ClientCredentialsAuth: &command.OAuth2ClientCredentials{
|
||||
ClientId: "my-client",
|
||||
ClientSecret: "some-secret",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
@@ -552,3 +782,122 @@ func Test_updateEmailProviderHTTPToConfig(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_testEmailProviderSMTPToConfig(t *testing.T) {
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
req *admin_pb.TestEmailProviderSMTPRequest
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res *smtp.Config
|
||||
}{
|
||||
{
|
||||
name: "all fields filled",
|
||||
args: args{
|
||||
ctx: authz.WithInstanceID(context.Background(), "instance"),
|
||||
req: &admin_pb.TestEmailProviderSMTPRequest{
|
||||
SenderAddress: "sender",
|
||||
SenderName: "sendername",
|
||||
Tls: true,
|
||||
Host: "host",
|
||||
User: "user",
|
||||
Password: "password",
|
||||
},
|
||||
},
|
||||
res: &smtp.Config{
|
||||
Tls: true,
|
||||
From: "sender",
|
||||
FromName: "sendername",
|
||||
SMTP: smtp.SMTP{
|
||||
Host: "host",
|
||||
PlainAuth: &smtp.PlainAuthConfig{
|
||||
User: "user",
|
||||
Password: "password",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "legacy auth (username password) should map to plain",
|
||||
args: args{
|
||||
ctx: authz.WithInstanceID(context.Background(), "instance"),
|
||||
req: &admin_pb.TestEmailProviderSMTPRequest{
|
||||
User: "user",
|
||||
Password: "password",
|
||||
},
|
||||
},
|
||||
res: &smtp.Config{
|
||||
SMTP: smtp.SMTP{
|
||||
PlainAuth: &smtp.PlainAuthConfig{
|
||||
User: "user",
|
||||
Password: "password",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "plain auth should map to plain",
|
||||
args: args{
|
||||
ctx: authz.WithInstanceID(context.Background(), "instance"),
|
||||
req: &admin_pb.TestEmailProviderSMTPRequest{
|
||||
User: "plain-user",
|
||||
Auth: &admin_pb.TestEmailProviderSMTPRequest_Plain{
|
||||
Plain: &admin_pb.SMTPPlainAuth{
|
||||
Password: "other_password",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
res: &smtp.Config{
|
||||
SMTP: smtp.SMTP{
|
||||
PlainAuth: &smtp.PlainAuthConfig{
|
||||
User: "plain-user",
|
||||
Password: "other_password",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "xoauth2 auth should map to xoauth2",
|
||||
args: args{
|
||||
ctx: authz.WithInstanceID(context.Background(), "instance"),
|
||||
req: &admin_pb.TestEmailProviderSMTPRequest{
|
||||
User: "xoauth2-user",
|
||||
Auth: &admin_pb.TestEmailProviderSMTPRequest_Xoauth2{
|
||||
Xoauth2: &admin_pb.SMTPXOAuth2Auth{
|
||||
TokenEndpoint: "auth.example.com/token",
|
||||
Scopes: []string{"scopes"},
|
||||
OAuth2Type: &admin_pb.SMTPXOAuth2Auth_ClientCredentials_{
|
||||
ClientCredentials: &admin_pb.SMTPXOAuth2Auth_ClientCredentials{
|
||||
ClientId: "my-client",
|
||||
ClientSecret: "some-secret",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
res: &smtp.Config{
|
||||
SMTP: smtp.SMTP{
|
||||
XOAuth2Auth: &smtp.XOAuth2AuthConfig{
|
||||
User: "xoauth2-user",
|
||||
TokenEndpoint: "auth.example.com/token",
|
||||
Scopes: []string{"scopes"},
|
||||
ClientCredentialsAuth: &smtp.OAuth2ClientCredentials{
|
||||
ClientId: "my-client",
|
||||
ClientSecret: "some-secret",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := testEmailProviderSMTPToConfig(tt.args.req)
|
||||
assert.Equal(t, tt.res, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,8 +133,9 @@ func SecretGeneratorTypeToDomain(generatorType settings_pb.SecretGeneratorType)
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated: use [addEmailProviderSMTPToConfig] instead
|
||||
func addSMTPToConfig(ctx context.Context, req *admin_pb.AddSMTPConfigRequest) *command.AddSMTPConfig {
|
||||
return &command.AddSMTPConfig{
|
||||
cmd := &command.AddSMTPConfig{
|
||||
ResourceOwner: authz.GetInstance(ctx).InstanceID(),
|
||||
Description: req.Description,
|
||||
Tls: req.Tls,
|
||||
@@ -143,12 +144,20 @@ func addSMTPToConfig(ctx context.Context, req *admin_pb.AddSMTPConfigRequest) *c
|
||||
ReplyToAddress: req.ReplyToAddress,
|
||||
Host: req.Host,
|
||||
User: req.User,
|
||||
Password: req.Password,
|
||||
}
|
||||
|
||||
if req.User != "" || req.Password != "" {
|
||||
cmd.PlainAuth = &command.PlainAuth{
|
||||
Password: req.Password,
|
||||
}
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// Deprecated: use [updateEmailProviderSMTPToConfig] instead
|
||||
func updateSMTPToConfig(ctx context.Context, req *admin_pb.UpdateSMTPConfigRequest) *command.ChangeSMTPConfig {
|
||||
return &command.ChangeSMTPConfig{
|
||||
cmd := &command.ChangeSMTPConfig{
|
||||
ResourceOwner: authz.GetInstance(ctx).InstanceID(),
|
||||
ID: req.Id,
|
||||
Description: req.Description,
|
||||
@@ -158,26 +167,35 @@ func updateSMTPToConfig(ctx context.Context, req *admin_pb.UpdateSMTPConfigReque
|
||||
ReplyToAddress: req.ReplyToAddress,
|
||||
Host: req.Host,
|
||||
User: req.User,
|
||||
Password: req.Password,
|
||||
}
|
||||
}
|
||||
|
||||
func SMTPConfigToPb(smtp *query.SMTPConfig) *settings_pb.SMTPConfig {
|
||||
if smtp.SMTPConfig != nil {
|
||||
return &settings_pb.SMTPConfig{
|
||||
Description: smtp.Description,
|
||||
Tls: smtp.SMTPConfig.TLS,
|
||||
SenderAddress: smtp.SMTPConfig.SenderAddress,
|
||||
SenderName: smtp.SMTPConfig.SenderName,
|
||||
ReplyToAddress: smtp.SMTPConfig.ReplyToAddress,
|
||||
Host: smtp.SMTPConfig.Host,
|
||||
User: smtp.SMTPConfig.User,
|
||||
Details: obj_grpc.ToViewDetailsPb(smtp.Sequence, smtp.CreationDate, smtp.ChangeDate, smtp.ResourceOwner),
|
||||
Id: smtp.ID,
|
||||
State: settings_pb.SMTPConfigState(smtp.State),
|
||||
if req.User != "" || req.Password != "" {
|
||||
cmd.PlainAuth = &command.PlainAuth{
|
||||
Password: req.Password,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// Deprecated: use [smtpToPb] instead.
|
||||
func SMTPConfigToPb(smtp *query.SMTPConfig) *settings_pb.SMTPConfig {
|
||||
if smtp.SMTPConfig == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &settings_pb.SMTPConfig{
|
||||
Description: smtp.Description,
|
||||
Tls: smtp.SMTPConfig.TLS,
|
||||
SenderAddress: smtp.SMTPConfig.SenderAddress,
|
||||
SenderName: smtp.SMTPConfig.SenderName,
|
||||
ReplyToAddress: smtp.SMTPConfig.ReplyToAddress,
|
||||
Host: smtp.SMTPConfig.Host,
|
||||
Details: obj_grpc.ToViewDetailsPb(smtp.Sequence, smtp.CreationDate, smtp.ChangeDate, smtp.ResourceOwner),
|
||||
Id: smtp.ID,
|
||||
State: settings_pb.SMTPConfigState(smtp.State),
|
||||
User: smtp.SMTPConfig.User,
|
||||
}
|
||||
}
|
||||
|
||||
func SecurityPolicyToPb(policy *query.SecurityPolicy) *settings_pb.SecurityPolicy {
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
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 {
|
||||
@@ -19,6 +20,7 @@ func (s *Server) GetSMTPConfig(ctx context.Context, req *admin_pb.GetSMTPConfigR
|
||||
}, 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 {
|
||||
@@ -29,6 +31,7 @@ func (s *Server) GetSMTPConfigById(ctx context.Context, req *admin_pb.GetSMTPCon
|
||||
}, 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 {
|
||||
@@ -40,6 +43,7 @@ func (s *Server) AddSMTPConfig(ctx context.Context, req *admin_pb.AddSMTPConfigR
|
||||
}, 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 {
|
||||
@@ -50,6 +54,7 @@ func (s *Server) UpdateSMTPConfig(ctx context.Context, req *admin_pb.UpdateSMTPC
|
||||
}, 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 {
|
||||
@@ -60,6 +65,7 @@ func (s *Server) RemoveSMTPConfig(ctx context.Context, req *admin_pb.RemoveSMTPC
|
||||
}, 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 {
|
||||
@@ -70,6 +76,7 @@ func (s *Server) UpdateSMTPConfigPassword(ctx context.Context, req *admin_pb.Upd
|
||||
}, 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 {
|
||||
@@ -85,6 +92,7 @@ func (s *Server) ListSMTPConfigs(ctx context.Context, req *admin_pb.ListSMTPConf
|
||||
}, 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 {
|
||||
@@ -96,6 +104,7 @@ func (s *Server) ActivateSMTPConfig(ctx context.Context, req *admin_pb.ActivateS
|
||||
}, 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 {
|
||||
@@ -107,6 +116,7 @@ func (s *Server) DeactivateSMTPConfig(ctx context.Context, req *admin_pb.Deactiv
|
||||
}, 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 {
|
||||
@@ -116,14 +126,20 @@ func (s *Server) TestSMTPConfigById(ctx context.Context, req *admin_pb.TestSMTPC
|
||||
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{}
|
||||
config.Tls = req.Tls
|
||||
config.From = req.SenderAddress
|
||||
config.FromName = req.SenderName
|
||||
config.SMTP.Host = req.Host
|
||||
config.SMTP.User = req.User
|
||||
config.SMTP.Password = req.Password
|
||||
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 {
|
||||
|
||||
@@ -165,7 +165,7 @@ func TestListInstances(t *testing.T) {
|
||||
|
||||
orgOwnerCtx := inst.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner)
|
||||
|
||||
relTableState := integration.RelationalTablesEnableMatrix()
|
||||
relTableState := integration.RelationalTablesEnableMatrix(t, ctx, ctxWithSysAuthZ)
|
||||
|
||||
tt := []struct {
|
||||
testName string
|
||||
@@ -222,16 +222,13 @@ func TestListInstances(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, stateCase := range relTableState {
|
||||
integration.EnsureInstanceFeature(t, ctx, inst, stateCase.FeatureSet, func(tCollect *assert.CollectT, got *feature.GetInstanceFeaturesResponse) {
|
||||
assert.Equal(tCollect, stateCase.FeatureSet.GetEnableRelationalTables(), got.EnableRelationalTables.GetEnabled())
|
||||
})
|
||||
|
||||
for _, tc := range tt {
|
||||
// TODO(IAM-Marco): Fix this test for relational case when permission checks are in place (see https://github.com/zitadel/zitadel/issues/10917)
|
||||
if tc.testName == "when unauthZ context should return unauthZ error" && stateCase.State == "when relational tables are enabled" {
|
||||
if tc.testName == "when unauthZ context should return unauthZ error" && stateCase.Name == "when relational tables are enabled" {
|
||||
continue
|
||||
}
|
||||
t.Run(fmt.Sprintf("%s - %s", stateCase.State, tc.testName), func(t *testing.T) {
|
||||
t.Run(fmt.Sprintf("%s - %s", stateCase.Name, tc.testName), func(t *testing.T) {
|
||||
// Test
|
||||
res, err := inst.Client.InstanceV2.ListInstances(tc.inputContext, tc.inputRequest)
|
||||
|
||||
@@ -251,7 +248,6 @@ func TestListInstances(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestListCustomDomains(t *testing.T) {
|
||||
|
||||
@@ -34,9 +34,12 @@ func TestAddCustomDomain(t *testing.T) {
|
||||
|
||||
relationalInst := integration.NewInstance(ctxWithSysAuthZ)
|
||||
iamOwnerRelationalCtx := relationalInst.WithAuthorizationToken(context.Background(), integration.UserTypeIAMOwner)
|
||||
integration.EnsureInstanceFeature(t, ctxWithSysAuthZ, relationalInst, &feature.SetInstanceFeaturesRequest{EnableRelationalTables: gu.Ptr(true)}, func(tCollect *assert.CollectT, got *feature.GetInstanceFeaturesResponse) {
|
||||
assert.True(tCollect, got.EnableRelationalTables.GetEnabled())
|
||||
})
|
||||
integration.EnsureInstanceFeature(t, ctxWithSysAuthZ, relationalInst,
|
||||
&feature.SetInstanceFeaturesRequest{EnableRelationalTables: gu.Ptr(true)},
|
||||
func(tCollect *assert.CollectT, got *feature.GetInstanceFeaturesResponse) {
|
||||
assert.True(tCollect, got.EnableRelationalTables.GetEnabled())
|
||||
},
|
||||
)
|
||||
|
||||
t.Cleanup(func() {
|
||||
inst.Client.InstanceV2Beta.DeleteInstance(ctxWithSysAuthZ, &instance.DeleteInstanceRequest{InstanceId: inst.ID()})
|
||||
|
||||
@@ -140,7 +140,7 @@ func TestListInstances(t *testing.T) {
|
||||
|
||||
orgOwnerCtx := inst.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner)
|
||||
|
||||
relTableState := integration.RelationalTablesEnableMatrix()
|
||||
relTableState := integration.RelationalTablesEnableMatrix(t, ctx, ctxWithSysAuthZ)
|
||||
|
||||
tt := []struct {
|
||||
testName string
|
||||
@@ -196,12 +196,8 @@ func TestListInstances(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, stateCase := range relTableState {
|
||||
integration.EnsureInstanceFeature(t, ctx, inst, stateCase.FeatureSet, func(tCollect *assert.CollectT, got *feature.GetInstanceFeaturesResponse) {
|
||||
assert.Equal(tCollect, stateCase.FeatureSet.GetEnableRelationalTables(), got.EnableRelationalTables.GetEnabled())
|
||||
})
|
||||
|
||||
for _, tc := range tt {
|
||||
t.Run(fmt.Sprintf("%s - %s", stateCase.State, tc.testName), func(t *testing.T) {
|
||||
t.Run(fmt.Sprintf("%s - %s", stateCase.Name, tc.testName), func(t *testing.T) {
|
||||
// Test
|
||||
res, err := inst.Client.InstanceV2Beta.ListInstances(tc.inputContext, tc.inputRequest)
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user