Skip to content

Commit e148777

Browse files
authored
Merge branch 'main' into fix-lang
2 parents c11a8e2 + 20674dd commit e148777

File tree

20 files changed

+378
-61
lines changed

20 files changed

+378
-61
lines changed

Diff for: cmd/migrate_storage_test.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ func TestMigratePackages(t *testing.T) {
4444
PackageFileInfo: packages_service.PackageFileInfo{
4545
Filename: "a.go",
4646
},
47-
Data: buf,
48-
IsLead: true,
47+
Creator: creator,
48+
Data: buf,
49+
IsLead: true,
4950
})
5051
assert.NoError(t, err)
5152
assert.NotNil(t, v)

Diff for: custom/conf/app.example.ini

+29
Original file line numberDiff line numberDiff line change
@@ -2335,6 +2335,35 @@ ROUTER = console
23352335
;;
23362336
;; Path for chunked uploads. Defaults to APP_DATA_PATH + `tmp/package-upload`
23372337
;CHUNKED_UPLOAD_PATH = tmp/package-upload
2338+
;;
2339+
;; Maxmimum count of package versions a single owner can have (`-1` means no limits)
2340+
;LIMIT_TOTAL_OWNER_COUNT = -1
2341+
;; Maxmimum size of packages a single owner can use (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
2342+
;LIMIT_TOTAL_OWNER_SIZE = -1
2343+
;; Maxmimum size of a Composer upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
2344+
;LIMIT_SIZE_COMPOSER = -1
2345+
;; Maxmimum size of a Conan upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
2346+
;LIMIT_SIZE_CONAN = -1
2347+
;; Maxmimum size of a Container upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
2348+
;LIMIT_SIZE_CONTAINER = -1
2349+
;; Maxmimum size of a Generic upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
2350+
;LIMIT_SIZE_GENERIC = -1
2351+
;; Maxmimum size of a Helm upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
2352+
;LIMIT_SIZE_HELM = -1
2353+
;; Maxmimum size of a Maven upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
2354+
;LIMIT_SIZE_MAVEN = -1
2355+
;; Maxmimum size of a npm upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
2356+
;LIMIT_SIZE_NPM = -1
2357+
;; Maxmimum size of a NuGet upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
2358+
;LIMIT_SIZE_NUGET = -1
2359+
;; Maxmimum size of a Pub upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
2360+
;LIMIT_SIZE_PUB = -1
2361+
;; Maxmimum size of a PyPI upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
2362+
;LIMIT_SIZE_PYPI = -1
2363+
;; Maxmimum size of a RubyGems upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
2364+
;LIMIT_SIZE_RUBYGEMS = -1
2365+
;; Maxmimum size of a Vagrant upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
2366+
;LIMIT_SIZE_VAGRANT = -1
23382367

23392368
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
23402369
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Diff for: docs/content/doc/advanced/config-cheat-sheet.en-us.md

+14
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,20 @@ Task queue configuration has been moved to `queue.task`. However, the below conf
11381138

11391139
- `ENABLED`: **true**: Enable/Disable package registry capabilities
11401140
- `CHUNKED_UPLOAD_PATH`: **tmp/package-upload**: Path for chunked uploads. Defaults to `APP_DATA_PATH` + `tmp/package-upload`
1141+
- `LIMIT_TOTAL_OWNER_COUNT`: **-1**: Maxmimum count of package versions a single owner can have (`-1` means no limits)
1142+
- `LIMIT_TOTAL_OWNER_SIZE`: **-1**: Maxmimum size of packages a single owner can use (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
1143+
- `LIMIT_SIZE_COMPOSER`: **-1**: Maxmimum size of a Composer upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
1144+
- `LIMIT_SIZE_CONAN`: **-1**: Maxmimum size of a Conan upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
1145+
- `LIMIT_SIZE_CONTAINER`: **-1**: Maxmimum size of a Container upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
1146+
- `LIMIT_SIZE_GENERIC`: **-1**: Maxmimum size of a Generic upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
1147+
- `LIMIT_SIZE_HELM`: **-1**: Maxmimum size of a Helm upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
1148+
- `LIMIT_SIZE_MAVEN`: **-1**: Maxmimum size of a Maven upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
1149+
- `LIMIT_SIZE_NPM`: **-1**: Maxmimum size of a npm upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
1150+
- `LIMIT_SIZE_NUGET`: **-1**: Maxmimum size of a NuGet upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
1151+
- `LIMIT_SIZE_PUB`: **-1**: Maxmimum size of a Pub upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
1152+
- `LIMIT_SIZE_PYPI`: **-1**: Maxmimum size of a PyPI upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
1153+
- `LIMIT_SIZE_RUBYGEMS`: **-1**: Maxmimum size of a RubyGems upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
1154+
- `LIMIT_SIZE_VAGRANT`: **-1**: Maxmimum size of a Vagrant upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
11411155

11421156
## Mirror (`mirror`)
11431157

Diff for: models/packages/package_file.go

+10
Original file line numberDiff line numberDiff line change
@@ -199,3 +199,13 @@ func SearchFiles(ctx context.Context, opts *PackageFileSearchOptions) ([]*Packag
199199
count, err := sess.FindAndCount(&pfs)
200200
return pfs, count, err
201201
}
202+
203+
// CalculateBlobSize sums up all blob sizes matching the search options.
204+
// It does NOT respect the deduplication of blobs.
205+
func CalculateBlobSize(ctx context.Context, opts *PackageFileSearchOptions) (int64, error) {
206+
return db.GetEngine(ctx).
207+
Table("package_file").
208+
Where(opts.toConds()).
209+
Join("INNER", "package_blob", "package_blob.id = package_file.blob_id").
210+
SumInt(new(PackageBlob), "size")
211+
}

Diff for: models/packages/package_version.go

+9
Original file line numberDiff line numberDiff line change
@@ -319,3 +319,12 @@ func SearchLatestVersions(ctx context.Context, opts *PackageSearchOptions) ([]*P
319319
count, err := sess.FindAndCount(&pvs)
320320
return pvs, count, err
321321
}
322+
323+
// CountVersions counts all versions of packages matching the search options
324+
func CountVersions(ctx context.Context, opts *PackageSearchOptions) (int64, error) {
325+
return db.GetEngine(ctx).
326+
Where(opts.toConds()).
327+
Table("package_version").
328+
Join("INNER", "package", "package.id = package_version.package_id").
329+
Count(new(PackageVersion))
330+
}

Diff for: modules/setting/packages.go

+49-1
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,15 @@
55
package setting
66

77
import (
8+
"math"
89
"net/url"
910
"os"
1011
"path/filepath"
1112

1213
"code.gitea.io/gitea/modules/log"
14+
15+
"github.com/dustin/go-humanize"
16+
ini "gopkg.in/ini.v1"
1317
)
1418

1519
// Package registry settings
@@ -19,8 +23,24 @@ var (
1923
Enabled bool
2024
ChunkedUploadPath string
2125
RegistryHost string
26+
27+
LimitTotalOwnerCount int64
28+
LimitTotalOwnerSize int64
29+
LimitSizeComposer int64
30+
LimitSizeConan int64
31+
LimitSizeContainer int64
32+
LimitSizeGeneric int64
33+
LimitSizeHelm int64
34+
LimitSizeMaven int64
35+
LimitSizeNpm int64
36+
LimitSizeNuGet int64
37+
LimitSizePub int64
38+
LimitSizePyPI int64
39+
LimitSizeRubyGems int64
40+
LimitSizeVagrant int64
2241
}{
23-
Enabled: true,
42+
Enabled: true,
43+
LimitTotalOwnerCount: -1,
2444
}
2545
)
2646

@@ -43,4 +63,32 @@ func newPackages() {
4363
if err := os.MkdirAll(Packages.ChunkedUploadPath, os.ModePerm); err != nil {
4464
log.Error("Unable to create chunked upload directory: %s (%v)", Packages.ChunkedUploadPath, err)
4565
}
66+
67+
Packages.LimitTotalOwnerSize = mustBytes(sec, "LIMIT_TOTAL_OWNER_SIZE")
68+
Packages.LimitSizeComposer = mustBytes(sec, "LIMIT_SIZE_COMPOSER")
69+
Packages.LimitSizeConan = mustBytes(sec, "LIMIT_SIZE_CONAN")
70+
Packages.LimitSizeContainer = mustBytes(sec, "LIMIT_SIZE_CONTAINER")
71+
Packages.LimitSizeGeneric = mustBytes(sec, "LIMIT_SIZE_GENERIC")
72+
Packages.LimitSizeHelm = mustBytes(sec, "LIMIT_SIZE_HELM")
73+
Packages.LimitSizeMaven = mustBytes(sec, "LIMIT_SIZE_MAVEN")
74+
Packages.LimitSizeNpm = mustBytes(sec, "LIMIT_SIZE_NPM")
75+
Packages.LimitSizeNuGet = mustBytes(sec, "LIMIT_SIZE_NUGET")
76+
Packages.LimitSizePub = mustBytes(sec, "LIMIT_SIZE_PUB")
77+
Packages.LimitSizePyPI = mustBytes(sec, "LIMIT_SIZE_PYPI")
78+
Packages.LimitSizeRubyGems = mustBytes(sec, "LIMIT_SIZE_RUBYGEMS")
79+
Packages.LimitSizeVagrant = mustBytes(sec, "LIMIT_SIZE_VAGRANT")
80+
}
81+
82+
func mustBytes(section *ini.Section, key string) int64 {
83+
const noLimit = "-1"
84+
85+
value := section.Key(key).MustString(noLimit)
86+
if value == noLimit {
87+
return -1
88+
}
89+
bytes, err := humanize.ParseBytes(value)
90+
if err != nil || bytes > math.MaxInt64 {
91+
return -1
92+
}
93+
return int64(bytes)
4694
}

Diff for: modules/setting/packages_test.go

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2022 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package setting
6+
7+
import (
8+
"testing"
9+
10+
"github.com/stretchr/testify/assert"
11+
ini "gopkg.in/ini.v1"
12+
)
13+
14+
func TestMustBytes(t *testing.T) {
15+
test := func(value string) int64 {
16+
sec, _ := ini.Empty().NewSection("test")
17+
sec.NewKey("VALUE", value)
18+
19+
return mustBytes(sec, "VALUE")
20+
}
21+
22+
assert.EqualValues(t, -1, test(""))
23+
assert.EqualValues(t, -1, test("-1"))
24+
assert.EqualValues(t, 0, test("0"))
25+
assert.EqualValues(t, 1, test("1"))
26+
assert.EqualValues(t, 10000, test("10000"))
27+
assert.EqualValues(t, 1000000, test("1 mb"))
28+
assert.EqualValues(t, 1048576, test("1mib"))
29+
assert.EqualValues(t, 1782579, test("1.7mib"))
30+
assert.EqualValues(t, -1, test("1 yib")) // too large
31+
}

Diff for: routers/api/packages/composer/composer.go

+9-5
Original file line numberDiff line numberDiff line change
@@ -235,16 +235,20 @@ func UploadPackage(ctx *context.Context) {
235235
PackageFileInfo: packages_service.PackageFileInfo{
236236
Filename: strings.ToLower(fmt.Sprintf("%s.%s.zip", strings.ReplaceAll(cp.Name, "/", "-"), cp.Version)),
237237
},
238-
Data: buf,
239-
IsLead: true,
238+
Creator: ctx.Doer,
239+
Data: buf,
240+
IsLead: true,
240241
},
241242
)
242243
if err != nil {
243-
if err == packages_model.ErrDuplicatePackageVersion {
244+
switch err {
245+
case packages_model.ErrDuplicatePackageVersion:
244246
apiError(ctx, http.StatusBadRequest, err)
245-
return
247+
case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize:
248+
apiError(ctx, http.StatusForbidden, err)
249+
default:
250+
apiError(ctx, http.StatusInternalServerError, err)
246251
}
247-
apiError(ctx, http.StatusInternalServerError, err)
248252
return
249253
}
250254

Diff for: routers/api/packages/conan/conan.go

+9-5
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,9 @@ func uploadFile(ctx *context.Context, fileFilter container.Set[string], fileKey
348348
Filename: strings.ToLower(filename),
349349
CompositeKey: fileKey,
350350
},
351-
Data: buf,
352-
IsLead: isConanfileFile,
351+
Creator: ctx.Doer,
352+
Data: buf,
353+
IsLead: isConanfileFile,
353354
Properties: map[string]string{
354355
conan_module.PropertyRecipeUser: rref.User,
355356
conan_module.PropertyRecipeChannel: rref.Channel,
@@ -416,11 +417,14 @@ func uploadFile(ctx *context.Context, fileFilter container.Set[string], fileKey
416417
pfci,
417418
)
418419
if err != nil {
419-
if err == packages_model.ErrDuplicatePackageFile {
420+
switch err {
421+
case packages_model.ErrDuplicatePackageFile:
420422
apiError(ctx, http.StatusBadRequest, err)
421-
return
423+
case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize:
424+
apiError(ctx, http.StatusForbidden, err)
425+
default:
426+
apiError(ctx, http.StatusInternalServerError, err)
422427
}
423-
apiError(ctx, http.StatusInternalServerError, err)
424428
return
425429
}
426430

Diff for: routers/api/packages/generic/generic.go

+9-5
Original file line numberDiff line numberDiff line change
@@ -104,16 +104,20 @@ func UploadPackage(ctx *context.Context) {
104104
PackageFileInfo: packages_service.PackageFileInfo{
105105
Filename: filename,
106106
},
107-
Data: buf,
108-
IsLead: true,
107+
Creator: ctx.Doer,
108+
Data: buf,
109+
IsLead: true,
109110
},
110111
)
111112
if err != nil {
112-
if err == packages_model.ErrDuplicatePackageFile {
113+
switch err {
114+
case packages_model.ErrDuplicatePackageFile:
113115
apiError(ctx, http.StatusConflict, err)
114-
return
116+
case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize:
117+
apiError(ctx, http.StatusForbidden, err)
118+
default:
119+
apiError(ctx, http.StatusInternalServerError, err)
115120
}
116-
apiError(ctx, http.StatusInternalServerError, err)
117121
return
118122
}
119123

Diff for: routers/api/packages/helm/helm.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -186,17 +186,21 @@ func UploadPackage(ctx *context.Context) {
186186
PackageFileInfo: packages_service.PackageFileInfo{
187187
Filename: createFilename(metadata),
188188
},
189+
Creator: ctx.Doer,
189190
Data: buf,
190191
IsLead: true,
191192
OverwriteExisting: true,
192193
},
193194
)
194195
if err != nil {
195-
if err == packages_model.ErrDuplicatePackageVersion {
196+
switch err {
197+
case packages_model.ErrDuplicatePackageVersion:
196198
apiError(ctx, http.StatusConflict, err)
197-
return
199+
case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize:
200+
apiError(ctx, http.StatusForbidden, err)
201+
default:
202+
apiError(ctx, http.StatusInternalServerError, err)
198203
}
199-
apiError(ctx, http.StatusInternalServerError, err)
200204
return
201205
}
202206

Diff for: routers/api/packages/maven/maven.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ func UploadPackageFile(ctx *context.Context) {
266266
PackageFileInfo: packages_service.PackageFileInfo{
267267
Filename: params.Filename,
268268
},
269+
Creator: ctx.Doer,
269270
Data: buf,
270271
IsLead: false,
271272
OverwriteExisting: params.IsMeta,
@@ -312,11 +313,14 @@ func UploadPackageFile(ctx *context.Context) {
312313
pfci,
313314
)
314315
if err != nil {
315-
if err == packages_model.ErrDuplicatePackageFile {
316+
switch err {
317+
case packages_model.ErrDuplicatePackageFile:
316318
apiError(ctx, http.StatusBadRequest, err)
317-
return
319+
case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize:
320+
apiError(ctx, http.StatusForbidden, err)
321+
default:
322+
apiError(ctx, http.StatusInternalServerError, err)
318323
}
319-
apiError(ctx, http.StatusInternalServerError, err)
320324
return
321325
}
322326

Diff for: routers/api/packages/npm/npm.go

+9-5
Original file line numberDiff line numberDiff line change
@@ -180,16 +180,20 @@ func UploadPackage(ctx *context.Context) {
180180
PackageFileInfo: packages_service.PackageFileInfo{
181181
Filename: npmPackage.Filename,
182182
},
183-
Data: buf,
184-
IsLead: true,
183+
Creator: ctx.Doer,
184+
Data: buf,
185+
IsLead: true,
185186
},
186187
)
187188
if err != nil {
188-
if err == packages_model.ErrDuplicatePackageVersion {
189+
switch err {
190+
case packages_model.ErrDuplicatePackageVersion:
189191
apiError(ctx, http.StatusBadRequest, err)
190-
return
192+
case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize:
193+
apiError(ctx, http.StatusForbidden, err)
194+
default:
195+
apiError(ctx, http.StatusInternalServerError, err)
191196
}
192-
apiError(ctx, http.StatusInternalServerError, err)
193197
return
194198
}
195199

0 commit comments

Comments
 (0)