Skip to content

Commit 19c1301

Browse files
committed
Merge branch 'main' of github.com:l3montree-dev/flawfix
2 parents 0f787aa + 9a528d8 commit 19c1301

6 files changed

Lines changed: 59 additions & 23 deletions

File tree

cmd/devguard/api/api.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,8 @@ func multiOrganizationMiddleware(rbacProvider core.RBACProvider, organizationSer
304304
return ctx.JSON(500, map[string]string{"error": "no oauth2 config found for external entity provider"})
305305
}
306306

307-
domainRBAC = accesscontrol.NewExternalEntityProviderRBAC(ctx, core.GetThirdPartyIntegration(ctx), *org.ExternalEntityProviderID, *conf.AdminToken)
307+
domainRBAC = accesscontrol.NewExternalEntityProviderRBAC(ctx, core.GetThirdPartyIntegration(ctx), *org.ExternalEntityProviderID, conf.AdminToken)
308+
308309
} else {
309310
domainRBAC = rbacProvider.GetDomainRBAC(org.ID.String())
310311
}

internal/accesscontrol/external_entity_provider_rbac.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ type externalEntityProviderRBAC struct {
1111
thirdPartyIntegration core.ThirdPartyIntegration
1212
externalEntityProviderID string
1313
externalEntityID string
14-
adminToken string
14+
adminToken *string
1515
ctx core.Context
1616
}
1717

@@ -29,7 +29,7 @@ func isRoleAllowedToPerformAction(role string, action core.Action) bool {
2929
return false
3030
}
3131

