diff options
author | Mike Crute <mike@crute.us> | 2022-01-30 12:24:26 -0800 |
---|---|---|
committer | Mike Crute <mike@crute.us> | 2022-01-30 12:24:26 -0800 |
commit | 1c24090da6b95ea304677d36f7cb6458034c08b9 (patch) | |
tree | b375186f692a1e850f2f35ad5a3295e90ab7906c /web | |
parent | 74c33667f4c317bed29a014306130b9dd8990538 (diff) | |
download | go_ddns_manager-1c24090da6b95ea304677d36f7cb6458034c08b9.tar.bz2 go_ddns_manager-1c24090da6b95ea304677d36f7cb6458034c08b9.tar.xz go_ddns_manager-1c24090da6b95ea304677d36f7cb6458034c08b9.zip |
Add ACMEv2 endpoints
The ACMEv2 endpoints are easier to use for clients running the Golang
acme.autocert.Manager. They require no tracking of state and also handle
DNS propagation checking so the client can remain simple.
Once the legacy REST client for the v1 endpoints is gone those old
endpoints can be removed.
Diffstat (limited to 'web')
-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 | } | ||