Skip to content

Commit 8adba93

Browse files
authored
Hide private repositories in packages (#19584)
1 parent 38d72d4 commit 8adba93

File tree

8 files changed

+115
-20
lines changed

8 files changed

+115
-20
lines changed

integrations/api_packages_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,44 @@ func TestPackageAPI(t *testing.T) {
7171
assert.Equal(t, packageVersion, p.Version)
7272
assert.NotNil(t, p.Creator)
7373
assert.Equal(t, user.Name, p.Creator.UserName)
74+
75+
t.Run("RepositoryLink", func(t *testing.T) {
76+
defer PrintCurrentTest(t)()
77+
78+
p, err := packages_model.GetPackageByName(db.DefaultContext, user.ID, packages_model.TypeGeneric, packageName)
79+
assert.NoError(t, err)
80+
81+
// no repository link
82+
req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, token))
83+
resp := MakeRequest(t, req, http.StatusOK)
84+
85+
var ap1 *api.Package
86+
DecodeJSON(t, resp, &ap1)
87+
assert.Nil(t, ap1.Repository)
88+
89+
// link to public repository
90+
assert.NoError(t, packages_model.SetRepositoryLink(db.DefaultContext, p.ID, 1))
91+
92+
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, token))
93+
resp = MakeRequest(t, req, http.StatusOK)
94+
95+
var ap2 *api.Package
96+
DecodeJSON(t, resp, &ap2)
97+
assert.NotNil(t, ap2.Repository)
98+
assert.EqualValues(t, 1, ap2.Repository.ID)
99+
100+
// link to private repository
101+
assert.NoError(t, packages_model.SetRepositoryLink(db.DefaultContext, p.ID, 2))
102+
103+
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, token))
104+
resp = MakeRequest(t, req, http.StatusOK)
105+
106+
var ap3 *api.Package
107+
DecodeJSON(t, resp, &ap3)
108+
assert.Nil(t, ap3.Repository)
109+
110+
assert.NoError(t, packages_model.UnlinkRepositoryFromAllPackages(db.DefaultContext, 2))
111+
})
74112
})
75113

