package acme import ( "errors" "fmt" "net" "net/http" "strings" "time" "gopkg.in/square/go-jose.v1" ) var ErrMustAgree = errors.New("must agree to TOS") // Registration Objects type Registration struct { Resource Resource `json:"resource"` // new-reg ID int `json:"id,omitempty"` Key *jose.JsonWebKey `json:"key,omitempty"` Contact Contacts `json:"contact,omitempty"` Agreement string `json:"agreement,omitempty"` InitialIP *net.IP `json:"initialIp,omitempty"` // not in draft CreatedAt *time.Time `json:"createdAt,omitempty"` } func Agree(q string) bool { var r string fmt.Printf("Agree to %s? [y/N] ", q) fmt.Scanln(&r) r = strings.ToLower(r) return len(r) > 0 && r[0] == 'y' } func (p *Provider) Register(c Contacts, agree func(string) bool) error { // first step: new-reg req := &Registration{ Resource: ResNewReg, Contact: c, } resp, err := p.postJson(p.NewReg, req) if err != nil { return err } defer resp.Body.Close() switch resp.StatusCode { case http.StatusCreated, http.StatusConflict: default: return errors.New(resp.Status) } ns := parseHeader(resp) tos := ns.Link["terms-of-service"] if !agree(tos) { return ErrMustAgree } // second step: reg, agree to tos req = &Registration{ Resource: ResReg, Contact: c, Agreement: tos, } resp, err = p.postJson(ns.Location, req) if err != nil { return err } defer resp.Body.Close() return nil }