diff options
Diffstat (limited to 'vendor/github.com/xenolf/lego/acme/client_test.go')
-rw-r--r-- | vendor/github.com/xenolf/lego/acme/client_test.go | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/vendor/github.com/xenolf/lego/acme/client_test.go b/vendor/github.com/xenolf/lego/acme/client_test.go new file mode 100644 index 000000000..e309554f3 --- /dev/null +++ b/vendor/github.com/xenolf/lego/acme/client_test.go @@ -0,0 +1,198 @@ +package acme + +import ( + "crypto" + "crypto/rand" + "crypto/rsa" + "encoding/json" + "net" + "net/http" + "net/http/httptest" + "strings" + "testing" +) + +func TestNewClient(t *testing.T) { + keyBits := 32 // small value keeps test fast + keyType := RSA2048 + key, err := rsa.GenerateKey(rand.Reader, keyBits) + if err != nil { + t.Fatal("Could not generate test key:", err) + } + user := mockUser{ + email: "test@test.com", + regres: new(RegistrationResource), + privatekey: key, + } + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + data, _ := json.Marshal(directory{NewAuthzURL: "http://test", NewCertURL: "http://test", NewRegURL: "http://test", RevokeCertURL: "http://test"}) + w.Write(data) + })) + + client, err := NewClient(ts.URL, user, keyType) + if err != nil { + t.Fatalf("Could not create client: %v", err) + } + + if client.jws == nil { + t.Fatalf("Expected client.jws to not be nil") + } + if expected, actual := key, client.jws.privKey; actual != expected { + t.Errorf("Expected jws.privKey to be %p but was %p", expected, actual) + } + + if client.keyType != keyType { + t.Errorf("Expected keyType to be %s but was %s", keyType, client.keyType) + } + + if expected, actual := 2, len(client.solvers); actual != expected { + t.Fatalf("Expected %d solver(s), got %d", expected, actual) + } +} + +func TestClientOptPort(t *testing.T) { + keyBits := 32 // small value keeps test fast + key, err := rsa.GenerateKey(rand.Reader, keyBits) + if err != nil { + t.Fatal("Could not generate test key:", err) + } + user := mockUser{ + email: "test@test.com", + regres: new(RegistrationResource), + privatekey: key, + } + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + data, _ := json.Marshal(directory{NewAuthzURL: "http://test", NewCertURL: "http://test", NewRegURL: "http://test", RevokeCertURL: "http://test"}) + w.Write(data) + })) + + optPort := "1234" + optHost := "" + client, err := NewClient(ts.URL, user, RSA2048) + if err != nil { + t.Fatalf("Could not create client: %v", err) + } + client.SetHTTPAddress(net.JoinHostPort(optHost, optPort)) + client.SetTLSAddress(net.JoinHostPort(optHost, optPort)) + + httpSolver, ok := client.solvers[HTTP01].(*httpChallenge) + if !ok { + t.Fatal("Expected http-01 solver to be httpChallenge type") + } + if httpSolver.jws != client.jws { + t.Error("Expected http-01 to have same jws as client") + } + if got := httpSolver.provider.(*HTTPProviderServer).port; got != optPort { + t.Errorf("Expected http-01 to have port %s but was %s", optPort, got) + } + if got := httpSolver.provider.(*HTTPProviderServer).iface; got != optHost { + t.Errorf("Expected http-01 to have iface %s but was %s", optHost, got) + } + + httpsSolver, ok := client.solvers[TLSSNI01].(*tlsSNIChallenge) + if !ok { + t.Fatal("Expected tls-sni-01 solver to be httpChallenge type") + } + if httpsSolver.jws != client.jws { + t.Error("Expected tls-sni-01 to have same jws as client") + } + if got := httpsSolver.provider.(*TLSProviderServer).port; got != optPort { + t.Errorf("Expected tls-sni-01 to have port %s but was %s", optPort, got) + } + if got := httpsSolver.provider.(*TLSProviderServer).iface; got != optHost { + t.Errorf("Expected tls-sni-01 to have port %s but was %s", optHost, got) + } + + // test setting different host + optHost = "127.0.0.1" + client.SetHTTPAddress(net.JoinHostPort(optHost, optPort)) + client.SetTLSAddress(net.JoinHostPort(optHost, optPort)) + + if got := httpSolver.provider.(*HTTPProviderServer).iface; got != optHost { + t.Errorf("Expected http-01 to have iface %s but was %s", optHost, got) + } + if got := httpsSolver.provider.(*TLSProviderServer).port; got != optPort { + t.Errorf("Expected tls-sni-01 to have port %s but was %s", optPort, got) + } +} + +func TestValidate(t *testing.T) { + var statuses []string + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Minimal stub ACME server for validation. + w.Header().Add("Replay-Nonce", "12345") + w.Header().Add("Retry-After", "0") + switch r.Method { + case "HEAD": + case "POST": + st := statuses[0] + statuses = statuses[1:] + writeJSONResponse(w, &challenge{Type: "http-01", Status: st, URI: "http://example.com/", Token: "token"}) + + case "GET": + st := statuses[0] + statuses = statuses[1:] + writeJSONResponse(w, &challenge{Type: "http-01", Status: st, URI: "http://example.com/", Token: "token"}) + + default: + http.Error(w, r.Method, http.StatusMethodNotAllowed) + } + })) + defer ts.Close() + + privKey, _ := rsa.GenerateKey(rand.Reader, 512) + j := &jws{privKey: privKey, directoryURL: ts.URL} + + tsts := []struct { + name string + statuses []string + want string + }{ + {"POST-unexpected", []string{"weird"}, "unexpected"}, + {"POST-valid", []string{"valid"}, ""}, + {"POST-invalid", []string{"invalid"}, "Error Detail"}, + {"GET-unexpected", []string{"pending", "weird"}, "unexpected"}, + {"GET-valid", []string{"pending", "valid"}, ""}, + {"GET-invalid", []string{"pending", "invalid"}, "Error Detail"}, + } + + for _, tst := range tsts { + statuses = tst.statuses + if err := validate(j, "example.com", ts.URL, challenge{Type: "http-01", Token: "token"}); err == nil && tst.want != "" { + t.Errorf("[%s] validate: got error %v, want something with %q", tst.name, err, tst.want) + } else if err != nil && !strings.Contains(err.Error(), tst.want) { + t.Errorf("[%s] validate: got error %v, want something with %q", tst.name, err, tst.want) + } + } +} + +// writeJSONResponse marshals the body as JSON and writes it to the response. +func writeJSONResponse(w http.ResponseWriter, body interface{}) { + bs, err := json.Marshal(body) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/json") + if _, err := w.Write(bs); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } +} + +// stubValidate is like validate, except it does nothing. +func stubValidate(j *jws, domain, uri string, chlng challenge) error { + return nil +} + +type mockUser struct { + email string + regres *RegistrationResource + privatekey *rsa.PrivateKey +} + +func (u mockUser) GetEmail() string { return u.email } +func (u mockUser) GetRegistration() *RegistrationResource { return u.regres } +func (u mockUser) GetPrivateKey() crypto.PrivateKey { return u.privatekey } |