mirror of
https://github.com/go-gitea/gitea.git
synced 2026-08-29 02:04:15 +00:00
fix(packages): restrict/limited/token-scope access (#39041, #39043, #39044, #39047, #39046) (#39058)
This commit is contained in:
@@ -91,6 +91,14 @@ func (org *Organization) IsOwnedBy(ctx context.Context, uid int64) (bool, error)
|
||||
return IsOrganizationOwner(ctx, org.ID, uid)
|
||||
}
|
||||
|
||||
// CanChangeRepoTeamAccess reports whether a repository administrator can change team access.
|
||||
func (org *Organization) CanChangeRepoTeamAccess(ctx context.Context, doer *user_model.User) (bool, error) {
|
||||
if org.RepoAdminChangeTeamAccess || doer.IsAdmin {
|
||||
return true, nil
|
||||
}
|
||||
return org.IsOwnedBy(ctx, doer.ID)
|
||||
}
|
||||
|
||||
// IsOrgAdmin returns true if given user is in the owner team or an admin team.
|
||||
func (org *Organization) IsOrgAdmin(ctx context.Context, uid int64) (bool, error) {
|
||||
return IsOrganizationAdmin(ctx, org.ID, uid)
|
||||
|
||||
@@ -89,6 +89,9 @@ func DoerViewOtherVisibility(doer, other *user_model.User) structs.VisibleType {
|
||||
if doer.IsAdmin || doer.ID == other.ID {
|
||||
return structs.VisibleTypePrivate
|
||||
}
|
||||
if doer.IsRestricted {
|
||||
return structs.VisibleTypePublic
|
||||
}
|
||||
return structs.VisibleTypeLimited
|
||||
}
|
||||
|
||||
|
||||
@@ -77,8 +77,14 @@ func testLoadOrgListTeams(t *testing.T) {
|
||||
}
|
||||
|
||||
func testDoerViewOtherVisibility(t *testing.T) {
|
||||
viewer := &user_model.User{ID: 1}
|
||||
other := &user_model.User{ID: 2}
|
||||
restrictedViewer := &user_model.User{ID: 3, IsRestricted: true}
|
||||
|
||||
assert.Equal(t, structs.VisibleTypePublic, organization.DoerViewOtherVisibility(nil, nil))
|
||||
assert.Equal(t, structs.VisibleTypeLimited, organization.DoerViewOtherVisibility(&user_model.User{ID: 1}, &user_model.User{ID: 2}))
|
||||
assert.Equal(t, structs.VisibleTypePrivate, organization.DoerViewOtherVisibility(&user_model.User{ID: 1}, &user_model.User{ID: 1}))
|
||||
assert.Equal(t, structs.VisibleTypePrivate, organization.DoerViewOtherVisibility(&user_model.User{ID: 1, IsAdmin: true}, &user_model.User{ID: 2}))
|
||||
assert.Equal(t, structs.VisibleTypeLimited, organization.DoerViewOtherVisibility(viewer, other))
|
||||
assert.Equal(t, structs.VisibleTypePublic, organization.DoerViewOtherVisibility(restrictedViewer, other))
|
||||
assert.Equal(t, structs.VisibleTypePrivate, organization.DoerViewOtherVisibility(viewer, viewer))
|
||||
assert.Equal(t, structs.VisibleTypePrivate, organization.DoerViewOtherVisibility(restrictedViewer, restrictedViewer))
|
||||
assert.Equal(t, structs.VisibleTypePrivate, organization.DoerViewOtherVisibility(&user_model.User{ID: 4, IsAdmin: true, IsRestricted: true}, other))
|
||||
}
|
||||
|
||||
@@ -126,6 +126,10 @@ func IsBlobAccessibleForUser(ctx context.Context, blobID int64, user *user_model
|
||||
if user.IsAdmin {
|
||||
return true, nil
|
||||
}
|
||||
ownerVisibilities := []structs.VisibleType{structs.VisibleTypePublic}
|
||||
if !user.IsRestricted {
|
||||
ownerVisibilities = append(ownerVisibilities, structs.VisibleTypeLimited)
|
||||
}
|
||||
|
||||
maxTeamAuthorize := builder.
|
||||
Select("max(team.authorize)").
|
||||
@@ -144,7 +148,7 @@ func IsBlobAccessibleForUser(ctx context.Context, blobID int64, user *user_model
|
||||
// owner = user
|
||||
builder.Eq{"`user`.id": user.ID}.
|
||||
// user can see owner
|
||||
Or(builder.Eq{"`user`.visibility": structs.VisibleTypePublic}.Or(builder.Eq{"`user`.visibility": structs.VisibleTypeLimited})).
|
||||
Or(builder.In("`user`.visibility", ownerVisibilities)).
|
||||
// owner is an organization and user has access to it
|
||||
Or(builder.Eq{"`user`.type": user_model.UserTypeOrganization}.
|
||||
And(builder.Lte{strconv.Itoa(int(perm.AccessModeRead)): maxTeamAuthorize}.Or(builder.Lte{strconv.Itoa(int(perm.AccessModeRead)): maxTeamUnitAccessMode}))),
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"gitea.dev/models/unittest"
|
||||
user_model "gitea.dev/models/user"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -49,3 +50,25 @@ func TestGetOrInsertBlobConcurrent(t *testing.T) {
|
||||
}
|
||||
assert.Equal(t, numGoroutines-1, existedCount)
|
||||
}
|
||||
|
||||
func TestIsBlobAccessibleForRestrictedUser(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 33})
|
||||
pkg, err := TryInsertPackage(t.Context(), &Package{OwnerID: owner.ID, Type: TypeContainer, Name: "limited", LowerName: "limited"})
|
||||
require.NoError(t, err)
|
||||
version, err := GetOrInsertVersion(t.Context(), &PackageVersion{PackageID: pkg.ID, Version: "1", LowerVersion: "1"})
|
||||
require.NoError(t, err)
|
||||
blob, _, err := GetOrInsertBlob(t.Context(), &PackageBlob{Size: 1, HashMD5: "md5", HashSHA1: "sha1", HashSHA256: "sha256", HashSHA512: "sha512"})
|
||||
require.NoError(t, err)
|
||||
_, err = TryInsertFile(t.Context(), &PackageFile{VersionID: version.ID, BlobID: blob.ID, Name: "blob", LowerName: "blob"})
|
||||
require.NoError(t, err)
|
||||
|
||||
accessible, err := IsBlobAccessibleForUser(t.Context(), blob.ID, unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}))
|
||||
require.NoError(t, err)
|
||||
assert.True(t, accessible)
|
||||
|
||||
accessible, err = IsBlobAccessibleForUser(t.Context(), blob.ID, unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 29}))
|
||||
require.NoError(t, err)
|
||||
assert.False(t, accessible)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user