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

Restrict permission check on repositories and fix some problems #5314

Merged
merged 32 commits into from
Nov 28, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
0bf41c2
fix units permission problems
lunny Nov 10, 2018
15f80b9
fix some bugs and merge LoadUnits to repoAssignment
lunny Nov 11, 2018
40d552c
refactor permission struct and add some copyright heads
lunny Nov 11, 2018
d80fea2
remove unused codes
lunny Nov 11, 2018
fb4a2cb
fix routes units check
lunny Nov 11, 2018
a21bfde
improve permission check
lunny Nov 11, 2018
422ba40
add unit tests for permission
lunny Nov 12, 2018
dae595b
fix typo
lunny Nov 12, 2018
6bed0d4
fix tests
lunny Nov 12, 2018
d5ba3a0
fix some routes
lunny Nov 12, 2018
426980d
fix api permission check
lunny Nov 12, 2018
50d1287
improve permission check
lunny Nov 12, 2018
95d9a58
fix some permission check
lunny Nov 13, 2018
5df61b6
fix tests
lunny Nov 13, 2018
4ee6e1f
fix tests
lunny Nov 13, 2018
de04377
improve some permission check
lunny Nov 13, 2018
66fd8f3
fix some permission check
lunny Nov 14, 2018
11bde94
refactor AccessLevel
lunny Nov 17, 2018
ba60cc8
fix bug
lunny Nov 17, 2018
a978acc
fix tests
lunny Nov 17, 2018
d161315
fix tests
lunny Nov 17, 2018
e5e165c
fix tests
lunny Nov 17, 2018
9253015
fix AccessLevel
lunny Nov 18, 2018
2f65f7a
rename CanAccess
lunny Nov 18, 2018
962be78
fix tests
lunny Nov 18, 2018
9742d63
fix comment
lunny Nov 18, 2018
2db05db
fix bug
lunny Nov 18, 2018
3620109
add missing unit for test repos
lunny Nov 18, 2018
861b3b2
fix bug
lunny Nov 18, 2018
b677d04
rename some functions
lunny Nov 18, 2018
79365d8
fix routes check
lunny Nov 18, 2018
d54bc51
Merge branch 'master' into lunny/fix_units_permissions
lunny Nov 28, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactor AccessLevel
  • Loading branch information
