diff options
Diffstat (limited to 'web/controllers/acmev2.go')
-rw-r--r-- | web/controllers/acmev2.go | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/web/controllers/acmev2.go b/web/controllers/acmev2.go new file mode 100644 index 0000000..a2fadf5 --- /dev/null +++ b/web/controllers/acmev2.go | |||
@@ -0,0 +1,90 @@ | |||
1 | package controllers | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "log" | ||
6 | "net/http" | ||
7 | |||
8 | "code.crute.me/mcrute/go_ddns_manager/dns" | ||
9 | "code.crute.me/mcrute/go_ddns_manager/web/middleware" | ||
10 | "github.com/gin-gonic/gin" | ||
11 | ) | ||
12 | |||
13 | func CreateAcmeChallengeV2(c *gin.Context) { | ||
14 | cfg := middleware.GetServerConfig(c) | ||
15 | |||
16 | var ch AcmeChallenge | ||
17 | if err := c.ShouldBindJSON(&ch); err != nil { | ||
18 | jsonError(c, http.StatusBadRequest, err) | ||
19 | return | ||
20 | } | ||
21 | |||
22 | zone, prefix := cfg.BindConfig.FindClosestZone(ch.Zone, cfg.AcmeView) | ||
23 | if zone == nil { | ||
24 | jsonError(c, http.StatusNotFound, "Zone not found") | ||
25 | return | ||
26 | } | ||
27 | |||
28 | if !cfg.IsAcmeClientAllowed(middleware.GetAcmeAuthContext(c), zone.Name) { | ||
29 | jsonError(c, http.StatusForbidden, "Zone update not allowed") | ||
30 | return | ||
31 | } | ||
32 | |||
33 | txn := cfg.DNSClient.StartUpdate(zone).Upsert(&dns.TXT{ | ||
34 | Name: joinDomainParts("_acme-challenge", prefix), | ||
35 | Ttl: 5, | ||
36 | Txt: []string{ch.Challenge}, | ||
37 | }) | ||
38 | |||
39 | if err := cfg.DNSClient.SendUpdate(txn); err != nil { | ||
40 | log.Printf("error Insert: %s", err) | ||
41 | jsonError(c, http.StatusInternalServerError, err) | ||
42 | return | ||
43 | } | ||
44 | |||
45 | if err := cfg.DNSClient.WaitForDNSPropagation( | ||
46 | c.Request.Context(), | ||
47 | fmt.Sprintf("_acme-challenge.%s.", prefix), | ||
48 | ch.Challenge, | ||
49 | ); err != nil { | ||
50 | jsonError(c, http.StatusInternalServerError, fmt.Errorf("Error polling for DNS propagation: %w", err)) | ||
51 | return | ||
52 | } | ||
53 | |||
54 | c.JSON(http.StatusCreated, "") | ||
55 | } | ||
56 | |||
57 | func DeleteAcmeChallengeV2(c *gin.Context) { | ||
58 | cfg := middleware.GetServerConfig(c) | ||
59 | |||
60 | var ch AcmeChallenge | ||
61 | if err := c.ShouldBindJSON(&ch); err != nil { | ||
62 | jsonError(c, http.StatusBadRequest, err) | ||
63 | return | ||
64 | } | ||
65 | |||
66 | zone, prefix := cfg.BindConfig.FindClosestZone(ch.Zone, cfg.AcmeView) | ||
67 | if zone == nil { | ||
68 | jsonError(c, http.StatusNotFound, "Zone not found") | ||
69 | return | ||
70 | } | ||
71 | |||
72 | if !cfg.IsAcmeClientAllowed(middleware.GetAcmeAuthContext(c), zone.Name) { | ||
73 | jsonError(c, http.StatusForbidden, "Zone update not allowed") | ||
74 | return | ||
75 | } | ||
76 | |||
77 | txn := cfg.DNSClient.StartUpdate(zone).Remove(&dns.TXT{ | ||
78 | Name: joinDomainParts("_acme-challenge", prefix), | ||
79 | Ttl: 5, | ||
80 | Txt: []string{ch.Challenge}, | ||
81 | }) | ||
82 | |||
83 | if err := cfg.DNSClient.SendUpdate(txn); err != nil { | ||
84 | log.Printf("error Remove: %s", err) | ||
85 | jsonError(c, http.StatusInternalServerError, err) | ||
86 | return | ||
87 | } | ||
88 | |||
89 | c.String(http.StatusNoContent, "") | ||
90 | } | ||