docker-ddns-server/dyndns/handler/cname.go
AuxXxilium 7685e2adcf tree: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-05 12:25:34 +02:00

123 lines
3.4 KiB
Go

package handler
import (
"fmt"
"net/http"
"strconv"
"github.com/AuxXxilium/docker-ddns-server/dyndns/model"
"github.com/AuxXxilium/docker-ddns-server/dyndns/nswrapper"
"github.com/labstack/echo/v4"
"gorm.io/gorm"
)
// ListCNames fetches all cnames from database and lists them on the website.
func (h *Handler) ListCNames(c echo.Context) (err error) {
if !h.AuthAdmin {
return c.JSON(http.StatusUnauthorized, &Error{UNAUTHORIZED})
}
cnames := new([]model.CName)
if err = h.DB.Preload("Target").Find(cnames).Error; err != nil {
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
}
return c.Render(http.StatusOK, "listcnames", echo.Map{
"cnames": cnames,
"title": h.Title,
})
}
// AddCName just renders the "add cname" website.
// Therefore all host entries from the database are being fetched.
func (h *Handler) AddCName(c echo.Context) (err error) {
if !h.AuthAdmin {
return c.JSON(http.StatusUnauthorized, &Error{UNAUTHORIZED})
}
hosts := new([]model.Host)
if err = h.DB.Find(hosts).Error; err != nil {
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
}
return c.Render(http.StatusOK, "addcname", echo.Map{
"config": h.Config,
"hosts": hosts,
"title": h.Title,
})
}
// CreateCName validates the cname data from the "add cname" website,
// adds the cname entry to the database,
// and adds the entry to the DNS server.
func (h *Handler) CreateCName(c echo.Context) (err error) {
if !h.AuthAdmin {
return c.JSON(http.StatusUnauthorized, &Error{UNAUTHORIZED})
}
cname := &model.CName{}
if err = c.Bind(cname); err != nil {
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
}
host := &model.Host{}
if err = h.DB.First(host, c.FormValue("target_id")).Error; err != nil {
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
}
cname.Target = *host
if err = c.Validate(cname); err != nil {
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
}
if err = h.checkUniqueHostname(cname.Hostname, cname.Target.Domain); err != nil {
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
}
if err = h.DB.Create(cname).Error; err != nil {
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
}
if err = nswrapper.UpdateRecord(cname.Hostname, fmt.Sprintf("%s.%s", cname.Target.Hostname, cname.Target.Domain), "CNAME", cname.Target.Domain, cname.Ttl, h.AllowWildcard); err != nil {
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
}
return c.JSON(http.StatusOK, cname)
}
// DeleteCName fetches a cname entry from the database by "id"
// and deletes the database and DNS server entry to it.
func (h *Handler) DeleteCName(c echo.Context) (err error) {
if !h.AuthAdmin {
return c.JSON(http.StatusUnauthorized, &Error{UNAUTHORIZED})
}
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
}
cname := &model.CName{}
if err = h.DB.Preload("Target").First(cname, id).Error; err != nil {
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
}
err = h.DB.Transaction(func(tx *gorm.DB) error {
if err = tx.Unscoped().Delete(cname).Error; err != nil {
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
}
return nil
})
if err != nil {
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
}
if err = nswrapper.DeleteRecord(cname.Hostname, cname.Target.Domain, h.AllowWildcard); err != nil {
return c.JSON(http.StatusBadRequest, &Error{err.Error()})
}
return c.JSON(http.StatusOK, id)
}