Test if container blob is accessible before mounting (#22759)
related #16865 This PR adds an accessibility check before mounting container blobs. --------- Co-authored-by: techknowlogick <techknowlogick@gitea.io> Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
parent
38844e0869
commit
115f40e433
3 changed files with 72 additions and 8 deletions
|
@ -5,11 +5,18 @@ package packages
|
|||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
// ErrPackageBlobNotExist indicates a package blob not exist error
|
||||
|
@ -98,3 +105,42 @@ func GetTotalUnreferencedBlobSize(ctx context.Context) (int64, error) {
|
|||
Where("package_file.id IS NULL").
|
||||
SumInt(&PackageBlob{}, "size")
|
||||
}
|
||||
|
||||
// IsBlobAccessibleForUser tests if the user has access to the blob
|
||||
func IsBlobAccessibleForUser(ctx context.Context, blobID int64, user *user_model.User) (bool, error) {
|
||||
if user.IsAdmin {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
maxTeamAuthorize := builder.
|
||||
Select("max(team.authorize)").
|
||||
From("team").
|
||||
InnerJoin("team_user", "team_user.team_id = team.id").
|
||||
Where(builder.Eq{"team_user.uid": user.ID}.And(builder.Expr("team_user.org_id = `user`.id")))
|
||||
|
||||
maxTeamUnitAccessMode := builder.
|
||||
Select("max(team_unit.access_mode)").
|
||||
From("team").
|
||||
InnerJoin("team_user", "team_user.team_id = team.id").
|
||||
InnerJoin("team_unit", "team_unit.team_id = team.id").
|
||||
Where(builder.Eq{"team_user.uid": user.ID, "team_unit.type": unit.TypePackages}.And(builder.Expr("team_user.org_id = `user`.id")))
|
||||
|
||||
cond := builder.Eq{"package_blob.id": blobID}.And(
|
||||
// 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})).
|
||||
// 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}))),
|
||||
)
|
||||
|
||||
return db.GetEngine(ctx).
|
||||
Table("package_blob").
|
||||
Join("INNER", "package_file", "package_file.blob_id = package_blob.id").
|
||||
Join("INNER", "package_version", "package_version.id = package_file.version_id").
|
||||
Join("INNER", "package", "package.id = package_version.package_id").
|
||||
Join("INNER", "user", "`user`.id = package.owner_id").
|
||||
Where(cond).
|
||||
Exist(&PackageBlob{})
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue