From 4262255f5c512e5c53a167c24a2eea2821f01ea5 Mon Sep 17 00:00:00 2001 From: Mike Crute Date: Tue, 10 Nov 2020 02:36:44 +0000 Subject: Add dynamic DNS functionality --- dns/client.go | 2 +- generate_dns_types.go | 1 - web/config.go | 1 + web/controllers/manage.go | 61 ++++++++++++++++++++++++++++++++++++++++++++++ web/middleware/api_auth.go | 34 ++++++++++++++++++++++++++ 5 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 web/controllers/manage.go create mode 100644 web/middleware/api_auth.go diff --git a/dns/client.go b/dns/client.go index f322b45..525444a 100644 --- a/dns/client.go +++ b/dns/client.go @@ -46,7 +46,7 @@ func (c *DNSClient) AXFR(zone *bind.Zone) (chan *dns.Envelope, error) { m.SetAxfr(zone.Name) k.Sign(m) - return t.In(m, fmt.Sprintf("%s:53", c.Server)) + return t.In(m, c.Server) } func (c *DNSClient) ReadRemoteZone(zone *bind.Zone) ([]RR, error) { diff --git a/generate_dns_types.go b/generate_dns_types.go index 282c630..89ba251 100644 --- a/generate_dns_types.go +++ b/generate_dns_types.go @@ -88,7 +88,6 @@ var _ RR = (*{{ $name }})(nil) {{ end }} - func FromDNS(rr dns.RR) interface{} { switch v := rr.(type) { {{ range $name, $fields := . -}} diff --git a/web/config.go b/web/config.go index b307425..9490b44 100644 --- a/web/config.go +++ b/web/config.go @@ -14,6 +14,7 @@ type ServerConfig struct { DynamicDnsView string DDNSSecrets map[string]string `json:"DDNS"` AcmeSecrets map[string]map[string]int `json:"ACME"` + ApiSecrets map[string]string `json:"DNS_MANAGE"` } func (s *ServerConfig) GetDDNSZoneName(k string) string { diff --git a/web/controllers/manage.go b/web/controllers/manage.go new file mode 100644 index 0000000..53a38a6 --- /dev/null +++ b/web/controllers/manage.go @@ -0,0 +1,61 @@ +package controllers + +import ( + "net/http" + + "github.com/gin-gonic/gin" + + "code.crute.me/mcrute/frame" + "code.crute.me/mcrute/go_ddns_manager/dns" + "code.crute.me/mcrute/go_ddns_manager/web/middleware" +) + +type UpdateZone struct { + Create []dns.RR + Update []dns.RR + Delete []dns.RR +} + +func ManageRoot(c *gin.Context) { + c.JSON(http.StatusOK, map[string]string{ + "views_url": frame.MakeURL(c.Request, "/manage/views").String(), + }) +} + +func ListViews(c *gin.Context) { + cfg := middleware.GetServerConfig(c) + + out := map[string]string{} + + for _, vn := range cfg.BindConfig.Views() { + out[vn] = frame.MakeURL(c.Request, "/manage/views/%s", vn).String() + } + + c.JSON(http.StatusOK, out) +} + +func ListView(c *gin.Context) { + cfg := middleware.GetServerConfig(c) + view := c.Param("view") + + out := map[string]string{} + + for _, z := range cfg.BindConfig.ZonesInView(view) { + out[z.Name] = frame.MakeURL(c.Request, "/manage/views/%s/%s", view, z.Name).String() + } + + c.JSON(http.StatusOK, out) +} + +func ListZone(c *gin.Context) { + cfg := middleware.GetServerConfig(c) + zone := cfg.BindConfig.Zone(c.Param("view"), c.Param("zone")) + + rrs, err := cfg.DNSClient.ReadRemoteZone(zone) + if err != nil { + c.JSON(http.StatusInternalServerError, err) + return + } + + c.JSON(http.StatusOK, rrs) +} diff --git a/web/middleware/api_auth.go b/web/middleware/api_auth.go new file mode 100644 index 0000000..b854297 --- /dev/null +++ b/web/middleware/api_auth.go @@ -0,0 +1,34 @@ +package middleware + +import ( + "net/http" + "strings" + + "github.com/gin-gonic/gin" +) + +const API_AUTH_USER_KEY = "APIAuthUserKey" + +func ApiAuthMiddleware(c *gin.Context) { + cfg := GetServerConfig(c) + + auth := strings.Split(c.Request.Header.Get("Authorization"), " ") + + if len(auth) != 2 || auth[0] != "Bearer" { + c.AbortWithStatus(http.StatusUnauthorized) + return + } + + if user, ok := cfg.ApiSecrets[auth[1]]; ok { + c.Set(API_AUTH_USER_KEY, user) + } else { + c.AbortWithStatus(http.StatusUnauthorized) + return + } + + c.Next() +} + +func GetAPIAuthUser(c *gin.Context) string { + return c.GetString(API_AUTH_USER_KEY) +} -- cgit v1.2.3