auth.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package auth
  2. import (
  3. "crypto"
  4. "crypto/rand"
  5. "crypto/rsa"
  6. "crypto/x509"
  7. "encoding/base64"
  8. "encoding/pem"
  9. log "github.com/sirupsen/logrus"
  10. "os"
  11. "pmail/db"
  12. "pmail/dto"
  13. "pmail/models"
  14. "strings"
  15. )
  16. // HasAuth 检查当前用户是否有某个邮件的auth
  17. func HasAuth(ctx *dto.Context, email *models.Email) bool {
  18. // 获取当前用户的auth
  19. var auth []models.UserAuth
  20. err := db.Instance.Select(&auth, db.WithContext(ctx, "select * from user_auth where user_id = ?"), ctx.UserInfo.ID)
  21. if err != nil {
  22. log.WithContext(ctx).Errorf("SQL error:%+v", err)
  23. return false
  24. }
  25. var hasAuth bool
  26. for _, userAuth := range auth {
  27. if userAuth.EmailAccount == "*" {
  28. hasAuth = true
  29. break
  30. } else if strings.Contains(email.Bcc, ctx.UserInfo.Account) || strings.Contains(email.Cc, ctx.UserInfo.Account) || strings.Contains(email.To, ctx.UserInfo.Account) {
  31. hasAuth = true
  32. break
  33. }
  34. }
  35. return hasAuth
  36. }
  37. func DkimGen() string {
  38. privKeyStr, _ := os.ReadFile("./config/dkim/dkim.priv")
  39. publicKeyStr, _ := os.ReadFile("./config/dkim/dkim.public")
  40. if len(privKeyStr) > 0 && len(publicKeyStr) > 0 {
  41. return string(publicKeyStr)
  42. }
  43. var (
  44. privKey crypto.Signer
  45. err error
  46. )
  47. privKey, err = rsa.GenerateKey(rand.Reader, 1024)
  48. if err != nil {
  49. log.Fatalf("Failed to generate key: %v", err)
  50. }
  51. privBytes, err := x509.MarshalPKCS8PrivateKey(privKey)
  52. if err != nil {
  53. log.Fatalf("Failed to marshal private key: %v", err)
  54. }
  55. f, err := os.OpenFile("./config/dkim/dkim.priv", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
  56. if err != nil {
  57. log.Fatalf("Failed to create key file: %v", err)
  58. }
  59. defer f.Close()
  60. privBlock := pem.Block{
  61. Type: "PRIVATE KEY",
  62. Bytes: privBytes,
  63. }
  64. if err := pem.Encode(f, &privBlock); err != nil {
  65. log.Fatalf("Failed to write key PEM block: %v", err)
  66. }
  67. if err := f.Close(); err != nil {
  68. log.Fatalf("Failed to close key file: %v", err)
  69. }
  70. var pubBytes []byte
  71. switch pubKey := privKey.Public().(type) {
  72. case *rsa.PublicKey:
  73. // RFC 6376 is inconsistent about whether RSA public keys should
  74. // be formatted as RSAPublicKey or SubjectPublicKeyInfo.
  75. // Erratum 3017 (https://www.rfc-editor.org/errata/eid3017)
  76. // proposes allowing both. We use SubjectPublicKeyInfo for
  77. // consistency with other implementations including opendkim,
  78. // Gmail, and Fastmail.
  79. pubBytes, err = x509.MarshalPKIXPublicKey(pubKey)
  80. if err != nil {
  81. log.Fatalf("Failed to marshal public key: %v", err)
  82. }
  83. default:
  84. panic("unreachable")
  85. }
  86. params := []string{
  87. "v=DKIM1",
  88. "k=rsa",
  89. "p=" + base64.StdEncoding.EncodeToString(pubBytes),
  90. }
  91. publicKey := strings.Join(params, "; ")
  92. os.WriteFile("./config/dkim/dkim.public", []byte(publicKey), 0666)
  93. return publicKey
  94. }