Skip to content

Commit 6d23290

Browse files
committed
Also support new/upload/patch/delete operations, refactor permissions
1 parent a9c552e commit 6d23290

File tree

16 files changed

+303
-207
lines changed

16 files changed

+303
-207
lines changed

models/repo/repo.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,7 @@ func (repo *Repository) AllowsPulls(ctx context.Context) bool {
644644

645645
// CanEnableEditor returns true if repository meets the requirements of web editor.
646646
func (repo *Repository) CanEnableEditor() bool {
647-
return !repo.IsMirror
647+
return !repo.IsMirror && !repo.IsArchived
648648
}
649649

650650
// DescriptionHTML does special handles to description and return HTML string.

routers/web/repo/editor.go

Lines changed: 215 additions & 147 deletions
Large diffs are not rendered by default.

routers/web/repo/patch.go

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,12 @@ const (
2424

2525
// NewDiffPatch render create patch page
2626
func NewDiffPatch(ctx *context.Context) {
27-
canCommit := renderCommitRights(ctx, ctx.Repo.Repository)
27+
editRepo := GetEditRepositoryOrFork(ctx, "_diffpatch")
28+
if editRepo == nil {
29+
return
30+
}
31+
32+
canCommit := renderCommitRights(ctx, editRepo)
2833

2934
ctx.Data["PageIsPatch"] = true
3035

@@ -35,7 +40,7 @@ func NewDiffPatch(ctx *context.Context) {
3540
} else {
3641
ctx.Data["commit_choice"] = frmCommitChoiceNewBranch
3742
}
38-
ctx.Data["new_branch_name"] = GetUniquePatchBranchName(ctx, ctx.Repo.Repository)
43+
ctx.Data["new_branch_name"] = GetUniquePatchBranchName(ctx, editRepo)
3944
ctx.Data["last_commit"] = ctx.Repo.CommitID
4045
ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",")
4146
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL()
@@ -47,7 +52,6 @@ func NewDiffPatch(ctx *context.Context) {
4752
func NewDiffPatchPost(ctx *context.Context) {
4853
form := web.GetForm(ctx).(*forms.EditRepoFileForm)
4954

50-
canCommit := renderCommitRights(ctx, ctx.Repo.Repository)
5155
branchName := ctx.Repo.BranchName
5256
if form.CommitChoice == frmCommitChoiceNewBranch {
5357
branchName = form.NewBranchName
@@ -67,11 +71,15 @@ func NewDiffPatchPost(ctx *context.Context) {
6771
return
6872
}
6973

74+
editRepo := GetEditRepositoryOrError(ctx, tplPatchFile, &form)
75+
if editRepo == nil {
76+
return
77+
}
78+
79+
canCommit := renderCommitRights(ctx, editRepo)
80+
7081
// Cannot commit to an existing branch if user doesn't have rights
71-
if branchName == ctx.Repo.BranchName && !canCommit {
72-
ctx.Data["Err_NewBranchName"] = true
73-
ctx.Data["commit_choice"] = frmCommitChoiceNewBranch
74-
ctx.RenderWithErr(ctx.Tr("repo.editor.cannot_commit_to_protected_branch", branchName), tplEditFile, &form)
82+
if !CheckCanPushEditBranch(ctx, editRepo, branchName, canCommit, tplPatchFile, &form) {
7583
return
7684
}
7785

@@ -94,9 +102,14 @@ func NewDiffPatchPost(ctx *context.Context) {
94102
return
95103
}
96104

97-
fileResponse, err := files.ApplyDiffPatch(ctx, ctx.Repo.Repository, ctx.Doer, &files.ApplyDiffPatchOptions{
105+
editBranchName, err := PushEditBranchOrError(ctx, editRepo, branchName, tplPatchFile, &form)
106+
if err != nil {
107+
return
108+
}
109+
110+
fileResponse, err := files.ApplyDiffPatch(ctx, editRepo, ctx.Doer, &files.ApplyDiffPatchOptions{
98111
LastCommitID: form.LastCommit,
99-
OldBranch: ctx.Repo.BranchName,
112+
OldBranch: editBranchName,
100113
NewBranch: branchName,
101114
Message: message,
102115
Content: strings.ReplaceAll(form.Content, "\r", ""),
@@ -119,7 +132,8 @@ func NewDiffPatchPost(ctx *context.Context) {
119132
}
120133

121134
if form.CommitChoice == frmCommitChoiceNewBranch && ctx.Repo.Repository.UnitEnabled(ctx, unit.TypePullRequests) {
122-
ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ctx.Repo.BranchName) + "..." + util.PathEscapeSegments(form.NewBranchName))
135+
editBranch := editRepo.Owner.Name + "/" + editRepo.Name + ":" + branchName
136+
ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ctx.Repo.BranchName) + "..." + util.PathEscapeSegments(editBranch))
123137
} else {
124138
ctx.Redirect(ctx.Repo.RepoLink + "/commit/" + fileResponse.Commit.SHA)
125139
}

routers/web/repo/repo.go

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -49,21 +49,6 @@ func MustBeNotEmpty(ctx *context.Context) {
4949
}
5050
}
5151

52-
// MustBeEditable check that repo can be edited
53-
func MustBeEditable(ctx *context.Context) {
54-
if !ctx.Repo.Repository.CanEnableEditor() {
55-
ctx.NotFound(nil)
56-
return
57-
}
58-
}
59-
60-
// MustBeAbleToUpload check that repo can be uploaded to
61-
func MustBeAbleToUpload(ctx *context.Context) {
62-
if !setting.Repository.Upload.Enabled {
63-
ctx.NotFound(nil)
64-
}
65-
}
66-
6752
func CommitInfoCache(ctx *context.Context) {
6853
var err error
6954
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch)

routers/web/repo/view_file.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) {
244244
ctx.Data["LineEscapeStatus"] = statuses
245245
}
246246
if !fInfo.isLFSFile {
247-
if ctx.Repo.CanEnableEditor(ctx, ctx.Doer) {
247+
if ctx.Repo.CanEnableEditor() {
248248
if lfsLock != nil && lfsLock.OwnerID != ctx.Doer.ID {
249249
ctx.Data["CanEditFile"] = false
250250
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.this_file_locked")
@@ -254,9 +254,6 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) {
254254
}
255255
} else if !ctx.Repo.RefFullName.IsBranch() {
256256
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.must_be_on_a_branch")
257-
} else if !ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.BranchName) {
258-
ctx.Data["CanEditFile"] = true
259-
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.edit_this_file")
260257
}
261258
}
262259

@@ -308,7 +305,7 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) {
308305
}
309306
}
310307

311-
if ctx.Repo.CanEnableEditor(ctx, ctx.Doer) {
308+
if ctx.Repo.CanEnableEditor() {
312309
if lfsLock != nil && lfsLock.OwnerID != ctx.Doer.ID {
313310
ctx.Data["CanDeleteFile"] = false
314311
ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.this_file_locked")
@@ -318,7 +315,5 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) {
318315
}
319316
} else if !ctx.Repo.RefFullName.IsBranch() {
320317
ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.must_be_on_a_branch")
321-
} else if !ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.BranchName) {
322-
ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.must_have_write_access")
323318
}
324319
}

routers/web/repo/view_readme.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ func prepareToRenderReadmeFile(ctx *context.Context, subfolder string, readmeFil
213213
}
214214

215215
if !fInfo.isLFSFile {
216-
if ctx.Repo.CanEnableEditor(ctx, ctx.Doer) || !ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.BranchName) {
216+
if ctx.Repo.CanEnableEditor() {
217217
ctx.Data["CanEditReadmeFile"] = true
218218
}
219219
}

routers/web/web.go

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,29 +1313,29 @@ func registerWebRoutes(m *web.Router) {
13131313

13141314
m.Group("/{username}/{reponame}", func() { // repo code
13151315
m.Group("", func() {
1316-
m.Group("", func() {
1317-
m.Combo("/_edit/*").Get(repo.EditFile).
1318-
Post(web.Bind(forms.EditRepoFileForm{}), repo.EditFilePost)
1319-
m.Combo("/_fork_to_edit/*").
1320-
Post(web.Bind(forms.ForkToEditRepoFileForm{}), repo.ForkToEditFilePost)
1321-
}, context.RepoRefByType(git.RefTypeBranch), repo.WebGitOperationCommonData)
13221316
m.Group("", func() {
13231317
m.Combo("/_new/*").Get(repo.NewFile).
13241318
Post(web.Bind(forms.EditRepoFileForm{}), repo.NewFilePost)
1319+
m.Combo("/_edit/*").Get(repo.EditFile).
1320+
Post(web.Bind(forms.EditRepoFileForm{}), repo.EditFilePost)
13251321
m.Combo("/_delete/*").Get(repo.DeleteFile).
13261322
Post(web.Bind(forms.DeleteRepoFileForm{}), repo.DeleteFilePost)
1327-
m.Combo("/_upload/*", repo.MustBeAbleToUpload).Get(repo.UploadFile).
1328-
Post(web.Bind(forms.UploadRepoFileForm{}), repo.UploadFilePost)
13291323
m.Combo("/_diffpatch/*").Get(repo.NewDiffPatch).
13301324
Post(web.Bind(forms.EditRepoFileForm{}), repo.NewDiffPatchPost)
1325+
m.Combo("/_upload/*", context.MustBeAbleToUpload()).Get(repo.UploadFile).
1326+
Post(web.Bind(forms.UploadRepoFileForm{}), repo.UploadFilePost)
1327+
m.Combo("/_fork_to_edit/*").
1328+
Post(web.Bind(forms.ForkToEditRepoFileForm{}), repo.ForkToEditFilePost)
1329+
}, context.MustEnableEditor())
1330+
m.Group("", func() {
13311331
m.Combo("/_cherrypick/{sha:([a-f0-9]{7,64})}/*").Get(repo.CherryPick).
13321332
Post(web.Bind(forms.CherryPickForm{}), repo.CherryPickPost)
1333-
}, context.RepoRefByType(git.RefTypeBranch), context.CanWriteToBranch(), repo.WebGitOperationCommonData)
1334-
m.Group("", func() {
1335-
m.Post("/upload-file", repo.UploadFileToServer)
1336-
m.Post("/upload-remove", web.Bind(forms.RemoveUploadFileForm{}), repo.RemoveUploadFileFromServer)
1337-
}, repo.MustBeAbleToUpload, reqRepoCodeWriter)
1338-
}, repo.MustBeEditable, context.RepoMustNotBeArchived())
1333+
}, context.MustBeAbleToCherryPick())
1334+
}, context.RepoRefByType(git.RefTypeBranch), repo.WebGitOperationCommonData)
1335+
m.Group("", func() {
1336+
m.Post("/upload-file", repo.UploadFileToServer)
1337+
m.Post("/upload-remove", web.Bind(forms.RemoveUploadFileForm{}), repo.RemoveUploadFileFromServer)
1338+
}, context.MustBeAbleToUpload())
13391339

