Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-pages.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlessio Caiazza <acaiazza@gitlab.com>2018-12-06 15:13:04 +0300
committerAlessio Caiazza <acaiazza@gitlab.com>2018-12-06 15:13:04 +0300
commitf65623e115dfe87521e22fe1afdff3b94ae9012e (patch)
tree938992cbfa9026b094a719ba9cacbac370c1e4e6 /internal/domain
parentd09650e7227efca1d0a0bc0ca094b90f81be9497 (diff)
Don't scan subgroups past gitlab-rails limit
Diffstat (limited to 'internal/domain')
-rw-r--r--internal/domain/domain.go7
-rw-r--r--internal/domain/map.go16
-rw-r--r--internal/domain/map_test.go52
3 files changed, 64 insertions, 11 deletions
diff --git a/internal/domain/domain.go b/internal/domain/domain.go
index 3638c372..8345f69c 100644
--- a/internal/domain/domain.go
+++ b/internal/domain/domain.go
@@ -22,10 +22,11 @@ import (
)
const (
- // MaxProjectDepth is set to the maximum nested project depth in gitlab (21) plus 3.
+ subgroupScanLimit int = 21
+ // maxProjectDepth is set to the maximum nested project depth in gitlab (21) plus 3.
// One for the project, one for the first empty element of the split (URL.Path starts with /),
// and one for the real file path
- MaxProjectDepth int = 24
+ maxProjectDepth int = subgroupScanLimit + 3
)
type locationDirectoryError struct {
@@ -120,7 +121,7 @@ func getHost(r *http.Request) string {
func (d *D) getProjectWithSubpath(r *http.Request) (*project, string, string) {
// Check for a project specified in the URL: http://group.gitlab.io/projectA
// If present, these projects shadow the group domain.
- split := strings.SplitN(r.URL.Path, "/", MaxProjectDepth)
+ split := strings.SplitN(r.URL.Path, "/", maxProjectDepth)
if len(split) >= 2 {
project, projectPath, urlPath := d.digProjectWithSubpath("", split[1:])
if project != nil {
diff --git a/internal/domain/map.go b/internal/domain/map.go
index 26657a1c..2891a272 100644
--- a/internal/domain/map.go
+++ b/internal/domain/map.go
@@ -60,7 +60,7 @@ func (dm Map) updateGroupDomain(rootDomain, groupName, projectPath string, https
}
}
- split := strings.SplitN(strings.ToLower(projectPath), "/", MaxProjectDepth)
+ split := strings.SplitN(strings.ToLower(projectPath), "/", maxProjectDepth)
projectName := split[len(split)-1]
g := &groupDomain.group
@@ -108,7 +108,7 @@ func (dm Map) readProjectConfig(rootDomain string, group, projectName string, co
}
}
-func readProject(group, parent, projectName string, fanIn chan<- jobResult) {
+func readProject(group, parent, projectName string, level int, fanIn chan<- jobResult) {
if strings.HasPrefix(projectName, ".") {
return
}
@@ -121,8 +121,10 @@ func readProject(group, parent, projectName string, fanIn chan<- jobResult) {
projectPath := filepath.Join(parent, projectName)
if _, err := os.Lstat(filepath.Join(group, projectPath, "public")); err != nil {
// maybe it's a subgroup
- buf := make([]byte, 2*os.Getpagesize())
- readProjects(group, projectPath, buf, fanIn)
+ if level <= subgroupScanLimit {
+ buf := make([]byte, 2*os.Getpagesize())
+ readProjects(group, projectPath, level+1, buf, fanIn)
+ }
return
}
@@ -137,7 +139,7 @@ func readProject(group, parent, projectName string, fanIn chan<- jobResult) {
fanIn <- jobResult{group: group, project: projectPath, config: config}
}
-func readProjects(group, parent string, buf []byte, fanIn chan<- jobResult) {
+func readProjects(group, parent string, level int, buf []byte, fanIn chan<- jobResult) {
subgroup := filepath.Join(group, parent)
fis, err := godirwalk.ReadDirents(subgroup, buf)
if err != nil {
@@ -154,7 +156,7 @@ func readProjects(group, parent string, buf []byte, fanIn chan<- jobResult) {
continue
}
- readProject(group, parent, project.Name(), fanIn)
+ readProject(group, parent, project.Name(), level, fanIn)
}
}
@@ -178,7 +180,7 @@ func (dm Map) ReadGroups(rootDomain string, fis godirwalk.Dirents) {
for group := range fanOutGroups {
started := time.Now()
- readProjects(group, "", buf, fanIn)
+ readProjects(group, "", 0, buf, fanIn)
log.WithFields(log.Fields{
"group": group,
diff --git a/internal/domain/map_test.go b/internal/domain/map_test.go
index f7b065e4..dc5e8648 100644
--- a/internal/domain/map_test.go
+++ b/internal/domain/map_test.go
@@ -5,6 +5,7 @@ import (
"fmt"
"io/ioutil"
"os"
+ "strings"
"testing"
"time"
@@ -78,7 +79,56 @@ func TestReadProjects(t *testing.T) {
subgroup, ok := domain.subgroups["subgroup"]
require.True(t, ok, "missing group.test.io subgroup")
_, ok = subgroup.projects["project"]
- require.True(t, ok, "missing project for subgrup in group.test.io domain")
+ require.True(t, ok, "missing project for subgroup in group.test.io domain")
+}
+
+func TestReadProjectsMaxDepth(t *testing.T) {
+ nGroups := 3
+ levels := subgroupScanLimit + 5
+ cleanup := buildFakeDomainsDirectory(t, nGroups, levels)
+ defer cleanup()
+
+ defaultDomain := "test.io"
+ dm := make(Map)
+ dm.ReadGroups(defaultDomain, getEntries(t))
+
+ var domains []string
+ for d := range dm {
+ domains = append(domains, d)
+ }
+
+ var expectedDomains []string
+ for i := 0; i < nGroups; i++ {
+ expectedDomains = append(expectedDomains, fmt.Sprintf("group-%d.%s", i, defaultDomain))
+ }
+
+ for _, expected := range domains {
+ assert.Contains(t, domains, expected)
+ }
+
+ for _, actual := range domains {
+ // we are not checking config.json domains here
+ if !strings.HasSuffix(actual, defaultDomain) {
+ continue
+ }
+ assert.Contains(t, expectedDomains, actual)
+ }
+
+ // check subgroups
+ domain, ok := dm["group-0.test.io"]
+ require.True(t, ok, "missing group-0.test.io domain")
+ subgroup := &domain.group
+ for i := 0; i < levels; i++ {
+ subgroup, ok = subgroup.subgroups["sub"]
+ if i <= subgroupScanLimit {
+ require.True(t, ok, "missing group-0.test.io subgroup at level %d", i)
+ _, ok = subgroup.projects["project-0"]
+ require.True(t, ok, "missing project for subgroup in group-0.test.io domain at level %d", i)
+ } else {
+ require.False(t, ok, "subgroup level %d. Maximum allowed nesting level is %d", i, subgroupScanLimit)
+ break
+ }
+ }
}
// This write must be atomic, otherwise we cannot predict the state of the