Skip to content

Commit f258297

Browse files
authored
Merge branch 'main' into sergeyd-user-dont-want-exhibit-selfs
2 parents 06fbdd5 + 19ac575 commit f258297

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+1568
-378
lines changed

cmd/hook.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -221,16 +221,16 @@ Gitea or set your environment appropriately.`, "")
221221
total++
222222
lastline++
223223

224-
// If the ref is a branch, check if it's protected
225-
if strings.HasPrefix(refFullName, git.BranchPrefix) {
224+
// If the ref is a branch or tag, check if it's protected
225+
if strings.HasPrefix(refFullName, git.BranchPrefix) || strings.HasPrefix(refFullName, git.TagPrefix) {
226226
oldCommitIDs[count] = oldCommitID
227227
newCommitIDs[count] = newCommitID
228228
refFullNames[count] = refFullName
229229
count++
230230
fmt.Fprintf(out, "*")
231231

232232
if count >= hookBatchSize {
233-
fmt.Fprintf(out, " Checking %d branches\n", count)
233+
fmt.Fprintf(out, " Checking %d references\n", count)
234234

235235
hookOptions.OldCommitIDs = oldCommitIDs
236236
hookOptions.NewCommitIDs = newCommitIDs
@@ -261,7 +261,7 @@ Gitea or set your environment appropriately.`, "")
261261
hookOptions.NewCommitIDs = newCommitIDs[:count]
262262
hookOptions.RefFullNames = refFullNames[:count]
263263

264-
fmt.Fprintf(out, " Checking %d branches\n", count)
264+
fmt.Fprintf(out, " Checking %d references\n", count)
265265