32-
func NewExternalEntityProviderRBAC(ctx core.Context, thirdPartyIntegration core.ThirdPartyIntegration, externalEntityProviderID string, adminToken string) core.AccessControl {
32+
func NewExternalEntityProviderRBAC(ctx core.Context, thirdPartyIntegration core.ThirdPartyIntegration, externalEntityProviderID string, adminToken *string) core.AccessControl {
3333
return &externalEntityProviderRBAC{
3434
thirdPartyIntegration: thirdPartyIntegration,
3535
externalEntityProviderID: externalEntityProviderID,
@@ -79,7 +79,7 @@ func (e *externalEntityProviderRBAC) GetExternalEntityProviderID() *string {
7979
*/
8080

8181
func (e *externalEntityProviderRBAC) HasAccess(userID string) (bool, error) {
82-
if userID == e.adminToken {
82+
if e.adminToken != nil && userID == *e.adminToken {
8383
return true, nil
8484
}
8585
return e.thirdPartyIntegration.HasAccessToExternalEntityProvider(e.ctx, e.externalEntityProviderID)
@@ -117,7 +117,7 @@ func (e *externalEntityProviderRBAC) AllowRole(role string, object core.Object,
117117
return nil
118118
}
119119
func (e *externalEntityProviderRBAC) IsAllowed(userID string, object core.Object, action core.Action) (bool, error) {
120-
if userID == e.adminToken {
120+
if e.adminToken != nil && userID == *e.adminToken {
121121
if action == core.ActionRead {
122122
return true, nil
123123
}
@@ -142,7 +142,7 @@ func (e *externalEntityProviderRBAC) IsAllowedInProject(project *models.Project,
142142
if project.ExternalEntityProviderID == nil || project.ExternalEntityID == nil {
143143
return false, nil
144144
}
145-
if user == e.adminToken && action == core.ActionRead {
145+
if e.adminToken != nil && user == *e.adminToken && action == core.ActionRead {
146146
return true, nil
147147
}
148148

internal/accesscontrol/external_entity_provider_rbac_test.go

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"testing"
66

77
"github.com/l3montree-dev/devguard/internal/core"
8+
"github.com/l3montree-dev/devguard/internal/utils"
89
"github.com/l3montree-dev/devguard/mocks"
910
"github.com/stretchr/testify/assert"
1011
"github.com/stretchr/testify/mock"
@@ -17,7 +18,7 @@ func TestIsAllowed(t *testing.T) {
1718
userID string
1819
object core.Object
1920
action core.Action
20-
adminToken string
21+
adminToken *string
2122
mockRole string
2223
mockRoleErr error
2324
expectedResult bool
@@ -30,23 +31,23 @@ func TestIsAllowed(t *testing.T) {
3031
userID: "admin-token",
3132
object: core.ObjectProject,
3233
action: core.ActionRead,
33-
adminToken: "admin-token",
34+
adminToken: utils.Ptr("admin-token"),
3435
expectedResult: true,
3536
},
3637
{
3738
name: "all users can read organization",
3839
userID: "user1",
3940
object: core.ObjectOrganization,
4041
action: core.ActionRead,
41-
adminToken: "admin-token",
42+
adminToken: utils.Ptr("admin-token"),
4243
expectedResult: true,
4344
},
4445
{
4546
name: "role member can read",
4647
userID: "user2",
4748
object: core.ObjectProject,
4849
action: core.ActionRead,
49-
adminToken: "admin-token",
50+
adminToken: utils.Ptr("admin-token"),
5051
mockRole: core.RoleMember,
5152
expectedResult: true,
5253
},
@@ -55,7 +56,7 @@ func TestIsAllowed(t *testing.T) {
5556
userID: "user3",
5657
object: core.ObjectProject,
5758
action: core.ActionUpdate,
58-
adminToken: "admin-token",
59+
adminToken: utils.Ptr("admin-token"),
5960
mockRole: core.RoleAdmin,
6061
expectedResult: true,
6162
},
@@ -64,7 +65,7 @@ func TestIsAllowed(t *testing.T) {
6465
userID: "user4",
6566
object: core.ObjectProject,
6667
action: core.ActionUpdate,
67-
adminToken: "admin-token",
68+
adminToken: utils.Ptr("admin-token"),
6869
mockRole: core.RoleMember,
6970
expectedResult: false,
7071
},
@@ -73,7 +74,7 @@ func TestIsAllowed(t *testing.T) {
7374
userID: "user5",
7475
object: core.ObjectProject,
7576
action: core.ActionRead,
76-
adminToken: "admin-token",
77+
adminToken: utils.Ptr("admin-token"),
7778
mockRoleErr: errors.New("some error"),
7879
expectErr: true,
7980
},
@@ -82,7 +83,7 @@ func TestIsAllowed(t *testing.T) {
8283
userID: "user6",
8384
object: core.ObjectProject,
8485
action: core.ActionDelete,
85-
adminToken: "admin-token",
86+
adminToken: utils.Ptr("admin-token"),
8687
mockRole: core.RoleAdmin,
8788
expectedResult: false,
8889
},
@@ -91,7 +92,7 @@ func TestIsAllowed(t *testing.T) {
9192
userID: "user7",
9293
object: core.ObjectProject,
9394
action: core.ActionDelete,
94-
adminToken: "admin-token",
95+
adminToken: utils.Ptr("admin-token"),
9596
mockRole: core.RoleMember,
9697
expectedResult: false,
9798
},
@@ -100,7 +101,7 @@ func TestIsAllowed(t *testing.T) {
100101
userID: "user8",
101102
object: core.ObjectProject,
102103
action: core.ActionDelete,
103-
adminToken: "admin-token",
104+
adminToken: utils.Ptr("admin-token"),
104105
mockRole: core.RoleOwner,
105106
expectedResult: true,
106107
},
@@ -109,15 +110,15 @@ func TestIsAllowed(t *testing.T) {
109110
userID: "admin-token",
110111
object: core.ObjectProject,
111112
action: core.ActionCreate,
112-
adminToken: "admin-token",
113+
adminToken: utils.Ptr("admin-token"),
113114
expectedResult: false,
114115
},
115116
{
116117
name: "admin token cannot delete",
117118
userID: "admin-token",
118119
object: core.ObjectProject,
119120
action: core.ActionDelete,
120-
adminToken: "admin-token",
121+
adminToken: utils.Ptr("admin-token"),
121122
expectedResult: false,
122123
},
123124
}
@@ -159,7 +160,7 @@ func TestHasAccess(t *testing.T) {
159160
nil,
160161
nil,
161162
"external-entity-provider-id",
162-
"admin-token",
163+
utils.Ptr("admin-token"),
163164
)
164165

165166
hasAccess, err := rbac.HasAccess("admin-token")
@@ -175,7 +176,7 @@ func TestHasAccess(t *testing.T) {
175176
nil,
176177
thirdpartyIntegrationMock,
177178
"external-entity-provider-id",
178-
"",
179+
nil,
179180
)
180181

181182
hasAccess, err := rbac.HasAccess("user1")
@@ -190,7 +191,7 @@ func TestHasAccess(t *testing.T) {
190191
nil,
191192
thirdpartyIntegrationMock,
192193
"external-entity-provider-id",
193-
"",
194+
nil,
194195
)
195196

196197
hasAccess, err := rbac.HasAccess("user1")

internal/core/integrations/gitlabint/gitlab_integration.go

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,15 +336,44 @@ func (g *GitlabIntegration) ListGroups(ctx core.Context, userID string, provider
336336
}
337337
// get the groups for this user
338338
groups, _, err := gitlabClient.ListGroups(ctx.Request().Context(), &gitlab.ListGroupsOptions{
339-
MinAccessLevel: utils.Ptr(gitlab.ReporterPermissions), // only list groups where the user has at least owner permissions
339+
ListOptions: gitlab.ListOptions{PerPage: 100},
340+
//MinAccessLevel: utils.Ptr(gitlab.ReporterPermissions),
341+
// only list groups where the user has at least reporter permissions
340342
})
341343

342344
if err != nil {
343345
slog.Error("failed to list groups", "err", err)
344346
return nil, err
345347
}
346348

347-
return utils.Map(groups, func(el *gitlab.Group) models.Project {
349+
errgroup := utils.ErrGroup[*gitlab.Group](10)
350+
for _, group := range groups {
351+
errgroup.Go(func() (*gitlab.Group, error) {
352+
member, _, err := gitlabClient.GetMemberInGroup(ctx.Request().Context(), token.GitLabUserID, (*group).ID)
353+
if err != nil {
354+
if strings.Contains(err.Error(), "403 Forbidden") || strings.Contains(err.Error(), "404 Not Found") {
355+
return nil, nil
356+
} else {
357+
358+
return nil, err
359+
}
360+
}
361+
if member.AccessLevel >= gitlab.ReporterPermissions {
362+
return group, nil
363+
}
364+
return nil, nil
365+
})
366+
}
367+
368+
cleanedGroups, err := errgroup.WaitAndCollect()
369+
if err != nil {
370+
return nil, err
371+
}
372+
cleanedGroups = utils.Filter(cleanedGroups, func(g *gitlab.Group) bool {
373+
return g != nil
374+
})
375+
376+
return utils.Map(cleanedGroups, func(el *gitlab.Group) models.Project {
348377
return groupToProject(el, providerID)
349378
}), nil
350379
}

internal/core/integrations/thirdparty_integration.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ func (t *thirdPartyIntegrations) GetRoleInGroup(ctx context.Context, userID stri
102102
return role, nil
103103
}
104104
}
105+
//when we are part of a subgroup we also have some basic access level to see the parent groups but we have no permissions to fetch the members of those groups
105106
return "", fmt.Errorf("no role found for user %s in org %s with providerID %s", userID, groupID, providerID)
106107
}
107108

internal/core/org/org_service.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ func (o *orgService) CreateOrganization(ctx core.Context, organization models.Or
5959
return echo.NewHTTPError(409, "organizations with an empty name or an empty slug are not allowed").WithInternal(fmt.Errorf("organizations with an empty name or an empty slug are not allowed"))
6060
}
6161

62+
if organization.Name == "opencode" || organization.Name == "gitlab" || organization.Name == "github" {
63+
return echo.NewHTTPError(409, "organizations named opencode, github or gitlab are not allowed").WithInternal(fmt.Errorf("organizations named opencode, github or gitlab are not allowed"))
64+
}
65+
6266
err := o.organizationRepository.Create(nil, &organization)
6367
if err != nil {
6468
if strings.Contains(err.Error(), "duplicate key value") { //Check the returned error of Create Function

0 commit comments

Comments
 (0)