mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2026-05-12 22:10:25 +00:00
feat: implement fine-grained access tokens in /repos/issues/search
This commit is contained in:
parent
2192184d9b
commit
0da4505a49
2 changed files with 93 additions and 0 deletions
|
|
@ -166,6 +166,8 @@ func SearchIssues(ctx *context.APIContext) {
|
|||
// MySQL will return different results when sorting by null in some cases
|
||||
OrderBy: db.SearchOrderByAlphabetically,
|
||||
Actor: ctx.Doer,
|
||||
|
||||
AuthorizationReducer: ctx.Reducer,
|
||||
}
|
||||
if ctx.IsSigned {
|
||||
opts.Private = !ctx.PublicOnly
|
||||
|
|
|
|||
|
|
@ -660,6 +660,97 @@ func TestAPISearchIssuesWithLabels(t *testing.T) {
|
|||
assert.Len(t, apiIssues, 2)
|
||||
}
|
||||
|
||||
func TestAPISearchIssuesAccessTokenResources(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
var issues []*api.Issue
|
||||
|
||||
// Test repos: repo1 (public), repo2 (private), repo16 (private).
|
||||
session := loginUser(t, "user2")
|
||||
writeToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteIssue)
|
||||
|
||||
// On those three test repos, create an issue with a specific title for search.
|
||||
for _, repo := range []string{"repo1", "repo2", "repo16"} {
|
||||
trueBool := true
|
||||
// Enable issues on each target repo as well
|
||||
req := NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/user2/%s", repo), &api.EditRepoOption{
|
||||
HasIssues: &trueBool,
|
||||
}).AddTokenAuth(writeToken)
|
||||
MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/user2/%s/issues", repo), &api.CreateIssueOption{
|
||||
Body: "body: abracadabra",
|
||||
Title: "important issue",
|
||||
}).AddTokenAuth(writeToken)
|
||||
MakeRequest(t, req, http.StatusCreated)
|
||||
}
|
||||
|
||||
find := func() (bool, bool, bool) {
|
||||
foundRepo1 := false // public user2/repo1
|
||||
foundRepo2 := false // private user2/repo2
|
||||
foundRepo16 := false // second private repo user2/repo16 used in fine-grain testing, included as baseline
|
||||
for _, issue := range issues {
|
||||
switch issue.Repo.Name {
|
||||
case "repo1":
|
||||
foundRepo1 = true
|
||||
case "repo2":
|
||||
foundRepo2 = true
|
||||
case "repo16":
|
||||
foundRepo16 = true
|
||||
}
|
||||
}
|
||||
return foundRepo1, foundRepo2, foundRepo16
|
||||
}
|
||||
|
||||
t.Run("all access token", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
allToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadIssue)
|
||||
|
||||
req := NewRequest(t, "GET", "/api/v1/repos/issues/search").AddTokenAuth(allToken)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &issues)
|
||||
foundRepo1, foundRepo2, foundRepo16 := find()
|
||||
|
||||
assert.True(t, foundRepo1) // public user2/repo1
|
||||
assert.True(t, foundRepo2) // private user2/repo2
|
||||
assert.True(t, foundRepo16) // private user2/repo16, used in fine-grain testing, included as baseline
|
||||
})
|
||||
|
||||
t.Run("public-only access token", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
publicOnlyToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopePublicOnly, auth_model.AccessTokenScopeReadIssue)
|
||||
|
||||
req := NewRequest(t, "GET", "/api/v1/repos/issues/search").AddTokenAuth(publicOnlyToken)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &issues)
|
||||
foundRepo1, foundRepo2, foundRepo16 := find()
|
||||
|
||||
assert.True(t, foundRepo1) // public user2/repo1
|
||||
assert.False(t, foundRepo2) // private user2/repo2
|
||||
assert.False(t, foundRepo16) // private user2/repo16
|
||||
})
|
||||
|
||||
t.Run("specific repo access token", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
repo2OnlyToken := createFineGrainedRepoAccessToken(t, "user2",
|
||||
[]auth_model.AccessTokenScope{auth_model.AccessTokenScopeReadIssue},
|
||||
[]int64{2},
|
||||
)
|
||||
|
||||
req := NewRequest(t, "GET", "/api/v1/repos/issues/search").AddTokenAuth(repo2OnlyToken)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &issues)
|
||||
foundRepo1, foundRepo2, foundRepo16 := find()
|
||||
|
||||
assert.True(t, foundRepo1) // public user2/repo1, allowed as it's public and read-access only
|
||||
assert.True(t, foundRepo2) // private user2/repo2, allowed inside fine-grain
|
||||
assert.False(t, foundRepo16) // private user2/repo16, denied outside fine-grain
|
||||
})
|
||||
}
|
||||
|
||||
func TestAPIInternalAndExternalIssueTracker(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue