From 3028225371bb24abaac5b34843ce96433ef2ee68 Mon Sep 17 00:00:00 2001 From: Chris Marchesi Date: Mon, 6 Jun 2016 11:45:22 -0700 Subject: [PATCH] reg: Add Query and Delete functions Add 2 new functions to acme.Client for registration stuff: * QueryRegistration: This performs a POST on the client registration's URI and gets the updated registration info. * DeleteRegistration: This deletes the registration as currently configured in the client. The latter, while a part of the IETF draft, may not be 100% functional in LE yet, my tests showed that resources were still available after deletion. --- acme/client.go | 62 ++++++++++++++++++++++++++++++++++++++++++++++++ acme/messages.go | 1 + 2 files changed, 63 insertions(+) diff --git a/acme/client.go b/acme/client.go index 5bda6bc2..445dc2bd 100644 --- a/acme/client.go +++ b/acme/client.go @@ -189,6 +189,68 @@ func (c *Client) Register() (*RegistrationResource, error) { return reg, nil } +// DeleteRegistration deletes the client's user registration from the ACME +// server. +func (c *Client) DeleteRegistration() error { + if c == nil || c.user == nil { + return errors.New("acme: cannot unregister a nil client or user") + } + logf("[INFO] acme: Deleting account for %s", c.user.GetEmail()) + + regMsg := registrationMessage{ + Resource: "reg", + Delete: true, + } + + _, err := postJSON(c.jws, c.user.GetRegistration().URI, regMsg, nil) + if err != nil { + return err + } + + return nil +} + +// QueryRegistration runs a POST request on the client's registration and +// returns the result. +// +// This is similar to the Register function, but acting on an existing +// registration link and resource. +func (c *Client) QueryRegistration() (*RegistrationResource, error) { + if c == nil || c.user == nil { + return nil, errors.New("acme: cannot query the registration of a nil client or user") + } + // Log the URL here instead of the email as the email may not be set + logf("[INFO] acme: Querying account for %s", c.user.GetRegistration().URI) + + regMsg := registrationMessage{ + Resource: "reg", + } + + var serverReg Registration + hdr, err := postJSON(c.jws, c.user.GetRegistration().URI, regMsg, &serverReg) + if err != nil { + return nil, err + } + + reg := &RegistrationResource{Body: serverReg} + + links := parseLinks(hdr["Link"]) + // Location: header is not returned so this needs to be populated off of + // existing URI + reg.URI = c.user.GetRegistration().URI + if links["terms-of-service"] != "" { + reg.TosURL = links["terms-of-service"] + } + + if links["next"] != "" { + reg.NewAuthzURL = links["next"] + } else { + return nil, errors.New("acme: No new-authz link in response to registration query") + } + + return reg, nil +} + // AgreeToTOS updates the Client registration and sends the agreement to // the server. func (c *Client) AgreeToTOS() error { diff --git a/acme/messages.go b/acme/messages.go index d1fac920..a6539b96 100644 --- a/acme/messages.go +++ b/acme/messages.go @@ -22,6 +22,7 @@ type recoveryKeyMessage struct { type registrationMessage struct { Resource string `json:"resource"` Contact []string `json:"contact"` + Delete bool `json:"delete,omitempty"` // RecoveryKey recoveryKeyMessage `json:"recoveryKey,omitempty"` }