Allow to add a note to secrets (#5898)

Co-authored-by: 6543 <6543@obermui.de>
This commit is contained in:
qwerty287
2026-01-10 13:06:27 +01:00
committed by GitHub
parent d554141d16
commit 8db8f49d16
10 changed files with 82 additions and 24 deletions

View File

@@ -1729,7 +1729,7 @@ const docTemplate = `{
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/Secret"
"$ref": "#/definitions/SecretPatch"
}
}
],
@@ -3921,7 +3921,7 @@ const docTemplate = `{
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/Secret"
"$ref": "#/definitions/SecretPatch"
}
}
],
@@ -4113,7 +4113,7 @@ const docTemplate = `{
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/Secret"
"$ref": "#/definitions/SecretPatch"
}
}
],
@@ -5456,6 +5456,9 @@ const docTemplate = `{
"name": {
"type": "string"
},
"note": {
"type": "string"
},
"org_id": {
"type": "integer"
},
@@ -5467,6 +5470,32 @@ const docTemplate = `{
}
}
},
"SecretPatch": {
"type": "object",
"properties": {
"events": {
"type": "array",
"items": {
"$ref": "#/definitions/WebhookEvent"
}
},
"images": {
"type": "array",
"items": {
"type": "string"
}
},
"name": {
"type": "string"
},
"note": {
"type": "string"
},
"value": {
"type": "string"
}
}
},
"StatusValue": {
"type": "string",
"enum": [

View File

@@ -89,6 +89,7 @@ func PostGlobalSecret(c *gin.Context) {
Value: in.Value,
Events: in.Events,
Images: in.Images,
Note: in.Note,
}
if err := secret.Validate(); err != nil {
c.String(http.StatusBadRequest, "Error inserting global secret. %s", err)
@@ -110,13 +111,13 @@ func PostGlobalSecret(c *gin.Context) {
// @Produce json
// @Success 200 {object} Secret
// @Tags Secrets
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
// @Param secret path string true "the secret's name"
// @Param secretData body Secret true "the secret's data"
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
// @Param secret path string true "the secret's name"
// @Param secretData body SecretPatch true "the secret's data"
func PatchGlobalSecret(c *gin.Context) {
name := c.Param("secret")
in := new(model.Secret)
in := new(model.SecretPatch)
err := c.Bind(in)
if err != nil {
c.String(http.StatusBadRequest, "Error parsing secret. %s", err)
@@ -129,8 +130,8 @@ func PatchGlobalSecret(c *gin.Context) {
handleDBError(c, err)
return
}
if in.Value != "" {
secret.Value = in.Value
if in.Value != nil && *in.Value != "" {
secret.Value = *in.Value
}
if in.Events != nil {
secret.Events = in.Events
@@ -138,6 +139,9 @@ func PatchGlobalSecret(c *gin.Context) {
if in.Images != nil {
secret.Images = in.Images
}
if in.Note != nil {
secret.Note = *in.Note
}
if err := secret.Validate(); err != nil {
c.String(http.StatusBadRequest, "Error updating global secret. %s", err)

View File

@@ -99,6 +99,7 @@ func PostOrgSecret(c *gin.Context) {
Value: in.Value,
Events: in.Events,
Images: in.Images,
Note: in.Note,
}
if err := secret.Validate(); err != nil {
c.String(http.StatusUnprocessableEntity, "Error inserting org %q secret. %s", org.ID, err)
@@ -120,15 +121,15 @@ func PostOrgSecret(c *gin.Context) {
// @Produce json
// @Success 200 {object} Secret
// @Tags Organization secrets
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
// @Param org_id path string true "the org's id"
// @Param secret path string true "the secret's name"
// @Param secretData body Secret true "the update secret data"
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
// @Param org_id path string true "the org's id"
// @Param secret path string true "the secret's name"
// @Param secretData body SecretPatch true "the update secret data"
func PatchOrgSecret(c *gin.Context) {
org := session.Org(c)
name := c.Param("secret")
in := new(model.Secret)
in := new(model.SecretPatch)
if err := c.Bind(in); err != nil {
c.String(http.StatusBadRequest, "Error parsing secret. %s", err)
return
@@ -140,8 +141,8 @@ func PatchOrgSecret(c *gin.Context) {
handleDBError(c, err)
return
}
if in.Value != "" {
secret.Value = in.Value
if in.Value != nil && *in.Value != "" {
secret.Value = *in.Value
}
if in.Events != nil {
secret.Events = in.Events
@@ -149,6 +150,9 @@ func PatchOrgSecret(c *gin.Context) {
if in.Images != nil {
secret.Images = in.Images
}
if in.Note != nil {
secret.Note = *in.Note
}
if err := secret.Validate(); err != nil {
c.String(http.StatusUnprocessableEntity, "Error updating org %q secret. %s", org.ID, err)

View File

@@ -71,6 +71,7 @@ func PostSecret(c *gin.Context) {
Value: in.Value,
Events: in.Events,
Images: in.Images,
Note: in.Note,
}
if err := secret.Validate(); err != nil {
c.String(http.StatusUnprocessableEntity, "Error inserting secret. %s", err)
@@ -92,17 +93,17 @@ func PostSecret(c *gin.Context) {
// @Produce json
// @Success 200 {object} Secret
// @Tags Repository secrets
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
// @Param repo_id path int true "the repository id"
// @Param secretName path string true "the secret name"
// @Param secret body Secret true "the secret itself"
// @Param Authorization header string true "Insert your personal access token" default(Bearer <personal access token>)
// @Param repo_id path int true "the repository id"
// @Param secretName path string true "the secret name"
// @Param secret body SecretPatch true "the secret itself"
func PatchSecret(c *gin.Context) {
var (
repo = session.Repo(c)
name = c.Param("secret")
)
in := new(model.Secret)
in := new(model.SecretPatch)
err := c.Bind(in)
if err != nil {
c.String(http.StatusBadRequest, "Error parsing secret. %s", err)
@@ -115,8 +116,8 @@ func PatchSecret(c *gin.Context) {
handleDBError(c, err)
return
}
if in.Value != "" {
secret.Value = in.Value
if in.Value != nil && *in.Value != "" {
secret.Value = *in.Value
}
if in.Events != nil {
secret.Events = in.Events
@@ -124,6 +125,9 @@ func PatchSecret(c *gin.Context) {
if in.Images != nil {
secret.Images = in.Images
}
if in.Note != nil {
secret.Note = *in.Note
}
if err := secret.Validate(); err != nil {
c.String(http.StatusUnprocessableEntity, "Error updating secret. %s", err)

View File

@@ -52,6 +52,7 @@ type Secret struct {
Value string `json:"value,omitempty" xorm:"TEXT 'value'"`
Images []string `json:"images" xorm:"json 'images'"`
Events []WebhookEvent `json:"events" xorm:"json 'events'"`
Note string `json:"note" xorm:"note"`
} // @name Secret
// TableName return database table name for xorm.
@@ -129,6 +130,7 @@ func (s *Secret) Copy() *Secret {
Name: s.Name,
Images: s.Images,
Events: sortEvents(s.Events),
Note: s.Note,
}
}
@@ -136,3 +138,11 @@ func sortEvents(wel WebhookEventList) WebhookEventList {
sort.Sort(wel)
return wel
}
type SecretPatch struct {
Name *string `json:"name" `
Value *string `json:"value,omitempty" `
Images []string `json:"images" `
Events []WebhookEvent `json:"events" `
Note *string `json:"note" `
} // @name SecretPatch

View File

@@ -465,6 +465,7 @@
"show": "Show secrets",
"name": "Name",
"value": "Value",
"note": "Note",
"delete_confirm": "Do you really want to delete this secret?",
"deleted": "Secret deleted",
"created": "Secret created",

View File

@@ -41,6 +41,10 @@
<CheckboxesField v-model="innerValue.events" :options="secretEventsOptions" />
</InputField>
<InputField v-slot="{ id }" :label="$t('secrets.note')">
<TextField :id="id" v-model="innerValue.note" :placeholder="$t('secrets.note')" :lines="3" />
</InputField>
<div class="flex gap-2">
<Button type="button" color="gray" :text="$t('cancel')" @click="$emit('cancel')" />
<Button

View File

@@ -5,7 +5,7 @@
:key="secret.id"
class="bg-wp-background-200! dark:bg-wp-background-200! items-center"
>
<span>{{ secret.name }}</span>
<span :title="secret.note">{{ secret.name }}</span>
<Badge
v-if="secret.edit === false"
class="ml-2"

View File

@@ -8,4 +8,5 @@ export interface Secret {
value: string;
events: WebhookEvents[];
images: string[];
note: string;
}

View File

@@ -183,6 +183,7 @@ type (
Value string `json:"value,omitempty"`
Images []string `json:"images"`
Events []string `json:"events"`
Note string `json:"note"`
}
// Feed represents an item in the user's feed or timeline.