aboutsummaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
authorKN4CK3R <admin@oldschoolhack.me>2023-07-09 13:24:43 +0200
committerGitHub <noreply@github.com>2023-07-09 11:24:43 +0000
commit115f40e43368fefc776232a2df289b2fcadbb11d (patch)
tree5a892ca23c2fc5173a39aa439cce428ede7356fc /models
parent38844e0869bff0a08f8810c97cb3f5cb07df9a8e (diff)
downloadgitea-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.go46
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{})
+}