This commit is contained in:
Bo-Yi Wu 2024-04-24 03:37:17 +08:00 committed by GitHub
commit ce0d29099a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 183 additions and 41 deletions

View File

@ -1073,26 +1073,21 @@ func Routes() *web.Route {
m.Post("/accept", repo.AcceptTransfer)
m.Post("/reject", repo.RejectTransfer)
}, reqToken())
m.Group("/actions", func() {
m.Group("/secrets", func() {
m.Combo("/{secretname}").
Put(reqToken(), reqOwner(), bind(api.CreateOrUpdateSecretOption{}), repo.CreateOrUpdateSecret).
Delete(reqToken(), reqOwner(), repo.DeleteSecret)
})
m.Group("/variables", func() {
m.Get("", reqToken(), reqOwner(), repo.ListVariables)
m.Combo("/{variablename}").
Get(reqToken(), reqOwner(), repo.GetVariable).
Delete(reqToken(), reqOwner(), repo.DeleteVariable).
Post(reqToken(), reqOwner(), bind(api.CreateVariableOption{}), repo.CreateVariable).
Put(reqToken(), reqOwner(), bind(api.UpdateVariableOption{}), repo.UpdateVariable)
})
m.Group("/runners", func() {
m.Get("/registration-token", reqToken(), reqOwner(), repo.GetRegistrationToken)
})
})
actionsGroup(
m,
reqOwner(),
actionAPI{
repo.ListActionsSecrets,
repo.CreateOrUpdateSecret,
repo.DeleteSecret,
repo.ListVariables,
repo.GetVariable,
repo.DeleteVariable,
repo.CreateVariable,
repo.UpdateVariable,
repo.GetRegistrationToken,
},
)
m.Group("/hooks/git", func() {
m.Combo("").Get(repo.ListGitHooks)
m.Group("/{id}", func() {
@ -1460,27 +1455,21 @@ func Routes() *web.Route {
m.Combo("/{username}").Get(reqToken(), org.IsMember).
Delete(reqToken(), reqOrgOwnership(), org.DeleteMember)
})
m.Group("/actions", func() {
m.Group("/secrets", func() {
m.Get("", reqToken(), reqOrgOwnership(), org.ListActionsSecrets)
m.Combo("/{secretname}").
Put(reqToken(), reqOrgOwnership(), bind(api.CreateOrUpdateSecretOption{}), org.CreateOrUpdateSecret).
Delete(reqToken(), reqOrgOwnership(), org.DeleteSecret)
})
m.Group("/variables", func() {
m.Get("", reqToken(), reqOrgOwnership(), org.ListVariables)
m.Combo("/{variablename}").
Get(reqToken(), reqOrgOwnership(), org.GetVariable).
Delete(reqToken(), reqOrgOwnership(), org.DeleteVariable).
Post(reqToken(), reqOrgOwnership(), bind(api.CreateVariableOption{}), org.CreateVariable).
Put(reqToken(), reqOrgOwnership(), bind(api.UpdateVariableOption{}), org.UpdateVariable)
})
m.Group("/runners", func() {
m.Get("/registration-token", reqToken(), reqOrgOwnership(), org.GetRegistrationToken)
})
})
actionsGroup(
m,
reqOrgOwnership(),
actionAPI{
org.ListActionsSecrets,
org.CreateOrUpdateSecret,
org.DeleteSecret,
org.ListVariables,
org.GetVariable,
org.DeleteVariable,
org.CreateVariable,
org.UpdateVariable,
org.GetRegistrationToken,
},
)
m.Group("/public_members", func() {
m.Get("", org.ListPublicMembers)
m.Combo("/{username}").Get(org.IsPublicMember).
@ -1596,6 +1585,47 @@ func Routes() *web.Route {
return m
}
// actionAPI is a struct that holds the actions API
type actionAPI struct {
ListActionsSecrets func(ctx *context.APIContext)
CreateOrUpdateSecret func(ctx *context.APIContext)
DeleteSecret func(ctx *context.APIContext)
ListVariables func(ctx *context.APIContext)
GetVariable func(ctx *context.APIContext)
DeleteVariable func(ctx *context.APIContext)
CreateVariable func(ctx *context.APIContext)
UpdateVariable func(ctx *context.APIContext)
GetRegistrationToken func(ctx *context.APIContext)
}
func actionsGroup(
m *web.Route,
reqChecker func(ctx *context.APIContext),
act actionAPI,
) {
m.Group("/actions", func() {
m.Group("/secrets", func() {
m.Get("", reqToken(), reqChecker, act.ListActionsSecrets)
m.Combo("/{secretname}").
Put(reqToken(), reqChecker, bind(api.CreateOrUpdateSecretOption{}), act.CreateOrUpdateSecret).
Delete(reqToken(), reqChecker, act.DeleteSecret)
})
m.Group("/variables", func() {
m.Get("", reqToken(), reqChecker, act.ListVariables)
m.Combo("/{variablename}").
Get(reqToken(), reqChecker, act.GetVariable).
Delete(reqToken(), reqChecker, act.DeleteVariable).
Post(reqToken(), reqChecker, bind(api.CreateVariableOption{}), act.CreateVariable).
Put(reqToken(), reqChecker, bind(api.UpdateVariableOption{}), act.UpdateVariable)
})
m.Group("/runners", func() {
m.Get("/registration-token", reqToken(), reqChecker, act.GetRegistrationToken)
})
})
}
func securityHeaders() func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {

View File

@ -9,6 +9,7 @@ import (
actions_model "code.gitea.io/gitea/models/actions"
"code.gitea.io/gitea/models/db"
secret_model "code.gitea.io/gitea/models/secret"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web"
@ -18,6 +19,63 @@ import (
secret_service "code.gitea.io/gitea/services/secrets"
)
// ListActionsSecrets list an repo's actions secrets
func ListActionsSecrets(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/actions/secrets repository repoListActionsSecrets
// ---
// summary: List an repo's actions secrets
// produces:
// - application/json
// parameters:
// - name: owner
// in: path
// description: owner of the repository
// type: string
// required: true
// - name: repo
// in: path
// description: name of the repository
// type: string
// required: true
// - 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/SecretList"
// "404":
// "$ref": "#/responses/notFound"
repo := ctx.Repo.Repository
opts := &secret_model.FindSecretsOptions{
RepoID: repo.ID,
ListOptions: utils.GetListOptions(ctx),
}
secrets, count, err := db.FindAndCount[secret_model.Secret](ctx, opts)
if err != nil {
ctx.InternalServerError(err)
return
}
apiSecrets := make([]*api.Secret, len(secrets))
for k, v := range secrets {
apiSecrets[k] = &api.Secret{
Name: v.Name,
Created: v.CreatedUnix.AsTime(),
}
}
ctx.SetTotalCountHeader(count)
ctx.JSON(http.StatusOK, apiSecrets)
}
// create or update one secret of the repository
func CreateOrUpdateSecret(ctx *context.APIContext) {
// swagger:operation PUT /repos/{owner}/{repo}/actions/secrets/{secretname} repository updateRepoSecret

View File

@ -3843,6 +3843,54 @@
}
}
},
"/repos/{owner}/{repo}/actions/secrets": {
"get": {
"produces": [
"application/json"
],
"tags": [
"repository"
],
"summary": "List an repo's actions secrets",
"operationId": "repoListActionsSecrets",
"parameters": [
{
"type": "string",
"description": "owner of the repository",
"name": "owner",
"in": "path",
"required": true
},
{
"type": "string",
"description": "name of the repository",
"name": "repo",
"in": "path",
"required": true
},
{
"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/SecretList"
},
"404": {
"$ref": "#/responses/notFound"
}
}
}
},
"/repos/{owner}/{repo}/actions/secrets/{secretname}": {
"put": {
"consumes": [

View File

@ -24,6 +24,12 @@ func TestAPIRepoSecrets(t *testing.T) {
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
t.Run("List", func(t *testing.T) {
req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/actions/secrets", repo.FullName())).
AddTokenAuth(token)
MakeRequest(t, req, http.StatusOK)
})
t.Run("Create", func(t *testing.T) {
cases := []struct {
Name string