-
-
Notifications
You must be signed in to change notification settings - Fork 383
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add global and organization secrets (#1027)
* Implement database changes and store methods for global and organization secrets * Add tests for new store methods * Add organization secret API and UI * Add global secrets API and UI * Add suggestions * Update warning style * Apply suggestions from code review Co-authored-by: Anbraten <[email protected]> * Fix lint warning Co-authored-by: Anbraten <[email protected]>
- Loading branch information
Showing
35 changed files
with
1,778 additions
and
131 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 gets 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 a 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 a 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, "") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// 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/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") | ||
) | ||
|
||
if user == nil { | ||
c.JSON(http.StatusOK, &model.OrgPerm{}) | ||
return | ||
} | ||
|
||
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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 gest 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 an 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 an 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.
Oops, something went wrong.