From 8cd46024fdcdaf04cd09be2c25db673e99b0a024 Mon Sep 17 00:00:00 2001 From: Bo-Yi Wu Date: Mon, 28 Aug 2023 13:08:19 +0800 Subject: [PATCH] refactor(API): refactor secret creation and update functionality (#26751) According to the GitHub API Spec: https://docs.github.com/en/rest/actions/secrets?apiVersion=2022-11-28#create-or-update-an-organization-secret Merge the Create and Update secret into a single API. - Remove the `CreateSecretOption` struct and replace it with `CreateOrUpdateSecretOption` in `modules/structs/secret.go` - Update the `CreateOrUpdateOrgSecret` function in `routers/api/v1/org/action.go` to use `CreateOrUpdateSecretOption` instead of `UpdateSecretOption` - Remove the `CreateOrgSecret` function in `routers/api/v1/org/action.go` and replace it with `CreateOrUpdateOrgSecret` - Update the Swagger documentation in `routers/api/v1/swagger/options.go` and `templates/swagger/v1_json.tmpl` to reflect the changes in the struct names and function names Signed-off-by: Bo-Yi Wu --- modules/structs/secret.go | 16 +---- routers/api/v1/api.go | 3 +- routers/api/v1/org/action.go | 74 ++++++-------------- routers/api/v1/swagger/options.go | 5 +- templates/swagger/v1_json.tmpl | 108 +++++++----------------------- 5 files changed, 51 insertions(+), 155 deletions(-) diff --git a/modules/structs/secret.go b/modules/structs/secret.go index 52221b51f0..a0673ca08c 100644 --- a/modules/structs/secret.go +++ b/modules/structs/secret.go @@ -14,21 +14,9 @@ type Secret struct { Created time.Time `json:"created_at"` } -// CreateSecretOption options when creating secret +// CreateOrUpdateSecretOption options when creating or updating secret // swagger:model -type CreateSecretOption struct { - // Name of the secret to create - // - // required: true - // unique: true - Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(100)"` - // Data of the secret to create - Data string `json:"data" binding:"Required"` -} - -// UpdateSecretOption options when updating secret -// swagger:model -type UpdateSecretOption struct { +type CreateOrUpdateSecretOption struct { // Data of the secret to update // // required: true diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 2d644507d5..6424931a47 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -1300,9 +1300,8 @@ func Routes() *web.Route { }) m.Group("/actions/secrets", func() { m.Get("", reqToken(), reqOrgOwnership(), org.ListActionsSecrets) - m.Post("", reqToken(), reqOrgOwnership(), bind(api.CreateSecretOption{}), org.CreateOrgSecret) m.Combo("/{secretname}"). - Put(reqToken(), reqOrgOwnership(), bind(api.UpdateSecretOption{}), org.UpdateOrgSecret). + Put(reqToken(), reqOrgOwnership(), bind(api.CreateOrUpdateSecretOption{}), org.CreateOrUpdateOrgSecret). Delete(reqToken(), reqOrgOwnership(), org.DeleteOrgSecret) }) m.Group("/public_members", func() { diff --git a/routers/api/v1/org/action.go b/routers/api/v1/org/action.go index 9697a11363..ee18cca26d 100644 --- a/routers/api/v1/org/action.go +++ b/routers/api/v1/org/action.go @@ -12,7 +12,6 @@ import ( "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" "code.gitea.io/gitea/routers/web/shared/actions" - "code.gitea.io/gitea/services/convert" ) // ListActionsSecrets list an organization's actions secrets @@ -74,55 +73,11 @@ func listActionsSecrets(ctx *context.APIContext) { ctx.JSON(http.StatusOK, apiSecrets) } -// CreateOrgSecret create one secret of the organization -func CreateOrgSecret(ctx *context.APIContext) { - // swagger:operation POST /orgs/{org}/actions/secrets organization createOrgSecret - // --- - // summary: Create a secret in an organization - // consumes: - // - application/json - // produces: - // - application/json - // parameters: - // - name: org - // in: path - // description: name of organization - // type: string - // required: true - // - name: body - // in: body - // schema: - // "$ref": "#/definitions/CreateSecretOption" - // responses: - // "201": - // "$ref": "#/responses/Secret" - // "400": - // "$ref": "#/responses/error" - // "404": - // "$ref": "#/responses/notFound" - // "403": - // "$ref": "#/responses/forbidden" - opt := web.GetForm(ctx).(*api.CreateSecretOption) - if err := actions.NameRegexMatch(opt.Name); err != nil { - ctx.Error(http.StatusBadRequest, "CreateOrgSecret", err) - return - } - s, err := secret_model.InsertEncryptedSecret( - ctx, ctx.Org.Organization.ID, 0, opt.Name, actions.ReserveLineBreakForTextarea(opt.Data), - ) - if err != nil { - ctx.Error(http.StatusInternalServerError, "InsertEncryptedSecret", err) - return - } - - ctx.JSON(http.StatusCreated, convert.ToSecret(s)) -} - -// UpdateOrgSecret update one secret of the organization -func UpdateOrgSecret(ctx *context.APIContext) { +// create or update one secret of the organization +func CreateOrUpdateOrgSecret(ctx *context.APIContext) { // swagger:operation PUT /orgs/{org}/actions/secrets/{secretname} organization updateOrgSecret // --- - // summary: Update a secret value in an organization + // summary: Create or Update a secret value in an organization // consumes: // - application/json // produces: @@ -141,19 +96,34 @@ func UpdateOrgSecret(ctx *context.APIContext) { // - name: body // in: body // schema: - // "$ref": "#/definitions/UpdateSecretOption" + // "$ref": "#/definitions/CreateOrUpdateSecretOption" // responses: + // "201": + // description: response when creating a secret // "204": - // description: update one secret of the organization + // description: response when updating a secret + // "400": + // "$ref": "#/responses/error" // "403": // "$ref": "#/responses/forbidden" secretName := ctx.Params(":secretname") - opt := web.GetForm(ctx).(*api.UpdateSecretOption) + if err := actions.NameRegexMatch(secretName); err != nil { + ctx.Error(http.StatusBadRequest, "CreateOrUpdateOrgSecret", err) + return + } + opt := web.GetForm(ctx).(*api.CreateOrUpdateSecretOption) err := secret_model.UpdateSecret( ctx, ctx.Org.Organization.ID, 0, secretName, opt.Data, ) if secret_model.IsErrSecretNotFound(err) { - ctx.NotFound(err) + _, err := secret_model.InsertEncryptedSecret( + ctx, ctx.Org.Organization.ID, 0, secretName, actions.ReserveLineBreakForTextarea(opt.Data), + ) + if err != nil { + ctx.Error(http.StatusInternalServerError, "InsertEncryptedSecret", err) + return + } + ctx.Status(http.StatusCreated) return } if err != nil { diff --git a/routers/api/v1/swagger/options.go b/routers/api/v1/swagger/options.go index e41ee66776..6f7859df62 100644 --- a/routers/api/v1/swagger/options.go +++ b/routers/api/v1/swagger/options.go @@ -189,8 +189,5 @@ type swaggerParameterBodies struct { UpdateRepoAvatarOptions api.UpdateRepoAvatarOption // in:body - CreateSecretOption api.CreateSecretOption - - // in:body - UpdateSecretOption api.UpdateSecretOption + CreateOrUpdateSecretOption api.CreateOrUpdateSecretOption } diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index ca4e1c4606..d37f4463f5 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -1586,49 +1586,6 @@ "$ref": "#/responses/SecretList" } } - }, - "post": { - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "organization" - ], - "summary": "Create a secret in an organization", - "operationId": "createOrgSecret", - "parameters": [ - { - "type": "string", - "description": "name of organization", - "name": "org", - "in": "path", - "required": true - }, - { - "name": "body", - "in": "body", - "schema": { - "$ref": "#/definitions/CreateSecretOption" - } - } - ], - "responses": { - "201": { - "$ref": "#/responses/Secret" - }, - "400": { - "$ref": "#/responses/error" - }, - "403": { - "$ref": "#/responses/forbidden" - }, - "404": { - "$ref": "#/responses/notFound" - } - } } }, "/orgs/{org}/actions/secrets/{secretname}": { @@ -1642,7 +1599,7 @@ "tags": [ "organization" ], - "summary": "Update a secret value in an organization", + "summary": "Create or Update a secret value in an organization", "operationId": "updateOrgSecret", "parameters": [ { @@ -1663,13 +1620,19 @@ "name": "body", "in": "body", "schema": { - "$ref": "#/definitions/UpdateSecretOption" + "$ref": "#/definitions/CreateOrUpdateSecretOption" } } ], "responses": { + "201": { + "description": "response when creating a secret" + }, "204": { - "description": "update one secret of the organization" + "description": "response when updating a secret" + }, + "400": { + "$ref": "#/responses/error" }, "403": { "$ref": "#/responses/forbidden" @@ -17283,6 +17246,21 @@ }, "x-go-package": "code.gitea.io/gitea/modules/structs" }, + "CreateOrUpdateSecretOption": { + "description": "CreateOrUpdateSecretOption options when creating or updating secret", + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "description": "Data of the secret to update", + "type": "string", + "x-go-name": "Data" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, "CreateOrgOption": { "description": "CreateOrgOption options for creating an organization", "type": "object", @@ -17569,27 +17547,6 @@ }, "x-go-package": "code.gitea.io/gitea/modules/structs" }, - "CreateSecretOption": { - "description": "CreateSecretOption options when creating secret", - "type": "object", - "required": [ - "name" - ], - "properties": { - "data": { - "description": "Data of the secret to create", - "type": "string", - "x-go-name": "Data" - }, - "name": { - "description": "Name of the secret to create", - "type": "string", - "uniqueItems": true, - "x-go-name": "Name" - } - }, - "x-go-package": "code.gitea.io/gitea/modules/structs" - }, "CreateStatusOption": { "description": "CreateStatusOption holds the information needed to create a new CommitStatus for a Commit", "type": "object", @@ -21978,21 +21935,6 @@ }, "x-go-package": "code.gitea.io/gitea/modules/structs" }, - "UpdateSecretOption": { - "description": "UpdateSecretOption options when updating secret", - "type": "object", - "required": [ - "data" - ], - "properties": { - "data": { - "description": "Data of the secret to update", - "type": "string", - "x-go-name": "Data" - } - }, - "x-go-package": "code.gitea.io/gitea/modules/structs" - }, "UpdateUserAvatarOption": { "description": "UpdateUserAvatarUserOption options when updating the user avatar", "type": "object", @@ -23309,7 +23251,7 @@ "parameterBodies": { "description": "parameterBodies", "schema": { - "$ref": "#/definitions/UpdateSecretOption" + "$ref": "#/definitions/CreateOrUpdateSecretOption" } }, "redirect": {