Add unauthorized error check
Add check for unauthorized error code and explicitly set the error code if the content could not be parsed. Updated repository test for unauthorized tests and nit feedback. Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
This commit is contained in:
parent
b4972a6bab
commit
3b5a2bbebc
2 changed files with 61 additions and 32 deletions
|
@ -52,6 +52,17 @@ func parseHTTPErrorResponse(r io.Reader) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleErrorResponse(resp *http.Response) error {
|
func handleErrorResponse(resp *http.Response) error {
|
||||||
|
if resp.StatusCode == 401 {
|
||||||
|
err := parseHTTPErrorResponse(resp.Body)
|
||||||
|
if uErr, ok := err.(*UnexpectedHTTPResponseError); ok {
|
||||||
|
return &v2.Error{
|
||||||
|
Code: v2.ErrorCodeUnauthorized,
|
||||||
|
Message: "401 Unauthorized",
|
||||||
|
Detail: uErr.Response,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
if resp.StatusCode >= 400 && resp.StatusCode < 500 {
|
if resp.StatusCode >= 400 && resp.StatusCode < 500 {
|
||||||
return parseHTTPErrorResponse(resp.Body)
|
return parseHTTPErrorResponse(resp.Body)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import (
|
||||||
"github.com/docker/distribution/context"
|
"github.com/docker/distribution/context"
|
||||||
"github.com/docker/distribution/digest"
|
"github.com/docker/distribution/digest"
|
||||||
"github.com/docker/distribution/manifest"
|
"github.com/docker/distribution/manifest"
|
||||||
|
"github.com/docker/distribution/registry/api/v2"
|
||||||
"github.com/docker/distribution/testutil"
|
"github.com/docker/distribution/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -73,26 +74,10 @@ func addTestFetch(repo string, dgst digest.Digest, content []byte, m *testutil.R
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func addPing(m *testutil.RequestResponseMap) {
|
|
||||||
*m = append(*m, testutil.RequestResponseMapping{
|
|
||||||
Request: testutil.Request{
|
|
||||||
Method: "GET",
|
|
||||||
Route: "/v2/",
|
|
||||||
},
|
|
||||||
Response: testutil.Response{
|
|
||||||
StatusCode: http.StatusOK,
|
|
||||||
Headers: http.Header(map[string][]string{
|
|
||||||
"Docker-Distribution-API-Version": {"registry/2.0"},
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBlobFetch(t *testing.T) {
|
func TestBlobFetch(t *testing.T) {
|
||||||
d1, b1 := newRandomBlob(1024)
|
d1, b1 := newRandomBlob(1024)
|
||||||
var m testutil.RequestResponseMap
|
var m testutil.RequestResponseMap
|
||||||
addTestFetch("test.example.com/repo1", d1, b1, &m)
|
addTestFetch("test.example.com/repo1", d1, b1, &m)
|
||||||
addPing(&m)
|
|
||||||
|
|
||||||
e, c := testServer(m)
|
e, c := testServer(m)
|
||||||
defer c()
|
defer c()
|
||||||
|
@ -112,14 +97,13 @@ func TestBlobFetch(t *testing.T) {
|
||||||
t.Fatalf("Wrong bytes values fetched: [%d]byte != [%d]byte", len(b), len(b1))
|
t.Fatalf("Wrong bytes values fetched: [%d]byte != [%d]byte", len(b), len(b1))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(dmcgowan): Test error cases
|
// TODO(dmcgowan): Test for unknown blob case
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBlobExists(t *testing.T) {
|
func TestBlobExists(t *testing.T) {
|
||||||
d1, b1 := newRandomBlob(1024)
|
d1, b1 := newRandomBlob(1024)
|
||||||
var m testutil.RequestResponseMap
|
var m testutil.RequestResponseMap
|
||||||
addTestFetch("test.example.com/repo1", d1, b1, &m)
|
addTestFetch("test.example.com/repo1", d1, b1, &m)
|
||||||
addPing(&m)
|
|
||||||
|
|
||||||
e, c := testServer(m)
|
e, c := testServer(m)
|
||||||
defer c()
|
defer c()
|
||||||
|
@ -150,7 +134,6 @@ func TestBlobExists(t *testing.T) {
|
||||||
func TestBlobUploadChunked(t *testing.T) {
|
func TestBlobUploadChunked(t *testing.T) {
|
||||||
dgst, b1 := newRandomBlob(1024)
|
dgst, b1 := newRandomBlob(1024)
|
||||||
var m testutil.RequestResponseMap
|
var m testutil.RequestResponseMap
|
||||||
addPing(&m)
|
|
||||||
chunks := [][]byte{
|
chunks := [][]byte{
|
||||||
b1[0:256],
|
b1[0:256],
|
||||||
b1[256:512],
|
b1[256:512],
|
||||||
|
@ -272,7 +255,6 @@ func TestBlobUploadChunked(t *testing.T) {
|
||||||
func TestBlobUploadMonolithic(t *testing.T) {
|
func TestBlobUploadMonolithic(t *testing.T) {
|
||||||
dgst, b1 := newRandomBlob(1024)
|
dgst, b1 := newRandomBlob(1024)
|
||||||
var m testutil.RequestResponseMap
|
var m testutil.RequestResponseMap
|
||||||
addPing(&m)
|
|
||||||
repo := "test.example.com/uploadrepo"
|
repo := "test.example.com/uploadrepo"
|
||||||
uploadID := uuid.New()
|
uploadID := uuid.New()
|
||||||
m = append(m, testutil.RequestResponseMapping{
|
m = append(m, testutil.RequestResponseMapping{
|
||||||
|
@ -378,7 +360,7 @@ func TestBlobUploadMonolithic(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRandomSchema1Manifest(name, tag string, blobCount int) (*manifest.SignedManifest, digest.Digest) {
|
func newRandomSchemaV1Manifest(name, tag string, blobCount int) (*manifest.SignedManifest, digest.Digest) {
|
||||||
blobs := make([]manifest.FSLayer, blobCount)
|
blobs := make([]manifest.FSLayer, blobCount)
|
||||||
history := make([]manifest.History, blobCount)
|
history := make([]manifest.History, blobCount)
|
||||||
|
|
||||||
|
@ -474,9 +456,8 @@ func checkEqualManifest(m1, m2 *manifest.SignedManifest) error {
|
||||||
|
|
||||||
func TestManifestFetch(t *testing.T) {
|
func TestManifestFetch(t *testing.T) {
|
||||||
repo := "test.example.com/repo"
|
repo := "test.example.com/repo"
|
||||||
m1, dgst := newRandomSchema1Manifest(repo, "latest", 6)
|
m1, dgst := newRandomSchemaV1Manifest(repo, "latest", 6)
|
||||||
var m testutil.RequestResponseMap
|
var m testutil.RequestResponseMap
|
||||||
addPing(&m)
|
|
||||||
addTestManifest(repo, dgst.String(), m1.Raw, &m)
|
addTestManifest(repo, dgst.String(), m1.Raw, &m)
|
||||||
|
|
||||||
e, c := testServer(m)
|
e, c := testServer(m)
|
||||||
|
@ -507,9 +488,8 @@ func TestManifestFetch(t *testing.T) {
|
||||||
|
|
||||||
func TestManifestFetchByTag(t *testing.T) {
|
func TestManifestFetchByTag(t *testing.T) {
|
||||||
repo := "test.example.com/repo/by/tag"
|
repo := "test.example.com/repo/by/tag"
|
||||||
m1, _ := newRandomSchema1Manifest(repo, "latest", 6)
|
m1, _ := newRandomSchemaV1Manifest(repo, "latest", 6)
|
||||||
var m testutil.RequestResponseMap
|
var m testutil.RequestResponseMap
|
||||||
addPing(&m)
|
|
||||||
addTestManifest(repo, "latest", m1.Raw, &m)
|
addTestManifest(repo, "latest", m1.Raw, &m)
|
||||||
|
|
||||||
e, c := testServer(m)
|
e, c := testServer(m)
|
||||||
|
@ -540,10 +520,9 @@ func TestManifestFetchByTag(t *testing.T) {
|
||||||
|
|
||||||
func TestManifestDelete(t *testing.T) {
|
func TestManifestDelete(t *testing.T) {
|
||||||
repo := "test.example.com/repo/delete"
|
repo := "test.example.com/repo/delete"
|
||||||
_, dgst1 := newRandomSchema1Manifest(repo, "latest", 6)
|
_, dgst1 := newRandomSchemaV1Manifest(repo, "latest", 6)
|
||||||
_, dgst2 := newRandomSchema1Manifest(repo, "latest", 6)
|
_, dgst2 := newRandomSchemaV1Manifest(repo, "latest", 6)
|
||||||
var m testutil.RequestResponseMap
|
var m testutil.RequestResponseMap
|
||||||
addPing(&m)
|
|
||||||
m = append(m, testutil.RequestResponseMapping{
|
m = append(m, testutil.RequestResponseMapping{
|
||||||
Request: testutil.Request{
|
Request: testutil.Request{
|
||||||
Method: "DELETE",
|
Method: "DELETE",
|
||||||
|
@ -577,9 +556,8 @@ func TestManifestDelete(t *testing.T) {
|
||||||
|
|
||||||
func TestManifestPut(t *testing.T) {
|
func TestManifestPut(t *testing.T) {
|
||||||
repo := "test.example.com/repo/delete"
|
repo := "test.example.com/repo/delete"
|
||||||
m1, dgst := newRandomSchema1Manifest(repo, "other", 6)
|
m1, dgst := newRandomSchemaV1Manifest(repo, "other", 6)
|
||||||
var m testutil.RequestResponseMap
|
var m testutil.RequestResponseMap
|
||||||
addPing(&m)
|
|
||||||
m = append(m, testutil.RequestResponseMapping{
|
m = append(m, testutil.RequestResponseMapping{
|
||||||
Request: testutil.Request{
|
Request: testutil.Request{
|
||||||
Method: "PUT",
|
Method: "PUT",
|
||||||
|
@ -608,7 +586,7 @@ func TestManifestPut(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(dmcgowan): Check for error cases
|
// TODO(dmcgowan): Check for invalid input error
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestManifestTags(t *testing.T) {
|
func TestManifestTags(t *testing.T) {
|
||||||
|
@ -624,7 +602,6 @@ func TestManifestTags(t *testing.T) {
|
||||||
}
|
}
|
||||||
`))
|
`))
|
||||||
var m testutil.RequestResponseMap
|
var m testutil.RequestResponseMap
|
||||||
addPing(&m)
|
|
||||||
m = append(m, testutil.RequestResponseMapping{
|
m = append(m, testutil.RequestResponseMapping{
|
||||||
Request: testutil.Request{
|
Request: testutil.Request{
|
||||||
Method: "GET",
|
Method: "GET",
|
||||||
|
@ -661,3 +638,44 @@ func TestManifestTags(t *testing.T) {
|
||||||
|
|
||||||
// TODO(dmcgowan): Check for error cases
|
// TODO(dmcgowan): Check for error cases
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestManifestUnauthorized(t *testing.T) {
|
||||||
|
repo := "test.example.com/repo"
|
||||||
|
_, dgst := newRandomSchemaV1Manifest(repo, "latest", 6)
|
||||||
|
var m testutil.RequestResponseMap
|
||||||
|
|
||||||
|
m = append(m, testutil.RequestResponseMapping{
|
||||||
|
Request: testutil.Request{
|
||||||
|
Method: "GET",
|
||||||
|
Route: "/v2/" + repo + "/manifests/" + dgst.String(),
|
||||||
|
},
|
||||||
|
Response: testutil.Response{
|
||||||
|
StatusCode: http.StatusUnauthorized,
|
||||||
|
Body: []byte("<html>garbage</html>"),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
e, c := testServer(m)
|
||||||
|
defer c()
|
||||||
|
|
||||||
|
r, err := NewRepository(context.Background(), repo, e, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
ms := r.Manifests()
|
||||||
|
|
||||||
|
_, err = ms.Get(dgst)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("Expected error fetching manifest")
|
||||||
|
}
|
||||||
|
v2Err, ok := err.(*v2.Error)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("Unexpected error type: %#v", err)
|
||||||
|
}
|
||||||
|
if v2Err.Code != v2.ErrorCodeUnauthorized {
|
||||||
|
t.Fatalf("Unexpected error code: %s", v2Err.Code.String())
|
||||||
|
}
|
||||||
|
if expected := "401 Unauthorized"; v2Err.Message != expected {
|
||||||
|
t.Fatalf("Unexpected message value: %s, expected %s", v2Err.Message, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue