79 lines
2.5 KiB
Go
79 lines
2.5 KiB
Go
package webui
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
|
|
"mailgoserver/internal/backup"
|
|
)
|
|
|
|
// exportDomain streams a passphrase-encrypted archive of every mailbox in a domain —
|
|
// see internal/backup.WriteDomain for exactly what's included.
|
|
func (a *App) exportDomain(w http.ResponseWriter, r *http.Request) {
|
|
dom, err := a.DB.GetDomainByID(pathID(r))
|
|
if err != nil || dom == nil {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
if !requireDomainAccess(w, r, dom.ID) {
|
|
return
|
|
}
|
|
passphrase := r.FormValue("passphrase")
|
|
if passphrase == "" {
|
|
setFlash(w, "error", "A passphrase is required to export a domain")
|
|
http.Redirect(w, r, fmt.Sprintf("%s/domains/%d/edit", Prefix, dom.ID), http.StatusFound)
|
|
return
|
|
}
|
|
|
|
filename := fmt.Sprintf("%s-export-%s.tar.gz", dom.DomainName, time.Now().UTC().Format("2006-01-02-150405"))
|
|
w.Header().Set("Content-Disposition", `attachment; filename="`+filename+`"`)
|
|
w.Header().Set("Content-Type", "application/gzip")
|
|
if err := backup.WriteDomain(w, a.DB, a.Mailstore, dom.ID, passphrase); err != nil {
|
|
a.Logger.Error("domain export %s: %v", dom.DomainName, err)
|
|
}
|
|
}
|
|
|
|
// importDomain restores an archive produced by exportDomain into an existing domain.
|
|
// A mailbox whose email already exists anywhere on this server is skipped, not
|
|
// overwritten — see internal/backup.RestoreDomain.
|
|
func (a *App) importDomain(w http.ResponseWriter, r *http.Request) {
|
|
dom, err := a.DB.GetDomainByID(pathID(r))
|
|
if err != nil || dom == nil {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
if !requireDomainAccess(w, r, dom.ID) {
|
|
return
|
|
}
|
|
redirect := fmt.Sprintf("%s/domains/%d/edit", Prefix, dom.ID)
|
|
|
|
if err := r.ParseMultipartForm(10 << 20); err != nil {
|
|
setFlash(w, "error", "Invalid upload")
|
|
http.Redirect(w, r, redirect, http.StatusFound)
|
|
return
|
|
}
|
|
passphrase := r.FormValue("passphrase")
|
|
file, _, err := r.FormFile("archive")
|
|
if err != nil {
|
|
setFlash(w, "error", "No archive file provided")
|
|
http.Redirect(w, r, redirect, http.StatusFound)
|
|
return
|
|
}
|
|
defer file.Close()
|
|
|
|
skipped, err := backup.RestoreDomain(file, a.DB, a.Mailstore, dom.ID, passphrase)
|
|
if err != nil {
|
|
a.Logger.Error("domain import into %s: %v", dom.DomainName, err)
|
|
setFlash(w, "error", "Import failed: "+err.Error())
|
|
http.Redirect(w, r, redirect, http.StatusFound)
|
|
return
|
|
}
|
|
if len(skipped) > 0 {
|
|
setFlash(w, "success", fmt.Sprintf("Import complete. Skipped %d mailbox(es) whose address already existed: %v", len(skipped), skipped))
|
|
} else {
|
|
setFlash(w, "success", "Import complete")
|
|
}
|
|
http.Redirect(w, r, redirect, http.StatusFound)
|
|
}
|