Skip to content

Commit

Permalink
🐛 Protect builtin questionnaires from update/delete (konveyor#512)
Browse files Browse the repository at this point in the history
Only changing the `required` field is permitted for builtin
questionnaires, all other changes and deletion are disallowed.

---------

Signed-off-by: Sam Lucidi <[email protected]>
  • Loading branch information
mansam authored and aufi committed Oct 30, 2023
1 parent 697b502 commit 855f10d
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 6 deletions.
38 changes: 32 additions & 6 deletions api/questionnaire.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ func (h QuestionnaireHandler) Delete(ctx *gin.Context) {
_ = ctx.Error(result.Error)
return
}
if m.Builtin() {
h.Status(ctx, http.StatusForbidden)
return
}
result = h.DB(ctx).Delete(m)
if result.Error != nil {
_ = ctx.Error(result.Error)
Expand All @@ -134,7 +138,9 @@ func (h QuestionnaireHandler) Delete(ctx *gin.Context) {

// Update godoc
// @summary Update a questionnaire.
// @description Update a questionnaire.
// @description Update a questionnaire. If the Questionnaire
// @description is builtin, only its "required" field can be changed
// @description and all other fields will be ignored.
// @tags questionnaires
// @accept json
// @success 204
Expand All @@ -149,12 +155,30 @@ func (h QuestionnaireHandler) Update(ctx *gin.Context) {
_ = ctx.Error(err)
return
}
m := r.Model()
m.ID = id
m.UpdateUser = h.CurrentUser(ctx)
db := h.DB(ctx).Model(m)
m := &model.Questionnaire{}
db := h.DB(ctx)
result := db.First(m, id)
if result.Error != nil {
_ = ctx.Error(result.Error)
return
}

updated := r.Model()
updated.ID = id
updated.UpdateUser = h.CurrentUser(ctx)
var fields map[string]interface{}
if m.Builtin() {
fields = map[string]interface{}{
"updateUser": updated.UpdateUser,
"required": updated.Required,
}
} else {
fields = h.fields(updated)
}

db = h.DB(ctx).Model(m)
db = db.Omit(clause.Associations)
result := db.Updates(h.fields(m))
result = db.Updates(fields)
if result.Error != nil {
_ = ctx.Error(result.Error)
return
Expand All @@ -171,6 +195,7 @@ type Questionnaire struct {
Sections []assessment.Section `json:"sections" yaml:"sections" binding:"required"`
Thresholds assessment.Thresholds `json:"thresholds" yaml:"thresholds" binding:"required"`
RiskMessages assessment.RiskMessages `json:"riskMessages" yaml:"riskMessages" binding:"required"`
Builtin bool `json:"builtin,omitempty" yaml:"builtin,omitempty"`
}

// With updates the resource with the model.
Expand All @@ -179,6 +204,7 @@ func (r *Questionnaire) With(m *model.Questionnaire) {
r.Name = m.Name
r.Description = m.Description
r.Required = m.Required
r.Builtin = m.Builtin()
_ = json.Unmarshal(m.Sections, &r.Sections)
_ = json.Unmarshal(m.Thresholds, &r.Thresholds)
_ = json.Unmarshal(m.RiskMessages, &r.RiskMessages)
Expand Down
6 changes: 6 additions & 0 deletions migration/v10/model/assessment.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ type Questionnaire struct {
Assessments []Assessment `gorm:"constraint:OnDelete:CASCADE"`
}

//
// Builtin returns true if this is a Konveyor-provided questionnaire.
func (r *Questionnaire) Builtin() bool {
return r.UUID != nil
}

type Assessment struct {
Model
ApplicationID *uint `gorm:"uniqueIndex:AssessmentA"`
Expand Down

0 comments on commit 855f10d

Please sign in to comment.