diff --git a/nodejs/models/group_ldap.js b/nodejs/models/group_ldap.js index 69c47ee..7231a92 100644 --- a/nodejs/models/group_ldap.js +++ b/nodejs/models/group_ldap.js @@ -7,11 +7,14 @@ const client = new Client({ url: conf.url, }); -async function getGroups(client){ +async function getGroups(client, member){ try{ + + let memberFilter = member ? `(member=${member})`: '' + let groups = (await client.search(conf.groupBase, { scope: 'sub', - filter: '(&(objectClass=groupOfNames))', + filter: `(&(objectClass=groupOfNames)${memberFilter})`, attributes: ['*', 'createTimestamp', 'modifyTimestamp'], })).searchEntries; @@ -81,11 +84,11 @@ async function removeMember(client, group, user){ var Group = {}; -Group.list = async function(){ +Group.list = async function(member){ try{ await client.bind(conf.bindDN, conf.bindPassword); - let groups = await getGroups(client) + let groups = await getGroups(client, member) await client.unbind(); @@ -95,11 +98,11 @@ Group.list = async function(){ } } -Group.listDetail = async function(){ +Group.listDetail = async function(member){ try{ await client.bind(conf.bindDN, conf.bindPassword); - let groups = await getGroups(client) + let groups = await getGroups(client, member) await client.unbind(); @@ -207,7 +210,4 @@ Group.remove = async function(){ } } - - - module.exports = {Group}; diff --git a/nodejs/models/user_ldap.js b/nodejs/models/user_ldap.js index 1d46adc..8a3d166 100644 --- a/nodejs/models/user_ldap.js +++ b/nodejs/models/user_ldap.js @@ -12,75 +12,84 @@ const client = new Client({ }); async function addPosixGroup(client, data){ + try{ - const groups = (await client.search(conf.groupBase, { - scope: 'sub', - filter: '(&(objectClass=posixGroup))', - })).searchEntries; + const groups = (await client.search(conf.groupBase, { + scope: 'sub', + filter: '(&(objectClass=posixGroup))', + })).searchEntries; - data.gidNumber = (Math.max(...groups.map(i => i.gidNumber))+1)+''; + data.gidNumber = (Math.max(...groups.map(i => i.gidNumber))+1)+''; - await client.add(`cn=${data.cn},${conf.groupBase}`, { - cn: data.cn, - gidNumber: data.gidNumber, - objectclass: [ 'posixGroup', 'top' ] - }); + await client.add(`cn=${data.cn},${conf.groupBase}`, { + cn: data.cn, + gidNumber: data.gidNumber, + objectclass: [ 'posixGroup', 'top' ] + }); - return data; + return data; }catch(error){ - throw error; + throw error; } } async function addPosixAccount(client, data){ try{ - const people = (await client.search(conf.userBase, { - scope: 'sub', - filter: conf.userFilter, - })).searchEntries; + const people = (await client.search(conf.userBase, { + scope: 'sub', + filter: conf.userFilter, + })).searchEntries; - data.uidNumber = (Math.max(...people.map(i => i.uidNumber))+1)+''; + data.uidNumber = (Math.max(...people.map(i => i.uidNumber))+1)+''; - await client.add(`cn=${data.cn},${conf.userBase}`, { - cn: data.cn, - sn: data.sn, - uid: data.uid, - uidNumber: data.uidNumber, - gidNumber: data.gidNumber, - givenName: data.givenName, - mail: data.mail, - mobile: data.mobile, - loginShell: data.loginShell, - homeDirectory: data.homeDirectory, - userPassword: data.userPassword, - objectclass: [ 'inetOrgPerson', 'posixAccount', 'top' ] - }); + await client.add(`cn=${data.cn},${conf.userBase}`, { + cn: data.cn, + sn: data.sn, + uid: data.uid, + uidNumber: data.uidNumber, + gidNumber: data.gidNumber, + givenName: data.givenName, + mail: data.mail, + mobile: data.mobile, + loginShell: data.loginShell, + homeDirectory: data.homeDirectory, + userPassword: data.userPassword, + description: data.description || ' ', + sudoHost: 'ALL', + sudoCommand: 'ALL', + sudoUser: data.uid, + sshPublicKey: data.sshPublicKey, + objectclass: ['inetOrgPerson', 'sudoRole', 'ldapPublicKey', 'posixAccount', 'top' ] + }); - return data + return data }catch(error){ - throw error; + throw error; } } async function addLdapUser(client, data){ + var group; + try{ - data.uid = `${data.givenName[0]}${data.sn}`; - data.cn = data.uid; - data.loginShell = '/bin/bash'; - data.homeDirectory= `/home/${data.uid}`; - data.userPassword = '{MD5}'+crypto.createHash('md5').update(data.userPassword, "binary").digest('base64'); + data.uid = `${data.givenName[0]}${data.sn}`; + data.cn = data.uid; + data.loginShell = '/bin/bash'; + data.homeDirectory= `/home/${data.uid}`; + data.userPassword = '{MD5}'+crypto.createHash('md5').update(data.userPassword, "binary").digest('base64'); - data = await addPosixGroup(client, data); - data = await addPosixAccount(client, data); + group = await addPosixGroup(client, data); + data = await addPosixAccount(client, group); - return data; + return data; }catch(error){ - throw error; + await deleteLdapDN(client, `cn=${data.uid},${conf.groupBase}`, true); + throw error; } } @@ -93,9 +102,19 @@ async function deleteLdapUser(client, data){ } } +async function deleteLdapDN(client, dn, ignoreError){ + try{ + client.del(dn) + }catch(error){ + if(!ignoreError) throw error; + console.error('ERROR: deleteLdapDN', error) + } +} + const user_parse = function(data){ if(data[conf.userNameAttribute]){ data.username = data[conf.userNameAttribute] + data.userPassword = undefined; } return data; @@ -152,23 +171,22 @@ User.listDetail = async function(){ } }; -User.get = async function(data, value){ +User.get = async function(data, key){ try{ if(typeof data !== 'object'){ let uid = data; data = {}; data.uid = uid; } - + + await client.bind(conf.bindDN, conf.bindPassword); - data.searchKey = data.searchKey || conf.userNameAttribute; + data.searchKey = data.searchKey || key || conf.userNameAttribute; data.searchValue = data.searchValue || data.uid; let filter = `(&${conf.userFilter}(${data.searchKey}=${data.searchValue}))`; - console.log('get filter', filter) - const res = await client.search(conf.userBase, { scope: 'sub', filter: filter, @@ -196,10 +214,10 @@ User.get = async function(data, value){ } }; -User.exists = async function(data){ +User.exists = async function(data, key){ // Return true or false if the requested entry exists ignoring error's. try{ - await this.get(data); + await this.get(data, key); return true }catch(error){ @@ -241,6 +259,35 @@ User.add = async function(data) { } }; +User.update = async function(data){ + try{ + let editableFeilds = ['mobile', 'sshPublicKey', 'description']; + + await client.bind(conf.bindDN, conf.bindPassword); + + for(let field of editableFeilds){ + if(data[field]){ + await client.modify(this.dn, [ + new Change({ + operation: 'replace', + modification: new Attribute({ + type: field, + values: [data[field]] + }) + }), + ]); + } + } + + await client.unbind() + + return this; + + }catch(error){ + throw error; + } +}; + User.addByInvite = async function(data){ try{ let token = await InviteToken.get(data.token); @@ -270,6 +317,11 @@ User.addByInvite = async function(data){ User.verifyEmail = async function(data){ try{ + + let exists = await this.exists(data.mail, 'mail'); + + if(exists) throw new Error('EmailInUse'); + let token = await InviteToken.get(data.token); await token.update({mail: data.mail}) await Mail.sendTemplate( @@ -294,8 +346,6 @@ User.passwordReset = async function(url, mail){ searchValue: mail }); - console.log('user', user) - let token = await PasswordResetToken.add(user); await Mail.sendTemplate( @@ -338,11 +388,11 @@ User.setPassword = async function(data){ await client.modify(this.dn, [ new Change({ - operation: 'replace', - modification: new Attribute({ - type: 'userPassword', - values: ['{MD5}'+crypto.createHash('md5').update(data.userPassword, "binary").digest('base64')] - })}), + operation: 'replace', + modification: new Attribute({ + type: 'userPassword', + values: ['{MD5}'+crypto.createHash('md5').update(data.userPassword, "binary").digest('base64')] + })}), ]); await client.unbind(); diff --git a/nodejs/public/js/app.js b/nodejs/public/js/app.js index 4d7e0b4..ab0afef 100755 --- a/nodejs/public/js/app.js +++ b/nodejs/public/js/app.js @@ -86,6 +86,7 @@ app.api = (function(app){ })(app) app.auth = (function(app) { + var user = {} function setToken(token){ localStorage.setItem('APIToken', token); } @@ -97,6 +98,7 @@ app.auth = (function(app) { function isLoggedIn(callack){ if(getToken()){ return app.api.get('user/me', function(error, data){ + if(!error) app.auth.user = data; return callack(error, data); }); }else{ @@ -153,6 +155,7 @@ app.user = (function(app){ } function remove(args, callack){ + if(!confirm('Delete '+ args.uid+ 'user?')) return false; app.api.delete('user/'+ args.uid, function(error, data){ callack(error, data); }); @@ -298,8 +301,6 @@ app.util = (function(app){ $.holdReady( true ); if(!location.pathname.includes('/login')){ app.auth.isLoggedIn(function(error, isLoggedIn){ - console.log('here', error, isLoggedIn) - if(error || !isLoggedIn){ app.auth.logOut(function(){}) location.replace('/login/?redirect='+location.pathname); @@ -335,17 +336,17 @@ function formAJAX( btn, del ) { var formData = $form.find( '[name]' ).serializeObject(); // builds query formDataing var method = $form.attr('method') || 'post'; + if( !$form.validate()) { + app.util.actionMessage('Please fix the form errors.', $form, 'danger') + return false; + } + app.util.actionMessage( '