acme: prompt for terms agreement
Allow Client.Register callers to report CA terms agreement,
simplifying the registration usage.
Change-Id: Ia2c237f31c8375b5ae669bbd07d9294c329f59b8
Reviewed-on: https://go-review.googlesource.com/23973
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/acme/internal/acme/acme.go b/acme/internal/acme/acme.go
index a16f0bb..a41b6ba 100644
--- a/acme/internal/acme/acme.go
+++ b/acme/internal/acme/acme.go
@@ -185,13 +185,35 @@
}
}
+// AcceptTOS always returns true to indicate the acceptance of a CA Terms of Service
+// during account registration. See Register method of Client for more details.
+func AcceptTOS(string) bool { return true }
+
// Register creates a new account registration by following the "new-reg" flow.
// It returns registered account. The a argument is not modified.
-func (c *Client) Register(a *Account) (*Account, error) {
+//
+// The registration may require the caller to agree to the CA Terms of Service (TOS).
+// If so, and the account has not indicated the acceptance of the terms (see Account for details),
+// Register calls prompt with a TOS URL provided by the CA. Prompt should report
+// whether the caller agrees to the terms. To always accept the terms, the caller can use AcceptTOS.
+func (c *Client) Register(a *Account, prompt func(tos string) bool) (*Account, error) {
if _, err := c.Discover(); err != nil {
return nil, err
}
- return c.doReg(c.dir.RegURL, "new-reg", a)
+
+ var err error
+ if a, err = c.doReg(c.dir.RegURL, "new-reg", a); err != nil {
+ return nil, err
+ }
+ var accept bool
+ if a.CurrentTerms != "" && a.CurrentTerms != a.AgreedTerms {
+ accept = prompt(a.CurrentTerms)
+ }
+ if accept {
+ a.AgreedTerms = a.CurrentTerms
+ a, err = c.UpdateReg(a)
+ }
+ return a, err
}
// GetReg retrieves an existing registration.
diff --git a/acme/internal/acme/acme_test.go b/acme/internal/acme/acme_test.go
index 6d7c424..eae8f66 100644
--- a/acme/internal/acme/acme_test.go
+++ b/acme/internal/acme/acme_test.go
@@ -117,10 +117,18 @@
}))
defer ts.Close()
+ prompt := func(url string) bool {
+ const terms = "https://ca.tld/acme/terms"
+ if url != terms {
+ t.Errorf("prompt url = %q; want %q", url, terms)
+ }
+ return false
+ }
+
c := Client{Key: testKey, dir: &Directory{RegURL: ts.URL}}
a := &Account{Contact: contacts}
var err error
- if a, err = c.Register(a); err != nil {
+ if a, err = c.Register(a, prompt); err != nil {
t.Fatal(err)
}
if a.URI != "https://ca.tld/acme/reg/1" {
diff --git a/acme/internal/acme/types.go b/acme/internal/acme/types.go
index e64dc11..702be79 100644
--- a/acme/internal/acme/types.go
+++ b/acme/internal/acme/types.go
@@ -25,7 +25,8 @@
Contact []string
// The terms user has agreed to.
- // Zero value indicates that the user hasn't agreed yet.
+ // A value not matching CurrentTerms indicates that the user hasn't agreed
+ // to the actual Terms of Service of the CA.
AgreedTerms string
// Actual terms of a CA.