Skip to content

Commit

Permalink
Merge pull request #109 from ansibleguy76/release/v4.0.17
Browse files Browse the repository at this point in the history
v4.0.17 into main
  • Loading branch information
ansibleguy76 authored Nov 7, 2023
2 parents 7ca4237 + 5a7c0b3 commit 1ea20d0
Show file tree
Hide file tree
Showing 23 changed files with 446 additions and 88 deletions.
18 changes: 17 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [4.0.17] - 2023-11-07

### Fixed

- AzureAD only returned first 100 groups.
- Constants with arrays now work correctly
- Little ldap test bug
- model bug, bad merging and weird caching

### Added

- Expression field can now have property `value` for manual data assignment
- Added form property ansibleCredentials, allowing to pass ansible_user and ansible_password

## [4.0.16] - 2023-10-07

### Changed
Expand Down Expand Up @@ -590,7 +604,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.16...HEAD
[Unreleased]: https://github.com/ansibleguy76/ansibleforms/compare/4.0.17...HEAD

[4.0.17]: https://github.com/ansibleguy76/ansibleforms/compare/4.0.16...4.0.17

[4.0.16]: https://github.com/ansibleguy76/ansibleforms/compare/4.0.15...4.0.16

Expand Down
4 changes: 2 additions & 2 deletions app_versions.gradle
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
ext.version_code = 40016
ext.version_name = "4.0.16"
ext.version_code = 40017
ext.version_name = "4.0.17"
16 changes: 8 additions & 8 deletions client/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ansible_forms_vue",
"version": "4.0.16",
"version": "4.0.17",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
Expand All @@ -12,9 +12,9 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "~3.33.0",
"vue": "~2.7",
"axios": "~1.5.1",
"core-js": "~3.33.2",
"vue": "~2.7.15",
"axios": "~1.6.0",
"es6-promise": "~4.2.8",
"vuelidate": "~0.7.7",
"vue-router": "~3.5.4",
Expand All @@ -37,10 +37,10 @@
"thenby": "*",
"vue-showdown": "2.4.1",
"bulma-calendar": "6.1.19",
"@fortawesome/fontawesome-svg-core":"~6.2.1",
"@fortawesome/free-solid-svg-icons":"~6.2.1",
"@fortawesome/free-regular-svg-icons":"~6.2.1",
"@fortawesome/free-brands-svg-icons":"~6.2.1",
"@fortawesome/fontawesome-svg-core":"~6.4.2",
"@fortawesome/free-solid-svg-icons":"~6.4.2",
"@fortawesome/free-regular-svg-icons":"~6.4.2",
"@fortawesome/free-brands-svg-icons":"~6.4.2",
"@fortawesome/vue-fontawesome":"2.0.10",
"@femessage/log-viewer":"*"

