Skip to content

Commit de865f2

Browse files
committed
merged with add/search-function-to-projectslist
2 parents b89353b + 7669480 commit de865f2

10 files changed

Lines changed: 815 additions & 25 deletions

File tree

cmd/devguard/api/api.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ func BuildRouter(db core.DB) *echo.Echo {
550550

551551
//Api functions for interacting with an organization -> .../organizations/<organization-name>/...
552552
organizationRouter := orgRouter.Group("/:organization", multiOrganizationMiddleware(casbinRBACProvider, orgService, gitlabOauth2Integrations), externalEntityProviderRefreshMiddleware(externalEntityProviderService))
553-
organizationRouter.GET("/trigger-sync", externalEntityProviderService.TriggerSync, neededScope([]string{"manage"}), accessControlMiddleware(core.ObjectOrganization, core.ActionRead))
553+
organizationRouter.GET("/trigger-sync/", externalEntityProviderService.TriggerSync, neededScope([]string{"manage"}), accessControlMiddleware(core.ObjectOrganization, core.ActionRead))
554554
organizationRouter.DELETE("/", orgController.Delete, neededScope([]string{"manage"}), accessControlMiddleware(core.ObjectOrganization, core.ActionDelete))
555555
organizationRouter.GET("/", orgController.Read, accessControlMiddleware(core.ObjectOrganization, core.ActionRead))
556556

internal/core/common_interfaces.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ type ProjectRepository interface {
4747
GetByOrgID(organizationID uuid.UUID) ([]models.Project, error)
4848
GetProjectByAssetID(assetID uuid.UUID) (models.Project, error)
4949
List(idSlice []uuid.UUID, parentID *uuid.UUID, organizationID uuid.UUID) ([]models.Project, error)
50+
ListPaged(projectIDs []uuid.UUID, parentID *uuid.UUID, orgID uuid.UUID, pageInfo PageInfo, search string) (Paged[models.Project], error)
5051
EnablePolicyForProject(tx DB, projectID uuid.UUID, policyID uuid.UUID) error
5152
DisablePolicyForProject(tx DB, projectID uuid.UUID, policyID uuid.UUID) error
5253
Upsert(projects *[]*models.Project, conflictingColumns []clause.Column, toUpdate []string) error
@@ -224,6 +225,7 @@ type ExternalEntityProviderService interface {
224225
type ProjectService interface {
225226
ReadBySlug(ctx Context, organizationID uuid.UUID, slug string) (models.Project, error)
226227
ListAllowedProjects(ctx Context) ([]models.Project, error)
228+
ListAllowedProjectsPaged(c Context) (Paged[models.Project], error)
227229
ListProjectsByOrganizationID(organizationID uuid.UUID) ([]models.Project, error)
228230
RecursivelyGetChildProjects(projectID uuid.UUID) ([]models.Project, error)
229231
GetDirectChildProjects(projectID uuid.UUID) ([]models.Project, error)

internal/core/org/org_controller.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ func (controller *httpController) ContentTree(ctx core.Context) error {
129129
// get the organization from the context
130130
organization := core.GetOrg(ctx)
131131

132-
ps, err := controller.projectService.ListAllowedProjects(ctx)
132+
ps, err := controller.projectService.ListAllowedProjects(
133+
ctx)
133134
if err != nil {
134135
return echo.NewHTTPError(500, "could not get projects").WithInternal(err)
135136
}

internal/core/project/project_controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ func (projectController *controller) Read(c core.Context) error {
253253

254254
func (projectController *controller) List(c core.Context) error {
255255
// get all projects the user has at least read access to - might be public projects as well
256-
projects, err := projectController.projectService.ListAllowedProjects(c)
256+
projects, err := projectController.projectService.ListAllowedProjectsPaged(c)
257257

258258
if err != nil {
259259
return err

internal/core/project/project_service.go

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -150,13 +150,7 @@ func (s *service) ListProjectsByOrganizationID(organizationID uuid.UUID) ([]mode
150150
return s.projectRepository.GetByOrgID(organizationID)
151151
}
152152

153-
func (s *service) ListAllowedProjects(c core.Context) ([]models.Project, error) {
154-
// get all projects the user has at least read access to
155-
rbac := core.GetRBAC(c)
156-
projectsIdsStr, err := rbac.GetAllProjectsForUser(core.GetSession(c).GetUserID())
157-
if err != nil {
158-
return nil, echo.NewHTTPError(500, "could not get projects for user").WithInternal(err)
159-
}
153+
func (s *service) projectsForUser(c core.Context, projectsIdsStr []string) ([]uuid.UUID, *uuid.UUID, error) {
160154

161155
// extract the project ids from the roles
162156
projectIDs := make(map[uuid.UUID]struct{})
@@ -172,7 +166,7 @@ func (s *service) ListAllowedProjects(c core.Context) ([]models.Project, error)
172166
if queryParentID != "" {
173167
tmp, err := uuid.Parse(queryParentID)
174168
if err != nil {
175-
return nil, err
169+
return nil, nil, err
176170
}
177171

178172
parentID = &tmp
@@ -183,6 +177,50 @@ func (s *service) ListAllowedProjects(c core.Context) ([]models.Project, error)
183177
projectIDsSlice = append(projectIDsSlice, projectID)
184178
}
185179

180+
return projectIDsSlice, parentID, nil
181+
}
182+
183+
func (s *service) ListAllowedProjectsPaged(c core.Context) (core.Paged[models.Project], error) {
184+
185+
pageInfo := core.GetPageInfo(c)
186+
search := c.QueryParam("search")
187+
188+
// get all projects the user has at least read access to
189+
rbac := core.GetRBAC(c)
190+
projectIDs, err := rbac.GetAllProjectsForUser(core.GetSession(c).GetUserID())
191+
if err != nil {
192+
return core.Paged[models.Project]{}, echo.NewHTTPError(500, "could not get projects for user").WithInternal(err)
193+
}
194+
195+
projectsIdsStr := projectIDs
196+
197+
projectIDsSlice, parentID, err := s.projectsForUser(c, projectsIdsStr)
198+
if err != nil {
199+
return core.Paged[models.Project]{}, err
200+
}
201+
202+
projects, err := s.projectRepository.ListPaged(projectIDsSlice, parentID, core.GetOrg(c).GetID(), pageInfo, search)
203+
204+
if err != nil {
205+
return core.Paged[models.Project]{}, err
206+
}
207+
208+
return projects, nil
209+
}
210+
211+
func (s *service) ListAllowedProjects(c core.Context) ([]models.Project, error) {
212+
// get all projects the user has at least read access to
213+
rbac := core.GetRBAC(c)
214+
projectIDs, err := rbac.GetAllProjectsForUser(core.GetSession(c).GetUserID())
215+
if err != nil {
216+
return nil, echo.NewHTTPError(500, "could not get projects for user").WithInternal(err)
217+
}
218+
219+
projectIDsSlice, parentID, err := s.projectsForUser(c, projectIDs)
220+
if err != nil {
221+
return nil, err
222+
}
223+
186224
projects, err := s.projectRepository.List(projectIDsSlice, parentID, core.GetOrg(c).GetID())
187225

188226
if err != nil {

internal/database/repositories/project_repository.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,39 @@ func (g *projectRepository) Update(tx core.DB, project *models.Project) error {
115115
return g.db.Save(project).Error
116116
}
117117

118+
func (g *projectRepository) ListPaged(projectIDs []uuid.UUID, parentID *uuid.UUID, orgID uuid.UUID, pageInfo core.PageInfo, search string) (core.Paged[models.Project], error) {
119+
var projects []models.Project
120+
121+
var q *gorm.DB
122+
if parentID != nil {
123+
q = g.db.Model(&models.Project{}).Where(
124+
g.db.Where("id IN ? AND parent_id = ?", projectIDs, parentID).
125+
Or("organization_id = ? AND is_public = true AND parent_id = ?", orgID, parentID),
126+
)
127+
} else {
128+
q = g.db.Model(&models.Project{}).Where(
129+
g.db.Where("id IN ? AND parent_id IS NULL", projectIDs).
130+
Or("organization_id = ? AND is_public = true AND parent_id IS NULL", orgID),
131+
)
132+
}
133+
134+
// apply search
135+
if search != "" {
136+
q = q.Where("name ILIKE ?", "%"+search+"%")
137+
}
138+
139+
var count int64
140+
err := q.Count(&count).Error
141+
if err != nil {
142+
return core.Paged[models.Project]{}, err
143+
}
144+
err = q.Limit(pageInfo.PageSize).Offset((pageInfo.Page - 1) * pageInfo.PageSize).Find(&projects).Error
145+
if err != nil {
146+
return core.Paged[models.Project]{}, err
147+
}
148+
return core.NewPaged(pageInfo, count, projects), nil
149+
}
150+
118151
func (g *projectRepository) List(projectIDs []uuid.UUID, parentID *uuid.UUID, orgID uuid.UUID) ([]models.Project, error) {
119152
var projects []models.Project
120153
if parentID != nil {

mocks/mock_GitLabOauth2TokenRepository.go

Lines changed: 1 addition & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mocks/mock_ProjectRepository.go

Lines changed: 84 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mocks/mock_ProjectService.go

Lines changed: 60 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)