summaryrefslogtreecommitdiff
path: root/web
diff options
context:
space:
mode:
Diffstat (limited to 'web')
-rw-r--r--web/config.go22
-rw-r--r--web/controllers/dns_manage.go68
-rw-r--r--web/middleware/dns_manage.go33
3 files changed, 117 insertions, 6 deletions
diff --git a/web/config.go b/web/config.go
index 2479e38..acdc4bf 100644
--- a/web/config.go
+++ b/web/config.go
@@ -1,6 +1,7 @@
1package web 1package web
2 2
3import ( 3import (
4 "crypto/subtle"
4 "encoding/json" 5 "encoding/json"
5 "io/ioutil" 6 "io/ioutil"
6 "strings" 7 "strings"
@@ -10,12 +11,13 @@ import (
10) 11)
11 12
12type ServerConfig struct { 13type ServerConfig struct {
13 BindConfig *bind.BINDConfig 14 BindConfig *bind.BINDConfig
14 DNSClient *dns.DNSClient 15 DNSClient *dns.DNSClient
15 AcmeView string 16 AcmeView string
16 DynamicDnsView string 17 DynamicDnsView string
17 DDNSSecrets map[string]string `json:"DDNS"` 18 DDNSSecrets map[string]string `json:"DDNS"`
18 AcmeSecrets map[string]map[string]int `json:"ACME"` 19 AcmeSecrets map[string]map[string]int `json:"ACME"`
20 DNSManageSecrets map[string]string `json:"DNS_MANAGE"`
19} 21}
20 22
21func LoadServerConfig(zonesFile, secretsFile, server, view string) (*ServerConfig, error) { 23func LoadServerConfig(zonesFile, secretsFile, server, view string) (*ServerConfig, error) {
@@ -53,6 +55,14 @@ func (s *ServerConfig) AcmeSecretExists(k string) bool {
53 return ok 55 return ok
54} 56}
55 57
58func (s *ServerConfig) DNSUserAuth(u, p string) bool {
59 cp, ok := s.DNSManageSecrets[u]
60 if !ok {
61 return false
62 }
63 return subtle.ConstantTimeCompare([]byte(p), []byte(cp)) == 1
64}
65
56func (s *ServerConfig) IsAcmeClientAllowed(key, zone string) bool { 66func (s *ServerConfig) IsAcmeClientAllowed(key, zone string) bool {
57 u, ok := s.AcmeSecrets[key] 67 u, ok := s.AcmeSecrets[key]
58 if !ok { 68 if !ok {
diff --git a/web/controllers/dns_manage.go b/web/controllers/dns_manage.go
new file mode 100644
index 0000000..6db0b13
--- /dev/null
+++ b/web/controllers/dns_manage.go
@@ -0,0 +1,68 @@
1package controllers
2
3import (
4 "net/http"
5
6 "github.com/gin-gonic/gin"
7 "github.com/miekg/dns"
8
9 "code.crute.me/mcrute/go_ddns_manager/bind"
10 "code.crute.me/mcrute/go_ddns_manager/util"
11 "code.crute.me/mcrute/go_ddns_manager/web/middleware"
12)
13
14func DnsManageRoot(c *gin.Context) {
15 c.IndentedJSON(http.StatusOK, gin.H{
16 "_rels": gin.H{
17 "zones": util.MakeURL(c.Request, "/dns/zone").String(),
18 "views": util.MakeURL(c.Request, "/dns/view").String(),
19 },
20 })
21}
22
23func DnsViews(c *gin.Context) {
24 cfg := middleware.GetServerConfig(c)
25 out := map[string]map[string]string{}
26
27 for _, v := range cfg.BindConfig.Views() {
28 k := map[string]string{}
29 out[v] = k
30 for _, z := range cfg.BindConfig.ZonesInView(v) {
31 zn := bind.DeCanonicalize(z.Name)
32 k[zn] = util.MakeURL(c.Request, "/dns/zone/%s/%s", v, zn).String()
33 }
34 }
35
36 c.IndentedJSON(http.StatusOK, gin.H{"views": out})
37}
38
39func DnsZones(c *gin.Context) {
40
41}
42
43func DnsZoneDetails(c *gin.Context) {
44 cfg := middleware.GetServerConfig(c)
45
46 z := cfg.BindConfig.Zone(c.Param("view"), c.Param("name"))
47 if z == nil {
48 c.JSON(http.StatusNotFound, gin.H{
49 "error": "Zone not found",
50 })
51 return
52 }
53
54 envs := []*dns.Envelope{}
55 ec, err := cfg.DNSClient.AXFR(z)
56 if err != nil {
57 c.JSON(http.StatusInternalServerError, gin.H{
58 "error": err.Error(),
59 })
60 return
61 }
62
63 for e := range ec {
64 envs = append(envs, e)
65 }
66
67 c.JSON(http.StatusOK, envs)
68}
diff --git a/web/middleware/dns_manage.go b/web/middleware/dns_manage.go
new file mode 100644
index 0000000..d3b420b
--- /dev/null
+++ b/web/middleware/dns_manage.go
@@ -0,0 +1,33 @@
1package middleware
2
3import (
4 "net/http"
5
6 "github.com/gin-gonic/gin"
7)
8
9const dnsUserId = "DNSManageUserID"
10
11func DnsManageAuthMiddleware(c *gin.Context) {
12 cfg := GetServerConfig(c)
13
14 user, pwd, ok := c.Request.BasicAuth()
15 if !ok {
16 c.Request.Header.Set("WWW-Authenticate", `Basic realm="closed site"`)
17 c.AbortWithStatus(http.StatusUnauthorized)
18 return
19 }
20
21 if !cfg.DNSUserAuth(user, pwd) {
22 c.AbortWithStatus(http.StatusForbidden)
23 return
24 } else {
25 c.Set(dnsUserId, user)
26 }
27
28 c.Next()
29}
30
31func GetDnsAuthContext(c *gin.Context) string {
32 return c.GetString(dnsUserId)
33}