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:
@ -61,11 +61,6 @@ func (api *API) template(rw http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if !api.Authorize(r, rbac.ActionRead, template) {
|
||||
httpapi.ResourceNotFound(rw)
|
||||
return
|
||||
}
|
||||
|
||||
count := uint32(0)
|
||||
if len(workspaceCounts) > 0 {
|
||||
count = uint32(workspaceCounts[0].Count)
|
||||
@ -248,9 +243,9 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
|
||||
|
||||
var dbTemplate database.Template
|
||||
var template codersdk.Template
|
||||
err = api.Database.InTx(func(db database.Store) error {
|
||||
err = api.Database.InTx(func(tx database.Store) error {
|
||||
now := database.Now()
|
||||
dbTemplate, err = db.InsertTemplate(ctx, database.InsertTemplateParams{
|
||||
dbTemplate, err = tx.InsertTemplate(ctx, database.InsertTemplateParams{
|
||||
ID: uuid.New(),
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
@ -269,7 +264,7 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
|
||||
|
||||
templateAudit.New = dbTemplate
|
||||
|
||||
err = db.UpdateTemplateVersionByID(ctx, database.UpdateTemplateVersionByIDParams{
|
||||
err = tx.UpdateTemplateVersionByID(ctx, database.UpdateTemplateVersionByIDParams{
|
||||
ID: templateVersion.ID,
|
||||
TemplateID: uuid.NullUUID{
|
||||
UUID: dbTemplate.ID,
|
||||
@ -288,7 +283,7 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
|
||||
templateVersionAudit.New = newTemplateVersion
|
||||
|
||||
for _, parameterValue := range createTemplate.ParameterValues {
|
||||
_, err = db.InsertParameterValue(ctx, database.InsertParameterValueParams{
|
||||
_, err = tx.InsertParameterValue(ctx, database.InsertParameterValueParams{
|
||||
ID: uuid.New(),
|
||||
Name: parameterValue.Name,
|
||||
CreatedAt: database.Now(),
|
||||
@ -304,7 +299,14 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
|
||||
}
|
||||
}
|
||||
|
||||
createdByNameMap, err := getCreatedByNamesByTemplateIDs(ctx, db, []database.Template{dbTemplate})
|
||||
err = tx.UpdateTemplateGroupACLByID(ctx, dbTemplate.ID, database.TemplateACL{
|
||||
dbTemplate.OrganizationID.String(): []rbac.Action{rbac.ActionRead},
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("update template group acl: %w", err)
|
||||
}
|
||||
|
||||
createdByNameMap, err := getCreatedByNamesByTemplateIDs(ctx, tx, []database.Template{dbTemplate})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("get creator name: %w", err)
|
||||
}
|
||||
@ -472,13 +474,7 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) {
|
||||
validErrs = append(validErrs, codersdk.ValidationError{Field: "min_autostart_interval_ms", Detail: "Must be a positive integer."})
|
||||
}
|
||||
if req.MaxTTLMillis > maxTTLDefault.Milliseconds() {
|
||||
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
|
||||
Message: "Invalid create template request.",
|
||||
Validations: []codersdk.ValidationError{
|
||||
{Field: "max_ttl_ms", Detail: "Cannot be greater than " + maxTTLDefault.String()},
|
||||
},
|
||||
})
|
||||
return
|
||||
validErrs = append(validErrs, codersdk.ValidationError{Field: "max_ttl_ms", Detail: "Cannot be greater than " + maxTTLDefault.String()})
|
||||
}
|
||||
|
||||
if len(validErrs) > 0 {
|
||||
@ -491,9 +487,9 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) {
|
||||
|
||||
count := uint32(0)
|
||||
var updated database.Template
|
||||
err := api.Database.InTx(func(s database.Store) error {
|
||||
err := api.Database.InTx(func(tx database.Store) error {
|
||||
// Fetch workspace counts
|
||||
workspaceCounts, err := s.GetWorkspaceOwnerCountsByTemplateIDs(ctx, []uuid.UUID{template.ID})
|
||||
workspaceCounts, err := tx.GetWorkspaceOwnerCountsByTemplateIDs(ctx, []uuid.UUID{template.ID})
|
||||
if xerrors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
}
|
||||
@ -530,7 +526,7 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) {
|
||||
minAutostartInterval = time.Duration(template.MinAutostartInterval)
|
||||
}
|
||||
|
||||
updated, err = s.UpdateTemplateMetaByID(ctx, database.UpdateTemplateMetaByIDParams{
|
||||
updated, err = tx.UpdateTemplateMetaByID(ctx, database.UpdateTemplateMetaByIDParams{
|
||||
ID: template.ID,
|
||||
UpdatedAt: database.Now(),
|
||||
Name: name,
|
||||
@ -597,13 +593,13 @@ type autoImportTemplateOpts struct {
|
||||
|
||||
func (api *API) autoImportTemplate(ctx context.Context, opts autoImportTemplateOpts) (database.Template, error) {
|
||||
var template database.Template
|
||||
err := api.Database.InTx(func(s database.Store) error {
|
||||
err := api.Database.InTx(func(tx database.Store) error {
|
||||
// Insert the archive into the files table.
|
||||
var (
|
||||
hash = sha256.Sum256(opts.archive)
|
||||
now = database.Now()
|
||||
)
|
||||
file, err := s.InsertFile(ctx, database.InsertFileParams{
|
||||
file, err := tx.InsertFile(ctx, database.InsertFileParams{
|
||||
Hash: hex.EncodeToString(hash[:]),
|
||||
CreatedAt: now,
|
||||
CreatedBy: opts.userID,
|
||||
@ -618,7 +614,7 @@ func (api *API) autoImportTemplate(ctx context.Context, opts autoImportTemplateO
|
||||
|
||||
// Insert parameters
|
||||
for key, value := range opts.params {
|
||||
_, err = s.InsertParameterValue(ctx, database.InsertParameterValueParams{
|
||||
_, err = tx.InsertParameterValue(ctx, database.InsertParameterValueParams{
|
||||
ID: uuid.New(),
|
||||
Name: key,
|
||||
CreatedAt: now,
|
||||
@ -635,7 +631,7 @@ func (api *API) autoImportTemplate(ctx context.Context, opts autoImportTemplateO
|
||||
}
|
||||
|
||||
// Create provisioner job
|
||||
job, err := s.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{
|
||||
job, err := tx.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{
|
||||
ID: jobID,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
@ -652,7 +648,7 @@ func (api *API) autoImportTemplate(ctx context.Context, opts autoImportTemplateO
|
||||
}
|
||||
|
||||
// Create template version
|
||||
templateVersion, err := s.InsertTemplateVersion(ctx, database.InsertTemplateVersionParams{
|
||||
templateVersion, err := tx.InsertTemplateVersion(ctx, database.InsertTemplateVersionParams{
|
||||
ID: uuid.New(),
|
||||
TemplateID: uuid.NullUUID{
|
||||
UUID: uuid.Nil,
|
||||
@ -674,7 +670,7 @@ func (api *API) autoImportTemplate(ctx context.Context, opts autoImportTemplateO
|
||||
}
|
||||
|
||||
// Create template
|
||||
template, err = s.InsertTemplate(ctx, database.InsertTemplateParams{
|
||||
template, err = tx.InsertTemplate(ctx, database.InsertTemplateParams{
|
||||
ID: uuid.New(),
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
@ -692,7 +688,7 @@ func (api *API) autoImportTemplate(ctx context.Context, opts autoImportTemplateO
|
||||
}
|
||||
|
||||
// Update template version with template ID
|
||||
err = s.UpdateTemplateVersionByID(ctx, database.UpdateTemplateVersionByIDParams{
|
||||
err = tx.UpdateTemplateVersionByID(ctx, database.UpdateTemplateVersionByIDParams{
|
||||
ID: templateVersion.ID,
|
||||
TemplateID: uuid.NullUUID{
|
||||
UUID: template.ID,
|
||||
@ -705,7 +701,7 @@ func (api *API) autoImportTemplate(ctx context.Context, opts autoImportTemplateO
|
||||
|
||||
// Insert parameters at the template scope
|
||||
for key, value := range opts.params {
|
||||
_, err = s.InsertParameterValue(ctx, database.InsertParameterValueParams{
|
||||
_, err = tx.InsertParameterValue(ctx, database.InsertParameterValueParams{
|
||||
ID: uuid.New(),
|
||||
Name: key,
|
||||
CreatedAt: now,
|
||||
@ -721,6 +717,13 @@ func (api *API) autoImportTemplate(ctx context.Context, opts autoImportTemplateO
|
||||
}
|
||||
}
|
||||
|
||||
err = tx.UpdateTemplateGroupACLByID(ctx, template.ID, database.TemplateACL{
|
||||
opts.orgID.String(): []rbac.Action{rbac.ActionRead},
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("update template group acl: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
|
Reference in New Issue
Block a user