diff options
author | Anthony Wang | 2023-02-11 23:52:36 +0000 |
---|---|---|
committer | Anthony Wang | 2023-02-11 23:52:36 +0000 |
commit | e61e9fba59d6e6f0eb86869e07d9d52867384132 (patch) | |
tree | c6072319ab1b1429eb4132c9797ab4c6d6ffd760 /tests | |
parent | 1a54d5e8970f2ff6ffe3aeaa19b3917f5e7dc9fd (diff) | |
parent | 1cb8d14bf71e0b8637c9eaa10808b4fd05139f45 (diff) |
Merge remote-tracking branch 'origin/main' into forgejo-federation
Diffstat (limited to 'tests')
-rw-r--r-- | tests/integration/api_packages_cargo_test.go | 341 | ||||
-rw-r--r-- | tests/integration/api_packages_chef_test.go | 560 | ||||
-rw-r--r-- | tests/integration/api_packages_container_test.go | 16 | ||||
-rw-r--r-- | tests/integration/api_packages_test.go | 5 | ||||
-rw-r--r-- | tests/integration/auth_ldap_test.go | 71 |
5 files changed, 935 insertions, 58 deletions
diff --git a/tests/integration/api_packages_cargo_test.go b/tests/integration/api_packages_cargo_test.go new file mode 100644 index 000000000..0c542eaf1 --- /dev/null +++ b/tests/integration/api_packages_cargo_test.go @@ -0,0 +1,341 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package integration + +import ( + "bytes" + "encoding/binary" + "fmt" + "io" + "net/http" + neturl "net/url" + "testing" + + "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/packages" + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/models/unittest" + user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/json" + cargo_module "code.gitea.io/gitea/modules/packages/cargo" + "code.gitea.io/gitea/modules/setting" + cargo_router "code.gitea.io/gitea/routers/api/packages/cargo" + cargo_service "code.gitea.io/gitea/services/packages/cargo" + "code.gitea.io/gitea/tests" + + "github.com/stretchr/testify/assert" +) + +func TestPackageCargo(t *testing.T) { + onGiteaRun(t, testPackageCargo) +} + +func testPackageCargo(t *testing.T, _ *neturl.URL) { + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + + packageName := "cargo-package" + packageVersion := "1.0.3" + packageDescription := "Package Description" + packageAuthor := "KN4CK3R" + packageHomepage := "https://gitea.io/" + packageLicense := "MIT" + + createPackage := func(name, version string) io.Reader { + metadata := `{ + "name":"` + name + `", + "vers":"` + version + `", + "description":"` + packageDescription + `", + "authors": ["` + packageAuthor + `"], + "deps":[ + { + "name":"dep", + "version_req":"1.0", + "registry": "https://gitea.io/user/_cargo-index", + "kind": "normal", + "default_features": true + } + ], + "homepage":"` + packageHomepage + `", + "license":"` + packageLicense + `" +}` + + var buf bytes.Buffer + binary.Write(&buf, binary.LittleEndian, uint32(len(metadata))) + buf.WriteString(metadata) + binary.Write(&buf, binary.LittleEndian, uint32(4)) + buf.WriteString("test") + return &buf + } + + err := cargo_service.InitializeIndexRepository(db.DefaultContext, user, user) + assert.NoError(t, err) + + repo, err := repo_model.GetRepositoryByOwnerAndName(db.DefaultContext, user.Name, cargo_service.IndexRepositoryName) + assert.NotNil(t, repo) + assert.NoError(t, err) + + readGitContent := func(t *testing.T, path string) string { + gitRepo, err := git.OpenRepository(db.DefaultContext, repo.RepoPath()) + assert.NoError(t, err) + defer gitRepo.Close() + + commit, err := gitRepo.GetBranchCommit(repo.DefaultBranch) + assert.NoError(t, err) + + blob, err := commit.GetBlobByPath(path) + assert.NoError(t, err) + + content, err := blob.GetBlobContent() + assert.NoError(t, err) + + return content + } + + root := fmt.Sprintf("%sapi/packages/%s/cargo", setting.AppURL, user.Name) + url := fmt.Sprintf("%s/api/v1/crates", root) + + t.Run("Index", func(t *testing.T) { + t.Run("Config", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + content := readGitContent(t, cargo_service.ConfigFileName) + + var config cargo_service.Config + err := json.Unmarshal([]byte(content), &config) + assert.NoError(t, err) + + assert.Equal(t, url, config.DownloadURL) + assert.Equal(t, root, config.APIURL) + }) + }) + + t.Run("Upload", func(t *testing.T) { + t.Run("InvalidNameOrVersion", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + content := createPackage("0test", "1.0.0") + + req := NewRequestWithBody(t, "PUT", url+"/new", content) + req = AddBasicAuthHeader(req, user.Name) + resp := MakeRequest(t, req, http.StatusBadRequest) + + var status cargo_router.StatusResponse + DecodeJSON(t, resp, &status) + assert.False(t, status.OK) + + content = createPackage("test", "-1.0.0") + + req = NewRequestWithBody(t, "PUT", url+"/new", content) + req = AddBasicAuthHeader(req, user.Name) + resp = MakeRequest(t, req, http.StatusBadRequest) + + DecodeJSON(t, resp, &status) + assert.False(t, status.OK) + }) + + t.Run("InvalidContent", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + metadata := `{"name":"test","vers":"1.0.0"}` + + var buf bytes.Buffer + binary.Write(&buf, binary.LittleEndian, uint32(len(metadata))) + buf.WriteString(metadata) + binary.Write(&buf, binary.LittleEndian, uint32(4)) + buf.WriteString("te") + + req := NewRequestWithBody(t, "PUT", url+"/new", &buf) + req = AddBasicAuthHeader(req, user.Name) + MakeRequest(t, req, http.StatusBadRequest) + }) + + t.Run("Valid", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequestWithBody(t, "PUT", url+"/new", createPackage(packageName, packageVersion)) + MakeRequest(t, req, http.StatusUnauthorized) + + req = NewRequestWithBody(t, "PUT", url+"/new", createPackage(packageName, packageVersion)) + req = AddBasicAuthHeader(req, user.Name) + resp := MakeRequest(t, req, http.StatusOK) + + var status cargo_router.StatusResponse + DecodeJSON(t, resp, &status) + assert.True(t, status.OK) + + pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeCargo) + assert.NoError(t, err) + assert.Len(t, pvs, 1) + + pd, err := packages.GetPackageDescriptor(db.DefaultContext, pvs[0]) + assert.NoError(t, err) + assert.NotNil(t, pd.SemVer) + assert.IsType(t, &cargo_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, 1) + assert.Equal(t, fmt.Sprintf("%s-%s.crate", packageName, packageVersion), pfs[0].Name) + assert.True(t, pfs[0].IsLead) + + pb, err := packages.GetBlobByID(db.DefaultContext, pfs[0].BlobID) + assert.NoError(t, err) + assert.EqualValues(t, 4, pb.Size) + + req = NewRequestWithBody(t, "PUT", url+"/new", createPackage(packageName, packageVersion)) + req = AddBasicAuthHeader(req, user.Name) + MakeRequest(t, req, http.StatusConflict) + + t.Run("Index", func(t *testing.T) { + t.Run("Entry", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + content := readGitContent(t, cargo_service.BuildPackagePath(packageName)) + + var entry cargo_service.IndexVersionEntry + err := json.Unmarshal([]byte(content), &entry) + assert.NoError(t, err) + + assert.Equal(t, packageName, entry.Name) + assert.Equal(t, packageVersion, entry.Version) + assert.Equal(t, pb.HashSHA256, entry.FileChecksum) + assert.False(t, entry.Yanked) + assert.Len(t, entry.Dependencies, 1) + dep := entry.Dependencies[0] + assert.Equal(t, "dep", dep.Name) + assert.Equal(t, "1.0", dep.Req) + assert.Equal(t, "normal", dep.Kind) + assert.True(t, dep.DefaultFeatures) + assert.Empty(t, dep.Features) + assert.False(t, dep.Optional) + assert.Nil(t, dep.Target) + assert.NotNil(t, dep.Registry) + assert.Equal(t, "https://gitea.io/user/_cargo-index", *dep.Registry) + assert.Nil(t, dep.Package) + }) + + t.Run("Rebuild", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + err := cargo_service.RebuildIndex(db.DefaultContext, user, user) + assert.NoError(t, err) + + _ = readGitContent(t, cargo_service.BuildPackagePath(packageName)) + }) + }) + }) + }) + + t.Run("Download", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + pv, err := packages.GetVersionByNameAndVersion(db.DefaultContext, user.ID, packages.TypeCargo, packageName, packageVersion) + assert.NoError(t, err) + assert.EqualValues(t, 0, pv.DownloadCount) + + pfs, err := packages.GetFilesByVersionID(db.DefaultContext, pv.ID) + assert.NoError(t, err) + assert.Len(t, pfs, 1) + + req := NewRequest(t, "GET", fmt.Sprintf("%s/%s/%s/download", url, neturl.PathEscape(packageName), neturl.PathEscape(pv.Version))) + req = AddBasicAuthHeader(req, user.Name) + resp := MakeRequest(t, req, http.StatusOK) + + assert.Equal(t, "test", resp.Body.String()) + + pv, err = packages.GetVersionByNameAndVersion(db.DefaultContext, user.ID, packages.TypeCargo, packageName, packageVersion) + assert.NoError(t, err) + assert.EqualValues(t, 1, pv.DownloadCount) + }) + + t.Run("Search", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + cases := []struct { + Query string + Page int + PerPage int + ExpectedTotal int64 + ExpectedResults int + }{ + {"", 0, 0, 1, 1}, + {"", 1, 10, 1, 1}, + {"cargo", 1, 0, 1, 1}, + {"cargo", 1, 10, 1, 1}, + {"cargo", 2, 10, 1, 0}, + {"test", 0, 10, 0, 0}, + } + + for i, c := range cases { + req := NewRequest(t, "GET", fmt.Sprintf("%s?q=%s&page=%d&per_page=%d", url, c.Query, c.Page, c.PerPage)) + req = AddBasicAuthHeader(req, user.Name) + resp := MakeRequest(t, req, http.StatusOK) + + var result cargo_router.SearchResult + DecodeJSON(t, resp, &result) + + assert.Equal(t, c.ExpectedTotal, result.Meta.Total, "case %d: unexpected total hits", i) + assert.Len(t, result.Crates, c.ExpectedResults, "case %d: unexpected result count", i) + } + }) + + t.Run("Yank", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "DELETE", fmt.Sprintf("%s/%s/%s/yank", url, neturl.PathEscape(packageName), neturl.PathEscape(packageVersion))) + req = AddBasicAuthHeader(req, user.Name) + resp := MakeRequest(t, req, http.StatusOK) + + var status cargo_router.StatusResponse + DecodeJSON(t, resp, &status) + assert.True(t, status.OK) + + content := readGitContent(t, cargo_service.BuildPackagePath(packageName)) + + var entry cargo_service.IndexVersionEntry + err := json.Unmarshal([]byte(content), &entry) + assert.NoError(t, err) + + assert.True(t, entry.Yanked) + }) + + t.Run("Unyank", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "PUT", fmt.Sprintf("%s/%s/%s/unyank", url, neturl.PathEscape(packageName), neturl.PathEscape(packageVersion))) + req = AddBasicAuthHeader(req, user.Name) + resp := MakeRequest(t, req, http.StatusOK) + + var status cargo_router.StatusResponse + DecodeJSON(t, resp, &status) + assert.True(t, status.OK) + + content := readGitContent(t, cargo_service.BuildPackagePath(packageName)) + + var entry cargo_service.IndexVersionEntry + err := json.Unmarshal([]byte(content), &entry) + assert.NoError(t, err) + + assert.False(t, entry.Yanked) + }) + + t.Run("ListOwners", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "GET", fmt.Sprintf("%s/%s/owners", url, neturl.PathEscape(packageName))) + resp := MakeRequest(t, req, http.StatusOK) + + var owners cargo_router.Owners + DecodeJSON(t, resp, &owners) + + assert.Len(t, owners.Users, 1) + assert.Equal(t, user.ID, owners.Users[0].ID) + assert.Equal(t, user.Name, owners.Users[0].Login) + assert.Equal(t, user.DisplayName(), owners.Users[0].Name) + }) +} diff --git a/tests/integration/api_packages_chef_test.go b/tests/integration/api_packages_chef_test.go new file mode 100644 index 000000000..14baddca9 --- /dev/null +++ b/tests/integration/api_packages_chef_test.go @@ -0,0 +1,560 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package integration + +import ( + "archive/tar" + "bytes" + "compress/gzip" + "crypto" + "crypto/rand" + "crypto/rsa" + "crypto/sha1" + "crypto/sha256" + "crypto/x509" + "encoding/base64" + "encoding/pem" + "fmt" + "hash" + "math/big" + "mime/multipart" + "net/http" + "path" + "strings" + "testing" + "time" + + "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/packages" + "code.gitea.io/gitea/models/unittest" + user_model "code.gitea.io/gitea/models/user" + chef_module "code.gitea.io/gitea/modules/packages/chef" + "code.gitea.io/gitea/modules/setting" + chef_router "code.gitea.io/gitea/routers/api/packages/chef" + "code.gitea.io/gitea/tests" + + "github.com/stretchr/testify/assert" +) + +func TestPackageChef(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + + privPem := `-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAtWp2PZz4TSU5A6ixw41HdbfBuGJwPuTtrsdoUf0DQ0/DJBNP +qOCBAgEu6ZdUqIbWJ5Da+nevjtncy5hENdi6XrXjyzlUxghMuXjE5SeLGpgfQvkq +bTkYaFpMe8PTzNeze3fei8+Eu6mzeb6g1GrqXznuPIc7bNss0w5iX9RiBM9dWPuX +onx9xSEy0LYqJm7yXmshNe1aRwkjG/y5C26BzBFnMKp9YRTua0DO1WqLNhcaRnda +lIFYouDNVTbwxSlYL16bZVoebqzZvLGrPvZJkPuCu6vH9brvOuYo0q8hLVNkBeXc +imRpsDjLhQYzEJjoMTbaiVGnjBky+PWNiofJnwIDAQABAoIBAQCotF1KxLt/ejr/ +9ROCh9JJXV3v6tL5GgkSPOv9Oq2bHgSZer/cixJNW+5VWd5nbiSe3K1WuJBw5pbW +Wj4sWORPiRRR+3mjQzqeS/nGJDTOwWJo9K8IrUzOVhLEEYLX/ksxaXJyT8PehFyb +vbNwdhCIB6ZNcXDItTWE+95twWJ5lxAIj2dNwZZni3UkwwjYnCnqFtvHCKOg0NH2 +RjQcFYmu3fncNeqLezUSdVyRyXxSCHsUdlYeX/e44StCnXdrmLUHlb2P27ZVdPGh +SW7qTUPpmJKekYiRPOpTLj+ZKXIsANkyWO+7dVtZLBm5bIyAsmp0W/DmK+wRsejj +alFbIsh5AoGBANJr7HSG695wkfn+kvu/V8qHbt+KDv4WjWHjGRsUqvxoHOUNkQmW +vZWdk4gjHYn1l+QHWmoOE3AgyqtCZ4bFILkZPLN/F8Mh3+r4B0Ac4biJJt7XGMNQ +Nv4wsk7TR7CCARsjO7GP1PT60hpjMvYmc1E36gNM7QIZE9jBE+L8eWYtAoGBANy2 +JOAWf+QeBlur6o9feH76cEmpQzUUq4Lj9mmnXgIirSsFoBnDb8VA6Ws+ltL9U9H2 +vaCoaTyi9twW9zWj+Ywg2mVR5nlSAPfdlTWS1GLUbDotlj5apc/lvnGuNlWzN+I4 +Tu64hhgBXqGvRZ0o7HzFodqRAkpVXp6CQCqBM7p7AoGAIgO0K3oL8t87ma/fTra1 +mFWgRJ5qogQ/Qo2VZ11F7ptd4GD7CxPE/cSFLsKOadi7fu75XJ994OhMGrcXSR/g +lEtSFqn6y15UdgU2FtUUX+I72FXo+Nmkqh5xFHDu68d4Kkzdv2xCvn81K3LRsByz +E3P4biQnQ+mN3cIIVu79KNkCgYEAm6uctrEn4y2KLn5DInyj8GuTZ2ELFhVOIzPG +SR7TH451tTJyiblezDHMcOfkWUx0IlN1zCr8jtgiZXmNQzg0erFxWKU7ebZtGGYh +J3g4dLx+2Unt/mzRJqFUgbnueOO/Nr+gbJ+ZdLUCmeeVohOLOTXrws0kYGl2Izab +K1+VrKECgYEAxQohoOegA0f4mofisXItbwwqTIX3bLpxBc4woa1sB4kjNrLo4slc +qtWZGVlRxwBvQUg0cYj+xtr5nyBdHLy0qwX/kMq4GqQnvW6NqsbrP3MjCZ8NX/Sj +A2W0jx50Hs/XNw6IZFLYgWVoOzCaD+jYFpHhzUZyQD6/rYhwhHrNQmU= +-----END RSA PRIVATE KEY-----` + + tmp, _ := pem.Decode([]byte(privPem)) + privKey, _ := x509.ParsePKCS1PrivateKey(tmp.Bytes) + + pubPem := `-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtWp2PZz4TSU5A6ixw41H +dbfBuGJwPuTtrsdoUf0DQ0/DJBNPqOCBAgEu6ZdUqIbWJ5Da+nevjtncy5hENdi6 +XrXjyzlUxghMuXjE5SeLGpgfQvkqbTkYaFpMe8PTzNeze3fei8+Eu6mzeb6g1Grq +XznuPIc7bNss0w5iX9RiBM9dWPuXonx9xSEy0LYqJm7yXmshNe1aRwkjG/y5C26B +zBFnMKp9YRTua0DO1WqLNhcaRndalIFYouDNVTbwxSlYL16bZVoebqzZvLGrPvZJ +kPuCu6vH9brvOuYo0q8hLVNkBeXcimRpsDjLhQYzEJjoMTbaiVGnjBky+PWNiofJ +nwIDAQAB +-----END PUBLIC KEY-----` + + err := user_model.SetUserSetting(user.ID, chef_module.SettingPublicPem, pubPem) + assert.NoError(t, err) + + t.Run("Authenticate", func(t *testing.T) { + auth := &chef_router.Auth{} + + t.Run("MissingUser", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "POST", "/dummy") + u, err := auth.Verify(req, nil, nil, nil) + assert.Nil(t, u) + assert.NoError(t, err) + }) + + t.Run("NotExistingUser", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "POST", "/dummy") + req.Header.Set("X-Ops-Userid", "not-existing-user") + u, err := auth.Verify(req, nil, nil, nil) + assert.Nil(t, u) + assert.Error(t, err) + }) + + t.Run("Timestamp", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "POST", "/dummy") + req.Header.Set("X-Ops-Userid", user.Name) + u, err := auth.Verify(req, nil, nil, nil) + assert.Nil(t, u) + assert.Error(t, err) + + req.Header.Set("X-Ops-Timestamp", "2023-01-01T00:00:00Z") + u, err = auth.Verify(req, nil, nil, nil) + assert.Nil(t, u) + assert.Error(t, err) + }) + + t.Run("SigningVersion", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "POST", "/dummy") + req.Header.Set("X-Ops-Userid", user.Name) + req.Header.Set("X-Ops-Timestamp", time.Now().UTC().Format(time.RFC3339)) + u, err := auth.Verify(req, nil, nil, nil) + assert.Nil(t, u) + assert.Error(t, err) + + req.Header.Set("X-Ops-Sign", "version=none") + u, err = auth.Verify(req, nil, nil, nil) + assert.Nil(t, u) + assert.Error(t, err) + + req.Header.Set("X-Ops-Sign", "version=1.4") + u, err = auth.Verify(req, nil, nil, nil) + assert.Nil(t, u) + assert.Error(t, err) + + req.Header.Set("X-Ops-Sign", "version=1.0;algorithm=sha2") + u, err = auth.Verify(req, nil, nil, nil) + assert.Nil(t, u) + assert.Error(t, err) + + req.Header.Set("X-Ops-Sign", "version=1.0;algorithm=sha256") + u, err = auth.Verify(req, nil, nil, nil) + assert.Nil(t, u) + assert.Error(t, err) + }) + + t.Run("SignedHeaders", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + ts := time.Now().UTC().Format(time.RFC3339) + + req := NewRequest(t, "POST", "/dummy") + req.Header.Set("X-Ops-Userid", user.Name) + req.Header.Set("X-Ops-Timestamp", ts) + req.Header.Set("X-Ops-Sign", "version=1.0;algorithm=sha1") + req.Header.Set("X-Ops-Content-Hash", "unused") + req.Header.Set("X-Ops-Authorization-4", "dummy") + u, err := auth.Verify(req, nil, nil, nil) + assert.Nil(t, u) + assert.Error(t, err) + + signRequest := func(t *testing.T, req *http.Request, version string) { + username := req.Header.Get("X-Ops-Userid") + if version != "1.0" && version != "1.3" { + sum := sha1.Sum([]byte(username)) + username = base64.StdEncoding.EncodeToString(sum[:]) + } + + req.Header.Set("X-Ops-Sign", "version="+version) + + var data []byte + if version == "1.3" { + data = []byte(fmt.Sprintf( + "Method:%s\nPath:%s\nX-Ops-Content-Hash:%s\nX-Ops-Sign:version=%s\nX-Ops-Timestamp:%s\nX-Ops-UserId:%s\nX-Ops-Server-API-Version:%s", + req.Method, + path.Clean(req.URL.Path), + req.Header.Get("X-Ops-Content-Hash"), + version, + req.Header.Get("X-Ops-Timestamp"), + username, + req.Header.Get("X-Ops-Server-Api-Version"), + )) + } else { + sum := sha1.Sum([]byte(path.Clean(req.URL.Path))) + data = []byte(fmt.Sprintf( + "Method:%s\nHashed Path:%s\nX-Ops-Content-Hash:%s\nX-Ops-Timestamp:%s\nX-Ops-UserId:%s", + req.Method, + base64.StdEncoding.EncodeToString(sum[:]), + req.Header.Get("X-Ops-Content-Hash"), + req.Header.Get("X-Ops-Timestamp"), + username, + )) + } + + for k := range req.Header { + if strings.HasPrefix(k, "X-Ops-Authorization-") { + req.Header.Del(k) + } + } + + var signature []byte + if version == "1.3" || version == "1.2" { + var h hash.Hash + var ch crypto.Hash + if version == "1.3" { + h = sha256.New() + ch = crypto.SHA256 + } else { + h = sha1.New() + ch = crypto.SHA1 + } + h.Write(data) + + signature, _ = rsa.SignPKCS1v15(rand.Reader, privKey, ch, h.Sum(nil)) + } else { + c := new(big.Int).SetBytes(data) + m := new(big.Int).Exp(c, privKey.D, privKey.N) + + signature = m.Bytes() + } + + enc := base64.StdEncoding.EncodeToString(signature) + + const chunkSize = 60 + chunks := make([]string, 0, (len(enc)-1)/chunkSize+1) + currentLen := 0 + currentStart := 0 + for i := range enc { + if currentLen == chunkSize { + chunks = append(chunks, enc[currentStart:i]) + currentLen = 0 + currentStart = i + } + currentLen++ + } + chunks = append(chunks, enc[currentStart:]) + + for i, chunk := range chunks { + req.Header.Set(fmt.Sprintf("X-Ops-Authorization-%d", i+1), chunk) + } + } + + for _, v := range []string{"1.0", "1.1", "1.2", "1.3"} { + t.Run(v, func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + signRequest(t, req, v) + u, err = auth.Verify(req, nil, nil, nil) + assert.NotNil(t, u) + assert.NoError(t, err) + }) + } + }) + }) + + packageName := "test" + packageVersion := "1.0.1" + packageDescription := "Test Description" + packageAuthor := "KN4CK3R" + + root := fmt.Sprintf("/api/packages/%s/chef/api/v1", user.Name) + + uploadPackage := func(t *testing.T, version string, expectedStatus int) { + var body bytes.Buffer + mpw := multipart.NewWriter(&body) + part, _ := mpw.CreateFormFile("tarball", fmt.Sprintf("%s.tar.gz", version)) + zw := gzip.NewWriter(part) + tw := tar.NewWriter(zw) + + content := `{"name":"` + packageName + `","version":"` + version + `","description":"` + packageDescription + `","maintainer":"` + packageAuthor + `"}` + + hdr := &tar.Header{ + Name: packageName + "/metadata.json", + Mode: 0o600, + Size: int64(len(content)), + } + tw.WriteHeader(hdr) + tw.Write([]byte(content)) + + tw.Close() + zw.Close() + mpw.Close() + + req := NewRequestWithBody(t, "POST", root+"/cookbooks", &body) + req.Header.Add("Content-Type", mpw.FormDataContentType()) + AddBasicAuthHeader(req, user.Name) + MakeRequest(t, req, expectedStatus) + } + + t.Run("Upload", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequestWithBody(t, "POST", root+"/cookbooks", bytes.NewReader([]byte{})) + MakeRequest(t, req, http.StatusUnauthorized) + + uploadPackage(t, packageVersion, http.StatusCreated) + + pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeChef) + assert.NoError(t, err) + assert.Len(t, pvs, 1) + + pd, err := packages.GetPackageDescriptor(db.DefaultContext, pvs[0]) + assert.NoError(t, err) + assert.NotNil(t, pd.SemVer) + assert.IsType(t, &chef_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, 1) + assert.Equal(t, fmt.Sprintf("%s.tar.gz", packageVersion), pfs[0].Name) + assert.True(t, pfs[0].IsLead) + + uploadPackage(t, packageVersion, http.StatusBadRequest) + }) + + t.Run("Download", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "GET", fmt.Sprintf("%s/cookbooks/%s/versions/%s/download", root, packageName, packageVersion)) + MakeRequest(t, req, http.StatusOK) + }) + + t.Run("Universe", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "GET", root+"/universe") + resp := MakeRequest(t, req, http.StatusOK) + + type VersionInfo struct { + LocationType string `json:"location_type"` + LocationPath string `json:"location_path"` + DownloadURL string `json:"download_url"` + Dependencies map[string]string `json:"dependencies"` + } + + var result map[string]map[string]*VersionInfo + DecodeJSON(t, resp, &result) + + assert.Len(t, result, 1) + assert.Contains(t, result, packageName) + + versions := result[packageName] + + assert.Len(t, versions, 1) + assert.Contains(t, versions, packageVersion) + + info := versions[packageVersion] + + assert.Equal(t, "opscode", info.LocationType) + assert.Equal(t, setting.AppURL+root[1:], info.LocationPath) + assert.Equal(t, fmt.Sprintf("%s%s/cookbooks/%s/versions/%s/download", setting.AppURL, root[1:], packageName, packageVersion), info.DownloadURL) + }) + + t.Run("Search", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + cases := []struct { + Query string + Start int + Items int + ExpectedTotal int + ExpectedResults int + }{ + {"", 0, 0, 1, 1}, + {"", 0, 10, 1, 1}, + {"gitea", 0, 10, 0, 0}, + {"test", 0, 10, 1, 1}, + {"test", 1, 10, 1, 0}, + } + + type Item struct { + CookbookName string `json:"cookbook_name"` + CookbookMaintainer string `json:"cookbook_maintainer"` + CookbookDescription string `json:"cookbook_description"` + Cookbook string `json:"cookbook"` + } + + type Result struct { + Start int `json:"start"` + Total int `json:"total"` + Items []*Item `json:"items"` + } + + for i, c := range cases { + req := NewRequest(t, "GET", fmt.Sprintf("%s/search?q=%s&start=%d&items=%d", root, c.Query, c.Start, c.Items)) + req = AddBasicAuthHeader(req, user.Name) + resp := MakeRequest(t, req, http.StatusOK) + + var result Result + DecodeJSON(t, resp, &result) + + assert.Equal(t, c.ExpectedTotal, result.Total, "case %d: unexpected total hits", i) + assert.Len(t, result.Items, c.ExpectedResults, "case %d: unexpected result count", i) + + if len(result.Items) == 1 { + item := result.Items[0] + assert.Equal(t, packageName, item.CookbookName) + assert.Equal(t, packageAuthor, item.CookbookMaintainer) + assert.Equal(t, packageDescription, item.CookbookDescription) + assert.Equal(t, fmt.Sprintf("%s%s/cookbooks/%s", setting.AppURL, root[1:], packageName), item.Cookbook) + } + } + }) + + t.Run("EnumeratePackages", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + cases := []struct { + Sort string + Start int + Items int + ExpectedTotal int + ExpectedResults int + }{ + {"", 0, 0, 1, 1}, + {"", 0, 10, 1, 1}, + {"RECENTLY_ADDED", 0, 10, 1, 1}, + {"RECENTLY_UPDATED", 0, 10, 1, 1}, + {"", 1, 10, 1, 0}, + } + + type Item struct { + CookbookName string `json:"cookbook_name"` + CookbookMaintainer string `json:"cookbook_maintainer"` + CookbookDescription string `json:"cookbook_description"` + Cookbook string `json:"cookbook"` + } + + type Result struct { + Start int `json:"start"` + Total int `json:"total"` + Items []*Item `json:"items"` + } + + for i, c := range cases { + req := NewRequest(t, "GET", fmt.Sprintf("%s/cookbooks?start=%d&items=%d&sort=%s", root, c.Start, c.Items, c.Sort)) + req = AddBasicAuthHeader(req, user.Name) + resp := MakeRequest(t, req, http.StatusOK) + + var result Result + DecodeJSON(t, resp, &result) + + assert.Equal(t, c.ExpectedTotal, result.Total, "case %d: unexpected total hits", i) + assert.Len(t, result.Items, c.ExpectedResults, "case %d: unexpected result count", i) + + if len(result.Items) == 1 { + item := result.Items[0] + assert.Equal(t, packageName, item.CookbookName) + assert.Equal(t, packageAuthor, item.CookbookMaintainer) + assert.Equal(t, packageDescription, item.CookbookDescription) + assert.Equal(t, fmt.Sprintf("%s%s/cookbooks/%s", setting.AppURL, root[1:], packageName), item.Cookbook) + } + } + }) + + t.Run("PackageMetadata", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "GET", fmt.Sprintf("%s/cookbooks/%s", root, packageName)) + resp := MakeRequest(t, req, http.StatusOK) + + type Result struct { + Name string `json:"name"` + Maintainer string `json:"maintainer"` + Description string `json:"description"` + Category string `json:"category"` + LatestVersion string `json:"latest_version"` + SourceURL string `json:"source_url"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Deprecated bool `json:"deprecated"` + Versions []string `json:"versions"` + } + + var result Result + DecodeJSON(t, resp, &result) + + versionURL := fmt.Sprintf("%s%s/cookbooks/%s/versions/%s", setting.AppURL, root[1:], packageName, packageVersion) + + assert.Equal(t, packageName, result.Name) + assert.Equal(t, packageAuthor, result.Maintainer) + assert.Equal(t, packageDescription, result.Description) + assert.Equal(t, versionURL, result.LatestVersion) + assert.False(t, result.Deprecated) + assert.ElementsMatch(t, []string{versionURL}, result.Versions) + }) + + t.Run("PackageVersionMetadata", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "GET", fmt.Sprintf("%s/cookbooks/%s/versions/%s", root, packageName, packageVersion)) + resp := MakeRequest(t, req, http.StatusOK) + + type Result struct { + Version string `json:"version"` + TarballFileSize int64 `json:"tarball_file_size"` + PublishedAt time.Time `json:"published_at"` + Cookbook string `json:"cookbook"` + File string `json:"file"` + License string `json:"license"` + Dependencies map[string]string `json:"dependencies"` + } + + var result Result + DecodeJSON(t, resp, &result) + + packageURL := fmt.Sprintf("%s%s/cookbooks/%s", setting.AppURL, root[1:], packageName) + + assert.Equal(t, packageVersion, result.Version) + assert.Equal(t, packageURL, result.Cookbook) + assert.Equal(t, fmt.Sprintf("%s/versions/%s/download", packageURL, packageVersion), result.File) + }) + + t.Run("Delete", func(t *testing.T) { + uploadPackage(t, "1.0.2", http.StatusCreated) + uploadPackage(t, "1.0.3", http.StatusCreated) + + t.Run("Version", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "DELETE", fmt.Sprintf("%s/cookbooks/%s/versions/%s", root, packageName, "1.0.2")) + MakeRequest(t, req, http.StatusUnauthorized) + + req = NewRequest(t, "DELETE", fmt.Sprintf("%s/cookbooks/%s/versions/%s", root, packageName, "1.0.2")) + AddBasicAuthHeader(req, user.Name) + MakeRequest(t, req, http.StatusOK) + + pv, err := packages.GetVersionByNameAndVersion(db.DefaultContext, user.ID, packages.TypeChef, packageName, "1.0.2") + assert.Nil(t, pv) + assert.Error(t, err) + }) + + t.Run("Package", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "DELETE", fmt.Sprintf("%s/cookbooks/%s", root, packageName)) + MakeRequest(t, req, http.StatusUnauthorized) + + req = NewRequest(t, "DELETE", fmt.Sprintf("%s/cookbooks/%s", root, packageName)) + AddBasicAuthHeader(req, user.Name) + MakeRequest(t, req, http.StatusOK) + + pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeChef) + assert.NoError(t, err) + assert.Empty(t, pvs) + }) + }) +} diff --git a/tests/integration/api_packages_container_test.go b/tests/integration/api_packages_container_test.go index 39297c7d9..3d9319f37 100644 --- a/tests/integration/api_packages_container_test.go +++ b/tests/integration/api_packages_container_test.go @@ -20,11 +20,11 @@ import ( "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" container_module "code.gitea.io/gitea/modules/packages/container" - "code.gitea.io/gitea/modules/packages/container/oci" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/tests" + oci "github.com/opencontainers/image-spec/specs-go/v1" "github.com/stretchr/testify/assert" ) @@ -66,13 +66,13 @@ func TestPackageContainer(t *testing.T) { configContent := `{"architecture":"amd64","config":{"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/true"],"ArgsEscaped":true,"Image":"sha256:9bd8b88dc68b80cffe126cc820e4b52c6e558eb3b37680bfee8e5f3ed7b8c257"},"container":"b89fe92a887d55c0961f02bdfbfd8ac3ddf66167db374770d2d9e9fab3311510","container_config":{"Hostname":"b89fe92a887d","Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/true\"]"],"ArgsEscaped":true,"Image":"sha256:9bd8b88dc68b80cffe126cc820e4b52c6e558eb3b37680bfee8e5f3ed7b8c257"},"created":"2022-01-01T00:00:00.000000000Z","docker_version":"20.10.12","history":[{"created":"2022-01-01T00:00:00.000000000Z","created_by":"/bin/sh -c #(nop) COPY file:0e7589b0c800daaf6fa460d2677101e4676dd9491980210cb345480e513f3602 in /true "},{"created":"2022-01-01T00:00:00.000000001Z","created_by":"/bin/sh -c #(nop) CMD [\"/true\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:0ff3b91bdf21ecdf2f2f3d4372c2098a14dbe06cd678e8f0a85fd4902d00e2e2"]}}` manifestDigest := "sha256:4f10484d1c1bb13e3956b4de1cd42db8e0f14a75be1617b60f2de3cd59c803c6" - manifestContent := `{"schemaVersion":2,"mediaType":"` + oci.MediaTypeDockerManifest + `","config":{"mediaType":"application/vnd.docker.container.image.v1+json","digest":"sha256:4607e093bec406eaadb6f3a340f63400c9d3a7038680744c406903766b938f0d","size":1069},"layers":[{"mediaType":"application/vnd.docker.image.rootfs.diff.tar.gzip","digest":"sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4","size":32}]}` + manifestContent := `{"schemaVersion":2,"mediaType":"application/vnd.docker.distribution.manifest.v2+json","config":{"mediaType":"application/vnd.docker.container.image.v1+json","digest":"sha256:4607e093bec406eaadb6f3a340f63400c9d3a7038680744c406903766b938f0d","size":1069},"layers":[{"mediaType":"application/vnd.docker.image.rootfs.diff.tar.gzip","digest":"sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4","size":32}]}` untaggedManifestDigest := "sha256:4305f5f5572b9a426b88909b036e52ee3cf3d7b9c1b01fac840e90747f56623d" untaggedManifestContent := `{"schemaVersion":2,"mediaType":"` + oci.MediaTypeImageManifest + `","config":{"mediaType":"application/vnd.docker.container.image.v1+json","digest":"sha256:4607e093bec406eaadb6f3a340f63400c9d3a7038680744c406903766b938f0d","size":1069},"layers":[{"mediaType":"application/vnd.docker.image.rootfs.diff.tar.gzip","digest":"sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4","size":32}]}` indexManifestDigest := "sha256:bab112d6efb9e7f221995caaaa880352feb5bd8b1faf52fae8d12c113aa123ec" - indexManifestContent := `{"schemaVersion":2,"mediaType":"` + oci.MediaTypeImageIndex + `","manifests":[{"mediaType":"` + oci.MediaTypeDockerManifest + `","digest":"` + manifestDigest + `","platform":{"os":"linux","architecture":"arm","variant":"v7"}},{"mediaType":"` + oci.MediaTypeImageManifest + `","digest":"` + untaggedManifestDigest + `","platform":{"os":"linux","architecture":"arm64","variant":"v8"}}]}` + indexManifestContent := `{"schemaVersion":2,"mediaType":"` + oci.MediaTypeImageIndex + `","manifests":[{"mediaType":"application/vnd.docker.distribution.manifest.v2+json","digest":"` + manifestDigest + `","platform":{"os":"linux","architecture":"arm","variant":"v7"}},{"mediaType":"` + oci.MediaTypeImageManifest + `","digest":"` + untaggedManifestDigest + `","platform":{"os":"linux","architecture":"arm64","variant":"v8"}}]}` anonymousToken := "" userToken := "" @@ -296,12 +296,12 @@ func TestPackageContainer(t *testing.T) { req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/manifests/%s", url, tag), strings.NewReader(manifestContent)) addTokenAuthHeader(req, anonymousToken) - req.Header.Set("Content-Type", oci.MediaTypeDockerManifest) + req.Header.Set("Content-Type", "application/vnd.docker.distribution.manifest.v2+json") MakeRequest(t, req, http.StatusUnauthorized) req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/manifests/%s", url, tag), strings.NewReader(manifestContent)) addTokenAuthHeader(req, userToken) - req.Header.Set("Content-Type", oci.MediaTypeDockerManifest) + req.Header.Set("Content-Type", "application/vnd.docker.distribution.manifest.v2+json") resp := MakeRequest(t, req, http.StatusCreated) assert.Equal(t, manifestDigest, resp.Header().Get("Docker-Content-Digest")) @@ -328,7 +328,7 @@ func TestPackageContainer(t *testing.T) { switch pfd.File.Name { case container_model.ManifestFilename: assert.True(t, pfd.File.IsLead) - assert.Equal(t, oci.MediaTypeDockerManifest, pfd.Properties.GetByName(container_module.PropertyMediaType)) + assert.Equal(t, "application/vnd.docker.distribution.manifest.v2+json", pfd.Properties.GetByName(container_module.PropertyMediaType)) assert.Equal(t, manifestDigest, pfd.Properties.GetByName(container_module.PropertyDigest)) case strings.Replace(configDigest, ":", "_", 1): assert.False(t, pfd.File.IsLead) @@ -354,7 +354,7 @@ func TestPackageContainer(t *testing.T) { // Overwrite existing tag should keep the download count req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/manifests/%s", url, tag), strings.NewReader(manifestContent)) addTokenAuthHeader(req, userToken) - req.Header.Set("Content-Type", oci.MediaTypeDockerManifest) + req.Header.Set("Content-Type", oci.MediaTypeImageManifest) MakeRequest(t, req, http.StatusCreated) pv, err = packages_model.GetVersionByNameAndVersion(db.DefaultContext, user.ID, packages_model.TypeContainer, image, tag) @@ -389,7 +389,7 @@ func TestPackageContainer(t *testing.T) { resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, fmt.Sprintf("%d", len(manifestContent)), resp.Header().Get("Content-Length")) - assert.Equal(t, oci.MediaTypeDockerManifest, resp.Header().Get("Content-Type")) + assert.Equal(t, oci.MediaTypeImageManifest, resp.Header().Get("Content-Type")) assert.Equal(t, manifestDigest, resp.Header().Get("Docker-Content-Digest")) assert.Equal(t, manifestContent, resp.Body.String()) }) diff --git a/tests/integration/api_packages_test.go b/tests/integration/api_packages_test.go index a6c335eb7..39852e212 100644 --- a/tests/integration/api_packages_test.go +++ b/tests/integration/api_packages_test.go @@ -21,6 +21,7 @@ import ( "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" packages_service "code.gitea.io/gitea/services/packages" + packages_cleanup_service "code.gitea.io/gitea/services/packages/cleanup" "code.gitea.io/gitea/tests" "github.com/stretchr/testify/assert" @@ -246,7 +247,7 @@ func TestPackageCleanup(t *testing.T) { _, err = packages_model.GetInternalVersionByNameAndVersion(db.DefaultContext, 2, packages_model.TypeContainer, "test", container_model.UploadVersion) assert.NoError(t, err) - err = packages_service.Cleanup(db.DefaultContext, duration) + err = packages_cleanup_service.Cleanup(db.DefaultContext, duration) assert.NoError(t, err) pbs, err = packages_model.FindExpiredUnreferencedBlobs(db.DefaultContext, duration) @@ -383,7 +384,7 @@ func TestPackageCleanup(t *testing.T) { pcr, err := packages_model.InsertCleanupRule(db.DefaultContext, c.Rule) assert.NoError(t, err) - err = packages_service.Cleanup(db.DefaultContext, duration) + err = packages_cleanup_service.Cleanup(db.DefaultContext, duration) assert.NoError(t, err) for _, v := range c.Versions { diff --git a/tests/integration/auth_ldap_test.go b/tests/integration/auth_ldap_test.go index 9dfa4c73d..883c9d80a 100644 --- a/tests/integration/auth_ldap_test.go +++ b/tests/integration/auth_ldap_test.go @@ -112,23 +112,14 @@ func getLDAPServerPort() string { return port } -func addAuthSourceLDAP(t *testing.T, sshKeyAttribute, groupFilter string, groupMapParams ...string) { - groupTeamMapRemoval := "off" - groupTeamMap := "" - if len(groupMapParams) == 2 { - groupTeamMapRemoval = groupMapParams[0] - groupTeamMap = groupMapParams[1] - } - +func buildAuthSourceLDAPPayload(csrf, sshKeyAttribute, groupFilter, groupTeamMap, groupTeamMapRemoval string) map[string]string { // Modify user filter to test group filter explicitly userFilter := "(&(objectClass=inetOrgPerson)(memberOf=cn=git,ou=people,dc=planetexpress,dc=com)(uid=%s))" if groupFilter != "" { userFilter = "(&(objectClass=inetOrgPerson)(uid=%s))" } - session := loginUser(t, "user1") - csrf := GetCSRF(t, session, "/admin/auths/new") - req := NewRequestWithValues(t, "POST", "/admin/auths/new", map[string]string{ + return map[string]string{ "_csrf": csrf, "type": "2", "name": "ldap", @@ -154,7 +145,19 @@ func addAuthSourceLDAP(t *testing.T, sshKeyAttribute, groupFilter string, groupM "group_team_map": groupTeamMap, "group_team_map_removal": groupTeamMapRemoval, "user_uid": "DN", - }) + } +} + +func addAuthSourceLDAP(t *testing.T, sshKeyAttribute, groupFilter string, groupMapParams ...string) { + groupTeamMapRemoval := "off" + groupTeamMap := "" + if len(groupMapParams) == 2 { + groupTeamMapRemoval = groupMapParams[0] + groupTeamMap = groupMapParams[1] + } + session := loginUser(t, "user1") + csrf := GetCSRF(t, session, "/admin/auths/new") + req := NewRequestWithValues(t, "POST", "/admin/auths/new", buildAuthSourceLDAPPayload(csrf, sshKeyAttribute, groupFilter, groupTeamMap, groupTeamMapRemoval)) session.MakeRequest(t, req, http.StatusSeeOther) } @@ -202,26 +205,7 @@ func TestLDAPAuthChange(t *testing.T) { binddn, _ := doc.Find(`input[name="bind_dn"]`).Attr("value") assert.Equal(t, binddn, "uid=gitea,ou=service,dc=planetexpress,dc=com") - req = NewRequestWithValues(t, "POST", href, map[string]string{ - "_csrf": csrf, - "type": "2", - "name": "ldap", - "host": getLDAPServerHost(), - "port": "389", - "bind_dn": "uid=gitea,ou=service,dc=planetexpress,dc=com", - "bind_password": "password", - "user_base": "ou=people,dc=planetexpress,dc=com", - "filter": "(&(objectClass=inetOrgPerson)(memberOf=cn=git,ou=people,dc=planetexpress,dc=com)(uid=%s))", - "admin_filter": "(memberOf=cn=admin_staff,ou=people,dc=planetexpress,dc=com)", - "restricted_filter": "(uid=leela)", - "attribute_username": "uid", - "attribute_name": "givenName", - "attribute_surname": "sn", - "attribute_mail": "mail", - "attribute_ssh_public_key": "", - "is_sync_enabled": "on", - "is_active": "on", - }) + req = NewRequestWithValues(t, "POST", href, buildAuthSourceLDAPPayload(csrf, "", "", "", "off")) session.MakeRequest(t, req, http.StatusSeeOther) req = NewRequest(t, "GET", href) @@ -395,7 +379,7 @@ func TestLDAPGroupTeamSyncAddMember(t *testing.T) { } defer tests.PrepareTestEnv(t)() addAuthSourceLDAP(t, "", "", "on", `{"cn=ship_crew,ou=people,dc=planetexpress,dc=com":{"org26": ["team11"]},"cn=admin_staff,ou=people,dc=planetexpress,dc=com": {"non-existent": ["non-existent"]}}`) - org, err := organization.GetOrgByName("org26") + org, err := organization.GetOrgByName(db.DefaultContext, "org26") assert.NoError(t, err) team, err := organization.GetTeam(db.DefaultContext, org.ID, "team11") assert.NoError(t, err) @@ -440,7 +424,7 @@ func TestLDAPGroupTeamSyncRemoveMember(t *testing.T) { } defer tests.PrepareTestEnv(t)() addAuthSourceLDAP(t, "", "", "on", `{"cn=dispatch,ou=people,dc=planetexpress,dc=com": {"org26": ["team11"]}}`) - org, err := organization.GetOrgByName("org26") + org, err := organization.GetOrgByName(db.DefaultContext, "org26") assert.NoError(t, err) team, err := organization.GetTeam(db.DefaultContext, org.ID, "team11") assert.NoError(t, err) @@ -468,24 +452,15 @@ func TestLDAPGroupTeamSyncRemoveMember(t *testing.T) { assert.False(t, isMember, "User membership should have been removed from team") } -// Login should work even if Team Group Map contains a broken JSON -func TestBrokenLDAPMapUserSignin(t *testing.T) { +func TestLDAPPreventInvalidGroupTeamMap(t *testing.T) { if skipLDAPTests() { t.Skip() return } defer tests.PrepareTestEnv(t)() - addAuthSourceLDAP(t, "", "", "on", `{"NOT_A_VALID_JSON"["MISSING_DOUBLE_POINT"]}`) - u := gitLDAPUsers[0] - - session := loginUserWithPassword(t, u.UserName, u.Password) - req := NewRequest(t, "GET", "/user/settings") - resp := session.MakeRequest(t, req, http.StatusOK) - - htmlDoc := NewHTMLParser(t, resp.Body) - - assert.Equal(t, u.UserName, htmlDoc.GetInputValueByName("name")) - assert.Equal(t, u.FullName, htmlDoc.GetInputValueByName("full_name")) - assert.Equal(t, u.Email, htmlDoc.Find(`label[for="email"]`).Siblings().First().Text()) + session := loginUser(t, "user1") + csrf := GetCSRF(t, session, "/admin/auths/new") + req := NewRequestWithValues(t, "POST", "/admin/auths/new", buildAuthSourceLDAPPayload(csrf, "", "", `{"NOT_A_VALID_JSON"["MISSING_DOUBLE_POINT"]}`, "off")) + session.MakeRequest(t, req, http.StatusOK) // StatusOK = failed, StatusSeeOther = ok } |