Skip to content

Commit 7c0e63e

Browse files
authored
Auditors authentication landing on wrong org (#2463)
* use can_view_org instead so roles like auditors can view * add auditor login test * bump to 1.26.4 to fix vulnerability * go mod tidy * try to use distinct email
1 parent f62bcc6 commit 7c0e63e

9 files changed

Lines changed: 43 additions & 8 deletions

File tree

cli/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/theopenlane/core/cli
22

3-
go 1.26.3
3+
go 1.26.4
44

55
require (
66
github.com/99designs/gqlgen v0.17.90

common/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/theopenlane/core/common
22

3-
go 1.26.3
3+
go 1.26.4
44

55
require (
66
entgo.io/ent v0.14.6

common/go.sum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
ariga.io/atlas v1.2.1 h1:xLIs6vThJ2J9Bl8gXFZhXbNyMf4yFuBeJ7AYlZ+Tn6M=
2+
ariga.io/atlas v1.2.1/go.mod h1:vg7qWSatkNqs04Y4Lheg7vR4bGX0wy51Wz4FIMFVr3U=
23
entgo.io/contrib v0.7.0 h1:4Ghx8O0rqSMmca3FIJ6QyZbQAoLvdzWqLMl1MbHFEEw=
34
entgo.io/contrib v0.7.0/go.mod h1:zbPSUrbn+6dfyv8S9HWEvn1MyGpO95ik2lUNgaqWTt4=
45
entgo.io/ent v0.14.6 h1:/f2696BpwuWAEEG6PVGWflg6+Inrpq4pRWuNlWz/Skk=

docker/all-in-one/Dockerfile.all-in-one

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM golang:1.26.3 as builder
1+
FROM golang:1.26.4 as builder
22

33
WORKDIR /go/src/app
44
COPY . .

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/theopenlane/core
22

3-
go 1.26.3
3+
go 1.26.4
44

55
tool (
66
github.com/dave/jennifer

go.work

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
go 1.26.3
1+
go 1.26.4
22

33
use (
44
// core is the main module containing the API and business logic, nothing in pkg or internal should be imported by other modules

internal/ent/hooks/usersettings.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,11 @@ func allowDefaultOrgUpdate(ctx context.Context, m *generated.UserSettingMutation
8484
SubjectID: owner.ID,
8585
SubjectType: auth.UserSubjectType,
8686
ObjectID: orgID,
87+
Relation: "can_view_org",
8788
Context: utils.NewOrganizationContextKey(usCaller.SubjectEmail),
8889
}
8990

90-
allow, err := m.Authz.CheckOrgReadAccess(ctx, req)
91+
allow, err := m.Authz.CheckOrgAccess(ctx, req)
9192
if err != nil {
9293
return false
9394
}

internal/httpserve/authmanager/authmanager.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,15 +262,16 @@ func (a *Client) authCheck(ctx context.Context, user *generated.User, orgID stri
262262
orgID = caller.OrganizationID
263263
}
264264

265-
// ensure user is already a member of the destination organization
265+
// ensure user can access the destination organization
266266
req := fgax.AccessCheck{
267267
SubjectID: caller.SubjectID,
268268
SubjectType: auth.UserSubjectType,
269269
ObjectID: orgID,
270+
Relation: "can_view_org",
270271
Context: utils.NewOrganizationContextKey(caller.SubjectEmail),
271272
}
272273

273-
allow, err := a.db.Authz.CheckOrgReadAccess(ctx, req)
274+
allow, err := a.db.Authz.CheckOrgAccess(ctx, req)
274275
if err != nil {
275276
logx.FromContext(ctx).Error().Err(err).Str("user_id", caller.SubjectID).Str("org_id", orgID).Msg("unable to check org read access")
276277

internal/httpserve/handlers/login_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,14 @@ func (suite *HandlerTestSuite) TestLoginHandler() {
110110
confirmedUser: true,
111111
tfaEnabled: tfaTrue,
112112
})
113+
114+
auditorUser := suite.userBuilderWithInput(ctx, &userInput{
115+
email: "auditor+" + strings.ToLower(ulids.New().String()) + "@examples.com",
116+
password: validPassword,
117+
confirmedUser: true,
118+
tfaEnabled: tfaTrue,
119+
})
120+
113121
// setup allow context with the client in the context which is required for hooks that run
114122
allowCtx := privacy.DecisionContext(validConfirmedUserRestrictedOrg.UserCtx, privacy.Allow)
115123
allowCtx = ent.NewContext(allowCtx, suite.db)
@@ -121,6 +129,10 @@ func (suite *HandlerTestSuite) TestLoginHandler() {
121129
ctxTargetOrg = privacy.DecisionContext(ctxTargetOrg, privacy.Allow)
122130
testUserCtx := ent.NewContext(ctxTargetOrg, suite.db)
123131

132+
auditorOrgCtx := auth.NewTestContextWithOrgID(validConfirmedUserRestrictedOrg.ID, org.ID)
133+
auditorOrgCtx = privacy.DecisionContext(auditorOrgCtx, privacy.Allow)
134+
auditorOrgCtx = ent.NewContext(auditorOrgCtx, suite.db)
135+
124136
suite.db.OrgMembership.Create().SetInput(generated.CreateOrgMembershipInput{
125137
OrganizationID: createdssoOrg.ID,
126138
UserID: ssoMember.UserInfo.ID,
@@ -129,6 +141,14 @@ func (suite *HandlerTestSuite) TestLoginHandler() {
129141

130142
suite.db.UserSetting.UpdateOneID(ssoMember.UserInfo.Edges.Setting.ID).SetDefaultOrgID(createdssoOrg.ID).ExecX(allowCtx)
131143

144+
suite.db.OrgMembership.Create().SetInput(generated.CreateOrgMembershipInput{
145+
OrganizationID: org.ID,
146+
UserID: auditorUser.UserInfo.ID,
147+
Role: &enums.RoleAuditor,
148+
}).ExecX(auditorOrgCtx)
149+
150+
suite.db.UserSetting.UpdateOneID(auditorUser.UserInfo.Edges.Setting.ID).SetDefaultOrgID(org.ID).ExecX(allowCtx)
151+
132152
// update the user settings to have the default org set that is the domain restricted org
133153
suite.db.UserSetting.UpdateOneID(validConfirmedUserRestrictedOrg.UserInfo.Edges.Setting.ID).
134154
SetDefaultOrgID(org.ID).ExecX(allowCtx)
@@ -176,6 +196,18 @@ func (suite *HandlerTestSuite) TestLoginHandler() {
176196
models.CatalogTrustCenterModule.String(),
177197
},
178198
},
199+
{
200+
name: "happy path, auditor default org",
201+
username: auditorUser.UserInfo.Email,
202+
password: validPassword,
203+
expectedStatus: http.StatusOK,
204+
expectedOrgID: org.ID,
205+
expectedModules: []interface{}{
206+
models.CatalogBaseModule.String(),
207+
models.CatalogComplianceModule.String(),
208+
models.CatalogTrustCenterModule.String(),
209+
},
210+
},
179211
{
180212
name: "domain restricted org, email not allowed, switch to personal org",
181213
username: invalidConfirmedUserRestrictedOrg.UserInfo.Email,

0 commit comments

Comments
 (0)