diff options
Diffstat (limited to 'routers/repo')
-rw-r--r-- | routers/repo/activity.go | 6 | ||||
-rw-r--r-- | routers/repo/branch.go | 5 | ||||
-rw-r--r-- | routers/repo/http.go | 37 | ||||
-rw-r--r-- | routers/repo/issue.go | 187 | ||||
-rw-r--r-- | routers/repo/issue_watch.go | 25 | ||||
-rw-r--r-- | routers/repo/pull.go | 24 | ||||
-rw-r--r-- | routers/repo/release.go | 6 | ||||
-rw-r--r-- | routers/repo/setting_protected_branch.go | 17 | ||||
-rw-r--r-- | routers/repo/view.go | 10 | ||||
-rw-r--r-- | routers/repo/wiki.go | 13 |
10 files changed, 193 insertions, 137 deletions
diff --git a/routers/repo/activity.go b/routers/repo/activity.go index a0a25dc936..5d90d73506 100644 --- a/routers/repo/activity.go +++ b/routers/repo/activity.go @@ -45,9 +45,9 @@ func Activity(ctx *context.Context) { var err error if ctx.Data["Activity"], err = models.GetActivityStats(ctx.Repo.Repository.ID, timeFrom, - ctx.Repo.Repository.UnitEnabled(models.UnitTypeReleases), - ctx.Repo.Repository.UnitEnabled(models.UnitTypeIssues), - ctx.Repo.Repository.UnitEnabled(models.UnitTypePullRequests)); err != nil { + ctx.Repo.CanRead(models.UnitTypeReleases), + ctx.Repo.CanRead(models.UnitTypeIssues), + ctx.Repo.CanRead(models.UnitTypePullRequests)); err != nil { ctx.ServerError("GetActivityStats", err) return } diff --git a/routers/repo/branch.go b/routers/repo/branch.go index 7b1e2a8bbe..295aeaa24b 100644 --- a/routers/repo/branch.go +++ b/routers/repo/branch.go @@ -1,4 +1,5 @@ // Copyright 2014 The Gogs Authors. All rights reserved. +// Copyright 2018 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. @@ -33,7 +34,7 @@ func Branches(ctx *context.Context) { ctx.Data["Title"] = "Branches" ctx.Data["IsRepoToolbarBranches"] = true ctx.Data["DefaultBranch"] = ctx.Repo.Repository.DefaultBranch - ctx.Data["IsWriter"] = ctx.Repo.IsWriter() + ctx.Data["IsWriter"] = ctx.Repo.CanWrite(models.UnitTypeCode) ctx.Data["IsMirror"] = ctx.Repo.Repository.IsMirror ctx.Data["PageIsViewCode"] = true ctx.Data["PageIsBranches"] = true @@ -161,7 +162,7 @@ func loadBranches(ctx *context.Context) []*Branch { } } - if ctx.Repo.IsWriter() { + if ctx.Repo.CanWrite(models.UnitTypeCode) { deletedBranches, err := getDeletedBranches(ctx) if err != nil { ctx.ServerError("getDeletedBranches", err) diff --git a/routers/repo/http.go b/routers/repo/http.go index 5b469754ad..ec5fbe6c0d 100644 --- a/routers/repo/http.go +++ b/routers/repo/http.go @@ -182,36 +182,19 @@ func HTTP(ctx *context.Context) { } } - if !isPublicPull { - has, err := models.HasAccess(authUser.ID, repo, accessMode) - if err != nil { - ctx.ServerError("HasAccess", err) - return - } else if !has { - if accessMode == models.AccessModeRead { - has, err = models.HasAccess(authUser.ID, repo, models.AccessModeWrite) - if err != nil { - ctx.ServerError("HasAccess2", err) - return - } else if !has { - ctx.HandleText(http.StatusForbidden, "User permission denied") - return - } - } else { - ctx.HandleText(http.StatusForbidden, "User permission denied") - return - } - } + perm, err := models.GetUserRepoPermission(repo, authUser) + if err != nil { + ctx.ServerError("GetUserRepoPermission", err) + return + } - if !isPull && repo.IsMirror { - ctx.HandleText(http.StatusForbidden, "mirror repository is read-only") - return - } + if !perm.CanAccess(accessMode, unitType) { + ctx.HandleText(http.StatusForbidden, "User permission denied") + return } - if !repo.CheckUnitUser(authUser.ID, authUser.IsAdmin, unitType) { - ctx.HandleText(http.StatusForbidden, fmt.Sprintf("User %s does not have allowed access to repository %s 's code", - authUser.Name, repo.RepoPath())) + if !isPull && repo.IsMirror { + ctx.HandleText(http.StatusForbidden, "mirror repository is read-only") return } diff --git a/routers/repo/issue.go b/routers/repo/issue.go index 08bdf311f9..8d95f33940 100644 --- a/routers/repo/issue.go +++ b/routers/repo/issue.go @@ -1,4 +1,5 @@ // Copyright 2014 The Gogs Authors. All rights reserved. +// Copyright 2018 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. @@ -63,8 +64,8 @@ var ( // MustEnableIssues check if repository enable internal issues func MustEnableIssues(ctx *context.Context) { - if !ctx.Repo.Repository.UnitEnabled(models.UnitTypeIssues) && - !ctx.Repo.Repository.UnitEnabled(models.UnitTypeExternalTracker) { + if !ctx.Repo.CanRead(models.UnitTypeIssues) && + !ctx.Repo.CanRead(models.UnitTypeExternalTracker) { ctx.NotFound("MustEnableIssues", nil) return } @@ -76,9 +77,9 @@ func MustEnableIssues(ctx *context.Context) { } } -// MustAllowPulls check if repository enable pull requests +// MustAllowPulls check if repository enable pull requests and user have right to do that func MustAllowPulls(ctx *context.Context) { - if !ctx.Repo.Repository.AllowsPulls() { + if !ctx.Repo.Repository.CanEnablePulls() || !ctx.Repo.CanRead(models.UnitTypePullRequests) { ctx.NotFound("MustAllowPulls", nil) return } @@ -280,7 +281,7 @@ func RetrieveRepoMilestonesAndAssignees(ctx *context.Context, repo *models.Repos // RetrieveRepoMetas find all the meta information of a repository func RetrieveRepoMetas(ctx *context.Context, repo *models.Repository) []*models.Label { - if !ctx.Repo.IsWriter() { + if !ctx.Repo.CanWrite(models.UnitTypeIssues) { return nil } @@ -369,7 +370,7 @@ func NewIssue(ctx *context.Context) { } // ValidateRepoMetas check and returns repository's meta informations -func ValidateRepoMetas(ctx *context.Context, form auth.CreateIssueForm) ([]int64, []int64, int64) { +func ValidateRepoMetas(ctx *context.Context, form auth.CreateIssueForm, isPull bool) ([]int64, []int64, int64) { var ( repo = ctx.Repo.Repository err error @@ -380,10 +381,6 @@ func ValidateRepoMetas(ctx *context.Context, form auth.CreateIssueForm) ([]int64 return nil, nil, 0 } - if !ctx.Repo.IsWriter() { - return nil, nil, 0 - } - var labelIDs []int64 hasSelected := false // Check labels. @@ -427,9 +424,19 @@ func ValidateRepoMetas(ctx *context.Context, form auth.CreateIssueForm) ([]int64 // Check if the passed assignees actually exists and has write access to the repo for _, aID := range assigneeIDs { - _, err = repo.GetUserIfHasWriteAccess(aID) + user, err := models.GetUserByID(aID) + if err != nil { + ctx.ServerError("GetUserByID", err) + return nil, nil, 0 + } + + perm, err := models.GetUserRepoPermission(repo, user) if err != nil { - ctx.ServerError("GetUserIfHasWriteAccess", err) + ctx.ServerError("GetUserRepoPermission", err) + return nil, nil, 0 + } + if !perm.CanWriteIssuesOrPulls(isPull) { + ctx.ServerError("CanWriteIssuesOrPulls", fmt.Errorf("No permission for %s", user.Name)) return nil, nil, 0 } } @@ -458,7 +465,7 @@ func NewIssuePost(ctx *context.Context, form auth.CreateIssueForm) { attachments []string ) - labelIDs, assigneeIDs, milestoneID := ValidateRepoMetas(ctx, form) + labelIDs, assigneeIDs, milestoneID := ValidateRepoMetas(ctx, form, false) if ctx.Written() { return } @@ -498,31 +505,23 @@ func NewIssuePost(ctx *context.Context, form auth.CreateIssueForm) { // commentTag returns the CommentTag for a comment in/with the given repo, poster and issue func commentTag(repo *models.Repository, poster *models.User, issue *models.Issue) (models.CommentTag, error) { - if repo.IsOwnedBy(poster.ID) { - return models.CommentTagOwner, nil - } else if repo.Owner.IsOrganization() { - isOwner, err := repo.Owner.IsOwnedBy(poster.ID) - if err != nil { - return models.CommentTagNone, err - } else if isOwner { - return models.CommentTagOwner, nil - } + perm, err := models.GetUserRepoPermission(repo, poster) + if err != nil { + return models.CommentTagNone, err } - if poster.IsWriterOfRepo(repo) { - return models.CommentTagWriter, nil + if perm.IsOwner() { + return models.CommentTagOwner, nil } else if poster.ID == issue.PosterID { return models.CommentTagPoster, nil + } else if perm.CanWrite(models.UnitTypeCode) { + return models.CommentTagWriter, nil } + return models.CommentTagNone, nil } // ViewIssue render issue view page func ViewIssue(ctx *context.Context) { - ctx.Data["RequireHighlightJS"] = true - ctx.Data["RequireDropzone"] = true - ctx.Data["RequireTribute"] = true - renderAttachmentSettings(ctx) - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrIssueNotExist(err) { @@ -532,25 +531,6 @@ func ViewIssue(ctx *context.Context) { } return } - ctx.Data["Title"] = fmt.Sprintf("#%d - %s", issue.Index, issue.Title) - - var iw *models.IssueWatch - var exists bool - if ctx.User != nil { - iw, exists, err = models.GetIssueWatch(ctx.User.ID, issue.ID) - if err != nil { - ctx.ServerError("GetIssueWatch", err) - return - } - if !exists { - iw = &models.IssueWatch{ - UserID: ctx.User.ID, - IssueID: issue.ID, - IsWatching: models.IsWatching(ctx.User.ID, ctx.Repo.Repository.ID), - } - } - } - ctx.Data["IssueWatch"] = iw // Make sure type and URL matches. if ctx.Params(":type") == "issues" && issue.IsPull { @@ -576,6 +556,31 @@ func ViewIssue(ctx *context.Context) { ctx.Data["PageIsIssueList"] = true } + ctx.Data["RequireHighlightJS"] = true + ctx.Data["RequireDropzone"] = true + ctx.Data["RequireTribute"] = true + renderAttachmentSettings(ctx) + + ctx.Data["Title"] = fmt.Sprintf("#%d - %s", issue.Index, issue.Title) + + var iw *models.IssueWatch + var exists bool + if ctx.User != nil { + iw, exists, err = models.GetIssueWatch(ctx.User.ID, issue.ID) + if err != nil { + ctx.ServerError("GetIssueWatch", err) + return + } + if !exists { + iw = &models.IssueWatch{ + UserID: ctx.User.ID, + IssueID: issue.ID, + IsWatching: models.IsWatching(ctx.User.ID, ctx.Repo.Repository.ID), + } + } + } + ctx.Data["IssueWatch"] = iw + issue.RenderedContent = string(markdown.Render([]byte(issue.Content), ctx.Repo.RepoLink, ctx.Repo.Repository.ComposeMetas())) @@ -616,7 +621,7 @@ func ViewIssue(ctx *context.Context) { ctx.Data["Labels"] = labels // Check milestone and assignee. - if ctx.Repo.IsWriter() { + if ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) { RetrieveRepoMilestonesAndAssignees(ctx, repo) if ctx.Written() { return @@ -761,13 +766,20 @@ func ViewIssue(ctx *context.Context) { if ctx.IsSigned { if err := pull.GetHeadRepo(); err != nil { log.Error(4, "GetHeadRepo: %v", err) - } else if pull.HeadRepo != nil && pull.HeadBranch != pull.HeadRepo.DefaultBranch && ctx.User.IsWriterOfRepo(pull.HeadRepo) { - // Check if branch is not protected - if protected, err := pull.HeadRepo.IsProtectedBranch(pull.HeadBranch, ctx.User); err != nil { - log.Error(4, "IsProtectedBranch: %v", err) - } else if !protected { - canDelete = true - ctx.Data["DeleteBranchLink"] = ctx.Repo.RepoLink + "/pulls/" + com.ToStr(issue.Index) + "/cleanup" + } else if pull.HeadRepo != nil && pull.HeadBranch != pull.HeadRepo.DefaultBranch { + perm, err := models.GetUserRepoPermission(pull.HeadRepo, ctx.User) + if err != nil { + ctx.ServerError("GetUserRepoPermission", err) + return + } + if perm.CanWrite(models.UnitTypeCode) { + // Check if branch is not protected + if protected, err := pull.HeadRepo.IsProtectedBranch(pull.HeadBranch, ctx.User); err != nil { + log.Error(4, "IsProtectedBranch: %v", err) + } else if !protected { + canDelete = true + ctx.Data["DeleteBranchLink"] = ctx.Repo.RepoLink + "/pulls/" + com.ToStr(issue.Index) + "/cleanup" + } } } } @@ -779,7 +791,7 @@ func ViewIssue(ctx *context.Context) { } prConfig := prUnit.PullRequestsConfig() - ctx.Data["AllowMerge"] = ctx.Data["IsRepositoryWriter"] + ctx.Data["AllowMerge"] = ctx.Repo.CanWrite(models.UnitTypeCode) if err := pull.CheckUserAllowedToMerge(ctx.User); err != nil { if !models.IsErrNotAllowedToMerge(err) { ctx.ServerError("CheckUserAllowedToMerge", err) @@ -818,8 +830,9 @@ func ViewIssue(ctx *context.Context) { ctx.Data["NumParticipants"] = len(participants) ctx.Data["Issue"] = issue ctx.Data["ReadOnly"] = true - ctx.Data["IsIssueOwner"] = ctx.Repo.IsWriter() || (ctx.IsSigned && issue.IsPoster(ctx.User.ID)) ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login?redirect_to=" + ctx.Data["Link"].(string) + ctx.Data["IsIssuePoster"] = ctx.IsSigned && issue.IsPoster(ctx.User.ID) + ctx.Data["IsIssueWriter"] = ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) ctx.HTML(200, tplIssueView) } @@ -842,8 +855,8 @@ func GetActionIssue(ctx *context.Context) *models.Issue { } func checkIssueRights(ctx *context.Context, issue *models.Issue) { - if issue.IsPull && !ctx.Repo.Repository.UnitEnabled(models.UnitTypePullRequests) || - !issue.IsPull && !ctx.Repo.Repository.UnitEnabled(models.UnitTypeIssues) { + if issue.IsPull && !ctx.Repo.CanRead(models.UnitTypePullRequests) || + !issue.IsPull && !ctx.Repo.CanRead(models.UnitTypeIssues) { ctx.NotFound("IssueOrPullRequestUnitNotAllowed", nil) } } @@ -868,8 +881,8 @@ func getActionIssues(ctx *context.Context) []*models.Issue { return nil } // Check access rights for all issues - issueUnitEnabled := ctx.Repo.Repository.UnitEnabled(models.UnitTypeIssues) - prUnitEnabled := ctx.Repo.Repository.UnitEnabled(models.UnitTypePullRequests) + issueUnitEnabled := ctx.Repo.CanRead(models.UnitTypeIssues) + prUnitEnabled := ctx.Repo.CanRead(models.UnitTypePullRequests) for _, issue := range issues { if issue.IsPull && !prUnitEnabled || !issue.IsPull && !issueUnitEnabled { ctx.NotFound("IssueOrPullRequestUnitNotAllowed", nil) @@ -890,7 +903,7 @@ func UpdateIssueTitle(ctx *context.Context) { return } - if !ctx.IsSigned || (!issue.IsPoster(ctx.User.ID) && !ctx.Repo.IsWriter()) { + if !ctx.IsSigned || (!issue.IsPoster(ctx.User.ID) && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)) { ctx.Error(403) return } @@ -918,7 +931,7 @@ func UpdateIssueContent(ctx *context.Context) { return } - if !ctx.IsSigned || (ctx.User.ID != issue.PosterID && !ctx.Repo.IsWriter()) { + if !ctx.IsSigned || (ctx.User.ID != issue.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)) { ctx.Error(403) return } @@ -1037,6 +1050,11 @@ func NewComment(ctx *context.Context, form auth.CreateCommentForm) { return } + if !ctx.IsSigned || (ctx.User.ID != issue.PosterID && !ctx.Repo.CanReadIssuesOrPulls(issue.IsPull)) { + ctx.Error(403) + return + } + var attachments []string if setting.AttachmentEnabled { attachments = form.Files @@ -1051,7 +1069,7 @@ func NewComment(ctx *context.Context, form auth.CreateCommentForm) { var comment *models.Comment defer func() { // Check if issue admin/poster changes the status of issue. - if (ctx.Repo.IsWriter() || (ctx.IsSigned && issue.IsPoster(ctx.User.ID))) && + if (ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) || (ctx.IsSigned && issue.IsPoster(ctx.User.ID))) && (form.Status == "reopen" || form.Status == "close") && !(issue.IsPull && issue.PullRequest.HasMerged) { @@ -1140,7 +1158,12 @@ func UpdateCommentContent(ctx *context.Context) { return } - if !ctx.IsSigned || (ctx.User.ID != comment.PosterID && !ctx.Repo.IsAdmin()) { + if err := comment.LoadIssue(); err != nil { + ctx.NotFoundOrServerError("LoadIssue", models.IsErrIssueNotExist, err) + return + } + + if !ctx.IsSigned || (ctx.User.ID != comment.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)) { ctx.Error(403) return } else if comment.Type != models.CommentTypeComment && comment.Type != models.CommentTypeCode { @@ -1174,7 +1197,12 @@ func DeleteComment(ctx *context.Context) { return } - if !ctx.IsSigned || (ctx.User.ID != comment.PosterID && !ctx.Repo.IsAdmin()) { + if err := comment.LoadIssue(); err != nil { + ctx.NotFoundOrServerError("LoadIssue", models.IsErrIssueNotExist, err) + return + } + + if !ctx.IsSigned || (ctx.User.ID != comment.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)) { ctx.Error(403) return } else if comment.Type != models.CommentTypeComment && comment.Type != models.CommentTypeCode { @@ -1417,6 +1445,11 @@ func ChangeIssueReaction(ctx *context.Context, form auth.ReactionForm) { return } + if !ctx.IsSigned || (ctx.User.ID != issue.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)) { + ctx.Error(403) + return + } + if ctx.HasError() { ctx.ServerError("ChangeIssueReaction", errors.New(ctx.GetErrMsg())) return @@ -1486,20 +1519,22 @@ func ChangeCommentReaction(ctx *context.Context, form auth.ReactionForm) { return } - issue, err := models.GetIssueByID(comment.IssueID) - checkIssueRights(ctx, issue) - if ctx.Written() { + if err := comment.LoadIssue(); err != nil { + ctx.NotFoundOrServerError("LoadIssue", models.IsErrIssueNotExist, err) return } - if ctx.HasError() { - ctx.ServerError("ChangeCommentReaction", errors.New(ctx.GetErrMsg())) + if !ctx.IsSigned || (ctx.User.ID != comment.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)) { + ctx.Error(403) + return + } else if comment.Type != models.CommentTypeComment && comment.Type != models.CommentTypeCode { + ctx.Error(204) return } switch ctx.Params(":action") { case "react": - reaction, err := models.CreateCommentReaction(ctx.User, issue, comment, form.Content) + reaction, err := models.CreateCommentReaction(ctx.User, comment.Issue, comment, form.Content) if err != nil { log.Info("CreateCommentReaction: %s", err) break @@ -1511,9 +1546,9 @@ func ChangeCommentReaction(ctx *context.Context, form auth.ReactionForm) { break } - log.Trace("Reaction for comment created: %d/%d/%d/%d", ctx.Repo.Repository.ID, issue.ID, comment.ID, reaction.ID) + log.Trace("Reaction for comment created: %d/%d/%d/%d", ctx.Repo.Repository.ID, comment.Issue.ID, comment.ID, reaction.ID) case "unreact": - if err := models.DeleteCommentReaction(ctx.User, issue, comment, form.Content); err != nil { + if err := models.DeleteCommentReaction(ctx.User, comment.Issue, comment, form.Content); err != nil { ctx.ServerError("DeleteCommentReaction", err) return } @@ -1525,7 +1560,7 @@ func ChangeCommentReaction(ctx *context.Context, form auth.ReactionForm) { break } - log.Trace("Reaction for comment removed: %d/%d/%d", ctx.Repo.Repository.ID, issue.ID, comment.ID) + log.Trace("Reaction for comment removed: %d/%d/%d", ctx.Repo.Repository.ID, comment.Issue.ID, comment.ID) default: ctx.NotFound(fmt.Sprintf("Unknown action %s", ctx.Params(":action")), nil) return diff --git a/routers/repo/issue_watch.go b/routers/repo/issue_watch.go index a499b70d9c..c6a436801a 100644 --- a/routers/repo/issue_watch.go +++ b/routers/repo/issue_watch.go @@ -14,23 +14,28 @@ import ( ) // IssueWatch sets issue watching -func IssueWatch(c *context.Context) { - watch, err := strconv.ParseBool(c.Req.PostForm.Get("watch")) - if err != nil { - c.ServerError("watch is not bool", err) +func IssueWatch(ctx *context.Context) { + issue := GetActionIssue(ctx) + if ctx.Written() { return } - issue := GetActionIssue(c) - if c.Written() { + if !ctx.IsSigned || (ctx.User.ID != issue.PosterID && !ctx.Repo.CanReadIssuesOrPulls(issue.IsPull)) { + ctx.Error(403) + return + } + + watch, err := strconv.ParseBool(ctx.Req.PostForm.Get("watch")) + if err != nil { + ctx.ServerError("watch is not bool", err) return } - if err := models.CreateOrUpdateIssueWatch(c.User.ID, issue.ID, watch); err != nil { - c.ServerError("CreateOrUpdateIssueWatch", err) + if err := models.CreateOrUpdateIssueWatch(ctx.User.ID, issue.ID, watch); err != nil { + ctx.ServerError("CreateOrUpdateIssueWatch", err) return } - url := fmt.Sprintf("%s/issues/%d", c.Repo.RepoLink, issue.Index) - c.Redirect(url, http.StatusSeeOther) + url := fmt.Sprintf("%s/issues/%d", ctx.Repo.RepoLink, issue.Index) + ctx.Redirect(url, http.StatusSeeOther) } diff --git a/routers/repo/pull.go b/routers/repo/pull.go index 4ec1c27cea..4adfb96e74 100644 --- a/routers/repo/pull.go +++ b/routers/repo/pull.go @@ -57,7 +57,13 @@ func getForkRepository(ctx *context.Context) *models.Repository { return nil } - if !forkRepo.CanBeForked() || !forkRepo.HasAccess(ctx.User) { + perm, err := models.GetUserRepoPermission(forkRepo, ctx.User) + if err != nil { + ctx.ServerError("GetUserRepoPermission", err) + return nil + } + + if forkRepo.IsBare || !perm.CanRead(models.UnitTypeCode) { ctx.NotFound("getForkRepository", nil) return nil } @@ -669,7 +675,12 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, * } } - if !ctx.User.IsWriterOfRepo(headRepo) && !ctx.User.IsAdmin { + perm, err := models.GetUserRepoPermission(headRepo, ctx.User) + if err != nil { + ctx.ServerError("GetUserRepoPermission", err) + return nil, nil, nil, nil, "", "" + } + if !perm.CanWrite(models.UnitTypeCode) { log.Trace("ParseCompareInfo[%d]: does not have write access or site admin", baseRepo.ID) ctx.NotFound("ParseCompareInfo", nil) return nil, nil, nil, nil, "", "" @@ -823,7 +834,7 @@ func CompareAndPullRequestPost(ctx *context.Context, form auth.CreateIssueForm) return } - labelIDs, assigneeIDs, milestoneID := ValidateRepoMetas(ctx, form) + labelIDs, assigneeIDs, milestoneID := ValidateRepoMetas(ctx, form, true) if ctx.Written() { return } @@ -969,7 +980,12 @@ func CleanUpPullRequest(ctx *context.Context) { return } - if !ctx.User.IsWriterOfRepo(pr.HeadRepo) { + perm, err := models.GetUserRepoPermission(pr.HeadRepo, ctx.User) + if err != nil { + ctx.ServerError("GetUserRepoPermission", err) + return + } + if !perm.CanWrite(models.UnitTypeCode) { ctx.NotFound("CleanUpPullRequest", nil) return } diff --git a/routers/repo/release.go b/routers/repo/release.go index bae87efdcd..5a869520f0 100644 --- a/routers/repo/release.go +++ b/routers/repo/release.go @@ -1,4 +1,5 @@ // Copyright 2014 The Gogs Authors. All rights reserved. +// Copyright 2018 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. @@ -65,8 +66,11 @@ func Releases(ctx *context.Context) { limit = 10 } + writeAccess := ctx.Repo.CanWrite(models.UnitTypeReleases) + ctx.Data["CanCreateRelease"] = writeAccess + opts := models.FindReleasesOptions{ - IncludeDrafts: ctx.Repo.IsWriter(), + IncludeDrafts: writeAccess, IncludeTags: true, } diff --git a/routers/repo/setting_protected_branch.go b/routers/repo/setting_protected_branch.go index db12f0afcd..c8f6f843da 100644 --- a/routers/repo/setting_protected_branch.go +++ b/routers/repo/setting_protected_branch.go @@ -165,12 +165,21 @@ func SettingsProtectedBranchPost(ctx *context.Context, f auth.ProtectBranchForm) } } + var whitelistUsers, whitelistTeams, mergeWhitelistUsers, mergeWhitelistTeams []int64 protectBranch.EnableWhitelist = f.EnableWhitelist - whitelistUsers, _ := base.StringsToInt64s(strings.Split(f.WhitelistUsers, ",")) - whitelistTeams, _ := base.StringsToInt64s(strings.Split(f.WhitelistTeams, ",")) + if strings.TrimSpace(f.WhitelistUsers) != "" { + whitelistUsers, _ = base.StringsToInt64s(strings.Split(f.WhitelistUsers, ",")) + } + if strings.TrimSpace(f.WhitelistTeams) != "" { + whitelistTeams, _ = base.StringsToInt64s(strings.Split(f.WhitelistTeams, ",")) + } protectBranch.EnableMergeWhitelist = f.EnableMergeWhitelist - mergeWhitelistUsers, _ := base.StringsToInt64s(strings.Split(f.MergeWhitelistUsers, ",")) - mergeWhitelistTeams, _ := base.StringsToInt64s(strings.Split(f.MergeWhitelistTeams, ",")) + if strings.TrimSpace(f.MergeWhitelistUsers) != "" { + mergeWhitelistUsers, _ = base.StringsToInt64s(strings.Split(f.MergeWhitelistUsers, ",")) + } + if strings.TrimSpace(f.MergeWhitelistTeams) != "" { + mergeWhitelistTeams, _ = base.StringsToInt64s(strings.Split(f.MergeWhitelistTeams, ",")) + } err = models.UpdateProtectBranch(ctx.Repo.Repository, protectBranch, whitelistUsers, whitelistTeams, mergeWhitelistUsers, mergeWhitelistTeams) if err != nil { ctx.ServerError("UpdateProtectBranch", err) diff --git a/routers/repo/view.go b/routers/repo/view.go index 657fe315a2..78a305aa28 100644 --- a/routers/repo/view.go +++ b/routers/repo/view.go @@ -137,7 +137,7 @@ func renderDirectory(ctx *context.Context, treeLink string) { ctx.Data["LatestCommitStatus"] = models.CalcCommitStatus(statuses) // Check permission to add or upload new file. - if ctx.Repo.IsWriter() && ctx.Repo.IsViewBranch { + if ctx.Repo.CanWrite(models.UnitTypeCode) && ctx.Repo.IsViewBranch { ctx.Data["CanAddFile"] = true ctx.Data["CanUploadFile"] = setting.Repository.Upload.Enabled } @@ -256,7 +256,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.edit_this_file") } else if !ctx.Repo.IsViewBranch { ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.must_be_on_a_branch") - } else if !ctx.Repo.IsWriter() { + } else if !ctx.Repo.CanWrite(models.UnitTypeCode) { ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.fork_before_edit") } @@ -275,16 +275,16 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.delete_this_file") } else if !ctx.Repo.IsViewBranch { ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.must_be_on_a_branch") - } else if !ctx.Repo.IsWriter() { + } else if !ctx.Repo.CanWrite(models.UnitTypeCode) { ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.must_have_write_access") } } // Home render repository home page func Home(ctx *context.Context) { - if len(ctx.Repo.Repository.Units) > 0 { + if len(ctx.Repo.Units) > 0 { var firstUnit *models.Unit - for _, repoUnit := range ctx.Repo.Repository.Units { + for _, repoUnit := range ctx.Repo.Units { if repoUnit.Type == models.UnitTypeCode { renderCode(ctx) return diff --git a/routers/repo/wiki.go b/routers/repo/wiki.go index 3220ab134d..2349236358 100644 --- a/routers/repo/wiki.go +++ b/routers/repo/wiki.go @@ -1,4 +1,5 @@ // Copyright 2015 The Gogs Authors. All rights reserved. +// Copyright 2018 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. @@ -30,8 +31,8 @@ const ( // MustEnableWiki check if wiki is enabled, if external then redirect func MustEnableWiki(ctx *context.Context) { - if !ctx.Repo.Repository.UnitEnabled(models.UnitTypeWiki) && - !ctx.Repo.Repository.UnitEnabled(models.UnitTypeExternalWiki) { + if !ctx.Repo.CanRead(models.UnitTypeWiki) && + !ctx.Repo.CanRead(models.UnitTypeExternalWiki) { ctx.NotFound("MustEnableWiki", nil) return } @@ -200,6 +201,7 @@ func renderWikiPage(ctx *context.Context, isViewPage bool) (*git.Repository, *gi // Wiki renders single wiki page func Wiki(ctx *context.Context) { ctx.Data["PageIsWiki"] = true + ctx.Data["CanWriteWiki"] = ctx.Repo.CanWrite(models.UnitTypeWiki) if !ctx.Repo.Repository.HasWiki() { ctx.Data["Title"] = ctx.Tr("repo.wiki") @@ -235,14 +237,15 @@ func Wiki(ctx *context.Context) { // WikiPages render wiki pages list page func WikiPages(ctx *context.Context) { - ctx.Data["Title"] = ctx.Tr("repo.wiki.pages") - ctx.Data["PageIsWiki"] = true - if !ctx.Repo.Repository.HasWiki() { ctx.Redirect(ctx.Repo.RepoLink + "/wiki") return } + ctx.Data["Title"] = ctx.Tr("repo.wiki.pages") + ctx.Data["PageIsWiki"] = true + ctx.Data["CanWriteWiki"] = ctx.Repo.CanWrite(models.UnitTypeWiki) + wikiRepo, commit, err := findWikiRepoCommit(ctx) if err != nil { return |