Skip to content

Commit

Permalink
Merge branch 'main' into sergeyd-user-dont-want-exhibit-selfs
Browse files Browse the repository at this point in the history
  • Loading branch information
zeripath authored Jun 26, 2021
2 parents 06fbdd5 + 19ac575 commit f258297
Show file tree
Hide file tree
Showing 78 changed files with 1,568 additions and 378 deletions.
8 changes: 4 additions & 4 deletions cmd/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,16 +221,16 @@ Gitea or set your environment appropriately.`, "")
total++
lastline++

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

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

hookOptions.OldCommitIDs = oldCommitIDs
hookOptions.NewCommitIDs = newCommitIDs
Expand Down Expand Up @@ -261,7 +261,7 @@ Gitea or set your environment appropriately.`, "")
hookOptions.NewCommitIDs = newCommitIDs[:count]
hookOptions.RefFullNames = refFullNames[:count]

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

statusCode, msg := private.HookPreReceive(username, reponame, hookOptions)
switch statusCode {
Expand Down
3 changes: 2 additions & 1 deletion contrib/pr/checkout.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"time"

"code.gitea.io/gitea/models"
gitea_git "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/external"
"code.gitea.io/gitea/modules/setting"
Expand Down Expand Up @@ -79,7 +80,7 @@ func runPR() {
setting.RunUser = curUser.Username

log.Printf("[PR] Loading fixtures data ...\n")
setting.CheckLFSVersion()
gitea_git.CheckLFSVersion()
//models.LoadConfigs()
/*
setting.Database.Type = "sqlite3"
Expand Down
2 changes: 2 additions & 0 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,8 @@ PATH =
;;
;; Minimum amount of time a user must exist before comments are kept when the user is deleted.
;USER_DELETE_WITH_COMMENTS_MAX_TIME = 0
;; Valid site url schemes for user profiles
;VALID_SITE_URL_SCHEMES=http,https


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Expand Down
1 change: 1 addition & 0 deletions docs/content/doc/advanced/config-cheat-sheet.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,7 @@ relation to port exhaustion.
- `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.
The user's email will be replaced with a concatenation of the user name in lower case, "@" and NO_REPLY_ADDRESS.
- `USER_DELETE_WITH_COMMENTS_MAX_TIME`: **0** Minimum amount of time a user must exist before comments are kept when the user is deleted.
- `VALID_SITE_URL_SCHEMES`: **http, https**: Valid site url schemes for user profiles

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

Expand Down
57 changes: 57 additions & 0 deletions docs/content/doc/advanced/protected-tags.en-us.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
date: "2021-05-14T00:00:00-00:00"
title: "Protected tags"
slug: "protected-tags"
weight: 45
toc: false
draft: false
menu:
sidebar:
parent: "advanced"
name: "Protected tags"
weight: 45
identifier: "protected-tags"
---

# Protected tags

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.

**Table of Contents**

{{< toc >}}

## Setting up protected tags

To protect a tag, you need to follow these steps:

1. Go to the repository’s **Settings** > **Tags** page.
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.
1. Choose the allowed users and/or teams. If you leave these fields empty noone is allowed to create or modify this tag.
1. Select **Save** to save the configuration.

## Pattern protected tags

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.

Examples:

| Type | Pattern Protected Tag | Possible Matching Tags |
| ----- | ------------------------ | --------------------------------------- |
| Glob | `v*` | `v`, `v-1`, `version2` |
| Glob | `v[0-9]` | `v0`, `v1` up to `v9` |
| Glob | `*-release` | `2.1-release`, `final-release` |
| Glob | `gitea` | only `gitea` |
| Glob | `*gitea*` | `gitea`, `2.1-gitea`, `1_gitea-release` |
| Glob | `{v,rel}-*` | `v-`, `v-1`, `v-final`, `rel-`, `rel-x` |
| Glob | `*` | matches all possible tag names |
| Regex | `/\Av/` | `v`, `v-1`, `version2` |
| Regex | `/\Av[0-9]\z/` | `v0`, `v1` up to `v9` |
| Regex | `/\Av\d+\.\d+\.\d+\z/` | `v1.0.17`, `v2.1.0` |
| Regex | `/\Av\d+(\.\d+){0,2}\z/` | `v1`, `v2.1`, `v1.2.34` |
| Regex | `/-release\z/` | `2.1-release`, `final-release` |
| Regex | `/gitea/` | `gitea`, `2.1-gitea`, `1_gitea-release` |
| Regex | `/\Agitea\z/` | only `gitea` |
| Regex | `/^gitea$/` | only `gitea` |
| Regex | `/\A(v\|rel)-/` | `v-`, `v-1`, `v-final`, `rel-`, `rel-x` |
| Regex | `/.+/` | matches all possible tag names |
2 changes: 1 addition & 1 deletion integrations/api_user_heatmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func TestUserHeatmap(t *testing.T) {
var heatmap []*models.UserHeatmapData
DecodeJSON(t, resp, &heatmap)
var dummyheatmap []*models.UserHeatmapData
dummyheatmap = append(dummyheatmap, &models.UserHeatmapData{Timestamp: 1603152000, Contributions: 1})
dummyheatmap = append(dummyheatmap, &models.UserHeatmapData{Timestamp: 1603227600, Contributions: 1})

assert.Equal(t, dummyheatmap, heatmap)
}
6 changes: 3 additions & 3 deletions integrations/git_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ func standardCommitAndPushTest(t *testing.T, dstPath string) (little, big string
func lfsCommitAndPushTest(t *testing.T, dstPath string) (littleLFS, bigLFS string) {
t.Run("LFS", func(t *testing.T) {
defer PrintCurrentTest(t)()
setting.CheckLFSVersion()
git.CheckLFSVersion()
if !setting.LFS.StartServer {
t.Skip()
return
Expand Down Expand Up @@ -213,7 +213,7 @@ func rawTest(t *testing.T, ctx *APITestContext, little, big, littleLFS, bigLFS s
resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
assert.Equal(t, littleSize, resp.Length)

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

setting.CheckLFSVersion()
git.CheckLFSVersion()
if setting.LFS.StartServer {
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", littleLFS))
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
Expand Down
3 changes: 2 additions & 1 deletion integrations/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/queue"
Expand Down Expand Up @@ -162,7 +163,7 @@ func initIntegrationTest() {
setting.SetCustomPathAndConf("", "", "")
setting.NewContext()
util.RemoveAll(models.LocalCopyPath())
setting.CheckLFSVersion()
git.CheckLFSVersion()
setting.InitDBConfig()
if err := storage.Init(); err != nil {
fmt.Printf("Init storage failed: %v", err)
Expand Down
13 changes: 7 additions & 6 deletions integrations/lfs_getobject_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"testing"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/routers/web"
Expand Down Expand Up @@ -81,7 +82,7 @@ func checkResponseTestContentEncoding(t *testing.T, content *[]byte, resp *httpt

func TestGetLFSSmall(t *testing.T) {
defer prepareTestEnv(t)()
setting.CheckLFSVersion()
git.CheckLFSVersion()
if !setting.LFS.StartServer {
t.Skip()
return
Expand All @@ -94,7 +95,7 @@ func TestGetLFSSmall(t *testing.T) {

func TestGetLFSLarge(t *testing.T) {
defer prepareTestEnv(t)()
setting.CheckLFSVersion()
git.CheckLFSVersion()
if !setting.LFS.StartServer {
t.Skip()
return
Expand All @@ -110,7 +111,7 @@ func TestGetLFSLarge(t *testing.T) {

func TestGetLFSGzip(t *testing.T) {
defer prepareTestEnv(t)()
setting.CheckLFSVersion()
git.CheckLFSVersion()
if !setting.LFS.StartServer {
t.Skip()
return
Expand All @@ -131,7 +132,7 @@ func TestGetLFSGzip(t *testing.T) {

func TestGetLFSZip(t *testing.T) {
defer prepareTestEnv(t)()
setting.CheckLFSVersion()
git.CheckLFSVersion()
if !setting.LFS.StartServer {
t.Skip()
return
Expand All @@ -154,7 +155,7 @@ func TestGetLFSZip(t *testing.T) {

func TestGetLFSRangeNo(t *testing.T) {
defer prepareTestEnv(t)()
setting.CheckLFSVersion()
git.CheckLFSVersion()
if !setting.LFS.StartServer {
t.Skip()
return
Expand All @@ -167,7 +168,7 @@ func TestGetLFSRangeNo(t *testing.T) {

func TestGetLFSRange(t *testing.T) {
defer prepareTestEnv(t)()
setting.CheckLFSVersion()
git.CheckLFSVersion()
if !setting.LFS.StartServer {
t.Skip()
return
Expand Down
3 changes: 2 additions & 1 deletion integrations/migration-test/migration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"code.gitea.io/gitea/models/migrations"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/charset"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"

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

setting.CheckLFSVersion()
git.CheckLFSVersion()
setting.InitDBConfig()
setting.NewLogServices(true)
return deferFn
Expand Down
2 changes: 2 additions & 0 deletions integrations/mirror_pull_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ func TestMirrorPull(t *testing.T) {

assert.NoError(t, release_service.CreateRelease(gitRepo, &models.Release{
RepoID: repo.ID,
Repo: repo,
PublisherID: user.ID,
Publisher: user,
TagName: "v0.2",
Target: "master",
Title: "v0.2 is released",
Expand Down
74 changes: 74 additions & 0 deletions integrations/repo_tag_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// 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 integrations

import (
"io/ioutil"
"net/url"
"testing"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/services/release"

"github.com/stretchr/testify/assert"
)

func TestCreateNewTagProtected(t *testing.T) {
defer prepareTestEnv(t)()

repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
owner := models.AssertExistsAndLoadBean(t, &models.User{ID: repo.OwnerID}).(*models.User)

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

err := release.CreateNewTag(owner, repo, "master", "v-1", "first tag")
assert.NoError(t, err)

err = models.InsertProtectedTag(&models.ProtectedTag{
RepoID: repo.ID,
NamePattern: "v-*",
})
assert.NoError(t, err)
err = models.InsertProtectedTag(&models.ProtectedTag{
RepoID: repo.ID,
NamePattern: "v-1.1",
AllowlistUserIDs: []int64{repo.OwnerID},
})
assert.NoError(t, err)

err = release.CreateNewTag(owner, repo, "master", "v-2", "second tag")
assert.Error(t, err)
assert.True(t, models.IsErrProtectedTagName(err))

err = release.CreateNewTag(owner, repo, "master", "v-1.1", "third tag")
assert.NoError(t, err)
})

t.Run("Git", func(t *testing.T) {
onGiteaRun(t, func(t *testing.T, u *url.URL) {
username := "user2"
httpContext := NewAPITestContext(t, username, "repo1")

dstPath, err := ioutil.TempDir("", httpContext.Reponame)
assert.NoError(t, err)
defer util.RemoveAll(dstPath)

u.Path = httpContext.GitPath()
u.User = url.UserPassword(username, userPassword)

doGitClone(dstPath, u)(t)

_, err = git.NewCommand("tag", "v-2").RunInDir(dstPath)
assert.NoError(t, err)

_, err = git.NewCommand("push", "--tags").RunInDir(dstPath)
assert.Error(t, err)
assert.Contains(t, err.Error(), "Tag v-2 is protected")
})
})
}
15 changes: 15 additions & 0 deletions models/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -985,6 +985,21 @@ func (err ErrInvalidTagName) Error() string {
return fmt.Sprintf("release tag name is not valid [tag_name: %s]", err.TagName)
}

// ErrProtectedTagName represents a "ProtectedTagName" kind of error.
type ErrProtectedTagName struct {
TagName string
}

// IsErrProtectedTagName checks if an error is a ErrProtectedTagName.
func IsErrProtectedTagName(err error) bool {
_, ok := err.(ErrProtectedTagName)
return ok
}

func (err ErrProtectedTagName) Error() string {
return fmt.Sprintf("release tag name is protected [tag_name: %s]", err.TagName)
}

// ErrRepoFileAlreadyExists represents a "RepoFileAlreadyExist" kind of error.
type ErrRepoFileAlreadyExists struct {
Path string
Expand Down
24 changes: 24 additions & 0 deletions models/fixtures/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,27 @@
repo_id: 22
is_private: true
created_unix: 1603267920

- id: 5
user_id: 10
op_type: 1 # create repo
act_user_id: 10
repo_id: 6
is_private: true
created_unix: 1603010100

- id: 6
user_id: 10
op_type: 1 # create repo
act_user_id: 10
repo_id: 7
is_private: true
created_unix: 1603011300

- id: 7
user_id: 10
op_type: 1 # create repo
act_user_id: 10
repo_id: 8
is_private: false
created_unix: 1603011540 # grouped with id:7
2 changes: 2 additions & 0 deletions models/migrations/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,8 @@ var migrations = []Migration{
NewMigration("Rename Task errors to message", renameTaskErrorsToMessage),
// v185 -> v186
NewMigration("Add new table repo_archiver", addRepoArchiver),
// v186 -> v187
NewMigration("Create protected tag table", createProtectedTagTable),
}

// GetCurrentDBVersion returns the current db version
Expand Down
Loading

0 comments on commit f258297

Please sign in to comment.