Add ability to manage computers and computer groups from web interface
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
718414d924
commit
d6e4ea2e56
@ -60,6 +60,18 @@ export default class SideBarComponent extends Component {
|
|||||||
type: 'resource',
|
type: 'resource',
|
||||||
resource: 'iam/Policy',
|
resource: 'iam/Policy',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: 'Computers',
|
||||||
|
action: 'list',
|
||||||
|
type: 'resource',
|
||||||
|
resource: 'ldap/Machine',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Computer Groups',
|
||||||
|
action: 'list',
|
||||||
|
type: 'resource',
|
||||||
|
resource: 'ldap/MachineGroup',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
text: 'LDAP Clients',
|
text: 'LDAP Clients',
|
||||||
action: 'list',
|
action: 'list',
|
||||||
|
92
app/assets/app/resource/ldap/Machine.resource.js
Normal file
92
app/assets/app/resource/ldap/Machine.resource.js
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
import CRUDBase from '../CRUDBase.js'
|
||||||
|
|
||||||
|
class MachineResource extends CRUDBase {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
|
||||||
|
this.endpoint = '/api/v1/ldap/machines'
|
||||||
|
this.required_fields = ['name', 'description']
|
||||||
|
this.permission_base = 'v1:ldap:machines'
|
||||||
|
|
||||||
|
this.item = 'Computer'
|
||||||
|
this.plural = 'Computers'
|
||||||
|
|
||||||
|
this.listing_definition = {
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'Machine Name',
|
||||||
|
field: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Host Name',
|
||||||
|
field: 'host_name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Description',
|
||||||
|
field: 'description',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
type: 'resource',
|
||||||
|
position: 'main',
|
||||||
|
action: 'insert',
|
||||||
|
text: 'Create New',
|
||||||
|
color: 'success',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'resource',
|
||||||
|
position: 'row',
|
||||||
|
action: 'update',
|
||||||
|
icon: 'fa fa-edit',
|
||||||
|
color: 'primary',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'resource',
|
||||||
|
position: 'row',
|
||||||
|
action: 'delete',
|
||||||
|
icon: 'fa fa-times',
|
||||||
|
color: 'danger',
|
||||||
|
confirm: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
this.form_definition = {
|
||||||
|
// back_action: {
|
||||||
|
// text: 'Back',
|
||||||
|
// action: 'back',
|
||||||
|
// },
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'Machine Name',
|
||||||
|
field: 'name',
|
||||||
|
placeholder: 'DNS01',
|
||||||
|
required: true,
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Description',
|
||||||
|
field: 'description',
|
||||||
|
required: true,
|
||||||
|
type: 'textarea',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Location',
|
||||||
|
field: 'location',
|
||||||
|
type: 'text',
|
||||||
|
placeholder: 'Server room 1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Host Name (FQDN)',
|
||||||
|
field: 'host_name',
|
||||||
|
type: 'text',
|
||||||
|
placeholder: 'dns01.my.domain',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ldap_machine = new MachineResource()
|
||||||
|
export { ldap_machine }
|
90
app/assets/app/resource/ldap/MachineGroup.resource.js
Normal file
90
app/assets/app/resource/ldap/MachineGroup.resource.js
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import CRUDBase from '../CRUDBase.js'
|
||||||
|
|
||||||
|
class MachineGroupResource extends CRUDBase {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
|
||||||
|
this.endpoint = '/api/v1/ldap/machine-groups'
|
||||||
|
this.required_fields = ['name']
|
||||||
|
this.permission_base = 'v1:ldap:machine_groups'
|
||||||
|
|
||||||
|
this.item = 'Computer Group'
|
||||||
|
this.plural = 'Computer Groups'
|
||||||
|
|
||||||
|
this.listing_definition = {
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'Group Name',
|
||||||
|
field: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '# Computers',
|
||||||
|
field: 'machine_ids',
|
||||||
|
renderer: machine_ids => Array.isArray(machine_ids) ? machine_ids.length : 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Description',
|
||||||
|
field: 'description',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
type: 'resource',
|
||||||
|
position: 'main',
|
||||||
|
action: 'insert',
|
||||||
|
text: 'Create New',
|
||||||
|
color: 'success',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'resource',
|
||||||
|
position: 'row',
|
||||||
|
action: 'update',
|
||||||
|
icon: 'fa fa-edit',
|
||||||
|
color: 'primary',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'resource',
|
||||||
|
position: 'row',
|
||||||
|
action: 'delete',
|
||||||
|
icon: 'fa fa-times',
|
||||||
|
color: 'danger',
|
||||||
|
confirm: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
this.form_definition = {
|
||||||
|
// back_action: {
|
||||||
|
// text: 'Back',
|
||||||
|
// action: 'back',
|
||||||
|
// },
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'Group Name',
|
||||||
|
field: 'name',
|
||||||
|
placeholder: 'DNS Servers',
|
||||||
|
required: true,
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Description',
|
||||||
|
field: 'description',
|
||||||
|
type: 'textarea',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Computers',
|
||||||
|
field: 'machine_ids',
|
||||||
|
type: 'select.dynamic.multiple',
|
||||||
|
options: {
|
||||||
|
resource: 'ldap/Machine',
|
||||||
|
display: machine => `${machine.name}${machine.host_name ? ' (' + machine.host_name + ')' : ''}`,
|
||||||
|
value: 'id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ldap_machinegroup = new MachineGroupResource()
|
||||||
|
export { ldap_machinegroup }
|
@ -46,6 +46,32 @@ class LDAPController extends Controller {
|
|||||||
return res.api(data)
|
return res.api(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async get_machines(req, res, next) {
|
||||||
|
const Machine = this.models.get('ldap:Machine')
|
||||||
|
const machines = await Machine.find({active: true})
|
||||||
|
const data = []
|
||||||
|
|
||||||
|
for ( const machine of machines ) {
|
||||||
|
if ( !req.user.can(`ldap:machine:${machine.id}:view`) ) continue
|
||||||
|
data.push(await machine.to_api())
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.api(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
async get_machine_groups(req, res, next) {
|
||||||
|
const MachineGroup = this.models.get('ldap:MachineGroup')
|
||||||
|
const groups = await MachineGroup.find({active: true})
|
||||||
|
const data = []
|
||||||
|
|
||||||
|
for ( const group of groups ) {
|
||||||
|
if ( !req.user.can(`ldap:machine_group:${group.id}:view`) ) continue
|
||||||
|
data.push(await group.to_api())
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.api(data)
|
||||||
|
}
|
||||||
|
|
||||||
async get_client(req, res, next) {
|
async get_client(req, res, next) {
|
||||||
const Client = this.models.get('ldap:Client')
|
const Client = this.models.get('ldap:Client')
|
||||||
const client = await Client.findById(req.params.id)
|
const client = await Client.findById(req.params.id)
|
||||||
@ -80,6 +106,40 @@ class LDAPController extends Controller {
|
|||||||
return res.api(await group.to_api())
|
return res.api(await group.to_api())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async get_machine(req, res, next) {
|
||||||
|
const Machine = this.models.get('ldap:Machine')
|
||||||
|
const machine = await Machine.findById(req.params.id)
|
||||||
|
|
||||||
|
if ( !machine || !machine.active )
|
||||||
|
return res.status(404)
|
||||||
|
.message(req.T('api.machine_not_found'))
|
||||||
|
.api()
|
||||||
|
|
||||||
|
if ( !req.user.can(`ldap:machine:${machine.id}:view`) )
|
||||||
|
return res.status(401)
|
||||||
|
.message(req.T('api.insufficient_permissions'))
|
||||||
|
.api()
|
||||||
|
|
||||||
|
return res.api(await machine.to_api())
|
||||||
|
}
|
||||||
|
|
||||||
|
async get_machine_group(req, res, next) {
|
||||||
|
const MachineGroup = this.models.get('ldap:MachineGroup')
|
||||||
|
const group = await MachineGroup.findById(req.params.id)
|
||||||
|
|
||||||
|
if ( !group || !group.active )
|
||||||
|
return res.status(404)
|
||||||
|
.message(req.T('api.group_not_found'))
|
||||||
|
.api()
|
||||||
|
|
||||||
|
if ( !req.user.can(`ldap:machine_group:${group.id}:view`) )
|
||||||
|
return res.status(401)
|
||||||
|
.message(req.T('api.insufficient_permissions'))
|
||||||
|
.api()
|
||||||
|
|
||||||
|
return res.api(await group.to_api())
|
||||||
|
}
|
||||||
|
|
||||||
async create_client(req, res, next) {
|
async create_client(req, res, next) {
|
||||||
if ( !req.user.can('ldap:client:create') )
|
if ( !req.user.can('ldap:client:create') )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
@ -121,13 +181,89 @@ class LDAPController extends Controller {
|
|||||||
return res.api(await client.to_api())
|
return res.api(await client.to_api())
|
||||||
}
|
}
|
||||||
|
|
||||||
async create_group(req, res, next) {
|
async create_machine(req, res, next) {
|
||||||
console.log(req.body)
|
// validate inputs
|
||||||
if ( !req.user.can(`ldap:group:create`) )
|
const required_fields = ['name', 'description']
|
||||||
return res.status(401)
|
for ( const field of required_fields ) {
|
||||||
.message(req.T('api.insufficient_permissions'))
|
if ( !req.body[field] )
|
||||||
|
return res.status(400)
|
||||||
|
.message(`${req.T('api.missing_field')} ${field}`)
|
||||||
|
.api()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the machine name is free
|
||||||
|
const Machine = this.models.get('ldap:Machine')
|
||||||
|
const existing_machine = await Machine.findOne({ name: req.body.name })
|
||||||
|
if ( existing_machine )
|
||||||
|
return res.status(400)
|
||||||
|
.message(req.T('api.machine_already_exists'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
|
const machine = new Machine({
|
||||||
|
name: req.body.name,
|
||||||
|
description: req.body.description,
|
||||||
|
host_name: req.body.host_name,
|
||||||
|
location: req.body.location,
|
||||||
|
})
|
||||||
|
|
||||||
|
if ( req.body.bind_password ) {
|
||||||
|
await machine.set_bind_password(req.body.bind_password)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( 'ldap_visible' in req.body ) {
|
||||||
|
machine.ldap_visible = !!req.body.ldap_visible
|
||||||
|
}
|
||||||
|
|
||||||
|
await machine.save()
|
||||||
|
return res.api(await machine.to_api())
|
||||||
|
}
|
||||||
|
|
||||||
|
async create_machine_group(req, res, next) {
|
||||||
|
// validate inputs
|
||||||
|
const required_fields = ['name']
|
||||||
|
for ( const field of required_fields ) {
|
||||||
|
if ( !req.body[field] )
|
||||||
|
return res.status(400)
|
||||||
|
.message(`${req.T('api.missing_field')} ${field}`)
|
||||||
|
.api()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the machine name is free
|
||||||
|
const MachineGroup = this.models.get('ldap:MachineGroup')
|
||||||
|
const existing_group = await MachineGroup.findOne({ name: req.body.name })
|
||||||
|
if ( existing_group )
|
||||||
|
return res.status(400)
|
||||||
|
.message(req.T('api.group_already_exists'))
|
||||||
|
.api()
|
||||||
|
|
||||||
|
const group = new MachineGroup({
|
||||||
|
name: req.body.name,
|
||||||
|
description: req.body.description,
|
||||||
|
})
|
||||||
|
|
||||||
|
if ( 'ldap_visible' in req.body ) {
|
||||||
|
group.ldap_visible = !!req.body.ldap_visible
|
||||||
|
}
|
||||||
|
|
||||||
|
const Machine = this.models.get('ldap:Machine')
|
||||||
|
const machine_ids = Array.isArray(req.body.machine_ids) ? req.body.machine_ids : []
|
||||||
|
group.machine_ids = []
|
||||||
|
for ( const potential of machine_ids ) {
|
||||||
|
const machine = await Machine.findOne({
|
||||||
|
_id: Machine.to_object_id(potential),
|
||||||
|
active: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
if ( machine ) {
|
||||||
|
group.machine_ids.push(potential)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await group.save()
|
||||||
|
return res.api(await group.to_api())
|
||||||
|
}
|
||||||
|
|
||||||
|
async create_group(req, res, next) {
|
||||||
// validate inputs
|
// validate inputs
|
||||||
const required_fields = ['role', 'name']
|
const required_fields = ['role', 'name']
|
||||||
for ( const field of required_fields ) {
|
for ( const field of required_fields ) {
|
||||||
@ -240,6 +376,106 @@ class LDAPController extends Controller {
|
|||||||
return res.api()
|
return res.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async update_machine(req, res, next) {
|
||||||
|
const Machine = this.models.get('ldap:Machine')
|
||||||
|
|
||||||
|
const machine = await Machine.findById(req.params.id)
|
||||||
|
if ( !machine || !machine.active )
|
||||||
|
return res.status(404)
|
||||||
|
.message(req.T('api.machine_not_found'))
|
||||||
|
.api()
|
||||||
|
|
||||||
|
if ( !req.user.can(`ldap:machine:${machine.id}:update`) )
|
||||||
|
return res.status(401)
|
||||||
|
.message(req.T('api.insufficient_permissions'))
|
||||||
|
.api()
|
||||||
|
|
||||||
|
const required_fields = ['name', 'description']
|
||||||
|
for ( const field of required_fields ) {
|
||||||
|
if ( !req.body[field] )
|
||||||
|
return res.status(400)
|
||||||
|
.message(`${req.T('api.missing_field')} ${field}`)
|
||||||
|
.api()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the machine name is free
|
||||||
|
const existing_machine = await Machine.findOne({ name: req.body.name })
|
||||||
|
if ( existing_machine && existing_machine.id !== machine.id )
|
||||||
|
return res.status(400)
|
||||||
|
.message(req.T('api.machine_already_exists'))
|
||||||
|
.api()
|
||||||
|
|
||||||
|
machine.name = req.body.name
|
||||||
|
machine.description = req.body.description
|
||||||
|
machine.host_name = req.body.host_name
|
||||||
|
machine.location = req.body.location
|
||||||
|
|
||||||
|
if ( req.body.bind_password ) {
|
||||||
|
await machine.set_bind_password(req.body.bind_password)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( 'ldap_visible' in req.body ) {
|
||||||
|
machine.ldap_visible = !!req.body.ldap_visible
|
||||||
|
}
|
||||||
|
|
||||||
|
await machine.save()
|
||||||
|
return res.api(await machine.to_api())
|
||||||
|
}
|
||||||
|
|
||||||
|
async update_machine_group(req, res, next) {
|
||||||
|
const MachineGroup = this.models.get('ldap:MachineGroup')
|
||||||
|
|
||||||
|
const group = await MachineGroup.findById(req.params.id)
|
||||||
|
if ( !group || !group.active )
|
||||||
|
return res.status(404)
|
||||||
|
.message(req.T('api.group_not_found'))
|
||||||
|
.api()
|
||||||
|
|
||||||
|
if ( !req.user.can(`ldap:machine_group:${group.id}:update`) )
|
||||||
|
return res.status(401)
|
||||||
|
.message(req.T('api.insufficient_permissions'))
|
||||||
|
.api()
|
||||||
|
|
||||||
|
const required_fields = ['name']
|
||||||
|
for ( const field of required_fields ) {
|
||||||
|
if ( !req.body[field] )
|
||||||
|
return res.status(400)
|
||||||
|
.message(`${req.T('api.missing_field')} ${field}`)
|
||||||
|
.api()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the machine name is free
|
||||||
|
const existing_group = await MachineGroup.findOne({ name: req.body.name })
|
||||||
|
if ( existing_group && existing_group.id !== group.id )
|
||||||
|
return res.status(400)
|
||||||
|
.message(req.T('api.group_already_exists'))
|
||||||
|
.api()
|
||||||
|
|
||||||
|
group.name = req.body.name
|
||||||
|
group.description = req.body.description
|
||||||
|
|
||||||
|
if ( 'ldap_visible' in req.body ) {
|
||||||
|
group.ldap_visible = !!req.body.ldap_visible
|
||||||
|
}
|
||||||
|
|
||||||
|
const Machine = this.models.get('ldap:Machine')
|
||||||
|
const machine_ids = Array.isArray(req.body.machine_ids) ? req.body.machine_ids : []
|
||||||
|
group.machine_ids = []
|
||||||
|
for ( const potential of machine_ids ) {
|
||||||
|
const machine = await Machine.findOne({
|
||||||
|
_id: Machine.to_object_id(potential),
|
||||||
|
active: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
if ( machine ) {
|
||||||
|
group.machine_ids.push(potential)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await group.save()
|
||||||
|
return res.api(await group.to_api())
|
||||||
|
}
|
||||||
|
|
||||||
async update_group(req, res, next) {
|
async update_group(req, res, next) {
|
||||||
const User = await this.models.get('auth:User')
|
const User = await this.models.get('auth:User')
|
||||||
const Group = await this.models.get('ldap:Group')
|
const Group = await this.models.get('ldap:Group')
|
||||||
@ -337,6 +573,44 @@ class LDAPController extends Controller {
|
|||||||
await group.save()
|
await group.save()
|
||||||
return res.api()
|
return res.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async delete_machine(req, res, next) {
|
||||||
|
const Machine = this.models.get('ldap:Machine')
|
||||||
|
const machine = await Machine.findById(req.params.id)
|
||||||
|
|
||||||
|
if ( !machine || !machine.active )
|
||||||
|
return res.status(404)
|
||||||
|
.message(req.T('api.machine_not_found'))
|
||||||
|
.api()
|
||||||
|
|
||||||
|
if ( !req.user.can(`ldap:machine:${machine.id}:delete`) )
|
||||||
|
return res.status(401)
|
||||||
|
.message(req.T('api.insufficient_permissions'))
|
||||||
|
.api()
|
||||||
|
|
||||||
|
machine.active = false
|
||||||
|
await machine.save()
|
||||||
|
return res.api()
|
||||||
|
}
|
||||||
|
|
||||||
|
async delete_machine_group(req, res, next) {
|
||||||
|
const MachineGroup = this.models.get('ldap:MachineGroup')
|
||||||
|
const group = await MachineGroup.findById(req.params.id)
|
||||||
|
|
||||||
|
if ( !group || !group.active )
|
||||||
|
return res.status(404)
|
||||||
|
.message(req.T('api.group_not_found'))
|
||||||
|
.api()
|
||||||
|
|
||||||
|
if ( !req.user.can(`ldap:machine_group:${group.id}:delete`) )
|
||||||
|
return res.status(401)
|
||||||
|
.message(req.T('api.insufficient_permissions'))
|
||||||
|
.api()
|
||||||
|
|
||||||
|
group.active = false
|
||||||
|
await group.save()
|
||||||
|
return res.api()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = exports = LDAPController
|
module.exports = exports = LDAPController
|
||||||
|
64
app/models/ldap/Machine.model.js
Normal file
64
app/models/ldap/Machine.model.js
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
const { Model } = require('flitter-orm')
|
||||||
|
const LDAP = require('ldapjs')
|
||||||
|
const bcrypt = require('bcrypt')
|
||||||
|
|
||||||
|
class MachineModel extends Model {
|
||||||
|
static get services() {
|
||||||
|
return [...super.services, 'models', 'ldap_server', 'configs']
|
||||||
|
}
|
||||||
|
|
||||||
|
static get schema() {
|
||||||
|
return {
|
||||||
|
name: String,
|
||||||
|
bind_password: String,
|
||||||
|
description: String,
|
||||||
|
host_name: String,
|
||||||
|
location: String,
|
||||||
|
active: { type: Boolean, default: true },
|
||||||
|
ldap_visible: { type: Boolean, default: true },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async to_api() {
|
||||||
|
return {
|
||||||
|
id: this.id,
|
||||||
|
name: this.name,
|
||||||
|
description: this.description,
|
||||||
|
host_name: this.host_name,
|
||||||
|
location: this.location,
|
||||||
|
ldap_visible: this.ldap_visible,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async set_bind_password(password) {
|
||||||
|
this.bind_password = await bcrypt.hash(password, 10)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
async check_bind_password(password) {
|
||||||
|
return await bcrypt.compare(password, this.bind_password)
|
||||||
|
}
|
||||||
|
|
||||||
|
get dn() {
|
||||||
|
return LDAP.parseDN(`cn=${this.name},${this.ldap_server.machine_dn().format(this.configs.get('ldap:server.format'))}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
async to_ldap() {
|
||||||
|
const data = {
|
||||||
|
cn: this.name,
|
||||||
|
dn: this.dn.format(this.configs.get('ldap:server.format')),
|
||||||
|
name: this.name,
|
||||||
|
id: this.id,
|
||||||
|
objectClass: ['computer'],
|
||||||
|
description: this.description,
|
||||||
|
dNSHostName: this.host_name,
|
||||||
|
location: this.location,
|
||||||
|
primaryGroupID: 515, // compat with AD
|
||||||
|
sAMAccountType: 805306369, // compat with AD
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = exports = MachineModel
|
47
app/models/ldap/MachineGroup.model.js
Normal file
47
app/models/ldap/MachineGroup.model.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
const { Model } = require('flitter-orm')
|
||||||
|
const uuid = require('uuid').v4
|
||||||
|
const LDAP = require('ldapjs')
|
||||||
|
|
||||||
|
class MachineGroupModel extends Model {
|
||||||
|
static get services() {
|
||||||
|
return [...super.services, 'models', 'ldap_server', 'configs']
|
||||||
|
}
|
||||||
|
|
||||||
|
static get schema() {
|
||||||
|
return {
|
||||||
|
name: String,
|
||||||
|
description: String,
|
||||||
|
UUID: { type: String, default: uuid },
|
||||||
|
active: { type: Boolean, default: true },
|
||||||
|
machine_ids: [String],
|
||||||
|
ldap_visible: { type: Boolean, default: true },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async to_api() {
|
||||||
|
return {
|
||||||
|
id: this.id,
|
||||||
|
name: this.name,
|
||||||
|
description: this.description || '',
|
||||||
|
UUID: this.UUID,
|
||||||
|
machine_ids: this.machine_ids,
|
||||||
|
ldap_visible: this.ldap_visible,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get dn() {
|
||||||
|
return LDAP.parseDN(`cn=${this.name},${this.ldap_server.machine_group_dn().format(this.configs.get('ldap:server.format'))}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
async to_ldap() {
|
||||||
|
return {
|
||||||
|
cn: this.name,
|
||||||
|
dn: this.dn.format(this.configs.get('ldap:server.format')),
|
||||||
|
id: this.id,
|
||||||
|
uuid: this.UUID,
|
||||||
|
description: this.description,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = exports = MachineGroupModel
|
@ -22,6 +22,22 @@ const ldap_routes = {
|
|||||||
['middleware::api:Permission', { check: 'v1:ldap:groups:get' }],
|
['middleware::api:Permission', { check: 'v1:ldap:groups:get' }],
|
||||||
'controller::api:v1:LDAP.get_group',
|
'controller::api:v1:LDAP.get_group',
|
||||||
],
|
],
|
||||||
|
'/machines': [
|
||||||
|
['middleware::api:Permission', { check: 'v1:ldap:machines:list' }],
|
||||||
|
'controller::api:v1:LDAP.get_machines',
|
||||||
|
],
|
||||||
|
'/machines/:id': [
|
||||||
|
['middleware::api:Permission', { check: 'v1:ldap:machines:get' }],
|
||||||
|
'controller::api:v1:LDAP.get_machine',
|
||||||
|
],
|
||||||
|
'/machine-groups': [
|
||||||
|
['middleware::api:Permission', { check: 'v1:ldap:machine_groups:list' }],
|
||||||
|
'controller::api:v1:LDAP.get_machine_groups',
|
||||||
|
],
|
||||||
|
'/machine-groups/:id': [
|
||||||
|
['middleware::api:Permission', { check: 'v1:ldap:machine_groups:get' }],
|
||||||
|
'controller::api:v1:LDAP.get_machine_group',
|
||||||
|
],
|
||||||
'/config': [
|
'/config': [
|
||||||
['middleware::api:Permission', { check: 'v1:ldap:config:get' }],
|
['middleware::api:Permission', { check: 'v1:ldap:config:get' }],
|
||||||
'controller::api:v1:LDAP.get_config',
|
'controller::api:v1:LDAP.get_config',
|
||||||
@ -37,6 +53,14 @@ const ldap_routes = {
|
|||||||
['middleware::api:Permission', { check: 'v1:ldap:groups:create' }],
|
['middleware::api:Permission', { check: 'v1:ldap:groups:create' }],
|
||||||
'controller::api:v1:LDAP.create_group',
|
'controller::api:v1:LDAP.create_group',
|
||||||
],
|
],
|
||||||
|
'/machines': [
|
||||||
|
['middleware::api:Permission', { check: 'v1:ldap:machines:create' }],
|
||||||
|
'controller::api:v1:LDAP.create_machine',
|
||||||
|
],
|
||||||
|
'/machine-groups': [
|
||||||
|
['middleware::api:Permission', { check: 'v1:ldap:machine_groups:create' }],
|
||||||
|
'controller::api:v1:LDAP.create_machine_group',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
patch: {
|
patch: {
|
||||||
@ -48,6 +72,14 @@ const ldap_routes = {
|
|||||||
['middleware::api:Permission', { check: 'v1:ldap:groups:update' }],
|
['middleware::api:Permission', { check: 'v1:ldap:groups:update' }],
|
||||||
'controller::api:v1:LDAP.update_group',
|
'controller::api:v1:LDAP.update_group',
|
||||||
],
|
],
|
||||||
|
'/machines/:id': [
|
||||||
|
['middleware::api:Permission', { check: 'v1:ldap:machines:update' }],
|
||||||
|
'controller::api:v1:LDAP.update_machine',
|
||||||
|
],
|
||||||
|
'/machine-groups/:id': [
|
||||||
|
['middleware::api:Permission', { check: 'v1:ldap:machine_groups:update' }],
|
||||||
|
'controller::api:v1:LDAP.update_machine_group',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
delete: {
|
delete: {
|
||||||
@ -59,6 +91,14 @@ const ldap_routes = {
|
|||||||
['middleware::api:Permission', { check: 'v1:ldap:groups:delete' }],
|
['middleware::api:Permission', { check: 'v1:ldap:groups:delete' }],
|
||||||
'controller::api:v1:LDAP.delete_group',
|
'controller::api:v1:LDAP.delete_group',
|
||||||
],
|
],
|
||||||
|
'/machines/:id': [
|
||||||
|
['middleware::api:Permission', { check: 'v1:ldap:machines:delete' }],
|
||||||
|
'controller::api:v1:LDAP.delete_machine',
|
||||||
|
],
|
||||||
|
'/machine-groups/:id': [
|
||||||
|
['middleware::api:Permission', { check: 'v1:ldap:machine_groups:delete' }],
|
||||||
|
'controller::api:v1:LDAP.delete_machine_group',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,14 @@ class LDAPServerUnit extends Unit {
|
|||||||
return this.build_dn(this.config.schema.group_base)
|
return this.build_dn(this.config.schema.group_base)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
machine_dn() {
|
||||||
|
return this.build_dn(this.config.schema.machine_base)
|
||||||
|
}
|
||||||
|
|
||||||
|
machine_group_dn() {
|
||||||
|
return this.build_dn(this.config.schema.machine_group_base)
|
||||||
|
}
|
||||||
|
|
||||||
sudo_dn() {
|
sudo_dn() {
|
||||||
return this.build_dn(this.config.schema.sudo_base)
|
return this.build_dn(this.config.schema.sudo_base)
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,8 @@ const ldap_server = {
|
|||||||
base_dc: env('LDAP_BASE_DC', 'dc=example,dc=com'),
|
base_dc: env('LDAP_BASE_DC', 'dc=example,dc=com'),
|
||||||
authentication_base: env('LDAP_AUTH_BASE', 'ou=people'),
|
authentication_base: env('LDAP_AUTH_BASE', 'ou=people'),
|
||||||
group_base: env('LDAP_GROUP_BASE', 'ou=groups'),
|
group_base: env('LDAP_GROUP_BASE', 'ou=groups'),
|
||||||
|
machine_base: env('LDAP_MACHINE_BASE', 'ou=computers'),
|
||||||
|
machine_group_base: env('LDAP_MACHINE_BASE', 'ou=computer groups'),
|
||||||
sudo_base: env('LDAP_SUDO_BASE', 'ou=sudo'),
|
sudo_base: env('LDAP_SUDO_BASE', 'ou=sudo'),
|
||||||
auth: {
|
auth: {
|
||||||
user_id: 'uid',
|
user_id: 'uid',
|
||||||
|
@ -3,7 +3,9 @@ module.exports = exports = {
|
|||||||
application_already_exists: 'An Application with that identifier already exists.',
|
application_already_exists: 'An Application with that identifier already exists.',
|
||||||
|
|
||||||
group_not_found: 'Group not found with that ID.',
|
group_not_found: 'Group not found with that ID.',
|
||||||
|
machine_not_found: 'Machine not found with that ID.',
|
||||||
group_already_exists: 'A group with that name already exists.',
|
group_already_exists: 'A group with that name already exists.',
|
||||||
|
machine_already_exists: 'A machine with that name already exists.',
|
||||||
|
|
||||||
user_not_found: 'User not found with that ID.',
|
user_not_found: 'User not found with that ID.',
|
||||||
user_already_exists: 'A user with that identifier already exists.',
|
user_already_exists: 'A user with that identifier already exists.',
|
||||||
|
Loading…
Reference in New Issue
Block a user