diff options
author | KN4CK3R <admin@oldschoolhack.me> | 2023-07-09 13:24:43 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-09 11:24:43 +0000 |
commit | 115f40e43368fefc776232a2df289b2fcadbb11d (patch) | |
tree | 5a892ca23c2fc5173a39aa439cce428ede7356fc /models | |
parent | 38844e0869bff0a08f8810c97cb3f5cb07df9a8e (diff) | |
download | gitea-115f40e43368fefc776232a2df289b2fcadbb11d.tar.gz gitea-115f40e43368fefc776232a2df289b2fcadbb11d.zip |
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>
Diffstat (limited to 'models')
-rw-r--r-- | models/packages/package_blob.go | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/models/packages/package_blob.go b/models/packages/package_blob.go index a55109af96..d1f470d520 100644 --- a/models/packages/package_blob.go +++ b/models/packages/package_blob.go @@ -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{}) +} |