Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. // Copyright 2023 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package cmd
  4. import (
  5. "errors"
  6. "fmt"
  7. "strings"
  8. auth_model "code.gitea.io/gitea/models/auth"
  9. "code.gitea.io/gitea/modules/util"
  10. "code.gitea.io/gitea/services/auth/source/smtp"
  11. "github.com/urfave/cli/v2"
  12. )
  13. var (
  14. smtpCLIFlags = []cli.Flag{
  15. &cli.StringFlag{
  16. Name: "name",
  17. Value: "",
  18. Usage: "Application Name",
  19. },
  20. &cli.StringFlag{
  21. Name: "auth-type",
  22. Value: "PLAIN",
  23. Usage: "SMTP Authentication Type (PLAIN/LOGIN/CRAM-MD5) default PLAIN",
  24. },
  25. &cli.StringFlag{
  26. Name: "host",
  27. Value: "",
  28. Usage: "SMTP Host",
  29. },
  30. &cli.IntFlag{
  31. Name: "port",
  32. Usage: "SMTP Port",
  33. },
  34. &cli.BoolFlag{
  35. Name: "force-smtps",
  36. Usage: "SMTPS is always used on port 465. Set this to force SMTPS on other ports.",
  37. Value: true,
  38. },
  39. &cli.BoolFlag{
  40. Name: "skip-verify",
  41. Usage: "Skip TLS verify.",
  42. Value: true,
  43. },
  44. &cli.StringFlag{
  45. Name: "helo-hostname",
  46. Value: "",
  47. Usage: "Hostname sent with HELO. Leave blank to send current hostname",
  48. },
  49. &cli.BoolFlag{
  50. Name: "disable-helo",
  51. Usage: "Disable SMTP helo.",
  52. Value: true,
  53. },
  54. &cli.StringFlag{
  55. Name: "allowed-domains",
  56. Value: "",
  57. Usage: "Leave empty to allow all domains. Separate multiple domains with a comma (',')",
  58. },
  59. &cli.BoolFlag{
  60. Name: "skip-local-2fa",
  61. Usage: "Skip 2FA to log on.",
  62. Value: true,
  63. },
  64. &cli.BoolFlag{
  65. Name: "active",
  66. Usage: "This Authentication Source is Activated.",
  67. Value: true,
  68. },
  69. }
  70. microcmdAuthAddSMTP = &cli.Command{
  71. Name: "add-smtp",
  72. Usage: "Add new SMTP authentication source",
  73. Action: runAddSMTP,
  74. Flags: smtpCLIFlags,
  75. }
  76. microcmdAuthUpdateSMTP = &cli.Command{
  77. Name: "update-smtp",
  78. Usage: "Update existing SMTP authentication source",
  79. Action: runUpdateSMTP,
  80. Flags: append(smtpCLIFlags[:1], append([]cli.Flag{idFlag}, smtpCLIFlags[1:]...)...),
  81. }
  82. )
  83. func parseSMTPConfig(c *cli.Context, conf *smtp.Source) error {
  84. if c.IsSet("auth-type") {
  85. conf.Auth = c.String("auth-type")
  86. validAuthTypes := []string{"PLAIN", "LOGIN", "CRAM-MD5"}
  87. if !util.SliceContainsString(validAuthTypes, strings.ToUpper(c.String("auth-type"))) {
  88. return errors.New("Auth must be one of PLAIN/LOGIN/CRAM-MD5")
  89. }
  90. conf.Auth = c.String("auth-type")
  91. }
  92. if c.IsSet("host") {
  93. conf.Host = c.String("host")
  94. }
  95. if c.IsSet("port") {
  96. conf.Port = c.Int("port")
  97. }
  98. if c.IsSet("allowed-domains") {
  99. conf.AllowedDomains = c.String("allowed-domains")
  100. }
  101. if c.IsSet("force-smtps") {
  102. conf.ForceSMTPS = c.Bool("force-smtps")
  103. }
  104. if c.IsSet("skip-verify") {
  105. conf.SkipVerify = c.Bool("skip-verify")
  106. }
  107. if c.IsSet("helo-hostname") {
  108. conf.HeloHostname = c.String("helo-hostname")
  109. }
  110. if c.IsSet("disable-helo") {
  111. conf.DisableHelo = c.Bool("disable-helo")
  112. }
  113. if c.IsSet("skip-local-2fa") {
  114. conf.SkipLocalTwoFA = c.Bool("skip-local-2fa")
  115. }
  116. return nil
  117. }
  118. func runAddSMTP(c *cli.Context) error {
  119. ctx, cancel := installSignals()
  120. defer cancel()
  121. if err := initDB(ctx); err != nil {
  122. return err
  123. }
  124. if !c.IsSet("name") || len(c.String("name")) == 0 {
  125. return errors.New("name must be set")
  126. }
  127. if !c.IsSet("host") || len(c.String("host")) == 0 {
  128. return errors.New("host must be set")
  129. }
  130. if !c.IsSet("port") {
  131. return errors.New("port must be set")
  132. }
  133. active := true
  134. if c.IsSet("active") {
  135. active = c.Bool("active")
  136. }
  137. var smtpConfig smtp.Source
  138. if err := parseSMTPConfig(c, &smtpConfig); err != nil {
  139. return err
  140. }
  141. // If not set default to PLAIN
  142. if len(smtpConfig.Auth) == 0 {
  143. smtpConfig.Auth = "PLAIN"
  144. }
  145. return auth_model.CreateSource(ctx, &auth_model.Source{
  146. Type: auth_model.SMTP,
  147. Name: c.String("name"),
  148. IsActive: active,
  149. Cfg: &smtpConfig,
  150. })
  151. }
  152. func runUpdateSMTP(c *cli.Context) error {
  153. if !c.IsSet("id") {
  154. return fmt.Errorf("--id flag is missing")
  155. }
  156. ctx, cancel := installSignals()
  157. defer cancel()
  158. if err := initDB(ctx); err != nil {
  159. return err
  160. }
  161. source, err := auth_model.GetSourceByID(ctx, c.Int64("id"))
  162. if err != nil {
  163. return err
  164. }
  165. smtpConfig := source.Cfg.(*smtp.Source)
  166. if err := parseSMTPConfig(c, smtpConfig); err != nil {
  167. return err
  168. }
  169. if c.IsSet("name") {
  170. source.Name = c.String("name")
  171. }
  172. if c.IsSet("active") {
  173. source.IsActive = c.Bool("active")
  174. }
  175. source.Cfg = smtpConfig
  176. return auth_model.UpdateSource(ctx, source)
  177. }