Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hide private repositories in packages #19584

Merged
merged 11 commits into from
May 7, 2022
38 changes: 38 additions & 0 deletions integrations/api_packages_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,44 @@ func TestPackageAPI(t *testing.T) {
assert.Equal(t, packageVersion, p.Version)
assert.NotNil(t, p.Creator)
assert.Equal(t, user.Name, p.Creator.UserName)

t.Run("RepositoryLink", func(t *testing.T) {
defer PrintCurrentTest(t)()

p, err := packages_model.GetPackageByName(db.DefaultContext, user.ID, packages_model.TypeGeneric, packageName)
assert.NoError(t, err)

// no repository link
req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, token))
resp := MakeRequest(t, req, http.StatusOK)

var ap1 *api.Package
DecodeJSON(t, resp, &ap1)
assert.Nil(t, ap1.Repository)

// link to public repository
assert.NoError(t, packages_model.SetRepositoryLink(db.DefaultContext, p.ID, 1))

req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, token))
resp = MakeRequest(t, req, http.StatusOK)

var ap2 *api.Package
DecodeJSON(t, resp, &ap2)
assert.NotNil(t, ap2.Repository)
assert.EqualValues(t, 1, ap2.Repository.ID)

// link to private repository
assert.NoError(t, packages_model.SetRepositoryLink(db.DefaultContext, p.ID, 2))

req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, token))
resp = MakeRequest(t, req, http.StatusOK)

var ap3 *api.Package
DecodeJSON(t, resp, &ap3)
assert.Nil(t, ap3.Repository)

assert.NoError(t, packages_model.UnlinkRepositoryFromAllPackages(db.DefaultContext, 2))
})
})

