mailcow-admin-aliases/internal/mailcow/aliases.go

122 lines
3.2 KiB
Go

package mailcow
import (
"bytes"
"encoding/json"
"fmt"
"io"
"log/slog"
"net/http"
"time"
"code.lila.network/adoralaura/mailcow-admin-aliases/internal/configuration"
)
type MailcowAlias struct {
ID int `json:"id"`
Domain string `json:"domain"`
PublicComment string `json:"public_comment"`
PrivateComment string `json:"private_comment"`
Goto string `json:"goto"`
Address string `json:"address"`
IsCatchAll int `json:"is_catch_all"`
Active int `json:"active"`
ActiveInt int `json:"active_int"`
SogoVisible int `json:"sogo_visible"`
SogoVisibleInt int `json:"sogo_visible_int"`
}
func NewAlias(alias string, destination string) MailcowAlias {
var a MailcowAlias
a.Active = 1
a.PublicComment = "automatically generated by the mail server admin"
a.PrivateComment = "automatically generated by the mail server admin"
a.Address = alias
a.Goto = destination
a.SogoVisible = 0
return a
}
func LoadAliases(cfg configuration.Config) ([]MailcowAlias, []string, error) {
var aliases []MailcowAlias
var aliasSlice []string
url := cfg.ApiEndpoint + configuration.AllAliasesApiEndpoint
method := "GET"
client := &http.Client{Timeout: 10 * time.Second}
req, err := http.NewRequest(method, url, nil)
slog.Debug("alias request", "method", method, "url", url)
if err != nil {
return []MailcowAlias{}, []string{}, fmt.Errorf("failed to create alias http request: %w", err)
}
req.Header.Add("accept", "application/json")
req.Header.Add("X-API-Key", cfg.ApiKey)
res, err := client.Do(req)
if err != nil {
return []MailcowAlias{}, []string{}, fmt.Errorf("failed to request aliases from server: %w", err)
}
defer res.Body.Close()
slog.Debug("alias response received", "status", res.Status, "status-code", res.StatusCode)
body, err := io.ReadAll(res.Body)
if err != nil {
return []MailcowAlias{}, []string{}, fmt.Errorf("failed to read alias request body: %w", err)
}
err = json.Unmarshal(body, &aliases)
if err != nil {
return []MailcowAlias{}, []string{}, fmt.Errorf("failed to unmarshal alias request body: %w", err)
}
for _, alias := range aliases {
aliasSlice = append(aliasSlice, alias.Address)
}
return aliases, aliasSlice, nil
}
func (a MailcowAlias) Create(cfg configuration.Config) error {
url := cfg.ApiEndpoint + configuration.AliasAddApiEndpoint
method := "POST"
payload, err := json.Marshal(a)
if err != nil {
return fmt.Errorf("failed to marshal api body: %w", err)
}
client := &http.Client{Timeout: 10 * time.Second}
req, err := http.NewRequest(method, url, bytes.NewReader(payload))
if err != nil {
return fmt.Errorf("failed to create new POST request: %w", err)
}
slog.Debug("alias create request", "method", method, "url", url)
req.Header.Add("accept", "application/json")
req.Header.Add("Content-Type", "application/json")
req.Header.Add("X-API-Key", cfg.ApiKey)
res, err := client.Do(req)
if err != nil {
return fmt.Errorf("failed to POST new alias to server: %w", err)
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
return fmt.Errorf("failed to read response body: %w", err)
}
err = checkApiResponseOK(body)
if err != nil {
return fmt.Errorf("api returned an error: %w", err)
}
return nil
}