Now you can configure the email system from the config.json and using .json instead of toml.

master
Zed A. Shaw 4 weeks ago
parent e376766315
commit 2600b60b8b
  1. 2
      .gitignore
  2. 2
      common/auth.go
  3. 43
      common/email/api.go
  4. 8
      common/email/data.go
  5. 36
      config/server.go
  6. 48
      config/settings.go
  7. 24
      config_example.json
  8. 8
      config_example.toml
  9. 1
      go.mod
  10. 2
      go.sum
  11. 10
      main.go
  12. 10
      tools/cmd/mailer/main.go
  13. 7
      tools/cmd/qmgr/main.go

2
.gitignore vendored

@ -27,7 +27,7 @@ coverage
coverage/*
.venv
*.gz
config.toml
config.json
public
*.idx
*.sqlite3

@ -15,7 +15,7 @@ import (
)
func IsAdmin(user *data.User) bool {
return user.Username == config.Settings.Admin
return user.Username == config.Settings.Server.Admin
}
func AuthCheck(c *fiber.Ctx, needs_admin bool) (*session.Session, error) {

@ -6,32 +6,33 @@ import (
"context"
"log"
"github.com/redis/go-redis/v9"
"MY/webapp/config"
)
func NewSender(ctx context.Context, config Config) (Sender){
func NewSender(ctx context.Context) (Sender){
client := redis.NewClient(&redis.Options{
Addr: config.RedisHostPort,
Password: config.RedisPassword,
DB: config.RedisDB,
Addr: config.Settings.Redis.HostPort,
Password: config.Settings.Redis.Password,
DB: config.Settings.Redis.DB,
})
return Sender{client, ctx}
}
func NewRouter(ctx context.Context, config Config) (Router, error) {
func NewRouter(ctx context.Context) (Router, error) {
var router Router
var err error
router.ctx = ctx
router.redis_client = redis.NewClient(&redis.Options{
Addr: config.RedisHostPort,
Password: config.RedisPassword,
DB: config.RedisDB,
Addr: config.Settings.Redis.HostPort,
Password: config.Settings.Redis.Password,
DB: config.Settings.Redis.DB,
})
router.smtp_client, err = mail.NewClient(config.SMTPHost,
mail.WithPort(config.SMTPPort),
router.smtp_client, err = mail.NewClient(config.Settings.Email.Host,
mail.WithPort(config.Settings.Email.Port),
mail.WithTLSPolicy(mail.NoTLS))
return router, err
@ -58,8 +59,13 @@ func (router *Router) DeliverEmail(msg EmailMessage) error {
email_msg.SetBodyString(mail.TypeTextPlain, msg.Text)
email_msg.SetBodyString(mail.TypeTextHTML, msg.HTML)
email_msg.SetGenHeader(mail.HeaderXMailer, "nunya-business")
email_msg.SetGenHeader(mail.HeaderUserAgent, "nunya-business")
if config.Settings.Email.XMailer != "" {
email_msg.SetGenHeader(mail.HeaderXMailer, config.Settings.Email.XMailer)
}
if config.Settings.Email.UserAgent != "" {
email_msg.SetGenHeader(mail.HeaderUserAgent, config.Settings.Email.UserAgent)
}
if err != nil { return err }
@ -72,7 +78,9 @@ func (router *Router) DeliverEmail(msg EmailMessage) error {
func (router *Router) ReceiveEmail() (EmailMessage, error) {
var msg EmailMessage
result, err := router.redis_client.BRPop(router.ctx, 0, "queue").Result()
result, err := router.redis_client.BRPop(
router.ctx, 0,
config.Settings.Email.RedisQueue).Result()
if err != nil { return msg, err }
// NOTE: 0=queue name, 1=message
@ -96,7 +104,10 @@ func (sender *Sender) QueueEmail(msg EmailMessage) error {
msg_json, err := json.Marshal(msg)
if err != nil { return err }
_, err = sender.redis_client.LPush(sender.ctx, "queue", string(msg_json)).Result()
_, err = sender.redis_client.LPush(
sender.ctx,
config.Settings.Email.RedisQueue,
string(msg_json)).Result()
if err != nil { return err }
return nil
@ -105,9 +116,7 @@ func (sender *Sender) QueueEmail(msg EmailMessage) error {
func OneShotSend(msg EmailMessage) {
ctx := context.Background()
sender := NewSender(ctx, Config{
RedisHostPort: "127.0.0.1:6379",
})
sender := NewSender(ctx)
defer sender.Close()
err := sender.QueueEmail(msg)

@ -6,14 +6,6 @@ import (
"context"
)
type Config struct {
RedisHostPort string
RedisPassword string
RedisDB int
SMTPHost string
SMTPPort int
}
type EmailMessage struct {
To string
From string

@ -1,36 +0,0 @@
package config
import (
"log"
"github.com/BurntSushi/toml"
)
type config struct {
Admin string `toml:"admin"`
Views string `toml:"views"`
Layouts string `toml:"layouts"`
Port string `toml:"port"`
Database struct {
Driver string `toml:"driver"`
Url string `toml:"url"`
} `toml:"database"`
}
var Settings config
func Load(path string) {
metadata, err := toml.DecodeFile(path, &Settings)
if err != nil {
log.Fatalf("error loading config.toml: %v", err)
}
bad_keys := metadata.Undecoded()
if len(bad_keys) > 0 {
log.Fatalf("unknown configuration keys: %v", bad_keys);
}
}

@ -0,0 +1,48 @@
package config
import (
"log"
"encoding/json"
"os"
)
type config struct {
Server struct {
Admin string
Views string
Layouts string
Port string
}
Database struct {
Driver string
Url string
}
Redis struct {
HostPort string
Password string
DB int
}
Email struct {
Host string
Port int
XMailer string
UserAgent string
RedisQueue string
}
}
var Settings config
func Load(path string) {
data, err := os.ReadFile(path)
if err != nil {
log.Fatalf("error loading %s: %v", path, err)
}
err = json.Unmarshal(data, &Settings)
if err != nil {
log.Fatal("error parsing %s: %v", path, err)
}
}

@ -0,0 +1,24 @@
{
"Server": {
"Admin": "admin",
"Views": "./views",
"Layouts": "layouts/main",
"Port": ":7001"
},
"Database": {
"Driver": "sqlite3",
"Url": "db.sqlite3"
},
"Redis": {
"HostPort": "localhost:6379",
"Password": "",
"DB": 0
},
"Email": {
"Host": "localhost",
"Port": 1025,
"XMailer": "nunya-business",
"UserAgent": "nunya-business",
"RedisQueue": "email"
}
}

@ -1,8 +0,0 @@
admin = "admin"
views = "./views"
layouts = "layouts/main"
port = ":7001"
[database]
driver = "sqlite3"
url = "db.sqlite3"

@ -3,7 +3,6 @@ module MY/webapp
go 1.25.3
require (
github.com/BurntSushi/toml v1.5.0
github.com/Masterminds/squirrel v1.5.4
github.com/chromedp/chromedp v0.14.2
github.com/go-playground/validator/v10 v10.28.0

@ -1,7 +1,5 @@
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM=
github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=

@ -23,17 +23,17 @@ import (
)
func main() {
config.Load("config.toml")
log.Printf("ADMIN is %s", config.Settings.Admin)
config.Load("config.json")
log.Printf("ADMIN is %s", config.Settings.Server.Admin)
log.SetFlags(log.LstdFlags | log.Lshortfile)
engine := html.New(config.Settings.Views, ".html")
engine := html.New(config.Settings.Server.Views, ".html")
engine.Reload(true)
app := fiber.New(fiber.Config{
Views: engine,
ViewsLayout: config.Settings.Layouts,
ViewsLayout: config.Settings.Server.Layouts,
CaseSensitive: true,
StrictRouting: true,
})
@ -55,7 +55,7 @@ func main() {
// this sets up graceful shutdown
go func() {
if err := app.Listen(config.Settings.Port); err != nil {
if err := app.Listen(config.Settings.Server.Port); err != nil {
log.Panic(err)
}
}()

@ -6,6 +6,7 @@ import (
"os"
"os/signal"
"syscall"
"MY/webapp/config"
email "MY/webapp/common/email"
)
@ -21,14 +22,11 @@ func EmailReceiver(router *email.Router) {
}
func main() {
ctx := context.Background()
config.Load("config.json")
router, err := email.NewRouter(ctx, email.Config{
RedisHostPort: "127.0.0.1:6379",
SMTPHost: "localhost",
SMTPPort: 1025,
})
ctx := context.Background()
router, err := email.NewRouter(ctx)
if err != nil { panic(err) }
defer router.Close()

@ -1,12 +1,15 @@
package main
import (
"MY/webapp/config"
email "MY/webapp/common/email"
"fmt"
"context"
)
func main() {
config.Load("config.json")
ctx := context.Background()
msg := email.EmailMessage{
@ -17,9 +20,7 @@ func main() {
HTML: fmt.Sprintf("<h1>Random number %v</h1>", 200),
}
sender := email.NewSender(ctx, email.Config{
RedisHostPort: "127.0.0.1:6379",
})
sender := email.NewSender(ctx)
defer sender.Close()
err := sender.QueueEmail(msg)

Loading…
Cancel
Save