mirror of
				https://github.com/go-gitea/gitea
				synced 2025-10-31 03:18:24 +00:00 
			
		
		
		
	add issue subscriber API
This commit is contained in:
		| @@ -73,6 +73,9 @@ issues: | |||||||
|     - path: routers/routes/routes.go |     - path: routers/routes/routes.go | ||||||
|       linters: |       linters: | ||||||
|         - dupl |         - dupl | ||||||
|  |     - path: routers/api/v1/repo/issue.go | ||||||
|  |       linters: | ||||||
|  |         - dupl | ||||||
|     - path: routers/repo/view.go |     - path: routers/repo/view.go | ||||||
|       linters: |       linters: | ||||||
|         - dupl |         - dupl | ||||||
|   | |||||||
| @@ -113,3 +113,9 @@ type EditPriorityOption struct { | |||||||
| 	// required:true | 	// required:true | ||||||
| 	Priority int `json:"priority"` | 	Priority int `json:"priority"` | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // IssueWatchers list of subscribers of an issue | ||||||
|  | type IssueWatchers struct { | ||||||
|  | 	// required:true | ||||||
|  | 	Subscribers []string `json:"subscribers"` | ||||||
|  | } | ||||||
|   | |||||||
| @@ -688,6 +688,11 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||||
| 							m.Post("/start", reqToken(), repo.StartIssueStopwatch) | 							m.Post("/start", reqToken(), repo.StartIssueStopwatch) | ||||||
| 							m.Post("/stop", reqToken(), repo.StopIssueStopwatch) | 							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) | 				}, mustEnableIssuesOrPulls) | ||||||
| 				m.Group("/labels", func() { | 				m.Group("/labels", func() { | ||||||
|   | |||||||
| @@ -598,3 +598,208 @@ func StopIssueStopwatch(ctx *context.APIContext) { | |||||||
|  |  | ||||||
| 	ctx.Status(201) | 	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}) | ||||||
|  | } | ||||||
|   | |||||||
| @@ -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": { |     "/repos/{owner}/{repo}/keys": { | ||||||
|       "get": { |       "get": { | ||||||
|         "produces": [ |         "produces": [ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user