@@ -5,11 +5,18 @@ package packages
55
66import (
77 "context"
8+ "strconv"
89 "time"
910
1011 "code.gitea.io/gitea/models/db"
12+ "code.gitea.io/gitea/models/perm"
13+ "code.gitea.io/gitea/models/unit"
14+ user_model "code.gitea.io/gitea/models/user"
15+ "code.gitea.io/gitea/modules/structs"
1116 "code.gitea.io/gitea/modules/timeutil"
1217 "code.gitea.io/gitea/modules/util"
18+
19+ "xorm.io/builder"
1320)
1421
1522// ErrPackageBlobNotExist indicates a package blob not exist error
@@ -98,3 +105,42 @@ func GetTotalUnreferencedBlobSize(ctx context.Context) (int64, error) {
98105 Where ("package_file.id IS NULL" ).
99106 SumInt (& PackageBlob {}, "size" )
100107}
108+
109+ // IsBlobAccessibleForUser tests if the user has access to the blob
110+ func IsBlobAccessibleForUser (ctx context.Context , blobID int64 , user * user_model.User ) (bool , error ) {
111+ if user .IsAdmin {
112+ return true , nil
113+ }
114+
115+ maxTeamAuthorize := builder .
116+ Select ("max(team.authorize)" ).
117+ From ("team" ).
118+ InnerJoin ("team_user" , "team_user.team_id = team.id" ).
119+ Where (builder.Eq {"team_user.uid" : user .ID }.And (builder .Expr ("team_user.org_id = `user`.id" )))
120+
121+ maxTeamUnitAccessMode := builder .
122+ Select ("max(team_unit.access_mode)" ).
123+ From ("team" ).
124+ InnerJoin ("team_user" , "team_user.team_id = team.id" ).
125+ InnerJoin ("team_unit" , "team_unit.team_id = team.id" ).
126+ Where (builder.Eq {"team_user.uid" : user .ID , "team_unit.type" : unit .TypePackages }.And (builder .Expr ("team_user.org_id = `user`.id" )))
127+
128+ cond := builder.Eq {"package_blob.id" : blobID }.And (
129+ // owner = user
130+ builder.Eq {"`user`.id" : user .ID }.
131+ // user can see owner
132+ Or (builder.Eq {"`user`.visibility" : structs .VisibleTypePublic }.Or (builder.Eq {"`user`.visibility" : structs .VisibleTypeLimited })).
133+ // owner is an organization and user has access to it
134+ Or (builder.Eq {"`user`.type" : user_model .UserTypeOrganization }.
135+ And (builder.Lte {strconv .Itoa (int (perm .AccessModeRead )): maxTeamAuthorize }.Or (builder.Lte {strconv .Itoa (int (perm .AccessModeRead )): maxTeamUnitAccessMode }))),
136+ )
137+
138+ return db .GetEngine (ctx ).
139+ Table ("package_blob" ).
140+ Join ("INNER" , "package_file" , "package_file.blob_id = package_blob.id" ).
141+ Join ("INNER" , "package_version" , "package_version.id = package_file.version_id" ).
142+ Join ("INNER" , "package" , "package.id = package_version.package_id" ).
143+ Join ("INNER" , "user" , "`user`.id = package.owner_id" ).
144+ Where (cond ).
145+ Exist (& PackageBlob {})
146+ }
0 commit comments