Skip to content

Commit bbf83f5

Browse files
yp05327delvh
andauthored
Improve permission check of packages (#23879)
At first, we have one unified team unit permission which is called `Team.Authorize` in DB. But since #17811, we allowed different units to have different permission. The old code is only designed for the old version. So after #17811, if org users have write permission of other units, but have no permission of packages, they can also get write permission of packages. Co-authored-by: delvh <dev.lh@web.de>
1 parent 5cb394f commit bbf83f5

File tree

8 files changed

+63
-26
lines changed

8 files changed

+63
-26
lines changed

models/fixtures/org_user.yml

+6
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,9 @@
7575
uid: 31
7676
org_id: 19
7777
is_public: true
78+
79+
-
80+
id: 14
81+
uid: 5
82+
org_id: 23
83+
is_public: false

models/fixtures/team.yml

+12-1
Original file line numberDiff line numberDiff line change
@@ -172,4 +172,15 @@
172172
num_repos: 0
173173
num_members: 0
174174
includes_all_repositories: false
175-
can_create_org_repo: true
175+
can_create_org_repo: true
176+
177+
-
178+
id: 17
179+
org_id: 23
180+
lower_name: team14writeauth
181+
name: team14WriteAuth
182+
authorize: 2 # write
183+
num_repos: 0
184+
num_members: 1
185+
includes_all_repositories: false
186+
can_create_org_repo: true

models/fixtures/team_unit.yml

+6
Original file line numberDiff line numberDiff line change
@@ -268,3 +268,9 @@
268268
team_id: 9
269269
type: 1 # code
270270
access_mode: 1
271+
272+
-
273+
id: 46
274+
team_id: 17
275+
type: 9 # package
276+
access_mode: 0

models/fixtures/team_user.yml

+6
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,9 @@
9999
org_id: 3
100100
team_id: 14
101101
uid: 2
102+
103+
-
104+
id: 18
105+
org_id: 23
106+
team_id: 17
107+
uid: 5

models/fixtures/user.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -844,8 +844,8 @@
844844
num_following: 0
845845
num_stars: 0
846846
num_repos: 2
847-
num_teams: 1
848-
num_members: 0
847+
num_teams: 2
848+
num_members: 1
849849
visibility: 2
850850
repo_admin_change_team_access: false
851851
theme: ""

models/organization/org_test.go

+11-5
Original file line numberDiff line numberDiff line change
@@ -212,25 +212,31 @@ func TestGetOrgUsersByUserID(t *testing.T) {
212212

213213
orgUsers, err := organization.GetOrgUsersByUserID(5, &organization.SearchOrganizationsOptions{All: true})
214214
assert.NoError(t, err)
215-
if assert.Len(t, orgUsers, 2) {
215+
if assert.Len(t, orgUsers, 3) {
216216
assert.Equal(t, organization.OrgUser{
217217
ID: orgUsers[0].ID,
218-
OrgID: 6,
218+
OrgID: 23,
219219
UID: 5,
220-
IsPublic: true,
220+
IsPublic: false,
221221
}, *orgUsers[0])
222222
assert.Equal(t, organization.OrgUser{
223223
ID: orgUsers[1].ID,
224+
OrgID: 6,
225+
UID: 5,
226+
IsPublic: true,
227+
}, *orgUsers[1])
228+
assert.Equal(t, organization.OrgUser{
229+
ID: orgUsers[2].ID,
224230
OrgID: 7,
225231
UID: 5,
226232
IsPublic: false,
227-
}, *orgUsers[1])
233+
}, *orgUsers[2])
228234
}
229235

230236
publicOrgUsers, err := organization.GetOrgUsersByUserID(5, &organization.SearchOrganizationsOptions{All: false})
231237
assert.NoError(t, err)
232238
assert.Len(t, publicOrgUsers, 1)
233-
assert.Equal(t, *orgUsers[0], *publicOrgUsers[0])
239+
assert.Equal(t, *orgUsers[1], *publicOrgUsers[0])
234240

235241
orgUsers, err = organization.GetOrgUsersByUserID(1, &organization.SearchOrganizationsOptions{All: true})
236242
assert.NoError(t, err)

modules/context/package.go

+10-18
Original file line numberDiff line numberDiff line change
@@ -92,33 +92,25 @@ func determineAccessMode(ctx *Context) (perm.AccessMode, error) {
9292
return perm.AccessModeNone, nil
9393
}
9494

95+
// TODO: ActionUser permission check
9596
accessMode := perm.AccessModeNone
9697
if ctx.Package.Owner.IsOrganization() {
9798
org := organization.OrgFromUser(ctx.Package.Owner)
9899

99-
// 1. Get user max authorize level for the org (may be none, if user is not member of the org)
100-
if ctx.Doer != nil {
101-
var err error
102-
accessMode, err = org.GetOrgUserMaxAuthorizeLevel(ctx.Doer.ID)
100+
if ctx.Doer != nil && !ctx.Doer.IsGhost() {
101+
// 1. If user is logged in, check all team packages permissions
102+
teams, err := organization.GetUserOrgTeams(ctx, org.ID, ctx.Doer.ID)
103103
if err != nil {
104104
return accessMode, err
105105
}
106-
// If access mode is less than write check every team for more permissions
107-
if accessMode < perm.AccessModeWrite {
108-
teams, err := organization.GetUserOrgTeams(ctx, org.ID, ctx.Doer.ID)
109-
if err != nil {
110-
return accessMode, err
111-
}
112-
for _, t := range teams {
113-
perm := t.UnitAccessMode(ctx, unit.TypePackages)
114-
if accessMode < perm {
115-
accessMode = perm
116-
}
106+
for _, t := range teams {
107+
perm := t.UnitAccessMode(ctx, unit.TypePackages)
108+
if accessMode < perm {
109+
accessMode = perm
117110
}
118111
}
119-
}
120-
// 2. If authorize level is none, check if org is visible to user
121-
if accessMode == perm.AccessModeNone && organization.HasOrgOrUserVisible(ctx, ctx.Package.Owner, ctx.Doer) {
112+
} else if organization.HasOrgOrUserVisible(ctx, ctx.Package.Owner, ctx.Doer) {
113+
// 2. If user is non-login, check if org is visible to non-login user
122114
accessMode = perm.AccessModeRead
123115
}
124116
} else {

tests/integration/api_packages_test.go

+10
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ func TestPackageAccess(t *testing.T) {
157157
admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
158158
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
159159
inactive := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 9})
160+
privatedOrg := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 23})
160161

161162
uploadPackage := func(doer, owner *user_model.User, expectedStatus int) {
162163
url := fmt.Sprintf("/api/packages/%s/generic/test-package/1.0/file.bin", owner.Name)
@@ -170,6 +171,15 @@ func TestPackageAccess(t *testing.T) {
170171
uploadPackage(inactive, user, http.StatusUnauthorized)
171172
uploadPackage(admin, inactive, http.StatusCreated)
172173
uploadPackage(admin, user, http.StatusCreated)
174+
175+
// team.authorize is write, but team_unit.access_mode is none
176+
// so the user can not upload packages or get package list
177+
uploadPackage(user, privatedOrg, http.StatusUnauthorized)
178+
179+
session := loginUser(t, user.Name)
180+
tokenReadPackage := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadPackage)
181+
req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s?token=%s", privatedOrg.Name, tokenReadPackage))
182+
MakeRequest(t, req, http.StatusForbidden)
173183
}
174184

175185
func TestPackageQuota(t *testing.T) {

0 commit comments

Comments
 (0)