From 06daf4e863a90ce49a594c23ef85fcc694772aa8 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 29 Oct 2019 11:17:45 +0100 Subject: [PATCH 01/29] add issue subscriber API --- .golangci.yml | 3 + modules/structs/issue.go | 6 + routers/api/v1/api.go | 5 + routers/api/v1/repo/issue.go | 205 +++++++++++++++++++++++++++++++++ templates/swagger/v1_json.tmpl | 159 +++++++++++++++++++++++++ 5 files changed, 378 insertions(+) diff --git a/.golangci.yml b/.golangci.yml index fd7393372be41..9b263918c951a 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -73,6 +73,9 @@ issues: - path: routers/routes/routes.go linters: - dupl + - path: routers/api/v1/repo/issue.go + linters: + - dupl - path: routers/repo/view.go linters: - dupl diff --git a/modules/structs/issue.go b/modules/structs/issue.go index 58fd7344b4f27..fe74b5b1bc1b1 100644 --- a/modules/structs/issue.go +++ b/modules/structs/issue.go @@ -113,3 +113,9 @@ type EditPriorityOption struct { // required:true Priority int `json:"priority"` } + +// IssueWatchers list of subscribers of an issue +type IssueWatchers struct { + // required:true + Subscribers []string `json:"subscribers"` +} diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index f8ab9025b780e..4c4b126ee4d3c 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -688,6 +688,11 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/start", reqToken(), repo.StartIssueStopwatch) m.Post("/stop", reqToken(), repo.StopIssueStopwatch) }) + m.Group("/subscriptions", func() { + m.Get("", reqToken(), bind(api.IssueWatchers{}), repo.GetIssueWatchers) + m.Put("/:user", reqToken(), repo.AddIssueSubscription) + m.Delete("/:user", reqToken(), repo.DelIssueSubscription) + }) }) }, mustEnableIssuesOrPulls) m.Group("/labels", func() { diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 426826653c109..f37c972ac9a77 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -598,3 +598,208 @@ func StopIssueStopwatch(ctx *context.APIContext) { ctx.Status(201) } + +// AddIssueSubscription add user to subscription list +func AddIssueSubscription(ctx *context.APIContext) { + // swagger:operation PUT /repos/{owner}/{repo}/issues/{index}/subscriptions/{user} issue issueAddSubscription + // --- + // summary: Add user to subscription list + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: index + // in: path + // description: index of the issue + // type: integer + // format: int64 + // required: true + // - name: user + // in: path + // description: user witch subscribe to issue + // type: string + // required: true + // responses: + // "201": + // "$ref": "#/responses/empty" + // "304": + // description: User has no right to add subscribe of other user + // "404": + // description: Issue not found + issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + if err != nil { + if models.IsErrIssueNotExist(err) { + ctx.NotFound() + } else { + ctx.Error(500, "GetIssueByIndex", err) + } + + return + } + + user, err := models.GetUserByName(ctx.Params(":user")) + if err != nil { + if models.IsErrUserNotExist(err) { + ctx.NotFound() + } else { + ctx.Error(500, "GetUserByName", err) + return + } + } + + if user.ID != ctx.User.ID && !ctx.User.IsAdmin { + ctx.Error(403, "User", nil) + return + } + + if err := models.CreateOrUpdateIssueWatch(user.ID, issue.ID, true); err != nil { + ctx.Error(500, "CreateOrUpdateIssueWatch", err) + return + } + + ctx.Status(201) +} + +// DelIssueSubscription remove user to subscription list +func DelIssueSubscription(ctx *context.APIContext) { + // swagger:operation DELETE /repos/{owner}/{repo}/issues/{index}/subscriptions/{user} issue issueDeleteSubscription + // --- + // summary: Delete user from subscription list + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: index + // in: path + // description: index of the issue + // type: integer + // format: int64 + // required: true + // - name: user + // in: path + // description: user witch unsubscribe to issue + // type: string + // required: true + // responses: + // "201": + // "$ref": "#/responses/empty" + // "304": + // description: User has no right to remove subscribe of other user + // "404": + // description: Issue not found + issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + if err != nil { + if models.IsErrIssueNotExist(err) { + ctx.NotFound() + } else { + ctx.Error(500, "GetIssueByIndex", err) + } + + return + } + + user, err := models.GetUserByName(ctx.Params(":user")) + if err != nil { + if models.IsErrUserNotExist(err) { + ctx.NotFound() + } else { + ctx.Error(500, "GetUserByName", err) + return + } + } + + if user.ID != ctx.User.ID && !ctx.User.IsAdmin { + ctx.Error(403, "User", nil) + return + } + + if err := models.CreateOrUpdateIssueWatch(user.ID, issue.ID, false); err != nil { + ctx.Error(500, "CreateOrUpdateIssueWatch", err) + return + } + + ctx.Status(201) +} + +// GetIssueWatchers return subscribers of an issue +func GetIssueWatchers(ctx *context.APIContext, form api.IssueWatchers) { + // swagger:operation GET /repos/{owner}/{repo}/issues/{index}/subscriptions issue issueSubscriptions + // --- + // summary: Get users who subscribed on an issue. + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: index + // in: path + // description: index of the issue + // type: integer + // format: int64 + // required: true + // responses: + // "201": + // "$ref": "#/responses/empty" + // "404": + // description: Issue not found + issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + if err != nil { + if models.IsErrIssueNotExist(err) { + ctx.NotFound() + } else { + ctx.Error(500, "GetIssueByIndex", err) + } + + return + } + + var subscribers []string + + iw, err := models.GetIssueWatchers(issue.ID) + if err != nil { + ctx.Error(500, "GetIssueWatchers", err) + return + } + + for _, s := range iw { + user, err := models.GetUserByID(s.UserID) + if err != nil { + continue + } + subscribers = append(subscribers, user.LoginName) + } + + ctx.JSON(200, api.IssueWatchers{Subscribers: subscribers}) +} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 5be36d23be94c..c933ac3edc49f 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -3731,6 +3731,165 @@ } } }, + "/repos/{owner}/{repo}/issues/{index}/subscriptions": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "issue" + ], + "summary": "Get users who subscribed on an issue.", + "operationId": "issueSubscriptions", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "int64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "$ref": "#/responses/empty" + }, + "404": { + "description": "Issue not found" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}/subscriptions/{user}": { + "put": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "issue" + ], + "summary": "Add user to subscription list", + "operationId": "issueAddSubscription", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "int64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "user witch subscribe to issue", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "$ref": "#/responses/empty" + }, + "304": { + "description": "User has no right to add subscribe of other user" + }, + "404": { + "description": "Issue not found" + } + } + }, + "delete": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "issue" + ], + "summary": "Delete user from subscription list", + "operationId": "issueDeleteSubscription", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "int64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "user witch unsubscribe to issue", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "$ref": "#/responses/empty" + }, + "304": { + "description": "User has no right to remove subscribe of other user" + }, + "404": { + "description": "Issue not found" + } + } + } + }, "/repos/{owner}/{repo}/keys": { "get": { "produces": [ From deaf69c801b08f347693f6d35103cd1bf6b8290d Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 29 Oct 2019 12:45:37 +0100 Subject: [PATCH 02/29] subscribers return []user.APIFormat --- modules/structs/issue.go | 6 ------ routers/api/v1/api.go | 2 +- routers/api/v1/repo/issue.go | 11 +++++------ 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/modules/structs/issue.go b/modules/structs/issue.go index fe74b5b1bc1b1..58fd7344b4f27 100644 --- a/modules/structs/issue.go +++ b/modules/structs/issue.go @@ -113,9 +113,3 @@ type EditPriorityOption struct { // required:true Priority int `json:"priority"` } - -// IssueWatchers list of subscribers of an issue -type IssueWatchers struct { - // required:true - Subscribers []string `json:"subscribers"` -} diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 4c4b126ee4d3c..d5889dd54a5d1 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -689,7 +689,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/stop", reqToken(), repo.StopIssueStopwatch) }) m.Group("/subscriptions", func() { - m.Get("", reqToken(), bind(api.IssueWatchers{}), repo.GetIssueWatchers) + m.Get("", reqToken(), bind(api.User{}), repo.GetIssueWatchers) m.Put("/:user", reqToken(), repo.AddIssueSubscription) m.Delete("/:user", reqToken(), repo.DelIssueSubscription) }) diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index f37c972ac9a77..e72d54f41d02f 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -744,7 +744,7 @@ func DelIssueSubscription(ctx *context.APIContext) { } // GetIssueWatchers return subscribers of an issue -func GetIssueWatchers(ctx *context.APIContext, form api.IssueWatchers) { +func GetIssueWatchers(ctx *context.APIContext, form api.User) { // swagger:operation GET /repos/{owner}/{repo}/issues/{index}/subscriptions issue issueSubscriptions // --- // summary: Get users who subscribed on an issue. @@ -785,21 +785,20 @@ func GetIssueWatchers(ctx *context.APIContext, form api.IssueWatchers) { return } - var subscribers []string - iw, err := models.GetIssueWatchers(issue.ID) if err != nil { ctx.Error(500, "GetIssueWatchers", err) return } - for _, s := range iw { + subscribers := make([]*api.User, len(iw)) + for i, s := range iw { user, err := models.GetUserByID(s.UserID) if err != nil { continue } - subscribers = append(subscribers, user.LoginName) + subscribers[i] = user.APIFormat() } - ctx.JSON(200, api.IssueWatchers{Subscribers: subscribers}) + ctx.JSON(200, subscribers) } From a7c7674b3f45875b6bfd0a7f2b55a53d08682907 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 29 Oct 2019 15:24:46 +0100 Subject: [PATCH 03/29] add comments --- routers/api/v1/repo/issue.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index e72d54f41d02f..3d67180120adb 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -658,6 +658,7 @@ func AddIssueSubscription(ctx *context.APIContext) { } } + //only admin and user for itself can change subscription if user.ID != ctx.User.ID && !ctx.User.IsAdmin { ctx.Error(403, "User", nil) return @@ -730,6 +731,7 @@ func DelIssueSubscription(ctx *context.APIContext) { } } + //only admin and user for itself can change subscription if user.ID != ctx.User.ID && !ctx.User.IsAdmin { ctx.Error(403, "User", nil) return From 413b2b63d92c36b9ba5337b4fc3672f672301123 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 29 Oct 2019 15:38:33 +0100 Subject: [PATCH 04/29] more meaningfull description --- routers/api/v1/repo/issue.go | 4 ++-- templates/swagger/v1_json.tmpl | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 3d67180120adb..993452d0b334f 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -634,7 +634,7 @@ func AddIssueSubscription(ctx *context.APIContext) { // "201": // "$ref": "#/responses/empty" // "304": - // description: User has no right to add subscribe of other user + // description: User can only subscribe itself if he is no admin // "404": // description: Issue not found issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) @@ -707,7 +707,7 @@ func DelIssueSubscription(ctx *context.APIContext) { // "201": // "$ref": "#/responses/empty" // "304": - // description: User has no right to remove subscribe of other user + // description: User can only subscribe itself if he is no admin // "404": // description: Issue not found issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index c933ac3edc49f..2c817c029ab72 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -3827,7 +3827,7 @@ "$ref": "#/responses/empty" }, "304": { - "description": "User has no right to add subscribe of other user" + "description": "User can only subscribe itself if he is no admin" }, "404": { "description": "Issue not found" @@ -3882,7 +3882,7 @@ "$ref": "#/responses/empty" }, "304": { - "description": "User has no right to remove subscribe of other user" + "description": "User can only subscribe itself if he is no admin" }, "404": { "description": "Issue not found" From 7c24ae37b8393551505b272030e0117bb03b24cb Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 29 Oct 2019 16:27:44 +0100 Subject: [PATCH 05/29] without "reqToken()" api works ... * should be still secure beause ctx.user has to be there or nothing will hapen --- routers/api/v1/api.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index d5889dd54a5d1..1ef99fdc95629 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -689,9 +689,9 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/stop", reqToken(), repo.StopIssueStopwatch) }) m.Group("/subscriptions", func() { - m.Get("", reqToken(), bind(api.User{}), repo.GetIssueWatchers) - m.Put("/:user", reqToken(), repo.AddIssueSubscription) - m.Delete("/:user", reqToken(), repo.DelIssueSubscription) + m.Get("", bind(api.User{}), repo.GetIssueWatchers) + m.Put("/:user", repo.AddIssueSubscription) + m.Delete("/:user", repo.DelIssueSubscription) }) }) }, mustEnableIssuesOrPulls) From 5eca9291858a821981992b0aaa38cef610d84bca Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 29 Oct 2019 18:32:35 +0100 Subject: [PATCH 06/29] FIX: getIssueWatchers() get only aktive suscriber --- models/issue_watch.go | 1 + 1 file changed, 1 insertion(+) diff --git a/models/issue_watch.go b/models/issue_watch.go index 2f55c6a84db86..06f6d61800886 100644 --- a/models/issue_watch.go +++ b/models/issue_watch.go @@ -65,6 +65,7 @@ func GetIssueWatchers(issueID int64) ([]*IssueWatch, error) { func getIssueWatchers(e Engine, issueID int64) (watches []*IssueWatch, err error) { err = e. Where("`issue_watch`.issue_id = ?", issueID). + And("`issue_watch`.is_watching > ?", 0). And("`user`.is_active = ?", true). And("`user`.prohibit_login = ?", false). Join("INNER", "`user`", "`user`.id = `issue_watch`.user_id"). From e8bb5572a0120ba38c5c9ff01db0789a3986d332 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 29 Oct 2019 18:35:05 +0100 Subject: [PATCH 07/29] add return avter error on right position --- routers/api/v1/repo/issue.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 993452d0b334f..6fcb2abfb64a8 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -654,8 +654,9 @@ func AddIssueSubscription(ctx *context.APIContext) { ctx.NotFound() } else { ctx.Error(500, "GetUserByName", err) - return } + + return } //only admin and user for itself can change subscription @@ -727,8 +728,9 @@ func DelIssueSubscription(ctx *context.APIContext) { ctx.NotFound() } else { ctx.Error(500, "GetUserByName", err) - return } + + return } //only admin and user for itself can change subscription From 2ca4a7e49ee80b4bb9c5b65fa46500751df5ba12 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 29 Oct 2019 19:31:48 +0100 Subject: [PATCH 08/29] Revert "FIX: getIssueWatchers() get only aktive suscriber" This reverts commit 5eca9291858a821981992b0aaa38cef610d84bca. --- models/issue_watch.go | 1 - 1 file changed, 1 deletion(-) diff --git a/models/issue_watch.go b/models/issue_watch.go index 06f6d61800886..2f55c6a84db86 100644 --- a/models/issue_watch.go +++ b/models/issue_watch.go @@ -65,7 +65,6 @@ func GetIssueWatchers(issueID int64) ([]*IssueWatch, error) { func getIssueWatchers(e Engine, issueID int64) (watches []*IssueWatch, err error) { err = e. Where("`issue_watch`.issue_id = ?", issueID). - And("`issue_watch`.is_watching > ?", 0). And("`user`.is_active = ?", true). And("`user`.prohibit_login = ?", false). Join("INNER", "`user`", "`user`.id = `issue_watch`.user_id"). From 432a38cb70c8dc7417ce7d8a814e72b3f63b4899 Mon Sep 17 00:00:00 2001 From: 6543 <24977596+6543@users.noreply.github.com> Date: Fri, 1 Nov 2019 04:18:57 +0100 Subject: [PATCH 09/29] Update routers/api/v1/repo/issue.go Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> --- routers/api/v1/repo/issue.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index a349aa8c1d165..9014a9c506725 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -759,7 +759,7 @@ func AddIssueSubscription(ctx *context.APIContext) { // required: true // - name: user // in: path - // description: user witch subscribe to issue + // description: user to subscribe // type: string // required: true // responses: From bab12356227e44334de113b76f12099de0b8aaa6 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Fri, 1 Nov 2019 04:19:54 +0100 Subject: [PATCH 10/29] test go linter again --- .golangci.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 9b263918c951a..fd7393372be41 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -73,9 +73,6 @@ issues: - path: routers/routes/routes.go linters: - dupl - - path: routers/api/v1/repo/issue.go - linters: - - dupl - path: routers/repo/view.go linters: - dupl From 69b5d7e9ca7861a975c462cdfc892486c219c267 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Fri, 1 Nov 2019 05:00:07 +0100 Subject: [PATCH 11/29] update swagger --- templates/swagger/v1_json.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 15f43bf268c15..d069ed9998229 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -3866,7 +3866,7 @@ }, { "type": "string", - "description": "user witch subscribe to issue", + "description": "user to subscribe", "name": "user", "in": "path", "required": true From 3d693faea6b8e79bd4e4b9edf5922aac394af3fd Mon Sep 17 00:00:00 2001 From: 6543 <24977596+6543@users.noreply.github.com> Date: Fri, 1 Nov 2019 05:06:50 +0100 Subject: [PATCH 12/29] GetIssueWatchers -> GetIssueSubscribers part one Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> --- routers/api/v1/api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 7238b4aad6e2b..b68717f7c8751 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -691,7 +691,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/stop", reqToken(), repo.StopIssueStopwatch) }) m.Group("/subscriptions", func() { - m.Get("", bind(api.User{}), repo.GetIssueWatchers) + m.Get("", bind(api.User{}), repo.GetIssueSubscribers) m.Put("/:user", repo.AddIssueSubscription) m.Delete("/:user", repo.DelIssueSubscription) }) From dea6928f30cd4daa48fde3c9a37470d69eca2cdc Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Fri, 1 Nov 2019 05:07:49 +0100 Subject: [PATCH 13/29] GetIssueWatchers -> GetIssueSubscribers part two --- routers/api/v1/repo/issue.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 9014a9c506725..5f3f5f4cefa08 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -879,8 +879,8 @@ func DelIssueSubscription(ctx *context.APIContext) { ctx.Status(201) } -// GetIssueWatchers return subscribers of an issue -func GetIssueWatchers(ctx *context.APIContext, form api.User) { +// GetIssueSubscribers return subscribers of an issue +func GetIssueSubscribers(ctx *context.APIContext, form api.User) { // swagger:operation GET /repos/{owner}/{repo}/issues/{index}/subscriptions issue issueSubscriptions // --- // summary: Get users who subscribed on an issue. From 59ca41911698b14ef7c40c751dc7537eac5dd497 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Fri, 1 Nov 2019 05:09:11 +0100 Subject: [PATCH 14/29] Revert "test go linter again" This reverts commit bab12356227e44334de113b76f12099de0b8aaa6. --- .golangci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.golangci.yml b/.golangci.yml index fd7393372be41..9b263918c951a 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -73,6 +73,9 @@ issues: - path: routers/routes/routes.go linters: - dupl + - path: routers/api/v1/repo/issue.go + linters: + - dupl - path: routers/repo/view.go linters: - dupl From bb6185cd8e1a8386e0750d995c1a58b1606fbe37 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Fri, 1 Nov 2019 05:16:22 +0100 Subject: [PATCH 15/29] change description for unsubscribe too --- routers/api/v1/repo/issue.go | 2 +- templates/swagger/v1_json.tmpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 5f3f5f4cefa08..bcc69726f38c9 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -833,7 +833,7 @@ func DelIssueSubscription(ctx *context.APIContext) { // required: true // - name: user // in: path - // description: user witch unsubscribe to issue + // description: user witch unsubscribe // type: string // required: true // responses: diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index d069ed9998229..03ceb93107e7c 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -3921,7 +3921,7 @@ }, { "type": "string", - "description": "user witch unsubscribe to issue", + "description": "user witch unsubscribe", "name": "user", "in": "path", "required": true From 3de794d62a6d352d67ad80d3ec211a0a04e209eb Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Fri, 1 Nov 2019 05:34:14 +0100 Subject: [PATCH 16/29] golangci-lint timeout avter 5min --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ebcfadb21db67..34685dea93c35 100644 --- a/Makefile +++ b/Makefile @@ -521,4 +521,4 @@ golangci-lint: export BINARY="golangci-lint"; \ curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(GOPATH)/bin v1.20.0; \ fi - golangci-lint run + golangci-lint run --timeout 5m From da005ac6be8c05c4cd7045c63125d8f9e744b5fb Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Fri, 1 Nov 2019 06:38:48 +0100 Subject: [PATCH 17/29] move issueSubscription to seperate file --- routers/api/v1/repo/issue.go | 208 -------------------- routers/api/v1/repo/issue_subscription.go | 220 ++++++++++++++++++++++ 2 files changed, 220 insertions(+), 208 deletions(-) create mode 100644 routers/api/v1/repo/issue_subscription.go diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index bcc69726f38c9..fe5862ea5e452 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -730,211 +730,3 @@ func StopIssueStopwatch(ctx *context.APIContext) { ctx.Status(201) } - -// AddIssueSubscription add user to subscription list -func AddIssueSubscription(ctx *context.APIContext) { - // swagger:operation PUT /repos/{owner}/{repo}/issues/{index}/subscriptions/{user} issue issueAddSubscription - // --- - // summary: Add user to subscription list - // consumes: - // - application/json - // produces: - // - application/json - // parameters: - // - name: owner - // in: path - // description: owner of the repo - // type: string - // required: true - // - name: repo - // in: path - // description: name of the repo - // type: string - // required: true - // - name: index - // in: path - // description: index of the issue - // type: integer - // format: int64 - // required: true - // - name: user - // in: path - // description: user to subscribe - // type: string - // required: true - // responses: - // "201": - // "$ref": "#/responses/empty" - // "304": - // description: User can only subscribe itself if he is no admin - // "404": - // description: Issue not found - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) - if err != nil { - if models.IsErrIssueNotExist(err) { - ctx.NotFound() - } else { - ctx.Error(500, "GetIssueByIndex", err) - } - - return - } - - user, err := models.GetUserByName(ctx.Params(":user")) - if err != nil { - if models.IsErrUserNotExist(err) { - ctx.NotFound() - } else { - ctx.Error(500, "GetUserByName", err) - } - - return - } - - //only admin and user for itself can change subscription - if user.ID != ctx.User.ID && !ctx.User.IsAdmin { - ctx.Error(403, "User", nil) - return - } - - if err := models.CreateOrUpdateIssueWatch(user.ID, issue.ID, true); err != nil { - ctx.Error(500, "CreateOrUpdateIssueWatch", err) - return - } - - ctx.Status(201) -} - -// DelIssueSubscription remove user to subscription list -func DelIssueSubscription(ctx *context.APIContext) { - // swagger:operation DELETE /repos/{owner}/{repo}/issues/{index}/subscriptions/{user} issue issueDeleteSubscription - // --- - // summary: Delete user from subscription list - // consumes: - // - application/json - // produces: - // - application/json - // parameters: - // - name: owner - // in: path - // description: owner of the repo - // type: string - // required: true - // - name: repo - // in: path - // description: name of the repo - // type: string - // required: true - // - name: index - // in: path - // description: index of the issue - // type: integer - // format: int64 - // required: true - // - name: user - // in: path - // description: user witch unsubscribe - // type: string - // required: true - // responses: - // "201": - // "$ref": "#/responses/empty" - // "304": - // description: User can only subscribe itself if he is no admin - // "404": - // description: Issue not found - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) - if err != nil { - if models.IsErrIssueNotExist(err) { - ctx.NotFound() - } else { - ctx.Error(500, "GetIssueByIndex", err) - } - - return - } - - user, err := models.GetUserByName(ctx.Params(":user")) - if err != nil { - if models.IsErrUserNotExist(err) { - ctx.NotFound() - } else { - ctx.Error(500, "GetUserByName", err) - } - - return - } - - //only admin and user for itself can change subscription - if user.ID != ctx.User.ID && !ctx.User.IsAdmin { - ctx.Error(403, "User", nil) - return - } - - if err := models.CreateOrUpdateIssueWatch(user.ID, issue.ID, false); err != nil { - ctx.Error(500, "CreateOrUpdateIssueWatch", err) - return - } - - ctx.Status(201) -} - -// GetIssueSubscribers return subscribers of an issue -func GetIssueSubscribers(ctx *context.APIContext, form api.User) { - // swagger:operation GET /repos/{owner}/{repo}/issues/{index}/subscriptions issue issueSubscriptions - // --- - // summary: Get users who subscribed on an issue. - // consumes: - // - application/json - // produces: - // - application/json - // parameters: - // - name: owner - // in: path - // description: owner of the repo - // type: string - // required: true - // - name: repo - // in: path - // description: name of the repo - // type: string - // required: true - // - name: index - // in: path - // description: index of the issue - // type: integer - // format: int64 - // required: true - // responses: - // "201": - // "$ref": "#/responses/empty" - // "404": - // description: Issue not found - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) - if err != nil { - if models.IsErrIssueNotExist(err) { - ctx.NotFound() - } else { - ctx.Error(500, "GetIssueByIndex", err) - } - - return - } - - iw, err := models.GetIssueWatchers(issue.ID) - if err != nil { - ctx.Error(500, "GetIssueWatchers", err) - return - } - - subscribers := make([]*api.User, len(iw)) - for i, s := range iw { - user, err := models.GetUserByID(s.UserID) - if err != nil { - continue - } - subscribers[i] = user.APIFormat() - } - - ctx.JSON(200, subscribers) -} diff --git a/routers/api/v1/repo/issue_subscription.go b/routers/api/v1/repo/issue_subscription.go new file mode 100644 index 0000000000000..51943e45557cf --- /dev/null +++ b/routers/api/v1/repo/issue_subscription.go @@ -0,0 +1,220 @@ +// Copyright 2016 The Gogs Authors. All rights reserved. +// Copyright 2018 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package repo + +import ( + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/context" + api "code.gitea.io/gitea/modules/structs" +) + +// AddIssueSubscription add user to subscription list +func AddIssueSubscription(ctx *context.APIContext) { + // swagger:operation PUT /repos/{owner}/{repo}/issues/{index}/subscriptions/{user} issue issueAddSubscription + // --- + // summary: Add user to subscription list + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: index + // in: path + // description: index of the issue + // type: integer + // format: int64 + // required: true + // - name: user + // in: path + // description: user to subscribe + // type: string + // required: true + // responses: + // "201": + // "$ref": "#/responses/empty" + // "304": + // description: User can only subscribe itself if he is no admin + // "404": + // description: Issue not found + issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + if err != nil { + if models.IsErrIssueNotExist(err) { + ctx.NotFound() + } else { + ctx.Error(500, "GetIssueByIndex", err) + } + + return + } + + user, err := models.GetUserByName(ctx.Params(":user")) + if err != nil { + if models.IsErrUserNotExist(err) { + ctx.NotFound() + } else { + ctx.Error(500, "GetUserByName", err) + } + + return + } + + //only admin and user for itself can change subscription + if user.ID != ctx.User.ID && !ctx.User.IsAdmin { + ctx.Error(403, "User", nil) + return + } + + if err := models.CreateOrUpdateIssueWatch(user.ID, issue.ID, true); err != nil { + ctx.Error(500, "CreateOrUpdateIssueWatch", err) + return + } + + ctx.Status(201) +} + +// DelIssueSubscription remove user to subscription list +func DelIssueSubscription(ctx *context.APIContext) { + // swagger:operation DELETE /repos/{owner}/{repo}/issues/{index}/subscriptions/{user} issue issueDeleteSubscription + // --- + // summary: Delete user from subscription list + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: index + // in: path + // description: index of the issue + // type: integer + // format: int64 + // required: true + // - name: user + // in: path + // description: user witch unsubscribe + // type: string + // required: true + // responses: + // "201": + // "$ref": "#/responses/empty" + // "304": + // description: User can only subscribe itself if he is no admin + // "404": + // description: Issue not found + issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + if err != nil { + if models.IsErrIssueNotExist(err) { + ctx.NotFound() + } else { + ctx.Error(500, "GetIssueByIndex", err) + } + + return + } + + user, err := models.GetUserByName(ctx.Params(":user")) + if err != nil { + if models.IsErrUserNotExist(err) { + ctx.NotFound() + } else { + ctx.Error(500, "GetUserByName", err) + } + + return + } + + //only admin and user for itself can change subscription + if user.ID != ctx.User.ID && !ctx.User.IsAdmin { + ctx.Error(403, "User", nil) + return + } + + if err := models.CreateOrUpdateIssueWatch(user.ID, issue.ID, false); err != nil { + ctx.Error(500, "CreateOrUpdateIssueWatch", err) + return + } + + ctx.Status(201) +} + +// GetIssueSubscribers return subscribers of an issue +func GetIssueSubscribers(ctx *context.APIContext, form api.User) { + // swagger:operation GET /repos/{owner}/{repo}/issues/{index}/subscriptions issue issueSubscriptions + // --- + // summary: Get users who subscribed on an issue. + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: index + // in: path + // description: index of the issue + // type: integer + // format: int64 + // required: true + // responses: + // "201": + // "$ref": "#/responses/empty" + // "404": + // description: Issue not found + issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + if err != nil { + if models.IsErrIssueNotExist(err) { + ctx.NotFound() + } else { + ctx.Error(500, "GetIssueByIndex", err) + } + + return + } + + iw, err := models.GetIssueWatchers(issue.ID) + if err != nil { + ctx.Error(500, "GetIssueWatchers", err) + return + } + + subscribers := make([]*api.User, len(iw)) + for i, s := range iw { + user, err := models.GetUserByID(s.UserID) + if err != nil { + continue + } + subscribers[i] = user.APIFormat() + } + + ctx.JSON(200, subscribers) +} From fb325d710b97ee086d60d78ca17cd991b17f1da5 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Fri, 1 Nov 2019 06:40:50 +0100 Subject: [PATCH 18/29] dont create black entitys --- routers/api/v1/repo/issue_subscription.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/routers/api/v1/repo/issue_subscription.go b/routers/api/v1/repo/issue_subscription.go index 51943e45557cf..5b9b222b7fc9f 100644 --- a/routers/api/v1/repo/issue_subscription.go +++ b/routers/api/v1/repo/issue_subscription.go @@ -207,13 +207,13 @@ func GetIssueSubscribers(ctx *context.APIContext, form api.User) { return } - subscribers := make([]*api.User, len(iw)) - for i, s := range iw { + var subscribers []*api.User + for _, s := range iw { user, err := models.GetUserByID(s.UserID) if err != nil { continue } - subscribers[i] = user.APIFormat() + subscribers = append(subscribers, user.APIFormat()) } ctx.JSON(200, subscribers) From bd3c7373a52eff57f1a903cd779c96e2527f17fa Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Fri, 1 Nov 2019 06:41:59 +0100 Subject: [PATCH 19/29] use IsWatching until refactoring --- routers/api/v1/repo/issue_subscription.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/routers/api/v1/repo/issue_subscription.go b/routers/api/v1/repo/issue_subscription.go index 5b9b222b7fc9f..ebd9332d4277b 100644 --- a/routers/api/v1/repo/issue_subscription.go +++ b/routers/api/v1/repo/issue_subscription.go @@ -209,11 +209,13 @@ func GetIssueSubscribers(ctx *context.APIContext, form api.User) { var subscribers []*api.User for _, s := range iw { - user, err := models.GetUserByID(s.UserID) - if err != nil { - continue + if s.IsWatching { + user, err := models.GetUserByID(s.UserID) + if err != nil { + continue + } + subscribers = append(subscribers, user.APIFormat()) } - subscribers = append(subscribers, user.APIFormat()) } ctx.JSON(200, subscribers) From 9c3bbccce729e64cff1ed65627397dafc1c3298b Mon Sep 17 00:00:00 2001 From: 6543 <24977596+6543@users.noreply.github.com> Date: Fri, 1 Nov 2019 06:44:50 +0100 Subject: [PATCH 20/29] Update License Info --- routers/api/v1/repo/issue_subscription.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/routers/api/v1/repo/issue_subscription.go b/routers/api/v1/repo/issue_subscription.go index ebd9332d4277b..d1022adf44726 100644 --- a/routers/api/v1/repo/issue_subscription.go +++ b/routers/api/v1/repo/issue_subscription.go @@ -1,5 +1,4 @@ -// Copyright 2016 The Gogs Authors. All rights reserved. -// Copyright 2018 The Gitea Authors. All rights reserved. +// Copyright 2019 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. From d52dbcbf74848d1e2f8d7ed05de0da5d28f71025 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Fri, 1 Nov 2019 07:33:21 +0100 Subject: [PATCH 21/29] better swagger description --- routers/api/v1/repo/issue_subscription.go | 8 ++++---- templates/swagger/v1_json.tmpl | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/routers/api/v1/repo/issue_subscription.go b/routers/api/v1/repo/issue_subscription.go index d1022adf44726..c51edda052eee 100644 --- a/routers/api/v1/repo/issue_subscription.go +++ b/routers/api/v1/repo/issue_subscription.go @@ -10,11 +10,11 @@ import ( api "code.gitea.io/gitea/modules/structs" ) -// AddIssueSubscription add user to subscription list +// AddIssueSubscription Subscribe user to issue func AddIssueSubscription(ctx *context.APIContext) { // swagger:operation PUT /repos/{owner}/{repo}/issues/{index}/subscriptions/{user} issue issueAddSubscription // --- - // summary: Add user to subscription list + // summary: Subscribe user to issue // consumes: // - application/json // produces: @@ -84,11 +84,11 @@ func AddIssueSubscription(ctx *context.APIContext) { ctx.Status(201) } -// DelIssueSubscription remove user to subscription list +// DelIssueSubscription Unsubscribe user from issue func DelIssueSubscription(ctx *context.APIContext) { // swagger:operation DELETE /repos/{owner}/{repo}/issues/{index}/subscriptions/{user} issue issueDeleteSubscription // --- - // summary: Delete user from subscription list + // summary: Unsubscribe user from issue // consumes: // - application/json // produces: diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 03ceb93107e7c..41e5353ea73b0 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -3839,7 +3839,7 @@ "tags": [ "issue" ], - "summary": "Add user to subscription list", + "summary": "Subscribe user to issue", "operationId": "issueAddSubscription", "parameters": [ { @@ -3894,7 +3894,7 @@ "tags": [ "issue" ], - "summary": "Delete user from subscription list", + "summary": "Unsubscribe user from issue", "operationId": "issueDeleteSubscription", "parameters": [ { From 1fcd4348f66e01325403cbec9d105f9e73a82e22 Mon Sep 17 00:00:00 2001 From: 6543 <24977596+6543@users.noreply.github.com> Date: Sat, 2 Nov 2019 02:16:00 +0100 Subject: [PATCH 22/29] Update .golangci.yml because functions moved from issue.go to issue_subscription.go --- .golangci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.golangci.yml b/.golangci.yml index 9b263918c951a..121ef583accb3 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -73,7 +73,7 @@ issues: - path: routers/routes/routes.go linters: - dupl - - path: routers/api/v1/repo/issue.go + - path: routers/api/v1/repo/issue_subscription.go linters: - dupl - path: routers/repo/view.go From 4a8d2d7fcf8ca086139dad601f4db298293b57ce Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Sat, 2 Nov 2019 05:26:11 +0100 Subject: [PATCH 23/29] add IssueWatchList type --- models/issue_watch.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/models/issue_watch.go b/models/issue_watch.go index 2f55c6a84db86..ccc1e8f6b67cd 100644 --- a/models/issue_watch.go +++ b/models/issue_watch.go @@ -16,6 +16,9 @@ type IssueWatch struct { UpdatedUnix timeutil.TimeStamp `xorm:"updated NOT NULL"` } +// IssueWatchList contains IssueWatch +type IssueWatchList []*IssueWatch + // CreateOrUpdateIssueWatch set watching for a user and issue func CreateOrUpdateIssueWatch(userID, issueID int64, isWatching bool) error { iw, exists, err := getIssueWatch(x, userID, issueID) From 577aa9ce73e09a9e19a9dc183d87a44a86520810 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Sat, 2 Nov 2019 05:36:11 +0100 Subject: [PATCH 24/29] batch tasks --- models/issue_watch.go | 24 +++++++++++++++++++++++ models/userlist.go | 10 ++++++++++ routers/api/v1/repo/issue_subscription.go | 15 +++----------- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/models/issue_watch.go b/models/issue_watch.go index ccc1e8f6b67cd..a4585c97be30b 100644 --- a/models/issue_watch.go +++ b/models/issue_watch.go @@ -86,3 +86,27 @@ func removeIssueWatchersByRepoID(e Engine, userID int64, repoID int64) error { Update(iw) return err } + +// LoadWatchUsers return watching users +func (iwl IssueWatchList) LoadWatchUsers() UserList { + return iwl.loadWatchUsers(x) +} + +func (iwl IssueWatchList) loadWatchUsers(e Engine) UserList { + if len(iwl) == 0 { + return nil + } + + var userIDs = make([]int64, 0, len(iwl)) + for _, iw := range iwl { + if iw.IsWatching { + userIDs = append(userIDs, iw.UserID) + } + } + + var users UserList + + x.In("id", userIDs).Find(&users) + + return users +} diff --git a/models/userlist.go b/models/userlist.go index a2a424848227b..16ec6fee55a3d 100644 --- a/models/userlist.go +++ b/models/userlist.go @@ -8,6 +8,7 @@ import ( "fmt" "code.gitea.io/gitea/modules/log" + api "code.gitea.io/gitea/modules/structs" ) //UserList is a list of user. @@ -93,3 +94,12 @@ func (users UserList) loadTwoFactorStatus(e Engine) (map[int64]*TwoFactor, error } return tokenMaps, nil } + +//APIFormat return list of users in api format +func (users UserList) APIFormat() []*api.User { + var result []*api.User + for _, u := range users { + result = append(result, u.APIFormat()) + } + return result +} diff --git a/routers/api/v1/repo/issue_subscription.go b/routers/api/v1/repo/issue_subscription.go index c51edda052eee..19e33ecfe701d 100644 --- a/routers/api/v1/repo/issue_subscription.go +++ b/routers/api/v1/repo/issue_subscription.go @@ -200,22 +200,13 @@ func GetIssueSubscribers(ctx *context.APIContext, form api.User) { return } - iw, err := models.GetIssueWatchers(issue.ID) + iwl, err := models.GetIssueWatchers(issue.ID) if err != nil { ctx.Error(500, "GetIssueWatchers", err) return } - var subscribers []*api.User - for _, s := range iw { - if s.IsWatching { - user, err := models.GetUserByID(s.UserID) - if err != nil { - continue - } - subscribers = append(subscribers, user.APIFormat()) - } - } + users := models.UserList.APIFormat(models.IssueWatchList.LoadWatchUsers(iwl)) - ctx.JSON(200, subscribers) + ctx.JSON(200, users) } From 34f31432fc1461917e4b196224ece2d00a5c9de0 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Sat, 2 Nov 2019 06:00:50 +0100 Subject: [PATCH 25/29] use e Engien --- models/issue_watch.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/models/issue_watch.go b/models/issue_watch.go index a4585c97be30b..616433c0120ab 100644 --- a/models/issue_watch.go +++ b/models/issue_watch.go @@ -92,7 +92,7 @@ func (iwl IssueWatchList) LoadWatchUsers() UserList { return iwl.loadWatchUsers(x) } -func (iwl IssueWatchList) loadWatchUsers(e Engine) UserList { +func (iwl IssueWatchList) loadWatchUsers(e Engine) (users UserList) { if len(iwl) == 0 { return nil } @@ -104,9 +104,7 @@ func (iwl IssueWatchList) loadWatchUsers(e Engine) UserList { } } - var users UserList + e.In("id", userIDs).Find(&users) - x.In("id", userIDs).Find(&users) - - return users + return } From 8bb20439c3776b4d6ca8d55e4a99c0e5adcbc2f3 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Sat, 2 Nov 2019 06:09:06 +0100 Subject: [PATCH 26/29] add error handling --- models/issue_watch.go | 12 ++++++------ routers/api/v1/repo/issue_subscription.go | 8 ++++++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/models/issue_watch.go b/models/issue_watch.go index 616433c0120ab..1c7e0c6aa483d 100644 --- a/models/issue_watch.go +++ b/models/issue_watch.go @@ -61,11 +61,11 @@ func getIssueWatch(e Engine, userID, issueID int64) (iw *IssueWatch, exists bool } // GetIssueWatchers returns watchers/unwatchers of a given issue -func GetIssueWatchers(issueID int64) ([]*IssueWatch, error) { +func GetIssueWatchers(issueID int64) (IssueWatchList, error) { return getIssueWatchers(x, issueID) } -func getIssueWatchers(e Engine, issueID int64) (watches []*IssueWatch, err error) { +func getIssueWatchers(e Engine, issueID int64) (watches IssueWatchList, err error) { err = e. Where("`issue_watch`.issue_id = ?", issueID). And("`user`.is_active = ?", true). @@ -88,13 +88,13 @@ func removeIssueWatchersByRepoID(e Engine, userID int64, repoID int64) error { } // LoadWatchUsers return watching users -func (iwl IssueWatchList) LoadWatchUsers() UserList { +func (iwl IssueWatchList) LoadWatchUsers() (err error, users UserList) { return iwl.loadWatchUsers(x) } -func (iwl IssueWatchList) loadWatchUsers(e Engine) (users UserList) { +func (iwl IssueWatchList) loadWatchUsers(e Engine) (err error, users UserList) { if len(iwl) == 0 { - return nil + return nil, nil } var userIDs = make([]int64, 0, len(iwl)) @@ -104,7 +104,7 @@ func (iwl IssueWatchList) loadWatchUsers(e Engine) (users UserList) { } } - e.In("id", userIDs).Find(&users) + err = e.In("id", userIDs).Find(&users) return } diff --git a/routers/api/v1/repo/issue_subscription.go b/routers/api/v1/repo/issue_subscription.go index 19e33ecfe701d..95bebbdb844cb 100644 --- a/routers/api/v1/repo/issue_subscription.go +++ b/routers/api/v1/repo/issue_subscription.go @@ -206,7 +206,11 @@ func GetIssueSubscribers(ctx *context.APIContext, form api.User) { return } - users := models.UserList.APIFormat(models.IssueWatchList.LoadWatchUsers(iwl)) + err, users := models.IssueWatchList.LoadWatchUsers(iwl) + if err != nil { + ctx.Error(500, "LoadWatchUsers", err) + return + } - ctx.JSON(200, users) + ctx.JSON(200, models.UserList.APIFormat(users)) } From ad29e4c395db294aeb7565e2627f65768004c101 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Sat, 2 Nov 2019 06:15:50 +0100 Subject: [PATCH 27/29] error should be the last type when returning multiple items --- models/issue_watch.go | 4 ++-- routers/api/v1/repo/issue_subscription.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/models/issue_watch.go b/models/issue_watch.go index 1c7e0c6aa483d..72d4c2bf35e6c 100644 --- a/models/issue_watch.go +++ b/models/issue_watch.go @@ -88,11 +88,11 @@ func removeIssueWatchersByRepoID(e Engine, userID int64, repoID int64) error { } // LoadWatchUsers return watching users -func (iwl IssueWatchList) LoadWatchUsers() (err error, users UserList) { +func (iwl IssueWatchList) LoadWatchUsers() (users UserList, err error) { return iwl.loadWatchUsers(x) } -func (iwl IssueWatchList) loadWatchUsers(e Engine) (err error, users UserList) { +func (iwl IssueWatchList) loadWatchUsers(e Engine) (users UserList, err error) { if len(iwl) == 0 { return nil, nil } diff --git a/routers/api/v1/repo/issue_subscription.go b/routers/api/v1/repo/issue_subscription.go index 95bebbdb844cb..2434539c7722b 100644 --- a/routers/api/v1/repo/issue_subscription.go +++ b/routers/api/v1/repo/issue_subscription.go @@ -206,7 +206,7 @@ func GetIssueSubscribers(ctx *context.APIContext, form api.User) { return } - err, users := models.IssueWatchList.LoadWatchUsers(iwl) + users, err := models.IssueWatchList.LoadWatchUsers(iwl) if err != nil { ctx.Error(500, "LoadWatchUsers", err) return From e0b11f9ad86b7cf4cd1005fd0963b05df4eae961 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Sat, 2 Nov 2019 06:51:32 +0100 Subject: [PATCH 28/29] short version --- routers/api/v1/repo/issue_subscription.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/routers/api/v1/repo/issue_subscription.go b/routers/api/v1/repo/issue_subscription.go index 2434539c7722b..012dcda44fa85 100644 --- a/routers/api/v1/repo/issue_subscription.go +++ b/routers/api/v1/repo/issue_subscription.go @@ -206,11 +206,11 @@ func GetIssueSubscribers(ctx *context.APIContext, form api.User) { return } - users, err := models.IssueWatchList.LoadWatchUsers(iwl) + users, err := iwl.LoadWatchUsers() if err != nil { ctx.Error(500, "LoadWatchUsers", err) return } - ctx.JSON(200, models.UserList.APIFormat(users)) + ctx.JSON(200, users.APIFormat()) } From 2056321a063edeb2e46406e9e81282b58c5e0645 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Sat, 2 Nov 2019 12:23:47 +0100 Subject: [PATCH 29/29] reurn empy UserList instead of nil --- models/issue_watch.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/models/issue_watch.go b/models/issue_watch.go index 72d4c2bf35e6c..1ae0c9d474717 100644 --- a/models/issue_watch.go +++ b/models/issue_watch.go @@ -94,7 +94,7 @@ func (iwl IssueWatchList) LoadWatchUsers() (users UserList, err error) { func (iwl IssueWatchList) loadWatchUsers(e Engine) (users UserList, err error) { if len(iwl) == 0 { - return nil, nil + return []*User{}, nil } var userIDs = make([]int64, 0, len(iwl)) @@ -104,6 +104,10 @@ func (iwl IssueWatchList) loadWatchUsers(e Engine) (users UserList, err error) { } } + if len(userIDs) == 0 { + return []*User{}, nil + } + err = e.In("id", userIDs).Find(&users) return