From b449cd74223e4019391ce63c5f9d7ee747fefe0b Mon Sep 17 00:00:00 2001 From: JakobDev Date: Thu, 7 Sep 2023 14:21:02 +0200 Subject: [PATCH 01/10] Add uploading packages through the Web UI --- routers/web/repo/packages.go | 4 + routers/web/shared/packages/upload.go | 202 ++++++++++++++++++++ routers/web/user/package.go | 51 +++++ routers/web/web.go | 7 + services/forms/package_form.go | 16 ++ templates/package/shared/list.tmpl | 3 + templates/package/upload/base.tmpl | 7 + templates/package/upload/choose.tmpl | 12 ++ templates/package/upload/debian.tmpl | 27 +++ templates/package/upload/generic.tmpl | 32 ++++ templates/user/overview/package_upload.tmpl | 27 +++ 11 files changed, 388 insertions(+) create mode 100644 routers/web/shared/packages/upload.go create mode 100644 templates/package/upload/base.tmpl create mode 100644 templates/package/upload/choose.tmpl create mode 100644 templates/package/upload/debian.tmpl create mode 100644 templates/package/upload/generic.tmpl create mode 100644 templates/user/overview/package_upload.tmpl diff --git a/routers/web/repo/packages.go b/routers/web/repo/packages.go index ac9e64d774e3f..255a10fd9e2fd 100644 --- a/routers/web/repo/packages.go +++ b/routers/web/repo/packages.go @@ -4,6 +4,7 @@ package repo import ( + "fmt" "net/http" "code.gitea.io/gitea/models/db" @@ -64,6 +65,9 @@ func Packages(ctx *context.Context) { ctx.Data["HasPackages"] = hasPackages if ctx.Repo != nil { ctx.Data["CanWritePackages"] = ctx.IsUserRepoWriter([]unit.Type{unit.TypePackages}) || ctx.IsUserSiteAdmin() + ctx.Data["ShowPackageUploadButton"] = ctx.Data["CanWritePackages"] + ctx.Data["PackageUploadUrl"] = fmt.Sprintf("%s/-/packages/upload", ctx.Repo.Owner.HTMLURL()) + ctx.Data["PackageUploadRepo"] = ctx.Repo.Repository.Name } ctx.Data["PackageDescriptors"] = pds ctx.Data["Total"] = total diff --git a/routers/web/shared/packages/upload.go b/routers/web/shared/packages/upload.go new file mode 100644 index 0000000000000..7966852ca103e --- /dev/null +++ b/routers/web/shared/packages/upload.go @@ -0,0 +1,202 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package packages + +import ( + "errors" + "fmt" + "io" + + packages_model "code.gitea.io/gitea/models/packages" + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/modules/context" + packages_module "code.gitea.io/gitea/modules/packages" + debian_module "code.gitea.io/gitea/modules/packages/debian" + "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/forms" + packages_service "code.gitea.io/gitea/services/packages" + debian_service "code.gitea.io/gitea/services/packages/debian" +) + +func servePackageUploadError(ctx *context.Context, err error, packageType, repo string) { + ctx.Flash.Error(err.Error()) + + if repo == "" { + ctx.Redirect(fmt.Sprintf("%s/-/packages/upload/%s", ctx.ContextUser.HTMLURL(), packageType)) + } else { + ctx.Redirect(fmt.Sprintf("%s/-/packages/upload/%s?repo=%s", ctx.ContextUser.HTMLURL(), packageType, repo)) + } +} + +func addRepoToUploadedPackage(ctx *context.Context, packageType, repoName string, packageID int64) bool { + repo, err := repo_model.GetRepositoryByOwnerAndName(ctx, ctx.ContextUser.Name, repoName) + if err != nil { + if repo_model.IsErrRepoNotExist(err) { + servePackageUploadError(ctx, fmt.Errorf("repo not found"), packageType, repoName) + return false + } else { + ctx.ServerError("GetRepositoryByOwnerAndName", err) + return false + } + } + + err = packages_model.SetRepositoryLink(ctx, packageID, repo.ID) + if err != nil { + ctx.ServerError("SetRepositoryLink", err) + return false + } + + return true +} + +func UploadGenericPackagePost(ctx *context.Context) { + form := web.GetForm(ctx).(*forms.PackageUploadGenericForm) + upload, err := form.PackageFile.Open() + if err != nil { + ctx.ServerError("GetPackageFile", err) + return + } + + buf, err := packages_module.CreateHashedBufferFromReader(upload) + if err != nil { + ctx.ServerError("CreateHashedBufferFromReader", err) + return + } + defer buf.Close() + + pv, _, err := packages_service.CreatePackageOrAddFileToExisting( + &packages_service.PackageCreationInfo{ + PackageInfo: packages_service.PackageInfo{ + Owner: ctx.Package.Owner, + PackageType: packages_model.TypeGeneric, + Name: form.PackageName, + Version: form.PackageVersion, + }, + Creator: ctx.Doer, + }, + &packages_service.PackageFileCreationInfo{ + PackageFileInfo: packages_service.PackageFileInfo{ + Filename: form.PackageFilename, + }, + Creator: ctx.Doer, + Data: buf, + IsLead: true, + }, + ) + if err != nil { + switch err { + case packages_model.ErrDuplicatePackageFile: + servePackageUploadError(ctx, err, "generic", form.PackageRepo) + case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: + servePackageUploadError(ctx, err, "generic", form.PackageRepo) + default: + ctx.ServerError("CreatePackageOrAddFileToExisting", err) + } + return + } + + if form.PackageRepo != "" { + if !addRepoToUploadedPackage(ctx, "generic", form.PackageRepo, pv.PackageID) { + return + } + } + + pd, err := packages_model.GetPackageDescriptor(ctx, pv) + if err != nil { + ctx.ServerError("GetPackageDescriptor", err) + return + } + + ctx.Redirect(pd.FullWebLink()) +} + +func UploadDebianPackagePost(ctx *context.Context) { + form := web.GetForm(ctx).(*forms.PackageUploadDebianForm) + upload, err := form.PackageFile.Open() + if err != nil { + ctx.ServerError("GetPackageFile", err) + return + } + + buf, err := packages_module.CreateHashedBufferFromReader(upload) + if err != nil { + ctx.ServerError("GetGenericPackageFile", err) + return + } + defer buf.Close() + + pck, err := debian_module.ParsePackage(buf) + if err != nil { + if errors.Is(err, util.ErrInvalidArgument) { + servePackageUploadError(ctx, err, "debian", form.PackageRepo) + } else { + ctx.ServerError("ParsePackage", err) + } + return + } + + if _, err := buf.Seek(0, io.SeekStart); err != nil { + ctx.ServerError("SeekBuffer", err) + return + } + + pv, _, err := packages_service.CreatePackageOrAddFileToExisting( + &packages_service.PackageCreationInfo{ + PackageInfo: packages_service.PackageInfo{ + Owner: ctx.Package.Owner, + PackageType: packages_model.TypeDebian, + Name: pck.Name, + Version: pck.Version, + }, + Creator: ctx.Doer, + Metadata: pck.Metadata, + }, + &packages_service.PackageFileCreationInfo{ + PackageFileInfo: packages_service.PackageFileInfo{ + Filename: fmt.Sprintf("%s_%s_%s.deb", pck.Name, pck.Version, pck.Architecture), + CompositeKey: fmt.Sprintf("%s|%s", form.PackageDistribution, form.PackageComponent), + }, + Creator: ctx.Doer, + Data: buf, + IsLead: true, + Properties: map[string]string{ + debian_module.PropertyDistribution: form.PackageDistribution, + debian_module.PropertyComponent: form.PackageComponent, + debian_module.PropertyArchitecture: pck.Architecture, + debian_module.PropertyControl: pck.Control, + }, + }, + ) + if err != nil { + switch err { + case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile: + servePackageUploadError(ctx, err, "debian", form.PackageRepo) + case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: + servePackageUploadError(ctx, err, "debian", form.PackageRepo) + default: + ctx.ServerError("CreatePackageOrAddFileToExisting", err) + } + return + } + + if err := debian_service.BuildSpecificRepositoryFiles(ctx, ctx.Package.Owner.ID, form.PackageDistribution, form.PackageComponent, pck.Architecture); err != nil { + ctx.ServerError("BuildSpecificRepositoryFiles", err) + return + } + + if form.PackageRepo != "" { + if !addRepoToUploadedPackage(ctx, "debian", form.PackageRepo, pv.PackageID) { + return + } + } + + pd, err := packages_model.GetPackageDescriptor(ctx, pv) + if err != nil { + ctx.ServerError("GetPackageDescriptor", err) + return + } + + ctx.Redirect(pd.FullWebLink()) +} diff --git a/routers/web/user/package.go b/routers/web/user/package.go index 57770b2b1aed8..9e9408297f582 100644 --- a/routers/web/user/package.go +++ b/routers/web/user/package.go @@ -4,7 +4,9 @@ package user import ( + "fmt" "net/http" + "slices" "code.gitea.io/gitea/models/db" org_model "code.gitea.io/gitea/models/organization" @@ -33,6 +35,7 @@ const ( tplPackagesView base.TplName = "package/view" tplPackageVersionList base.TplName = "user/overview/package_versions" tplPackagesSettings base.TplName = "package/settings" + tplPackageUpload base.TplName = "user/overview/package_upload" ) // ListPackages displays a list of all packages of the context user @@ -100,6 +103,7 @@ func ListPackages(ctx *context.Context) { ctx.Data["PackageDescriptors"] = pds ctx.Data["Total"] = total ctx.Data["RepositoryAccessMap"] = repositoryAccessMap + ctx.Data["PackageUploadUrl"] = fmt.Sprintf("%s/-/packages/upload", ctx.ContextUser.HTMLURL()) err = shared_user.LoadHeaderCount(ctx) if err != nil { @@ -116,10 +120,16 @@ func ListPackages(ctx *context.Context) { if ctx.Doer != nil { ctx.Data["IsOrganizationMember"], _ = org_model.IsOrganizationMember(ctx, org.ID, ctx.Doer.ID) ctx.Data["IsOrganizationOwner"], _ = org_model.IsOrganizationOwner(ctx, org.ID, ctx.Doer.ID) + ctx.Data["ShowPackageUploadButton"] = ctx.Data["IsOrganizationMember"] } else { ctx.Data["IsOrganizationMember"] = false ctx.Data["IsOrganizationOwner"] = false + ctx.Data["ShowPackageUploadButton"] = false } + } else if ctx.Doer != nil { + ctx.Data["ShowPackageUploadButton"] = ctx.Doer.ID == ctx.ContextUser.ID + } else { + ctx.Data["ShowPackageUploadButton"] = false } pager := context.NewPagination(int(total), setting.UI.PackagesPagingNum, page, 5) @@ -478,3 +488,44 @@ func DownloadPackageFile(ctx *context.Context) { packages_helper.ServePackageFile(ctx, s, u, pf) } + +func UploadPackageChoose(ctx *context.Context) { + shared_user.PrepareContextForProfileBigAvatar(ctx) + + ctx.Data["IsPackagesPage"] = true + ctx.Data["PackageUploadPage"] = "choose" + ctx.Data["PackageUploadRepo"] = ctx.FormString("repo") + + err := shared_user.LoadHeaderCount(ctx) + if err != nil { + ctx.ServerError("LoadHeaderCount", err) + return + } + + ctx.HTML(http.StatusOK, tplPackageUpload) +} + +func UploadPackagePage(ctx *context.Context) { + shared_user.PrepareContextForProfileBigAvatar(ctx) + + packageType := ctx.Params("upload_type") + + allowdTypes := []string{"generic", "debian"} + + if !slices.Contains(allowdTypes, packageType) { + ctx.NotFound("", nil) + return + } + + ctx.Data["IsPackagesPage"] = true + ctx.Data["PackageUploadPage"] = packageType + ctx.Data["PackageUploadRepo"] = ctx.FormString("repo") + + err := shared_user.LoadHeaderCount(ctx) + if err != nil { + ctx.ServerError("LoadHeaderCount", err) + return + } + + ctx.HTML(http.StatusOK, tplPackageUpload) +} diff --git a/routers/web/web.go b/routers/web/web.go index ec6742f6ce765..86f23b4558ba8 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -34,6 +34,7 @@ import ( "code.gitea.io/gitea/routers/web/repo" "code.gitea.io/gitea/routers/web/repo/actions" repo_setting "code.gitea.io/gitea/routers/web/repo/setting" + "code.gitea.io/gitea/routers/web/shared/packages" "code.gitea.io/gitea/routers/web/user" user_setting "code.gitea.io/gitea/routers/web/user/setting" "code.gitea.io/gitea/routers/web/user/setting/security" @@ -828,6 +829,12 @@ func registerRoutes(m *web.Route) { }, reqPackageAccess(perm.AccessModeWrite)) }) }) + m.Group("/upload", func() { + m.Get("", user.UploadPackageChoose) + m.Get("/{upload_type}", user.UploadPackagePage) + m.Post("/generic/upload", web.Bind(forms.PackageUploadGenericForm{}), packages.UploadGenericPackagePost) + m.Post("/debian/upload", web.Bind(forms.PackageUploadDebianForm{}), packages.UploadDebianPackagePost) + }, reqPackageAccess(perm.AccessModeWrite)) }, context.PackageAssignment(), reqPackageAccess(perm.AccessModeRead)) } diff --git a/services/forms/package_form.go b/services/forms/package_form.go index 2f08dfe9f4864..2906eccfeb9c7 100644 --- a/services/forms/package_form.go +++ b/services/forms/package_form.go @@ -4,6 +4,7 @@ package forms import ( + "mime/multipart" "net/http" "code.gitea.io/gitea/modules/context" @@ -28,3 +29,18 @@ func (f *PackageCleanupRuleForm) Validate(req *http.Request, errs binding.Errors ctx := context.GetValidateContext(req) return middleware.Validate(errs, ctx.Data, f, ctx.Locale) } + +type PackageUploadGenericForm struct { + PackageRepo string + PackageName string + PackageVersion string + PackageFilename string + PackageFile *multipart.FileHeader +} + +type PackageUploadDebianForm struct { + PackageRepo string + PackageDistribution string + PackageComponent string + PackageFile *multipart.FileHeader +} diff --git a/templates/package/shared/list.tmpl b/templates/package/shared/list.tmpl index afa360fd93d18..4c904bb3d1d58 100644 --- a/templates/package/shared/list.tmpl +++ b/templates/package/shared/list.tmpl @@ -10,6 +10,9 @@ {{end}} + {{if .ShowPackageUploadButton}} + Upload + {{end}}
diff --git a/templates/package/upload/base.tmpl b/templates/package/upload/base.tmpl new file mode 100644 index 0000000000000..cb70150bc2e5c --- /dev/null +++ b/templates/package/upload/base.tmpl @@ -0,0 +1,7 @@ +{{if eq $.PackageUploadPage "choose"}} + {{template "package/upload/choose" .}} +{{else if eq $.PackageUploadPage "generic"}} + {{template "package/upload/generic" .}} +{{else if eq $.PackageUploadPage "debian"}} + {{template "package/upload/debian" .}} +{{end}} diff --git a/templates/package/upload/choose.tmpl b/templates/package/upload/choose.tmpl new file mode 100644 index 0000000000000..ade79e3b2a1ac --- /dev/null +++ b/templates/package/upload/choose.tmpl @@ -0,0 +1,12 @@ + + + + + + + + + + + +
GenericUpload
DebianUpload
diff --git a/templates/package/upload/debian.tmpl b/templates/package/upload/debian.tmpl new file mode 100644 index 0000000000000..976f4ef1097d3 --- /dev/null +++ b/templates/package/upload/debian.tmpl @@ -0,0 +1,27 @@ +
+ {{template "base/alert" .}} +
+ {{.CsrfTokenHtml}} + + + +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+
+
diff --git a/templates/package/upload/generic.tmpl b/templates/package/upload/generic.tmpl new file mode 100644 index 0000000000000..494ebf753420d --- /dev/null +++ b/templates/package/upload/generic.tmpl @@ -0,0 +1,32 @@ +
+ {{template "base/alert" .}} +
+ {{.CsrfTokenHtml}} + + + +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+
+
diff --git a/templates/user/overview/package_upload.tmpl b/templates/user/overview/package_upload.tmpl new file mode 100644 index 0000000000000..5541b8631cb2e --- /dev/null +++ b/templates/user/overview/package_upload.tmpl @@ -0,0 +1,27 @@ +{{template "base/head" .}} +{{if .ContextUser.IsOrganization}} +
+ {{template "shared/user/org_profile_avatar" .}} +
+ {{template "user/overview/header" .}} + {{template "package/upload/base" .}} +
+
+{{else}} +
+
+
+
+ {{template "shared/user/profile_big_avatar" .}} +
+
+
+ {{template "user/overview/header" .}} +
+ {{template "package/upload/base" .}} +
+
+
+
+{{end}} +{{template "base/footer" .}} From c71e622a9a127cb726500cc5e4ae667efeb9af83 Mon Sep 17 00:00:00 2001 From: JakobDev Date: Thu, 7 Sep 2023 15:28:25 +0200 Subject: [PATCH 02/10] Some improvements --- routers/web/shared/packages/upload.go | 15 +++++++++++---- templates/package/upload/debian.tmpl | 5 +++-- templates/package/upload/generic.tmpl | 7 ++++--- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/routers/web/shared/packages/upload.go b/routers/web/shared/packages/upload.go index 7966852ca103e..7dbea51be5be3 100644 --- a/routers/web/shared/packages/upload.go +++ b/routers/web/shared/packages/upload.go @@ -36,10 +36,10 @@ func addRepoToUploadedPackage(ctx *context.Context, packageType, repoName string if repo_model.IsErrRepoNotExist(err) { servePackageUploadError(ctx, fmt.Errorf("repo not found"), packageType, repoName) return false - } else { - ctx.ServerError("GetRepositoryByOwnerAndName", err) - return false } + + ctx.ServerError("GetRepositoryByOwnerAndName", err) + return false } err = packages_model.SetRepositoryLink(ctx, packageID, repo.ID) @@ -66,6 +66,13 @@ func UploadGenericPackagePost(ctx *context.Context) { } defer buf.Close() + var filename string + if form.PackageFilename == "" { + filename = form.PackageFile.Filename + } else { + filename = form.PackageFilename + } + pv, _, err := packages_service.CreatePackageOrAddFileToExisting( &packages_service.PackageCreationInfo{ PackageInfo: packages_service.PackageInfo{ @@ -78,7 +85,7 @@ func UploadGenericPackagePost(ctx *context.Context) { }, &packages_service.PackageFileCreationInfo{ PackageFileInfo: packages_service.PackageFileInfo{ - Filename: form.PackageFilename, + Filename: filename, }, Creator: ctx.Doer, Data: buf, diff --git a/templates/package/upload/debian.tmpl b/templates/package/upload/debian.tmpl index 976f4ef1097d3..0a131e8c57c1e 100644 --- a/templates/package/upload/debian.tmpl +++ b/templates/package/upload/debian.tmpl @@ -1,4 +1,5 @@
+

Upload Debian Package

{{template "base/alert" .}}
{{.CsrfTokenHtml}} @@ -15,8 +16,8 @@
-
- +
+
diff --git a/templates/package/upload/generic.tmpl b/templates/package/upload/generic.tmpl index 494ebf753420d..4e90d7e40289f 100644 --- a/templates/package/upload/generic.tmpl +++ b/templates/package/upload/generic.tmpl @@ -1,4 +1,5 @@
+

Upload Generic Package

{{template "base/alert" .}} {{.CsrfTokenHtml}} @@ -17,11 +18,11 @@
- +
-
- +
+
From 6caaaf271abf605c4f5fe88f555878a5f8f7a79f Mon Sep 17 00:00:00 2001 From: JakobDev Date: Thu, 7 Sep 2023 16:13:40 +0200 Subject: [PATCH 03/10] Move Upload Code into Service --- routers/api/packages/debian/debian.go | 68 +-------------- routers/api/packages/generic/generic.go | 40 +-------- routers/web/shared/packages/upload.go | 105 +++--------------------- services/packages/upload/debian.go | 84 +++++++++++++++++++ services/packages/upload/generic.go | 55 +++++++++++++ templates/package/upload/base.tmpl | 6 +- 6 files changed, 160 insertions(+), 198 deletions(-) create mode 100644 services/packages/upload/debian.go create mode 100644 services/packages/upload/generic.go diff --git a/routers/api/packages/debian/debian.go b/routers/api/packages/debian/debian.go index 04ca2ed977c70..e0f4c10662897 100644 --- a/routers/api/packages/debian/debian.go +++ b/routers/api/packages/debian/debian.go @@ -7,20 +7,18 @@ import ( stdctx "context" "errors" "fmt" - "io" "net/http" "strings" "code.gitea.io/gitea/models/db" packages_model "code.gitea.io/gitea/models/packages" "code.gitea.io/gitea/modules/context" - packages_module "code.gitea.io/gitea/modules/packages" - debian_module "code.gitea.io/gitea/modules/packages/debian" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" notify_service "code.gitea.io/gitea/services/notify" packages_service "code.gitea.io/gitea/services/packages" debian_service "code.gitea.io/gitea/services/packages/debian" + packages_upload_service "code.gitea.io/gitea/services/packages/upload" ) func apiError(ctx *context.Context, status int, obj any) { @@ -136,69 +134,9 @@ func UploadPackageFile(ctx *context.Context) { defer upload.Close() } - buf, err := packages_module.CreateHashedBufferFromReader(upload) + statusCode, _, err := packages_upload_service.UploadDebianPackage(ctx, upload, distribution, component) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) - return - } - defer buf.Close() - - pck, err := debian_module.ParsePackage(buf) - if err != nil { - if errors.Is(err, util.ErrInvalidArgument) { - apiError(ctx, http.StatusBadRequest, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } - return - } - - if _, err := buf.Seek(0, io.SeekStart); err != nil { - apiError(ctx, http.StatusInternalServerError, err) - return - } - - _, _, err = packages_service.CreatePackageOrAddFileToExisting( - &packages_service.PackageCreationInfo{ - PackageInfo: packages_service.PackageInfo{ - Owner: ctx.Package.Owner, - PackageType: packages_model.TypeDebian, - Name: pck.Name, - Version: pck.Version, - }, - Creator: ctx.Doer, - Metadata: pck.Metadata, - }, - &packages_service.PackageFileCreationInfo{ - PackageFileInfo: packages_service.PackageFileInfo{ - Filename: fmt.Sprintf("%s_%s_%s.deb", pck.Name, pck.Version, pck.Architecture), - CompositeKey: fmt.Sprintf("%s|%s", distribution, component), - }, - Creator: ctx.Doer, - Data: buf, - IsLead: true, - Properties: map[string]string{ - debian_module.PropertyDistribution: distribution, - debian_module.PropertyComponent: component, - debian_module.PropertyArchitecture: pck.Architecture, - debian_module.PropertyControl: pck.Control, - }, - }, - ) - if err != nil { - switch err { - case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusBadRequest, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } - return - } - - if err := debian_service.BuildSpecificRepositoryFiles(ctx, ctx.Package.Owner.ID, distribution, component, pck.Architecture); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, statusCode, err) return } diff --git a/routers/api/packages/generic/generic.go b/routers/api/packages/generic/generic.go index c5866ef9c354b..2ee83cf0bf004 100644 --- a/routers/api/packages/generic/generic.go +++ b/routers/api/packages/generic/generic.go @@ -11,10 +11,9 @@ import ( packages_model "code.gitea.io/gitea/models/packages" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/log" - packages_module "code.gitea.io/gitea/modules/packages" "code.gitea.io/gitea/routers/api/packages/helper" packages_service "code.gitea.io/gitea/services/packages" + packages_upload_service "code.gitea.io/gitea/services/packages/upload" ) var ( @@ -80,42 +79,9 @@ func UploadPackage(ctx *context.Context) { defer upload.Close() } - buf, err := packages_module.CreateHashedBufferFromReader(upload) + statusCode, _, err := packages_upload_service.UploadGenericPackage(ctx, upload, packageName, packageVersion, filename) if err != nil { - log.Error("Error creating hashed buffer: %v", err) - apiError(ctx, http.StatusInternalServerError, err) - return - } - defer buf.Close() - - _, _, err = packages_service.CreatePackageOrAddFileToExisting( - &packages_service.PackageCreationInfo{ - PackageInfo: packages_service.PackageInfo{ - Owner: ctx.Package.Owner, - PackageType: packages_model.TypeGeneric, - Name: packageName, - Version: packageVersion, - }, - Creator: ctx.Doer, - }, - &packages_service.PackageFileCreationInfo{ - PackageFileInfo: packages_service.PackageFileInfo{ - Filename: filename, - }, - Creator: ctx.Doer, - Data: buf, - IsLead: true, - }, - ) - if err != nil { - switch err { - case packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, statusCode, err) return } diff --git a/routers/web/shared/packages/upload.go b/routers/web/shared/packages/upload.go index 7dbea51be5be3..c1377dce567c4 100644 --- a/routers/web/shared/packages/upload.go +++ b/routers/web/shared/packages/upload.go @@ -4,20 +4,16 @@ package packages import ( - "errors" "fmt" - "io" + "net/http" packages_model "code.gitea.io/gitea/models/packages" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" packages_module "code.gitea.io/gitea/modules/packages" - debian_module "code.gitea.io/gitea/modules/packages/debian" - "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/forms" - packages_service "code.gitea.io/gitea/services/packages" - debian_service "code.gitea.io/gitea/services/packages/debian" + packages_upload_service "code.gitea.io/gitea/services/packages/upload" ) func servePackageUploadError(ctx *context.Context, err error, packageType, repo string) { @@ -73,35 +69,14 @@ func UploadGenericPackagePost(ctx *context.Context) { filename = form.PackageFilename } - pv, _, err := packages_service.CreatePackageOrAddFileToExisting( - &packages_service.PackageCreationInfo{ - PackageInfo: packages_service.PackageInfo{ - Owner: ctx.Package.Owner, - PackageType: packages_model.TypeGeneric, - Name: form.PackageName, - Version: form.PackageVersion, - }, - Creator: ctx.Doer, - }, - &packages_service.PackageFileCreationInfo{ - PackageFileInfo: packages_service.PackageFileInfo{ - Filename: filename, - }, - Creator: ctx.Doer, - Data: buf, - IsLead: true, - }, - ) + statusCode, pv, err := packages_upload_service.UploadGenericPackage(ctx, upload, form.PackageName, form.PackageVersion, filename) if err != nil { - switch err { - case packages_model.ErrDuplicatePackageFile: - servePackageUploadError(ctx, err, "generic", form.PackageRepo) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: + if statusCode == http.StatusInternalServerError { + ctx.ServerError("UploadGenericPackage", err) + } else { servePackageUploadError(ctx, err, "generic", form.PackageRepo) - default: - ctx.ServerError("CreatePackageOrAddFileToExisting", err) + return } - return } if form.PackageRepo != "" { @@ -127,70 +102,14 @@ func UploadDebianPackagePost(ctx *context.Context) { return } - buf, err := packages_module.CreateHashedBufferFromReader(upload) - if err != nil { - ctx.ServerError("GetGenericPackageFile", err) - return - } - defer buf.Close() - - pck, err := debian_module.ParsePackage(buf) + statusCode, pv, err := packages_upload_service.UploadDebianPackage(ctx, upload, form.PackageDistribution, form.PackageComponent) if err != nil { - if errors.Is(err, util.ErrInvalidArgument) { - servePackageUploadError(ctx, err, "debian", form.PackageRepo) + if statusCode == http.StatusInternalServerError { + ctx.ServerError("UploadGenericPackage", err) } else { - ctx.ServerError("ParsePackage", err) - } - return - } - - if _, err := buf.Seek(0, io.SeekStart); err != nil { - ctx.ServerError("SeekBuffer", err) - return - } - - pv, _, err := packages_service.CreatePackageOrAddFileToExisting( - &packages_service.PackageCreationInfo{ - PackageInfo: packages_service.PackageInfo{ - Owner: ctx.Package.Owner, - PackageType: packages_model.TypeDebian, - Name: pck.Name, - Version: pck.Version, - }, - Creator: ctx.Doer, - Metadata: pck.Metadata, - }, - &packages_service.PackageFileCreationInfo{ - PackageFileInfo: packages_service.PackageFileInfo{ - Filename: fmt.Sprintf("%s_%s_%s.deb", pck.Name, pck.Version, pck.Architecture), - CompositeKey: fmt.Sprintf("%s|%s", form.PackageDistribution, form.PackageComponent), - }, - Creator: ctx.Doer, - Data: buf, - IsLead: true, - Properties: map[string]string{ - debian_module.PropertyDistribution: form.PackageDistribution, - debian_module.PropertyComponent: form.PackageComponent, - debian_module.PropertyArchitecture: pck.Architecture, - debian_module.PropertyControl: pck.Control, - }, - }, - ) - if err != nil { - switch err { - case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile: - servePackageUploadError(ctx, err, "debian", form.PackageRepo) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - servePackageUploadError(ctx, err, "debian", form.PackageRepo) - default: - ctx.ServerError("CreatePackageOrAddFileToExisting", err) + servePackageUploadError(ctx, err, "generic", form.PackageRepo) + return } - return - } - - if err := debian_service.BuildSpecificRepositoryFiles(ctx, ctx.Package.Owner.ID, form.PackageDistribution, form.PackageComponent, pck.Architecture); err != nil { - ctx.ServerError("BuildSpecificRepositoryFiles", err) - return } if form.PackageRepo != "" { diff --git a/services/packages/upload/debian.go b/services/packages/upload/debian.go new file mode 100644 index 0000000000000..b3ebbd7fed0d1 --- /dev/null +++ b/services/packages/upload/debian.go @@ -0,0 +1,84 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package upload + +import ( + "errors" + "fmt" + "io" + "net/http" + + packages_model "code.gitea.io/gitea/models/packages" + "code.gitea.io/gitea/modules/context" + packages_module "code.gitea.io/gitea/modules/packages" + debian_module "code.gitea.io/gitea/modules/packages/debian" + "code.gitea.io/gitea/modules/util" + packages_service "code.gitea.io/gitea/services/packages" + debian_service "code.gitea.io/gitea/services/packages/debian" +) + +func UploadDebianPackage(ctx *context.Context, upload io.Reader, distribution, component string) (int, *packages_model.PackageVersion, error) { + buf, err := packages_module.CreateHashedBufferFromReader(upload) + if err != nil { + return http.StatusInternalServerError, nil, err + } + defer buf.Close() + + pck, err := debian_module.ParsePackage(buf) + if err != nil { + if errors.Is(err, util.ErrInvalidArgument) { + return http.StatusBadGateway, nil, err + } + + return http.StatusInternalServerError, nil, err + } + + if _, err := buf.Seek(0, io.SeekStart); err != nil { + return http.StatusInternalServerError, nil, err + } + + pv, _, err := packages_service.CreatePackageOrAddFileToExisting( + &packages_service.PackageCreationInfo{ + PackageInfo: packages_service.PackageInfo{ + Owner: ctx.Package.Owner, + PackageType: packages_model.TypeDebian, + Name: pck.Name, + Version: pck.Version, + }, + Creator: ctx.Doer, + Metadata: pck.Metadata, + }, + &packages_service.PackageFileCreationInfo{ + PackageFileInfo: packages_service.PackageFileInfo{ + Filename: fmt.Sprintf("%s_%s_%s.deb", pck.Name, pck.Version, pck.Architecture), + CompositeKey: fmt.Sprintf("%s|%s", distribution, component), + }, + Creator: ctx.Doer, + Data: buf, + IsLead: true, + Properties: map[string]string{ + debian_module.PropertyDistribution: distribution, + debian_module.PropertyComponent: component, + debian_module.PropertyArchitecture: pck.Architecture, + debian_module.PropertyControl: pck.Control, + }, + }, + ) + if err != nil { + switch err { + case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile: + return http.StatusBadRequest, nil, err + case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: + return http.StatusForbidden, nil, err + default: + return http.StatusInternalServerError, nil, err + } + } + + if err := debian_service.BuildSpecificRepositoryFiles(ctx, ctx.Package.Owner.ID, distribution, component, pck.Architecture); err != nil { + return http.StatusInternalServerError, nil, err + } + + return http.StatusOK, pv, nil +} diff --git a/services/packages/upload/generic.go b/services/packages/upload/generic.go new file mode 100644 index 0000000000000..4ce62d1f141cf --- /dev/null +++ b/services/packages/upload/generic.go @@ -0,0 +1,55 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package upload + +import ( + "io" + "net/http" + + packages_model "code.gitea.io/gitea/models/packages" + "code.gitea.io/gitea/modules/context" + packages_module "code.gitea.io/gitea/modules/packages" + packages_service "code.gitea.io/gitea/services/packages" +) + +func UploadGenericPackage(ctx *context.Context, upload io.Reader, name, version, filename string) (int, *packages_model.PackageVersion, error) { + buf, err := packages_module.CreateHashedBufferFromReader(upload) + if err != nil { + ctx.ServerError("CreateHashedBufferFromReader", err) + return http.StatusInternalServerError, nil, err + } + defer buf.Close() + + pv, _, err := packages_service.CreatePackageOrAddFileToExisting( + &packages_service.PackageCreationInfo{ + PackageInfo: packages_service.PackageInfo{ + Owner: ctx.Package.Owner, + PackageType: packages_model.TypeGeneric, + Name: name, + Version: version, + }, + Creator: ctx.Doer, + }, + &packages_service.PackageFileCreationInfo{ + PackageFileInfo: packages_service.PackageFileInfo{ + Filename: filename, + }, + Creator: ctx.Doer, + Data: buf, + IsLead: true, + }, + ) + if err != nil { + switch err { + case packages_model.ErrDuplicatePackageFile: + return http.StatusConflict, nil, err + case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: + return http.StatusForbidden, nil, err + default: + return http.StatusInternalServerError, nil, err + } + } + + return http.StatusOK, pv, nil +} diff --git a/templates/package/upload/base.tmpl b/templates/package/upload/base.tmpl index cb70150bc2e5c..396e925f04e8f 100644 --- a/templates/package/upload/base.tmpl +++ b/templates/package/upload/base.tmpl @@ -1,7 +1,7 @@ {{if eq $.PackageUploadPage "choose"}} - {{template "package/upload/choose" .}} + {{template "package/upload/choose" .}} {{else if eq $.PackageUploadPage "generic"}} - {{template "package/upload/generic" .}} + {{template "package/upload/generic" .}} {{else if eq $.PackageUploadPage "debian"}} - {{template "package/upload/debian" .}} + {{template "package/upload/debian" .}} {{end}} From d0e269b04f0da436c891264952a917dc907be94c Mon Sep 17 00:00:00 2001 From: JakobDev Date: Thu, 7 Sep 2023 16:49:27 +0200 Subject: [PATCH 04/10] Add support for RPM packages --- routers/api/packages/rpm/rpm.go | 71 +--------------------- routers/web/shared/packages/upload.go | 44 +++++++++++--- routers/web/user/package.go | 2 +- routers/web/web.go | 1 + services/forms/package_form.go | 5 ++ services/packages/upload/debian.go | 2 +- services/packages/upload/rpm.go | 86 +++++++++++++++++++++++++++ templates/package/upload/base.tmpl | 2 + templates/package/upload/choose.tmpl | 4 ++ templates/package/upload/rpm.tmpl | 18 ++++++ 10 files changed, 157 insertions(+), 78 deletions(-) create mode 100644 services/packages/upload/rpm.go create mode 100644 templates/package/upload/rpm.tmpl diff --git a/routers/api/packages/rpm/rpm.go b/routers/api/packages/rpm/rpm.go index 1e462bb9080f4..edd9bc3f90213 100644 --- a/routers/api/packages/rpm/rpm.go +++ b/routers/api/packages/rpm/rpm.go @@ -7,22 +7,19 @@ import ( stdctx "context" "errors" "fmt" - "io" "net/http" "strings" "code.gitea.io/gitea/models/db" packages_model "code.gitea.io/gitea/models/packages" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/json" - packages_module "code.gitea.io/gitea/modules/packages" - rpm_module "code.gitea.io/gitea/modules/packages/rpm" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" notify_service "code.gitea.io/gitea/services/notify" packages_service "code.gitea.io/gitea/services/packages" rpm_service "code.gitea.io/gitea/services/packages/rpm" + packages_upload_service "code.gitea.io/gitea/services/packages/upload" ) func apiError(ctx *context.Context, status int, obj any) { @@ -94,71 +91,9 @@ func UploadPackageFile(ctx *context.Context) { defer upload.Close() } - buf, err := packages_module.CreateHashedBufferFromReader(upload) + statusCode, _, err := packages_upload_service.UploadRpmPackage(ctx, upload) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) - return - } - defer buf.Close() - - pck, err := rpm_module.ParsePackage(buf) - if err != nil { - if errors.Is(err, util.ErrInvalidArgument) { - apiError(ctx, http.StatusBadRequest, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } - return - } - - if _, err := buf.Seek(0, io.SeekStart); err != nil { - apiError(ctx, http.StatusInternalServerError, err) - return - } - - fileMetadataRaw, err := json.Marshal(pck.FileMetadata) - if err != nil { - apiError(ctx, http.StatusInternalServerError, err) - return - } - - _, _, err = packages_service.CreatePackageOrAddFileToExisting( - &packages_service.PackageCreationInfo{ - PackageInfo: packages_service.PackageInfo{ - Owner: ctx.Package.Owner, - PackageType: packages_model.TypeRpm, - Name: pck.Name, - Version: pck.Version, - }, - Creator: ctx.Doer, - Metadata: pck.VersionMetadata, - }, - &packages_service.PackageFileCreationInfo{ - PackageFileInfo: packages_service.PackageFileInfo{ - Filename: fmt.Sprintf("%s-%s.%s.rpm", pck.Name, pck.Version, pck.FileMetadata.Architecture), - }, - Creator: ctx.Doer, - Data: buf, - IsLead: true, - Properties: map[string]string{ - rpm_module.PropertyMetadata: string(fileMetadataRaw), - }, - }, - ) - if err != nil { - switch err { - case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } - return - } - - if err := rpm_service.BuildRepositoryFiles(ctx, ctx.Package.Owner.ID); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, statusCode, err) return } diff --git a/routers/web/shared/packages/upload.go b/routers/web/shared/packages/upload.go index c1377dce567c4..80d2ab72783e8 100644 --- a/routers/web/shared/packages/upload.go +++ b/routers/web/shared/packages/upload.go @@ -10,7 +10,6 @@ import ( packages_model "code.gitea.io/gitea/models/packages" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" - packages_module "code.gitea.io/gitea/modules/packages" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/forms" packages_upload_service "code.gitea.io/gitea/services/packages/upload" @@ -55,13 +54,6 @@ func UploadGenericPackagePost(ctx *context.Context) { return } - buf, err := packages_module.CreateHashedBufferFromReader(upload) - if err != nil { - ctx.ServerError("CreateHashedBufferFromReader", err) - return - } - defer buf.Close() - var filename string if form.PackageFilename == "" { filename = form.PackageFile.Filename @@ -73,6 +65,7 @@ func UploadGenericPackagePost(ctx *context.Context) { if err != nil { if statusCode == http.StatusInternalServerError { ctx.ServerError("UploadGenericPackage", err) + return } else { servePackageUploadError(ctx, err, "generic", form.PackageRepo) return @@ -106,6 +99,7 @@ func UploadDebianPackagePost(ctx *context.Context) { if err != nil { if statusCode == http.StatusInternalServerError { ctx.ServerError("UploadGenericPackage", err) + return } else { servePackageUploadError(ctx, err, "generic", form.PackageRepo) return @@ -126,3 +120,37 @@ func UploadDebianPackagePost(ctx *context.Context) { ctx.Redirect(pd.FullWebLink()) } + +func UploadRpmPackagePost(ctx *context.Context) { + form := web.GetForm(ctx).(*forms.PackageUploadRpmForm) + upload, err := form.PackageFile.Open() + if err != nil { + ctx.ServerError("GetPackageFile", err) + return + } + + statusCode, pv, err := packages_upload_service.UploadRpmPackage(ctx, upload) + if err != nil { + if statusCode == http.StatusInternalServerError { + ctx.ServerError("UploadRpmPackage", err) + return + } else { + servePackageUploadError(ctx, err, "rpm", form.PackageRepo) + return + } + } + + if form.PackageRepo != "" { + if !addRepoToUploadedPackage(ctx, "rpm", form.PackageRepo, pv.PackageID) { + return + } + } + + pd, err := packages_model.GetPackageDescriptor(ctx, pv) + if err != nil { + ctx.ServerError("GetPackageDescriptor", err) + return + } + + ctx.Redirect(pd.FullWebLink()) +} diff --git a/routers/web/user/package.go b/routers/web/user/package.go index 9e9408297f582..4165706f2c976 100644 --- a/routers/web/user/package.go +++ b/routers/web/user/package.go @@ -510,7 +510,7 @@ func UploadPackagePage(ctx *context.Context) { packageType := ctx.Params("upload_type") - allowdTypes := []string{"generic", "debian"} + allowdTypes := []string{"generic", "debian", "rpm"} if !slices.Contains(allowdTypes, packageType) { ctx.NotFound("", nil) diff --git a/routers/web/web.go b/routers/web/web.go index 86f23b4558ba8..64dddaabb3d82 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -834,6 +834,7 @@ func registerRoutes(m *web.Route) { m.Get("/{upload_type}", user.UploadPackagePage) m.Post("/generic/upload", web.Bind(forms.PackageUploadGenericForm{}), packages.UploadGenericPackagePost) m.Post("/debian/upload", web.Bind(forms.PackageUploadDebianForm{}), packages.UploadDebianPackagePost) + m.Post("/rpm/upload", web.Bind(forms.PackageUploadRpmForm{}), packages.UploadRpmPackagePost) }, reqPackageAccess(perm.AccessModeWrite)) }, context.PackageAssignment(), reqPackageAccess(perm.AccessModeRead)) } diff --git a/services/forms/package_form.go b/services/forms/package_form.go index 2906eccfeb9c7..d26fc72f9a436 100644 --- a/services/forms/package_form.go +++ b/services/forms/package_form.go @@ -44,3 +44,8 @@ type PackageUploadDebianForm struct { PackageComponent string PackageFile *multipart.FileHeader } + +type PackageUploadRpmForm struct { + PackageRepo string + PackageFile *multipart.FileHeader +} diff --git a/services/packages/upload/debian.go b/services/packages/upload/debian.go index b3ebbd7fed0d1..d485f2b600db4 100644 --- a/services/packages/upload/debian.go +++ b/services/packages/upload/debian.go @@ -28,7 +28,7 @@ func UploadDebianPackage(ctx *context.Context, upload io.Reader, distribution, c pck, err := debian_module.ParsePackage(buf) if err != nil { if errors.Is(err, util.ErrInvalidArgument) { - return http.StatusBadGateway, nil, err + return http.StatusBadRequest, nil, err } return http.StatusInternalServerError, nil, err diff --git a/services/packages/upload/rpm.go b/services/packages/upload/rpm.go new file mode 100644 index 0000000000000..e56f584043222 --- /dev/null +++ b/services/packages/upload/rpm.go @@ -0,0 +1,86 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package upload + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + + packages_model "code.gitea.io/gitea/models/packages" + "code.gitea.io/gitea/modules/context" + packages_module "code.gitea.io/gitea/modules/packages" + rpm_module "code.gitea.io/gitea/modules/packages/rpm" + "code.gitea.io/gitea/modules/util" + packages_service "code.gitea.io/gitea/services/packages" + rpm_service "code.gitea.io/gitea/services/packages/rpm" +) + +func UploadRpmPackage(ctx *context.Context, upload io.Reader) (int, *packages_model.PackageVersion, error) { + buf, err := packages_module.CreateHashedBufferFromReader(upload) + if err != nil { + return http.StatusInternalServerError, nil, err + } + defer buf.Close() + + pck, err := rpm_module.ParsePackage(buf) + if err != nil { + if errors.Is(err, util.ErrInvalidArgument) { + return http.StatusBadRequest, nil, err + } + + return http.StatusInternalServerError, nil, err + } + + if _, err := buf.Seek(0, io.SeekStart); err != nil { + return http.StatusInternalServerError, nil, err + } + + fileMetadataRaw, err := json.Marshal(pck.FileMetadata) + if err != nil { + return http.StatusInternalServerError, nil, err + } + + pv, _, err := packages_service.CreatePackageOrAddFileToExisting( + &packages_service.PackageCreationInfo{ + PackageInfo: packages_service.PackageInfo{ + Owner: ctx.Package.Owner, + PackageType: packages_model.TypeRpm, + Name: pck.Name, + Version: pck.Version, + }, + Creator: ctx.Doer, + Metadata: pck.VersionMetadata, + }, + &packages_service.PackageFileCreationInfo{ + PackageFileInfo: packages_service.PackageFileInfo{ + Filename: fmt.Sprintf("%s-%s.%s.rpm", pck.Name, pck.Version, pck.FileMetadata.Architecture), + }, + Creator: ctx.Doer, + Data: buf, + IsLead: true, + Properties: map[string]string{ + rpm_module.PropertyMetadata: string(fileMetadataRaw), + }, + }, + ) + if err != nil { + switch err { + case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile: + return http.StatusConflict, nil, err + case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: + return http.StatusForbidden, nil, err + default: + return http.StatusInternalServerError, nil, err + } + } + + if err := rpm_service.BuildRepositoryFiles(ctx, ctx.Package.Owner.ID); err != nil { + return http.StatusInternalServerError, nil, err + } + + return http.StatusOK, pv, nil +} diff --git a/templates/package/upload/base.tmpl b/templates/package/upload/base.tmpl index 396e925f04e8f..3b690a73d3e47 100644 --- a/templates/package/upload/base.tmpl +++ b/templates/package/upload/base.tmpl @@ -4,4 +4,6 @@ {{template "package/upload/generic" .}} {{else if eq $.PackageUploadPage "debian"}} {{template "package/upload/debian" .}} +{{else if eq $.PackageUploadPage "rpm"}} + {{template "package/upload/rpm" .}} {{end}} diff --git a/templates/package/upload/choose.tmpl b/templates/package/upload/choose.tmpl index ade79e3b2a1ac..4c472bec0ae2e 100644 --- a/templates/package/upload/choose.tmpl +++ b/templates/package/upload/choose.tmpl @@ -8,5 +8,9 @@ Debian Upload + + RPM + Upload + diff --git a/templates/package/upload/rpm.tmpl b/templates/package/upload/rpm.tmpl new file mode 100644 index 0000000000000..bab3048beeffa --- /dev/null +++ b/templates/package/upload/rpm.tmpl @@ -0,0 +1,18 @@ +
+

Upload RPM Package

+ {{template "base/alert" .}} + + {{.CsrfTokenHtml}} + + + +
+ + +
+ +
+ +
+ +
From 3be5ad7489729d567cbbc1256309dc489499938f Mon Sep 17 00:00:00 2001 From: JakobDev Date: Tue, 12 Sep 2023 08:16:44 +0200 Subject: [PATCH 05/10] Some Frontend refactoring --- routers/api/packages/debian/debian.go | 3 +- routers/api/packages/generic/generic.go | 4 +-- routers/api/packages/rpm/rpm.go | 3 +- routers/web/shared/packages/upload.go | 28 ++++++++++--------- .../{upload/debian.go => debian/upload.go} | 5 ++-- .../{upload/generic.go => generic/upload.go} | 0 .../packages/{upload/rpm.go => rpm/upload.go} | 5 ++-- 7 files changed, 23 insertions(+), 25 deletions(-) rename services/packages/{upload/debian.go => debian/upload.go} (91%) rename services/packages/{upload/generic.go => generic/upload.go} (100%) rename services/packages/{upload/rpm.go => rpm/upload.go} (93%) diff --git a/routers/api/packages/debian/debian.go b/routers/api/packages/debian/debian.go index e0f4c10662897..2e0d61e28f17c 100644 --- a/routers/api/packages/debian/debian.go +++ b/routers/api/packages/debian/debian.go @@ -18,7 +18,6 @@ import ( notify_service "code.gitea.io/gitea/services/notify" packages_service "code.gitea.io/gitea/services/packages" debian_service "code.gitea.io/gitea/services/packages/debian" - packages_upload_service "code.gitea.io/gitea/services/packages/upload" ) func apiError(ctx *context.Context, status int, obj any) { @@ -134,7 +133,7 @@ func UploadPackageFile(ctx *context.Context) { defer upload.Close() } - statusCode, _, err := packages_upload_service.UploadDebianPackage(ctx, upload, distribution, component) + statusCode, _, err := debian_service.UploadDebianPackage(ctx, upload, distribution, component) if err != nil { apiError(ctx, statusCode, err) return diff --git a/routers/api/packages/generic/generic.go b/routers/api/packages/generic/generic.go index 2ee83cf0bf004..96c8d559db4ff 100644 --- a/routers/api/packages/generic/generic.go +++ b/routers/api/packages/generic/generic.go @@ -13,7 +13,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/routers/api/packages/helper" packages_service "code.gitea.io/gitea/services/packages" - packages_upload_service "code.gitea.io/gitea/services/packages/upload" + generic_service "code.gitea.io/gitea/services/packages/generic" ) var ( @@ -79,7 +79,7 @@ func UploadPackage(ctx *context.Context) { defer upload.Close() } - statusCode, _, err := packages_upload_service.UploadGenericPackage(ctx, upload, packageName, packageVersion, filename) + statusCode, _, err := generic_service.UploadGenericPackage(ctx, upload, packageName, packageVersion, filename) if err != nil { apiError(ctx, statusCode, err) return diff --git a/routers/api/packages/rpm/rpm.go b/routers/api/packages/rpm/rpm.go index edd9bc3f90213..9017125fefa79 100644 --- a/routers/api/packages/rpm/rpm.go +++ b/routers/api/packages/rpm/rpm.go @@ -19,7 +19,6 @@ import ( notify_service "code.gitea.io/gitea/services/notify" packages_service "code.gitea.io/gitea/services/packages" rpm_service "code.gitea.io/gitea/services/packages/rpm" - packages_upload_service "code.gitea.io/gitea/services/packages/upload" ) func apiError(ctx *context.Context, status int, obj any) { @@ -91,7 +90,7 @@ func UploadPackageFile(ctx *context.Context) { defer upload.Close() } - statusCode, _, err := packages_upload_service.UploadRpmPackage(ctx, upload) + statusCode, _, err := rpm_service.UploadRpmPackage(ctx, upload) if err != nil { apiError(ctx, statusCode, err) return diff --git a/routers/web/shared/packages/upload.go b/routers/web/shared/packages/upload.go index 80d2ab72783e8..60828f1c89d17 100644 --- a/routers/web/shared/packages/upload.go +++ b/routers/web/shared/packages/upload.go @@ -12,7 +12,9 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/forms" - packages_upload_service "code.gitea.io/gitea/services/packages/upload" + debian_service "code.gitea.io/gitea/services/packages/debian" + generic_service "code.gitea.io/gitea/services/packages/generic" + rpm_service "code.gitea.io/gitea/services/packages/rpm" ) func servePackageUploadError(ctx *context.Context, err error, packageType, repo string) { @@ -61,15 +63,15 @@ func UploadGenericPackagePost(ctx *context.Context) { filename = form.PackageFilename } - statusCode, pv, err := packages_upload_service.UploadGenericPackage(ctx, upload, form.PackageName, form.PackageVersion, filename) + statusCode, pv, err := generic_service.UploadGenericPackage(ctx, upload, form.PackageName, form.PackageVersion, filename) if err != nil { if statusCode == http.StatusInternalServerError { ctx.ServerError("UploadGenericPackage", err) return - } else { - servePackageUploadError(ctx, err, "generic", form.PackageRepo) - return } + + servePackageUploadError(ctx, err, "generic", form.PackageRepo) + return } if form.PackageRepo != "" { @@ -95,15 +97,15 @@ func UploadDebianPackagePost(ctx *context.Context) { return } - statusCode, pv, err := packages_upload_service.UploadDebianPackage(ctx, upload, form.PackageDistribution, form.PackageComponent) + statusCode, pv, err := debian_service.UploadDebianPackage(ctx, upload, form.PackageDistribution, form.PackageComponent) if err != nil { if statusCode == http.StatusInternalServerError { ctx.ServerError("UploadGenericPackage", err) return - } else { - servePackageUploadError(ctx, err, "generic", form.PackageRepo) - return } + + servePackageUploadError(ctx, err, "debian", form.PackageRepo) + return } if form.PackageRepo != "" { @@ -129,15 +131,15 @@ func UploadRpmPackagePost(ctx *context.Context) { return } - statusCode, pv, err := packages_upload_service.UploadRpmPackage(ctx, upload) + statusCode, pv, err := rpm_service.UploadRpmPackage(ctx, upload) if err != nil { if statusCode == http.StatusInternalServerError { ctx.ServerError("UploadRpmPackage", err) return - } else { - servePackageUploadError(ctx, err, "rpm", form.PackageRepo) - return } + + servePackageUploadError(ctx, err, "rpm", form.PackageRepo) + return } if form.PackageRepo != "" { diff --git a/services/packages/upload/debian.go b/services/packages/debian/upload.go similarity index 91% rename from services/packages/upload/debian.go rename to services/packages/debian/upload.go index d485f2b600db4..c4fa698b62038 100644 --- a/services/packages/upload/debian.go +++ b/services/packages/debian/upload.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package upload +package debian import ( "errors" @@ -15,7 +15,6 @@ import ( debian_module "code.gitea.io/gitea/modules/packages/debian" "code.gitea.io/gitea/modules/util" packages_service "code.gitea.io/gitea/services/packages" - debian_service "code.gitea.io/gitea/services/packages/debian" ) func UploadDebianPackage(ctx *context.Context, upload io.Reader, distribution, component string) (int, *packages_model.PackageVersion, error) { @@ -76,7 +75,7 @@ func UploadDebianPackage(ctx *context.Context, upload io.Reader, distribution, c } } - if err := debian_service.BuildSpecificRepositoryFiles(ctx, ctx.Package.Owner.ID, distribution, component, pck.Architecture); err != nil { + if err := BuildSpecificRepositoryFiles(ctx, ctx.Package.Owner.ID, distribution, component, pck.Architecture); err != nil { return http.StatusInternalServerError, nil, err } diff --git a/services/packages/upload/generic.go b/services/packages/generic/upload.go similarity index 100% rename from services/packages/upload/generic.go rename to services/packages/generic/upload.go diff --git a/services/packages/upload/rpm.go b/services/packages/rpm/upload.go similarity index 93% rename from services/packages/upload/rpm.go rename to services/packages/rpm/upload.go index e56f584043222..81a9584e78b26 100644 --- a/services/packages/upload/rpm.go +++ b/services/packages/rpm/upload.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package upload +package rpm import ( "encoding/json" @@ -16,7 +16,6 @@ import ( rpm_module "code.gitea.io/gitea/modules/packages/rpm" "code.gitea.io/gitea/modules/util" packages_service "code.gitea.io/gitea/services/packages" - rpm_service "code.gitea.io/gitea/services/packages/rpm" ) func UploadRpmPackage(ctx *context.Context, upload io.Reader) (int, *packages_model.PackageVersion, error) { @@ -78,7 +77,7 @@ func UploadRpmPackage(ctx *context.Context, upload io.Reader) (int, *packages_mo } } - if err := rpm_service.BuildRepositoryFiles(ctx, ctx.Package.Owner.ID); err != nil { + if err := BuildRepositoryFiles(ctx, ctx.Package.Owner.ID); err != nil { return http.StatusInternalServerError, nil, err } From c9a0ac7e6cd8fb5cee279ce4053be48a8d2baf8d Mon Sep 17 00:00:00 2001 From: JakobDev Date: Tue, 12 Sep 2023 10:29:41 +0200 Subject: [PATCH 06/10] More refactoring --- models/packages/package.go | 15 +++++++++++++ options/locale/locale_en-US.ini | 13 +++++++++++ routers/web/repo/packages.go | 18 +++++++++------- routers/web/shared/packages/upload.go | 6 ++++++ routers/web/user/package.go | 31 +++++++-------------------- routers/web/web.go | 3 +-- services/packages/generic/upload.go | 2 +- services/packages/rpm/upload.go | 2 +- templates/package/shared/list.tmpl | 10 ++++++++- templates/package/upload/base.tmpl | 10 ++++----- templates/package/upload/choose.tmpl | 16 -------------- templates/package/upload/debian.tmpl | 14 ++++++------ templates/package/upload/generic.tmpl | 18 ++++++++-------- templates/package/upload/rpm.tmpl | 6 +++--- 14 files changed, 87 insertions(+), 77 deletions(-) delete mode 100644 templates/package/upload/choose.tmpl diff --git a/models/packages/package.go b/models/packages/package.go index 380a076f9dfe1..159967ac29175 100644 --- a/models/packages/package.go +++ b/models/packages/package.go @@ -175,6 +175,21 @@ func (pt Type) SVGName() string { panic(fmt.Sprintf("unknown package type: %s", string(pt))) } +// String converts the package type to a string +func (pt Type) String() string { + return string(pt) +} + +// GetPackageTypeByString returns the type for the given string +func GetPackageTypeByString(typeName string) *Type { + for _, currentType := range TypeList { + if currentType.String() == typeName { + return ¤tType + } + } + return nil +} + // Package represents a package type Package struct { ID int64 `xorm:"pk autoincr"` diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 4f5f0383e9aa2..883c051ae51bd 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -3436,6 +3436,19 @@ owner.settings.cleanuprules.success.delete = Cleanup rule has been deleted. owner.settings.chef.title = Chef Registry owner.settings.chef.keypair = Generate key pair owner.settings.chef.keypair.description = A key pair is necessary to authenticate to the Chef registry. If you have generated a key pair before, generating a new key pair will discard the old key pair. +upload.button = Upload +upload.title = Upload %s Package +upload.distribution.label = Distribution: +upload.distribution.placeholder = The distribution may match the release name of the OS +upload.component.label = Component: +upload.component.placeholder = The component can be used to group packages or just main or similar +upload.file.label = File: +upload.name.label = Name: +upload.name.placeholder = The package name +upload.version.label = Version: +upload.version.placeholder = The package version +upload.filename.label = Filename: +upload.filename.placeholder = The filename (leave empty to use name from uploaded file) [secrets] secrets = Secrets diff --git a/routers/web/repo/packages.go b/routers/web/repo/packages.go index 255a10fd9e2fd..169a52a0de63c 100644 --- a/routers/web/repo/packages.go +++ b/routers/web/repo/packages.go @@ -8,12 +8,13 @@ import ( "net/http" "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/models/packages" + packages_model "code.gitea.io/gitea/models/packages" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/routers/web/shared/packages" ) const ( @@ -29,15 +30,15 @@ func Packages(ctx *context.Context) { query := ctx.FormTrim("q") packageType := ctx.FormTrim("type") - pvs, total, err := packages.SearchLatestVersions(ctx, &packages.PackageSearchOptions{ + pvs, total, err := packages_model.SearchLatestVersions(ctx, &packages_model.PackageSearchOptions{ Paginator: &db.ListOptions{ PageSize: setting.UI.PackagesPagingNum, Page: page, }, OwnerID: ctx.ContextUser.ID, RepoID: ctx.Repo.Repository.ID, - Type: packages.Type(packageType), - Name: packages.SearchValue{Value: query}, + Type: packages_model.Type(packageType), + Name: packages_model.SearchValue{Value: query}, IsInternal: util.OptionalBoolFalse, }) if err != nil { @@ -45,13 +46,13 @@ func Packages(ctx *context.Context) { return } - pds, err := packages.GetPackageDescriptors(ctx, pvs) + pds, err := packages_model.GetPackageDescriptors(ctx, pvs) if err != nil { ctx.ServerError("GetPackageDescriptors", err) return } - hasPackages, err := packages.HasRepositoryPackages(ctx, ctx.Repo.Repository.ID) + hasPackages, err := packages_model.HasRepositoryPackages(ctx, ctx.Repo.Repository.ID) if err != nil { ctx.ServerError("HasRepositoryPackages", err) return @@ -61,13 +62,14 @@ func Packages(ctx *context.Context) { ctx.Data["IsPackagesPage"] = true ctx.Data["Query"] = query ctx.Data["PackageType"] = packageType - ctx.Data["AvailableTypes"] = packages.TypeList + ctx.Data["AvailableTypes"] = packages_model.TypeList ctx.Data["HasPackages"] = hasPackages if ctx.Repo != nil { ctx.Data["CanWritePackages"] = ctx.IsUserRepoWriter([]unit.Type{unit.TypePackages}) || ctx.IsUserSiteAdmin() ctx.Data["ShowPackageUploadButton"] = ctx.Data["CanWritePackages"] - ctx.Data["PackageUploadUrl"] = fmt.Sprintf("%s/-/packages/upload", ctx.Repo.Owner.HTMLURL()) + ctx.Data["PackageUploadUrl"] = fmt.Sprintf("%s/-/packages/upload/", ctx.Repo.Owner.HTMLURL()) ctx.Data["PackageUploadRepo"] = ctx.Repo.Repository.Name + ctx.Data["AllowedUploadTypes"] = packages.UploadTypeList } ctx.Data["PackageDescriptors"] = pds ctx.Data["Total"] = total diff --git a/routers/web/shared/packages/upload.go b/routers/web/shared/packages/upload.go index 60828f1c89d17..33e8b19d2c3ee 100644 --- a/routers/web/shared/packages/upload.go +++ b/routers/web/shared/packages/upload.go @@ -17,6 +17,12 @@ import ( rpm_service "code.gitea.io/gitea/services/packages/rpm" ) +var UploadTypeList = []packages_model.Type{ + packages_model.TypeDebian, + packages_model.TypeGeneric, + packages_model.TypeRpm, +} + func servePackageUploadError(ctx *context.Context, err error, packageType, repo string) { ctx.Flash.Error(err.Error()) diff --git a/routers/web/user/package.go b/routers/web/user/package.go index 4165706f2c976..fad628a9b0249 100644 --- a/routers/web/user/package.go +++ b/routers/web/user/package.go @@ -25,6 +25,7 @@ import ( "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" packages_helper "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/routers/web/shared/packages" shared_user "code.gitea.io/gitea/routers/web/shared/user" "code.gitea.io/gitea/services/forms" packages_service "code.gitea.io/gitea/services/packages" @@ -103,7 +104,8 @@ func ListPackages(ctx *context.Context) { ctx.Data["PackageDescriptors"] = pds ctx.Data["Total"] = total ctx.Data["RepositoryAccessMap"] = repositoryAccessMap - ctx.Data["PackageUploadUrl"] = fmt.Sprintf("%s/-/packages/upload", ctx.ContextUser.HTMLURL()) + ctx.Data["PackageUploadUrl"] = fmt.Sprintf("%s/-/packages/upload/", ctx.ContextUser.HTMLURL()) + ctx.Data["AllowedUploadTypes"] = packages.UploadTypeList err = shared_user.LoadHeaderCount(ctx) if err != nil { @@ -489,37 +491,20 @@ func DownloadPackageFile(ctx *context.Context) { packages_helper.ServePackageFile(ctx, s, u, pf) } -func UploadPackageChoose(ctx *context.Context) { +func UploadPackage(ctx *context.Context) { shared_user.PrepareContextForProfileBigAvatar(ctx) - ctx.Data["IsPackagesPage"] = true - ctx.Data["PackageUploadPage"] = "choose" - ctx.Data["PackageUploadRepo"] = ctx.FormString("repo") - - err := shared_user.LoadHeaderCount(ctx) - if err != nil { - ctx.ServerError("LoadHeaderCount", err) - return - } - - ctx.HTML(http.StatusOK, tplPackageUpload) -} - -func UploadPackagePage(ctx *context.Context) { - shared_user.PrepareContextForProfileBigAvatar(ctx) - - packageType := ctx.Params("upload_type") - - allowdTypes := []string{"generic", "debian", "rpm"} + packageType := packages_model.GetPackageTypeByString(ctx.Params("upload_type")) - if !slices.Contains(allowdTypes, packageType) { + if packageType == nil || !slices.Contains(packages.UploadTypeList, *packageType) { ctx.NotFound("", nil) return } ctx.Data["IsPackagesPage"] = true - ctx.Data["PackageUploadPage"] = packageType + ctx.Data["PackageUploadType"] = packageType ctx.Data["PackageUploadRepo"] = ctx.FormString("repo") + ctx.Data["Title"] = ctx.Tr("packages.upload.title", packageType.Name()) err := shared_user.LoadHeaderCount(ctx) if err != nil { diff --git a/routers/web/web.go b/routers/web/web.go index 64dddaabb3d82..745d8afc0d8d5 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -830,8 +830,7 @@ func registerRoutes(m *web.Route) { }) }) m.Group("/upload", func() { - m.Get("", user.UploadPackageChoose) - m.Get("/{upload_type}", user.UploadPackagePage) + m.Get("/{upload_type}", user.UploadPackage) m.Post("/generic/upload", web.Bind(forms.PackageUploadGenericForm{}), packages.UploadGenericPackagePost) m.Post("/debian/upload", web.Bind(forms.PackageUploadDebianForm{}), packages.UploadDebianPackagePost) m.Post("/rpm/upload", web.Bind(forms.PackageUploadRpmForm{}), packages.UploadRpmPackagePost) diff --git a/services/packages/generic/upload.go b/services/packages/generic/upload.go index 4ce62d1f141cf..0ff47b15311fe 100644 --- a/services/packages/generic/upload.go +++ b/services/packages/generic/upload.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package upload +package generic import ( "io" diff --git a/services/packages/rpm/upload.go b/services/packages/rpm/upload.go index 81a9584e78b26..320420a6d3a2f 100644 --- a/services/packages/rpm/upload.go +++ b/services/packages/rpm/upload.go @@ -4,7 +4,6 @@ package rpm import ( - "encoding/json" "errors" "fmt" "io" @@ -12,6 +11,7 @@ import ( packages_model "code.gitea.io/gitea/models/packages" "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/json" packages_module "code.gitea.io/gitea/modules/packages" rpm_module "code.gitea.io/gitea/modules/packages/rpm" "code.gitea.io/gitea/modules/util" diff --git a/templates/package/shared/list.tmpl b/templates/package/shared/list.tmpl index 4c904bb3d1d58..02c2cb043424e 100644 --- a/templates/package/shared/list.tmpl +++ b/templates/package/shared/list.tmpl @@ -11,7 +11,15 @@ {{if .ShowPackageUploadButton}} - Upload + {{end}}
diff --git a/templates/package/upload/base.tmpl b/templates/package/upload/base.tmpl index 3b690a73d3e47..005c565c765b2 100644 --- a/templates/package/upload/base.tmpl +++ b/templates/package/upload/base.tmpl @@ -1,9 +1,7 @@ -{{if eq $.PackageUploadPage "choose"}} - {{template "package/upload/choose" .}} -{{else if eq $.PackageUploadPage "generic"}} - {{template "package/upload/generic" .}} -{{else if eq $.PackageUploadPage "debian"}} +{{if eq $.PackageUploadType.String "debian"}} {{template "package/upload/debian" .}} -{{else if eq $.PackageUploadPage "rpm"}} +{{else if eq $.PackageUploadType.String "generic"}} + {{template "package/upload/generic" .}} +{{else if eq $.PackageUploadType.String "rpm"}} {{template "package/upload/rpm" .}} {{end}} diff --git a/templates/package/upload/choose.tmpl b/templates/package/upload/choose.tmpl deleted file mode 100644 index 4c472bec0ae2e..0000000000000 --- a/templates/package/upload/choose.tmpl +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - -
GenericUpload
DebianUpload
RPMUpload
diff --git a/templates/package/upload/debian.tmpl b/templates/package/upload/debian.tmpl index 0a131e8c57c1e..ea510245e7a58 100644 --- a/templates/package/upload/debian.tmpl +++ b/templates/package/upload/debian.tmpl @@ -1,5 +1,5 @@
-

Upload Debian Package

+

{{.Title}}

{{template "base/alert" .}}
{{.CsrfTokenHtml}} @@ -7,22 +7,22 @@
- - + +
- - + +
- +
- +
diff --git a/templates/package/upload/generic.tmpl b/templates/package/upload/generic.tmpl index 4e90d7e40289f..7ad0952eada05 100644 --- a/templates/package/upload/generic.tmpl +++ b/templates/package/upload/generic.tmpl @@ -1,5 +1,5 @@
-

Upload Generic Package

+

{{.Title}}

{{template "base/alert" .}}
{{.CsrfTokenHtml}} @@ -7,27 +7,27 @@
- - + +
- - + +
- - + +
- +
- +
diff --git a/templates/package/upload/rpm.tmpl b/templates/package/upload/rpm.tmpl index bab3048beeffa..942b7bd10ad3c 100644 --- a/templates/package/upload/rpm.tmpl +++ b/templates/package/upload/rpm.tmpl @@ -1,5 +1,5 @@
-

Upload RPM Package

+

{{.Title}}

{{template "base/alert" .}}
{{.CsrfTokenHtml}} @@ -7,12 +7,12 @@
- +
- +
From 3a5230c426e989f48cadc60a583b95a0e56ed878 Mon Sep 17 00:00:00 2001 From: JakobDev Date: Tue, 12 Sep 2023 11:53:15 +0200 Subject: [PATCH 07/10] Add Alpine Packages --- options/locale/locale_en-US.ini | 6 +- routers/api/packages/alpine/alpine.go | 74 +-------------------- routers/web/shared/packages/upload.go | 94 ++++++++++++++------------- routers/web/web.go | 3 +- services/forms/package_form.go | 19 ++++-- services/packages/alpine/upload.go | 90 +++++++++++++++++++++++++ services/packages/debian/upload.go | 3 +- services/packages/generic/upload.go | 3 +- services/packages/rpm/upload.go | 3 +- templates/package/upload/alpine.tmpl | 28 ++++++++ templates/package/upload/base.tmpl | 4 +- 11 files changed, 198 insertions(+), 129 deletions(-) create mode 100644 services/packages/alpine/upload.go create mode 100644 templates/package/upload/alpine.tmpl diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 883c051ae51bd..baa49149ab4db 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -3438,11 +3438,15 @@ owner.settings.chef.keypair = Generate key pair owner.settings.chef.keypair.description = A key pair is necessary to authenticate to the Chef registry. If you have generated a key pair before, generating a new key pair will discard the old key pair. upload.button = Upload upload.title = Upload %s Package +upload.branch.label = Branch: +upload.branch.placeholder = The branch to use +upload.repo.label = Repository: +upload.repo.placeholder = The repository to use +upload.file.label = File: upload.distribution.label = Distribution: upload.distribution.placeholder = The distribution may match the release name of the OS upload.component.label = Component: upload.component.placeholder = The component can be used to group packages or just main or similar -upload.file.label = File: upload.name.label = Name: upload.name.placeholder = The package name upload.version.label = Version: diff --git a/routers/api/packages/alpine/alpine.go b/routers/api/packages/alpine/alpine.go index 51a5c784e0280..c53233ac6a75f 100644 --- a/routers/api/packages/alpine/alpine.go +++ b/routers/api/packages/alpine/alpine.go @@ -9,15 +9,11 @@ import ( "encoding/pem" "errors" "fmt" - "io" "net/http" "strings" packages_model "code.gitea.io/gitea/models/packages" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/json" - packages_module "code.gitea.io/gitea/modules/packages" - alpine_module "code.gitea.io/gitea/modules/packages/alpine" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" packages_service "code.gitea.io/gitea/services/packages" @@ -105,75 +101,9 @@ func UploadPackageFile(ctx *context.Context) { defer upload.Close() } - buf, err := packages_module.CreateHashedBufferFromReader(upload) + statusCode, _, err := alpine_service.UploadAlpinePackage(ctx, upload, branch, repository) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) - return - } - defer buf.Close() - - pck, err := alpine_module.ParsePackage(buf) - if err != nil { - if errors.Is(err, util.ErrInvalidArgument) || err == io.EOF { - apiError(ctx, http.StatusBadRequest, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } - return - } - - if _, err := buf.Seek(0, io.SeekStart); err != nil { - apiError(ctx, http.StatusInternalServerError, err) - return - } - - fileMetadataRaw, err := json.Marshal(pck.FileMetadata) - if err != nil { - apiError(ctx, http.StatusInternalServerError, err) - return - } - - _, _, err = packages_service.CreatePackageOrAddFileToExisting( - &packages_service.PackageCreationInfo{ - PackageInfo: packages_service.PackageInfo{ - Owner: ctx.Package.Owner, - PackageType: packages_model.TypeAlpine, - Name: pck.Name, - Version: pck.Version, - }, - Creator: ctx.Doer, - Metadata: pck.VersionMetadata, - }, - &packages_service.PackageFileCreationInfo{ - PackageFileInfo: packages_service.PackageFileInfo{ - Filename: fmt.Sprintf("%s-%s.apk", pck.Name, pck.Version), - CompositeKey: fmt.Sprintf("%s|%s|%s", branch, repository, pck.FileMetadata.Architecture), - }, - Creator: ctx.Doer, - Data: buf, - IsLead: true, - Properties: map[string]string{ - alpine_module.PropertyBranch: branch, - alpine_module.PropertyRepository: repository, - alpine_module.PropertyArchitecture: pck.FileMetadata.Architecture, - alpine_module.PropertyMetadata: string(fileMetadataRaw), - }, - }, - ) - if err != nil { - switch err { - case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusBadRequest, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } - return - } - - if err := alpine_service.BuildSpecificRepositoryFiles(ctx, ctx.Package.Owner.ID, branch, repository, pck.FileMetadata.Architecture); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, statusCode, err) return } diff --git a/routers/web/shared/packages/upload.go b/routers/web/shared/packages/upload.go index 33e8b19d2c3ee..09cd5172325a7 100644 --- a/routers/web/shared/packages/upload.go +++ b/routers/web/shared/packages/upload.go @@ -12,12 +12,14 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/forms" + alpine_service "code.gitea.io/gitea/services/packages/alpine" debian_service "code.gitea.io/gitea/services/packages/debian" generic_service "code.gitea.io/gitea/services/packages/generic" rpm_service "code.gitea.io/gitea/services/packages/rpm" ) var UploadTypeList = []packages_model.Type{ + packages_model.TypeAlpine, packages_model.TypeDebian, packages_model.TypeGeneric, packages_model.TypeRpm, @@ -54,45 +56,42 @@ func addRepoToUploadedPackage(ctx *context.Context, packageType, repoName string return true } -func UploadGenericPackagePost(ctx *context.Context) { - form := web.GetForm(ctx).(*forms.PackageUploadGenericForm) - upload, err := form.PackageFile.Open() +func uploadPackageFinish(ctx *context.Context, packageType, packageRepo string, pv *packages_model.PackageVersion) { + if packageRepo != "" { + if !addRepoToUploadedPackage(ctx, "generic", packageRepo, pv.PackageID) { + return + } + } + + pd, err := packages_model.GetPackageDescriptor(ctx, pv) if err != nil { - ctx.ServerError("GetPackageFile", err) + ctx.ServerError("GetPackageDescriptor", err) return } - var filename string - if form.PackageFilename == "" { - filename = form.PackageFile.Filename - } else { - filename = form.PackageFilename - } + ctx.Redirect(pd.FullWebLink()) +} - statusCode, pv, err := generic_service.UploadGenericPackage(ctx, upload, form.PackageName, form.PackageVersion, filename) +func UploadAlpinePackagePost(ctx *context.Context) { + form := web.GetForm(ctx).(*forms.PackageUploadAlpineForm) + upload, err := form.PackageFile.Open() if err != nil { - if statusCode == http.StatusInternalServerError { - ctx.ServerError("UploadGenericPackage", err) - return - } - - servePackageUploadError(ctx, err, "generic", form.PackageRepo) + ctx.ServerError("GetPackageFile", err) return } - if form.PackageRepo != "" { - if !addRepoToUploadedPackage(ctx, "generic", form.PackageRepo, pv.PackageID) { + statusCode, pv, err := alpine_service.UploadAlpinePackage(ctx, upload, form.PackageRepo, form.PackageBranch) + if err != nil { + if statusCode == http.StatusInternalServerError { + ctx.ServerError("UploadAlpinePackage", err) return } - } - pd, err := packages_model.GetPackageDescriptor(ctx, pv) - if err != nil { - ctx.ServerError("GetPackageDescriptor", err) + servePackageUploadError(ctx, err, "alpine", form.PackageRepo) return } - ctx.Redirect(pd.FullWebLink()) + uploadPackageFinish(ctx, "alpine", form.PackageRepo, pv) } func UploadDebianPackagePost(ctx *context.Context) { @@ -106,7 +105,7 @@ func UploadDebianPackagePost(ctx *context.Context) { statusCode, pv, err := debian_service.UploadDebianPackage(ctx, upload, form.PackageDistribution, form.PackageComponent) if err != nil { if statusCode == http.StatusInternalServerError { - ctx.ServerError("UploadGenericPackage", err) + ctx.ServerError("UploadDebianPackage", err) return } @@ -114,19 +113,36 @@ func UploadDebianPackagePost(ctx *context.Context) { return } - if form.PackageRepo != "" { - if !addRepoToUploadedPackage(ctx, "debian", form.PackageRepo, pv.PackageID) { - return - } + uploadPackageFinish(ctx, "debian", form.PackageRepo, pv) +} + +func UploadGenericPackagePost(ctx *context.Context) { + form := web.GetForm(ctx).(*forms.PackageUploadGenericForm) + upload, err := form.PackageFile.Open() + if err != nil { + ctx.ServerError("GetPackageFile", err) + return } - pd, err := packages_model.GetPackageDescriptor(ctx, pv) + var filename string + if form.PackageFilename == "" { + filename = form.PackageFile.Filename + } else { + filename = form.PackageFilename + } + + statusCode, pv, err := generic_service.UploadGenericPackage(ctx, upload, form.PackageName, form.PackageVersion, filename) if err != nil { - ctx.ServerError("GetPackageDescriptor", err) + if statusCode == http.StatusInternalServerError { + ctx.ServerError("UploadGenericPackage", err) + return + } + + servePackageUploadError(ctx, err, "generic", form.PackageRepo) return } - ctx.Redirect(pd.FullWebLink()) + uploadPackageFinish(ctx, "debian", form.PackageRepo, pv) } func UploadRpmPackagePost(ctx *context.Context) { @@ -148,17 +164,5 @@ func UploadRpmPackagePost(ctx *context.Context) { return } - if form.PackageRepo != "" { - if !addRepoToUploadedPackage(ctx, "rpm", form.PackageRepo, pv.PackageID) { - return - } - } - - pd, err := packages_model.GetPackageDescriptor(ctx, pv) - if err != nil { - ctx.ServerError("GetPackageDescriptor", err) - return - } - - ctx.Redirect(pd.FullWebLink()) + uploadPackageFinish(ctx, "rpm", form.PackageRepo, pv) } diff --git a/routers/web/web.go b/routers/web/web.go index 745d8afc0d8d5..f2087f599a646 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -831,8 +831,9 @@ func registerRoutes(m *web.Route) { }) m.Group("/upload", func() { m.Get("/{upload_type}", user.UploadPackage) - m.Post("/generic/upload", web.Bind(forms.PackageUploadGenericForm{}), packages.UploadGenericPackagePost) + m.Post("/alpine/upload", web.Bind(forms.PackageUploadAlpineForm{}), packages.UploadAlpinePackagePost) m.Post("/debian/upload", web.Bind(forms.PackageUploadDebianForm{}), packages.UploadDebianPackagePost) + m.Post("/generic/upload", web.Bind(forms.PackageUploadGenericForm{}), packages.UploadGenericPackagePost) m.Post("/rpm/upload", web.Bind(forms.PackageUploadRpmForm{}), packages.UploadRpmPackagePost) }, reqPackageAccess(perm.AccessModeWrite)) }, context.PackageAssignment(), reqPackageAccess(perm.AccessModeRead)) diff --git a/services/forms/package_form.go b/services/forms/package_form.go index d26fc72f9a436..5ee9efb6cd8b9 100644 --- a/services/forms/package_form.go +++ b/services/forms/package_form.go @@ -30,12 +30,11 @@ func (f *PackageCleanupRuleForm) Validate(req *http.Request, errs binding.Errors return middleware.Validate(errs, ctx.Data, f, ctx.Locale) } -type PackageUploadGenericForm struct { - PackageRepo string - PackageName string - PackageVersion string - PackageFilename string - PackageFile *multipart.FileHeader +type PackageUploadAlpineForm struct { + PackageRepo string + PackageBranch string + PackageRepository string + PackageFile *multipart.FileHeader } type PackageUploadDebianForm struct { @@ -45,6 +44,14 @@ type PackageUploadDebianForm struct { PackageFile *multipart.FileHeader } +type PackageUploadGenericForm struct { + PackageRepo string + PackageName string + PackageVersion string + PackageFilename string + PackageFile *multipart.FileHeader +} + type PackageUploadRpmForm struct { PackageRepo string PackageFile *multipart.FileHeader diff --git a/services/packages/alpine/upload.go b/services/packages/alpine/upload.go new file mode 100644 index 0000000000000..a4023fd2fc290 --- /dev/null +++ b/services/packages/alpine/upload.go @@ -0,0 +1,90 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package alpine + +import ( + "errors" + "fmt" + "io" + "net/http" + + packages_model "code.gitea.io/gitea/models/packages" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/json" + packages_module "code.gitea.io/gitea/modules/packages" + alpine_module "code.gitea.io/gitea/modules/packages/alpine" + "code.gitea.io/gitea/modules/util" + packages_service "code.gitea.io/gitea/services/packages" +) + +// UploadAlpinePackage adds a Alpine Package to the registry +func UploadAlpinePackage(ctx *context.Context, upload io.Reader, branch, repository string) (int, *packages_model.PackageVersion, error) { + buf, err := packages_module.CreateHashedBufferFromReader(upload) + if err != nil { + return http.StatusInternalServerError, nil, err + } + defer buf.Close() + + pck, err := alpine_module.ParsePackage(buf) + if err != nil { + if errors.Is(err, util.ErrInvalidArgument) || err == io.EOF { + return http.StatusBadRequest, nil, err + } + + return http.StatusInternalServerError, nil, err + } + + if _, err := buf.Seek(0, io.SeekStart); err != nil { + return http.StatusInternalServerError, nil, err + } + + fileMetadataRaw, err := json.Marshal(pck.FileMetadata) + if err != nil { + return http.StatusInternalServerError, nil, err + } + + pv, _, err := packages_service.CreatePackageOrAddFileToExisting( + &packages_service.PackageCreationInfo{ + PackageInfo: packages_service.PackageInfo{ + Owner: ctx.Package.Owner, + PackageType: packages_model.TypeAlpine, + Name: pck.Name, + Version: pck.Version, + }, + Creator: ctx.Doer, + Metadata: pck.VersionMetadata, + }, + &packages_service.PackageFileCreationInfo{ + PackageFileInfo: packages_service.PackageFileInfo{ + Filename: fmt.Sprintf("%s-%s.apk", pck.Name, pck.Version), + CompositeKey: fmt.Sprintf("%s|%s|%s", branch, repository, pck.FileMetadata.Architecture), + }, + Creator: ctx.Doer, + Data: buf, + IsLead: true, + Properties: map[string]string{ + alpine_module.PropertyBranch: branch, + alpine_module.PropertyRepository: repository, + alpine_module.PropertyArchitecture: pck.FileMetadata.Architecture, + alpine_module.PropertyMetadata: string(fileMetadataRaw), + }, + }, + ) + if err != nil { + switch err { + case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile: + return http.StatusBadRequest, nil, err + case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: + return http.StatusForbidden, nil, err + default: + return http.StatusInternalServerError, nil, err + } + } + + if err := BuildSpecificRepositoryFiles(ctx, ctx.Package.Owner.ID, branch, repository, pck.FileMetadata.Architecture); err != nil { + return http.StatusInternalServerError, nil, err + } + + return http.StatusCreated, pv, nil +} diff --git a/services/packages/debian/upload.go b/services/packages/debian/upload.go index c4fa698b62038..ed1e655a0211a 100644 --- a/services/packages/debian/upload.go +++ b/services/packages/debian/upload.go @@ -17,6 +17,7 @@ import ( packages_service "code.gitea.io/gitea/services/packages" ) +// UploadDebianPackage adds a Debian Package to the registry func UploadDebianPackage(ctx *context.Context, upload io.Reader, distribution, component string) (int, *packages_model.PackageVersion, error) { buf, err := packages_module.CreateHashedBufferFromReader(upload) if err != nil { @@ -79,5 +80,5 @@ func UploadDebianPackage(ctx *context.Context, upload io.Reader, distribution, c return http.StatusInternalServerError, nil, err } - return http.StatusOK, pv, nil + return http.StatusCreated, pv, nil } diff --git a/services/packages/generic/upload.go b/services/packages/generic/upload.go index 0ff47b15311fe..fd9fa20fb1b17 100644 --- a/services/packages/generic/upload.go +++ b/services/packages/generic/upload.go @@ -13,6 +13,7 @@ import ( packages_service "code.gitea.io/gitea/services/packages" ) +// UploadGenericPackage adds a Generic Package to the registry func UploadGenericPackage(ctx *context.Context, upload io.Reader, name, version, filename string) (int, *packages_model.PackageVersion, error) { buf, err := packages_module.CreateHashedBufferFromReader(upload) if err != nil { @@ -51,5 +52,5 @@ func UploadGenericPackage(ctx *context.Context, upload io.Reader, name, version, } } - return http.StatusOK, pv, nil + return http.StatusCreated, pv, nil } diff --git a/services/packages/rpm/upload.go b/services/packages/rpm/upload.go index 320420a6d3a2f..43dbdcff3e938 100644 --- a/services/packages/rpm/upload.go +++ b/services/packages/rpm/upload.go @@ -18,6 +18,7 @@ import ( packages_service "code.gitea.io/gitea/services/packages" ) +// UploadRpmPackage adds a RPM Package to the registry func UploadRpmPackage(ctx *context.Context, upload io.Reader) (int, *packages_model.PackageVersion, error) { buf, err := packages_module.CreateHashedBufferFromReader(upload) if err != nil { @@ -81,5 +82,5 @@ func UploadRpmPackage(ctx *context.Context, upload io.Reader) (int, *packages_mo return http.StatusInternalServerError, nil, err } - return http.StatusOK, pv, nil + return http.StatusCreated, pv, nil } diff --git a/templates/package/upload/alpine.tmpl b/templates/package/upload/alpine.tmpl new file mode 100644 index 0000000000000..b97220164c8c6 --- /dev/null +++ b/templates/package/upload/alpine.tmpl @@ -0,0 +1,28 @@ +
+

{{.Title}}

+ {{template "base/alert" .}} +
+ {{.CsrfTokenHtml}} + + + +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+
+
diff --git a/templates/package/upload/base.tmpl b/templates/package/upload/base.tmpl index 005c565c765b2..4988593f9a85f 100644 --- a/templates/package/upload/base.tmpl +++ b/templates/package/upload/base.tmpl @@ -1,4 +1,6 @@ -{{if eq $.PackageUploadType.String "debian"}} +{{if eq $.PackageUploadType.String "alpine"}} + {{template "package/upload/alpine" .}} +{{else if eq $.PackageUploadType.String "debian"}} {{template "package/upload/debian" .}} {{else if eq $.PackageUploadType.String "generic"}} {{template "package/upload/generic" .}} From 197974eff9a9f99d945527285b549b51e31cde70 Mon Sep 17 00:00:00 2001 From: JakobDev Date: Tue, 12 Sep 2023 12:06:54 +0200 Subject: [PATCH 08/10] Use correct argument --- routers/web/shared/packages/upload.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/web/shared/packages/upload.go b/routers/web/shared/packages/upload.go index 09cd5172325a7..134a1fcbcc494 100644 --- a/routers/web/shared/packages/upload.go +++ b/routers/web/shared/packages/upload.go @@ -58,7 +58,7 @@ func addRepoToUploadedPackage(ctx *context.Context, packageType, repoName string func uploadPackageFinish(ctx *context.Context, packageType, packageRepo string, pv *packages_model.PackageVersion) { if packageRepo != "" { - if !addRepoToUploadedPackage(ctx, "generic", packageRepo, pv.PackageID) { + if !addRepoToUploadedPackage(ctx, packageType, packageRepo, pv.PackageID) { return } } From 127114da7dbb1ec15f5d25640987cbce09cf499d Mon Sep 17 00:00:00 2001 From: JakobDev Date: Tue, 19 Sep 2023 08:13:25 +0200 Subject: [PATCH 09/10] Change strings in en-us.ini --- options/locale/locale_en-US.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index baa49149ab4db..971ae69fae2f6 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -3448,11 +3448,11 @@ upload.distribution.placeholder = The distribution may match the release name of upload.component.label = Component: upload.component.placeholder = The component can be used to group packages or just main or similar upload.name.label = Name: -upload.name.placeholder = The package name +upload.name.placeholder = Package name upload.version.label = Version: -upload.version.placeholder = The package version +upload.version.placeholder = Package version upload.filename.label = Filename: -upload.filename.placeholder = The filename (leave empty to use name from uploaded file) +upload.filename.placeholder = Filename (leave empty to use name from uploaded file) [secrets] secrets = Secrets From bf924f9a10f1af2eded836a4a42e9ae335bc7667 Mon Sep 17 00:00:00 2001 From: JakobDev Date: Tue, 26 Sep 2023 11:07:59 +0200 Subject: [PATCH 10/10] Do requested changes --- options/locale/locale_en-US.ini | 3 +- routers/api/packages/alpine/alpine.go | 12 +++++- routers/api/packages/debian/debian.go | 12 +++++- routers/api/packages/generic/generic.go | 12 +++++- routers/api/packages/rpm/rpm.go | 12 +++++- routers/web/shared/packages/upload.go | 51 +++++++++++++------------ services/forms/package_form.go | 30 +++++++-------- services/packages/alpine/upload.go | 28 +++++++------- services/packages/debian/upload.go | 26 ++++++------- services/packages/generic/upload.go | 18 ++++----- services/packages/rpm/upload.go | 28 +++++++------- templates/package/shared/list.tmpl | 4 +- templates/package/upload/alpine.tmpl | 16 ++++---- templates/package/upload/debian.tmpl | 16 ++++---- templates/package/upload/generic.tmpl | 20 +++++----- templates/package/upload/rpm.tmpl | 8 ++-- 16 files changed, 162 insertions(+), 134 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 1d9485cfb456e..81cfbf9611460 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -140,6 +140,8 @@ confirm_delete_selected = Confirm to delete all selected items? name = Name value = Value +upload = Upload + [aria] navbar = Navigation Bar footer = Footer @@ -3445,7 +3447,6 @@ owner.settings.cleanuprules.success.delete = Cleanup rule has been deleted. owner.settings.chef.title = Chef Registry owner.settings.chef.keypair = Generate key pair owner.settings.chef.keypair.description = A key pair is necessary to authenticate to the Chef registry. If you have generated a key pair before, generating a new key pair will discard the old key pair. -upload.button = Upload upload.title = Upload %s Package upload.branch.label = Branch: upload.branch.placeholder = The branch to use diff --git a/routers/api/packages/alpine/alpine.go b/routers/api/packages/alpine/alpine.go index 511fc32e27d45..29390605f527a 100644 --- a/routers/api/packages/alpine/alpine.go +++ b/routers/api/packages/alpine/alpine.go @@ -101,9 +101,17 @@ func UploadPackageFile(ctx *context.Context) { defer upload.Close() } - statusCode, _, err := alpine_service.UploadAlpinePackage(ctx, upload, branch, repository) + userError, _, err := alpine_service.UploadAlpinePackage(ctx, upload, branch, repository) if err != nil { - apiError(ctx, statusCode, err) + if userError { + if err == packages_service.ErrQuotaTotalCount || err == packages_service.ErrQuotaTypeSize || err == packages_service.ErrQuotaTotalSize { + apiError(ctx, http.StatusForbidden, err) + } else { + apiError(ctx, http.StatusBadRequest, err) + } + } else { + apiError(ctx, http.StatusInternalServerError, err) + } return } diff --git a/routers/api/packages/debian/debian.go b/routers/api/packages/debian/debian.go index 57d5757e0f8ba..7590e92e72791 100644 --- a/routers/api/packages/debian/debian.go +++ b/routers/api/packages/debian/debian.go @@ -133,9 +133,17 @@ func UploadPackageFile(ctx *context.Context) { defer upload.Close() } - statusCode, _, err := debian_service.UploadDebianPackage(ctx, upload, distribution, component) + userError, _, err := debian_service.UploadDebianPackage(ctx, upload, distribution, component) if err != nil { - apiError(ctx, statusCode, err) + if userError { + if err == packages_service.ErrQuotaTotalCount || err == packages_service.ErrQuotaTypeSize || err == packages_service.ErrQuotaTotalSize { + apiError(ctx, http.StatusForbidden, err) + } else { + apiError(ctx, http.StatusBadRequest, err) + } + } else { + apiError(ctx, http.StatusInternalServerError, err) + } return } diff --git a/routers/api/packages/generic/generic.go b/routers/api/packages/generic/generic.go index 0eedb99f50ca5..67845cd3abb84 100644 --- a/routers/api/packages/generic/generic.go +++ b/routers/api/packages/generic/generic.go @@ -79,9 +79,17 @@ func UploadPackage(ctx *context.Context) { defer upload.Close() } - statusCode, _, err := generic_service.UploadGenericPackage(ctx, upload, packageName, packageVersion, filename) + userError, _, err := generic_service.UploadGenericPackage(ctx, upload, packageName, packageVersion, filename) if err != nil { - apiError(ctx, statusCode, err) + if userError { + if err == packages_service.ErrQuotaTotalCount || err == packages_service.ErrQuotaTypeSize || err == packages_service.ErrQuotaTotalSize { + apiError(ctx, http.StatusForbidden, err) + } else { + apiError(ctx, http.StatusBadRequest, err) + } + } else { + apiError(ctx, http.StatusInternalServerError, err) + } return } diff --git a/routers/api/packages/rpm/rpm.go b/routers/api/packages/rpm/rpm.go index 88f6a93b73e07..86d6c09553a7a 100644 --- a/routers/api/packages/rpm/rpm.go +++ b/routers/api/packages/rpm/rpm.go @@ -90,9 +90,17 @@ func UploadPackageFile(ctx *context.Context) { defer upload.Close() } - statusCode, _, err := rpm_service.UploadRpmPackage(ctx, upload) + userError, _, err := rpm_service.UploadRpmPackage(ctx, upload) if err != nil { - apiError(ctx, statusCode, err) + if userError { + if err == packages_service.ErrQuotaTotalCount || err == packages_service.ErrQuotaTypeSize || err == packages_service.ErrQuotaTotalSize { + apiError(ctx, http.StatusForbidden, err) + } else { + apiError(ctx, http.StatusBadRequest, err) + } + } else { + apiError(ctx, http.StatusInternalServerError, err) + } return } diff --git a/routers/web/shared/packages/upload.go b/routers/web/shared/packages/upload.go index 134a1fcbcc494..ac112cdc194a6 100644 --- a/routers/web/shared/packages/upload.go +++ b/routers/web/shared/packages/upload.go @@ -5,7 +5,6 @@ package packages import ( "fmt" - "net/http" packages_model "code.gitea.io/gitea/models/packages" repo_model "code.gitea.io/gitea/models/repo" @@ -74,95 +73,99 @@ func uploadPackageFinish(ctx *context.Context, packageType, packageRepo string, func UploadAlpinePackagePost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.PackageUploadAlpineForm) - upload, err := form.PackageFile.Open() + upload, err := form.File.Open() if err != nil { ctx.ServerError("GetPackageFile", err) return } + defer upload.Close() - statusCode, pv, err := alpine_service.UploadAlpinePackage(ctx, upload, form.PackageRepo, form.PackageBranch) + userError, pv, err := alpine_service.UploadAlpinePackage(ctx, upload, form.Repo, form.Branch) if err != nil { - if statusCode == http.StatusInternalServerError { + if !userError { ctx.ServerError("UploadAlpinePackage", err) return } - servePackageUploadError(ctx, err, "alpine", form.PackageRepo) + servePackageUploadError(ctx, err, "alpine", form.Repo) return } - uploadPackageFinish(ctx, "alpine", form.PackageRepo, pv) + uploadPackageFinish(ctx, "alpine", form.Repo, pv) } func UploadDebianPackagePost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.PackageUploadDebianForm) - upload, err := form.PackageFile.Open() + upload, err := form.File.Open() if err != nil { ctx.ServerError("GetPackageFile", err) return } + defer upload.Close() - statusCode, pv, err := debian_service.UploadDebianPackage(ctx, upload, form.PackageDistribution, form.PackageComponent) + userError, pv, err := debian_service.UploadDebianPackage(ctx, upload, form.Distribution, form.Component) if err != nil { - if statusCode == http.StatusInternalServerError { + if !userError { ctx.ServerError("UploadDebianPackage", err) return } - servePackageUploadError(ctx, err, "debian", form.PackageRepo) + servePackageUploadError(ctx, err, "debian", form.Repo) return } - uploadPackageFinish(ctx, "debian", form.PackageRepo, pv) + uploadPackageFinish(ctx, "debian", form.Repo, pv) } func UploadGenericPackagePost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.PackageUploadGenericForm) - upload, err := form.PackageFile.Open() + upload, err := form.File.Open() if err != nil { ctx.ServerError("GetPackageFile", err) return } + defer upload.Close() var filename string - if form.PackageFilename == "" { - filename = form.PackageFile.Filename + if form.Filename == "" { + filename = form.File.Filename } else { - filename = form.PackageFilename + filename = form.Filename } - statusCode, pv, err := generic_service.UploadGenericPackage(ctx, upload, form.PackageName, form.PackageVersion, filename) + userError, pv, err := generic_service.UploadGenericPackage(ctx, upload, form.Name, form.Version, filename) if err != nil { - if statusCode == http.StatusInternalServerError { + if !userError { ctx.ServerError("UploadGenericPackage", err) return } - servePackageUploadError(ctx, err, "generic", form.PackageRepo) + servePackageUploadError(ctx, err, "generic", form.Repo) return } - uploadPackageFinish(ctx, "debian", form.PackageRepo, pv) + uploadPackageFinish(ctx, "debian", form.Repo, pv) } func UploadRpmPackagePost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.PackageUploadRpmForm) - upload, err := form.PackageFile.Open() + upload, err := form.File.Open() if err != nil { ctx.ServerError("GetPackageFile", err) return } + defer upload.Close() - statusCode, pv, err := rpm_service.UploadRpmPackage(ctx, upload) + userError, pv, err := rpm_service.UploadRpmPackage(ctx, upload) if err != nil { - if statusCode == http.StatusInternalServerError { + if !userError { ctx.ServerError("UploadRpmPackage", err) return } - servePackageUploadError(ctx, err, "rpm", form.PackageRepo) + servePackageUploadError(ctx, err, "rpm", form.Repo) return } - uploadPackageFinish(ctx, "rpm", form.PackageRepo, pv) + uploadPackageFinish(ctx, "rpm", form.Repo, pv) } diff --git a/services/forms/package_form.go b/services/forms/package_form.go index 5ee9efb6cd8b9..e8abb96c8b57f 100644 --- a/services/forms/package_form.go +++ b/services/forms/package_form.go @@ -31,28 +31,28 @@ func (f *PackageCleanupRuleForm) Validate(req *http.Request, errs binding.Errors } type PackageUploadAlpineForm struct { - PackageRepo string - PackageBranch string - PackageRepository string - PackageFile *multipart.FileHeader + Repo string + Branch string + Repository string + File *multipart.FileHeader } type PackageUploadDebianForm struct { - PackageRepo string - PackageDistribution string - PackageComponent string - PackageFile *multipart.FileHeader + Repo string + Distribution string + Component string + File *multipart.FileHeader } type PackageUploadGenericForm struct { - PackageRepo string - PackageName string - PackageVersion string - PackageFilename string - PackageFile *multipart.FileHeader + Repo string + Name string + Version string + Filename string + File *multipart.FileHeader } type PackageUploadRpmForm struct { - PackageRepo string - PackageFile *multipart.FileHeader + Repo string + File *multipart.FileHeader } diff --git a/services/packages/alpine/upload.go b/services/packages/alpine/upload.go index a4023fd2fc290..187b86936a001 100644 --- a/services/packages/alpine/upload.go +++ b/services/packages/alpine/upload.go @@ -7,7 +7,6 @@ import ( "errors" "fmt" "io" - "net/http" packages_model "code.gitea.io/gitea/models/packages" "code.gitea.io/gitea/modules/context" @@ -18,33 +17,34 @@ import ( packages_service "code.gitea.io/gitea/services/packages" ) -// UploadAlpinePackage adds a Alpine Package to the registry -func UploadAlpinePackage(ctx *context.Context, upload io.Reader, branch, repository string) (int, *packages_model.PackageVersion, error) { +// UploadAlpinePackage adds a Alpine Package to the registry. The first return value indictaes if the error is a user error. +func UploadAlpinePackage(ctx *context.Context, upload io.Reader, branch, repository string) (bool, *packages_model.PackageVersion, error) { buf, err := packages_module.CreateHashedBufferFromReader(upload) if err != nil { - return http.StatusInternalServerError, nil, err + return false, nil, err } defer buf.Close() pck, err := alpine_module.ParsePackage(buf) if err != nil { if errors.Is(err, util.ErrInvalidArgument) || err == io.EOF { - return http.StatusBadRequest, nil, err + return true, nil, err } - return http.StatusInternalServerError, nil, err + return false, nil, err } if _, err := buf.Seek(0, io.SeekStart); err != nil { - return http.StatusInternalServerError, nil, err + return false, nil, err } fileMetadataRaw, err := json.Marshal(pck.FileMetadata) if err != nil { - return http.StatusInternalServerError, nil, err + return false, nil, err } pv, _, err := packages_service.CreatePackageOrAddFileToExisting( + ctx, &packages_service.PackageCreationInfo{ PackageInfo: packages_service.PackageInfo{ Owner: ctx.Package.Owner, @@ -73,18 +73,16 @@ func UploadAlpinePackage(ctx *context.Context, upload io.Reader, branch, reposit ) if err != nil { switch err { - case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile: - return http.StatusBadRequest, nil, err - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - return http.StatusForbidden, nil, err + case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile, packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: + return true, nil, err default: - return http.StatusInternalServerError, nil, err + return false, nil, err } } if err := BuildSpecificRepositoryFiles(ctx, ctx.Package.Owner.ID, branch, repository, pck.FileMetadata.Architecture); err != nil { - return http.StatusInternalServerError, nil, err + return false, nil, err } - return http.StatusCreated, pv, nil + return false, pv, nil } diff --git a/services/packages/debian/upload.go b/services/packages/debian/upload.go index ed1e655a0211a..a483785977dbc 100644 --- a/services/packages/debian/upload.go +++ b/services/packages/debian/upload.go @@ -7,7 +7,6 @@ import ( "errors" "fmt" "io" - "net/http" packages_model "code.gitea.io/gitea/models/packages" "code.gitea.io/gitea/modules/context" @@ -17,28 +16,29 @@ import ( packages_service "code.gitea.io/gitea/services/packages" ) -// UploadDebianPackage adds a Debian Package to the registry -func UploadDebianPackage(ctx *context.Context, upload io.Reader, distribution, component string) (int, *packages_model.PackageVersion, error) { +// UploadDebianPackage adds a Debian Package to the registry. The first return value indictaes if the error is a user error. +func UploadDebianPackage(ctx *context.Context, upload io.Reader, distribution, component string) (bool, *packages_model.PackageVersion, error) { buf, err := packages_module.CreateHashedBufferFromReader(upload) if err != nil { - return http.StatusInternalServerError, nil, err + return false, nil, err } defer buf.Close() pck, err := debian_module.ParsePackage(buf) if err != nil { if errors.Is(err, util.ErrInvalidArgument) { - return http.StatusBadRequest, nil, err + return true, nil, err } - return http.StatusInternalServerError, nil, err + return false, nil, err } if _, err := buf.Seek(0, io.SeekStart); err != nil { - return http.StatusInternalServerError, nil, err + return false, nil, err } pv, _, err := packages_service.CreatePackageOrAddFileToExisting( + ctx, &packages_service.PackageCreationInfo{ PackageInfo: packages_service.PackageInfo{ Owner: ctx.Package.Owner, @@ -67,18 +67,16 @@ func UploadDebianPackage(ctx *context.Context, upload io.Reader, distribution, c ) if err != nil { switch err { - case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile: - return http.StatusBadRequest, nil, err - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - return http.StatusForbidden, nil, err + case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile, packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: + return true, nil, err default: - return http.StatusInternalServerError, nil, err + return false, nil, err } } if err := BuildSpecificRepositoryFiles(ctx, ctx.Package.Owner.ID, distribution, component, pck.Architecture); err != nil { - return http.StatusInternalServerError, nil, err + return false, nil, err } - return http.StatusCreated, pv, nil + return false, pv, nil } diff --git a/services/packages/generic/upload.go b/services/packages/generic/upload.go index fd9fa20fb1b17..6fae3a2e16e27 100644 --- a/services/packages/generic/upload.go +++ b/services/packages/generic/upload.go @@ -5,7 +5,6 @@ package generic import ( "io" - "net/http" packages_model "code.gitea.io/gitea/models/packages" "code.gitea.io/gitea/modules/context" @@ -13,16 +12,17 @@ import ( packages_service "code.gitea.io/gitea/services/packages" ) -// UploadGenericPackage adds a Generic Package to the registry -func UploadGenericPackage(ctx *context.Context, upload io.Reader, name, version, filename string) (int, *packages_model.PackageVersion, error) { +// UploadGenericPackage adds a Generic Package to the registry. The first return value indictaes if the error is a user error. +func UploadGenericPackage(ctx *context.Context, upload io.Reader, name, version, filename string) (bool, *packages_model.PackageVersion, error) { buf, err := packages_module.CreateHashedBufferFromReader(upload) if err != nil { ctx.ServerError("CreateHashedBufferFromReader", err) - return http.StatusInternalServerError, nil, err + return false, nil, err } defer buf.Close() pv, _, err := packages_service.CreatePackageOrAddFileToExisting( + ctx, &packages_service.PackageCreationInfo{ PackageInfo: packages_service.PackageInfo{ Owner: ctx.Package.Owner, @@ -43,14 +43,12 @@ func UploadGenericPackage(ctx *context.Context, upload io.Reader, name, version, ) if err != nil { switch err { - case packages_model.ErrDuplicatePackageFile: - return http.StatusConflict, nil, err - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - return http.StatusForbidden, nil, err + case packages_model.ErrDuplicatePackageFile, packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: + return true, nil, err default: - return http.StatusInternalServerError, nil, err + return false, nil, err } } - return http.StatusCreated, pv, nil + return false, pv, nil } diff --git a/services/packages/rpm/upload.go b/services/packages/rpm/upload.go index 43dbdcff3e938..a1d07e4426684 100644 --- a/services/packages/rpm/upload.go +++ b/services/packages/rpm/upload.go @@ -7,7 +7,6 @@ import ( "errors" "fmt" "io" - "net/http" packages_model "code.gitea.io/gitea/models/packages" "code.gitea.io/gitea/modules/context" @@ -18,33 +17,34 @@ import ( packages_service "code.gitea.io/gitea/services/packages" ) -// UploadRpmPackage adds a RPM Package to the registry -func UploadRpmPackage(ctx *context.Context, upload io.Reader) (int, *packages_model.PackageVersion, error) { +// UploadRpmPackage adds a RPM Package to the registry. The first return value indictaes if the error is a user error. +func UploadRpmPackage(ctx *context.Context, upload io.Reader) (bool, *packages_model.PackageVersion, error) { buf, err := packages_module.CreateHashedBufferFromReader(upload) if err != nil { - return http.StatusInternalServerError, nil, err + return false, nil, err } defer buf.Close() pck, err := rpm_module.ParsePackage(buf) if err != nil { if errors.Is(err, util.ErrInvalidArgument) { - return http.StatusBadRequest, nil, err + return true, nil, err } - return http.StatusInternalServerError, nil, err + return false, nil, err } if _, err := buf.Seek(0, io.SeekStart); err != nil { - return http.StatusInternalServerError, nil, err + return false, nil, err } fileMetadataRaw, err := json.Marshal(pck.FileMetadata) if err != nil { - return http.StatusInternalServerError, nil, err + return false, nil, err } pv, _, err := packages_service.CreatePackageOrAddFileToExisting( + ctx, &packages_service.PackageCreationInfo{ PackageInfo: packages_service.PackageInfo{ Owner: ctx.Package.Owner, @@ -69,18 +69,16 @@ func UploadRpmPackage(ctx *context.Context, upload io.Reader) (int, *packages_mo ) if err != nil { switch err { - case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile: - return http.StatusConflict, nil, err - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - return http.StatusForbidden, nil, err + case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile, packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: + return true, nil, err default: - return http.StatusInternalServerError, nil, err + return false, nil, err } } if err := BuildRepositoryFiles(ctx, ctx.Package.Owner.ID); err != nil { - return http.StatusInternalServerError, nil, err + return false, nil, err } - return http.StatusCreated, pv, nil + return false, pv, nil } diff --git a/templates/package/shared/list.tmpl b/templates/package/shared/list.tmpl index aac034969a32d..f9dea0a070130 100644 --- a/templates/package/shared/list.tmpl +++ b/templates/package/shared/list.tmpl @@ -9,10 +9,10 @@ {{$type.Name}} {{end}} - + {{if .ShowPackageUploadButton}} diff --git a/templates/package/upload/generic.tmpl b/templates/package/upload/generic.tmpl index 7ad0952eada05..291452def7581 100644 --- a/templates/package/upload/generic.tmpl +++ b/templates/package/upload/generic.tmpl @@ -4,30 +4,30 @@
{{.CsrfTokenHtml}} - +
- - + +
- - + +
- - + +
- - + +
- +
diff --git a/templates/package/upload/rpm.tmpl b/templates/package/upload/rpm.tmpl index 942b7bd10ad3c..0961e8560c453 100644 --- a/templates/package/upload/rpm.tmpl +++ b/templates/package/upload/rpm.tmpl @@ -4,15 +4,15 @@
{{.CsrfTokenHtml}} - +
- - + +
- +