diff --git a/server/handlers/default.go b/server/handlers/default.go index 98ff720077..7b56bc774a 100644 --- a/server/handlers/default.go +++ b/server/handlers/default.go @@ -37,6 +37,12 @@ func MainHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) er // backend is atomically updated with all the new records. func AtomicUpdateHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) error { defer r.Body.Close() + vars := mux.Vars(r) + return atomicUpdateHandler(ctx, w, r, vars) +} + +func atomicUpdateHandler(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { + gun := vars["imageName"] s := ctx.Value("metaStore") store, ok := s.(storage.MetaStore) if !ok { @@ -48,8 +54,6 @@ func AtomicUpdateHandler(ctx context.Context, w http.ResponseWriter, r *http.Req return errors.ErrNoCryptoService.WithDetail(nil) } - vars := mux.Vars(r) - gun := vars["imageName"] reader, err := r.MultipartReader() if err != nil { return errors.ErrMalformedUpload.WithDetail(nil) @@ -94,14 +98,19 @@ func AtomicUpdateHandler(ctx context.Context, w http.ResponseWriter, r *http.Req // GetHandler returns the json for a specified role and GUN. func GetHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) error { + defer r.Body.Close() + vars := mux.Vars(r) + return getHandler(ctx, w, r, vars) +} + +func getHandler(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { + gun := vars["imageName"] + tufRole := vars["tufRole"] s := ctx.Value("metaStore") store, ok := s.(storage.MetaStore) if !ok { return errors.ErrNoStorage.WithDetail(nil) } - vars := mux.Vars(r) - gun := vars["imageName"] - tufRole := vars["tufRole"] logger := ctxu.GetLoggerWithFields(ctx, map[string]interface{}{"gun": gun, "tufRole": tufRole}) diff --git a/server/handlers/default_test.go b/server/handlers/default_test.go index 91c104af74..b4d1652cea 100644 --- a/server/handlers/default_test.go +++ b/server/handlers/default_test.go @@ -1,15 +1,22 @@ package handlers import ( + "bytes" + "encoding/json" + "io/ioutil" "net/http" "net/http/httptest" "testing" "golang.org/x/net/context" + "github.com/docker/notary/server/storage" + "github.com/docker/notary/tuf/data" "github.com/docker/notary/tuf/signed" + "github.com/docker/notary/tuf/testutils" "github.com/docker/notary/utils" + "github.com/stretchr/testify/assert" ) func TestMainHandlerGet(t *testing.T) { @@ -38,3 +45,145 @@ func TestMainHandlerNotGet(t *testing.T) { t.Fatalf("Expected 404, received %d", res.StatusCode) } } + +func TestGetHandlerRoot(t *testing.T) { + store := storage.NewMemStorage() + _, repo, _ := testutils.EmptyRepo() + + ctx := context.Background() + ctx = context.WithValue(ctx, "metaStore", store) + + root, err := repo.SignRoot(data.DefaultExpires("root")) + rootJSON, err := json.Marshal(root) + assert.NoError(t, err) + store.UpdateCurrent("gun", storage.MetaUpdate{Role: "root", Version: 1, Data: rootJSON}) + + req := &http.Request{ + Body: ioutil.NopCloser(bytes.NewBuffer(nil)), + } + + vars := map[string]string{ + "imageName": "gun", + "tufRole": "root", + } + + rw := httptest.NewRecorder() + + err = getHandler(ctx, rw, req, vars) + assert.NoError(t, err) +} + +func TestGetHandlerTimestamp(t *testing.T) { + store := storage.NewMemStorage() + _, repo, crypto := testutils.EmptyRepo() + + ctx := context.Background() + ctx = context.WithValue(ctx, "metaStore", store) + ctx = context.WithValue(ctx, "cryptoService", crypto) + + sn, err := repo.SignSnapshot(data.DefaultExpires("snapshot")) + snJSON, err := json.Marshal(sn) + assert.NoError(t, err) + store.UpdateCurrent("gun", storage.MetaUpdate{Role: "snapshot", Version: 1, Data: snJSON}) + + ts, err := repo.SignTimestamp(data.DefaultExpires("timestamp")) + tsJSON, err := json.Marshal(ts) + assert.NoError(t, err) + store.UpdateCurrent("gun", storage.MetaUpdate{Role: "timestamp", Version: 1, Data: tsJSON}) + + req := &http.Request{ + Body: ioutil.NopCloser(bytes.NewBuffer(nil)), + } + + vars := map[string]string{ + "imageName": "gun", + "tufRole": "timestamp", + } + + rw := httptest.NewRecorder() + + err = getHandler(ctx, rw, req, vars) + assert.NoError(t, err) +} + +func TestGetHandlerSnapshot(t *testing.T) { + store := storage.NewMemStorage() + _, repo, crypto := testutils.EmptyRepo() + + ctx := context.Background() + ctx = context.WithValue(ctx, "metaStore", store) + ctx = context.WithValue(ctx, "cryptoService", crypto) + + sn, err := repo.SignSnapshot(data.DefaultExpires("snapshot")) + snJSON, err := json.Marshal(sn) + assert.NoError(t, err) + store.UpdateCurrent("gun", storage.MetaUpdate{Role: "snapshot", Version: 1, Data: snJSON}) + + req := &http.Request{ + Body: ioutil.NopCloser(bytes.NewBuffer(nil)), + } + + vars := map[string]string{ + "imageName": "gun", + "tufRole": "snapshot", + } + + rw := httptest.NewRecorder() + + err = getHandler(ctx, rw, req, vars) + assert.NoError(t, err) +} + +func TestGetHandler404(t *testing.T) { + store := storage.NewMemStorage() + + ctx := context.Background() + ctx = context.WithValue(ctx, "metaStore", store) + + req := &http.Request{ + Body: ioutil.NopCloser(bytes.NewBuffer(nil)), + } + + vars := map[string]string{ + "imageName": "gun", + "tufRole": "root", + } + + rw := httptest.NewRecorder() + + err := getHandler(ctx, rw, req, vars) + assert.Error(t, err) +} + +func TestGetHandlerNilData(t *testing.T) { + store := storage.NewMemStorage() + store.UpdateCurrent("gun", storage.MetaUpdate{Role: "root", Version: 1, Data: nil}) + + ctx := context.Background() + ctx = context.WithValue(ctx, "metaStore", store) + + req := &http.Request{ + Body: ioutil.NopCloser(bytes.NewBuffer(nil)), + } + + vars := map[string]string{ + "imageName": "gun", + "tufRole": "root", + } + + rw := httptest.NewRecorder() + + err := getHandler(ctx, rw, req, vars) + assert.Error(t, err) +} + +func TestGetHandlerNoStorage(t *testing.T) { + ctx := context.Background() + + req := &http.Request{ + Body: ioutil.NopCloser(bytes.NewBuffer(nil)), + } + + err := GetHandler(ctx, nil, req) + assert.Error(t, err) +}