t.Run("ListPackageFiles", func(t *testing.T) {
Expand Down
21 changes: 16 additions & 5 deletions modules/convert/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,39 @@
package convert

import (
"context"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/packages"
"code.gitea.io/gitea/models/perm"
6543 marked this conversation as resolved.
Show resolved Hide resolved
user_model "code.gitea.io/gitea/models/user"
api "code.gitea.io/gitea/modules/structs"
)

// ToPackage convert a packages.PackageDescriptor to api.Package
func ToPackage(pd *packages.PackageDescriptor) *api.Package {
func ToPackage(ctx context.Context, pd *packages.PackageDescriptor, doer *user_model.User) (*api.Package, error) {
var repo *api.Repository
if pd.Repository != nil {
repo = ToRepo(pd.Repository, perm.AccessModeNone)
permission, err := models.GetUserRepoPermission(ctx, pd.Repository, doer)
if err != nil {
return nil, err
}

if permission.HasAccess() {
repo = ToRepo(pd.Repository, perm.AccessModeNone)
}
6543 marked this conversation as resolved.
Show resolved Hide resolved
6543 marked this conversation as resolved.
Show resolved Hide resolved
}

return &api.Package{
ID: pd.Version.ID,
Owner: ToUser(pd.Owner, nil),
Owner: ToUser(pd.Owner, doer),
Repository: repo,
Creator: ToUser(pd.Creator, nil),
Creator: ToUser(pd.Creator, doer),
Type: string(pd.Package.Type),
Name: pd.Package.Name,
Version: pd.Version.Version,
CreatedAt: pd.Version.CreatedUnix.AsTime(),
}
}, nil
}

// ToPackageFile converts packages.PackageFileDescriptor to api.PackageFile
Expand Down
11 changes: 10 additions & 1 deletion modules/notification/webhook/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -877,10 +877,19 @@ func notifyPackage(sender *user_model.User, pd *packages_model.PackageDescriptor
org = nil
}

ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.notifyPackage Package: %s[%d]", pd.Package.Name, pd.Package.ID))
defer finished()

apiPackage, err := convert.ToPackage(ctx, pd, sender)
if err != nil {
log.Error("Error converting package: %v", err)
return
}

if err := webhook_services.PrepareWebhooks(pd.Repository, webhook.HookEventPackage, &api.PackagePayload{
Action: action,
Repository: convert.ToRepo(pd.Repository, perm.AccessModeNone),
Package: convert.ToPackage(pd),
Package: apiPackage,
6543 marked this conversation as resolved.
Show resolved Hide resolved
Organization: convert.ToUser(org, nil),
Sender: convert.ToUser(sender, nil),
}); err != nil {
Expand Down
15 changes: 13 additions & 2 deletions routers/api/v1/packages/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,12 @@ func ListPackages(ctx *context.APIContext) {

apiPackages := make([]*api.Package, 0, len(pds))
for _, pd := range pds {
apiPackages = append(apiPackages, convert.ToPackage(pd))
apiPackage, err := convert.ToPackage(ctx, pd, ctx.Doer)
if err != nil {
ctx.Error(http.StatusInternalServerError, "Error converting package for api", err)
return
}
apiPackages = append(apiPackages, apiPackage)
}

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

ctx.JSON(http.StatusOK, convert.ToPackage(ctx.Package.Descriptor))
apiPackage, err := convert.ToPackage(ctx, ctx.Package.Descriptor, ctx.Doer)
if err != nil {
ctx.Error(http.StatusInternalServerError, "Error converting package for api", err)
return
}

ctx.JSON(http.StatusOK, apiPackage)
}

// DeletePackage deletes a package
Expand Down
1 change: 1 addition & 0 deletions routers/web/repo/packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ func Packages(ctx *context.Context) {
ctx.Data["HasPackages"] = hasPackages
ctx.Data["PackageDescriptors"] = pds
ctx.Data["Total"] = total
ctx.Data["RepositoryAccessMap"] = map[int64]bool{ctx.Repo.Repository.ID: true} // There is only the current repository

pager := context.NewPagination(int(total), setting.UI.PackagesPagingNum, page, 5)
pager.AddParam(ctx, "q", "Query")
Expand Down
29 changes: 29 additions & 0 deletions routers/web/user/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,23 @@ func ListPackages(ctx *context.Context) {
return
}

repositoryAccessMap := make(map[int64]bool)
for _, pd := range pds {
if pd.Repository == nil {
continue
}
if _, has := repositoryAccessMap[pd.Repository.ID]; has {
continue
}

permission, err := models.GetUserRepoPermission(ctx, pd.Repository, ctx.Doer)
if err != nil {
ctx.ServerError("GetUserRepoPermission", err)
return
}
repositoryAccessMap[pd.Repository.ID] = permission.HasAccess()
}

hasPackages, err := packages_model.HasOwnerPackages(ctx, ctx.ContextUser.ID)
if err != nil {
ctx.ServerError("HasOwnerPackages", err)
Expand All @@ -72,6 +89,7 @@ func ListPackages(ctx *context.Context) {
ctx.Data["HasPackages"] = hasPackages
ctx.Data["PackageDescriptors"] = pds
ctx.Data["Total"] = total
ctx.Data["RepositoryAccessMap"] = repositoryAccessMap

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

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

hasRepositoryAccess := false
if pd.Repository != nil {
permission, err := models.GetUserRepoPermission(ctx, pd.Repository, ctx.Doer)
if err != nil {
ctx.ServerError("GetUserRepoPermission", err)
return
}
hasRepositoryAccess = permission.HasAccess()
}
ctx.Data["HasRepositoryAccess"] = hasRepositoryAccess

ctx.HTML(http.StatusOK, tplPackagesView)
}

Expand Down
4 changes: 4 additions & 0 deletions templates/package/shared/list.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@
</div>
<div class="desc issue-item-bottom-row df ac fw my-1">
{{$timeStr := TimeSinceUnix .Version.CreatedUnix $.i18n.Lang}}
{{$hasRepositoryAccess := false}}
{{if .Repository}}
{{$hasRepositoryAccess = index $.RepositoryAccessMap .Repository.ID}}
{{end}}
{{if $hasRepositoryAccess}}
{{$.i18n.Tr "packages.published_by_in" $timeStr .Creator.HomeLink (.Creator.GetDisplayName | Escape) .Repository.HTMLURL (.Repository.FullName | Escape) | Safe}}
{{else}}
{{$.i18n.Tr "packages.published_by" $timeStr .Creator.HomeLink (.Creator.GetDisplayName | Escape) | Safe}}
Expand Down
8 changes: 4 additions & 4 deletions templates/package/view.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</div>
<div>
{{$timeStr := TimeSinceUnix .PackageDescriptor.Version.CreatedUnix $.i18n.Lang}}
{{if .PackageDescriptor.Repository}}
{{if .HasRepositoryAccess}}
{{.i18n.Tr "packages.published_by_in" $timeStr .PackageDescriptor.Creator.HomeLink (.PackageDescriptor.Creator.GetDisplayName | Escape) .PackageDescriptor.Repository.HTMLURL (.PackageDescriptor.Repository.FullName | Escape) | Safe}}
{{else}}
{{.i18n.Tr "packages.published_by" $timeStr .PackageDescriptor.Creator.HomeLink (.PackageDescriptor.Creator.GetDisplayName | Escape) | Safe}}
Expand All @@ -35,7 +35,7 @@
<strong>{{.i18n.Tr "packages.details"}}</strong>
<div class="ui relaxed list">
<div class="item">{{svg .PackageDescriptor.Package.Type.SVGName 16 "mr-3"}} {{.PackageDescriptor.Package.Type.Name}}</div>
{{if .PackageDescriptor.Repository}}
{{if .HasRepositoryAccess}}
<div class="item">{{svg "octicon-repo" 16 "mr-3"}} <a href="{{.PackageDescriptor.Repository.HTMLURL}}">{{.PackageDescriptor.Repository.FullName}}</a></div>
{{end}}
<div class="item">{{svg "octicon-calendar" 16 "mr-3"}} {{.PackageDescriptor.Version.CreatedUnix.FormatDate}}</div>
Expand Down Expand Up @@ -76,10 +76,10 @@
{{end}}
</div>
{{end}}
{{if or .CanWritePackages .PackageDescriptor.Repository}}
{{if or .CanWritePackages .HasRepositoryAccess}}
<div class="ui divider"></div>
<div class="ui relaxed list">
{{if .PackageDescriptor.Repository}}
{{if .HasRepositoryAccess}}
<div class="item">{{svg "octicon-issue-opened" 16 "mr-3"}} <a href="{{.PackageDescriptor.Repository.HTMLURL}}/issues">{{.i18n.Tr "repo.issues"}}</a></div>
{{end}}
{{if .CanWritePackages}}
Expand Down