Expand Down
2 changes: 1 addition & 1 deletion client/public/assets/css/swagger.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.topbar-wrapper img[alt="Swagger UI"] {
.topbar-wrapper>a.link {
content: url('/assets/img/logo_ansible_forms_full_white.svg');
}

Expand Down
2 changes: 1 addition & 1 deletion client/src/components/BulmaSettingsMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
{group:"authentication",title:"Groups",to:"/groups"},
{group:"authentication",title:"Users",to:"/users"},
{group:"authentication",title:"Ldap",to:"/ldap"},
{group:"authentication",title:"Azure AD",to:"/azuread"},
{group:"authentication",title:"MS Entra ID",to:"/azuread"},
{group:"connection",title:"Credentials",to:"/credentials"},
{group:"connection",title:"Ssh",to:"/sshkey"},
{group:"connection",title:"Known Hosts",to:"/knownhosts"},
Expand Down
45 changes: 30 additions & 15 deletions client/src/components/Form.vue
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@
import Helpers from './../lib/Helpers'
import Copy from 'copy-to-clipboard'
import 'vue-json-pretty/lib/styles.css';
import Lodash from 'lodash'
import VueShowdown from 'vue-showdown';
import { required, minValue,maxValue,minLength,maxLength,helpers,requiredIf,sameAs } from 'vuelidate/lib/validators'
Expand Down Expand Up @@ -1288,14 +1289,13 @@
foundfield=foundfield.replace(/\[[0-9]*\]/,'') // make xxx[y] => xxx
fieldvalue = undefined
targetflag = undefined
// console.log(foundfield + "("+fieldvalue+")" + " -> targetflag = " + targetflag)
// mark the field as a dependent field
if(foundfield in ref.form){ // does field xxx exist in our form ?
// if the field exists
// and it's from an expression or table
// or it's deep link in a column (colum has .)
// and the reference field is an object
if(ref.fieldOptions[foundfield] && (["expression","table"].includes(ref.fieldOptions[foundfield].type)||column.includes(".")) && (typeof ref.form[foundfield]=="object")){
if(ref.fieldOptions[foundfield] && (["expression","table","constant"].includes(ref.fieldOptions[foundfield].type)||column.includes(".")) && ((typeof ref.form[foundfield]=="object") || (Array.isArray(ref.form[foundfield])))){
// objects and array should be stringified
fieldvalue=JSON.stringify(ref.form[foundfield])
// console.log(Helpers.replacePlaceholders(match[1],ref.form))
Expand Down Expand Up @@ -1345,10 +1345,10 @@
value=undefined // cannot evaluate yet
}
if(value!=undefined){
value=value.replace("'__undefined__'","undefined") // replace undefined values
value=value.replace("__undefined__","undefined")
value=value.replace("'__null__'","null") // replace undefined values
value=value.replace("__null__","null")
value=value.replaceAll("'__undefined__'","undefined") // replace undefined values
value=value.replaceAll("__undefined__","undefined")
value=value.replaceAll("'__null__'","null") // replace undefined values
value=value.replaceAll("__null__","null")
}
return {"hasPlaceholders":hasPlaceholders,"value":value} // return the result
},
Expand Down Expand Up @@ -1582,6 +1582,10 @@
ref.$toast("Cannot reset field status " + item.name)
}
}
} else if(item.value && flag==undefined){
ref.setFieldStatus(item.name,"running",false)
if(item.type=="expression") Vue.set(ref.form, item.name, item.value);
ref.setFieldStatus(item.name,"fixed")
}
}else{ // not visible field
if(item.type=="expression"){
Expand Down Expand Up @@ -1826,36 +1830,44 @@
// generate the form json output
generateJsonOutput(filedata={}){
var ref=this
this.formdata={}
var formdata={}
this.currentForm.fields.forEach((item, i) => {
// this.checkDependencies(item) // hide field based on dependency
if(this.visibility[item.name] && !item.noOutput){
var fieldmodel = [].concat(item.model || [])
var outputObject = item.outputObject || item.type=="expression" || item.type=="file" || item.type=="table" || false
var outputValue
var outputValue = undefined
// if uploaded file info, use that
if(item.name in filedata){
outputValue=filedata[item.name]
// else just use the formdata
}else{
outputValue = this.form[item.name]
// deep clone, otherwise weird effects
outputValue = JSON.parse(JSON.stringify(this.form[item.name]))
}
// if no model is given, we assign to the root
if(!outputObject){ // do we need to flatten output ?
outputValue=this.getFieldValue(outputValue,item.valueColumn || "",true)
}
if(fieldmodel.length==0){
this.formdata[item.name]=outputValue
// deep clone = otherwise weird effects
formdata[item.name]=JSON.parse(JSON.stringify(outputValue))
}else{
fieldmodel.forEach((f)=>{
// convert fieldmodel for actual object
// svm.lif.name => svm["lif"].name = formvalue
// using reduce, which is a recursive function
f.split(/\s*\.\s*/).reduce((master,obj, level,arr) => {
// if last
if (level === (arr.length - 1)){
// the last piece we assign the value to
master[obj]=outputValue
if(master[obj]===undefined){
master[obj]=outputValue
}else{
master[obj]=Lodash.merge(master[obj],outputValue)
}
}else{
// initialize first time to object
if(master[obj]===undefined){
Expand All @@ -1865,13 +1877,14 @@
// return the result for next reduce iteration
return master[obj]
},ref.formdata);
},formdata);
})
}
}
});
// update main data
Vue.set(this,"formdata",formdata)
},
// validate form before submit
validateForm(){
Expand Down Expand Up @@ -1977,7 +1990,6 @@
.forEach(f => {
postdata.credentials[f.name]=this.formdata[f.name]
})
this.jobResult.message= "Connecting with job api ";
this.jobResult.status="info";
Expand Down Expand Up @@ -2106,7 +2118,7 @@
Vue.set(ref.fieldOptions,item.name,{}) // storing some easy to find options
Vue.set(ref.fieldOptions[item.name],"evalDefault",item.evalDefault??false)
if(["expression","query","enum","table","html"].includes(item.type)){
Vue.set(ref.fieldOptions[item.name],"isDynamic",!!(item.expression??item.query??false))
Vue.set(ref.fieldOptions[item.name],"isDynamic",!!(item.expression??item.query??item.value??false))
Vue.set(ref.fieldOptions[item.name],"valueColumn",item.valueColumn||"")
Vue.set(ref.fieldOptions[item.name],"placeholderColumn",item.placeholderColumn||"")
Vue.set(ref.fieldOptions[item.name],"type",item.type)
Expand All @@ -2133,6 +2145,9 @@
// initiate the constants
if(ref.constants){
Object.keys(ref.constants).forEach((item)=>{
ref.fieldOptions[item]={
type: "constant",
}
Vue.set(ref.form,item,ref.constants[item])
})
}
Expand Down
6 changes: 3 additions & 3 deletions client/src/views/AzureAd.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<section v-if="isAdmin" class="section">
<div class="container">
<h1 class="title has-text-info"><font-awesome-icon icon="address-card" /> Azure AD</h1>
<h1 class="title has-text-info"><font-awesome-icon icon="address-card" /> MS Entra ID</h1>
<div class="columns">
<div class="column is-narrow">
<BulmaSettingsMenu />
Expand All @@ -10,12 +10,12 @@
<nav class="level">
<!-- Left side -->
<div class="level-left">
<p class="level-item"><BulmaButton icon="save" label="Update AzureAd" @click="updateAzureAd()"></BulmaButton></p>
<p class="level-item"><BulmaButton icon="save" label="Update" @click="updateAzureAd()"></BulmaButton></p>
</div>
</nav>
<div class="columns">
<div class="column">
<BulmaCheckbox checktype="checkbox" v-model="azuread.enable" label="Enable Azure AD" />
<BulmaCheckbox checktype="checkbox" v-model="azuread.enable" label="Enable MS Entra ID" />
<div class="mt-2">
<BulmaInput :disabled="!azuread.enable" icon="user-tag" v-model="azuread.client_id" label="Client Id" placeholder="" :required="true" :hasError="$v.azuread.client_id.$invalid" :errors="[]" />
<BulmaInput :disabled="!azuread.enable" icon="user-secret" v-model="azuread.secret_id" type="password" label="Secret Id" placeholder="" :required="true" :hasError="$v.azuread.secret_id.$invalid" :errors="[]" />
Expand Down
56 changes: 32 additions & 24 deletions client/src/views/Login.vue
Original file line number Diff line number Diff line change
Expand Up @@ -68,34 +68,42 @@
this.$toast.error("Failed to get settings")
})
},
getGroupsAndLogin(azuretoken){
getGroupsAndLogin(azuretoken, url = `${this.azureGraphUrl}/v1.0/me/transitiveMemberOf`, allGroups = []) {
const config = {
headers: {
Authorization: `Bearer ${azuretoken}`
}
headers: {
Authorization: `Bearer ${azuretoken}`
}
};
axios.get(`${this.azureGraphUrl}/v1.0/me/transitiveMemberOf`,config)
.then((res) => {
const groups = res.data.value.map(x=>('azuread/'+x.displayName))
axios.post('/api/v1/auth/azureadoauth2/login',{azuretoken,groups})
.then((result)=>{
if(result.data.token){
TokenStorage.storeToken(result.data.token)
TokenStorage.storeRefreshToken(result.data.refreshtoken)
this.$emit("authenticated", result.data.token);
}else{
this.$toast.error("Azure AD Login failed, no token found")
axios.get(url, config)
.then((res) => {
const groups = res.data.value.filter(x => x.displayName).map(x => ('azuread/' + x.displayName));
allGroups = allGroups.concat(groups);
if (res.data['@odata.nextLink']) {
// 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 {
// No more nextLink, you have all the groups
axios.post('/api/v1/auth/azureadoauth2/login', { azuretoken, groups:allGroups })
.then((result) => {
if (result.data.token) {
TokenStorage.storeToken(result.data.token);
TokenStorage.storeRefreshToken(result.data.refreshtoken);
this.$emit("authenticated", result.data.token);
} else {
this.$toast.error("Azure AD Login failed, no token found");
}
})
.catch((err) => {
console.log(err);
this.$toast.error("Azure AD Login failed");
});
}
})
.catch((err)=>{
console.log(err)
this.$toast.error("Azure AD Login failed")
})
})
.catch((err)=>{
this.$toast.error("Failed to get groupmembership")
})
.catch((err) => {
this.$toast.error("Failed to get group membership");
});
},
login() {
Expand Down
Loading

0 comments on commit 1ea20d0

Please sign in to comment.