Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "Allow edits from maintainer" feature #18002

Merged
merged 122 commits into from Apr 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
122 commits
Select commit Hold shift + click to select a range
a30c4d0
Add basic logifc for allow edits by maintainers feature and allow upd…
qwerty287 Dec 14, 2021
fe06546
Add "Allow edits from maintainer" feature
qwerty287 Dec 16, 2021
ff92170
Merge branch 'main' into allow-edits
qwerty287 Dec 16, 2021
d9ae6cf
Fix security issue
qwerty287 Dec 16, 2021
2efd678
Merge branch 'main' into allow-edits
qwerty287 Dec 16, 2021
bc5f4d0
fmt
qwerty287 Dec 16, 2021
44d7b25
Fix typo
qwerty287 Dec 16, 2021
bf2244a
Resolve TODO
qwerty287 Dec 16, 2021
298f912
Update web_src/js/features/repo-issue.js
qwerty287 Dec 17, 2021
4f2f34a
Merge branch 'main' into allow-edits
qwerty287 Dec 17, 2021
b4dbc8d
Rm debug code
qwerty287 Dec 17, 2021
111896c
Update desc
qwerty287 Dec 17, 2021
594d277
Rm var
qwerty287 Dec 17, 2021
c30bdc3
Disable JS on new PR
qwerty287 Dec 17, 2021
4c7f2ba
Use var to save url
qwerty287 Dec 17, 2021
f086784
Show error popup if failed
qwerty287 Dec 17, 2021
17f0729
Fix lint
qwerty287 Dec 17, 2021
31ff678
Fix js
qwerty287 Dec 17, 2021
9f60458
Merge branch 'main' into allow-edits
qwerty287 Dec 20, 2021
9e475a7
Merge branch 'main' into allow-edits
qwerty287 Dec 21, 2021
f5f208e
Hide optin if pr is closed
qwerty287 Dec 21, 2021
2f912a2
Remove `nil` check
qwerty287 Dec 21, 2021
b010961
Move checkbox into segment
qwerty287 Dec 21, 2021
ad83a25
Apply suggestions from code review
qwerty287 Dec 22, 2021
2feff0b
len() check
qwerty287 Dec 22, 2021
ac654e3
Merge branch 'allow-edits' of github.com:qwerty287/gitea into allow-e…
qwerty287 Dec 22, 2021
7c5e39c
Merge branch 'main' into allow-edits
qwerty287 Jan 7, 2022
819d679
fmt
qwerty287 Jan 7, 2022
c6e2a02
Fix permissions
qwerty287 Jan 7, 2022
f4a0983
Use not null default true
qwerty287 Jan 7, 2022
e55c639
methods -> funcs
qwerty287 Jan 7, 2022
fb2ff38
Merge branch 'main' into allow-edits
qwerty287 Jan 9, 2022
4d5b073
Rename
qwerty287 Jan 14, 2022
cd6ba30
Merge branch 'main' into allow-edits
qwerty287 Jan 14, 2022
d21701f
fmt
qwerty287 Jan 18, 2022
0a12828
Merge branch 'main' into allow-edits
qwerty287 Jan 18, 2022
1642c2f
Merge branch 'main' into allow-edits
qwerty287 Jan 19, 2022
f0b688f
fmt
qwerty287 Jan 19, 2022
6949086
Merge branch 'allow-edits' of github.com:qwerty287/gitea into allow-e…
qwerty287 Jan 19, 2022
9b68464
Merge branch 'main' into allow-edits
qwerty287 Jan 22, 2022
e564c33
Merge branch 'main' into allow-edits
qwerty287 Jan 25, 2022
bdfe2fd
Merge branch 'allow-edits' of github.com:qwerty287/gitea into allow-e…
qwerty287 Jan 25, 2022
59bda50
Update col name
qwerty287 Jan 26, 2022
a93a7b7
Merge branch 'main' into allow-edits
qwerty287 Jan 26, 2022
1f7825b
Merge branch 'main' into allow-edits
6543 Jan 27, 2022
cd7981d
Merge branch 'main' into allow-edits
6543 Jan 31, 2022
f581696
Merge branch 'main' into allow-edits
qwerty287 Feb 5, 2022
d22e233
Merge branch 'main' into allow-edits
wxiaoguang Feb 7, 2022
1012a62
Merge branch 'main' into allow-edits
qwerty287 Feb 7, 2022
b689ae3
Merge branch 'allow-edits' of github.com:qwerty287/gitea into allow-e…
qwerty287 Feb 7, 2022
7add045
Fix 500 + disable checkbox
qwerty287 Feb 7, 2022
9cd6a2c
Fix lint
qwerty287 Feb 7, 2022
870ebf0
Merge branch 'main' into allow-edits
qwerty287 Feb 14, 2022
4e13dfc
Fix branch perms values
qwerty287 Feb 14, 2022
dfe968b
Merge branch 'main' into allow-edits
6543 Feb 14, 2022
af05be8
Handle casting error
qwerty287 Feb 14, 2022
ce93b59
Merge branch 'main' into allow-edits
qwerty287 Feb 15, 2022
ae5b39e
Use single endpoint and update popup
qwerty287 Feb 15, 2022
9a31150
Update API endpoints
qwerty287 Feb 15, 2022
ec88ad9
Rm dupl loading
qwerty287 Feb 19, 2022
6e55f66
Merge branch 'main' into allow-edits
qwerty287 Feb 19, 2022
2c041e1
Merge branch 'main' into allow-edits
qwerty287 Feb 19, 2022
6c2e446
Merge branch 'main' into allow-edits
6543 Feb 20, 2022
f85ee71
Merge branch 'master' into allow-edits
6543 Feb 25, 2022
12f0efc
add right formations & text to migrations.go
6543 Feb 25, 2022
463618f
refactor
6543 Feb 25, 2022
ae410cd
Merge branch 'main' into allow-edits
qwerty287 Feb 26, 2022
884f09e
Merge branch 'main' into allow-edits
qwerty287 Mar 2, 2022
290f0c3
Merge branch 'allow-edits' of github.com:qwerty287/gitea into allow-e…
qwerty287 Mar 2, 2022
bfc946d
Merge branch 'main' into allow-edits
qwerty287 Mar 3, 2022
d4f4901
Merge branch 'main' into allow-edits
6543 Mar 6, 2022
723658a
Move base repo loading
qwerty287 Mar 11, 2022
024d44f
Fix checkbox visibility
qwerty287 Mar 11, 2022
e8e3527
Merge branch 'main' into allow-edits
qwerty287 Mar 11, 2022
cf2285a
Merge branch 'main' into allow-edits
qwerty287 Mar 23, 2022
4140480
Fix merge
qwerty287 Mar 23, 2022
4753b2f
Fix refactored parts
qwerty287 Mar 23, 2022
e62e988
Update models/migrations/migrations.go
qwerty287 Mar 24, 2022
d3f7b92
Merge branch 'main' into allow-edits
qwerty287 Mar 24, 2022
95e1eaa
Merge branch 'main' into allow-edits
qwerty287 Mar 27, 2022
228ead8
Merge branch 'main' into allow-edits
qwerty287 Apr 5, 2022
4deda60
Merge branch 'main' into allow-edits
6543 Apr 5, 2022
0feca99
Warn on SSH connection for incorrect configuration (#19317)
Gusted Apr 5, 2022
29904e7
Add `ENABLE_SSH_LOG` to debugging problems (#19316)
Gusted Apr 5, 2022
eb579d4
[skip ci] Updated translations via Crowdin
GiteaBot Apr 6, 2022
84f66d9
Package registry changes (#19305)
KN4CK3R Apr 6, 2022
b70b908
Show ssh command directly in template instead of i18n translation (#1…
junjieyuan Apr 6, 2022
1815192
[skip ci] Updated translations via Crowdin
GiteaBot Apr 7, 2022
2818531
Never use /api/v1 from Gitea UI Pages (#19318)
lunny Apr 7, 2022
c3d9871
[skip ci] Updated translations via Crowdin
GiteaBot Apr 8, 2022
ceb20d3
API: Search Issues, dont show 500 if filter result in empty list (#19…
6543 Apr 8, 2022
b01e16f
Remove dependent on session auth for api/v1 routers (#19321)
lunny Apr 8, 2022
ee153a3
Refactor CSRF protection modules, make sure CSRF tokens can be up-to-…
wxiaoguang Apr 8, 2022
53b8d49
Move milestone to models/issues/ (#19278)
lunny Apr 8, 2022
3cb3172
Use "main" as default branch name (#19354)
wxiaoguang Apr 9, 2022
52cccf7
Allow package linking to private repository (#19348)
KN4CK3R Apr 9, 2022
5d5cdff
[skip ci] Updated translations via Crowdin
GiteaBot Apr 10, 2022
fb9ec70
Fixed registry host value. (#19363)
KN4CK3R Apr 10, 2022
f8f3cb9
Add logic to switch between source/rendered on Markdown (#19356)
Gusted Apr 10, 2022
1c00aee
Fix panic in teams API when requesting members (#19360)
delvh Apr 11, 2022
66fff7c
Fix middleware function's placements for some `/user/...` (#19377)
Gusted Apr 12, 2022
e11d4d1
Document 409 error returned by repos/migrate api (#19376)
harryzcy Apr 12, 2022
c0c3a71
Note where frontend files are located in docs (#19379)
ktprograms Apr 12, 2022
013f563
[skip ci] Updated translations via Crowdin
GiteaBot Apr 13, 2022
5060442
Disallow selecting the text of buttons (#19330)
delvh Apr 14, 2022
68d2735
Use a struct as test options (#19393)
lunny Apr 14, 2022
a137027
Fix double blob-hunk (#19404)
Gusted Apr 15, 2022
093f3f2
Merge branch 'master' into allow-edits
6543 Apr 27, 2022
0dbf2c0
default is false
6543 Apr 27, 2022
3aa8116
Update models/pull.go
6543 Apr 27, 2022
5098223
Update models/pull.go
6543 Apr 27, 2022
3a8968f
use pull_services
6543 Apr 27, 2022
57bf535
Merge branch 'main' into allow-edits
qwerty287 Apr 28, 2022
87ebb3f
Consistent name
qwerty287 Apr 28, 2022
978764d
Fix hack
qwerty287 Apr 28, 2022
6a00395
Fix func
qwerty287 Apr 28, 2022
c7f17c9
fix form item name
wxiaoguang Apr 28, 2022
5079662
Merge branch 'main' into allow-edits
wxiaoguang Apr 28, 2022
ed139f0
fix merge conflicts
wxiaoguang Apr 28, 2022
7b64f0f
Remove name
qwerty287 Apr 28, 2022
4c2eb4d
Fix name
qwerty287 Apr 28, 2022
d0880cb
Merge branch 'main' into allow-edits
6543 Apr 28, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions models/migrations/migrations.go
Expand Up @@ -61,6 +61,7 @@ type Version struct {
// update minDBVersion accordingly
var migrations = []Migration{
// Gitea 1.5.0 ends at v69
6543 marked this conversation as resolved.
Show resolved Hide resolved

// v70 -> v71
NewMigration("add issue_dependencies", addIssueDependencies),
// v71 -> v72
Expand Down Expand Up @@ -380,6 +381,8 @@ var migrations = []Migration{
NewMigration("Create ForeignReference table", createForeignReferenceTable),
// v212 -> v213
NewMigration("Add package tables", addPackageTables),
// v213 -> v214
NewMigration("Add allow edits from maintainers to PullRequest table", addAllowMaintainerEdit),
}

// GetCurrentDBVersion returns the current db version
Expand Down
18 changes: 18 additions & 0 deletions models/migrations/v213.go
@@ -0,0 +1,18 @@
// Copyright 2022 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 migrations

import (
"xorm.io/xorm"
)

func addAllowMaintainerEdit(x *xorm.Engine) error {
// PullRequest represents relation between pull request and repositories.
type PullRequest struct {
AllowMaintainerEdit bool `xorm:"NOT NULL DEFAULT false"`
}

return x.Sync2(new(PullRequest))
}
27 changes: 18 additions & 9 deletions models/pull.go
Expand Up @@ -69,15 +69,16 @@ type PullRequest struct {
Issue *Issue `xorm:"-"`
Index int64

HeadRepoID int64 `xorm:"INDEX"`
HeadRepo *repo_model.Repository `xorm:"-"`
BaseRepoID int64 `xorm:"INDEX"`
BaseRepo *repo_model.Repository `xorm:"-"`
HeadBranch string
HeadCommitID string `xorm:"-"`
BaseBranch string
ProtectedBranch *ProtectedBranch `xorm:"-"`
MergeBase string `xorm:"VARCHAR(40)"`
HeadRepoID int64 `xorm:"INDEX"`
HeadRepo *repo_model.Repository `xorm:"-"`
BaseRepoID int64 `xorm:"INDEX"`
BaseRepo *repo_model.Repository `xorm:"-"`
HeadBranch string
HeadCommitID string `xorm:"-"`
BaseBranch string
ProtectedBranch *ProtectedBranch `xorm:"-"`
MergeBase string `xorm:"VARCHAR(40)"`
AllowMaintainerEdit bool `xorm:"NOT NULL DEFAULT false"`

HasMerged bool `xorm:"INDEX"`
MergedCommitID string `xorm:"VARCHAR(40)"`
Expand Down Expand Up @@ -711,6 +712,14 @@ func (pr *PullRequest) GetHeadBranchHTMLURL() string {
return pr.HeadRepo.HTMLURL() + "/src/branch/" + util.PathEscapeSegments(pr.HeadBranch)
}

// UpdateAllowEdits update if PR can be edited from maintainers
func UpdateAllowEdits(ctx context.Context, pr *PullRequest) error {
if _, err := db.GetEngine(ctx).ID(pr.ID).Cols("allow_maintainer_edit").Update(pr); err != nil {
return err
}
return nil
}

// Mergeable returns if the pullrequest is mergeable.
func (pr *PullRequest) Mergeable() bool {
// If a pull request isn't mergable if it's:
Expand Down
34 changes: 34 additions & 0 deletions models/repo_permission.go
Expand Up @@ -103,6 +103,39 @@ func (p *Permission) CanWriteIssuesOrPulls(isPull bool) bool {
return p.CanWrite(unit.TypeIssues)
}

// CanWriteToBranch checks if the branch is writable by the user
func (p *Permission) CanWriteToBranch(user *user_model.User, branch string) bool {
if p.CanWrite(unit.TypeCode) {
return true
}

if len(p.Units) < 1 {
return false
}

prs, err := GetUnmergedPullRequestsByHeadInfo(p.Units[0].RepoID, branch)
qwerty287 marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return false
}

for _, pr := range prs {
if pr.AllowMaintainerEdit {
err = pr.LoadBaseRepo()
if err != nil {
continue
}
prPerm, err := GetUserRepoPermission(db.DefaultContext, pr.BaseRepo, user)
if err != nil {
continue
}
if prPerm.CanWrite(unit.TypeCode) {
return true
}
}
}
return false
}

// ColorFormat writes a colored string for these Permissions
func (p *Permission) ColorFormat(s fmt.State) {
noColor := log.ColorBytes(log.Reset)
Expand Down Expand Up @@ -160,6 +193,7 @@ func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, use
perm)
}()
}

// anonymous user visit private repo.
// TODO: anonymous user visit public unit of private repo???
if user == nil && repo.IsPrivate {
Expand Down
10 changes: 10 additions & 0 deletions modules/context/permission.go
Expand Up @@ -29,6 +29,16 @@ func RequireRepoWriter(unitType unit.Type) func(ctx *Context) {
}
}

// CanEnableEditor checks if the user is allowed to write to the branch of the repo
func CanEnableEditor() func(ctx *Context) {
return func(ctx *Context) {
if !ctx.Repo.Permission.CanWriteToBranch(ctx.Doer, ctx.Repo.BranchName) {
ctx.NotFound("CanWriteToBranch denies permission", nil)
return
}
}
}

// RequireRepoWriterOr returns a middleware for requiring repository write to one of the unit permission
func RequireRepoWriterOr(unitTypes ...unit.Type) func(ctx *Context) {
return func(ctx *Context) {
Expand Down
8 changes: 4 additions & 4 deletions modules/context/repo.go
Expand Up @@ -78,8 +78,8 @@ type Repository struct {
}

// CanEnableEditor returns true if repository is editable and user has proper access level.
func (r *Repository) CanEnableEditor() bool {
return r.Permission.CanWrite(unit_model.TypeCode) && r.Repository.CanEnableEditor() && r.IsViewBranch && !r.Repository.IsArchived
func (r *Repository) CanEnableEditor(user *user_model.User) bool {
return r.IsViewBranch && r.Permission.CanWriteToBranch(user, r.BranchName) && r.Repository.CanEnableEditor() && !r.Repository.IsArchived
}

// CanCreateBranch returns true if repository is editable and user has proper access level.
Expand Down Expand Up @@ -123,7 +123,7 @@ func (r *Repository) CanCommitToBranch(ctx context.Context, doer *user_model.Use

sign, keyID, _, err := asymkey_service.SignCRUDAction(ctx, r.Repository.RepoPath(), doer, r.Repository.RepoPath(), git.BranchPrefix+r.BranchName)

canCommit := r.CanEnableEditor() && userCanPush
canCommit := r.CanEnableEditor(doer) && userCanPush
if requireSigned {
canCommit = canCommit && sign
}
Expand All @@ -139,7 +139,7 @@ func (r *Repository) CanCommitToBranch(ctx context.Context, doer *user_model.Use

return CanCommitToBranchResults{
CanCommitToBranch: canCommit,
EditorEnabled: r.CanEnableEditor(),
EditorEnabled: r.CanEnableEditor(doer),
UserCanPush: userCanPush,
RequireSigned: requireSigned,
WillSign: sign,
Expand Down
9 changes: 8 additions & 1 deletion modules/convert/convert.go
Expand Up @@ -41,12 +41,19 @@ func ToEmail(email *user_model.EmailAddress) *api.Email {
func ToBranch(repo *repo_model.Repository, b *git.Branch, c *git.Commit, bp *models.ProtectedBranch, user *user_model.User, isRepoAdmin bool) (*api.Branch, error) {
if bp == nil {
var hasPerm bool
var canPush bool
var err error
if user != nil {
hasPerm, err = models.HasAccessUnit(user, repo, unit.TypeCode, perm.AccessModeWrite)
if err != nil {
return nil, err
}

perms, err := models.GetUserRepoPermission(db.DefaultContext, repo, user)
if err != nil {
return nil, err
}
canPush = perms.CanWriteToBranch(user, b.Name)
}

return &api.Branch{
Expand All @@ -56,7 +63,7 @@ func ToBranch(repo *repo_model.Repository, b *git.Branch, c *git.Commit, bp *mod
RequiredApprovals: 0,
EnableStatusCheck: false,
StatusCheckContexts: []string{},
UserCanPush: hasPerm,
UserCanPush: canPush,
UserCanMerge: hasPerm,
}, nil
}
Expand Down
2 changes: 2 additions & 0 deletions modules/convert/pull.go
Expand Up @@ -73,6 +73,8 @@ func ToAPIPullRequest(ctx context.Context, pr *models.PullRequest, doer *user_mo
Created: pr.Issue.CreatedUnix.AsTimePtr(),
Updated: pr.Issue.UpdatedUnix.AsTimePtr(),

AllowMaintainerEdit: pr.AllowMaintainerEdit,

Base: &api.PRBranchInfo{
Name: pr.BaseBranch,
Ref: pr.BaseBranch,
Expand Down
12 changes: 7 additions & 5 deletions modules/structs/pull.go
Expand Up @@ -31,9 +31,10 @@ type PullRequest struct {
Mergeable bool `json:"mergeable"`
HasMerged bool `json:"merged"`
// swagger:strfmt date-time
Merged *time.Time `json:"merged_at"`
MergedCommitID *string `json:"merge_commit_sha"`
MergedBy *User `json:"merged_by"`
Merged *time.Time `json:"merged_at"`
MergedCommitID *string `json:"merge_commit_sha"`
MergedBy *User `json:"merged_by"`
AllowMaintainerEdit bool `json:"allow_maintainer_edit"`

Base *PRBranchInfo `json:"base"`
Head *PRBranchInfo `json:"head"`
Expand Down Expand Up @@ -90,6 +91,7 @@ type EditPullRequestOption struct {
Labels []int64 `json:"labels"`
State *string `json:"state"`
// swagger:strfmt date-time
Deadline *time.Time `json:"due_date"`
RemoveDeadline *bool `json:"unset_due_date"`
Deadline *time.Time `json:"due_date"`
RemoveDeadline *bool `json:"unset_due_date"`
AllowMaintainerEdit *bool `json:"allow_maintainer_edit"`
}
20 changes: 20 additions & 0 deletions modules/structs/repo_file.go
Expand Up @@ -30,6 +30,11 @@ type CreateFileOptions struct {
Content string `json:"content"`
}

// Branch returns branch name
func (o *CreateFileOptions) Branch() string {
return o.FileOptions.BranchName
6543 marked this conversation as resolved.
Show resolved Hide resolved
}

// DeleteFileOptions options for deleting files (used for other File structs below)
// Note: `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used)
type DeleteFileOptions struct {
Expand All @@ -39,6 +44,11 @@ type DeleteFileOptions struct {
SHA string `json:"sha" binding:"Required"`
}

// Branch returns branch name
func (o *DeleteFileOptions) Branch() string {
return o.FileOptions.BranchName
}

// UpdateFileOptions options for updating files
// Note: `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used)
type UpdateFileOptions struct {
Expand All @@ -50,6 +60,16 @@ type UpdateFileOptions struct {
FromPath string `json:"from_path" binding:"MaxSize(500)"`
}

// Branch returns branch name
func (o *UpdateFileOptions) Branch() string {
return o.FileOptions.BranchName
}

// FileOptionInterface provides a unified interface for the different file options
type FileOptionInterface interface {
Branch() string
}

// ApplyDiffPatchFileOptions options for applying a diff patch
// Note: `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used)
type ApplyDiffPatchFileOptions struct {
Expand Down
3 changes: 3 additions & 0 deletions options/locale/locale_en-US.ini
Expand Up @@ -1488,6 +1488,9 @@ pulls.desc = Enable pull requests and code reviews.
pulls.new = New Pull Request
pulls.view = View Pull Request
pulls.compare_changes = New Pull Request
pulls.allow_edits_from_maintainers = Allow edits from maintainers
pulls.allow_edits_from_maintainers_desc = Users with write access to the base branch can also push to this branch
pulls.allow_edits_from_maintainers_err = Updating failed
pulls.compare_changes_desc = Select the branch to merge into and the branch to pull from.
pulls.compare_base = merge into
pulls.compare_compare = pull from
Expand Down
17 changes: 13 additions & 4 deletions routers/api/v1/api.go
Expand Up @@ -283,6 +283,15 @@ func reqRepoWriter(unitTypes ...unit.Type) func(ctx *context.APIContext) {
}
}

// reqRepoBranchWriter user should have a permission to write to a branch, or be a site admin
func reqRepoBranchWriter(ctx *context.APIContext) {
options, ok := web.GetForm(ctx).(api.FileOptionInterface)
if !ok || (!ctx.Repo.CanWriteToBranch(ctx.Doer, options.Branch()) && !ctx.IsUserSiteAdmin()) {
ctx.Error(http.StatusForbidden, "reqRepoBranchWriter", "user should have a permission to write to this branch")
return
}
}

// reqRepoReader user should have specific read permission or be a repo admin or a site admin
func reqRepoReader(unitType unit.Type) func(ctx *context.APIContext) {
return func(ctx *context.APIContext) {
Expand Down Expand Up @@ -1021,10 +1030,10 @@ func Routes() *web.Route {
m.Get("", repo.GetContentsList)
m.Get("/*", repo.GetContents)
m.Group("/*", func() {
m.Post("", bind(api.CreateFileOptions{}), repo.CreateFile)
qwerty287 marked this conversation as resolved.
Show resolved Hide resolved
m.Put("", bind(api.UpdateFileOptions{}), repo.UpdateFile)
m.Delete("", bind(api.DeleteFileOptions{}), repo.DeleteFile)
}, reqRepoWriter(unit.TypeCode), reqToken())
m.Post("", bind(api.CreateFileOptions{}), reqRepoBranchWriter, repo.CreateFile)
qwerty287 marked this conversation as resolved.
Show resolved Hide resolved
m.Put("", bind(api.UpdateFileOptions{}), reqRepoBranchWriter, repo.UpdateFile)
m.Delete("", bind(api.DeleteFileOptions{}), reqRepoBranchWriter, repo.DeleteFile)
}, reqToken())
}, reqRepoReader(unit.TypeCode))
m.Get("/signing-key.gpg", misc.SigningKey)
m.Group("/topics", func() {
Expand Down
10 changes: 6 additions & 4 deletions routers/api/v1/repo/file.go
Expand Up @@ -173,8 +173,10 @@ func GetEditorconfig(ctx *context.APIContext) {
}

// canWriteFiles returns true if repository is editable and user has proper access level.
func canWriteFiles(r *context.Repository) bool {
return r.Permission.CanWrite(unit.TypeCode) && !r.Repository.IsMirror && !r.Repository.IsArchived
func canWriteFiles(ctx *context.APIContext, branch string) bool {
return ctx.Repo.Permission.CanWriteToBranch(ctx.Doer, branch) &&
!ctx.Repo.Repository.IsMirror &&
!ctx.Repo.Repository.IsArchived
}

// canReadFiles returns true if repository is readable and user has proper access level.
Expand Down Expand Up @@ -376,7 +378,7 @@ func handleCreateOrUpdateFileError(ctx *context.APIContext, err error) {

// Called from both CreateFile or UpdateFile to handle both
func createOrUpdateFile(ctx *context.APIContext, opts *files_service.UpdateRepoFileOptions) (*api.FileResponse, error) {
if !canWriteFiles(ctx.Repo) {
if !canWriteFiles(ctx, opts.OldBranch) {
return nil, models.ErrUserDoesNotHaveAccessToRepo{
UserID: ctx.Doer.ID,
RepoName: ctx.Repo.Repository.LowerName,
Expand Down Expand Up @@ -433,7 +435,7 @@ func DeleteFile(ctx *context.APIContext) {
// "$ref": "#/responses/error"

apiOpts := web.GetForm(ctx).(*api.DeleteFileOptions)
if !canWriteFiles(ctx.Repo) {
if !canWriteFiles(ctx, apiOpts.BranchName) {
ctx.Error(http.StatusForbidden, "DeleteFile", models.ErrUserDoesNotHaveAccessToRepo{
UserID: ctx.Doer.ID,
RepoName: ctx.Repo.Repository.LowerName,
Expand Down
2 changes: 1 addition & 1 deletion routers/api/v1/repo/patch.go
Expand Up @@ -77,7 +77,7 @@ func ApplyDiffPatch(ctx *context.APIContext) {
opts.Message = "apply-patch"
}

if !canWriteFiles(ctx.Repo) {
if !canWriteFiles(ctx, apiOpts.BranchName) {
ctx.Error(http.StatusInternalServerError, "ApplyPatch", models.ErrUserDoesNotHaveAccessToRepo{
UserID: ctx.Doer.ID,
RepoName: ctx.Repo.Repository.LowerName,
Expand Down
12 changes: 12 additions & 0 deletions routers/api/v1/repo/pull.go
Expand Up @@ -616,6 +616,18 @@ func EditPullRequest(ctx *context.APIContext) {
notification.NotifyPullRequestChangeTargetBranch(ctx.Doer, pr, form.Base)
}

// update allow edits
if form.AllowMaintainerEdit != nil {
if err := pull_service.SetAllowEdits(ctx, ctx.Doer, pr, *form.AllowMaintainerEdit); err != nil {
if errors.Is(pull_service.ErrUserHasNoPermissionForAction, err) {
ctx.Error(http.StatusForbidden, "SetAllowEdits", fmt.Sprintf("SetAllowEdits: %s", err))
return
}
ctx.ServerError("SetAllowEdits", err)
return
}
}

// Refetch from database
pr, err = models.GetPullRequestByIndex(ctx.Repo.Repository.ID, pr.Index)
if err != nil {
Expand Down