From 4f12b5c206ffe72dcc6bcd32500fcf3f29280e69 Mon Sep 17 00:00:00 2001 From: Knut Ahlers Date: Sun, 2 Apr 2023 14:55:27 +0200 Subject: [PATCH] [editor] Add validation for template fields closes #38 Signed-off-by: Knut Ahlers --- config.go | 4 ++++ configEditor_global.go | 27 ++++++++++++++++++++++++ src/automessages.vue | 13 ++++++++++++ src/rules.vue | 14 ++++++++++++ src/tplEditor.vue | 48 ++++++++++++++++++++++++++++++++++++------ 5 files changed, 100 insertions(+), 6 deletions(-) diff --git a/config.go b/config.go index b330ddc..292fb20 100644 --- a/config.go +++ b/config.go @@ -172,6 +172,10 @@ func patchConfig(filename, authorName, authorEmail, summary string, patcher func return errors.Wrap(err, "patching config") } + if err = cfgFile.runLoadChecks(); err != nil { + return errors.Wrap(err, "checking config after patch") + } + return errors.Wrap( writeConfigToYAML(filename, authorName, authorEmail, summary, cfgFile), "replacing config", diff --git a/configEditor_global.go b/configEditor_global.go index bd1bbb8..d6819a9 100644 --- a/configEditor_global.go +++ b/configEditor_global.go @@ -13,6 +13,7 @@ import ( var frontendReloadHooks = newHooker() +//nolint:funlen // Just contains a collection of objects func registerEditorGlobalMethods() { for _, rd := range []plugins.HTTPRouteRegistrationArgs{ { @@ -100,6 +101,23 @@ func registerEditorGlobalMethods() { }, ResponseType: plugins.HTTPRouteResponseTypeTextPlain, }, + { + Description: "Validate a template expression against the built in template function library", + HandlerFunc: configEditorGlobalValidateTemplate, + Method: http.MethodPut, + Module: "config-editor", + Name: "Validate template expression", + Path: "/validate-template", + QueryParams: []plugins.HTTPRouteParamDocumentation{ + { + Description: "The template expression to test", + Name: "template", + Required: true, + Type: "string", + }, + }, + ResponseType: plugins.HTTPRouteResponseTypeTextPlain, + }, } { if err := registerRoute(rd); err != nil { log.WithError(err).Fatal("Unable to register config editor route") @@ -215,3 +233,12 @@ func configEditorGlobalValidateRegex(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNoContent) } + +func configEditorGlobalValidateTemplate(w http.ResponseWriter, r *http.Request) { + if err := validateTemplate(r.FormValue("template")); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + w.WriteHeader(http.StatusNoContent) +} diff --git a/src/automessages.vue b/src/automessages.vue index fe0b336..acb8efb 100644 --- a/src/automessages.vue +++ b/src/automessages.vue @@ -124,6 +124,7 @@ id="formAutoMessageMessage" v-model="models.autoMessage.message" :state="models.autoMessage.message ? models.autoMessage.message.length <= validateAutoMessageMessageLength : false" + @valid-template="valid => updateTemplateValid('autoMessage.message', valid)" />
@@ -284,6 +286,10 @@ export default { return false } + if (Object.entries(this.templateValid).filter(e => !e[1]).length > 0) { + return false + } + return true }, @@ -344,6 +350,7 @@ export default { }, showAutoMessageEditModal: false, + templateValid: {}, } }, @@ -376,6 +383,7 @@ export default { ...msg, sendMode: msg.cron ? 'cron' : 'lines', }) + this.templateValid = {} this.showAutoMessageEditModal = true }, @@ -392,6 +400,7 @@ export default { newAutoMessage() { Vue.set(this.models, 'autoMessage', {}) + this.templateValid = {} this.showAutoMessageEditModal = true }, @@ -422,6 +431,10 @@ export default { }) .catch(err => this.$bus.$emit(constants.NOTIFY_FETCH_ERROR, err)) }, + + updateTemplateValid(id, valid) { + Vue.set(this.templateValid, id, valid) + }, }, mounted() { diff --git a/src/rules.vue b/src/rules.vue index 083182d..5cf29f0 100644 --- a/src/rules.vue +++ b/src/rules.vue @@ -398,6 +398,7 @@ @@ -603,6 +604,7 @@ :id="`${models.rule.uuid}-action-${idx}-${field.key}`" v-model="models.rule.actions[idx].attributes[field.key]" :state="validateActionArgument(idx, field.key)" + @valid-template="valid => updateTemplateValid(`${models.rule.uuid}-action-${idx}-${field.key}`, valid)" /> @@ -781,6 +783,7 @@ export default { showRuleEditModal: false, showRuleSubscribeModal: false, + templateValid: {}, validateReason: null, } }, @@ -850,6 +853,7 @@ export default { cooldown: this.fixDurationRepresentationToString(msg.cooldown), user_cooldown: this.fixDurationRepresentationToString(msg.user_cooldown), }) + this.templateValid = {} this.showRuleEditModal = true this.validateMatcherRegex() }, @@ -976,6 +980,7 @@ export default { newRule() { Vue.set(this.models, 'rule', { match_message__validation: true }) + this.templateValid = {} this.showRuleEditModal = true }, @@ -1094,6 +1099,10 @@ export default { .catch(err => this.$bus.$emit(constants.NOTIFY_FETCH_ERROR, err)) }, + updateTemplateValid(id, valid) { + Vue.set(this.templateValid, id, valid) + }, + validateActionArgument(idx, key) { const action = this.models.rule.actions[idx] const def = this.getActionDefinitionByType(action.type) @@ -1189,6 +1198,11 @@ export default { }, validateRule() { + if (Object.entries(this.templateValid).filter(e => !e[1]).length > 0) { + this.validateReason = 'templateValid' + return false + } + if (!this.models.rule.match_message__validation) { this.validateReason = 'rule.match_message__validation' return false diff --git a/src/tplEditor.vue b/src/tplEditor.vue index f3a6ded..2ac2376 100644 --- a/src/tplEditor.vue +++ b/src/tplEditor.vue @@ -1,11 +1,20 @@