From 9c9f0eed49d398b9e5a8b019c2144f03c60c6405 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Wed, 16 Jun 2021 02:17:37 +0200 Subject: [PATCH 1/8] API: GET/SET User Settings --- modules/structs/user.go | 26 ++++++ routers/api/v1/api.go | 4 + routers/api/v1/swagger/options.go | 3 + routers/api/v1/swagger/user.go | 7 ++ routers/api/v1/user/preferences.go | 96 ++++++++++++++++++++ templates/swagger/v1_json.tmpl | 138 ++++++++++++++++++++++++++++- 6 files changed, 273 insertions(+), 1 deletion(-) create mode 100644 routers/api/v1/user/preferences.go diff --git a/modules/structs/user.go b/modules/structs/user.go index 2dbc5305382ab..058731d84eaff 100644 --- a/modules/structs/user.go +++ b/modules/structs/user.go @@ -55,3 +55,29 @@ func (u User) MarshalJSON() ([]byte, error) { CompatUserName string `json:"username"` }{shadow(u), u.UserName}) } + +type UserSettings struct { + FullName string `json:"full_name"` + Website string `json:"website"` + Description string `json:"description"` + Location string `json:"location"` + Language string `json:"language"` + Theme string `json:"theme"` + DiffViewStyle string `json:"diff_view_style"` + // Piracy + HideEmail bool `json:"hide_email"` + HideActivity bool `json:"hide_activity"` +} + +type UserSettingsOptions struct { + FullName *string `json:"full_name" binding:"MaxSize(100)"` + Website *string `json:"website" binding:"OmitEmpty;ValidUrl;MaxSize(255)"` + Description *string `json:"description" binding:"MaxSize(255)"` + Location *string `json:"location" binding:"MaxSize(50)"` + Language *string `json:"language"` + Theme *string `json:"theme"` + DiffViewStyle *string `json:"diff_view_style"` + // Piracy + HideEmail *bool `json:"hide_email"` + HideActivity *bool `json:"hide_activity"` +} diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index acee6329afd07..11fd65bb8d128 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -649,6 +649,10 @@ func Routes() *web.Route { m.Group("/user", func() { m.Get("", user.GetAuthenticatedUser) + m.Group("/preferences", func() { + m.Get("", user.GetUserSettings) + m.Patch("", bind(api.UserSettingsOptions{}), user.UpdateUserSettings) + }, reqToken()) m.Combo("/emails").Get(user.ListEmails). Post(bind(api.CreateEmailOption{}), user.AddEmail). Delete(bind(api.DeleteEmailOption{}), user.DeleteEmail) diff --git a/routers/api/v1/swagger/options.go b/routers/api/v1/swagger/options.go index dad025710dbad..49d056dcb874b 100644 --- a/routers/api/v1/swagger/options.go +++ b/routers/api/v1/swagger/options.go @@ -158,4 +158,7 @@ type swaggerParameterBodies struct { // in:body PullReviewRequestOptions api.PullReviewRequestOptions + + // in:body + UserSettingsOptions api.UserSettingsOptions } diff --git a/routers/api/v1/swagger/user.go b/routers/api/v1/swagger/user.go index a2df40e4cf5a1..a4d52012367a5 100644 --- a/routers/api/v1/swagger/user.go +++ b/routers/api/v1/swagger/user.go @@ -42,3 +42,10 @@ type swaggerResponseUserHeatmapData struct { // in:body Body []models.UserHeatmapData `json:"body"` } + +// UserSettings +// swagger:response UserSettings +type swaggerResponseUserSettings struct { + // in:body + Body []api.UserSettings `json:"body"` +} diff --git a/routers/api/v1/user/preferences.go b/routers/api/v1/user/preferences.go new file mode 100644 index 0000000000000..c6c3092cea011 --- /dev/null +++ b/routers/api/v1/user/preferences.go @@ -0,0 +1,96 @@ +// Copyright 2021 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 user + +import ( + "net/http" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/context" + api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" +) + +func user2UserSettings(user *models.User) api.UserSettings { + return api.UserSettings{ + FullName: user.FullName, + Website: user.Website, + Location: user.Location, + Language: user.Language, + Description: user.Description, + Theme: user.Theme, + HideEmail: user.KeepEmailPrivate, + HideActivity: user.KeepActivityPrivate, + DiffViewStyle: user.DiffViewStyle, + } +} + +// GetUserSettings returns user settings +func GetUserSettings(ctx *context.APIContext) { + // swagger:operation GET /user/preferences user getUserSettings + // --- + // summary: Get user settings + // produces: + // - application/json + // responses: + // "200": + // "$ref": "#/responses/UserSettings" + ctx.JSON(http.StatusOK, user2UserSettings(ctx.User)) +} + +// UpdateUserSettings returns user settings +func UpdateUserSettings(ctx *context.APIContext) { + // swagger:operation PATCH /user/preferences user getUserSettings + // --- + // summary: Update user settings + // parameters: + // - name: body + // in: body + // schema: + // "$ref": "#/definitions/UserSettingsOptions" + // produces: + // - application/json + // responses: + // "200": + // "$ref": "#/responses/UserSettings" + + form := web.GetForm(ctx).(*api.UserSettingsOptions) + + if form.FullName != nil { + ctx.User.FullName = *form.FullName + } + if form.Description != nil { + ctx.User.Description = *form.Description + } + if form.Website != nil { + ctx.User.Website = *form.Website + } + if form.Location != nil { + ctx.User.Location = *form.Location + } + if form.Language != nil { + ctx.User.Language = *form.Language + } + if form.Theme != nil { + ctx.User.Theme = *form.Theme + } + if form.DiffViewStyle != nil { + ctx.User.DiffViewStyle = *form.DiffViewStyle + } + + if form.HideEmail != nil { + ctx.User.KeepEmailPrivate = *form.HideEmail + } + if form.HideActivity != nil { + ctx.User.KeepActivityPrivate = *form.HideActivity + } + + if err := models.UpdateUser(ctx.User); err != nil { + ctx.InternalServerError(err) + return + } + + ctx.JSON(http.StatusOK, user2UserSettings(ctx.User)) +} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index e3ac4a4c8a68c..f1b89d7fa3a3c 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -10654,6 +10654,47 @@ } } }, + "/user/preferences": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Get user settings", + "operationId": "getUserSettings", + "responses": { + "200": { + "$ref": "#/responses/UserSettings" + } + } + }, + "patch": { + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Update user settings", + "operationId": "getUserSettings", + "parameters": [ + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/UserSettingsOptions" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/UserSettings" + } + } + } + }, "/user/repos": { "get": { "produces": [ @@ -16344,6 +16385,92 @@ }, "x-go-package": "code.gitea.io/gitea/models" }, + "UserSettings": { + "type": "object", + "properties": { + "description": { + "type": "string", + "x-go-name": "Description" + }, + "diff_view_style": { + "type": "string", + "x-go-name": "DiffViewStyle" + }, + "full_name": { + "type": "string", + "x-go-name": "FullName" + }, + "hide_activity": { + "type": "boolean", + "x-go-name": "HideActivity" + }, + "hide_email": { + "description": "Piracy", + "type": "boolean", + "x-go-name": "HideEmail" + }, + "language": { + "type": "string", + "x-go-name": "Language" + }, + "location": { + "type": "string", + "x-go-name": "Location" + }, + "theme": { + "type": "string", + "x-go-name": "Theme" + }, + "website": { + "type": "string", + "x-go-name": "Website" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "UserSettingsOptions": { + "type": "object", + "properties": { + "description": { + "type": "string", + "x-go-name": "Description" + }, + "diff_view_style": { + "type": "string", + "x-go-name": "DiffViewStyle" + }, + "full_name": { + "type": "string", + "x-go-name": "FullName" + }, + "hide_activity": { + "type": "boolean", + "x-go-name": "HideActivity" + }, + "hide_email": { + "description": "Piracy", + "type": "boolean", + "x-go-name": "HideEmail" + }, + "language": { + "type": "string", + "x-go-name": "Language" + }, + "location": { + "type": "string", + "x-go-name": "Location" + }, + "theme": { + "type": "string", + "x-go-name": "Theme" + }, + "website": { + "type": "string", + "x-go-name": "Website" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, "WatchInfo": { "description": "WatchInfo represents an API watch status of one repository", "type": "object", @@ -17047,6 +17174,15 @@ } } }, + "UserSettings": { + "description": "UserSettings", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/UserSettings" + } + } + }, "WatchInfo": { "description": "WatchInfo", "schema": { @@ -17101,7 +17237,7 @@ "parameterBodies": { "description": "parameterBodies", "schema": { - "$ref": "#/definitions/PullReviewRequestOptions" + "$ref": "#/definitions/UserSettingsOptions" } }, "redirect": { From 230f01edc5dd292ddddbf4c691166f4ffe9961ea Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Wed, 16 Jun 2021 02:36:08 +0200 Subject: [PATCH 2/8] linter --- modules/structs/user.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/structs/user.go b/modules/structs/user.go index 058731d84eaff..9d7ac68008bdc 100644 --- a/modules/structs/user.go +++ b/modules/structs/user.go @@ -56,6 +56,8 @@ func (u User) MarshalJSON() ([]byte, error) { }{shadow(u), u.UserName}) } +// UserSettingsOptions represents user settings +// swagger:model type UserSettings struct { FullName string `json:"full_name"` Website string `json:"website"` @@ -69,6 +71,8 @@ type UserSettings struct { HideActivity bool `json:"hide_activity"` } +// UserSettingsOptions represents options to change user settings +// swagger:model type UserSettingsOptions struct { FullName *string `json:"full_name" binding:"MaxSize(100)"` Website *string `json:"website" binding:"OmitEmpty;ValidUrl;MaxSize(255)"` From b87550af451e5e53edf5321ec1b6169f823db553 Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Tue, 15 Jun 2021 20:40:50 -0400 Subject: [PATCH 3/8] Apply suggestions from code review --- modules/structs/user.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/structs/user.go b/modules/structs/user.go index 9d7ac68008bdc..765bf48ecf643 100644 --- a/modules/structs/user.go +++ b/modules/structs/user.go @@ -66,7 +66,7 @@ type UserSettings struct { Language string `json:"language"` Theme string `json:"theme"` DiffViewStyle string `json:"diff_view_style"` - // Piracy + // Privacy HideEmail bool `json:"hide_email"` HideActivity bool `json:"hide_activity"` } @@ -81,7 +81,7 @@ type UserSettingsOptions struct { Language *string `json:"language"` Theme *string `json:"theme"` DiffViewStyle *string `json:"diff_view_style"` - // Piracy + // Privacy HideEmail *bool `json:"hide_email"` HideActivity *bool `json:"hide_activity"` } From 2005cc99cc552629fdb73329d897376b441fec68 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Wed, 16 Jun 2021 03:00:21 +0200 Subject: [PATCH 4/8] Update modules/structs/user.go --- modules/structs/user.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/structs/user.go b/modules/structs/user.go index 765bf48ecf643..6a6be40a6f247 100644 --- a/modules/structs/user.go +++ b/modules/structs/user.go @@ -56,7 +56,7 @@ func (u User) MarshalJSON() ([]byte, error) { }{shadow(u), u.UserName}) } -// UserSettingsOptions represents user settings +// UserSettings represents user settings // swagger:model type UserSettings struct { FullName string `json:"full_name"` From 04fe58e62f0f617e54efed02df4cef3f84edb502 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Wed, 16 Jun 2021 14:05:49 +0200 Subject: [PATCH 5/8] lint --- templates/swagger/v1_json.tmpl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index f1b89d7fa3a3c..e0f4efd3905ec 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -16386,6 +16386,7 @@ "x-go-package": "code.gitea.io/gitea/models" }, "UserSettings": { + "description": "UserSettings represents user settings", "type": "object", "properties": { "description": { @@ -16405,7 +16406,7 @@ "x-go-name": "HideActivity" }, "hide_email": { - "description": "Piracy", + "description": "Privacy", "type": "boolean", "x-go-name": "HideEmail" }, @@ -16429,6 +16430,7 @@ "x-go-package": "code.gitea.io/gitea/modules/structs" }, "UserSettingsOptions": { + "description": "UserSettingsOptions represents options to change user settings", "type": "object", "properties": { "description": { @@ -16448,7 +16450,7 @@ "x-go-name": "HideActivity" }, "hide_email": { - "description": "Piracy", + "description": "Privacy", "type": "boolean", "x-go-name": "HideEmail" }, From 2a80654cec696e2198f87b98d374ecba3a4d2c3d Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Thu, 17 Jun 2021 13:03:24 +0200 Subject: [PATCH 6/8] fix swagger --- routers/api/v1/user/preferences.go | 2 +- templates/swagger/v1_json.tmpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/routers/api/v1/user/preferences.go b/routers/api/v1/user/preferences.go index c6c3092cea011..6a14051ce806a 100644 --- a/routers/api/v1/user/preferences.go +++ b/routers/api/v1/user/preferences.go @@ -42,7 +42,7 @@ func GetUserSettings(ctx *context.APIContext) { // UpdateUserSettings returns user settings func UpdateUserSettings(ctx *context.APIContext) { - // swagger:operation PATCH /user/preferences user getUserSettings + // swagger:operation PATCH /user/preferences user updateUserSettings // --- // summary: Update user settings // parameters: diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 9068ff204f4e4..79e9d59fb2e2a 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -10760,7 +10760,7 @@ "user" ], "summary": "Update user settings", - "operationId": "getUserSettings", + "operationId": "updateUserSettings", "parameters": [ { "name": "body", From a4b40a2284cb728f9f19e7d698fa4290ce4b71c4 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Thu, 17 Jun 2021 13:06:24 +0200 Subject: [PATCH 7/8] move User2UserSettings to convert --- modules/convert/user.go | 15 +++++++++++++++ routers/api/v1/user/preferences.go | 19 +++---------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/modules/convert/user.go b/modules/convert/user.go index c588f5f2f076b..0fa2368201255 100644 --- a/modules/convert/user.go +++ b/modules/convert/user.go @@ -67,3 +67,18 @@ func toUser(user *models.User, signed, authed bool) *api.User { } return result } + +// User2UserSettings return UserSettings based on a user +func User2UserSettings(user *models.User) api.UserSettings { + return api.UserSettings{ + FullName: user.FullName, + Website: user.Website, + Location: user.Location, + Language: user.Language, + Description: user.Description, + Theme: user.Theme, + HideEmail: user.KeepEmailPrivate, + HideActivity: user.KeepActivityPrivate, + DiffViewStyle: user.DiffViewStyle, + } +} diff --git a/routers/api/v1/user/preferences.go b/routers/api/v1/user/preferences.go index 6a14051ce806a..7138f34c04efa 100644 --- a/routers/api/v1/user/preferences.go +++ b/routers/api/v1/user/preferences.go @@ -9,24 +9,11 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" ) -func user2UserSettings(user *models.User) api.UserSettings { - return api.UserSettings{ - FullName: user.FullName, - Website: user.Website, - Location: user.Location, - Language: user.Language, - Description: user.Description, - Theme: user.Theme, - HideEmail: user.KeepEmailPrivate, - HideActivity: user.KeepActivityPrivate, - DiffViewStyle: user.DiffViewStyle, - } -} - // GetUserSettings returns user settings func GetUserSettings(ctx *context.APIContext) { // swagger:operation GET /user/preferences user getUserSettings @@ -37,7 +24,7 @@ func GetUserSettings(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/UserSettings" - ctx.JSON(http.StatusOK, user2UserSettings(ctx.User)) + ctx.JSON(http.StatusOK, convert.User2UserSettings(ctx.User)) } // UpdateUserSettings returns user settings @@ -92,5 +79,5 @@ func UpdateUserSettings(ctx *context.APIContext) { return } - ctx.JSON(http.StatusOK, user2UserSettings(ctx.User)) + ctx.JSON(http.StatusOK, convert.User2UserSettings(ctx.User)) } From 5ed38ae250ce8590d3040bb41c7623fe74954ae8 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Thu, 17 Jun 2021 15:25:17 +0200 Subject: [PATCH 8/8] as per @zeripath "preferences" -> "settings" --- routers/api/v1/api.go | 2 +- .../v1/user/{preferences.go => settings.go} | 4 +- templates/swagger/v1_json.tmpl | 82 +++++++++---------- 3 files changed, 44 insertions(+), 44 deletions(-) rename routers/api/v1/user/{preferences.go => settings.go} (93%) diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 11fd65bb8d128..6bb697a0f6c8b 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -649,7 +649,7 @@ func Routes() *web.Route { m.Group("/user", func() { m.Get("", user.GetAuthenticatedUser) - m.Group("/preferences", func() { + m.Group("/settings", func() { m.Get("", user.GetUserSettings) m.Patch("", bind(api.UserSettingsOptions{}), user.UpdateUserSettings) }, reqToken()) diff --git a/routers/api/v1/user/preferences.go b/routers/api/v1/user/settings.go similarity index 93% rename from routers/api/v1/user/preferences.go rename to routers/api/v1/user/settings.go index 7138f34c04efa..b4548e7443fa2 100644 --- a/routers/api/v1/user/preferences.go +++ b/routers/api/v1/user/settings.go @@ -16,7 +16,7 @@ import ( // GetUserSettings returns user settings func GetUserSettings(ctx *context.APIContext) { - // swagger:operation GET /user/preferences user getUserSettings + // swagger:operation GET /user/settings user getUserSettings // --- // summary: Get user settings // produces: @@ -29,7 +29,7 @@ func GetUserSettings(ctx *context.APIContext) { // UpdateUserSettings returns user settings func UpdateUserSettings(ctx *context.APIContext) { - // swagger:operation PATCH /user/preferences user updateUserSettings + // swagger:operation PATCH /user/settings user updateUserSettings // --- // summary: Update user settings // parameters: diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 79e9d59fb2e2a..dd7519a1e5132 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -10736,47 +10736,6 @@ } } }, - "/user/preferences": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "user" - ], - "summary": "Get user settings", - "operationId": "getUserSettings", - "responses": { - "200": { - "$ref": "#/responses/UserSettings" - } - } - }, - "patch": { - "produces": [ - "application/json" - ], - "tags": [ - "user" - ], - "summary": "Update user settings", - "operationId": "updateUserSettings", - "parameters": [ - { - "name": "body", - "in": "body", - "schema": { - "$ref": "#/definitions/UserSettingsOptions" - } - } - ], - "responses": { - "200": { - "$ref": "#/responses/UserSettings" - } - } - } - }, "/user/repos": { "get": { "produces": [ @@ -10842,6 +10801,47 @@ } } }, + "/user/settings": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Get user settings", + "operationId": "getUserSettings", + "responses": { + "200": { + "$ref": "#/responses/UserSettings" + } + } + }, + "patch": { + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Update user settings", + "operationId": "updateUserSettings", + "parameters": [ + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/UserSettingsOptions" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/UserSettings" + } + } + } + }, "/user/starred": { "get": { "produces": [