diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/integration/api_packages_conan_test.go | 170 | ||||
-rw-r--r-- | tests/integration/api_packages_container_test.go | 80 | ||||
-rw-r--r-- | tests/integration/api_packages_nuget_test.go | 203 |
3 files changed, 383 insertions, 70 deletions
diff --git a/tests/integration/api_packages_conan_test.go b/tests/integration/api_packages_conan_test.go index a25713f039..3055e57a2e 100644 --- a/tests/integration/api_packages_conan_test.go +++ b/tests/integration/api_packages_conan_test.go @@ -11,6 +11,7 @@ import ( "testing" "time" + auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/packages" conan_model "code.gitea.io/gitea/models/packages/conan" @@ -19,6 +20,7 @@ import ( conan_module "code.gitea.io/gitea/modules/packages/conan" "code.gitea.io/gitea/modules/setting" conan_router "code.gitea.io/gitea/routers/api/packages/conan" + package_service "code.gitea.io/gitea/services/packages" "code.gitea.io/gitea/tests" "github.com/stretchr/testify/assert" @@ -225,7 +227,7 @@ func TestPackageConan(t *testing.T) { token := "" - t.Run("Authenticate", func(t *testing.T) { + t.Run("UserName/Password Authenticate", func(t *testing.T) { defer tests.PrintCurrentTest(t)() req := NewRequest(t, "GET", fmt.Sprintf("%s/v1/users/authenticate", url)). @@ -234,6 +236,73 @@ func TestPackageConan(t *testing.T) { token = resp.Body.String() assert.NotEmpty(t, token) + + pkgMeta, err := package_service.ParseAuthorizationToken(token) + assert.NoError(t, err) + assert.Equal(t, user.ID, pkgMeta.UserID) + assert.Equal(t, auth_model.AccessTokenScopeAll, pkgMeta.Scope) + }) + + badToken := "" + t.Run("Token Scope Authentication", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + session := loginUser(t, user.Name) + + badToken = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadNotification) + + testCase := func(t *testing.T, scope auth_model.AccessTokenScope, expectedAuthStatusCode, expectedStatusCode int) { + t.Helper() + + token := getTokenForLoggedInUser(t, session, scope) + + req := NewRequest(t, "GET", fmt.Sprintf("%s/v1/users/authenticate", url)). + AddTokenAuth(token) + resp := MakeRequest(t, req, expectedAuthStatusCode) + if expectedAuthStatusCode != http.StatusOK { + return + } + + body := resp.Body.String() + assert.NotEmpty(t, body) + + pkgMeta, err := package_service.ParseAuthorizationToken(body) + assert.NoError(t, err) + assert.Equal(t, user.ID, pkgMeta.UserID) + assert.Equal(t, scope, pkgMeta.Scope) + + recipeURL := fmt.Sprintf("%s/v1/conans/%s/%s/%s/%s", url, "TestScope", version1, "testing", channel1) + + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("%s/upload_urls", recipeURL), map[string]int64{ + conanfileName: 64, + "removed.txt": 0, + }).AddTokenAuth(token) + MakeRequest(t, req, expectedStatusCode) + } + + t.Run("No Package permission", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + testCase(t, auth_model.AccessTokenScopeReadNotification, http.StatusUnauthorized, http.StatusForbidden) + }) + + t.Run("Package Read permission", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + testCase(t, auth_model.AccessTokenScopeReadPackage, http.StatusOK, http.StatusUnauthorized) + }) + + t.Run("Package Write permission", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + testCase(t, auth_model.AccessTokenScopeWritePackage, http.StatusOK, http.StatusOK) + }) + + t.Run("All permission", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + testCase(t, auth_model.AccessTokenScopeAll, http.StatusOK, http.StatusOK) + }) }) t.Run("CheckCredentials", func(t *testing.T) { @@ -431,6 +500,11 @@ func TestPackageConan(t *testing.T) { req := NewRequestWithJSON(t, "POST", fmt.Sprintf("%s/v1/conans/%s/%s/%s/%s/packages/delete", url, name, version1, user1, c.Channel), map[string][]string{ "package_ids": c.References, + }).AddTokenAuth(badToken) + MakeRequest(t, req, http.StatusUnauthorized) + + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("%s/v1/conans/%s/%s/%s/%s/packages/delete", url, name, version1, user1, c.Channel), map[string][]string{ + "package_ids": c.References, }).AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) @@ -457,6 +531,10 @@ func TestPackageConan(t *testing.T) { assert.NotEmpty(t, revisions) req := NewRequest(t, "DELETE", fmt.Sprintf("%s/v1/conans/%s/%s/%s/%s", url, name, version1, user1, c.Channel)). + AddTokenAuth(badToken) + MakeRequest(t, req, http.StatusUnauthorized) + + req = NewRequest(t, "DELETE", fmt.Sprintf("%s/v1/conans/%s/%s/%s/%s", url, name, version1, user1, c.Channel)). AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) @@ -480,7 +558,7 @@ func TestPackageConan(t *testing.T) { token := "" - t.Run("Authenticate", func(t *testing.T) { + t.Run("UserName/Password Authenticate", func(t *testing.T) { defer tests.PrintCurrentTest(t)() req := NewRequest(t, "GET", fmt.Sprintf("%s/v2/users/authenticate", url)). @@ -490,9 +568,75 @@ func TestPackageConan(t *testing.T) { body := resp.Body.String() assert.NotEmpty(t, body) + pkgMeta, err := package_service.ParseAuthorizationToken(body) + assert.NoError(t, err) + assert.Equal(t, user.ID, pkgMeta.UserID) + assert.Equal(t, auth_model.AccessTokenScopeAll, pkgMeta.Scope) + token = fmt.Sprintf("Bearer %s", body) }) + badToken := "" + + t.Run("Token Scope Authentication", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + session := loginUser(t, user.Name) + + badToken = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadNotification) + + testCase := func(t *testing.T, scope auth_model.AccessTokenScope, expectedAuthStatusCode, expectedStatusCode int) { + t.Helper() + + token := getTokenForLoggedInUser(t, session, scope) + + req := NewRequest(t, "GET", fmt.Sprintf("%s/v2/users/authenticate", url)). + AddTokenAuth(token) + resp := MakeRequest(t, req, expectedAuthStatusCode) + if expectedAuthStatusCode != http.StatusOK { + return + } + + body := resp.Body.String() + assert.NotEmpty(t, body) + + pkgMeta, err := package_service.ParseAuthorizationToken(body) + assert.NoError(t, err) + assert.Equal(t, user.ID, pkgMeta.UserID) + assert.Equal(t, scope, pkgMeta.Scope) + + recipeURL := fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s", url, "TestScope", version1, "testing", channel1, revision1) + + req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/files/%s", recipeURL, conanfileName), strings.NewReader("Demo Conan file")). + AddTokenAuth(token) + MakeRequest(t, req, expectedStatusCode) + } + + t.Run("No Package permission", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + testCase(t, auth_model.AccessTokenScopeReadNotification, http.StatusUnauthorized, http.StatusUnauthorized) + }) + + t.Run("Package Read permission", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + testCase(t, auth_model.AccessTokenScopeReadPackage, http.StatusOK, http.StatusUnauthorized) + }) + + t.Run("Package Write permission", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + testCase(t, auth_model.AccessTokenScopeWritePackage, http.StatusOK, http.StatusCreated) + }) + + t.Run("All permission", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + testCase(t, auth_model.AccessTokenScopeAll, http.StatusOK, http.StatusCreated) + }) + }) + t.Run("CheckCredentials", func(t *testing.T) { defer tests.PrintCurrentTest(t)() @@ -511,7 +655,7 @@ func TestPackageConan(t *testing.T) { pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeConan) assert.NoError(t, err) - assert.Len(t, pvs, 2) + assert.Len(t, pvs, 3) }) }) @@ -663,12 +807,20 @@ func TestPackageConan(t *testing.T) { checkPackageRevisionCount(2) req := NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s/packages/%s/revisions/%s", url, name, version1, user1, channel1, revision1, conanPackageReference, revision1)). + AddTokenAuth(badToken) + MakeRequest(t, req, http.StatusUnauthorized) + + req = NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s/packages/%s/revisions/%s", url, name, version1, user1, channel1, revision1, conanPackageReference, revision1)). AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) checkPackageRevisionCount(1) req = NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s/packages/%s", url, name, version1, user1, channel1, revision1, conanPackageReference)). + AddTokenAuth(badToken) + MakeRequest(t, req, http.StatusUnauthorized) + + req = NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s/packages/%s", url, name, version1, user1, channel1, revision1, conanPackageReference)). AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) @@ -679,6 +831,10 @@ func TestPackageConan(t *testing.T) { checkPackageReferenceCount(1) req = NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s/packages", url, name, version1, user1, channel1, revision2)). + AddTokenAuth(badToken) + MakeRequest(t, req, http.StatusUnauthorized) + + req = NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s/packages", url, name, version1, user1, channel1, revision2)). AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) @@ -699,12 +855,20 @@ func TestPackageConan(t *testing.T) { checkRecipeRevisionCount(2) req := NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s", url, name, version1, user1, channel1, revision1)). + AddTokenAuth(badToken) + MakeRequest(t, req, http.StatusUnauthorized) + + req = NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s", url, name, version1, user1, channel1, revision1)). AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) checkRecipeRevisionCount(1) req = NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s", url, name, version1, user1, channel1)). + AddTokenAuth(badToken) + MakeRequest(t, req, http.StatusUnauthorized) + + req = NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s", url, name, version1, user1, channel1)). AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) diff --git a/tests/integration/api_packages_container_test.go b/tests/integration/api_packages_container_test.go index fcd1cc529f..409e7513a6 100644 --- a/tests/integration/api_packages_container_test.go +++ b/tests/integration/api_packages_container_test.go @@ -23,6 +23,7 @@ import ( "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/test" + package_service "code.gitea.io/gitea/services/packages" "code.gitea.io/gitea/tests" oci "github.com/opencontainers/image-spec/specs-go/v1" @@ -78,6 +79,8 @@ func TestPackageContainer(t *testing.T) { anonymousToken := "" userToken := "" + readToken := "" + badToken := "" t.Run("Authenticate", func(t *testing.T) { type TokenResponse struct { @@ -123,7 +126,7 @@ func TestPackageContainer(t *testing.T) { assert.Equal(t, `Bearer realm="https://domain:8443/v2/token",service="container_registry",scope="*"`, resp.Header().Get("WWW-Authenticate")) }) - t.Run("User", func(t *testing.T) { + t.Run("UserName/Password", func(t *testing.T) { defer tests.PrintCurrentTest(t)() req := NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)) @@ -139,6 +142,10 @@ func TestPackageContainer(t *testing.T) { DecodeJSON(t, resp, &tokenResponse) assert.NotEmpty(t, tokenResponse.Token) + pkgMeta, err := package_service.ParseAuthorizationToken(tokenResponse.Token) + assert.NoError(t, err) + assert.Equal(t, user.ID, pkgMeta.UserID) + assert.Equal(t, auth_model.AccessTokenScopeAll, pkgMeta.Scope) userToken = fmt.Sprintf("Bearer %s", tokenResponse.Token) @@ -146,6 +153,52 @@ func TestPackageContainer(t *testing.T) { AddTokenAuth(userToken) MakeRequest(t, req, http.StatusOK) }) + + // Token that should enforce the read scope. + t.Run("AccessToken", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + session := loginUser(t, user.Name) + + readToken = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadPackage) + req := NewRequest(t, "GET", fmt.Sprintf("%sv2/token", setting.AppURL)) + req.Request.SetBasicAuth(user.Name, readToken) + resp := MakeRequest(t, req, http.StatusOK) + tokenResponse := &TokenResponse{} + DecodeJSON(t, resp, &tokenResponse) + + readToken = fmt.Sprintf("Bearer %s", tokenResponse.Token) + + badToken = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadNotification) + req = NewRequest(t, "GET", fmt.Sprintf("%sv2/token", setting.AppURL)) + req.Request.SetBasicAuth(user.Name, badToken) + MakeRequest(t, req, http.StatusUnauthorized) + + testCase := func(scope auth_model.AccessTokenScope, expectedAuthStatus, expectedStatus int) { + token := getTokenForLoggedInUser(t, session, scope) + + req := NewRequest(t, "GET", fmt.Sprintf("%sv2/token", setting.AppURL)) + req.SetBasicAuth(user.Name, token) + + resp := MakeRequest(t, req, expectedAuthStatus) + if expectedAuthStatus != http.StatusOK { + return + } + + tokenResponse := &TokenResponse{} + DecodeJSON(t, resp, &tokenResponse) + + assert.NotEmpty(t, tokenResponse.Token) + + req = NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)). + AddTokenAuth(fmt.Sprintf("Bearer %s", tokenResponse.Token)) + MakeRequest(t, req, expectedStatus) + } + testCase(auth_model.AccessTokenScopeReadPackage, http.StatusOK, http.StatusOK) + testCase(auth_model.AccessTokenScopeAll, http.StatusOK, http.StatusOK) + testCase(auth_model.AccessTokenScopeReadNotification, http.StatusUnauthorized, http.StatusUnauthorized) + testCase(auth_model.AccessTokenScopeWritePackage, http.StatusOK, http.StatusOK) + }) }) t.Run("DetermineSupport", func(t *testing.T) { @@ -155,6 +208,15 @@ func TestPackageContainer(t *testing.T) { AddTokenAuth(userToken) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, "registry/2.0", resp.Header().Get("Docker-Distribution-Api-Version")) + + req = NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)). + AddTokenAuth(readToken) + resp = MakeRequest(t, req, http.StatusOK) + assert.Equal(t, "registry/2.0", resp.Header().Get("Docker-Distribution-Api-Version")) + + req = NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)). + AddTokenAuth(badToken) + MakeRequest(t, req, http.StatusUnauthorized) }) for _, image := range images { @@ -168,6 +230,14 @@ func TestPackageContainer(t *testing.T) { AddTokenAuth(anonymousToken) MakeRequest(t, req, http.StatusUnauthorized) + req = NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads", url)). + AddTokenAuth(readToken) + MakeRequest(t, req, http.StatusUnauthorized) + + req = NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads", url)). + AddTokenAuth(badToken) + MakeRequest(t, req, http.StatusUnauthorized) + req = NewRequestWithBody(t, "POST", fmt.Sprintf("%s/blobs/uploads?digest=%s", url, unknownDigest), bytes.NewReader(blobContent)). AddTokenAuth(userToken) MakeRequest(t, req, http.StatusBadRequest) @@ -195,6 +265,14 @@ func TestPackageContainer(t *testing.T) { defer tests.PrintCurrentTest(t)() req := NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads", url)). + AddTokenAuth(readToken) + MakeRequest(t, req, http.StatusUnauthorized) + + req = NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads", url)). + AddTokenAuth(badToken) + MakeRequest(t, req, http.StatusUnauthorized) + + req = NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads", url)). AddTokenAuth(userToken) resp := MakeRequest(t, req, http.StatusAccepted) diff --git a/tests/integration/api_packages_nuget_test.go b/tests/integration/api_packages_nuget_test.go index 630b4de3f9..622c2c4394 100644 --- a/tests/integration/api_packages_nuget_test.go +++ b/tests/integration/api_packages_nuget_test.go @@ -26,6 +26,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/packages/nuget" + packageService "code.gitea.io/gitea/services/packages" "code.gitea.io/gitea/tests" "github.com/stretchr/testify/assert" @@ -81,7 +82,9 @@ func TestPackageNuGet(t *testing.T) { } user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - token := getUserToken(t, user.Name, auth_model.AccessTokenScopeWritePackage) + writeToken := getUserToken(t, user.Name, auth_model.AccessTokenScopeWritePackage) + readToken := getUserToken(t, user.Name, auth_model.AccessTokenScopeReadPackage) + badToken := getUserToken(t, user.Name, auth_model.AccessTokenScopeReadNotification) packageName := "test.package" packageVersion := "1.0.3" @@ -127,34 +130,44 @@ func TestPackageNuGet(t *testing.T) { privateUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{Visibility: structs.VisibleTypePrivate}) cases := []struct { - Owner string - UseBasicAuth bool - UseTokenAuth bool + Owner string + UseBasicAuth bool + token string + expectedStatus int }{ - {privateUser.Name, false, false}, - {privateUser.Name, true, false}, - {privateUser.Name, false, true}, - {user.Name, false, false}, - {user.Name, true, false}, - {user.Name, false, true}, + {privateUser.Name, false, "", http.StatusOK}, + {privateUser.Name, true, "", http.StatusOK}, + {privateUser.Name, false, writeToken, http.StatusOK}, + {privateUser.Name, false, readToken, http.StatusOK}, + {privateUser.Name, false, badToken, http.StatusOK}, + {user.Name, false, "", http.StatusOK}, + {user.Name, true, "", http.StatusOK}, + {user.Name, false, writeToken, http.StatusOK}, + {user.Name, false, readToken, http.StatusOK}, + {user.Name, false, badToken, http.StatusOK}, } for _, c := range cases { - url := fmt.Sprintf("/api/packages/%s/nuget", c.Owner) - - req := NewRequest(t, "GET", url) - if c.UseBasicAuth { - req.AddBasicAuth(user.Name) - } else if c.UseTokenAuth { - addNuGetAPIKeyHeader(req, token) - } - resp := MakeRequest(t, req, http.StatusOK) + t.Run(c.Owner, func(t *testing.T) { + url := fmt.Sprintf("/api/packages/%s/nuget", c.Owner) + + req := NewRequest(t, "GET", url) + if c.UseBasicAuth { + req.AddBasicAuth(user.Name) + } else if c.token != "" { + addNuGetAPIKeyHeader(req, c.token) + } + resp := MakeRequest(t, req, c.expectedStatus) + if c.expectedStatus != http.StatusOK { + return + } - var result nuget.ServiceIndexResponseV2 - decodeXML(t, resp, &result) + var result nuget.ServiceIndexResponseV2 + decodeXML(t, resp, &result) - assert.Equal(t, setting.AppURL+url[1:], result.Base) - assert.Equal(t, "Packages", result.Workspace.Collection.Href) + assert.Equal(t, setting.AppURL+url[1:], result.Base) + assert.Equal(t, "Packages", result.Workspace.Collection.Href) + }) } }) @@ -164,56 +177,67 @@ func TestPackageNuGet(t *testing.T) { privateUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{Visibility: structs.VisibleTypePrivate}) cases := []struct { - Owner string - UseBasicAuth bool - UseTokenAuth bool + Owner string + UseBasicAuth bool + token string + expectedStatus int }{ - {privateUser.Name, false, false}, - {privateUser.Name, true, false}, - {privateUser.Name, false, true}, - {user.Name, false, false}, - {user.Name, true, false}, - {user.Name, false, true}, + {privateUser.Name, false, "", http.StatusOK}, + {privateUser.Name, true, "", http.StatusOK}, + {privateUser.Name, false, writeToken, http.StatusOK}, + {privateUser.Name, false, readToken, http.StatusOK}, + {privateUser.Name, false, badToken, http.StatusOK}, + {user.Name, false, "", http.StatusOK}, + {user.Name, true, "", http.StatusOK}, + {user.Name, false, writeToken, http.StatusOK}, + {user.Name, false, readToken, http.StatusOK}, + {user.Name, false, badToken, http.StatusOK}, } for _, c := range cases { - url := fmt.Sprintf("/api/packages/%s/nuget", c.Owner) - - req := NewRequest(t, "GET", fmt.Sprintf("%s/index.json", url)) - if c.UseBasicAuth { - req.AddBasicAuth(user.Name) - } else if c.UseTokenAuth { - addNuGetAPIKeyHeader(req, token) - } - resp := MakeRequest(t, req, http.StatusOK) + t.Run(c.Owner, func(t *testing.T) { + url := fmt.Sprintf("/api/packages/%s/nuget", c.Owner) + + req := NewRequest(t, "GET", fmt.Sprintf("%s/index.json", url)) + if c.UseBasicAuth { + req.AddBasicAuth(user.Name) + } else if c.token != "" { + addNuGetAPIKeyHeader(req, c.token) + } + resp := MakeRequest(t, req, c.expectedStatus) - var result nuget.ServiceIndexResponseV3 - DecodeJSON(t, resp, &result) + if c.expectedStatus != http.StatusOK { + return + } - assert.Equal(t, "3.0.0", result.Version) - assert.NotEmpty(t, result.Resources) - - root := setting.AppURL + url[1:] - for _, r := range result.Resources { - switch r.Type { - case "SearchQueryService": - fallthrough - case "SearchQueryService/3.0.0-beta": - fallthrough - case "SearchQueryService/3.0.0-rc": - assert.Equal(t, root+"/query", r.ID) - case "RegistrationsBaseUrl": - fallthrough - case "RegistrationsBaseUrl/3.0.0-beta": - fallthrough - case "RegistrationsBaseUrl/3.0.0-rc": - assert.Equal(t, root+"/registration", r.ID) - case "PackageBaseAddress/3.0.0": - assert.Equal(t, root+"/package", r.ID) - case "PackagePublish/2.0.0": - assert.Equal(t, root, r.ID) + var result nuget.ServiceIndexResponseV3 + DecodeJSON(t, resp, &result) + + assert.Equal(t, "3.0.0", result.Version) + assert.NotEmpty(t, result.Resources) + + root := setting.AppURL + url[1:] + for _, r := range result.Resources { + switch r.Type { + case "SearchQueryService": + fallthrough + case "SearchQueryService/3.0.0-beta": + fallthrough + case "SearchQueryService/3.0.0-rc": + assert.Equal(t, root+"/query", r.ID) + case "RegistrationsBaseUrl": + fallthrough + case "RegistrationsBaseUrl/3.0.0-beta": + fallthrough + case "RegistrationsBaseUrl/3.0.0-rc": + assert.Equal(t, root+"/registration", r.ID) + case "PackageBaseAddress/3.0.0": + assert.Equal(t, root+"/package", r.ID) + case "PackagePublish/2.0.0": + assert.Equal(t, root, r.ID) + } } - } + }) } }) }) @@ -222,6 +246,7 @@ func TestPackageNuGet(t *testing.T) { t.Run("DependencyPackage", func(t *testing.T) { defer tests.PrintCurrentTest(t)() + // create with username/password req := NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) @@ -258,6 +283,52 @@ func TestPackageNuGet(t *testing.T) { req = NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusConflict) + + // delete the package + assert.NoError(t, packageService.DeletePackageVersionAndReferences(db.DefaultContext, pvs[0])) + + // create failure with token without write access + req = NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)). + AddTokenAuth(readToken) + MakeRequest(t, req, http.StatusUnauthorized) + + // create with token + req = NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)). + AddTokenAuth(writeToken) + MakeRequest(t, req, http.StatusCreated) + + pvs, err = packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNuGet) + assert.NoError(t, err) + assert.Len(t, pvs, 1, "Should have one version") + + pd, err = packages.GetPackageDescriptor(db.DefaultContext, pvs[0]) + assert.NoError(t, err) + assert.NotNil(t, pd.SemVer) + assert.IsType(t, &nuget_module.Metadata{}, pd.Metadata) + assert.Equal(t, packageName, pd.Package.Name) + assert.Equal(t, packageVersion, pd.Version.Version) + + pfs, err = packages.GetFilesByVersionID(db.DefaultContext, pvs[0].ID) + assert.NoError(t, err) + assert.Len(t, pfs, 2, "Should have 2 files: nuget and nuspec") + for _, pf := range pfs { + switch pf.Name { + case fmt.Sprintf("%s.%s.nupkg", packageName, packageVersion): + assert.True(t, pf.IsLead) + + pb, err := packages.GetBlobByID(db.DefaultContext, pf.BlobID) + assert.NoError(t, err) + assert.Equal(t, int64(len(content)), pb.Size) + case fmt.Sprintf("%s.nuspec", packageName): + assert.False(t, pf.IsLead) + default: + assert.Fail(t, "unexpected filename: %v", pf.Name) + } + } + + req = NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)). + AddBasicAuth(user.Name) + MakeRequest(t, req, http.StatusConflict) }) t.Run("SymbolPackage", func(t *testing.T) { |