2023-09-27 15:25:38 +03:00
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package cmd
import (
"errors"
"fmt"
"strings"
auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/services/auth/source/smtp"
"github.com/urfave/cli/v2"
)
var (
smtpCLIFlags = [ ] cli . Flag {
& cli . StringFlag {
Name : "name" ,
Value : "" ,
Usage : "Application Name" ,
} ,
& cli . StringFlag {
Name : "auth-type" ,
Value : "PLAIN" ,
Usage : "SMTP Authentication Type (PLAIN/LOGIN/CRAM-MD5) default PLAIN" ,
} ,
& cli . StringFlag {
Name : "host" ,
Value : "" ,
Usage : "SMTP Host" ,
} ,
& cli . IntFlag {
Name : "port" ,
Usage : "SMTP Port" ,
} ,
& cli . BoolFlag {
Name : "force-smtps" ,
Usage : "SMTPS is always used on port 465. Set this to force SMTPS on other ports." ,
Value : true ,
} ,
& cli . BoolFlag {
Name : "skip-verify" ,
Usage : "Skip TLS verify." ,
Value : true ,
} ,
& cli . StringFlag {
Name : "helo-hostname" ,
Value : "" ,
Usage : "Hostname sent with HELO. Leave blank to send current hostname" ,
} ,
& cli . BoolFlag {
Name : "disable-helo" ,
Usage : "Disable SMTP helo." ,
Value : true ,
} ,
& cli . StringFlag {
Name : "allowed-domains" ,
Value : "" ,
Usage : "Leave empty to allow all domains. Separate multiple domains with a comma (',')" ,
} ,
& cli . BoolFlag {
Name : "skip-local-2fa" ,
Usage : "Skip 2FA to log on." ,
Value : true ,
} ,
& cli . BoolFlag {
Name : "active" ,
Usage : "This Authentication Source is Activated." ,
Value : true ,
} ,
}
microcmdAuthAddSMTP = & cli . Command {
Name : "add-smtp" ,
Usage : "Add new SMTP authentication source" ,
Action : runAddSMTP ,
Flags : smtpCLIFlags ,
}
microcmdAuthUpdateSMTP = & cli . Command {
Name : "update-smtp" ,
Usage : "Update existing SMTP authentication source" ,
Action : runUpdateSMTP ,
Flags : append ( smtpCLIFlags [ : 1 ] , append ( [ ] cli . Flag { idFlag } , smtpCLIFlags [ 1 : ] ... ) ... ) ,
}
)
func parseSMTPConfig ( c * cli . Context , conf * smtp . Source ) error {
if c . IsSet ( "auth-type" ) {
conf . Auth = c . String ( "auth-type" )
validAuthTypes := [ ] string { "PLAIN" , "LOGIN" , "CRAM-MD5" }
if ! util . SliceContainsString ( validAuthTypes , strings . ToUpper ( c . String ( "auth-type" ) ) ) {
return errors . New ( "Auth must be one of PLAIN/LOGIN/CRAM-MD5" )
}
conf . Auth = c . String ( "auth-type" )
}
if c . IsSet ( "host" ) {
conf . Host = c . String ( "host" )
}
if c . IsSet ( "port" ) {
conf . Port = c . Int ( "port" )
}
if c . IsSet ( "allowed-domains" ) {
conf . AllowedDomains = c . String ( "allowed-domains" )
}
if c . IsSet ( "force-smtps" ) {
conf . ForceSMTPS = c . Bool ( "force-smtps" )
}
if c . IsSet ( "skip-verify" ) {
conf . SkipVerify = c . Bool ( "skip-verify" )
}
if c . IsSet ( "helo-hostname" ) {
conf . HeloHostname = c . String ( "helo-hostname" )
}
if c . IsSet ( "disable-helo" ) {
conf . DisableHelo = c . Bool ( "disable-helo" )
}
if c . IsSet ( "skip-local-2fa" ) {
conf . SkipLocalTwoFA = c . Bool ( "skip-local-2fa" )
}
return nil
}
func runAddSMTP ( c * cli . Context ) error {
ctx , cancel := installSignals ( )
defer cancel ( )
if err := initDB ( ctx ) ; err != nil {
return err
}
if ! c . IsSet ( "name" ) || len ( c . String ( "name" ) ) == 0 {
return errors . New ( "name must be set" )
}
if ! c . IsSet ( "host" ) || len ( c . String ( "host" ) ) == 0 {
return errors . New ( "host must be set" )
}
if ! c . IsSet ( "port" ) {
return errors . New ( "port must be set" )
}
active := true
if c . IsSet ( "active" ) {
active = c . Bool ( "active" )
}
var smtpConfig smtp . Source
if err := parseSMTPConfig ( c , & smtpConfig ) ; err != nil {
return err
}
// If not set default to PLAIN
if len ( smtpConfig . Auth ) == 0 {
smtpConfig . Auth = "PLAIN"
}
2023-10-11 07:24:07 +03:00
return auth_model . CreateSource ( ctx , & auth_model . Source {
2023-09-27 15:25:38 +03:00
Type : auth_model . SMTP ,
Name : c . String ( "name" ) ,
IsActive : active ,
Cfg : & smtpConfig ,
} )
}
func runUpdateSMTP ( c * cli . Context ) error {
if ! c . IsSet ( "id" ) {
return fmt . Errorf ( "--id flag is missing" )
}
ctx , cancel := installSignals ( )
defer cancel ( )
if err := initDB ( ctx ) ; err != nil {
return err
}
2023-10-11 07:24:07 +03:00
source , err := auth_model . GetSourceByID ( ctx , c . Int64 ( "id" ) )
2023-09-27 15:25:38 +03:00
if err != nil {
return err
}
smtpConfig := source . Cfg . ( * smtp . Source )
if err := parseSMTPConfig ( c , smtpConfig ) ; err != nil {
return err
}
if c . IsSet ( "name" ) {
source . Name = c . String ( "name" )
}
if c . IsSet ( "active" ) {
source . IsActive = c . Bool ( "active" )
}
source . Cfg = smtpConfig
2023-10-11 07:24:07 +03:00
return auth_model . UpdateSource ( ctx , source )
2023-09-27 15:25:38 +03:00
}