From 8df5ddb11d6b22f22dc6241911efec3bad5aca3d Mon Sep 17 00:00:00 2001 From: Mirko Van Colen Date: Fri, 10 Nov 2023 11:38:18 +0100 Subject: [PATCH 1/5] version bump --- client/package.json | 2 +- server/package.json | 2 +- server/src/swagger.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/package.json b/client/package.json index b11e90e6..fd7e27c5 100644 --- a/client/package.json +++ b/client/package.json @@ -1,6 +1,6 @@ { "name": "ansible_forms_vue", - "version": "4.0.18", + "version": "4.0.19", "private": true, "scripts": { "serve": "vue-cli-service serve", diff --git a/server/package.json b/server/package.json index 0d80370e..e83a22c6 100644 --- a/server/package.json +++ b/server/package.json @@ -1,6 +1,6 @@ { "name": "ansible_forms", - "version": "4.0.18", + "version": "4.0.19", "repository": { "type": "git", "url": "git://github.com/ansibleguy76/ansibleforms.git" diff --git a/server/src/swagger.json b/server/src/swagger.json index e76a106d..bdaf19ed 100644 --- a/server/src/swagger.json +++ b/server/src/swagger.json @@ -2,7 +2,7 @@ "swagger": "2.0", "info": { "description": "This is the swagger interface for AnsibleForms.\r\nUse the `/auth/login` api with basic authentication to obtain a JWT token.\r\nThen use the access token, prefixed with the word '**Bearer**' to use all other api's.\r\nNote that the access token is limited in time. You can then either login again and get a new set of tokens or use the `/token` api and the refresh token to obtain a new set (preferred).", - "version": "4.0.18", + "version": "4.0.19", "title": "AnsibleForms", "contact": { "email": "info@ansibleforms.com" From ec8aef86982e0c68b5491f3663c95920d8a8a095 Mon Sep 17 00:00:00 2001 From: Mirko Van Colen Date: Wed, 22 Nov 2023 09:52:05 +0100 Subject: [PATCH 2/5] bug fix --- client/src/components/Form.vue | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/src/components/Form.vue b/client/src/components/Form.vue index bde69e04..18c26dd4 100644 --- a/client/src/components/Form.vue +++ b/client/src/components/Form.vue @@ -1180,7 +1180,7 @@ // check self references while(!finishedFlag){ finishedFlag=true - temp = JSON.parse(JSON.stringify(ref.dynamicFieldDependencies)); // copy dependencies to temp + temp = Helpers.deepClone(ref.dynamicFieldDependencies); // copy dependencies to temp for (const [key, value] of Object.entries(temp)) { // loop all found dependenies and dig deeper value.forEach((item,i) => { @@ -1270,7 +1270,7 @@ // console.log("item = " + value) // console.log(typeof value) // console.log(testRegex) - value = value?.replace(/\n+/g, ' ') // put everything in 1 line. + value = value?.replace(/\n+/g, '') // put everything in 1 line. matches=[...value.matchAll(testRegex)] // force match array for(match of matches){ // console.log("-> match : " + match[0] + "->" + match[1]) @@ -1843,7 +1843,7 @@ // else just use the formdata }else{ // deep clone, otherwise weird effects - outputValue = JSON.parse(JSON.stringify(this.form[item.name])) + outputValue = Helpers.deepClone(this.form[item.name]) } // if no model is given, we assign to the root if(!outputObject){ // do we need to flatten output ? @@ -1851,7 +1851,7 @@ } if(fieldmodel.length==0){ // deep clone = otherwise weird effects - formdata[item.name]=JSON.parse(JSON.stringify(outputValue)) + formdata[item.name]=Helpers.deepClone(outputValue) }else{ fieldmodel.forEach((f)=>{ // convert fieldmodel for actual object From 4b4273e30a49f28c960bf301b7a89696dc11db72 Mon Sep 17 00:00:00 2001 From: Mirko Van Colen Date: Wed, 22 Nov 2023 09:52:21 +0100 Subject: [PATCH 3/5] bump changelog --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc943d71..79166761 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- undefined error with json + +### Added + +- Added AzureAD group filter to limit the number of groups + ## [4.0.18] - 2023-11-10 ### Fixed From 212dc406633c8d1558046188c60ffd254d6d0b06 Mon Sep 17 00:00:00 2001 From: Mirko Van Colen Date: Wed, 22 Nov 2023 09:52:42 +0100 Subject: [PATCH 4/5] add azuread groupfilter --- client/src/lib/Helpers.js | 15 ++++++++++++++- client/src/views/AzureAd.vue | 4 +++- client/src/views/Login.vue | 15 +++++++++++++++ server/schema/forms_schema.json | 2 ++ server/src/controllers/login.controller.js | 1 + server/src/db/create_azuread_table.sql | 5 +++-- server/src/models/azureAd.model.js | 3 ++- server/src/models/schema.model.js | 1 + 8 files changed, 41 insertions(+), 5 deletions(-) diff --git a/client/src/lib/Helpers.js b/client/src/lib/Helpers.js index 0ab90d17..1ae942c4 100644 --- a/client/src/lib/Helpers.js +++ b/client/src/lib/Helpers.js @@ -28,6 +28,18 @@ var Helpers = { var i = size == 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024)); return (size / Math.pow(1024, i)).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i]; }, + deepClone(o){ + if(o===undefined){ + return o + } + try{ + return (JSON.parse(JSON.stringify(o))) + }catch(e){ + console.error("Failed deepcloning - ",e) + return undefined + } + + }, evalSandbox(expression){ // local autonumbering function fnGetNumberedName(names,pattern,value,fillgap=false){ @@ -177,7 +189,8 @@ var Helpers = { return o }) } - } + } + if(expression) return eval(expression) } diff --git a/client/src/views/AzureAd.vue b/client/src/views/AzureAd.vue index 169d5ac2..eeca2294 100644 --- a/client/src/views/AzureAd.vue +++ b/client/src/views/AzureAd.vue @@ -19,6 +19,7 @@
+
Required API Permissions
    @@ -67,7 +68,8 @@ azuread:{ client_id:"", secret_id:"", - enable:true + enable:true, + groupfilter:"" }, settings:{ url:"" diff --git a/client/src/views/Login.vue b/client/src/views/Login.vue index f02cbf84..6b795b6e 100644 --- a/client/src/views/Login.vue +++ b/client/src/views/Login.vue @@ -46,6 +46,7 @@ password: "" }, azureAdEnabled:false, + azureGroupfilter:"", azureGraphUrl:"https://graph.microsoft.com" } }, @@ -56,6 +57,7 @@ .then((result)=>{ if(result.data?.status=='success'){ this.azureAdEnabled=!!result.data.data.output.azureAdEnabled + this.azureGroupfilter=result.data.data.output.azureGroupfilter this.azureGraphUrl=result.data.data.output.azureGraphUrl if(azuretoken){ this.getGroupsAndLogin(azuretoken) @@ -69,6 +71,7 @@ }) }, getGroupsAndLogin(azuretoken, url = `${this.azureGraphUrl}/v1.0/me/transitiveMemberOf`, allGroups = []) { + var ref=this const config = { headers: { Authorization: `Bearer ${azuretoken}` @@ -84,6 +87,18 @@ // If there's a nextLink, make a recursive call to get the next page of data this.getGroupsAndLogin(azuretoken, res.data['@odata.nextLink'], allGroups); } else { + var validRegex=true + var regex + try{ + regex = new RegExp(ref.azureGroupfilter, 'g'); + }catch(e){ + console.error("MS Entra ID Group filter is not a valid regular expression") + validRegex=false + } + if(validRegex && ref.azureGroupfilter){ + allGroups = allGroups.filter(x => x.match(regex)) + console.log("Groups have been filtered") + } // No more nextLink, you have all the groups axios.post('/api/v1/auth/azureadoauth2/login', { azuretoken, groups:allGroups }) .then((result) => { diff --git a/server/schema/forms_schema.json b/server/schema/forms_schema.json index d081f540..27551412 100644 --- a/server/schema/forms_schema.json +++ b/server/schema/forms_schema.json @@ -452,6 +452,7 @@ "recipients" ] }, + "hasApproval":{ "type": "boolean"}, "approval": { "$id": "/approval", "type": "object", @@ -487,6 +488,7 @@ "type": "string", "enum": ["ansible", "awx", "git","multistep"] }, + "hasApproval":{ "type": "boolean"}, "approval":{ "$ref": "/approval" }, diff --git a/server/src/controllers/login.controller.js b/server/src/controllers/login.controller.js index d4e5fa8d..8db02247 100644 --- a/server/src/controllers/login.controller.js +++ b/server/src/controllers/login.controller.js @@ -39,6 +39,7 @@ exports.settings = async function(req,res){ var settings={} // console.log(inspect(azure)) settings.azureAdEnabled=azure.enable + settings.azureGroupfilter=azure.groupfilter settings.azureGraphUrl=authConfig.azureGraphUrl res.json(new RestResult("success","",settings,"")) }) diff --git a/server/src/db/create_azuread_table.sql b/server/src/db/create_azuread_table.sql index b8dab25e..99787607 100644 --- a/server/src/db/create_azuread_table.sql +++ b/server/src/db/create_azuread_table.sql @@ -3,6 +3,7 @@ DROP TABLE IF EXISTS `azuread`; CREATE TABLE `azuread` ( `client_id` text DEFAULT NULL, `secret_id` text DEFAULT NULL, - `enable` tinyint(4) DEFAULT NULL + `enable` tinyint(4) DEFAULT NULL, + `groupfilter` varchar(250) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -INSERT INTO AnsibleForms.azuread(client_id,secret_id,enable) VALUES('','',0); +INSERT INTO AnsibleForms.azuread(client_id,secret_id,enable,groupfilter) VALUES('','',0,''); diff --git a/server/src/models/azureAd.model.js b/server/src/models/azureAd.model.js index a3d3bb12..c80e9800 100644 --- a/server/src/models/azureAd.model.js +++ b/server/src/models/azureAd.model.js @@ -10,13 +10,14 @@ var AzureAd=function(azuread){ this.client_id = azuread.client_id; this.secret_id = encrypt(azuread.secret_id); this.enable = (azuread.enable)?1:0; + this.groupfilter = azuread.groupfilter; }; AzureAd.update = function (record) { logger.info(`Updating azuread`) return mysql.do("UPDATE AnsibleForms.`azuread` set ?", record) }; AzureAd.isEnabled = function(){ - return mysql.do("SELECT enable FROM AnsibleForms.`azuread` limit 1;") + return mysql.do("SELECT enable,groupfilter FROM AnsibleForms.`azuread` limit 1;") .then((res)=>{ if(res.length>0){ return res[0] diff --git a/server/src/models/schema.model.js b/server/src/models/schema.model.js index 2a81e9ed..c2d81455 100644 --- a/server/src/models/schema.model.js +++ b/server/src/models/schema.model.js @@ -273,6 +273,7 @@ function patchAll(){ buffer = fs.readFileSync(`${__dirname}/../db/create_azuread_table.sql`) sql = buffer.toString() tablePromises.push(addTable("azuread",sql)) // add azuread table + tablePromises.push(addColumn("azuread","groupfilter","varchar(250)",true,"NULL")) // add column to limit azuread groups //tablePromises.push(addRecord("settings",["mail_server","mail_port","mail_secure","mail_username","mail_password","mail_from","url"],["''",25,0,"''","''","''","''"])) // buffer=fs.readFileSync(`${__dirname}/../db/create_settings_table.sql`) // sql=buffer.toString(); From c49e398b7de1ffef58de8700cc4e29d0a3f31efd Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Wed, 22 Nov 2023 13:49:41 +0000 Subject: [PATCH 5/5] Prepare release 4.0.19 --- CHANGELOG.md | 6 +++++- app_versions.gradle | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79166761..0dbb7f88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [4.0.19] - 2023-11-22 + ### Fixed - undefined error with json @@ -619,7 +621,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Allow change password for current local user - Start tracking versions -[Unreleased]: https://github.com/ansibleguy76/ansibleforms/compare/4.0.18...HEAD +[Unreleased]: https://github.com/ansibleguy76/ansibleforms/compare/4.0.19...HEAD + +[4.0.19]: https://github.com/ansibleguy76/ansibleforms/compare/4.0.18...4.0.19 [4.0.18]: https://github.com/ansibleguy76/ansibleforms/compare/4.0.17...4.0.18 diff --git a/app_versions.gradle b/app_versions.gradle index df57aeeb..1d069c96 100644 --- a/app_versions.gradle +++ b/app_versions.gradle @@ -1,2 +1,2 @@ -ext.version_code = 40018 -ext.version_name = "4.0.18" +ext.version_code = 40019 +ext.version_name = "4.0.19"