summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorKN4CK3R <admin@oldschoolhack.me>2021-06-25 16:28:55 +0200
committerGitHub <noreply@github.com>2021-06-25 16:28:55 +0200
commit44b8b07631666e3ae691149bdba31ca0f51569f5 (patch)
tree51808ac8f6cb9388e18660d6364fcf876532877f /services
parent7a0ed9a0469b24768c9041e137bfcd2d28f05319 (diff)
downloadgitea-44b8b07631666e3ae691149bdba31ca0f51569f5.tar.gz
gitea-44b8b07631666e3ae691149bdba31ca0f51569f5.zip
Add tag protection (#15629)
* Added tag protection in hook. * Prevent UI tag creation if protected. * Added settings page. * Added tests. * Added suggestions. * Moved tests. * Use individual errors. * Removed unneeded methods. * Switched delete selector. * Changed method names. * No reason to be unique. * Allow editing of protected tags. * Removed unique key from migration. * Added docs page. * Changed date. * Respond with 404 to not found tags. * Replaced glob with regex pattern. * Added support for glob and regex pattern. * Updated documentation. * Changed white* to allow*. * Fixed edit button link. * Added cancel button. Co-authored-by: zeripath <art27@cantab.net> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Diffstat (limited to 'services')
-rw-r--r--services/forms/repo_tag_form.go27
-rw-r--r--services/release/release.go27
-rw-r--r--services/release/release_test.go26
3 files changed, 75 insertions, 5 deletions
diff --git a/services/forms/repo_tag_form.go b/services/forms/repo_tag_form.go
new file mode 100644
index 0000000000..337e7fe1ea
--- /dev/null
+++ b/services/forms/repo_tag_form.go
@@ -0,0 +1,27 @@
+// Copyright 2021 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package forms
+
+import (
+ "net/http"
+
+ "code.gitea.io/gitea/modules/context"
+ "code.gitea.io/gitea/modules/web/middleware"
+
+ "gitea.com/go-chi/binding"
+)
+
+// ProtectTagForm form for changing protected tag settings
+type ProtectTagForm struct {
+ NamePattern string `binding:"Required;GlobOrRegexPattern"`
+ AllowlistUsers string
+ AllowlistTeams string
+}
+
+// Validate validates the fields
+func (f *ProtectTagForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
+ ctx := context.GetContext(req)
+ return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
+}
diff --git a/services/release/release.go b/services/release/release.go
index 9d201edf6d..6f5aa02c85 100644
--- a/services/release/release.go
+++ b/services/release/release.go
@@ -23,6 +23,25 @@ func createTag(gitRepo *git.Repository, rel *models.Release, msg string) (bool,
// Only actual create when publish.
if !rel.IsDraft {
if !gitRepo.IsTagExist(rel.TagName) {
+ if err := rel.LoadAttributes(); err != nil {
+ log.Error("LoadAttributes: %v", err)
+ return false, err
+ }
+
+ protectedTags, err := rel.Repo.GetProtectedTags()
+ if err != nil {
+ return false, fmt.Errorf("GetProtectedTags: %v", err)
+ }
+ isAllowed, err := models.IsUserAllowedToControlTag(protectedTags, rel.TagName, rel.PublisherID)
+ if err != nil {
+ return false, err
+ }
+ if !isAllowed {
+ return false, models.ErrProtectedTagName{
+ TagName: rel.TagName,
+ }
+ }
+
commit, err := gitRepo.GetCommit(rel.Target)
if err != nil {
return false, fmt.Errorf("GetCommit: %v", err)
@@ -49,11 +68,7 @@ func createTag(gitRepo *git.Repository, rel *models.Release, msg string) (bool,
}
created = true
rel.LowerTagName = strings.ToLower(rel.TagName)
- // Prepare Notify
- if err := rel.LoadAttributes(); err != nil {
- log.Error("LoadAttributes: %v", err)
- return false, err
- }
+
notification.NotifyPushCommits(
rel.Publisher, rel.Repo,
&repository.PushUpdateOptions{
@@ -137,7 +152,9 @@ func CreateNewTag(doer *models.User, repo *models.Repository, commit, tagName, m
rel := &models.Release{
RepoID: repo.ID,
+ Repo: repo,
PublisherID: doer.ID,
+ Publisher: doer,
TagName: tagName,
Target: commit,
IsDraft: false,
diff --git a/services/release/release_test.go b/services/release/release_test.go
index 085be55cb4..9f665fabab 100644
--- a/services/release/release_test.go
+++ b/services/release/release_test.go
@@ -33,7 +33,9 @@ func TestRelease_Create(t *testing.T) {
assert.NoError(t, CreateRelease(gitRepo, &models.Release{
RepoID: repo.ID,
+ Repo: repo,
PublisherID: user.ID,
+ Publisher: user,
TagName: "v0.1",
Target: "master",
Title: "v0.1 is released",
@@ -45,7 +47,9 @@ func TestRelease_Create(t *testing.T) {
assert.NoError(t, CreateRelease(gitRepo, &models.Release{
RepoID: repo.ID,
+ Repo: repo,
PublisherID: user.ID,
+ Publisher: user,
TagName: "v0.1.1",
Target: "65f1bf27bc3bf70f64657658635e66094edbcb4d",
Title: "v0.1.1 is released",
@@ -57,7 +61,9 @@ func TestRelease_Create(t *testing.T) {
assert.NoError(t, CreateRelease(gitRepo, &models.Release{
RepoID: repo.ID,
+ Repo: repo,
PublisherID: user.ID,
+ Publisher: user,
TagName: "v0.1.2",
Target: "65f1bf2",
Title: "v0.1.2 is released",
@@ -69,7 +75,9 @@ func TestRelease_Create(t *testing.T) {
assert.NoError(t, CreateRelease(gitRepo, &models.Release{
RepoID: repo.ID,
+ Repo: repo,
PublisherID: user.ID,
+ Publisher: user,
TagName: "v0.1.3",
Target: "65f1bf2",
Title: "v0.1.3 is released",
@@ -81,7 +89,9 @@ func TestRelease_Create(t *testing.T) {
assert.NoError(t, CreateRelease(gitRepo, &models.Release{
RepoID: repo.ID,
+ Repo: repo,
PublisherID: user.ID,
+ Publisher: user,
TagName: "v0.1.4",
Target: "65f1bf2",
Title: "v0.1.4 is released",
@@ -99,7 +109,9 @@ func TestRelease_Create(t *testing.T) {
var release = models.Release{
RepoID: repo.ID,
+ Repo: repo,
PublisherID: user.ID,
+ Publisher: user,
TagName: "v0.1.5",
Target: "65f1bf2",
Title: "v0.1.5 is released",
@@ -125,7 +137,9 @@ func TestRelease_Update(t *testing.T) {
// Test a changed release
assert.NoError(t, CreateRelease(gitRepo, &models.Release{
RepoID: repo.ID,
+ Repo: repo,
PublisherID: user.ID,
+ Publisher: user,
TagName: "v1.1.1",
Target: "master",
Title: "v1.1.1 is released",
@@ -147,7 +161,9 @@ func TestRelease_Update(t *testing.T) {
// Test a changed draft
assert.NoError(t, CreateRelease(gitRepo, &models.Release{
RepoID: repo.ID,
+ Repo: repo,
PublisherID: user.ID,
+ Publisher: user,
TagName: "v1.2.1",
Target: "65f1bf2",
Title: "v1.2.1 is draft",
@@ -169,7 +185,9 @@ func TestRelease_Update(t *testing.T) {
// Test a changed pre-release
assert.NoError(t, CreateRelease(gitRepo, &models.Release{
RepoID: repo.ID,
+ Repo: repo,
PublisherID: user.ID,
+ Publisher: user,
TagName: "v1.3.1",
Target: "65f1bf2",
Title: "v1.3.1 is pre-released",
@@ -192,7 +210,9 @@ func TestRelease_Update(t *testing.T) {
// Test create release
release = &models.Release{
RepoID: repo.ID,
+ Repo: repo,
PublisherID: user.ID,
+ Publisher: user,
TagName: "v1.1.2",
Target: "master",
Title: "v1.1.2 is released",
@@ -258,7 +278,9 @@ func TestRelease_createTag(t *testing.T) {
// Test a changed release
release := &models.Release{
RepoID: repo.ID,
+ Repo: repo,
PublisherID: user.ID,
+ Publisher: user,
TagName: "v2.1.1",
Target: "master",
Title: "v2.1.1 is released",
@@ -280,7 +302,9 @@ func TestRelease_createTag(t *testing.T) {
// Test a changed draft
release = &models.Release{
RepoID: repo.ID,
+ Repo: repo,
PublisherID: user.ID,
+ Publisher: user,
TagName: "v2.2.1",
Target: "65f1bf2",
Title: "v2.2.1 is draft",
@@ -301,7 +325,9 @@ func TestRelease_createTag(t *testing.T) {
// Test a changed pre-release
release = &models.Release{
RepoID: repo.ID,
+ Repo: repo,
PublisherID: user.ID,
+ Publisher: user,
TagName: "v2.3.1",
Target: "65f1bf2",
Title: "v2.3.1 is pre-released",