Skip to content

Commit

Permalink
fix(dashboards): add limit to repos for dashboards and dashboards for…
Browse files Browse the repository at this point in the history
… users (#1116)

* fix(dashboards): add limit to repos

* also add user dashboard limit
  • Loading branch information
ecrupper authored May 2, 2024
1 parent 33155bf commit 58ef7e8
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 15 deletions.
39 changes: 39 additions & 0 deletions constants/limit.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,45 @@ package constants

// Limits and constraints.
const (
// BuildLimitMin defines the minimum value for repo concurrent build limit.
BuildLimitMin = 1

// BuildLimitMax defines the maximum value for repo concurrent build limit.
BuildLimitMax = 30

// BuildLimitDefault defines the default value for repo concurrent build limit.
BuildLimitDefault = 10

// BuildTimeoutMin defines the minimum value in minutes for repo build timeout.
BuildTimeoutMin = 1

// BuildTimeoutMax defines the maximum value in minutes for repo build timeout.
BuildTimeoutMax = 90

// BuildTimeoutDefault defines the default value in minutes for repo build timeout.
BuildTimeoutDefault = 30

// FavoritesMaxSize defines the maximum size in characters for user favorites.
FavoritesMaxSize = 5000

// RunningBuildIDsMaxSize defines the maximum size in characters for worker RunningBuildIDs.
RunningBuildIDsMaxSize = 500

// TopicsMaxSize defines the maximum size in characters for repo topics. Ex: GitHub has a 20-topic, 50-char limit.
TopicsMaxSize = 1020

// DeployBuildsMaxSize defines the maximum size in characters for deployment builds.
DeployBuildsMaxSize = 500

// ReportStepStatusLimit defines the maximum number of steps in a pipeline that may report their status to the SCM.
ReportStepStatusLimit = 10

// DashboardRepoLimit defines the maximum number of repos that can be assigned to a dashboard.
DashboardRepoLimit = 10

// UserDashboardLimit defines the maximum number of dashboards that can be assigned to a user.
UserDashboardLimit = 10

// DashboardAdminMaxSize defines the maximum size in characters for dashboard admins.
DashboardAdminMaxSize = 5000
)
6 changes: 6 additions & 0 deletions database/types/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/google/uuid"

api "github.com/go-vela/server/api/types"
"github.com/go-vela/server/constants"
"github.com/go-vela/server/util"
)

Expand Down Expand Up @@ -142,6 +143,11 @@ func (d *Dashboard) Validate() error {
return ErrEmptyDashName
}

// verify the number of repos
if len(d.Repos) > constants.DashboardRepoLimit {
return fmt.Errorf("exceeded repos limit of %d", constants.DashboardRepoLimit)
}

// ensure that all Dashboard string fields
// that can be returned as JSON are sanitized
// to avoid unsafe HTML content
Expand Down
15 changes: 15 additions & 0 deletions database/types/dashboard_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,17 @@ func TestTypes_Dashboard_ToAPI(t *testing.T) {
func TestTypes_Dashboard_Validate(t *testing.T) {
uuid, _ := uuid.Parse("c8da1302-07d6-11ea-882f-4893bca275b8")

dashRepo := new(api.DashboardRepo)
dashRepo.SetName("dashboard-repo")

dashRepos := []*api.DashboardRepo{}
for i := 0; i < 11; i++ {
dashRepos = append(dashRepos, dashRepo)
}

exceededReposDashboard := testDashboard()
exceededReposDashboard.Repos = DashReposJSON(dashRepos)

// setup tests
tests := []struct {
failure bool
Expand All @@ -105,6 +116,10 @@ func TestTypes_Dashboard_Validate(t *testing.T) {
ID: uuid,
},
},
{ // hit repo limit
failure: true,
dashboard: exceededReposDashboard,
},
}

// run tests
Expand Down
14 changes: 3 additions & 11 deletions database/types/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (
"github.com/lib/pq"

api "github.com/go-vela/server/api/types"
"github.com/go-vela/server/constants"
"github.com/go-vela/server/util"
"github.com/go-vela/types/constants"
)

var (
Expand Down Expand Up @@ -216,16 +216,8 @@ func (u *User) Validate() error {
return ErrExceededFavoritesLimit
}

// calculate totalDashboards size of dashboards
totalDashboards := 0
for _, d := range u.Dashboards {
totalDashboards += len(d)
}

// verify the Dashboards field is within the database constraints
// len is to factor in number of comma separators included in the database field,
// removing 1 due to the last item not having an appended comma
if (totalDashboards + len(u.Dashboards) - 1) > constants.FavoritesMaxSize {
// validate number of dashboards
if len(u.Dashboards) > constants.UserDashboardLimit {
return ErrExceededDashboardsLimit
}

Expand Down
8 changes: 4 additions & 4 deletions database/types/user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ func TestTypes_User_Validate(t *testing.T) {
ID: sql.NullInt64{Int64: 1, Valid: true},
Name: sql.NullString{String: "octocat", Valid: true},
Token: sql.NullString{String: "superSecretToken", Valid: true},
Favorites: exceededField(),
Favorites: exceededField(500),
},
},
{ // invalid dashboards set for user
Expand All @@ -213,7 +213,7 @@ func TestTypes_User_Validate(t *testing.T) {
ID: sql.NullInt64{Int64: 1, Valid: true},
Name: sql.NullString{String: "octocat", Valid: true},
Token: sql.NullString{String: "superSecretToken", Valid: true},
Dashboards: exceededField(),
Dashboards: exceededField(11),
},
},
}
Expand Down Expand Up @@ -275,12 +275,12 @@ func testUser() *User {
}

// exceededField returns a list of strings that exceed the maximum size of a field.
func exceededField() []string {
func exceededField(indexes int) []string {
// initialize empty favorites
values := []string{}

// add enough strings to exceed the character limit
for i := 0; i < 500; i++ {
for i := 0; i < indexes; i++ {
// construct field
// use i to adhere to unique favorites
field := "github/octocat-" + strconv.Itoa(i)
Expand Down

0 comments on commit 58ef7e8

Please sign in to comment.