2017-06-25 22:51:07 +08:00
|
|
|
// Copyright 2017 The Gitea Authors. All rights reserved.
|
2022-11-28 02:20:29 +08:00
|
|
|
// SPDX-License-Identifier: MIT
|
2017-06-25 22:51:07 +08:00
|
|
|
|
2022-09-03 03:18:23 +08:00
|
|
|
package integration
|
2017-06-25 22:51:07 +08:00
|
|
|
|
|
|
|
import (
|
2018-09-13 10:33:48 +08:00
|
|
|
"fmt"
|
2017-06-25 22:51:07 +08:00
|
|
|
"net/http"
|
2020-01-12 14:35:11 +08:00
|
|
|
"net/url"
|
2023-06-05 18:33:47 +08:00
|
|
|
"strconv"
|
|
|
|
"sync"
|
2017-06-25 22:51:07 +08:00
|
|
|
"testing"
|
2020-11-24 04:49:36 +08:00
|
|
|
"time"
|
2017-06-25 22:51:07 +08:00
|
|
|
|
2023-01-18 05:46:03 +08:00
|
|
|
auth_model "code.gitea.io/gitea/models/auth"
|
2022-06-13 17:37:59 +08:00
|
|
|
"code.gitea.io/gitea/models/db"
|
|
|
|
issues_model "code.gitea.io/gitea/models/issues"
|
2021-12-10 09:27:50 +08:00
|
|
|
repo_model "code.gitea.io/gitea/models/repo"
|
2021-11-16 16:53:21 +08:00
|
|
|
"code.gitea.io/gitea/models/unittest"
|
2021-11-24 17:49:20 +08:00
|
|
|
user_model "code.gitea.io/gitea/models/user"
|
2022-08-06 18:43:40 +08:00
|
|
|
"code.gitea.io/gitea/modules/setting"
|
2019-05-11 18:21:34 +08:00
|
|
|
api "code.gitea.io/gitea/modules/structs"
|
2022-09-03 03:18:23 +08:00
|
|
|
"code.gitea.io/gitea/tests"
|
2017-06-25 22:51:07 +08:00
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestAPIListIssues(t *testing.T) {
|
2022-09-03 03:18:23 +08:00
|
|
|
defer tests.PrepareTestEnv(t)()
|
2017-06-25 22:51:07 +08:00
|
|
|
|
2022-08-16 10:22:25 +08:00
|
|
|
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
|
|
|
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
|
2017-06-25 22:51:07 +08:00
|
|
|
|
|
|
|
session := loginUser(t, owner.Name)
|
Redesign Scoped Access Tokens (#24767)
## Changes
- Adds the following high level access scopes, each with `read` and
`write` levels:
- `activitypub`
- `admin` (hidden if user is not a site admin)
- `misc`
- `notification`
- `organization`
- `package`
- `issue`
- `repository`
- `user`
- Adds new middleware function `tokenRequiresScopes()` in addition to
`reqToken()`
- `tokenRequiresScopes()` is used for each high-level api section
- _if_ a scoped token is present, checks that the required scope is
included based on the section and HTTP method
- `reqToken()` is used for individual routes
- checks that required authentication is present (but does not check
scope levels as this will already have been handled by
`tokenRequiresScopes()`
- Adds migration to convert old scoped access tokens to the new set of
scopes
- Updates the user interface for scope selection
### User interface example
<img width="903" alt="Screen Shot 2023-05-31 at 1 56 55 PM"
src="https://github.com/go-gitea/gitea/assets/23248839/654766ec-2143-4f59-9037-3b51600e32f3">
<img width="917" alt="Screen Shot 2023-05-31 at 1 56 43 PM"
src="https://github.com/go-gitea/gitea/assets/23248839/1ad64081-012c-4a73-b393-66b30352654c">
## tokenRequiresScopes Design Decision
- `tokenRequiresScopes()` was added to more reliably cover api routes.
For an incoming request, this function uses the given scope category
(say `AccessTokenScopeCategoryOrganization`) and the HTTP method (say
`DELETE`) and verifies that any scoped tokens in use include
`delete:organization`.
- `reqToken()` is used to enforce auth for individual routes that
require it. If a scoped token is not present for a request,
`tokenRequiresScopes()` will not return an error
## TODO
- [x] Alphabetize scope categories
- [x] Change 'public repos only' to a radio button (private vs public).
Also expand this to organizations
- [X] Disable token creation if no scopes selected. Alternatively, show
warning
- [x] `reqToken()` is missing from many `POST/DELETE` routes in the api.
`tokenRequiresScopes()` only checks that a given token has the correct
scope, `reqToken()` must be used to check that a token (or some other
auth) is present.
- _This should be addressed in this PR_
- [x] The migration should be reviewed very carefully in order to
minimize access changes to existing user tokens.
- _This should be addressed in this PR_
- [x] Link to api to swagger documentation, clarify what
read/write/delete levels correspond to
- [x] Review cases where more than one scope is needed as this directly
deviates from the api definition.
- _This should be addressed in this PR_
- For example:
```go
m.Group("/users/{username}/orgs", func() {
m.Get("", reqToken(), org.ListUserOrgs)
m.Get("/{org}/permissions", reqToken(), org.GetUserOrgsPermissions)
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser,
auth_model.AccessTokenScopeCategoryOrganization),
context_service.UserAssignmentAPI())
```
## Future improvements
- [ ] Add required scopes to swagger documentation
- [ ] Redesign `reqToken()` to be opt-out rather than opt-in
- [ ] Subdivide scopes like `repository`
- [ ] Once a token is created, if it has no scopes, we should display
text instead of an empty bullet point
- [ ] If the 'public repos only' option is selected, should read
categories be selected by default
Closes #24501
Closes #24799
Co-authored-by: Jonathan Tran <jon@allspice.io>
Co-authored-by: Kyle D <kdumontnu@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2023-06-05 02:57:16 +08:00
|
|
|
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadIssue)
|
2021-06-17 06:33:37 +08:00
|
|
|
link, _ := url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/issues", owner.Name, repo.Name))
|
|
|
|
|
|
|
|
link.RawQuery = url.Values{"token": {token}, "state": {"all"}}.Encode()
|
2022-12-02 11:39:42 +08:00
|
|
|
resp := MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK)
|
2017-06-25 22:51:07 +08:00
|
|
|
var apiIssues []*api.Issue
|
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
2022-06-13 17:37:59 +08:00
|
|
|
assert.Len(t, apiIssues, unittest.GetCount(t, &issues_model.Issue{RepoID: repo.ID}))
|
2017-06-25 22:51:07 +08:00
|
|
|
for _, apiIssue := range apiIssues {
|
2022-06-13 17:37:59 +08:00
|
|
|
unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: apiIssue.ID, RepoID: repo.ID})
|
2017-06-25 22:51:07 +08:00
|
|
|
}
|
2020-04-30 12:15:39 +08:00
|
|
|
|
|
|
|
// test milestone filter
|
2021-06-17 06:33:37 +08:00
|
|
|
link.RawQuery = url.Values{"token": {token}, "state": {"all"}, "type": {"all"}, "milestones": {"ignore,milestone1,3,4"}}.Encode()
|
2022-12-02 11:39:42 +08:00
|
|
|
resp = MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK)
|
2020-04-30 12:15:39 +08:00
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
|
|
|
if assert.Len(t, apiIssues, 2) {
|
|
|
|
assert.EqualValues(t, 3, apiIssues[0].Milestone.ID)
|
|
|
|
assert.EqualValues(t, 1, apiIssues[1].Milestone.ID)
|
|
|
|
}
|
|
|
|
|
2021-06-17 06:33:37 +08:00
|
|
|
link.RawQuery = url.Values{"token": {token}, "state": {"all"}, "created_by": {"user2"}}.Encode()
|
2022-12-02 11:39:42 +08:00
|
|
|
resp = MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK)
|
2021-06-17 06:33:37 +08:00
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
|
|
|
if assert.Len(t, apiIssues, 1) {
|
|
|
|
assert.EqualValues(t, 5, apiIssues[0].ID)
|
|
|
|
}
|
|
|
|
|
|
|
|
link.RawQuery = url.Values{"token": {token}, "state": {"all"}, "assigned_by": {"user1"}}.Encode()
|
2022-12-02 11:39:42 +08:00
|
|
|
resp = MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK)
|
2021-06-17 06:33:37 +08:00
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
|
|
|
if assert.Len(t, apiIssues, 1) {
|
|
|
|
assert.EqualValues(t, 1, apiIssues[0].ID)
|
|
|
|
}
|
|
|
|
|
|
|
|
link.RawQuery = url.Values{"token": {token}, "state": {"all"}, "mentioned_by": {"user4"}}.Encode()
|
2022-12-02 11:39:42 +08:00
|
|
|
resp = MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK)
|
2021-06-17 06:33:37 +08:00
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
|
|
|
if assert.Len(t, apiIssues, 1) {
|
|
|
|
assert.EqualValues(t, 1, apiIssues[0].ID)
|
|
|
|
}
|
2017-06-25 22:51:07 +08:00
|
|
|
}
|
|
|
|
|
2024-10-08 17:51:09 +08:00
|
|
|
func TestAPIListIssuesPublicOnly(t *testing.T) {
|
|
|
|
defer tests.PrepareTestEnv(t)()
|
|
|
|
|
|
|
|
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
|
|
|
owner1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo1.OwnerID})
|
|
|
|
|
|
|
|
session := loginUser(t, owner1.Name)
|
|
|
|
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadIssue)
|
|
|
|
link, _ := url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/issues", owner1.Name, repo1.Name))
|
|
|
|
link.RawQuery = url.Values{"state": {"all"}}.Encode()
|
|
|
|
req := NewRequest(t, "GET", link.String()).AddTokenAuth(token)
|
|
|
|
MakeRequest(t, req, http.StatusOK)
|
|
|
|
|
|
|
|
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
|
|
|
|
owner2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo2.OwnerID})
|
|
|
|
|
|
|
|
session = loginUser(t, owner2.Name)
|
|
|
|
token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadIssue)
|
|
|
|
link, _ = url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/issues", owner2.Name, repo2.Name))
|
|
|
|
link.RawQuery = url.Values{"state": {"all"}}.Encode()
|
|
|
|
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
|
|
|
|
MakeRequest(t, req, http.StatusOK)
|
|
|
|
|
|
|
|
publicOnlyToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadIssue, auth_model.AccessTokenScopePublicOnly)
|
|
|
|
req = NewRequest(t, "GET", link.String()).AddTokenAuth(publicOnlyToken)
|
|
|
|
MakeRequest(t, req, http.StatusForbidden)
|
|
|
|
}
|
|
|
|
|
2017-06-25 22:51:07 +08:00
|
|
|
func TestAPICreateIssue(t *testing.T) {
|
2022-09-03 03:18:23 +08:00
|
|
|
defer tests.PrepareTestEnv(t)()
|
2017-06-25 22:51:07 +08:00
|
|
|
const body, title = "apiTestBody", "apiTestTitle"
|
|
|
|
|
2022-08-16 10:22:25 +08:00
|
|
|
repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
|
|
|
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID})
|
2017-06-25 22:51:07 +08:00
|
|
|
|
|
|
|
session := loginUser(t, owner.Name)
|
Redesign Scoped Access Tokens (#24767)
## Changes
- Adds the following high level access scopes, each with `read` and
`write` levels:
- `activitypub`
- `admin` (hidden if user is not a site admin)
- `misc`
- `notification`
- `organization`
- `package`
- `issue`
- `repository`
- `user`
- Adds new middleware function `tokenRequiresScopes()` in addition to
`reqToken()`
- `tokenRequiresScopes()` is used for each high-level api section
- _if_ a scoped token is present, checks that the required scope is
included based on the section and HTTP method
- `reqToken()` is used for individual routes
- checks that required authentication is present (but does not check
scope levels as this will already have been handled by
`tokenRequiresScopes()`
- Adds migration to convert old scoped access tokens to the new set of
scopes
- Updates the user interface for scope selection
### User interface example
<img width="903" alt="Screen Shot 2023-05-31 at 1 56 55 PM"
src="https://github.com/go-gitea/gitea/assets/23248839/654766ec-2143-4f59-9037-3b51600e32f3">
<img width="917" alt="Screen Shot 2023-05-31 at 1 56 43 PM"
src="https://github.com/go-gitea/gitea/assets/23248839/1ad64081-012c-4a73-b393-66b30352654c">
## tokenRequiresScopes Design Decision
- `tokenRequiresScopes()` was added to more reliably cover api routes.
For an incoming request, this function uses the given scope category
(say `AccessTokenScopeCategoryOrganization`) and the HTTP method (say
`DELETE`) and verifies that any scoped tokens in use include
`delete:organization`.
- `reqToken()` is used to enforce auth for individual routes that
require it. If a scoped token is not present for a request,
`tokenRequiresScopes()` will not return an error
## TODO
- [x] Alphabetize scope categories
- [x] Change 'public repos only' to a radio button (private vs public).
Also expand this to organizations
- [X] Disable token creation if no scopes selected. Alternatively, show
warning
- [x] `reqToken()` is missing from many `POST/DELETE` routes in the api.
`tokenRequiresScopes()` only checks that a given token has the correct
scope, `reqToken()` must be used to check that a token (or some other
auth) is present.
- _This should be addressed in this PR_
- [x] The migration should be reviewed very carefully in order to
minimize access changes to existing user tokens.
- _This should be addressed in this PR_
- [x] Link to api to swagger documentation, clarify what
read/write/delete levels correspond to
- [x] Review cases where more than one scope is needed as this directly
deviates from the api definition.
- _This should be addressed in this PR_
- For example:
```go
m.Group("/users/{username}/orgs", func() {
m.Get("", reqToken(), org.ListUserOrgs)
m.Get("/{org}/permissions", reqToken(), org.GetUserOrgsPermissions)
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser,
auth_model.AccessTokenScopeCategoryOrganization),
context_service.UserAssignmentAPI())
```
## Future improvements
- [ ] Add required scopes to swagger documentation
- [ ] Redesign `reqToken()` to be opt-out rather than opt-in
- [ ] Subdivide scopes like `repository`
- [ ] Once a token is created, if it has no scopes, we should display
text instead of an empty bullet point
- [ ] If the 'public repos only' option is selected, should read
categories be selected by default
Closes #24501
Closes #24799
Co-authored-by: Jonathan Tran <jon@allspice.io>
Co-authored-by: Kyle D <kdumontnu@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2023-06-05 02:57:16 +08:00
|
|
|
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue)
|
2024-03-04 16:16:03 +08:00
|
|
|
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues", owner.Name, repoBefore.Name)
|
2017-06-25 22:51:07 +08:00
|
|
|
req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateIssueOption{
|
|
|
|
Body: body,
|
|
|
|
Title: title,
|
|
|
|
Assignee: owner.Name,
|
2023-12-22 07:59:59 +08:00
|
|
|
}).AddTokenAuth(token)
|
2022-12-02 11:39:42 +08:00
|
|
|
resp := MakeRequest(t, req, http.StatusCreated)
|
2017-06-25 22:51:07 +08:00
|
|
|
var apiIssue api.Issue
|
|
|
|
DecodeJSON(t, resp, &apiIssue)
|
2021-06-07 13:27:09 +08:00
|
|
|
assert.Equal(t, body, apiIssue.Body)
|
|
|
|
assert.Equal(t, title, apiIssue.Title)
|
2017-06-25 22:51:07 +08:00
|
|
|
|
2022-06-13 17:37:59 +08:00
|
|
|
unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{
|
2020-02-20 15:46:46 +08:00
|
|
|
RepoID: repoBefore.ID,
|
2017-06-25 22:51:07 +08:00
|
|
|
AssigneeID: owner.ID,
|
|
|
|
Content: body,
|
|
|
|
Title: title,
|
|
|
|
})
|
2020-02-20 15:46:46 +08:00
|
|
|
|
2022-08-16 10:22:25 +08:00
|
|
|
repoAfter := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
2020-02-20 15:46:46 +08:00
|
|
|
assert.Equal(t, repoBefore.NumIssues+1, repoAfter.NumIssues)
|
|
|
|
assert.Equal(t, repoBefore.NumClosedIssues, repoAfter.NumClosedIssues)
|
2024-03-04 16:16:03 +08:00
|
|
|
|
|
|
|
user34 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 34})
|
|
|
|
req = NewRequestWithJSON(t, "POST", urlStr, &api.CreateIssueOption{
|
|
|
|
Title: title,
|
|
|
|
}).AddTokenAuth(getUserToken(t, user34.Name, auth_model.AccessTokenScopeWriteIssue))
|
|
|
|
MakeRequest(t, req, http.StatusForbidden)
|
2017-06-25 22:51:07 +08:00
|
|
|
}
|
2020-01-02 06:51:10 +08:00
|
|
|
|
2023-06-05 18:33:47 +08:00
|
|
|
func TestAPICreateIssueParallel(t *testing.T) {
|
|
|
|
defer tests.PrepareTestEnv(t)()
|
2024-11-25 14:10:11 +08:00
|
|
|
|
|
|
|
// FIXME: There seems to be a bug in github.com/mattn/go-sqlite3 with sqlite_unlock_notify, when doing concurrent writes to the same database,
|
|
|
|
// some requests may get stuck in "go-sqlite3.(*SQLiteRows).Next", "go-sqlite3.(*SQLiteStmt).exec" and "go-sqlite3.unlock_notify_wait",
|
|
|
|
// because the "unlock_notify_wait" never returns and the internal lock never gets releases.
|
|
|
|
//
|
|
|
|
// The trigger is: a previous test created issues and made the real issue indexer queue start processing, then this test does concurrent writing.
|
|
|
|
// Adding this "Sleep" makes go-sqlite3 "finish" some internal operations before concurrent writes and then won't get stuck.
|
|
|
|
// To reproduce: make a new test run these 2 tests enough times:
|
|
|
|
// > func TestBug() { for i := 0; i < 100; i++ { testAPICreateIssue(t); testAPICreateIssueParallel(t) } }
|
|
|
|
// Usually the test gets stuck in fewer than 10 iterations without this "sleep".
|
|
|
|
time.Sleep(time.Second)
|
|
|
|
|
2023-06-05 18:33:47 +08:00
|
|
|
const body, title = "apiTestBody", "apiTestTitle"
|
|
|
|
|
|
|
|
repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
|
|
|
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID})
|
|
|
|
|
|
|
|
session := loginUser(t, owner.Name)
|
|
|
|
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue)
|
2024-03-04 16:16:03 +08:00
|
|
|
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues", owner.Name, repoBefore.Name)
|
2023-06-05 18:33:47 +08:00
|
|
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
for i := 0; i < 10; i++ {
|
|
|
|
wg.Add(1)
|
|
|
|
go func(parentT *testing.T, i int) {
|
|
|
|
parentT.Run(fmt.Sprintf("ParallelCreateIssue_%d", i), func(t *testing.T) {
|
|
|
|
newTitle := title + strconv.Itoa(i)
|
|
|
|
newBody := body + strconv.Itoa(i)
|
|
|
|
req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateIssueOption{
|
|
|
|
Body: newBody,
|
|
|
|
Title: newTitle,
|
|
|
|
Assignee: owner.Name,
|
2023-12-22 07:59:59 +08:00
|
|
|
}).AddTokenAuth(token)
|
2023-06-05 18:33:47 +08:00
|
|
|
resp := MakeRequest(t, req, http.StatusCreated)
|
|
|
|
var apiIssue api.Issue
|
|
|
|
DecodeJSON(t, resp, &apiIssue)
|
|
|
|
assert.Equal(t, newBody, apiIssue.Body)
|
|
|
|
assert.Equal(t, newTitle, apiIssue.Title)
|
|
|
|
|
|
|
|
unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{
|
|
|
|
RepoID: repoBefore.ID,
|
|
|
|
AssigneeID: owner.ID,
|
|
|
|
Content: newBody,
|
|
|
|
Title: newTitle,
|
|
|
|
})
|
|
|
|
|
|
|
|
wg.Done()
|
|
|
|
})
|
|
|
|
}(t, i)
|
|
|
|
}
|
|
|
|
wg.Wait()
|
|
|
|
}
|
|
|
|
|
2020-01-02 06:51:10 +08:00
|
|
|
func TestAPIEditIssue(t *testing.T) {
|
2022-09-03 03:18:23 +08:00
|
|
|
defer tests.PrepareTestEnv(t)()
|
2020-01-02 06:51:10 +08:00
|
|
|
|
2022-08-16 10:22:25 +08:00
|
|
|
issueBefore := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10})
|
|
|
|
repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID})
|
|
|
|
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID})
|
2022-06-13 17:37:59 +08:00
|
|
|
assert.NoError(t, issueBefore.LoadAttributes(db.DefaultContext))
|
2020-01-02 06:51:10 +08:00
|
|
|
assert.Equal(t, int64(1019307200), int64(issueBefore.DeadlineUnix))
|
|
|
|
assert.Equal(t, api.StateOpen, issueBefore.State())
|
|
|
|
|
|
|
|
session := loginUser(t, owner.Name)
|
Redesign Scoped Access Tokens (#24767)
## Changes
- Adds the following high level access scopes, each with `read` and
`write` levels:
- `activitypub`
- `admin` (hidden if user is not a site admin)
- `misc`
- `notification`
- `organization`
- `package`
- `issue`
- `repository`
- `user`
- Adds new middleware function `tokenRequiresScopes()` in addition to
`reqToken()`
- `tokenRequiresScopes()` is used for each high-level api section
- _if_ a scoped token is present, checks that the required scope is
included based on the section and HTTP method
- `reqToken()` is used for individual routes
- checks that required authentication is present (but does not check
scope levels as this will already have been handled by
`tokenRequiresScopes()`
- Adds migration to convert old scoped access tokens to the new set of
scopes
- Updates the user interface for scope selection
### User interface example
<img width="903" alt="Screen Shot 2023-05-31 at 1 56 55 PM"
src="https://github.com/go-gitea/gitea/assets/23248839/654766ec-2143-4f59-9037-3b51600e32f3">
<img width="917" alt="Screen Shot 2023-05-31 at 1 56 43 PM"
src="https://github.com/go-gitea/gitea/assets/23248839/1ad64081-012c-4a73-b393-66b30352654c">
## tokenRequiresScopes Design Decision
- `tokenRequiresScopes()` was added to more reliably cover api routes.
For an incoming request, this function uses the given scope category
(say `AccessTokenScopeCategoryOrganization`) and the HTTP method (say
`DELETE`) and verifies that any scoped tokens in use include
`delete:organization`.
- `reqToken()` is used to enforce auth for individual routes that
require it. If a scoped token is not present for a request,
`tokenRequiresScopes()` will not return an error
## TODO
- [x] Alphabetize scope categories
- [x] Change 'public repos only' to a radio button (private vs public).
Also expand this to organizations
- [X] Disable token creation if no scopes selected. Alternatively, show
warning
- [x] `reqToken()` is missing from many `POST/DELETE` routes in the api.
`tokenRequiresScopes()` only checks that a given token has the correct
scope, `reqToken()` must be used to check that a token (or some other
auth) is present.
- _This should be addressed in this PR_
- [x] The migration should be reviewed very carefully in order to
minimize access changes to existing user tokens.
- _This should be addressed in this PR_
- [x] Link to api to swagger documentation, clarify what
read/write/delete levels correspond to
- [x] Review cases where more than one scope is needed as this directly
deviates from the api definition.
- _This should be addressed in this PR_
- For example:
```go
m.Group("/users/{username}/orgs", func() {
m.Get("", reqToken(), org.ListUserOrgs)
m.Get("/{org}/permissions", reqToken(), org.GetUserOrgsPermissions)
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser,
auth_model.AccessTokenScopeCategoryOrganization),
context_service.UserAssignmentAPI())
```
## Future improvements
- [ ] Add required scopes to swagger documentation
- [ ] Redesign `reqToken()` to be opt-out rather than opt-in
- [ ] Subdivide scopes like `repository`
- [ ] Once a token is created, if it has no scopes, we should display
text instead of an empty bullet point
- [ ] If the 'public repos only' option is selected, should read
categories be selected by default
Closes #24501
Closes #24799
Co-authored-by: Jonathan Tran <jon@allspice.io>
Co-authored-by: Kyle D <kdumontnu@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2023-06-05 02:57:16 +08:00
|
|
|
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue)
|
2020-01-02 06:51:10 +08:00
|
|
|
|
|
|
|
// update values of issue
|
|
|
|
issueState := "closed"
|
|
|
|
removeDeadline := true
|
|
|
|
milestone := int64(4)
|
|
|
|
body := "new content!"
|
|
|
|
title := "new title from api set"
|
|
|
|
|
2023-12-22 07:59:59 +08:00
|
|
|
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d", owner.Name, repoBefore.Name, issueBefore.Index)
|
2020-01-02 06:51:10 +08:00
|
|
|
req := NewRequestWithJSON(t, "PATCH", urlStr, api.EditIssueOption{
|
|
|
|
State: &issueState,
|
|
|
|
RemoveDeadline: &removeDeadline,
|
|
|
|
Milestone: &milestone,
|
|
|
|
Body: &body,
|
|
|
|
Title: title,
|
|
|
|
|
|
|
|
// ToDo change more
|
2023-12-22 07:59:59 +08:00
|
|
|
}).AddTokenAuth(token)
|
2022-12-02 11:39:42 +08:00
|
|
|
resp := MakeRequest(t, req, http.StatusCreated)
|
2020-01-02 06:51:10 +08:00
|
|
|
var apiIssue api.Issue
|
|
|
|
DecodeJSON(t, resp, &apiIssue)
|
|
|
|
|
2022-08-16 10:22:25 +08:00
|
|
|
issueAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10})
|
|
|
|
repoAfter := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID})
|
2020-01-02 06:51:10 +08:00
|
|
|
|
2024-05-03 14:11:51 +08:00
|
|
|
// check comment history
|
|
|
|
unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: issueAfter.ID, OldTitle: issueBefore.Title, NewTitle: title})
|
|
|
|
unittest.AssertExistsAndLoadBean(t, &issues_model.ContentHistory{IssueID: issueAfter.ID, ContentText: body, IsFirstCreated: false})
|
|
|
|
|
2020-01-02 06:51:10 +08:00
|
|
|
// check deleted user
|
|
|
|
assert.Equal(t, int64(500), issueAfter.PosterID)
|
2022-06-13 17:37:59 +08:00
|
|
|
assert.NoError(t, issueAfter.LoadAttributes(db.DefaultContext))
|
2020-01-02 06:51:10 +08:00
|
|
|
assert.Equal(t, int64(-1), issueAfter.PosterID)
|
|
|
|
assert.Equal(t, int64(-1), issueBefore.PosterID)
|
|
|
|
assert.Equal(t, int64(-1), apiIssue.Poster.ID)
|
|
|
|
|
2020-02-20 15:46:46 +08:00
|
|
|
// check repo change
|
|
|
|
assert.Equal(t, repoBefore.NumClosedIssues+1, repoAfter.NumClosedIssues)
|
|
|
|
|
2020-01-02 06:51:10 +08:00
|
|
|
// API response
|
|
|
|
assert.Equal(t, api.StateClosed, apiIssue.State)
|
|
|
|
assert.Equal(t, milestone, apiIssue.Milestone.ID)
|
|
|
|
assert.Equal(t, body, apiIssue.Body)
|
|
|
|
assert.True(t, apiIssue.Deadline == nil)
|
|
|
|
assert.Equal(t, title, apiIssue.Title)
|
|
|
|
|
|
|
|
// in database
|
|
|
|
assert.Equal(t, api.StateClosed, issueAfter.State())
|
|
|
|
assert.Equal(t, milestone, issueAfter.MilestoneID)
|
|
|
|
assert.Equal(t, int64(0), int64(issueAfter.DeadlineUnix))
|
|
|
|
assert.Equal(t, body, issueAfter.Content)
|
|
|
|
assert.Equal(t, title, issueAfter.Title)
|
|
|
|
}
|
2020-01-12 14:35:11 +08:00
|
|
|
|
Add Organization Wide Labels (#10814)
* Add organization wide labels
Implement organization wide labels similar to organization wide
webhooks. This lets you create individual labels for organizations that can be used
for all repos under that organization (so being able to reuse the same
label across multiple repos).
This makes it possible for small organizations with many repos to use
labels effectively.
Fixes #7406
* Add migration
* remove comments
* fix tests
* Update options/locale/locale_en-US.ini
Removed unused translation string
* show org labels in issue search label filter
* Use more clear var name
* rename migration after merge from master
* comment typo
* update migration again after rebase with master
* check for orgID <=0 per guillep2k review
* fmt
* Apply suggestions from code review
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* remove unused code
* Make sure RepoID is 0 when searching orgID per code review
* more changes/code review requests
* More descriptive translation var per code review
* func description/delete comment when issue label deleted instead of hiding it
* remove comment
* only use issues in that repo when calculating number of open issues for org label on repo label page
* Add integration test for IssuesSearch API with labels
* remove unused function
* Update models/issue_label.go
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* Use subquery in GetLabelIDsInReposByNames
* Fix tests to use correct orgID
* fix more tests
* IssuesSearch api now uses new BuildLabelNamesIssueIDsCondition. Add a few more tests as well
* update comment for clarity
* Revert previous code change now that we can use the new BuildLabelNamesIssueIDsCondition
* Don't sort repos by date in IssuesSearch API
After much debugging I've found a strange issue where in some cases MySQL will return a different result than other enigines if a query is sorted by a null collumn. For example with our integration test data where we don't set updated_unix in repository fixtures:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 45
Returns different results for MySQL than other engines. However, the similar query:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 30
Returns the same results.
This causes integration tests to fail on MySQL in certain cases but would never show up in a real installation. Since this API call always returns issues based on the optionally provided repo_priority_id or the issueID itself, there is no change to results by changing the repo sorting method used to get ids earlier in the function.
* linter is back!
* code review
* remove now unused option
* Fix newline at end of files
* more unused code
* update to master
* check for matching ids before query
* Update models/issue_label.go
Co-Authored-By: 6543 <6543@obermui.de>
* Update models/issue_label.go
* update comments
* Update routers/org/setting.go
Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
Co-authored-by: 6543 <6543@obermui.de>
2020-04-01 12:14:46 +08:00
|
|
|
func TestAPISearchIssues(t *testing.T) {
|
2022-09-03 03:18:23 +08:00
|
|
|
defer tests.PrepareTestEnv(t)()
|
2020-01-12 14:35:11 +08:00
|
|
|
|
2022-08-06 18:43:40 +08:00
|
|
|
// as this API was used in the frontend, it uses UI page size
|
2024-02-24 20:38:43 +08:00
|
|
|
expectedIssueCount := 20 // from the fixtures
|
2022-08-06 18:43:40 +08:00
|
|
|
if expectedIssueCount > setting.UI.IssuePagingNum {
|
|
|
|
expectedIssueCount = setting.UI.IssuePagingNum
|
|
|
|
}
|
|
|
|
|
2020-01-12 14:35:11 +08:00
|
|
|
link, _ := url.Parse("/api/v1/repos/issues/search")
|
2023-12-23 11:29:51 +08:00
|
|
|
token := getUserToken(t, "user1", auth_model.AccessTokenScopeReadIssue)
|
|
|
|
query := url.Values{}
|
2020-01-12 14:35:11 +08:00
|
|
|
var apiIssues []*api.Issue
|
|
|
|
|
|
|
|
link.RawQuery = query.Encode()
|
2023-12-23 11:29:51 +08:00
|
|
|
req := NewRequest(t, "GET", link.String()).AddTokenAuth(token)
|
2022-08-06 18:43:40 +08:00
|
|
|
resp := MakeRequest(t, req, http.StatusOK)
|
2020-01-12 14:35:11 +08:00
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
2022-08-06 18:43:40 +08:00
|
|
|
assert.Len(t, apiIssues, expectedIssueCount)
|
2020-01-12 14:35:11 +08:00
|
|
|
|
2024-10-08 17:51:09 +08:00
|
|
|
publicOnlyToken := getUserToken(t, "user1", auth_model.AccessTokenScopeReadIssue, auth_model.AccessTokenScopePublicOnly)
|
|
|
|
req = NewRequest(t, "GET", link.String()).AddTokenAuth(publicOnlyToken)
|
|
|
|
resp = MakeRequest(t, req, http.StatusOK)
|
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
|
|
|
assert.Len(t, apiIssues, 15) // 15 public issues
|
|
|
|
|
2023-09-01 20:01:36 +08:00
|
|
|
since := "2000-01-01T00:50:01+00:00" // 946687801
|
2020-11-24 04:49:36 +08:00
|
|
|
before := time.Unix(999307200, 0).Format(time.RFC3339)
|
|
|
|
query.Add("since", since)
|
|
|
|
query.Add("before", before)
|
|
|
|
link.RawQuery = query.Encode()
|
2023-12-23 11:29:51 +08:00
|
|
|
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
|
2022-04-08 12:22:10 +08:00
|
|
|
resp = MakeRequest(t, req, http.StatusOK)
|
2020-11-24 04:49:36 +08:00
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
2023-09-21 19:59:50 +08:00
|
|
|
assert.Len(t, apiIssues, 11)
|
2020-11-24 04:49:36 +08:00
|
|
|
query.Del("since")
|
|
|
|
query.Del("before")
|
|
|
|
|
2020-01-12 14:35:11 +08:00
|
|
|
query.Add("state", "closed")
|
|
|
|
link.RawQuery = query.Encode()
|
2023-12-23 11:29:51 +08:00
|
|
|
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
|
2022-04-08 12:22:10 +08:00
|
|
|
resp = MakeRequest(t, req, http.StatusOK)
|
2020-01-12 14:35:11 +08:00
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
|
|
|
assert.Len(t, apiIssues, 2)
|
|
|
|
|
|
|
|
query.Set("state", "all")
|
|
|
|
link.RawQuery = query.Encode()
|
2023-12-23 11:29:51 +08:00
|
|
|
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
|
2022-04-08 12:22:10 +08:00
|
|
|
resp = MakeRequest(t, req, http.StatusOK)
|
2020-01-12 14:35:11 +08:00
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
2024-02-24 20:38:43 +08:00
|
|
|
assert.EqualValues(t, "22", resp.Header().Get("X-Total-Count"))
|
2023-09-21 19:59:50 +08:00
|
|
|
assert.Len(t, apiIssues, 20)
|
2020-01-12 14:35:11 +08:00
|
|
|
|
2022-08-06 18:43:40 +08:00
|
|
|
query.Add("limit", "10")
|
2020-01-12 14:35:11 +08:00
|
|
|
link.RawQuery = query.Encode()
|
2023-12-23 11:29:51 +08:00
|
|
|
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
|
2022-04-08 12:22:10 +08:00
|
|
|
resp = MakeRequest(t, req, http.StatusOK)
|
2020-01-12 14:35:11 +08:00
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
2024-02-24 20:38:43 +08:00
|
|
|
assert.EqualValues(t, "22", resp.Header().Get("X-Total-Count"))
|
2022-08-06 18:43:40 +08:00
|
|
|
assert.Len(t, apiIssues, 10)
|
2020-11-24 04:49:36 +08:00
|
|
|
|
2023-12-23 11:29:51 +08:00
|
|
|
query = url.Values{"assigned": {"true"}, "state": {"all"}}
|
2020-11-24 04:49:36 +08:00
|
|
|
link.RawQuery = query.Encode()
|
2023-12-23 11:29:51 +08:00
|
|
|
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
|
2022-04-08 12:22:10 +08:00
|
|
|
resp = MakeRequest(t, req, http.StatusOK)
|
2020-11-24 04:49:36 +08:00
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
2022-05-16 17:49:17 +08:00
|
|
|
assert.Len(t, apiIssues, 2)
|
2021-06-17 14:40:59 +08:00
|
|
|
|
2023-12-23 11:29:51 +08:00
|
|
|
query = url.Values{"milestones": {"milestone1"}, "state": {"all"}}
|
2021-06-17 14:40:59 +08:00
|
|
|
link.RawQuery = query.Encode()
|
2023-12-23 11:29:51 +08:00
|
|
|
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
|
2022-04-08 12:22:10 +08:00
|
|
|
resp = MakeRequest(t, req, http.StatusOK)
|
2021-06-17 14:40:59 +08:00
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
|
|
|
assert.Len(t, apiIssues, 1)
|
|
|
|
|
2023-12-23 11:29:51 +08:00
|
|
|
query = url.Values{"milestones": {"milestone1,milestone3"}, "state": {"all"}}
|
2021-06-17 14:40:59 +08:00
|
|
|
link.RawQuery = query.Encode()
|
2023-12-23 11:29:51 +08:00
|
|
|
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
|
2022-04-08 12:22:10 +08:00
|
|
|
resp = MakeRequest(t, req, http.StatusOK)
|
2021-08-14 04:47:25 +08:00
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
|
|
|
assert.Len(t, apiIssues, 2)
|
|
|
|
|
2023-12-23 11:29:51 +08:00
|
|
|
query = url.Values{"owner": {"user2"}} // user
|
2021-08-14 04:47:25 +08:00
|
|
|
link.RawQuery = query.Encode()
|
2023-12-23 11:29:51 +08:00
|
|
|
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
|
2022-04-08 12:22:10 +08:00
|
|
|
resp = MakeRequest(t, req, http.StatusOK)
|
2021-08-14 04:47:25 +08:00
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
2023-07-29 03:18:12 +08:00
|
|
|
assert.Len(t, apiIssues, 8)
|
2021-08-14 04:47:25 +08:00
|
|
|
|
2023-12-23 11:29:51 +08:00
|
|
|
query = url.Values{"owner": {"org3"}} // organization
|
2021-08-14 04:47:25 +08:00
|
|
|
link.RawQuery = query.Encode()
|
2023-12-23 11:29:51 +08:00
|
|
|
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
|
2022-04-08 12:22:10 +08:00
|
|
|
resp = MakeRequest(t, req, http.StatusOK)
|
2021-08-14 04:47:25 +08:00
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
2022-05-16 17:49:17 +08:00
|
|
|
assert.Len(t, apiIssues, 5)
|
2021-08-14 04:47:25 +08:00
|
|
|
|
2023-12-23 11:29:51 +08:00
|
|
|
query = url.Values{"owner": {"org3"}, "team": {"team1"}} // organization + team
|
2021-08-14 04:47:25 +08:00
|
|
|
link.RawQuery = query.Encode()
|
2023-12-23 11:29:51 +08:00
|
|
|
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
|
2022-04-08 12:22:10 +08:00
|
|
|
resp = MakeRequest(t, req, http.StatusOK)
|
2021-06-17 14:40:59 +08:00
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
|
|
|
assert.Len(t, apiIssues, 2)
|
2020-01-12 14:35:11 +08:00
|
|
|
}
|
Add Organization Wide Labels (#10814)
* Add organization wide labels
Implement organization wide labels similar to organization wide
webhooks. This lets you create individual labels for organizations that can be used
for all repos under that organization (so being able to reuse the same
label across multiple repos).
This makes it possible for small organizations with many repos to use
labels effectively.
Fixes #7406
* Add migration
* remove comments
* fix tests
* Update options/locale/locale_en-US.ini
Removed unused translation string
* show org labels in issue search label filter
* Use more clear var name
* rename migration after merge from master
* comment typo
* update migration again after rebase with master
* check for orgID <=0 per guillep2k review
* fmt
* Apply suggestions from code review
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* remove unused code
* Make sure RepoID is 0 when searching orgID per code review
* more changes/code review requests
* More descriptive translation var per code review
* func description/delete comment when issue label deleted instead of hiding it
* remove comment
* only use issues in that repo when calculating number of open issues for org label on repo label page
* Add integration test for IssuesSearch API with labels
* remove unused function
* Update models/issue_label.go
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* Use subquery in GetLabelIDsInReposByNames
* Fix tests to use correct orgID
* fix more tests
* IssuesSearch api now uses new BuildLabelNamesIssueIDsCondition. Add a few more tests as well
* update comment for clarity
* Revert previous code change now that we can use the new BuildLabelNamesIssueIDsCondition
* Don't sort repos by date in IssuesSearch API
After much debugging I've found a strange issue where in some cases MySQL will return a different result than other enigines if a query is sorted by a null collumn. For example with our integration test data where we don't set updated_unix in repository fixtures:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 45
Returns different results for MySQL than other engines. However, the similar query:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 30
Returns the same results.
This causes integration tests to fail on MySQL in certain cases but would never show up in a real installation. Since this API call always returns issues based on the optionally provided repo_priority_id or the issueID itself, there is no change to results by changing the repo sorting method used to get ids earlier in the function.
* linter is back!
* code review
* remove now unused option
* Fix newline at end of files
* more unused code
* update to master
* check for matching ids before query
* Update models/issue_label.go
Co-Authored-By: 6543 <6543@obermui.de>
* Update models/issue_label.go
* update comments
* Update routers/org/setting.go
Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
Co-authored-by: 6543 <6543@obermui.de>
2020-04-01 12:14:46 +08:00
|
|
|
|
|
|
|
func TestAPISearchIssuesWithLabels(t *testing.T) {
|
2022-09-03 03:18:23 +08:00
|
|
|
defer tests.PrepareTestEnv(t)()
|
Add Organization Wide Labels (#10814)
* Add organization wide labels
Implement organization wide labels similar to organization wide
webhooks. This lets you create individual labels for organizations that can be used
for all repos under that organization (so being able to reuse the same
label across multiple repos).
This makes it possible for small organizations with many repos to use
labels effectively.
Fixes #7406
* Add migration
* remove comments
* fix tests
* Update options/locale/locale_en-US.ini
Removed unused translation string
* show org labels in issue search label filter
* Use more clear var name
* rename migration after merge from master
* comment typo
* update migration again after rebase with master
* check for orgID <=0 per guillep2k review
* fmt
* Apply suggestions from code review
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* remove unused code
* Make sure RepoID is 0 when searching orgID per code review
* more changes/code review requests
* More descriptive translation var per code review
* func description/delete comment when issue label deleted instead of hiding it
* remove comment
* only use issues in that repo when calculating number of open issues for org label on repo label page
* Add integration test for IssuesSearch API with labels
* remove unused function
* Update models/issue_label.go
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* Use subquery in GetLabelIDsInReposByNames
* Fix tests to use correct orgID
* fix more tests
* IssuesSearch api now uses new BuildLabelNamesIssueIDsCondition. Add a few more tests as well
* update comment for clarity
* Revert previous code change now that we can use the new BuildLabelNamesIssueIDsCondition
* Don't sort repos by date in IssuesSearch API
After much debugging I've found a strange issue where in some cases MySQL will return a different result than other enigines if a query is sorted by a null collumn. For example with our integration test data where we don't set updated_unix in repository fixtures:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 45
Returns different results for MySQL than other engines. However, the similar query:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 30
Returns the same results.
This causes integration tests to fail on MySQL in certain cases but would never show up in a real installation. Since this API call always returns issues based on the optionally provided repo_priority_id or the issueID itself, there is no change to results by changing the repo sorting method used to get ids earlier in the function.
* linter is back!
* code review
* remove now unused option
* Fix newline at end of files
* more unused code
* update to master
* check for matching ids before query
* Update models/issue_label.go
Co-Authored-By: 6543 <6543@obermui.de>
* Update models/issue_label.go
* update comments
* Update routers/org/setting.go
Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
Co-authored-by: 6543 <6543@obermui.de>
2020-04-01 12:14:46 +08:00
|
|
|
|
2022-08-06 18:43:40 +08:00
|
|
|
// as this API was used in the frontend, it uses UI page size
|
2024-02-24 20:38:43 +08:00
|
|
|
expectedIssueCount := 20 // from the fixtures
|
2022-08-06 18:43:40 +08:00
|
|
|
if expectedIssueCount > setting.UI.IssuePagingNum {
|
|
|
|
expectedIssueCount = setting.UI.IssuePagingNum
|
|
|
|
}
|
Add Organization Wide Labels (#10814)
* Add organization wide labels
Implement organization wide labels similar to organization wide
webhooks. This lets you create individual labels for organizations that can be used
for all repos under that organization (so being able to reuse the same
label across multiple repos).
This makes it possible for small organizations with many repos to use
labels effectively.
Fixes #7406
* Add migration
* remove comments
* fix tests
* Update options/locale/locale_en-US.ini
Removed unused translation string
* show org labels in issue search label filter
* Use more clear var name
* rename migration after merge from master
* comment typo
* update migration again after rebase with master
* check for orgID <=0 per guillep2k review
* fmt
* Apply suggestions from code review
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* remove unused code
* Make sure RepoID is 0 when searching orgID per code review
* more changes/code review requests
* More descriptive translation var per code review
* func description/delete comment when issue label deleted instead of hiding it
* remove comment
* only use issues in that repo when calculating number of open issues for org label on repo label page
* Add integration test for IssuesSearch API with labels
* remove unused function
* Update models/issue_label.go
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* Use subquery in GetLabelIDsInReposByNames
* Fix tests to use correct orgID
* fix more tests
* IssuesSearch api now uses new BuildLabelNamesIssueIDsCondition. Add a few more tests as well
* update comment for clarity
* Revert previous code change now that we can use the new BuildLabelNamesIssueIDsCondition
* Don't sort repos by date in IssuesSearch API
After much debugging I've found a strange issue where in some cases MySQL will return a different result than other enigines if a query is sorted by a null collumn. For example with our integration test data where we don't set updated_unix in repository fixtures:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 45
Returns different results for MySQL than other engines. However, the similar query:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 30
Returns the same results.
This causes integration tests to fail on MySQL in certain cases but would never show up in a real installation. Since this API call always returns issues based on the optionally provided repo_priority_id or the issueID itself, there is no change to results by changing the repo sorting method used to get ids earlier in the function.
* linter is back!
* code review
* remove now unused option
* Fix newline at end of files
* more unused code
* update to master
* check for matching ids before query
* Update models/issue_label.go
Co-Authored-By: 6543 <6543@obermui.de>
* Update models/issue_label.go
* update comments
* Update routers/org/setting.go
Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
Co-authored-by: 6543 <6543@obermui.de>
2020-04-01 12:14:46 +08:00
|
|
|
|
|
|
|
link, _ := url.Parse("/api/v1/repos/issues/search")
|
2023-12-23 11:29:51 +08:00
|
|
|
token := getUserToken(t, "user1", auth_model.AccessTokenScopeReadIssue)
|
|
|
|
query := url.Values{}
|
Add Organization Wide Labels (#10814)
* Add organization wide labels
Implement organization wide labels similar to organization wide
webhooks. This lets you create individual labels for organizations that can be used
for all repos under that organization (so being able to reuse the same
label across multiple repos).
This makes it possible for small organizations with many repos to use
labels effectively.
Fixes #7406
* Add migration
* remove comments
* fix tests
* Update options/locale/locale_en-US.ini
Removed unused translation string
* show org labels in issue search label filter
* Use more clear var name
* rename migration after merge from master
* comment typo
* update migration again after rebase with master
* check for orgID <=0 per guillep2k review
* fmt
* Apply suggestions from code review
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* remove unused code
* Make sure RepoID is 0 when searching orgID per code review
* more changes/code review requests
* More descriptive translation var per code review
* func description/delete comment when issue label deleted instead of hiding it
* remove comment
* only use issues in that repo when calculating number of open issues for org label on repo label page
* Add integration test for IssuesSearch API with labels
* remove unused function
* Update models/issue_label.go
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* Use subquery in GetLabelIDsInReposByNames
* Fix tests to use correct orgID
* fix more tests
* IssuesSearch api now uses new BuildLabelNamesIssueIDsCondition. Add a few more tests as well
* update comment for clarity
* Revert previous code change now that we can use the new BuildLabelNamesIssueIDsCondition
* Don't sort repos by date in IssuesSearch API
After much debugging I've found a strange issue where in some cases MySQL will return a different result than other enigines if a query is sorted by a null collumn. For example with our integration test data where we don't set updated_unix in repository fixtures:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 45
Returns different results for MySQL than other engines. However, the similar query:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 30
Returns the same results.
This causes integration tests to fail on MySQL in certain cases but would never show up in a real installation. Since this API call always returns issues based on the optionally provided repo_priority_id or the issueID itself, there is no change to results by changing the repo sorting method used to get ids earlier in the function.
* linter is back!
* code review
* remove now unused option
* Fix newline at end of files
* more unused code
* update to master
* check for matching ids before query
* Update models/issue_label.go
Co-Authored-By: 6543 <6543@obermui.de>
* Update models/issue_label.go
* update comments
* Update routers/org/setting.go
Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
Co-authored-by: 6543 <6543@obermui.de>
2020-04-01 12:14:46 +08:00
|
|
|
var apiIssues []*api.Issue
|
|
|
|
|
|
|
|
link.RawQuery = query.Encode()
|
2023-12-23 11:29:51 +08:00
|
|
|
req := NewRequest(t, "GET", link.String()).AddTokenAuth(token)
|
2022-08-06 18:43:40 +08:00
|
|
|
resp := MakeRequest(t, req, http.StatusOK)
|
Add Organization Wide Labels (#10814)
* Add organization wide labels
Implement organization wide labels similar to organization wide
webhooks. This lets you create individual labels for organizations that can be used
for all repos under that organization (so being able to reuse the same
label across multiple repos).
This makes it possible for small organizations with many repos to use
labels effectively.
Fixes #7406
* Add migration
* remove comments
* fix tests
* Update options/locale/locale_en-US.ini
Removed unused translation string
* show org labels in issue search label filter
* Use more clear var name
* rename migration after merge from master
* comment typo
* update migration again after rebase with master
* check for orgID <=0 per guillep2k review
* fmt
* Apply suggestions from code review
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* remove unused code
* Make sure RepoID is 0 when searching orgID per code review
* more changes/code review requests
* More descriptive translation var per code review
* func description/delete comment when issue label deleted instead of hiding it
* remove comment
* only use issues in that repo when calculating number of open issues for org label on repo label page
* Add integration test for IssuesSearch API with labels
* remove unused function
* Update models/issue_label.go
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* Use subquery in GetLabelIDsInReposByNames
* Fix tests to use correct orgID
* fix more tests
* IssuesSearch api now uses new BuildLabelNamesIssueIDsCondition. Add a few more tests as well
* update comment for clarity
* Revert previous code change now that we can use the new BuildLabelNamesIssueIDsCondition
* Don't sort repos by date in IssuesSearch API
After much debugging I've found a strange issue where in some cases MySQL will return a different result than other enigines if a query is sorted by a null collumn. For example with our integration test data where we don't set updated_unix in repository fixtures:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 45
Returns different results for MySQL than other engines. However, the similar query:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 30
Returns the same results.
This causes integration tests to fail on MySQL in certain cases but would never show up in a real installation. Since this API call always returns issues based on the optionally provided repo_priority_id or the issueID itself, there is no change to results by changing the repo sorting method used to get ids earlier in the function.
* linter is back!
* code review
* remove now unused option
* Fix newline at end of files
* more unused code
* update to master
* check for matching ids before query
* Update models/issue_label.go
Co-Authored-By: 6543 <6543@obermui.de>
* Update models/issue_label.go
* update comments
* Update routers/org/setting.go
Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
Co-authored-by: 6543 <6543@obermui.de>
2020-04-01 12:14:46 +08:00
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
2022-08-06 18:43:40 +08:00
|
|
|
assert.Len(t, apiIssues, expectedIssueCount)
|
Add Organization Wide Labels (#10814)
* Add organization wide labels
Implement organization wide labels similar to organization wide
webhooks. This lets you create individual labels for organizations that can be used
for all repos under that organization (so being able to reuse the same
label across multiple repos).
This makes it possible for small organizations with many repos to use
labels effectively.
Fixes #7406
* Add migration
* remove comments
* fix tests
* Update options/locale/locale_en-US.ini
Removed unused translation string
* show org labels in issue search label filter
* Use more clear var name
* rename migration after merge from master
* comment typo
* update migration again after rebase with master
* check for orgID <=0 per guillep2k review
* fmt
* Apply suggestions from code review
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* remove unused code
* Make sure RepoID is 0 when searching orgID per code review
* more changes/code review requests
* More descriptive translation var per code review
* func description/delete comment when issue label deleted instead of hiding it
* remove comment
* only use issues in that repo when calculating number of open issues for org label on repo label page
* Add integration test for IssuesSearch API with labels
* remove unused function
* Update models/issue_label.go
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* Use subquery in GetLabelIDsInReposByNames
* Fix tests to use correct orgID
* fix more tests
* IssuesSearch api now uses new BuildLabelNamesIssueIDsCondition. Add a few more tests as well
* update comment for clarity
* Revert previous code change now that we can use the new BuildLabelNamesIssueIDsCondition
* Don't sort repos by date in IssuesSearch API
After much debugging I've found a strange issue where in some cases MySQL will return a different result than other enigines if a query is sorted by a null collumn. For example with our integration test data where we don't set updated_unix in repository fixtures:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 45
Returns different results for MySQL than other engines. However, the similar query:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 30
Returns the same results.
This causes integration tests to fail on MySQL in certain cases but would never show up in a real installation. Since this API call always returns issues based on the optionally provided repo_priority_id or the issueID itself, there is no change to results by changing the repo sorting method used to get ids earlier in the function.
* linter is back!
* code review
* remove now unused option
* Fix newline at end of files
* more unused code
* update to master
* check for matching ids before query
* Update models/issue_label.go
Co-Authored-By: 6543 <6543@obermui.de>
* Update models/issue_label.go
* update comments
* Update routers/org/setting.go
Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
Co-authored-by: 6543 <6543@obermui.de>
2020-04-01 12:14:46 +08:00
|
|
|
|
|
|
|
query.Add("labels", "label1")
|
|
|
|
link.RawQuery = query.Encode()
|
2023-12-23 11:29:51 +08:00
|
|
|
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
|
2022-04-08 12:22:10 +08:00
|
|
|
resp = MakeRequest(t, req, http.StatusOK)
|
Add Organization Wide Labels (#10814)
* Add organization wide labels
Implement organization wide labels similar to organization wide
webhooks. This lets you create individual labels for organizations that can be used
for all repos under that organization (so being able to reuse the same
label across multiple repos).
This makes it possible for small organizations with many repos to use
labels effectively.
Fixes #7406
* Add migration
* remove comments
* fix tests
* Update options/locale/locale_en-US.ini
Removed unused translation string
* show org labels in issue search label filter
* Use more clear var name
* rename migration after merge from master
* comment typo
* update migration again after rebase with master
* check for orgID <=0 per guillep2k review
* fmt
* Apply suggestions from code review
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* remove unused code
* Make sure RepoID is 0 when searching orgID per code review
* more changes/code review requests
* More descriptive translation var per code review
* func description/delete comment when issue label deleted instead of hiding it
* remove comment
* only use issues in that repo when calculating number of open issues for org label on repo label page
* Add integration test for IssuesSearch API with labels
* remove unused function
* Update models/issue_label.go
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* Use subquery in GetLabelIDsInReposByNames
* Fix tests to use correct orgID
* fix more tests
* IssuesSearch api now uses new BuildLabelNamesIssueIDsCondition. Add a few more tests as well
* update comment for clarity
* Revert previous code change now that we can use the new BuildLabelNamesIssueIDsCondition
* Don't sort repos by date in IssuesSearch API
After much debugging I've found a strange issue where in some cases MySQL will return a different result than other enigines if a query is sorted by a null collumn. For example with our integration test data where we don't set updated_unix in repository fixtures:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 45
Returns different results for MySQL than other engines. However, the similar query:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 30
Returns the same results.
This causes integration tests to fail on MySQL in certain cases but would never show up in a real installation. Since this API call always returns issues based on the optionally provided repo_priority_id or the issueID itself, there is no change to results by changing the repo sorting method used to get ids earlier in the function.
* linter is back!
* code review
* remove now unused option
* Fix newline at end of files
* more unused code
* update to master
* check for matching ids before query
* Update models/issue_label.go
Co-Authored-By: 6543 <6543@obermui.de>
* Update models/issue_label.go
* update comments
* Update routers/org/setting.go
Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
Co-authored-by: 6543 <6543@obermui.de>
2020-04-01 12:14:46 +08:00
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
|
|
|
assert.Len(t, apiIssues, 2)
|
|
|
|
|
|
|
|
// multiple labels
|
|
|
|
query.Set("labels", "label1,label2")
|
|
|
|
link.RawQuery = query.Encode()
|
2023-12-23 11:29:51 +08:00
|
|
|
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
|
2022-04-08 12:22:10 +08:00
|
|
|
resp = MakeRequest(t, req, http.StatusOK)
|
Add Organization Wide Labels (#10814)
* Add organization wide labels
Implement organization wide labels similar to organization wide
webhooks. This lets you create individual labels for organizations that can be used
for all repos under that organization (so being able to reuse the same
label across multiple repos).
This makes it possible for small organizations with many repos to use
labels effectively.
Fixes #7406
* Add migration
* remove comments
* fix tests
* Update options/locale/locale_en-US.ini
Removed unused translation string
* show org labels in issue search label filter
* Use more clear var name
* rename migration after merge from master
* comment typo
* update migration again after rebase with master
* check for orgID <=0 per guillep2k review
* fmt
* Apply suggestions from code review
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* remove unused code
* Make sure RepoID is 0 when searching orgID per code review
* more changes/code review requests
* More descriptive translation var per code review
* func description/delete comment when issue label deleted instead of hiding it
* remove comment
* only use issues in that repo when calculating number of open issues for org label on repo label page
* Add integration test for IssuesSearch API with labels
* remove unused function
* Update models/issue_label.go
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* Use subquery in GetLabelIDsInReposByNames
* Fix tests to use correct orgID
* fix more tests
* IssuesSearch api now uses new BuildLabelNamesIssueIDsCondition. Add a few more tests as well
* update comment for clarity
* Revert previous code change now that we can use the new BuildLabelNamesIssueIDsCondition
* Don't sort repos by date in IssuesSearch API
After much debugging I've found a strange issue where in some cases MySQL will return a different result than other enigines if a query is sorted by a null collumn. For example with our integration test data where we don't set updated_unix in repository fixtures:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 45
Returns different results for MySQL than other engines. However, the similar query:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 30
Returns the same results.
This causes integration tests to fail on MySQL in certain cases but would never show up in a real installation. Since this API call always returns issues based on the optionally provided repo_priority_id or the issueID itself, there is no change to results by changing the repo sorting method used to get ids earlier in the function.
* linter is back!
* code review
* remove now unused option
* Fix newline at end of files
* more unused code
* update to master
* check for matching ids before query
* Update models/issue_label.go
Co-Authored-By: 6543 <6543@obermui.de>
* Update models/issue_label.go
* update comments
* Update routers/org/setting.go
Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
Co-authored-by: 6543 <6543@obermui.de>
2020-04-01 12:14:46 +08:00
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
|
|
|
assert.Len(t, apiIssues, 2)
|
|
|
|
|
|
|
|
// an org label
|
|
|
|
query.Set("labels", "orglabel4")
|
|
|
|
link.RawQuery = query.Encode()
|
2023-12-23 11:29:51 +08:00
|
|
|
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
|
2022-04-08 12:22:10 +08:00
|
|
|
resp = MakeRequest(t, req, http.StatusOK)
|
Add Organization Wide Labels (#10814)
* Add organization wide labels
Implement organization wide labels similar to organization wide
webhooks. This lets you create individual labels for organizations that can be used
for all repos under that organization (so being able to reuse the same
label across multiple repos).
This makes it possible for small organizations with many repos to use
labels effectively.
Fixes #7406
* Add migration
* remove comments
* fix tests
* Update options/locale/locale_en-US.ini
Removed unused translation string
* show org labels in issue search label filter
* Use more clear var name
* rename migration after merge from master
* comment typo
* update migration again after rebase with master
* check for orgID <=0 per guillep2k review
* fmt
* Apply suggestions from code review
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* remove unused code
* Make sure RepoID is 0 when searching orgID per code review
* more changes/code review requests
* More descriptive translation var per code review
* func description/delete comment when issue label deleted instead of hiding it
* remove comment
* only use issues in that repo when calculating number of open issues for org label on repo label page
* Add integration test for IssuesSearch API with labels
* remove unused function
* Update models/issue_label.go
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* Use subquery in GetLabelIDsInReposByNames
* Fix tests to use correct orgID
* fix more tests
* IssuesSearch api now uses new BuildLabelNamesIssueIDsCondition. Add a few more tests as well
* update comment for clarity
* Revert previous code change now that we can use the new BuildLabelNamesIssueIDsCondition
* Don't sort repos by date in IssuesSearch API
After much debugging I've found a strange issue where in some cases MySQL will return a different result than other enigines if a query is sorted by a null collumn. For example with our integration test data where we don't set updated_unix in repository fixtures:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 45
Returns different results for MySQL than other engines. However, the similar query:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 30
Returns the same results.
This causes integration tests to fail on MySQL in certain cases but would never show up in a real installation. Since this API call always returns issues based on the optionally provided repo_priority_id or the issueID itself, there is no change to results by changing the repo sorting method used to get ids earlier in the function.
* linter is back!
* code review
* remove now unused option
* Fix newline at end of files
* more unused code
* update to master
* check for matching ids before query
* Update models/issue_label.go
Co-Authored-By: 6543 <6543@obermui.de>
* Update models/issue_label.go
* update comments
* Update routers/org/setting.go
Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
Co-authored-by: 6543 <6543@obermui.de>
2020-04-01 12:14:46 +08:00
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
|
|
|
assert.Len(t, apiIssues, 1)
|
|
|
|
|
|
|
|
// org and repo label
|
|
|
|
query.Set("labels", "label2,orglabel4")
|
|
|
|
query.Add("state", "all")
|
|
|
|
link.RawQuery = query.Encode()
|
2023-12-23 11:29:51 +08:00
|
|
|
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
|
2022-04-08 12:22:10 +08:00
|
|
|
resp = MakeRequest(t, req, http.StatusOK)
|
Add Organization Wide Labels (#10814)
* Add organization wide labels
Implement organization wide labels similar to organization wide
webhooks. This lets you create individual labels for organizations that can be used
for all repos under that organization (so being able to reuse the same
label across multiple repos).
This makes it possible for small organizations with many repos to use
labels effectively.
Fixes #7406
* Add migration
* remove comments
* fix tests
* Update options/locale/locale_en-US.ini
Removed unused translation string
* show org labels in issue search label filter
* Use more clear var name
* rename migration after merge from master
* comment typo
* update migration again after rebase with master
* check for orgID <=0 per guillep2k review
* fmt
* Apply suggestions from code review
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* remove unused code
* Make sure RepoID is 0 when searching orgID per code review
* more changes/code review requests
* More descriptive translation var per code review
* func description/delete comment when issue label deleted instead of hiding it
* remove comment
* only use issues in that repo when calculating number of open issues for org label on repo label page
* Add integration test for IssuesSearch API with labels
* remove unused function
* Update models/issue_label.go
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* Use subquery in GetLabelIDsInReposByNames
* Fix tests to use correct orgID
* fix more tests
* IssuesSearch api now uses new BuildLabelNamesIssueIDsCondition. Add a few more tests as well
* update comment for clarity
* Revert previous code change now that we can use the new BuildLabelNamesIssueIDsCondition
* Don't sort repos by date in IssuesSearch API
After much debugging I've found a strange issue where in some cases MySQL will return a different result than other enigines if a query is sorted by a null collumn. For example with our integration test data where we don't set updated_unix in repository fixtures:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 45
Returns different results for MySQL than other engines. However, the similar query:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 30
Returns the same results.
This causes integration tests to fail on MySQL in certain cases but would never show up in a real installation. Since this API call always returns issues based on the optionally provided repo_priority_id or the issueID itself, there is no change to results by changing the repo sorting method used to get ids earlier in the function.
* linter is back!
* code review
* remove now unused option
* Fix newline at end of files
* more unused code
* update to master
* check for matching ids before query
* Update models/issue_label.go
Co-Authored-By: 6543 <6543@obermui.de>
* Update models/issue_label.go
* update comments
* Update routers/org/setting.go
Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
Co-authored-by: 6543 <6543@obermui.de>
2020-04-01 12:14:46 +08:00
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
|
|
|
assert.Len(t, apiIssues, 2)
|
|
|
|
|
|
|
|
// org and repo label which share the same issue
|
|
|
|
query.Set("labels", "label1,orglabel4")
|
|
|
|
link.RawQuery = query.Encode()
|
2023-12-23 11:29:51 +08:00
|
|
|
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
|
2022-04-08 12:22:10 +08:00
|
|
|
resp = MakeRequest(t, req, http.StatusOK)
|
Add Organization Wide Labels (#10814)
* Add organization wide labels
Implement organization wide labels similar to organization wide
webhooks. This lets you create individual labels for organizations that can be used
for all repos under that organization (so being able to reuse the same
label across multiple repos).
This makes it possible for small organizations with many repos to use
labels effectively.
Fixes #7406
* Add migration
* remove comments
* fix tests
* Update options/locale/locale_en-US.ini
Removed unused translation string
* show org labels in issue search label filter
* Use more clear var name
* rename migration after merge from master
* comment typo
* update migration again after rebase with master
* check for orgID <=0 per guillep2k review
* fmt
* Apply suggestions from code review
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* remove unused code
* Make sure RepoID is 0 when searching orgID per code review
* more changes/code review requests
* More descriptive translation var per code review
* func description/delete comment when issue label deleted instead of hiding it
* remove comment
* only use issues in that repo when calculating number of open issues for org label on repo label page
* Add integration test for IssuesSearch API with labels
* remove unused function
* Update models/issue_label.go
Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com>
* Use subquery in GetLabelIDsInReposByNames
* Fix tests to use correct orgID
* fix more tests
* IssuesSearch api now uses new BuildLabelNamesIssueIDsCondition. Add a few more tests as well
* update comment for clarity
* Revert previous code change now that we can use the new BuildLabelNamesIssueIDsCondition
* Don't sort repos by date in IssuesSearch API
After much debugging I've found a strange issue where in some cases MySQL will return a different result than other enigines if a query is sorted by a null collumn. For example with our integration test data where we don't set updated_unix in repository fixtures:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 45
Returns different results for MySQL than other engines. However, the similar query:
SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 30
Returns the same results.
This causes integration tests to fail on MySQL in certain cases but would never show up in a real installation. Since this API call always returns issues based on the optionally provided repo_priority_id or the issueID itself, there is no change to results by changing the repo sorting method used to get ids earlier in the function.
* linter is back!
* code review
* remove now unused option
* Fix newline at end of files
* more unused code
* update to master
* check for matching ids before query
* Update models/issue_label.go
Co-Authored-By: 6543 <6543@obermui.de>
* Update models/issue_label.go
* update comments
* Update routers/org/setting.go
Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
Co-authored-by: 6543 <6543@obermui.de>
2020-04-01 12:14:46 +08:00
|
|
|
DecodeJSON(t, resp, &apiIssues)
|
|
|
|
assert.Len(t, apiIssues, 2)
|
|
|
|
}
|