mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
feat: add template RBAC/groups (#4235)
This commit is contained in:
@ -24,8 +24,12 @@ import (
|
||||
|
||||
func (api *API) templateVersion(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
templateVersion := httpmw.TemplateVersionParam(r)
|
||||
if !api.Authorize(r, rbac.ActionRead, templateVersion) {
|
||||
var (
|
||||
templateVersion = httpmw.TemplateVersionParam(r)
|
||||
template = httpmw.TemplateParam(r)
|
||||
)
|
||||
|
||||
if !api.Authorize(r, rbac.ActionRead, templateVersion.RBACObject(template)) {
|
||||
httpapi.ResourceNotFound(rw)
|
||||
return
|
||||
}
|
||||
@ -53,8 +57,11 @@ func (api *API) templateVersion(rw http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func (api *API) patchCancelTemplateVersion(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
templateVersion := httpmw.TemplateVersionParam(r)
|
||||
if !api.Authorize(r, rbac.ActionUpdate, templateVersion) {
|
||||
var (
|
||||
templateVersion = httpmw.TemplateVersionParam(r)
|
||||
template = httpmw.TemplateParam(r)
|
||||
)
|
||||
if !api.Authorize(r, rbac.ActionUpdate, templateVersion.RBACObject(template)) {
|
||||
httpapi.ResourceNotFound(rw)
|
||||
return
|
||||
}
|
||||
@ -105,8 +112,12 @@ func (api *API) patchCancelTemplateVersion(rw http.ResponseWriter, r *http.Reque
|
||||
|
||||
func (api *API) templateVersionSchema(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
templateVersion := httpmw.TemplateVersionParam(r)
|
||||
if !api.Authorize(r, rbac.ActionRead, templateVersion) {
|
||||
var (
|
||||
templateVersion = httpmw.TemplateVersionParam(r)
|
||||
template = httpmw.TemplateParam(r)
|
||||
)
|
||||
|
||||
if !api.Authorize(r, rbac.ActionRead, templateVersion.RBACObject(template)) {
|
||||
httpapi.ResourceNotFound(rw)
|
||||
return
|
||||
}
|
||||
@ -153,8 +164,11 @@ func (api *API) templateVersionSchema(rw http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func (api *API) templateVersionParameters(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
templateVersion := httpmw.TemplateVersionParam(r)
|
||||
if !api.Authorize(r, rbac.ActionRead, templateVersion) {
|
||||
var (
|
||||
templateVersion = httpmw.TemplateVersionParam(r)
|
||||
template = httpmw.TemplateParam(r)
|
||||
)
|
||||
if !api.Authorize(r, rbac.ActionRead, templateVersion.RBACObject(template)) {
|
||||
httpapi.ResourceNotFound(rw)
|
||||
return
|
||||
}
|
||||
@ -195,9 +209,12 @@ func (api *API) templateVersionParameters(rw http.ResponseWriter, r *http.Reques
|
||||
|
||||
func (api *API) postTemplateVersionDryRun(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
apiKey := httpmw.APIKey(r)
|
||||
templateVersion := httpmw.TemplateVersionParam(r)
|
||||
if !api.Authorize(r, rbac.ActionRead, templateVersion) {
|
||||
var (
|
||||
apiKey = httpmw.APIKey(r)
|
||||
templateVersion = httpmw.TemplateVersionParam(r)
|
||||
template = httpmw.TemplateParam(r)
|
||||
)
|
||||
if !api.Authorize(r, rbac.ActionRead, templateVersion.RBACObject(template)) {
|
||||
httpapi.ResourceNotFound(rw)
|
||||
return
|
||||
}
|
||||
@ -367,9 +384,11 @@ func (api *API) fetchTemplateVersionDryRunJob(rw http.ResponseWriter, r *http.Re
|
||||
var (
|
||||
ctx = r.Context()
|
||||
templateVersion = httpmw.TemplateVersionParam(r)
|
||||
template = httpmw.TemplateParam(r)
|
||||
jobID = chi.URLParam(r, "jobID")
|
||||
)
|
||||
if !api.Authorize(r, rbac.ActionRead, templateVersion) {
|
||||
|
||||
if !api.Authorize(r, rbac.ActionRead, templateVersion.RBACObject(template)) {
|
||||
httpapi.ResourceNotFound(rw)
|
||||
return database.ProvisionerJob{}, false
|
||||
}
|
||||
@ -667,14 +686,10 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
|
||||
return
|
||||
}
|
||||
|
||||
// Making a new template version is the same permission as creating a new template.
|
||||
if !api.Authorize(r, rbac.ActionCreate, rbac.ResourceTemplate.InOrg(organization.ID)) {
|
||||
httpapi.ResourceNotFound(rw)
|
||||
return
|
||||
}
|
||||
|
||||
var template database.Template
|
||||
if req.TemplateID != uuid.Nil {
|
||||
_, err := api.Database.GetTemplateByID(ctx, req.TemplateID)
|
||||
var err error
|
||||
template, err = api.Database.GetTemplateByID(ctx, req.TemplateID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(ctx, rw, http.StatusNotFound, codersdk.Response{
|
||||
Message: "Template does not exist.",
|
||||
@ -690,6 +705,17 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
|
||||
}
|
||||
}
|
||||
|
||||
if template.ID != uuid.Nil {
|
||||
if !api.Authorize(r, rbac.ActionCreate, template) {
|
||||
httpapi.ResourceNotFound(rw)
|
||||
return
|
||||
}
|
||||
} else if !api.Authorize(r, rbac.ActionCreate, rbac.ResourceTemplate.InOrg(organization.ID)) {
|
||||
// Making a new template version is the same permission as creating a new template.
|
||||
httpapi.ResourceNotFound(rw)
|
||||
return
|
||||
}
|
||||
|
||||
file, err := api.Database.GetFileByHash(ctx, req.StorageSource)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(ctx, rw, http.StatusNotFound, codersdk.Response{
|
||||
@ -705,14 +731,16 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
|
||||
return
|
||||
}
|
||||
|
||||
if !api.Authorize(r, rbac.ActionRead, file) {
|
||||
httpapi.ResourceNotFound(rw)
|
||||
return
|
||||
}
|
||||
// TODO(JonA): Readd this check once we update the unique constraint
|
||||
// on files to be owner + hash.
|
||||
// if !api.Authorize(r, rbac.ActionRead, file) {
|
||||
// httpapi.ResourceNotFound(rw)
|
||||
// return
|
||||
// }
|
||||
|
||||
var templateVersion database.TemplateVersion
|
||||
var provisionerJob database.ProvisionerJob
|
||||
err = api.Database.InTx(func(db database.Store) error {
|
||||
err = api.Database.InTx(func(tx database.Store) error {
|
||||
jobID := uuid.New()
|
||||
inherits := make([]uuid.UUID, 0)
|
||||
for _, parameterValue := range req.ParameterValues {
|
||||
@ -727,7 +755,7 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
|
||||
return xerrors.Errorf("cannot inherit parameters if template_id is not set")
|
||||
}
|
||||
|
||||
inheritedParams, err := db.ParameterValues(ctx, database.ParameterValuesParams{
|
||||
inheritedParams, err := tx.ParameterValues(ctx, database.ParameterValuesParams{
|
||||
IDs: inherits,
|
||||
})
|
||||
if err != nil {
|
||||
@ -736,7 +764,7 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
|
||||
for _, copy := range inheritedParams {
|
||||
// This is a bit inefficient, as we make a new db call for each
|
||||
// param.
|
||||
version, err := db.GetTemplateVersionByJobID(ctx, copy.ScopeID)
|
||||
version, err := tx.GetTemplateVersionByJobID(ctx, copy.ScopeID)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("fetch template version for param %q: %w", copy.Name, err)
|
||||
}
|
||||
@ -761,7 +789,7 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
|
||||
continue
|
||||
}
|
||||
|
||||
_, err = db.InsertParameterValue(ctx, database.InsertParameterValueParams{
|
||||
_, err = tx.InsertParameterValue(ctx, database.InsertParameterValueParams{
|
||||
ID: uuid.New(),
|
||||
Name: parameterValue.Name,
|
||||
CreatedAt: database.Now(),
|
||||
@ -777,7 +805,7 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
|
||||
}
|
||||
}
|
||||
|
||||
provisionerJob, err = db.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{
|
||||
provisionerJob, err = tx.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{
|
||||
ID: jobID,
|
||||
CreatedAt: database.Now(),
|
||||
UpdatedAt: database.Now(),
|
||||
@ -805,7 +833,7 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
|
||||
req.Name = namesgenerator.GetRandomName(1)
|
||||
}
|
||||
|
||||
templateVersion, err = db.InsertTemplateVersion(ctx, database.InsertTemplateVersionParams{
|
||||
templateVersion, err = tx.InsertTemplateVersion(ctx, database.InsertTemplateVersionParams{
|
||||
ID: uuid.New(),
|
||||
TemplateID: templateID,
|
||||
OrganizationID: organization.ID,
|
||||
@ -851,8 +879,12 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
|
||||
// return agents associated with any particular workspace.
|
||||
func (api *API) templateVersionResources(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
templateVersion := httpmw.TemplateVersionParam(r)
|
||||
if !api.Authorize(r, rbac.ActionRead, templateVersion) {
|
||||
var (
|
||||
templateVersion = httpmw.TemplateVersionParam(r)
|
||||
template = httpmw.TemplateParam(r)
|
||||
)
|
||||
|
||||
if !api.Authorize(r, rbac.ActionRead, templateVersion.RBACObject(template)) {
|
||||
httpapi.ResourceNotFound(rw)
|
||||
return
|
||||
}
|
||||
@ -874,8 +906,12 @@ func (api *API) templateVersionResources(rw http.ResponseWriter, r *http.Request
|
||||
// Eg: Logs returned from 'terraform plan' when uploading a new terraform file.
|
||||
func (api *API) templateVersionLogs(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
templateVersion := httpmw.TemplateVersionParam(r)
|
||||
if !api.Authorize(r, rbac.ActionRead, templateVersion) {
|
||||
var (
|
||||
templateVersion = httpmw.TemplateVersionParam(r)
|
||||
template = httpmw.TemplateParam(r)
|
||||
)
|
||||
|
||||
if !api.Authorize(r, rbac.ActionRead, templateVersion.RBACObject(template)) {
|
||||
httpapi.ResourceNotFound(rw)
|
||||
return
|
||||
}
|
||||
|
Reference in New Issue
Block a user