-
- {{svg "octicon-key" 32}}
+ {{if .desc}}
+
+ {{ctx.Locale.Tr .desc}}
-
-
- {{.Name}}
-
-
- ******
+ {{end}}
+ {{if .ctxData.Secrets}}
+ {{range .ctxData.Secrets}}
+
+
+ {{svg "octicon-key" 32}}
+
+
+
+ {{.Name}}
+
+
+ ******
+
+
+
+
+ {{ctx.Locale.Tr "settings.added_on" (DateTime "short" .CreatedUnix) | Safe}}
+
+
+
+ {{end}}
+ {{else}}
+
+ {{ctx.Locale.Tr "secrets.none"}}
-
-
- {{ctx.Locale.Tr "settings.added_on" (DateTime "short" .CreatedUnix) | Safe}}
-
-
-
-
{{end}}
- {{else}}
- {{ctx.Locale.Tr "secrets.none"}}
- {{end}}
{{/* Add secret dialog */}}
diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl
index 403f241d72787..84badc0d2ba6d 100644
--- a/templates/swagger/v1_json.tmpl
+++ b/templates/swagger/v1_json.tmpl
@@ -75,6 +75,84 @@
}
}
},
+ "/admin/actions/secrets/{secretname}": {
+ "put": {
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "admin"
+ ],
+ "summary": "Create or Update a secret value in instance scope",
+ "operationId": "updateAdminSecret",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "name of the secret",
+ "name": "secretname",
+ "in": "path",
+ "required": true
+ },
+ {
+ "name": "body",
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/CreateOrUpdateSecretOption"
+ }
+ }
+ ],
+ "responses": {
+ "201": {
+ "description": "secret created"
+ },
+ "204": {
+ "description": "secret updated"
+ },
+ "400": {
+ "$ref": "#/responses/error"
+ },
+ "404": {
+ "$ref": "#/responses/notFound"
+ }
+ }
+ },
+ "delete": {
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "admin"
+ ],
+ "summary": "Delete a secret in instance scope",
+ "operationId": "deleteAdminSecret",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "name of the secret",
+ "name": "secretname",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "secret deleted"
+ },
+ "400": {
+ "$ref": "#/responses/error"
+ },
+ "404": {
+ "$ref": "#/responses/notFound"
+ }
+ }
+ }
+ },
"/admin/cron": {
"get": {
"produces": [
@@ -1687,10 +1765,10 @@
],
"responses": {
"201": {
- "description": "response when creating a secret"
+ "description": "secret created"
},
"204": {
- "description": "response when updating a secret"
+ "description": "secret updated"
},
"400": {
"$ref": "#/responses/error"
@@ -1730,7 +1808,7 @@
],
"responses": {
"204": {
- "description": "delete one secret of the organization"
+ "description": "secret deleted"
},
"400": {
"$ref": "#/responses/error"
@@ -3414,10 +3492,10 @@
],
"responses": {
"201": {
- "description": "response when creating a secret"
+ "description": "secret created"
},
"204": {
- "description": "response when updating a secret"
+ "description": "secret updated"
},
"400": {
"$ref": "#/responses/error"
@@ -3464,7 +3542,7 @@
],
"responses": {
"204": {
- "description": "delete one secret of the organization"
+ "description": "secret deleted"
},
"400": {
"$ref": "#/responses/error"
@@ -14644,10 +14722,10 @@
],
"responses": {
"201": {
- "description": "response when creating a secret"
+ "description": "secret created"
},
"204": {
- "description": "response when updating a secret"
+ "description": "secret updated"
},
"400": {
"$ref": "#/responses/error"
@@ -14680,7 +14758,7 @@
],
"responses": {
"204": {
- "description": "delete one secret of the user"
+ "description": "secret deleted"
},
"400": {
"$ref": "#/responses/error"
diff --git a/templates/user/settings/actions.tmpl b/templates/user/settings/actions.tmpl
index abc544338355b..37f211eeff092 100644
--- a/templates/user/settings/actions.tmpl
+++ b/templates/user/settings/actions.tmpl
@@ -1,7 +1,7 @@
{{template "user/settings/layout_head" (dict "ctxData" . "pageClass" "user settings actions")}}
{{if eq .PageType "secrets"}}
- {{template "shared/secrets/add_list" .}}
+ {{template "shared/secrets/add_list" (dict "ctxData" .)}}
{{else if eq .PageType "runners"}}
{{template "shared/actions/runner_list" .}}
{{else if eq .PageType "variables"}}
diff --git a/tests/integration/api_admin_secrets_test.go b/tests/integration/api_admin_secrets_test.go
new file mode 100644
index 0000000000000..694f274d8645f
--- /dev/null
+++ b/tests/integration/api_admin_secrets_test.go
@@ -0,0 +1,98 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package integration
+
+import (
+ "fmt"
+ "net/http"
+ "testing"
+
+ auth_model "code.gitea.io/gitea/models/auth"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/tests"
+)
+
+func TestAPIAdminSecrets(t *testing.T) {
+ defer tests.PrepareTestEnv(t)()
+
+ session := loginUser(t, "user1")
+ token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteAdmin)
+
+ t.Run("Create", func(t *testing.T) {
+ cases := []struct {
+ Name string
+ ExpectedStatus int
+ }{
+ {
+ Name: "",
+ ExpectedStatus: http.StatusNotFound,
+ },
+ {
+ Name: "-",
+ ExpectedStatus: http.StatusBadRequest,
+ },
+ {
+ Name: "_",
+ ExpectedStatus: http.StatusCreated,
+ },
+ {
+ Name: "secret",
+ ExpectedStatus: http.StatusCreated,
+ },
+ {
+ Name: "2secret",
+ ExpectedStatus: http.StatusBadRequest,
+ },
+ {
+ Name: "GITEA_secret",
+ ExpectedStatus: http.StatusBadRequest,
+ },
+ {
+ Name: "GITHUB_secret",
+ ExpectedStatus: http.StatusBadRequest,
+ },
+ }
+
+ for _, c := range cases {
+ req := NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/admin/actions/secrets/%s", c.Name), api.CreateOrUpdateSecretOption{
+ Data: "data",
+ }).AddTokenAuth(token)
+ MakeRequest(t, req, c.ExpectedStatus)
+ }
+ })
+
+ t.Run("Update", func(t *testing.T) {
+ name := "update_secret"
+ url := fmt.Sprintf("/api/v1/admin/actions/secrets/%s", name)
+
+ req := NewRequestWithJSON(t, "PUT", url, api.CreateOrUpdateSecretOption{
+ Data: "initial",
+ }).AddTokenAuth(token)
+ MakeRequest(t, req, http.StatusCreated)
+
+ req = NewRequestWithJSON(t, "PUT", url, api.CreateOrUpdateSecretOption{
+ Data: "changed",
+ }).AddTokenAuth(token)
+ MakeRequest(t, req, http.StatusNoContent)
+ })
+
+ t.Run("Delete", func(t *testing.T) {
+ name := "delete_secret"
+ url := fmt.Sprintf("/api/v1/admin/actions/secrets/%s", name)
+
+ req := NewRequestWithJSON(t, "PUT", url, api.CreateOrUpdateSecretOption{
+ Data: "initial",
+ }).AddTokenAuth(token)
+ MakeRequest(t, req, http.StatusCreated)
+
+ req = NewRequest(t, "DELETE", url).AddTokenAuth(token)
+ MakeRequest(t, req, http.StatusNoContent)
+
+ req = NewRequest(t, "DELETE", url).AddTokenAuth(token)
+ MakeRequest(t, req, http.StatusNotFound)
+
+ req = NewRequest(t, "DELETE", "/api/v1/admin/actions/secrets/000").AddTokenAuth(token)
+ MakeRequest(t, req, http.StatusBadRequest)
+ })
+}