76114
t.Run("ListPackageFiles", func(t *testing.T) {

modules/convert/package.go

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,38 @@
55
package convert
66

77
import (
8+
"context"
9+
10+
"code.gitea.io/gitea/models"
811
"code.gitea.io/gitea/models/packages"
9-
"code.gitea.io/gitea/models/perm"
12+
user_model "code.gitea.io/gitea/models/user"
1013
api "code.gitea.io/gitea/modules/structs"
1114
)
1215

1316
// ToPackage convert a packages.PackageDescriptor to api.Package
14-
func ToPackage(pd *packages.PackageDescriptor) *api.Package {
17+
func ToPackage(ctx context.Context, pd *packages.PackageDescriptor, doer *user_model.User) (*api.Package, error) {
1518
var repo *api.Repository
1619
if pd.Repository != nil {
17-
repo = ToRepo(pd.Repository, perm.AccessModeNone)
20+
permission, err := models.GetUserRepoPermission(ctx, pd.Repository, doer)
21+
if err != nil {
22+
return nil, err
23+
}
24+
25+
if permission.HasAccess() {
26+
repo = ToRepo(pd.Repository, permission.AccessMode)
27+
}
1828
}
1929

2030
return &api.Package{
2131
ID: pd.Version.ID,
22-
Owner: ToUser(pd.Owner, nil),
32+
Owner: ToUser(pd.Owner, doer),
2333
Repository: repo,
24-
Creator: ToUser(pd.Creator, nil),
34+
Creator: ToUser(pd.Creator, doer),
2535
Type: string(pd.Package.Type),
2636
Name: pd.Package.Name,
2737
Version: pd.Version.Version,
2838
CreatedAt: pd.Version.CreatedUnix.AsTime(),
29-
}
39+
}, nil
3040
}
3141

3242
// ToPackageFile converts packages.PackageFileDescriptor to api.PackageFile

modules/notification/webhook/webhook.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -872,17 +872,19 @@ func notifyPackage(sender *user_model.User, pd *packages_model.PackageDescriptor
872872
return
873873
}
874874

875-
org := pd.Owner
876-
if !org.IsOrganization() {
877-
org = nil
875+
ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.notifyPackage Package: %s[%d]", pd.Package.Name, pd.Package.ID))
876+
defer finished()
877+
878+
apiPackage, err := convert.ToPackage(ctx, pd, sender)
879+
if err != nil {
880+
log.Error("Error converting package: %v", err)
881+
return
878882
}
879883

880884
if err := webhook_services.PrepareWebhooks(pd.Repository, webhook.HookEventPackage, &api.PackagePayload{
881-
Action: action,
882-
Repository: convert.ToRepo(pd.Repository, perm.AccessModeNone),
883-
Package: convert.ToPackage(pd),
884-
Organization: convert.ToUser(org, nil),
885-
Sender: convert.ToUser(sender, nil),
885+
Action: action,
886+
Package: apiPackage,
887+
Sender: convert.ToUser(sender, nil),
886888
}); err != nil {
887889
log.Error("PrepareWebhooks: %v", err)
888890
}

routers/api/v1/packages/package.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,12 @@ func ListPackages(ctx *context.APIContext) {
7373

7474
apiPackages := make([]*api.Package, 0, len(pds))
7575
for _, pd := range pds {
76-
apiPackages = append(apiPackages, convert.ToPackage(pd))
76+
apiPackage, err := convert.ToPackage(ctx, pd, ctx.Doer)
77+
if err != nil {
78+
ctx.Error(http.StatusInternalServerError, "Error converting package for api", err)
79+
return
80+
}
81+
apiPackages = append(apiPackages, apiPackage)
7782
}
7883

7984
ctx.SetLinkHeader(int(count), listOptions.PageSize)
@@ -115,7 +120,13 @@ func GetPackage(ctx *context.APIContext) {
115120
// "404":
116121
// "$ref": "#/responses/notFound"
117122

118-
ctx.JSON(http.StatusOK, convert.ToPackage(ctx.Package.Descriptor))
123+
apiPackage, err := convert.ToPackage(ctx, ctx.Package.Descriptor, ctx.Doer)
124+
if err != nil {
125+
ctx.Error(http.StatusInternalServerError, "Error converting package for api", err)
126+
return
127+
}
128+
129+
ctx.JSON(http.StatusOK, apiPackage)
119130
}
120131

121132
// DeletePackage deletes a package

routers/web/repo/packages.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ func Packages(ctx *context.Context) {
6262
ctx.Data["HasPackages"] = hasPackages
6363
ctx.Data["PackageDescriptors"] = pds
6464
ctx.Data["Total"] = total
65+
ctx.Data["RepositoryAccessMap"] = map[int64]bool{ctx.Repo.Repository.ID: true} // There is only the current repository
6566

6667
pager := context.NewPagination(int(total), setting.UI.PackagesPagingNum, page, 5)
6768
pager.AddParam(ctx, "q", "Query")

routers/web/user/package.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,23 @@ func ListPackages(ctx *context.Context) {
5858
return
5959
}
6060

61+
repositoryAccessMap := make(map[int64]bool)
62+
for _, pd := range pds {
63+
if pd.Repository == nil {
64+
continue
65+
}
66+
if _, has := repositoryAccessMap[pd.Repository.ID]; has {
67+
continue
68+
}
69+
70+
permission, err := models.GetUserRepoPermission(ctx, pd.Repository, ctx.Doer)
71+
if err != nil {
72+
ctx.ServerError("GetUserRepoPermission", err)
73+
return
74+
}
75+
repositoryAccessMap[pd.Repository.ID] = permission.HasAccess()
76+
}
77+
6178
hasPackages, err := packages_model.HasOwnerPackages(ctx, ctx.ContextUser.ID)
6279
if err != nil {
6380
ctx.ServerError("HasOwnerPackages", err)
@@ -72,6 +89,7 @@ func ListPackages(ctx *context.Context) {
7289
ctx.Data["HasPackages"] = hasPackages
7390
ctx.Data["PackageDescriptors"] = pds
7491
ctx.Data["Total"] = total
92+
ctx.Data["RepositoryAccessMap"] = repositoryAccessMap
7593

7694
pager := context.NewPagination(int(total), setting.UI.PackagesPagingNum, page, 5)
7795
pager.AddParam(ctx, "q", "Query")
@@ -157,6 +175,17 @@ func ViewPackageVersion(ctx *context.Context) {
157175

158176
ctx.Data["CanWritePackages"] = ctx.Package.AccessMode >= perm.AccessModeWrite || ctx.IsUserSiteAdmin()
159177

178+
hasRepositoryAccess := false
179+
if pd.Repository != nil {
180+
permission, err := models.GetUserRepoPermission(ctx, pd.Repository, ctx.Doer)
181+
if err != nil {
182+
ctx.ServerError("GetUserRepoPermission", err)
183+
return
184+
}
185+
hasRepositoryAccess = permission.HasAccess()
186+
}
187+
ctx.Data["HasRepositoryAccess"] = hasRepositoryAccess
188+
160189
ctx.HTML(http.StatusOK, tplPackagesView)
161190
}
162191

templates/package/shared/list.tmpl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@
3030
</div>
3131
<div class="desc issue-item-bottom-row df ac fw my-1">
3232
{{$timeStr := TimeSinceUnix .Version.CreatedUnix $.i18n.Lang}}
33+
{{$hasRepositoryAccess := false}}
3334
{{if .Repository}}
35+
{{$hasRepositoryAccess = index $.RepositoryAccessMap .Repository.ID}}
36+
{{end}}
37+
{{if $hasRepositoryAccess}}
3438
{{$.i18n.Tr "packages.published_by_in" $timeStr .Creator.HomeLink (.Creator.GetDisplayName | Escape) .Repository.HTMLURL (.Repository.FullName | Escape) | Safe}}
3539
{{else}}
3640
{{$.i18n.Tr "packages.published_by" $timeStr .Creator.HomeLink (.Creator.GetDisplayName | Escape) | Safe}}

templates/package/view.tmpl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</div>
1111
<div>
1212
{{$timeStr := TimeSinceUnix .PackageDescriptor.Version.CreatedUnix $.i18n.Lang}}
13-
{{if .PackageDescriptor.Repository}}
13+
{{if .HasRepositoryAccess}}
1414
{{.i18n.Tr "packages.published_by_in" $timeStr .PackageDescriptor.Creator.HomeLink (.PackageDescriptor.Creator.GetDisplayName | Escape) .PackageDescriptor.Repository.HTMLURL (.PackageDescriptor.Repository.FullName | Escape) | Safe}}
1515
{{else}}
1616
{{.i18n.Tr "packages.published_by" $timeStr .PackageDescriptor.Creator.HomeLink (.PackageDescriptor.Creator.GetDisplayName | Escape) | Safe}}
@@ -35,7 +35,7 @@
3535
<strong>{{.i18n.Tr "packages.details"}}</strong>
3636
<div class="ui relaxed list">
3737
<div class="item">{{svg .PackageDescriptor.Package.Type.SVGName 16 "mr-3"}} {{.PackageDescriptor.Package.Type.Name}}</div>
38-
{{if .PackageDescriptor.Repository}}
38+
{{if .HasRepositoryAccess}}
3939
<div class="item">{{svg "octicon-repo" 16 "mr-3"}} <a href="{{.PackageDescriptor.Repository.HTMLURL}}">{{.PackageDescriptor.Repository.FullName}}</a></div>
4040
{{end}}
4141
<div class="item">{{svg "octicon-calendar" 16 "mr-3"}} {{.PackageDescriptor.Version.CreatedUnix.FormatDate}}</div>
@@ -76,10 +76,10 @@
7676
{{end}}
7777
</div>
7878
{{end}}
79-
{{if or .CanWritePackages .PackageDescriptor.Repository}}
79+
{{if or .CanWritePackages .HasRepositoryAccess}}
8080
<div class="ui divider"></div>
8181
<div class="ui relaxed list">
82-
{{if .PackageDescriptor.Repository}}
82+
{{if .HasRepositoryAccess}}
8383
<div class="item">{{svg "octicon-issue-opened" 16 "mr-3"}} <a href="{{.PackageDescriptor.Repository.HTMLURL}}/issues">{{.i18n.Tr "repo.issues"}}</a></div>
8484
{{end}}
8585
{{if .CanWritePackages}}

0 commit comments

Comments
 (0)