13401340
m.Group("/branches", func() {
13411341
m.Group("/_new", func() {

services/context/permission.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ func RequireRepoAdmin() func(ctx *Context) {
2121
}
2222
}
2323

24-
// CanWriteToBranch checks if the user is allowed to write to the branch of the repo
25-
func CanWriteToBranch() func(ctx *Context) {
24+
// MustBeAbleToCherryPick checks if the user is allowed to cherry-pick to a branch of the repo
25+
func MustBeAbleToCherryPick() func(ctx *Context) {
2626
return func(ctx *Context) {
27-
if !ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.BranchName) {
27+
if !ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.BranchName) || !ctx.Repo.Repository.CanEnableEditor() {
2828
ctx.NotFound(nil)
2929
return
3030
}

services/context/repo.go

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,10 @@ func (r *Repository) CanWriteToBranch(ctx context.Context, user *user_model.User
7171
return issues_model.CanMaintainerWriteToBranch(ctx, r.Permission, branch, user)
7272
}
7373

74-
// CanEnableEditor returns true if repository is editable and user has proper access level.
75-
func (r *Repository) CanEnableEditor(ctx context.Context, user *user_model.User) bool {
76-
return r.RefFullName.IsBranch() && r.CanWriteToBranch(ctx, user, r.BranchName) && r.Repository.CanEnableEditor() && !r.Repository.IsArchived
74+
// CanEnableEditor returns true if the web editor can be enabled for this repository,
75+
// either by directly writing to the repository or to a user fork.
76+
func (r *Repository) CanEnableEditor() bool {
77+
return r.RefFullName.IsBranch() && r.Repository.CanEnableEditor()
7778
}
7879

7980
// CanCreateBranch returns true if repository is editable and user has proper access level.
@@ -94,10 +95,27 @@ func RepoMustNotBeArchived() func(ctx *Context) {
9495
}
9596
}
9697

98+
// MustEnableEditor checks if the web editor can be enabled for this repository
99+
func MustEnableEditor() func(ctx *Context) {
100+
return func(ctx *Context) {
101+
if !ctx.Repo.CanEnableEditor() {
102+
ctx.NotFound(nil)
103+
}
104+
}
105+
}
106+
107+
// MustBeAbleToUpload check that upload is enabled on this site and useful for editing
108+
func MustBeAbleToUpload() func(ctx *Context) {
109+
return func(ctx *Context) {
110+
if !setting.Repository.Upload.Enabled || !ctx.Repo.Repository.CanEnableEditor() {
111+
ctx.NotFound(nil)
112+
}
113+
}
114+
}
115+
97116
// CanCommitToBranchResults represents the results of CanCommitToBranch
98117
type CanCommitToBranchResults struct {
99118
CanCommitToBranch bool
100-
EditorEnabled bool
101119
UserCanPush bool
102120
RequireSigned bool
103121
WillSign bool
@@ -123,7 +141,7 @@ func (r *Repository) CanCommitToBranch(ctx context.Context, doer *user_model.Use
123141

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

126-
canCommit := r.CanEnableEditor(ctx, doer) && userCanPush
144+
canCommit := r.CanEnableEditor() && r.CanWriteToBranch(ctx, doer, r.BranchName) && userCanPush
127145
if requireSigned {
128146
canCommit = canCommit && sign
129147
}
@@ -139,7 +157,6 @@ func (r *Repository) CanCommitToBranch(ctx context.Context, doer *user_model.Use
139157

140158
return CanCommitToBranchResults{
141159
CanCommitToBranch: canCommit,
142-
EditorEnabled: r.CanEnableEditor(ctx, doer),
143160
UserCanPush: userCanPush,
144161
RequireSigned: requireSigned,
145162
WillSign: sign,

services/forms/repo_form.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,8 @@ func (f *EditPreviewDiffForm) Validate(req *http.Request, errs binding.Errors) b
735735

736736
// ForkToEditRepoFileForm form for forking the repo to edit a file
737737
type ForkToEditRepoFileForm struct {
738-
TreePath string `binding:"Required;MaxSize(500)"`
738+
TreePath string `binding:"Required;MaxSize(500)"`
739+
EditOperation string `binding:"Required;MaxSize(20)"`
739740
}
740741

741742
// Validate validates the fields

0 commit comments

Comments
 (0)