From 98666a9f4d79a1d2bb8e9be318946e99bdcaa8b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Fri, 6 Sep 2019 16:23:45 +0200 Subject: [PATCH] Move over checker plugins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- apps/workflowengine/src/components/Check.vue | 5 +- .../{Values => Checks}/FileMimeType.vue | 5 +- .../src/components/Checks/FileSystemTag.vue | 68 +++++++++ .../src/components/Checks/RequestTime.vue | 94 +++++++++++++ .../components/Checks/RequestUserAgent.vue | 122 ++++++++++++++++ .../src/components/Checks/file.js | 102 ++++++++++++++ .../src/components/Checks/index.js | 26 ++++ .../src/components/Checks/request.js | 70 +++++++++ apps/workflowengine/src/components/Event.vue | 2 +- apps/workflowengine/src/components/Rule.vue | 4 +- .../src/components/Values/SizeValue.vue | 44 ------ .../src/components/Values/file.js | 133 ------------------ apps/workflowengine/src/helpers/validators.js | 49 +++++++ apps/workflowengine/src/workflowengine.js | 16 +-- 14 files changed, 547 insertions(+), 193 deletions(-) rename apps/workflowengine/src/components/{Values => Checks}/FileMimeType.vue (95%) create mode 100644 apps/workflowengine/src/components/Checks/FileSystemTag.vue create mode 100644 apps/workflowengine/src/components/Checks/RequestTime.vue create mode 100644 apps/workflowengine/src/components/Checks/RequestUserAgent.vue create mode 100644 apps/workflowengine/src/components/Checks/file.js create mode 100644 apps/workflowengine/src/components/Checks/index.js create mode 100644 apps/workflowengine/src/components/Checks/request.js delete mode 100644 apps/workflowengine/src/components/Values/SizeValue.vue delete mode 100644 apps/workflowengine/src/components/Values/file.js create mode 100644 apps/workflowengine/src/helpers/validators.js diff --git a/apps/workflowengine/src/components/Check.vue b/apps/workflowengine/src/components/Check.vue index e521dffbb2..508b8a4a1f 100644 --- a/apps/workflowengine/src/components/Check.vue +++ b/apps/workflowengine/src/components/Check.vue @@ -16,9 +16,10 @@ + + diff --git a/apps/workflowengine/src/components/Checks/RequestTime.vue b/apps/workflowengine/src/components/Checks/RequestTime.vue new file mode 100644 index 0000000000..2f09693232 --- /dev/null +++ b/apps/workflowengine/src/components/Checks/RequestTime.vue @@ -0,0 +1,94 @@ + + + + + diff --git a/apps/workflowengine/src/components/Checks/RequestUserAgent.vue b/apps/workflowengine/src/components/Checks/RequestUserAgent.vue new file mode 100644 index 0000000000..676a4c2317 --- /dev/null +++ b/apps/workflowengine/src/components/Checks/RequestUserAgent.vue @@ -0,0 +1,122 @@ + + + + + + + diff --git a/apps/workflowengine/src/components/Checks/file.js b/apps/workflowengine/src/components/Checks/file.js new file mode 100644 index 0000000000..146ac045ce --- /dev/null +++ b/apps/workflowengine/src/components/Checks/file.js @@ -0,0 +1,102 @@ +/* + * @copyright Copyright (c) 2019 Julius Härtl + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +import FileMimeType from './FileMimeType'; +import { stringValidator, validateIPv4, validateIPv6} from './../../helpers/validators' +const FileChecks = [ + { + class: 'OCA\\WorkflowEngine\\Check\\FileName', + name: t('workflowengine', 'File name'), + operators: [ + { operator: 'is', name: t('workflowengine', 'is') }, + { operator: '!is', name: t('workflowengine', 'is not') }, + { operator: 'matches', name: t('workflowengine', 'matches') }, + { operator: '!matches', name: t('workflowengine', 'does not match') } + ], + placeholder: (check) => { + if (check.operator === 'matches' || check.operator === '!matches') { + return '/^dummy-.+$/i' + } + return 'filename.txt' + }, + validate: stringValidator + }, + + { + class: 'OCA\\WorkflowEngine\\Check\\FileMimeType', + name: t('workflowengine', 'File MIME type'), + operators: [ + { operator: 'is', name: t('workflowengine', 'is') }, + { operator: '!is', name: t('workflowengine', 'is not') }, + { operator: 'matches', name: t('workflowengine', 'matches') }, + { operator: '!matches', name: t('workflowengine', 'does not match') } + ], + component: FileMimeType + }, + + { + class: 'OCA\\WorkflowEngine\\Check\\FileSize', + name: t('workflowengine', 'File size (upload)'), + operators: [ + { operator: 'less', name: t('workflowengine', 'less') }, + { operator: '!greater', name: t('workflowengine', 'less or equals') }, + { operator: '!less', name: t('workflowengine', 'greater or equals') }, + { operator: 'greater', name: t('workflowengine', 'greater') } + ], + placeholder: (check) => '5 MB', + validate: (check) => check.value.match(/^[0-9]+[ ]?[kmgt]?b$/i) !== null + }, + + { + class: 'OCA\\WorkflowEngine\\Check\\RequestRemoteAddress', + name: t('workflowengine', 'Request remote address'), + operators: [ + { operator: 'matchesIPv4', name: t('workflowengine', 'matches IPv4') }, + { operator: '!matchesIPv4', name: t('workflowengine', 'does not match IPv4') }, + { operator: 'matchesIPv6', name: t('workflowengine', 'matches IPv6') }, + { operator: '!matchesIPv6', name: t('workflowengine', 'does not match IPv6') } + ], + placeholder: (check) => { + if (check.operator === 'matchesIPv6' || check.operator === '!matchesIPv6') { + return '::1/128'; + } + return '127.0.0.1/32' + }, + validate: (check) => { + if (check.operator === 'matchesIPv6' || check.operator === '!matchesIPv6') { + return validateIPv6(check.value) + } + return validateIPv4(check.value) + } + }, + + { + class: 'OCA\\WorkflowEngine\\Check\\FileSystemTags', + name: t('workflowengine', 'File system tag'), + operators: [ + { operator: 'is', name: t('workflowengine', 'is tagged with') }, + { operator: '!is', name: t('workflowengine', 'is not tagged with') } + ] + } +] + +export default FileChecks diff --git a/apps/workflowengine/src/components/Checks/index.js b/apps/workflowengine/src/components/Checks/index.js new file mode 100644 index 0000000000..d20472111b --- /dev/null +++ b/apps/workflowengine/src/components/Checks/index.js @@ -0,0 +1,26 @@ +/* + * @copyright Copyright (c) 2019 Julius Härtl + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +import FileChecks from './file' +import RequestChecks from './request' + +export default [...FileChecks, ...RequestChecks] diff --git a/apps/workflowengine/src/components/Checks/request.js b/apps/workflowengine/src/components/Checks/request.js new file mode 100644 index 0000000000..d2e4eaa356 --- /dev/null +++ b/apps/workflowengine/src/components/Checks/request.js @@ -0,0 +1,70 @@ +/* + * @copyright Copyright (c) 2019 Julius Härtl + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +import RequestUserAgent from './RequestUserAgent'; +import RequestTime from './RequestTime'; + +const RequestChecks = [ + { + class: 'OCA\\WorkflowEngine\\Check\\RequestURL', + name: t('workflowengine', 'Request URL'), + operators: [ + { operator: 'is', name: t('workflowengine', 'is') }, + { operator: '!is', name: t('workflowengine', 'is not') }, + { operator: 'matches', name: t('workflowengine', 'matches') }, + { operator: '!matches', name: t('workflowengine', 'does not match') } + ], + // TODO: implement component + }, + { + class: 'OCA\\WorkflowEngine\\Check\\RequestTime', + name: t('workflowengine', 'Request time'), + operators: [ + { operator: 'in', name: t('workflowengine', 'between') }, + { operator: '!in', name: t('workflowengine', 'not between') } + ], + // TODO: implement component + component: RequestTime + }, + { + class: 'OCA\\WorkflowEngine\\Check\\RequestUserAgent', + name: t('workflowengine', 'Request user agent'), + operators: [ + { operator: 'is', name: t('workflowengine', 'is') }, + { operator: '!is', name: t('workflowengine', 'is not') }, + { operator: 'matches', name: t('workflowengine', 'matches') }, + { operator: '!matches', name: t('workflowengine', 'does not match') } + ], + component: RequestUserAgent + }, + { + class: 'OCA\\WorkflowEngine\\Check\\UserGroupMembership', + name: t('workflowengine', 'User group membership'), + operators: [ + { operator: 'is', name: t('workflowengine', 'is member of') }, + { operator: '!is', name: t('workflowengine', 'is not member of') } + ], + // TODO: implement component + } +] + +export default RequestChecks diff --git a/apps/workflowengine/src/components/Event.vue b/apps/workflowengine/src/components/Event.vue index 5ff59882b9..ea153758c7 100644 --- a/apps/workflowengine/src/components/Event.vue +++ b/apps/workflowengine/src/components/Event.vue @@ -20,7 +20,7 @@ - - diff --git a/apps/workflowengine/src/components/Values/file.js b/apps/workflowengine/src/components/Values/file.js deleted file mode 100644 index 2d8ca93639..0000000000 --- a/apps/workflowengine/src/components/Values/file.js +++ /dev/null @@ -1,133 +0,0 @@ -/* - * @copyright Copyright (c) 2019 Julius Härtl - * - * @author Julius Härtl - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -import './../../legacy/filesystemtagsplugin' -import './../../legacy/requesttimeplugin' -import './../../legacy/requesturlplugin' -import './../../legacy/requestuseragentplugin' -import './../../legacy/usergroupmembershipplugin' - -import FileMimeType from './FileMimeType'; - -const FileChecks = Object.values(OCA.WorkflowEngine.Plugins).map((plugin) => { - if (plugin.component) { - return { ...plugin.getCheck(), component: plugin.component() } - } - return plugin.getCheck() -}) - - -// new way of registering checks - -const validateRegex = function(string) { - var regexRegex = /^\/(.*)\/([gui]{0,3})$/ - var result = regexRegex.exec(string) - return result !== null -} - -const validateIPv4 = function(string) { - var regexRegex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/(3[0-2]|[1-2][0-9]|[1-9])$/ - var result = regexRegex.exec(string) - return result !== null -} - -const validateIPv6 = function(string) { - var regexRegex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9])$/ - var result = regexRegex.exec(string) - return result !== null -} - -const stringValidator = (check) => { - if (check.operator === 'matches' || check.operator === '!matches') { - return validateRegex(check.value) - } - return true -} - - -FileChecks.push({ - class: 'OCA\\WorkflowEngine\\Check\\FileName', - name: t('workflowengine', 'File name'), - operators: [ - { operator: 'is', name: t('workflowengine', 'is') }, - { operator: '!is', name: t('workflowengine', 'is not') }, - { operator: 'matches', name: t('workflowengine', 'matches') }, - { operator: '!matches', name: t('workflowengine', 'does not match') } - ], - placeholder: (check) => { - if (check.operator === 'matches' || check.operator === '!matches') { - return '/^dummy-.+$/i' - } - return 'filename.txt' - }, - validate: stringValidator -}) - -FileChecks.push({ - class: 'OCA\\WorkflowEngine\\Check\\FileMimeType', - name: t('workflowengine', 'File MIME type'), - operators: [ - { operator: 'is', name: t('workflowengine', 'is') }, - { operator: '!is', name: t('workflowengine', 'is not') }, - { operator: 'matches', name: t('workflowengine', 'matches') }, - { operator: '!matches', name: t('workflowengine', 'does not match') } - ], - component: FileMimeType -}) - -FileChecks.push({ - class: 'OCA\\WorkflowEngine\\Check\\FileSize', - name: t('workflowengine', 'File size (upload)'), - operators: [ - { operator: 'less', name: t('workflowengine', 'less') }, - { operator: '!greater', name: t('workflowengine', 'less or equals') }, - { operator: '!less', name: t('workflowengine', 'greater or equals') }, - { operator: 'greater', name: t('workflowengine', 'greater') } - ], - placeholder: (check) => '5 MB', - validate: (check) => check.value.match(/^[0-9]+[ ]?[kmgt]?b$/i) !== null -}) - -FileChecks.push({ - class: 'OCA\\WorkflowEngine\\Check\\RequestRemoteAddress', - name: t('workflowengine', 'Request remote address'), - operators: [ - { operator: 'matchesIPv4', name: t('workflowengine', 'matches IPv4') }, - { operator: '!matchesIPv4', name: t('workflowengine', 'does not match IPv4') }, - { operator: 'matchesIPv6', name: t('workflowengine', 'matches IPv6') }, - { operator: '!matchesIPv6', name: t('workflowengine', 'does not match IPv6') } - ], - placeholder: (check) => { - if (check.operator === 'matchesIPv6' || check.operator === '!matchesIPv6') { - return '::1/128'; - } - return '127.0.0.1/32' - }, - validate: (check) => { - if (check.operator === 'matchesIPv6' || check.operator === '!matchesIPv6') { - return validateIPv6(check.value) - } - return validateIPv4(check.value) - } -}) - -export default FileChecks diff --git a/apps/workflowengine/src/helpers/validators.js b/apps/workflowengine/src/helpers/validators.js new file mode 100644 index 0000000000..033ce2ec7f --- /dev/null +++ b/apps/workflowengine/src/helpers/validators.js @@ -0,0 +1,49 @@ +/* + * @copyright Copyright (c) 2019 Julius Härtl + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + + +const validateRegex = function(string) { + var regexRegex = /^\/(.*)\/([gui]{0,3})$/ + var result = regexRegex.exec(string) + return result !== null +} + +const validateIPv4 = function(string) { + var regexRegex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/(3[0-2]|[1-2][0-9]|[1-9])$/ + var result = regexRegex.exec(string) + return result !== null +} + +const validateIPv6 = function(string) { + var regexRegex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9])$/ + var result = regexRegex.exec(string) + return result !== null +} + +const stringValidator = (check) => { + if (check.operator === 'matches' || check.operator === '!matches') { + return validateRegex(check.value) + } + return true +} + +export { validateRegex, stringValidator, validateIPv4, validateIPv6 } diff --git a/apps/workflowengine/src/workflowengine.js b/apps/workflowengine/src/workflowengine.js index e05ac0a505..149f9d4aa8 100644 --- a/apps/workflowengine/src/workflowengine.js +++ b/apps/workflowengine/src/workflowengine.js @@ -1,9 +1,8 @@ import Vue from 'vue' import Vuex from 'vuex' import store from './store' - import Settings from './components/Workflow' -import FileValues from './components/Values/file' +import ShippedChecks from './components/Checks' /** * A plugin for displaying a custom value field for checks @@ -43,7 +42,6 @@ import FileValues from './components/Values/file' */ window.OCA.WorkflowEngine = Object.assign({}, OCA.WorkflowEngine, { - /** * * @param {CheckPlugin} Plugin @@ -60,8 +58,8 @@ window.OCA.WorkflowEngine = Object.assign({}, OCA.WorkflowEngine, { } }) -// Register shipped checks for file entity -FileValues.forEach((checkPlugin) => window.OCA.WorkflowEngine.registerCheck(checkPlugin)) +// Register shipped checks +ShippedChecks.forEach((checkPlugin) => window.OCA.WorkflowEngine.registerCheck(checkPlugin)) /** * FIXME: remove before merge as this is for UI testing only @@ -69,16 +67,16 @@ FileValues.forEach((checkPlugin) => window.OCA.WorkflowEngine.registerCheck(chec const demo = [ { id: 'OCA\\TestExample\\Operation1', - name: 'Rename file', - description: '🚧 For UI mocking only', - iconClass: 'icon-address-white', + name: 'Convert to PDF', + description: 'Convert a file to PDF using Libreoffice', + iconClass: 'icon-convert-pdf', color: 'var(--color-success)', operation: 'deny' }, { id: 'OCA\\TestExample\\Operation2', name: 'Notify me', - description: '🚧 For UI mocking only', + description: 'Send a Nextcloud Notification', iconClass: 'icon-comment-white', color: 'var(--color-warning)', operation: 'deny'