diff options
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/hook.go | 48 | ||||
-rw-r--r-- | cmd/serv.go | 11 | ||||
-rw-r--r-- | cmd/web.go | 29 |
3 files changed, 76 insertions, 12 deletions
diff --git a/cmd/hook.go b/cmd/hook.go index cb8b5112..c65b76e2 100644 --- a/cmd/hook.go +++ b/cmd/hook.go @@ -8,6 +8,7 @@ import ( "bufio" "bytes" "crypto/tls" + "fmt" "os" "os/exec" "path/filepath" @@ -64,13 +65,58 @@ func runHookPreReceive(c *cli.Context) error { if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 { return nil } - setup(c, "hooks/pre-receive.log", false) + setup(c, "hooks/pre-receive.log", true) + + isWiki := strings.Contains(os.Getenv(http.ENV_REPO_CUSTOM_HOOKS_PATH), ".wiki.git/") buf := bytes.NewBuffer(nil) scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { buf.Write(scanner.Bytes()) buf.WriteByte('\n') + + if isWiki { + continue + } + + fields := bytes.Fields(scanner.Bytes()) + if len(fields) != 3 { + continue + } + oldCommitID := string(fields[0]) + newCommitID := string(fields[1]) + branchName := strings.TrimPrefix(string(fields[2]), git.BRANCH_PREFIX) + + // Branch protection + repoID := com.StrTo(os.Getenv(http.ENV_REPO_ID)).MustInt64() + protectBranch, err := models.GetProtectBranchOfRepoByName(repoID, branchName) + if err != nil { + if models.IsErrBranchNotExist(err) { + continue + } + fail("Internal error", "GetProtectBranchOfRepoByName [repo_id: %d, branch: %s]: %v", repoID, branchName, err) + } + if !protectBranch.Protected { + continue + } + + // Check if branch allows direct push + if protectBranch.RequirePullRequest { + fail(fmt.Sprintf("Branch '%s' is protected and commits must be merged through pull request", branchName), "") + } + + // check and deletion + if newCommitID == git.EMPTY_SHA { + fail(fmt.Sprintf("Branch '%s' is protected from deletion", branchName), "") + } + + // Check force push + output, err := git.NewCommand("rev-list", oldCommitID, "^"+newCommitID).Run() + if err != nil { + fail("Internal error", "Fail to detect force push: %v", err) + } else if len(output) > 0 { + fail(fmt.Sprintf("Branch '%s' is protected from force push", branchName), "") + } } customHooksPath := filepath.Join(os.Getenv(http.ENV_REPO_CUSTOM_HOOKS_PATH), "pre-receive") diff --git a/cmd/serv.go b/cmd/serv.go index 57a674e5..3bd23ff9 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -175,7 +175,7 @@ func runServ(c *cli.Context) error { // Prohibit push to mirror repositories. if requestMode > models.ACCESS_MODE_READ && repo.IsMirror { - fail("mirror repository is read-only", "") + fail("Mirror repository is read-only", "") } // Allow anonymous (user is nil) clone for public repositories. @@ -251,7 +251,14 @@ func runServ(c *cli.Context) error { gitCmd = exec.Command(verb, repoFullName) } if requestMode == models.ACCESS_MODE_WRITE { - gitCmd.Env = append(os.Environ(), http.ComposeHookEnvs(repo.RepoPath(), owner.Name, owner.Salt, repo.Name, user)...) + gitCmd.Env = append(os.Environ(), http.ComposeHookEnvs(http.ComposeHookEnvsOptions{ + AuthUser: user, + OwnerName: owner.Name, + OwnerSalt: owner.Salt, + RepoID: repo.ID, + RepoName: repo.Name, + RepoPath: repo.RepoPath(), + })...) } gitCmd.Dir = setting.RepoRootPath gitCmd.Stdout = os.Stdout @@ -435,10 +435,21 @@ func runWeb(ctx *cli.Context) error { m.Combo("").Get(repo.Settings). Post(bindIgnErr(auth.RepoSettingForm{}), repo.SettingsPost) m.Group("/collaboration", func() { - m.Combo("").Get(repo.Collaboration).Post(repo.CollaborationPost) + m.Combo("").Get(repo.SettingsCollaboration).Post(repo.SettingsCollaborationPost) m.Post("/access_mode", repo.ChangeCollaborationAccessMode) m.Post("/delete", repo.DeleteCollaboration) }) + m.Group("/branches", func() { + m.Get("", repo.SettingsBranches) + m.Post("/default_branch", repo.UpdateDefaultBranch) + m.Combo("/*").Get(repo.SettingsProtectedBranch). + Post(bindIgnErr(auth.ProtectBranchForm{}), repo.SettingsProtectedBranchPost) + }, func(ctx *context.Context) { + if ctx.Repo.Repository.IsMirror { + ctx.NotFound() + return + } + }) m.Group("/hooks", func() { m.Get("", repo.Webhooks) @@ -452,15 +463,15 @@ func runWeb(ctx *cli.Context) error { m.Post("/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost) m.Group("/git", func() { - m.Get("", repo.GitHooks) - m.Combo("/:name").Get(repo.GitHooksEdit). - Post(repo.GitHooksEditPost) + m.Get("", repo.SettingsGitHooks) + m.Combo("/:name").Get(repo.SettingsGitHooksEdit). + Post(repo.SettingsGitHooksEditPost) }, context.GitHookService()) }) m.Group("/keys", func() { - m.Combo("").Get(repo.DeployKeys). - Post(bindIgnErr(auth.AddSSHKeyForm{}), repo.DeployKeysPost) + m.Combo("").Get(repo.SettingsDeployKeys). + Post(bindIgnErr(auth.AddSSHKeyForm{}), repo.SettingsDeployKeysPost) m.Post("/delete", repo.DeleteDeployKey) }) @@ -555,13 +566,13 @@ func runWeb(ctx *cli.Context) error { m.Post("/upload-remove", bindIgnErr(auth.RemoveUploadFileForm{}), repo.RemoveUploadFileFromServer) }, func(ctx *context.Context) { if !setting.Repository.Upload.Enabled { - ctx.Handle(404, "", nil) + ctx.NotFound() return } }) }, reqRepoWriter, context.RepoRef(), func(ctx *context.Context) { - if !ctx.Repo.Repository.CanEnableEditor() || ctx.Repo.IsViewCommit { - ctx.Handle(404, "", nil) + if !ctx.Repo.CanEnableEditor() { + ctx.NotFound() return } }) |