266266
statusCode, msg := private.HookPreReceive(username, reponame, hookOptions)
267267
switch statusCode {

contrib/pr/checkout.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"time"
2727

2828
"code.gitea.io/gitea/models"
29+
gitea_git "code.gitea.io/gitea/modules/git"
2930
"code.gitea.io/gitea/modules/markup"
3031
"code.gitea.io/gitea/modules/markup/external"
3132
"code.gitea.io/gitea/modules/setting"
@@ -79,7 +80,7 @@ func runPR() {
7980
setting.RunUser = curUser.Username
8081

8182
log.Printf("[PR] Loading fixtures data ...\n")
82-
setting.CheckLFSVersion()
83+
gitea_git.CheckLFSVersion()
8384
//models.LoadConfigs()
8485
/*
8586
setting.Database.Type = "sqlite3"

custom/conf/app.example.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,8 @@ PATH =
711711
;;
712712
;; Minimum amount of time a user must exist before comments are kept when the user is deleted.
713713
;USER_DELETE_WITH_COMMENTS_MAX_TIME = 0
714+
;; Valid site url schemes for user profiles
715+
;VALID_SITE_URL_SCHEMES=http,https
714716

715717

716718
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,7 @@ relation to port exhaustion.
520520
- `NO_REPLY_ADDRESS`: **noreply.DOMAIN** Value for the domain part of the user's email address in the git log if user has set KeepEmailPrivate to true. DOMAIN resolves to the value in server.DOMAIN.
521521
The user's email will be replaced with a concatenation of the user name in lower case, "@" and NO_REPLY_ADDRESS.
522522
- `USER_DELETE_WITH_COMMENTS_MAX_TIME`: **0** Minimum amount of time a user must exist before comments are kept when the user is deleted.
523+
- `VALID_SITE_URL_SCHEMES`: **http, https**: Valid site url schemes for user profiles
523524

524525
### Service - Expore (`service.explore`)
525526

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
---
2+
date: "2021-05-14T00:00:00-00:00"
3+
title: "Protected tags"
4+
slug: "protected-tags"
5+
weight: 45
6+
toc: false
7+
draft: false
8+
menu:
9+
sidebar:
10+
parent: "advanced"
11+
name: "Protected tags"
12+
weight: 45
13+
identifier: "protected-tags"
14+
---
15+
16+
# Protected tags
17+
18+
Protected tags allow control over who has permission to create or update git tags. Each rule allows you to match either an individual tag name, or use an appropriate pattern to control multiple tags at once.
19+
20+
**Table of Contents**
21+
22+
{{< toc >}}
23+
24+
## Setting up protected tags
25+
26+
To protect a tag, you need to follow these steps:
27+
28+
1. Go to the repository’s **Settings** > **Tags** page.
29+
1. Type a pattern to match a name. You can use a single name, a [glob pattern](https://pkg.go.dev/github.com/gobwas/glob#Compile) or a regular expression.
30+
1. Choose the allowed users and/or teams. If you leave these fields empty noone is allowed to create or modify this tag.
31+
1. Select **Save** to save the configuration.
32+
33+
## Pattern protected tags
34+
35+
The pattern uses [glob](https://pkg.go.dev/github.com/gobwas/glob#Compile) or regular expressions to match a tag name. For regular expressions you need to enclose the pattern in slashes.
36+
37+
Examples:
38+
39+
| Type | Pattern Protected Tag | Possible Matching Tags |
40+
| ----- | ------------------------ | --------------------------------------- |
41+
| Glob | `v*` | `v`, `v-1`, `version2` |
42+
| Glob | `v[0-9]` | `v0`, `v1` up to `v9` |
43+
| Glob | `*-release` | `2.1-release`, `final-release` |
44+
| Glob | `gitea` | only `gitea` |
45+
| Glob | `*gitea*` | `gitea`, `2.1-gitea`, `1_gitea-release` |
46+
| Glob | `{v,rel}-*` | `v-`, `v-1`, `v-final`, `rel-`, `rel-x` |
47+
| Glob | `*` | matches all possible tag names |
48+
| Regex | `/\Av/` | `v`, `v-1`, `version2` |
49+
| Regex | `/\Av[0-9]\z/` | `v0`, `v1` up to `v9` |
50+
| Regex | `/\Av\d+\.\d+\.\d+\z/` | `v1.0.17`, `v2.1.0` |
51+
| Regex | `/\Av\d+(\.\d+){0,2}\z/` | `v1`, `v2.1`, `v1.2.34` |
52+
| Regex | `/-release\z/` | `2.1-release`, `final-release` |
53+
| Regex | `/gitea/` | `gitea`, `2.1-gitea`, `1_gitea-release` |
54+
| Regex | `/\Agitea\z/` | only `gitea` |
55+
| Regex | `/^gitea$/` | only `gitea` |
56+
| Regex | `/\A(v\|rel)-/` | `v-`, `v-1`, `v-final`, `rel-`, `rel-x` |
57+
| Regex | `/.+/` | matches all possible tag names |

integrations/api_user_heatmap_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func TestUserHeatmap(t *testing.T) {
2626
var heatmap []*models.UserHeatmapData
2727
DecodeJSON(t, resp, &heatmap)
2828
var dummyheatmap []*models.UserHeatmapData
29-
dummyheatmap = append(dummyheatmap, &models.UserHeatmapData{Timestamp: 1603152000, Contributions: 1})
29+
dummyheatmap = append(dummyheatmap, &models.UserHeatmapData{Timestamp: 1603227600, Contributions: 1})
3030

3131
assert.Equal(t, dummyheatmap, heatmap)
3232
}

integrations/git_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ func standardCommitAndPushTest(t *testing.T, dstPath string) (little, big string
143143
func lfsCommitAndPushTest(t *testing.T, dstPath string) (littleLFS, bigLFS string) {
144144
t.Run("LFS", func(t *testing.T) {
145145
defer PrintCurrentTest(t)()
146-
setting.CheckLFSVersion()
146+
git.CheckLFSVersion()
147147
if !setting.LFS.StartServer {
148148
t.Skip()
149149
return
@@ -213,7 +213,7 @@ func rawTest(t *testing.T, ctx *APITestContext, little, big, littleLFS, bigLFS s
213213
resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
214214
assert.Equal(t, littleSize, resp.Length)
215215

216-
setting.CheckLFSVersion()
216+
git.CheckLFSVersion()
217217
if setting.LFS.StartServer {
218218
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", littleLFS))
219219
resp := session.MakeRequest(t, req, http.StatusOK)
@@ -255,7 +255,7 @@ func mediaTest(t *testing.T, ctx *APITestContext, little, big, littleLFS, bigLFS
255255
resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
256256
assert.Equal(t, littleSize, resp.Length)
257257

258-
setting.CheckLFSVersion()
258+
git.CheckLFSVersion()
259259
if setting.LFS.StartServer {
260260
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", littleLFS))
261261
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)

integrations/integration_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626

2727
"code.gitea.io/gitea/models"
2828
"code.gitea.io/gitea/modules/base"
29+
"code.gitea.io/gitea/modules/git"
2930
"code.gitea.io/gitea/modules/graceful"
3031
"code.gitea.io/gitea/modules/log"
3132
"code.gitea.io/gitea/modules/queue"
@@ -162,7 +163,7 @@ func initIntegrationTest() {
162163
setting.SetCustomPathAndConf("", "", "")
163164
setting.NewContext()
164165
util.RemoveAll(models.LocalCopyPath())
165-
setting.CheckLFSVersion()
166+
git.CheckLFSVersion()
166167
setting.InitDBConfig()
167168
if err := storage.Init(); err != nil {
168169
fmt.Printf("Init storage failed: %v", err)

integrations/lfs_getobject_test.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"testing"
1414

1515
"code.gitea.io/gitea/models"
16+
"code.gitea.io/gitea/modules/git"
1617
"code.gitea.io/gitea/modules/lfs"
1718
"code.gitea.io/gitea/modules/setting"
1819
"code.gitea.io/gitea/routers/web"
@@ -81,7 +82,7 @@ func checkResponseTestContentEncoding(t *testing.T, content *[]byte, resp *httpt
8182

8283
func TestGetLFSSmall(t *testing.T) {
8384
defer prepareTestEnv(t)()
84-
setting.CheckLFSVersion()
85+
git.CheckLFSVersion()
8586
if !setting.LFS.StartServer {
8687
t.Skip()
8788
return
@@ -94,7 +95,7 @@ func TestGetLFSSmall(t *testing.T) {
9495

9596
func TestGetLFSLarge(t *testing.T) {
9697
defer prepareTestEnv(t)()
97-
setting.CheckLFSVersion()
98+
git.CheckLFSVersion()
9899
if !setting.LFS.StartServer {
99100
t.Skip()
100101
return
@@ -110,7 +111,7 @@ func TestGetLFSLarge(t *testing.T) {
110111

111112
func TestGetLFSGzip(t *testing.T) {
112113
defer prepareTestEnv(t)()
113-
setting.CheckLFSVersion()
114+
git.CheckLFSVersion()
114115
if !setting.LFS.StartServer {
115116
t.Skip()
116117
return
@@ -131,7 +132,7 @@ func TestGetLFSGzip(t *testing.T) {
131132

132133
func TestGetLFSZip(t *testing.T) {
133134
defer prepareTestEnv(t)()
134-
setting.CheckLFSVersion()
135+
git.CheckLFSVersion()
135136
if !setting.LFS.StartServer {
136137
t.Skip()
137138
return
@@ -154,7 +155,7 @@ func TestGetLFSZip(t *testing.T) {
154155

155156
func TestGetLFSRangeNo(t *testing.T) {
156157
defer prepareTestEnv(t)()
157-
setting.CheckLFSVersion()
158+
git.CheckLFSVersion()
158159
if !setting.LFS.StartServer {
159160
t.Skip()
160161
return
@@ -167,7 +168,7 @@ func TestGetLFSRangeNo(t *testing.T) {
167168

168169
func TestGetLFSRange(t *testing.T) {
169170
defer prepareTestEnv(t)()
170-
setting.CheckLFSVersion()
171+
git.CheckLFSVersion()
171172
if !setting.LFS.StartServer {
172173
t.Skip()
173174
return

integrations/migration-test/migration_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"code.gitea.io/gitea/models/migrations"
2424
"code.gitea.io/gitea/modules/base"
2525
"code.gitea.io/gitea/modules/charset"
26+
"code.gitea.io/gitea/modules/git"
2627
"code.gitea.io/gitea/modules/setting"
2728
"code.gitea.io/gitea/modules/util"
2829

@@ -61,7 +62,7 @@ func initMigrationTest(t *testing.T) func() {
6162
assert.NoError(t, util.RemoveAll(setting.RepoRootPath))
6263
assert.NoError(t, util.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath))
6364

64-
setting.CheckLFSVersion()
65+
git.CheckLFSVersion()
6566
setting.InitDBConfig()
6667
setting.NewLogServices(true)
6768
return deferFn

integrations/mirror_pull_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ func TestMirrorPull(t *testing.T) {
5959

6060
assert.NoError(t, release_service.CreateRelease(gitRepo, &models.Release{
6161
RepoID: repo.ID,
62+
Repo: repo,
6263
PublisherID: user.ID,
64+
Publisher: user,
6365
TagName: "v0.2",
6466
Target: "master",
6567
Title: "v0.2 is released",

integrations/repo_tag_test.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Copyright 2021 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 integrations
6+
7+
import (
8+
"io/ioutil"
9+
"net/url"
10+
"testing"
11+
12+
"code.gitea.io/gitea/models"
13+
"code.gitea.io/gitea/modules/git"
14+
"code.gitea.io/gitea/modules/util"
15+
"code.gitea.io/gitea/services/release"
16+
17+
"github.com/stretchr/testify/assert"
18+
)
19+
20+
func TestCreateNewTagProtected(t *testing.T) {
21+
defer prepareTestEnv(t)()
22+
23+
repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
24+
owner := models.AssertExistsAndLoadBean(t, &models.User{ID: repo.OwnerID}).(*models.User)
25+
26+
t.Run("API", func(t *testing.T) {
27+
defer PrintCurrentTest(t)()
28+
29+
err := release.CreateNewTag(owner, repo, "master", "v-1", "first tag")
30+
assert.NoError(t, err)
31+
32+
err = models.InsertProtectedTag(&models.ProtectedTag{
33+
RepoID: repo.ID,
34+
NamePattern: "v-*",
35+
})
36+
assert.NoError(t, err)
37+
err = models.InsertProtectedTag(&models.ProtectedTag{
38+
RepoID: repo.ID,
39+
NamePattern: "v-1.1",
40+
AllowlistUserIDs: []int64{repo.OwnerID},
41+
})
42+
assert.NoError(t, err)
43+
44+
err = release.CreateNewTag(owner, repo, "master", "v-2", "second tag")
45+
assert.Error(t, err)
46+
assert.True(t, models.IsErrProtectedTagName(err))
47+
48+
err = release.CreateNewTag(owner, repo, "master", "v-1.1", "third tag")
49+
assert.NoError(t, err)
50+
})
51+
52+
t.Run("Git", func(t *testing.T) {
53+
onGiteaRun(t, func(t *testing.T, u *url.URL) {
54+
username := "user2"
55+
httpContext := NewAPITestContext(t, username, "repo1")
56+
57+
dstPath, err := ioutil.TempDir("", httpContext.Reponame)
58+
assert.NoError(t, err)
59+
defer util.RemoveAll(dstPath)
60+
61+
u.Path = httpContext.GitPath()
62+
u.User = url.UserPassword(username, userPassword)
63+
64+
doGitClone(dstPath, u)(t)
65+
66+
_, err = git.NewCommand("tag", "v-2").RunInDir(dstPath)
67+
assert.NoError(t, err)
68+
69+
_, err = git.NewCommand("push", "--tags").RunInDir(dstPath)
70+
assert.Error(t, err)
71+
assert.Contains(t, err.Error(), "Tag v-2 is protected")
72+
})
73+
})
74+
}

models/error.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,21 @@ func (err ErrInvalidTagName) Error() string {
985985
return fmt.Sprintf("release tag name is not valid [tag_name: %s]", err.TagName)
986986
}
987987

988+
// ErrProtectedTagName represents a "ProtectedTagName" kind of error.
989+
type ErrProtectedTagName struct {
990+
TagName string
991+
}
992+
993+
// IsErrProtectedTagName checks if an error is a ErrProtectedTagName.
994+
func IsErrProtectedTagName(err error) bool {
995+
_, ok := err.(ErrProtectedTagName)
996+
return ok
997+
}
998+
999+
func (err ErrProtectedTagName) Error() string {
1000+
return fmt.Sprintf("release tag name is protected [tag_name: %s]", err.TagName)
1001+
}
1002+
9881003
// ErrRepoFileAlreadyExists represents a "RepoFileAlreadyExist" kind of error.
9891004
type ErrRepoFileAlreadyExists struct {
9901005
Path string

models/fixtures/action.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,27 @@
3232
repo_id: 22
3333
is_private: true
3434
created_unix: 1603267920
35+
36+
- id: 5
37+
user_id: 10
38+
op_type: 1 # create repo
39+
act_user_id: 10
40+
repo_id: 6
41+
is_private: true
42+
created_unix: 1603010100
43+
44+
- id: 6
45+
user_id: 10
46+
op_type: 1 # create repo
47+
act_user_id: 10
48+
repo_id: 7
49+
is_private: true
50+
created_unix: 1603011300
51+
52+
- id: 7
53+
user_id: 10
54+
op_type: 1 # create repo
55+
act_user_id: 10
56+
repo_id: 8
57+
is_private: false
58+
created_unix: 1603011540 # grouped with id:7

models/migrations/migrations.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,8 @@ var migrations = []Migration{
321321
NewMigration("Rename Task errors to message", renameTaskErrorsToMessage),
322322
// v185 -> v186
323323
NewMigration("Add new table repo_archiver", addRepoArchiver),
324+
// v186 -> v187
325+
NewMigration("Create protected tag table", createProtectedTagTable),
324326
}
325327

326328
// GetCurrentDBVersion returns the current db version

0 commit comments

Comments
 (0)