diff --git a/models/repo/repo.go b/models/repo/repo.go index 238a6d95a3f..eecd7133cf6 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -575,14 +575,13 @@ func (repo *Repository) IsOwnedBy(userID int64) bool { return repo.OwnerID == userID } -// CanCreateBranch returns true if repository meets the requirements for creating new branches. -func (repo *Repository) CanCreateBranch() bool { - return !repo.IsMirror -} - // CanEnablePulls returns true if repository meets the requirements of accepting pulls. func (repo *Repository) CanEnablePulls() bool { - return !repo.IsMirror && !repo.IsEmpty + return repo.CanContentChange() && !repo.IsEmpty +} + +func (repo *Repository) CanContentChange() bool { + return !repo.IsMirror && !repo.IsArchived } // AllowsPulls returns true if repository meets the requirements of accepting pulls and has them enabled. @@ -590,17 +589,6 @@ func (repo *Repository) AllowsPulls(ctx context.Context) bool { return repo.CanEnablePulls() && repo.UnitEnabled(ctx, unit.TypePullRequests) } -// CanEnableEditor returns true if repository meets the requirements of web editor. -// FIXME: most CanEnableEditor calls should be replaced with CanContentChange -// And all other like CanCreateBranch / CanEnablePulls should also be updated -func (repo *Repository) CanEnableEditor() bool { - return repo.CanContentChange() -} - -func (repo *Repository) CanContentChange() bool { - return !repo.IsMirror && !repo.IsArchived -} - // DescriptionHTML does special handles to description and return HTML string. func (repo *Repository) DescriptionHTML(ctx context.Context) template.HTML { return markup.PostProcessDescriptionHTML(markup.NewRenderContext(ctx), htmlutil.EscapeString(repo.Description)) diff --git a/options/locale/locale_en-US.json b/options/locale/locale_en-US.json index 6cb8a033a0e..a887742a6e4 100644 --- a/options/locale/locale_en-US.json +++ b/options/locale/locale_en-US.json @@ -1324,7 +1324,9 @@ "repo.editor.upload_files_to_dir": "Upload files to \"%s\"", "repo.editor.cannot_commit_to_protected_branch": "Cannot commit to protected branch \"%s\".", "repo.editor.no_commit_to_branch": "Not allowed to commit directly to branch because:", - "repo.editor.user_no_push_to_branch": "User cannot push to branch", + "repo.editor.no_write_permission": "No write permission.", + "repo.editor.repo_not_editable": "Repository is not editable.", + "repo.editor.branch_is_protected": "Branch is protected", "repo.editor.require_signed_commit": "Branch requires a signed commit", "repo.editor.cherry_pick": "Cherry-pick %s onto:", "repo.editor.revert": "Revert %s onto:", diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 51fca8e85c6..d1219fc4d3d 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -874,7 +874,7 @@ func mustNotBeArchived(ctx *context.APIContext) { } func mustEnableEditor(ctx *context.APIContext) { - if !ctx.Repo.Repository.CanEnableEditor() { + if !ctx.Repo.Repository.CanContentChange() { ctx.APIError(http.StatusLocked, "repo is not allowed to edit") return } diff --git a/routers/web/repo/editor.go b/routers/web/repo/editor.go index d0f6e7db72e..d65186e3f50 100644 --- a/routers/web/repo/editor.go +++ b/routers/web/repo/editor.go @@ -67,7 +67,7 @@ func prepareEditorPageFormOptions(ctx *context.Context, editorAction string) *co return nil } - if commitFormOptions.WillSubmitToFork && !commitFormOptions.TargetRepo.CanEnableEditor() { + if commitFormOptions.WillSubmitToFork && !commitFormOptions.TargetRepo.CanContentChange() { ctx.Data["NotFoundPrompt"] = ctx.Locale.Tr("repo.editor.fork_not_editable") ctx.NotFound(nil) } diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index 43fb14c2d95..4da2f8484c7 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -49,7 +49,7 @@ func MustBeNotEmpty(ctx *context.Context) { // MustBeEditable check that repo can be edited func MustBeEditable(ctx *context.Context) { - if !ctx.Repo.Repository.CanEnableEditor() { + if !ctx.Repo.Repository.CanContentChange() { ctx.NotFound(nil) return } diff --git a/routers/web/repo/view_file.go b/routers/web/repo/view_file.go index dac82ae7ac6..dead532c74d 100644 --- a/routers/web/repo/view_file.go +++ b/routers/web/repo/view_file.go @@ -255,7 +255,7 @@ func prepareFileView(ctx *context.Context, entry *git.TreeEntry) { func prepareFileViewEditorButtons(ctx *context.Context) bool { // archived or mirror repository, the buttons should not be shown - if !ctx.Repo.Repository.CanEnableEditor() { + if !ctx.Repo.Repository.CanContentChange() { return true } diff --git a/routers/web/repo/view_readme.go b/routers/web/repo/view_readme.go index 69fa95ef9f7..3341c3b1388 100644 --- a/routers/web/repo/view_readme.go +++ b/routers/web/repo/view_readme.go @@ -220,7 +220,7 @@ func prepareToRenderReadmeFile(ctx *context.Context, subfolder string, readmeFil ctx.Data["EscapeStatus"], ctx.Data["FileContent"] = charset.EscapeControlHTML(template.HTML(contentEscaped), ctx.Locale) } - if !fInfo.isLFSFile() && ctx.Repo.Repository.CanEnableEditor() { + if !fInfo.isLFSFile() && ctx.Repo.Repository.CanContentChange() { ctx.Data["CanEditReadmeFile"] = true } } diff --git a/services/context/repo.go b/services/context/repo.go index 0d0fafc4a64..b54e1c4641e 100644 --- a/services/context/repo.go +++ b/services/context/repo.go @@ -9,6 +9,7 @@ import ( "errors" "fmt" "html" + "html/template" "net/http" "net/url" "path" @@ -124,7 +125,7 @@ func (r *Repository) CanWriteToBranch(ctx context.Context, user *user_model.User // CanCreateBranch returns true if repository is editable and user has proper access level. func (r *Repository) CanCreateBranch() bool { - return r.Permission.CanWrite(unit_model.TypeCode) && r.Repository.CanCreateBranch() + return r.Permission.CanWrite(unit_model.TypeCode) && r.Repository.CanContentChange() } func (r *Repository) GetObjectFormat() git.ObjectFormat { @@ -143,15 +144,18 @@ func RepoMustNotBeArchived() func(ctx *Context) { type CommitFormOptions struct { NeedFork bool - TargetRepo *repo_model.Repository - TargetFormAction string - WillSubmitToFork bool + TargetRepo *repo_model.Repository + TargetFormAction string + + WillSubmitToFork bool + CanCommitToBranch bool - UserCanPush bool - RequireSigned bool - WillSign bool - SigningKeyFormDisplay string - WontSignReason string + DenyCommitToBranchReason template.HTML + + WillSign bool + SigningKeyFormDisplay string + WontSignReason string + CanCreatePullRequest bool CanCreateBasePullRequest bool } @@ -172,7 +176,7 @@ func PrepareCommitFormOptions(ctx *Context, doer *user_model.User, targetRepo *r } // now, we get our own forked repo; it must be writable by us. } - submitToForkedRepo := targetRepo.ID != originRepo.ID + err := targetRepo.GetBaseRepo(ctx) if err != nil { return nil, err @@ -214,20 +218,14 @@ func PrepareCommitFormOptions(ctx *Context, doer *user_model.User, targetRepo *r return nil, err } - canCommitToBranch := !submitToForkedRepo /* same repo */ && targetRepo.CanEnableEditor() && canPushWithProtection - if protectionRequireSigned { - canCommitToBranch = canCommitToBranch && willSign - } - canCreateBasePullRequest := targetRepo.BaseRepo != nil && targetRepo.BaseRepo.UnitEnabled(ctx, unit_model.TypePullRequests) canCreatePullRequest := targetRepo.UnitEnabled(ctx, unit_model.TypePullRequests) || canCreateBasePullRequest opts := &CommitFormOptions{ - TargetRepo: targetRepo, - WillSubmitToFork: submitToForkedRepo, - CanCommitToBranch: canCommitToBranch, - UserCanPush: canPushWithProtection, - RequireSigned: protectionRequireSigned, + TargetRepo: targetRepo, + + WillSubmitToFork: targetRepo.ID != originRepo.ID, + WillSign: willSign, SigningKeyFormDisplay: asymkey_model.GetDisplaySigningKey(signKey), WontSignReason: wontSignReason, @@ -235,12 +233,28 @@ func PrepareCommitFormOptions(ctx *Context, doer *user_model.User, targetRepo *r CanCreatePullRequest: canCreatePullRequest, CanCreateBasePullRequest: canCreateBasePullRequest, } + editorAction := ctx.PathParam("editor_action") editorPathParamRemaining := util.PathEscapeSegments(branchName) + "/" + util.PathEscapeSegments(ctx.Repo.TreePath) - if submitToForkedRepo { + + opts.CanCommitToBranch = false + if opts.WillSubmitToFork { + opts.DenyCommitToBranchReason = ctx.Locale.Tr("repo.editor.no_write_permission") // there is only "default branch" in forked repo, we will use "from_base_branch" to get a new branch from base repo editorPathParamRemaining = util.PathEscapeSegments(targetRepo.DefaultBranch) + "/" + util.PathEscapeSegments(ctx.Repo.TreePath) + "?from_base_branch=" + url.QueryEscape(branchName) + } else { + // if the user is committing to the same repo, we need to check if the branch is protected and if the user can push to it + if !targetRepo.CanContentChange() { + opts.DenyCommitToBranchReason = ctx.Locale.Tr("repo.editor.repo_not_editable") + } else if !canPushWithProtection { + opts.DenyCommitToBranchReason = ctx.Locale.Tr("repo.editor.branch_is_protected") + } else if protectionRequireSigned && !willSign { + opts.DenyCommitToBranchReason = ctx.Locale.Tr("repo.editor.require_signed_commit") + } else { + opts.CanCommitToBranch = true + } } + if editorAction == "_cherrypick" { opts.TargetFormAction = targetRepo.Link() + "/" + editorAction + "/" + ctx.PathParam("sha") + "/" + editorPathParamRemaining } else { diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl index 52204947d7c..3b329b1b2dc 100644 --- a/templates/repo/diff/box.tmpl +++ b/templates/repo/diff/box.tmpl @@ -160,7 +160,7 @@ {{ctx.Locale.Tr "repo.diff.view_file"}} {{else}} {{ctx.Locale.Tr "repo.diff.view_file"}} - {{if and $.Repository.CanEnableEditor $.CanEditFile}} + {{if and $.Repository.CanContentChange $.CanEditFile}} {{ctx.Locale.Tr "repo.editor.edit_this_file"}} {{end}} {{end}} diff --git a/templates/repo/editor/commit_form.tmpl b/templates/repo/editor/commit_form.tmpl index d0c47e9bdd9..b3aa359947c 100644 --- a/templates/repo/editor/commit_form.tmpl +++ b/templates/repo/editor/commit_form.tmpl @@ -32,10 +32,9 @@ {{if not .CommitFormOptions.CanCommitToBranch}}
{{ctx.Locale.Tr "repo.editor.no_commit_to_branch"}} - + {{if .CommitFormOptions.DenyCommitToBranchReason}} + + {{end}}
{{end}} diff --git a/templates/repo/view_content.tmpl b/templates/repo/view_content.tmpl index b42690b6d20..4b9e71ddb83 100644 --- a/templates/repo/view_content.tmpl +++ b/templates/repo/view_content.tmpl @@ -70,7 +70,7 @@ {{$addFilePath = ""}} {{end}} {{end}} -