mirror of
https://github.com/go-gitea/gitea
synced 2025-07-22 18:28:37 +00:00
Fix nuget/conan/container packages upload bugs (#31967)
This commit is contained in:
@@ -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,11 +807,19 @@ 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)
|
||||
@@ -678,6 +830,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,11 +855,19 @@ 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)
|
||||
|
@@ -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)
|
||||
|
||||
|
@@ -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)
|
||||
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.UseTokenAuth {
|
||||
addNuGetAPIKeyHeader(req, token)
|
||||
}
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
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)
|
||||
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.UseTokenAuth {
|
||||
addNuGetAPIKeyHeader(req, token)
|
||||
}
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
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)
|
||||
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)
|
||||
|
||||
if c.expectedStatus != http.StatusOK {
|
||||
return
|
||||
}
|
||||
|
||||
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) {
|
||||
|
Reference in New Issue
Block a user