lunny committed Nov 28, 2018
commit 11bde943868c9e7b50a7c6a4eef846c79fd2ecf6
12 changes: 10 additions & 2 deletions models/access.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,16 @@ func accessLevel(e Engine, userID int64, repo *Repository) (AccessMode, error) {

// AccessLevel returns the Access a user has to a repository. Will return NoneAccess if the
// user does not have access.
func AccessLevel(userID int64, repo *Repository) (AccessMode, error) {
return accessLevel(x, userID, repo)
func AccessLevel(user *User, repo *Repository) (AccessMode, error) {
return accessLevelUnit(user, repo, UnitTypeCode)
}

func accessLevelUnit(user *User, repo *Repository, unitType UnitType) (AccessMode, error) {
perm, err := GetUserRepoPermission(repo, user)
if err != nil {
return AccessModeNone, err
}
return perm.UnitAccessMode(UnitTypeCode), nil
}

func hasAccess(e Engine, userID int64, repo *Repository, testMode AccessMode) (bool, error) {
Expand Down
12 changes: 6 additions & 6 deletions models/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ func (issue *Issue) sendLabelUpdatedWebhook(doer *User) {
return
}

mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
mode, _ := AccessLevel(issue.Poster, issue.Repo)
if issue.IsPull {
if err = issue.loadPullRequest(x); err != nil {
log.Error(4, "loadPullRequest: %v", err)
Expand Down Expand Up @@ -533,7 +533,7 @@ func (issue *Issue) ClearLabels(doer *User) (err error) {
return fmt.Errorf("loadPoster: %v", err)
}

mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
mode, _ := AccessLevel(issue.Poster, issue.Repo)
if issue.IsPull {
err = issue.PullRequest.LoadIssue()
if err != nil {
Expand Down Expand Up @@ -727,7 +727,7 @@ func (issue *Issue) ChangeStatus(doer *User, repo *Repository, isClosed bool) (e
}
sess.Close()

mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
mode, _ := AccessLevel(issue.Poster, issue.Repo)
if issue.IsPull {
// Merge pull request calls issue.changeStatus so we need to handle separately.
issue.PullRequest.Issue = issue
Expand Down Expand Up @@ -789,7 +789,7 @@ func (issue *Issue) ChangeTitle(doer *User, title string) (err error) {
return err
}

mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
mode, _ := AccessLevel(issue.Poster, issue.Repo)
if issue.IsPull {
issue.PullRequest.Issue = issue
err = PrepareWebhooks(issue.Repo, HookEventPullRequest, &api.PullRequestPayload{
Expand Down Expand Up @@ -855,7 +855,7 @@ func (issue *Issue) ChangeContent(doer *User, content string) (err error) {
return fmt.Errorf("UpdateIssueCols: %v", err)
}

mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
mode, _ := AccessLevel(issue.Poster, issue.Repo)
if issue.IsPull {
issue.PullRequest.Issue = issue
err = PrepareWebhooks(issue.Repo, HookEventPullRequest, &api.PullRequestPayload{
Expand Down Expand Up @@ -1075,7 +1075,7 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, assigneeIDs []in
log.Error(4, "MailParticipants: %v", err)
}

mode, _ := AccessLevel(issue.Poster.ID, issue.Repo)
mode, _ := AccessLevel(issue.Poster, issue.Repo)
if err = PrepareWebhooks(repo, HookEventIssues, &api.IssuePayload{
Action: api.HookIssueOpened,
Index: issue.Index,
Expand Down
6 changes: 3 additions & 3 deletions models/issue_comment.go
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,7 @@ func CreateIssueComment(doer *User, repo *Repository, issue *Issue, content stri
return nil, fmt.Errorf("CreateComment: %v", err)
}

mode, _ := AccessLevel(doer.ID, repo)
mode, _ := AccessLevel(doer, repo)
if err = PrepareWebhooks(repo, HookEventIssueComment, &api.IssueCommentPayload{
Action: api.HookIssueCommentCreated,
Issue: issue.APIFormat(),
Expand Down Expand Up @@ -990,7 +990,7 @@ func UpdateComment(doer *User, c *Comment, oldContent string) error {
return err
}

mode, _ := AccessLevel(doer.ID, c.Issue.Repo)
mode, _ := AccessLevel(doer, c.Issue.Repo)
if err := PrepareWebhooks(c.Issue.Repo, HookEventIssueComment, &api.IssueCommentPayload{
Action: api.HookIssueCommentEdited,
Issue: c.Issue.APIFormat(),
Expand Down Expand Up @@ -1047,7 +1047,7 @@ func DeleteComment(doer *User, comment *Comment) error {
return err
}

mode, _ := AccessLevel(doer.ID, comment.Issue.Repo)
mode, _ := AccessLevel(doer, comment.Issue.Repo)

if err := PrepareWebhooks(comment.Issue.Repo, HookEventIssueComment, &api.IssueCommentPayload{
Action: api.HookIssueCommentDeleted,
Expand Down
2 changes: 1 addition & 1 deletion models/issue_milestone.go
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ func ChangeMilestoneAssign(issue *Issue, doer *User, oldMilestoneID int64) (err
return err
}

mode, _ := AccessLevel(doer.ID, issue.Repo)
mode, _ := AccessLevel(doer, issue.Repo)
if issue.IsPull {
err = issue.PullRequest.LoadIssue()
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion models/org_team_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ func TestDeleteTeam(t *testing.T) {
// check that team members don't have "leftover" access to repos
user := AssertExistsAndLoadBean(t, &User{ID: 4}).(*User)
repo := AssertExistsAndLoadBean(t, &Repository{ID: 3}).(*Repository)
accessMode, err := AccessLevel(user.ID, repo)
accessMode, err := AccessLevel(user, repo)
assert.NoError(t, err)
assert.True(t, accessMode < AccessModeWrite)
}
Expand Down
4 changes: 2 additions & 2 deletions models/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle
return nil
}

mode, _ := AccessLevel(doer.ID, pr.Issue.Repo)
mode, _ := AccessLevel(doer, pr.Issue.Repo)
if err = PrepareWebhooks(pr.Issue.Repo, HookEventPullRequest, &api.PullRequestPayload{
Action: api.HookIssueClosed,
Index: pr.Index,
Expand Down Expand Up @@ -787,7 +787,7 @@ func NewPullRequest(repo *Repository, pull *Issue, labelIDs []int64, uuids []str

pr.Issue = pull
pull.PullRequest = pr
mode, _ := AccessLevel(pull.Poster.ID, repo)
mode, _ := AccessLevel(pull.Poster, repo)
if err = PrepareWebhooks(repo, HookEventPullRequest, &api.PullRequestPayload{
Action: api.HookIssueOpened,
Index: pull.Index,
Expand Down
6 changes: 3 additions & 3 deletions models/release.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ func CreateRelease(gitRepo *git.Repository, rel *Release, attachmentUUIDs []stri
if err := rel.LoadAttributes(); err != nil {
log.Error(2, "LoadAttributes: %v", err)
} else {
mode, _ := AccessLevel(rel.PublisherID, rel.Repo)
mode, _ := AccessLevel(rel.Publisher, rel.Repo)
if err := PrepareWebhooks(rel.Repo, HookEventRelease, &api.ReleasePayload{
Action: api.HookReleasePublished,
Release: rel.APIFormat(),
Expand Down Expand Up @@ -392,7 +392,7 @@ func UpdateRelease(doer *User, gitRepo *git.Repository, rel *Release, attachment

err = addReleaseAttachments(rel.ID, attachmentUUIDs)

mode, _ := accessLevel(x, doer.ID, rel.Repo)
mode, _ := AccessLevel(doer, rel.Repo)
if err1 := PrepareWebhooks(rel.Repo, HookEventRelease, &api.ReleasePayload{
Action: api.HookReleaseUpdated,
Release: rel.APIFormat(),
Expand Down Expand Up @@ -454,7 +454,7 @@ func DeleteReleaseByID(id int64, u *User, delTag bool) error {
return fmt.Errorf("LoadAttributes: %v", err)
}

mode, _ := accessLevel(x, u.ID, rel.Repo)
mode, _ := AccessLevel(u, rel.Repo)
if err := PrepareWebhooks(rel.Repo, HookEventRelease, &api.ReleasePayload{
Action: api.HookReleaseDeleted,
Release: rel.APIFormat(),
Expand Down
4 changes: 2 additions & 2 deletions models/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -2429,8 +2429,8 @@ func ForkRepository(doer, u *User, oldRepo *Repository, name, desc string) (_ *R
return nil, err
}

oldMode, _ := AccessLevel(doer.ID, oldRepo)
mode, _ := AccessLevel(doer.ID, repo)
oldMode, _ := AccessLevel(doer, oldRepo)
mode, _ := AccessLevel(doer, repo)

if err = PrepareWebhooks(oldRepo, HookEventFork, &api.ForkPayload{
Forkee: oldRepo.APIFormat(oldMode),
Expand Down
2 changes: 1 addition & 1 deletion modules/context/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ func repoAssignment(ctx *Context, repo *models.Repository) {
var err error
ctx.Repo.Permission, err = models.GetUserRepoPermission(repo, ctx.User)
if err != nil {
ctx.ServerError("AccessLevel", err)
ctx.ServerError("GetUserRepoPermission", err)
return
}

Expand Down
6 changes: 3 additions & 3 deletions modules/private/internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func newInternalRequest(url, method string) *httplib.Request {
// CheckUnitUser check whether user could visit the unit of this repository
func CheckUnitUser(userID, repoID int64, isAdmin bool, unitType models.UnitType) (*models.AccessMode, error) {
reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repositories/%d/user/%d/checkunituser?isAdmin=%t&unitType=%d", repoID, userID, isAdmin, unitType)
log.GitLogger.Trace("AccessLevel: %s", reqURL)
log.GitLogger.Trace("CheckUnitUser: %s", reqURL)

resp, err := newInternalRequest(reqURL, "GET").Response()
if err != nil {
Expand All @@ -75,7 +75,7 @@ func CheckUnitUser(userID, repoID int64, isAdmin bool, unitType models.UnitType)

// AccessLevel returns the Access a user has to a repository. Will return NoneAccess if the
// user does not have access.
func AccessLevel(userID, repoID int64) (*models.AccessMode, error) {
/*func AccessLevel(userID, repoID int64) (*models.AccessMode, error) {
reqURL := setting.LocalURL + fmt.Sprintf("api/internal/repositories/%d/user/%d/accesslevel", repoID, userID)
log.GitLogger.Trace("AccessLevel: %s", reqURL)

Expand All @@ -95,7 +95,7 @@ func AccessLevel(userID, repoID int64) (*models.AccessMode, error) {
}

return &a, nil
}
}*/

// GetRepositoryByOwnerAndName returns the repository by given ownername and reponame.
func GetRepositoryByOwnerAndName(ownerName, repoName string) (*models.Repository, error) {
Expand Down
6 changes: 3 additions & 3 deletions routers/api/v1/org/team.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ func GetTeamRepos(ctx *context.APIContext) {
}
repos := make([]*api.Repository, len(team.Repos))
for i, repo := range team.Repos {
access, err := models.AccessLevel(ctx.User.ID, repo)
access, err := models.AccessLevel(ctx.User, repo)
if err != nil {
ctx.Error(500, "GetTeamRepos", err)
return
Expand Down Expand Up @@ -366,7 +366,7 @@ func AddTeamRepository(ctx *context.APIContext) {
if ctx.Written() {
return
}
if access, err := models.AccessLevel(ctx.User.ID, repo); err != nil {
if access, err := models.AccessLevel(ctx.User, repo); err != nil {
ctx.Error(500, "AccessLevel", err)
return
} else if access < models.AccessModeAdmin {
Expand Down Expand Up @@ -413,7 +413,7 @@ func RemoveTeamRepository(ctx *context.APIContext) {
if ctx.Written() {
return
}
if access, err := models.AccessLevel(ctx.User.ID, repo); err != nil {
if access, err := models.AccessLevel(ctx.User, repo); err != nil {
ctx.Error(500, "AccessLevel", err)
return
} else if access < models.AccessModeAdmin {
Expand Down
3 changes: 1 addition & 2 deletions routers/api/v1/repo/fork.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ package repo
import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/routers/api/v1/utils"

api "code.gitea.io/sdk/gitea"
)
Expand Down Expand Up @@ -40,7 +39,7 @@ func ListForks(ctx *context.APIContext) {
}
apiForks := make([]*api.Repository, len(forks))
for i, fork := range forks {
access, err := models.AccessLevel(utils.UserID(ctx), fork)
access, err := models.AccessLevel(ctx.User, fork)
if err != nil {
ctx.Error(500, "AccessLevel", err)
return
Expand Down
7 changes: 1 addition & 6 deletions routers/api/v1/repo/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,6 @@ func Search(ctx *context.APIContext) {
return
}

var userID int64
if ctx.IsSigned {
userID = ctx.User.ID
}

results := make([]*api.Repository, len(repos))
for i, repo := range repos {
if err = repo.GetOwner(); err != nil {
Expand All @@ -198,7 +193,7 @@ func Search(ctx *context.APIContext) {
})
return
}
accessMode, err := models.AccessLevel(userID, repo)
accessMode, err := models.AccessLevel(ctx.User, repo)
if err != nil {
ctx.JSON(500, api.SearchError{
OK: false,
Expand Down
7 changes: 2 additions & 5 deletions routers/api/v1/user/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,10 @@ func listUserRepos(ctx *context.APIContext, u *models.User, private bool) {
ctx.Error(500, "GetUserRepositories", err)
return
}

apiRepos := make([]*api.Repository, 0, len(repos))
var ctxUserID int64
if ctx.User != nil {
ctxUserID = ctx.User.ID
}
for i := range repos {
access, err := models.AccessLevel(ctxUserID, repos[i])
access, err := models.AccessLevel(ctx.User, repos[i])
if err != nil {
ctx.Error(500, "AccessLevel", err)
return
Expand Down
10 changes: 5 additions & 5 deletions routers/api/v1/user/star.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ import (

// getStarredRepos returns the repos that the user with the specified userID has
// starred
func getStarredRepos(userID int64, private bool) ([]*api.Repository, error) {
starredRepos, err := models.GetStarredRepos(userID, private)
func getStarredRepos(user *models.User, private bool) ([]*api.Repository, error) {
starredRepos, err := models.GetStarredRepos(user.ID, private)
if err != nil {
return nil, err
}

repos := make([]*api.Repository, len(starredRepos))
for i, starred := range starredRepos {
access, err := models.AccessLevel(userID, starred)
access, err := models.AccessLevel(user, starred)
if err != nil {
return nil, err
}
Expand All @@ -48,7 +48,7 @@ func GetStarredRepos(ctx *context.APIContext) {
// "$ref": "#/responses/RepositoryList"
user := GetUserByParams(ctx)
private := user.ID == ctx.User.ID
repos, err := getStarredRepos(user.ID, private)
repos, err := getStarredRepos(user, private)
if err != nil {
ctx.Error(500, "getStarredRepos", err)
}
Expand All @@ -65,7 +65,7 @@ func GetMyStarredRepos(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/RepositoryList"
repos, err := getStarredRepos(ctx.User.ID, true)
repos, err := getStarredRepos(ctx.User, true)
if err != nil {
ctx.Error(500, "getStarredRepos", err)
}
Expand Down
10 changes: 5 additions & 5 deletions routers/api/v1/user/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ import (

// getWatchedRepos returns the repos that the user with the specified userID is
// watching
func getWatchedRepos(userID int64, private bool) ([]*api.Repository, error) {
watchedRepos, err := models.GetWatchedRepos(userID, private)
func getWatchedRepos(user *models.User, private bool) ([]*api.Repository, error) {
watchedRepos, err := models.GetWatchedRepos(user.ID, private)
if err != nil {
return nil, err
}

repos := make([]*api.Repository, len(watchedRepos))
for i, watched := range watchedRepos {
access, err := models.AccessLevel(userID, watched)
access, err := models.AccessLevel(user, watched)
if err != nil {
return nil, err
}
Expand All @@ -49,7 +49,7 @@ func GetWatchedRepos(ctx *context.APIContext) {
// "$ref": "#/responses/RepositoryList"
user := GetUserByParams(ctx)
private := user.ID == ctx.User.ID
repos, err := getWatchedRepos(user.ID, private)
repos, err := getWatchedRepos(user, private)
if err != nil {
ctx.Error(500, "getWatchedRepos", err)
}
Expand All @@ -66,7 +66,7 @@ func GetMyWatchedRepos(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/RepositoryList"
repos, err := getWatchedRepos(ctx.User.ID, true)
repos, err := getWatchedRepos(ctx.User, true)
if err != nil {
ctx.Error(500, "getWatchedRepos", err)
}
Expand Down
6 changes: 3 additions & 3 deletions routers/private/internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func GetRepositoryByOwnerAndName(ctx *macaron.Context) {
}

//AccessLevel chainload to models.AccessLevel
func AccessLevel(ctx *macaron.Context) {
/*func AccessLevel(ctx *macaron.Context) {
repoID := ctx.ParamsInt64(":repoid")
userID := ctx.ParamsInt64(":userid")
repo, err := models.GetRepositoryByID(repoID)
Expand All @@ -57,7 +57,7 @@ func AccessLevel(ctx *macaron.Context) {
return
}
ctx.JSON(200, al)
}
}*/

//CheckUnitUser chainload to models.CheckUnitUser
func CheckUnitUser(ctx *macaron.Context) {
Expand Down Expand Up @@ -98,7 +98,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/ssh/:id/user", GetUserByKeyID)
m.Post("/ssh/:id/update", UpdatePublicKey)
m.Post("/repositories/:repoid/keys/:keyid/update", UpdateDeployKey)
m.Get("/repositories/:repoid/user/:userid/accesslevel", AccessLevel)
//m.Get("/repositories/:repoid/user/:userid/accesslevel", AccessLevel)
m.Get("/repositories/:repoid/user/:userid/checkunituser", CheckUnitUser)
m.Get("/repositories/:repoid/has-keys/:keyid", HasDeployKey)
m.Post("/push/update", PushUpdate)
Expand Down