From 8c3f7aa200960b08de47517c0829ba985ea1f2ad Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Mon, 6 Feb 2023 16:55:23 -0500 Subject: [PATCH 01/10] add admin API email endpoints --- modules/structs/user_email.go | 9 ++++--- routers/api/v1/admin/email.go | 49 +++++++++++++++++++++++++++++++++++ routers/api/v1/api.go | 7 +++++ services/convert/convert.go | 11 ++++++++ 4 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 routers/api/v1/admin/email.go diff --git a/modules/structs/user_email.go b/modules/structs/user_email.go index 6a11e040afb33..bb144175824ac 100644 --- a/modules/structs/user_email.go +++ b/modules/structs/user_email.go @@ -1,4 +1,5 @@ // Copyright 2015 The Gogs Authors. All rights reserved. +// Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT package structs @@ -6,9 +7,11 @@ package structs // Email an email address belonging to a user type Email struct { // swagger:strfmt email - Email string `json:"email"` - Verified bool `json:"verified"` - Primary bool `json:"primary"` + Email string `json:"email"` + Verified bool `json:"verified"` + Primary bool `json:"primary"` + UserID int64 `json:"user_id"` + LoginName string `json:"login_name"` } // CreateEmailOption options when creating email addresses diff --git a/routers/api/v1/admin/email.go b/routers/api/v1/admin/email.go new file mode 100644 index 0000000000000..6ed19e2b90726 --- /dev/null +++ b/routers/api/v1/admin/email.go @@ -0,0 +1,49 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package admin + +import ( + "net/http" + + user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/context" + api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" +) + +// GetAllEmails +func GetAllEmails(ctx *context.APIContext) { + + listOptions := utils.GetListOptions(ctx) + + emails, maxResults, err := user_model.SearchEmails(&user_model.SearchEmailOptions{ + Keyword: ctx.Params(":email"), + ListOptions: listOptions, + }) + if err != nil { + ctx.Error(http.StatusInternalServerError, "GetAllEmails", err) + return + } + + results := make([]*api.Email, len(emails)) + for i := range emails { + results[i] = convert.ToEmailSearch(emails[i]) + } + + ctx.SetLinkHeader(int(maxResults), listOptions.PageSize) + ctx.SetTotalCountHeader(maxResults) + ctx.JSON(http.StatusOK, &results) +} + +// GetEmail +func GetEmail(ctx *context.APIContext) { + GetAllEmails(ctx) +} + +// SearchEmail +func SearchEmail(ctx *context.APIContext) { + ctx.SetParams(":email", ctx.FormTrim("q")) + GetAllEmails(ctx) +} diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 5f57977c290bb..a8cf78157c4b7 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -1252,6 +1252,13 @@ func Routes(ctx gocontext.Context) *web.Route { m.Post("/repos", bind(api.CreateRepoOption{}), admin.CreateRepo) }, context_service.UserAssignmentAPI()) }) + m.Group("/emails", func() { + m.Get("", admin.GetAllEmails) + m.Get("/search", admin.SearchEmail) + m.Group("/{email}", func() { + m.Get("", admin.GetEmail) + }) + }) m.Group("/unadopted", func() { m.Get("", admin.ListUnadoptedRepositories) m.Post("/{username}/{reponame}", admin.AdoptRepository) diff --git a/services/convert/convert.go b/services/convert/convert.go index 17f7e3d650679..2d3cb7d35d30e 100644 --- a/services/convert/convert.go +++ b/services/convert/convert.go @@ -38,6 +38,17 @@ func ToEmail(email *user_model.EmailAddress) *api.Email { } } +// ToEmail convert models.EmailAddress to api.Email +func ToEmailSearch(email *user_model.SearchEmailResult) *api.Email { + return &api.Email{ + Email: email.Email, + Verified: email.IsActivated, + Primary: email.IsPrimary, + UserID: email.UID, + LoginName: email.Name, + } +} + // ToBranch convert a git.Commit and git.Branch to an api.Branch func ToBranch(repo *repo_model.Repository, b *git.Branch, c *git.Commit, bp *git_model.ProtectedBranch, user *user_model.User, isRepoAdmin bool) (*api.Branch, error) { if bp == nil { From c84160fcdfcc8e082c39972a2935f7ab5eb21b38 Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Mon, 20 Feb 2023 11:55:52 -0500 Subject: [PATCH 02/10] Update user_email.go --- modules/structs/user_email.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/structs/user_email.go b/modules/structs/user_email.go index bb144175824ac..5882631b0265c 100644 --- a/modules/structs/user_email.go +++ b/modules/structs/user_email.go @@ -11,7 +11,7 @@ type Email struct { Verified bool `json:"verified"` Primary bool `json:"primary"` UserID int64 `json:"user_id"` - LoginName string `json:"login_name"` + UserName string `json:"username"` } // CreateEmailOption options when creating email addresses From 1c3feb1a4d604a89b0ad26b2076b8769aa6d4379 Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Mon, 20 Feb 2023 11:56:56 -0500 Subject: [PATCH 03/10] Update convert.go --- services/convert/convert.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/convert/convert.go b/services/convert/convert.go index 2d3cb7d35d30e..1c4ee84e42a3d 100644 --- a/services/convert/convert.go +++ b/services/convert/convert.go @@ -45,7 +45,7 @@ func ToEmailSearch(email *user_model.SearchEmailResult) *api.Email { Verified: email.IsActivated, Primary: email.IsPrimary, UserID: email.UID, - LoginName: email.Name, + UserName: email.Name, } } From f7356365928fb5027febc8ba47434cef3650cd8c Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Mon, 20 Feb 2023 11:57:38 -0500 Subject: [PATCH 04/10] Update user_email.go --- modules/structs/user_email.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/structs/user_email.go b/modules/structs/user_email.go index 5882631b0265c..75affe9c293dd 100644 --- a/modules/structs/user_email.go +++ b/modules/structs/user_email.go @@ -10,7 +10,7 @@ type Email struct { Email string `json:"email"` Verified bool `json:"verified"` Primary bool `json:"primary"` - UserID int64 `json:"user_id"` + UserID int64 `json:"user_id"` UserName string `json:"username"` } From 7106a6e54913c822fd425019b5ff6da69e74a788 Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Mon, 20 Feb 2023 12:06:41 -0500 Subject: [PATCH 05/10] Update user_email.go --- modules/structs/user_email.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/structs/user_email.go b/modules/structs/user_email.go index 75affe9c293dd..5451915c8df66 100644 --- a/modules/structs/user_email.go +++ b/modules/structs/user_email.go @@ -10,8 +10,8 @@ type Email struct { Email string `json:"email"` Verified bool `json:"verified"` Primary bool `json:"primary"` - UserID int64 `json:"user_id"` - UserName string `json:"username"` + UserID int64 `json:"user_id"` + UserName string `json:"username"` } // CreateEmailOption options when creating email addresses From ca244a9cfc4ea465ed993d110e123a23a807baaa Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Tue, 21 Feb 2023 11:16:27 -0500 Subject: [PATCH 06/10] make fmt --- modules/structs/user_email.go | 10 +++++----- routers/api/v1/admin/email.go | 1 - services/convert/convert.go | 8 ++++---- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/modules/structs/user_email.go b/modules/structs/user_email.go index 5451915c8df66..9319667e8fca6 100644 --- a/modules/structs/user_email.go +++ b/modules/structs/user_email.go @@ -7,11 +7,11 @@ package structs // Email an email address belonging to a user type Email struct { // swagger:strfmt email - Email string `json:"email"` - Verified bool `json:"verified"` - Primary bool `json:"primary"` - UserID int64 `json:"user_id"` - UserName string `json:"username"` + Email string `json:"email"` + Verified bool `json:"verified"` + Primary bool `json:"primary"` + UserID int64 `json:"user_id"` + UserName string `json:"username"` } // CreateEmailOption options when creating email addresses diff --git a/routers/api/v1/admin/email.go b/routers/api/v1/admin/email.go index 6ed19e2b90726..cc4163418935f 100644 --- a/routers/api/v1/admin/email.go +++ b/routers/api/v1/admin/email.go @@ -15,7 +15,6 @@ import ( // GetAllEmails func GetAllEmails(ctx *context.APIContext) { - listOptions := utils.GetListOptions(ctx) emails, maxResults, err := user_model.SearchEmails(&user_model.SearchEmailOptions{ diff --git a/services/convert/convert.go b/services/convert/convert.go index ce195cd34f95c..bce0e7ba214b6 100644 --- a/services/convert/convert.go +++ b/services/convert/convert.go @@ -41,10 +41,10 @@ func ToEmail(email *user_model.EmailAddress) *api.Email { // ToEmail convert models.EmailAddress to api.Email func ToEmailSearch(email *user_model.SearchEmailResult) *api.Email { return &api.Email{ - Email: email.Email, - Verified: email.IsActivated, - Primary: email.IsPrimary, - UserID: email.UID, + Email: email.Email, + Verified: email.IsActivated, + Primary: email.IsPrimary, + UserID: email.UID, UserName: email.Name, } } From 41b02aaceed6e7dbe618644a3396f0b92ea4dc0a Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Thu, 2 Mar 2023 00:38:13 -0500 Subject: [PATCH 07/10] fix swagger --- templates/swagger/v1_json.tmpl | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 2a675766abc92..e04718d1cf9c6 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -16775,6 +16775,15 @@ "type": "boolean", "x-go-name": "Primary" }, + "user_id": { + "type": "integer", + "format": "int64", + "x-go-name": "UserID" + }, + "username": { + "type": "string", + "x-go-name": "UserName" + }, "verified": { "type": "boolean", "x-go-name": "Verified" @@ -21020,4 +21029,4 @@ "TOTPHeader": [] } ] -} +} \ No newline at end of file From c84ed518107822b18a62753de9583afd314e22dd Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Mon, 13 Mar 2023 00:59:05 -0400 Subject: [PATCH 08/10] trailing whitespace --- templates/swagger/v1_json.tmpl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 6ea8b1056bf60..9990c848e0252 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -21197,4 +21197,5 @@ "TOTPHeader": [] } ] -} \ No newline at end of file +} + From 3c9749b8d36456115a67c47907b0e76127f0dd8b Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Mon, 13 Mar 2023 01:10:02 -0400 Subject: [PATCH 09/10] trailing whitespace --- templates/swagger/v1_json.tmpl | 1 - 1 file changed, 1 deletion(-) diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 9990c848e0252..9ba1ac4a05f4a 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -21198,4 +21198,3 @@ } ] } - From 422b702b62b252e96c870234d9c05c5333cb2168 Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Mon, 13 Mar 2023 23:04:47 -0400 Subject: [PATCH 10/10] add swagger --- routers/api/v1/admin/email.go | 49 +++++++++++++++++++--- routers/api/v1/api.go | 3 -- templates/swagger/v1_json.tmpl | 74 ++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+), 8 deletions(-) diff --git a/routers/api/v1/admin/email.go b/routers/api/v1/admin/email.go index cc4163418935f..8d0491e07024b 100644 --- a/routers/api/v1/admin/email.go +++ b/routers/api/v1/admin/email.go @@ -15,6 +15,26 @@ import ( // GetAllEmails func GetAllEmails(ctx *context.APIContext) { + // swagger:operation GET /admin/emails admin adminGetAllEmails + // --- + // summary: List all emails + // produces: + // - application/json + // parameters: + // - name: page + // in: query + // description: page number of results to return (1-based) + // type: integer + // - name: limit + // in: query + // description: page size of results + // type: integer + // responses: + // "200": + // "$ref": "#/responses/EmailList" + // "403": + // "$ref": "#/responses/forbidden" + listOptions := utils.GetListOptions(ctx) emails, maxResults, err := user_model.SearchEmails(&user_model.SearchEmailOptions{ @@ -36,13 +56,32 @@ func GetAllEmails(ctx *context.APIContext) { ctx.JSON(http.StatusOK, &results) } -// GetEmail -func GetEmail(ctx *context.APIContext) { - GetAllEmails(ctx) -} - // SearchEmail func SearchEmail(ctx *context.APIContext) { + // swagger:operation GET /admin/emails/search admin adminSearchEmails + // --- + // summary: Search all emails + // produces: + // - application/json + // parameters: + // - name: q + // in: query + // description: keyword + // type: string + // - name: page + // in: query + // description: page number of results to return (1-based) + // type: integer + // - name: limit + // in: query + // description: page size of results + // type: integer + // responses: + // "200": + // "$ref": "#/responses/EmailList" + // "403": + // "$ref": "#/responses/forbidden" + ctx.SetParams(":email", ctx.FormTrim("q")) GetAllEmails(ctx) } diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 43574792662d1..6725340ff74c2 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -1262,9 +1262,6 @@ func Routes(ctx gocontext.Context) *web.Route { m.Group("/emails", func() { m.Get("", admin.GetAllEmails) m.Get("/search", admin.SearchEmail) - m.Group("/{email}", func() { - m.Get("", admin.GetEmail) - }) }) m.Group("/unadopted", func() { m.Get("", admin.ListUnadoptedRepositories) diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 39ff4fb54c01d..c94d156b1fc62 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -138,6 +138,80 @@ } } }, + "/admin/emails": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "List all emails", + "operationId": "adminGetAllEmails", + "parameters": [ + { + "type": "integer", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/EmailList" + }, + "403": { + "$ref": "#/responses/forbidden" + } + } + } + }, + "/admin/emails/search": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "Search all emails", + "operationId": "adminSearchEmails", + "parameters": [ + { + "type": "string", + "description": "keyword", + "name": "q", + "in": "query" + }, + { + "type": "integer", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/EmailList" + }, + "403": { + "$ref": "#/responses/forbidden" + } + } + } + }, "/admin/hooks": { "get": { "produces": [