Skip to content

Commit

Permalink
Implement database changes and store methods for global and organizat…
Browse files Browse the repository at this point in the history
…ion secrets

* Add tests for new store methods
* Add organization secret API and UI
* Add global secrets API and UI
  • Loading branch information
lafriks committed Aug 7, 2022
1 parent 98636a5 commit 79e9c2b
Show file tree
Hide file tree
Showing 34 changed files with 1,744 additions and 129 deletions.
2 changes: 1 addition & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"voorjaar.windicss-intellisense",
"johnsoncodehk.volar",
"Vue.volar",
"redhat.vscode-yaml",
"davidanson.vscode-markdownlint"
],
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ require (
google.golang.org/grpc v1.47.0
google.golang.org/protobuf v1.28.0
gopkg.in/yaml.v3 v3.0.1
xorm.io/builder v0.3.10
xorm.io/xorm v1.3.0
xorm.io/builder v0.3.12
xorm.io/xorm v1.3.1
)

require (
Expand Down
10 changes: 5 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1199,8 +1199,8 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
xorm.io/builder v0.3.9/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
xorm.io/builder v0.3.10 h1:Rvkncad3Lo9YIVqCbgIf6QnpR/HcW3IEr0AANNpuyMQ=
xorm.io/builder v0.3.10/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
xorm.io/xorm v1.3.0 h1:UsVke0wyAk3tJcb0j15gLWv2DEshVUnySVyvcYDny8w=
xorm.io/xorm v1.3.0/go.mod h1:cEaWjDPqoIusTkmDAG+krCcPcTglqo8CDU8geX/yhko=
xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
xorm.io/builder v0.3.12 h1:ASZYX7fQmy+o8UJdhlLHSW57JDOkM8DNhcAF5d0LiJM=
xorm.io/builder v0.3.12/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
xorm.io/xorm v1.3.1 h1:z5egKrDoOLqZFhMjcGF4FBHiTmE5/feQoHclfhNidfM=
xorm.io/xorm v1.3.1/go.mod h1:9NbjqdnjX6eyjRRhh01GHm64r6N9shTb/8Ak3YRt8Nw=
123 changes: 123 additions & 0 deletions server/api/global_secret.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Copyright 2022 Woodpecker Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package api

import (
"net/http"

"github.com/woodpecker-ci/woodpecker/server"
"github.com/woodpecker-ci/woodpecker/server/model"

"github.com/gin-gonic/gin"
)

// GetGlobalSecretList get the global secret list from
// the database and writes to the response in json format.
func GetGlobalSecretList(c *gin.Context) {
list, err := server.Config.Services.Secrets.GlobalSecretList()
if err != nil {
c.String(http.StatusInternalServerError, "Error getting global secret list. %s", err)
return
}
// copy the secret detail to remove the sensitive
// password and token fields.
for i, secret := range list {
list[i] = secret.Copy()
}
c.JSON(http.StatusOK, list)
}

// GetGlobalSecret gets the named global secret from the database
// and writes to the response in json format.
func GetGlobalSecret(c *gin.Context) {
name := c.Param("secret")
secret, err := server.Config.Services.Secrets.GlobalSecretFind(name)
if err != nil {
c.String(404, "Error getting global secret %q. %s", name, err)
return
}
c.JSON(200, secret.Copy())
}

// PostGlobalSecret persists the global secret to the database.
func PostGlobalSecret(c *gin.Context) {
in := new(model.Secret)
if err := c.Bind(in); err != nil {
c.String(http.StatusBadRequest, "Error parsing global secret. %s", err)
return
}
secret := &model.Secret{
Name: in.Name,
Value: in.Value,
Events: in.Events,
Images: in.Images,
}
if err := secret.Validate(); err != nil {
c.String(400, "Error inserting global secret. %s", err)
return
}
if err := server.Config.Services.Secrets.GlobalSecretCreate(secret); err != nil {
c.String(500, "Error inserting global secret %q. %s", in.Name, err)
return
}
c.JSON(200, secret.Copy())
}

// PatchGlobalSecret updates the global secret in the database.
func PatchGlobalSecret(c *gin.Context) {
name := c.Param("secret")

in := new(model.Secret)
err := c.Bind(in)
if err != nil {
c.String(http.StatusBadRequest, "Error parsing secret. %s", err)
return
}

secret, err := server.Config.Services.Secrets.GlobalSecretFind(name)
if err != nil {
c.String(404, "Error getting global secret %q. %s", name, err)
return
}
if in.Value != "" {
secret.Value = in.Value
}
if in.Events != nil {
secret.Events = in.Events
}
if in.Images != nil {
secret.Images = in.Images
}

if err := secret.Validate(); err != nil {
c.String(400, "Error updating global secret. %s", err)
return
}
if err := server.Config.Services.Secrets.GlobalSecretUpdate(secret); err != nil {
c.String(500, "Error updating global secret %q. %s", in.Name, err)
return
}
c.JSON(200, secret.Copy())
}

// DeleteGlobalSecret deletes the named global secret from the database.
func DeleteGlobalSecret(c *gin.Context) {
name := c.Param("secret")
if err := server.Config.Services.Secrets.GlobalSecretDelete(name); err != nil {
c.String(500, "Error deleting global secret %q. %s", name, err)
return
}
c.String(204, "")
}
41 changes: 41 additions & 0 deletions server/api/org.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2022 Woodpecker Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package api

import (
"net/http"

"github.com/woodpecker-ci/woodpecker/server"
"github.com/woodpecker-ci/woodpecker/server/router/middleware/session"

"github.com/gin-gonic/gin"
)

// GetOrgPermissions returns the permissions of the current user in the given organization.
func GetOrgPermissions(c *gin.Context) {
var (
err error
user = session.User(c)
owner = c.Param("owner")
)

perm, err := server.Config.Services.Membership.Get(c, user, owner)
if err != nil {
c.String(http.StatusInternalServerError, "Error getting membership for %q. %s", owner, err)
return
}

c.JSON(http.StatusOK, perm)
}
136 changes: 136 additions & 0 deletions server/api/org_secret.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
// Copyright 2022 Woodpecker Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package api

import (
"net/http"

"github.com/woodpecker-ci/woodpecker/server"
"github.com/woodpecker-ci/woodpecker/server/model"

"github.com/gin-gonic/gin"
)

// GetOrgSecret gets the named organization secret from the database
// and writes to the response in json format.
func GetOrgSecret(c *gin.Context) {
var (
owner = c.Param("owner")
name = c.Param("secret")
)
secret, err := server.Config.Services.Secrets.OrgSecretFind(owner, name)
if err != nil {
c.String(404, "Error getting org %q secret %q. %s", owner, name, err)
return
}
c.JSON(200, secret.Copy())
}

// GetOrgSecretList get the organization secret list from
// the database and writes to the response in json format.
func GetOrgSecretList(c *gin.Context) {
owner := c.Param("owner")
list, err := server.Config.Services.Secrets.OrgSecretList(owner)
if err != nil {
c.String(http.StatusInternalServerError, "Error getting secret list for %q. %s", owner, err)
return
}
// copy the secret detail to remove the sensitive
// password and token fields.
for i, secret := range list {
list[i] = secret.Copy()
}
c.JSON(http.StatusOK, list)
}

// PostOrgSecret persists the organization secret to the database.
func PostOrgSecret(c *gin.Context) {
owner := c.Param("owner")

in := new(model.Secret)
if err := c.Bind(in); err != nil {
c.String(http.StatusBadRequest, "Error parsing org %q secret. %s", owner, err)
return
}
secret := &model.Secret{
Owner: owner,
Name: in.Name,
Value: in.Value,
Events: in.Events,
Images: in.Images,
}
if err := secret.Validate(); err != nil {
c.String(400, "Error inserting org %q secret. %s", owner, err)
return
}
if err := server.Config.Services.Secrets.OrgSecretCreate(owner, secret); err != nil {
c.String(500, "Error inserting org %q secret %q. %s", owner, in.Name, err)
return
}
c.JSON(200, secret.Copy())
}

// PatchOrgSecret updates the organization secret in the database.
func PatchOrgSecret(c *gin.Context) {
var (
owner = c.Param("owner")
name = c.Param("secret")
)

in := new(model.Secret)
err := c.Bind(in)
if err != nil {
c.String(http.StatusBadRequest, "Error parsing secret. %s", err)
return
}

secret, err := server.Config.Services.Secrets.OrgSecretFind(owner, name)
if err != nil {
c.String(404, "Error getting org %q secret %q. %s", owner, name, err)
return
}
if in.Value != "" {
secret.Value = in.Value
}
if in.Events != nil {
secret.Events = in.Events
}
if in.Images != nil {
secret.Images = in.Images
}

if err := secret.Validate(); err != nil {
c.String(400, "Error updating org %q secret. %s", owner, err)
return
}
if err := server.Config.Services.Secrets.OrgSecretUpdate(owner, secret); err != nil {
c.String(500, "Error updating org %q secret %q. %s", owner, in.Name, err)
return
}
c.JSON(200, secret.Copy())
}

// DeleteOrgSecret deletes the named organization secret from the database.
func DeleteOrgSecret(c *gin.Context) {
var (
owner = c.Param("owner")
name = c.Param("secret")
)
if err := server.Config.Services.Secrets.OrgSecretDelete(owner, name); err != nil {
c.String(500, "Error deleting org %q secret %q. %s", owner, name, err)
return
}
c.String(204, "")
}
File renamed without changes.
Loading

0 comments on commit 79e9c2b

Please sign in to comment.