diff --git a/app/assets/app/resource/iam/Policy.resource.js b/app/assets/app/resource/iam/Policy.resource.js index d2c777d..07241bf 100644 --- a/app/assets/app/resource/iam/Policy.resource.js +++ b/app/assets/app/resource/iam/Policy.resource.js @@ -122,6 +122,8 @@ class PolicyResource extends CRUDBase { options: [ {display: 'Application', value: 'application'}, {display: 'API Scope', value: 'api_scope'}, + {display: 'Computer', value: 'machine'}, + {display: 'Computer Group', value: 'machine_group'}, ], }, { @@ -148,6 +150,30 @@ class PolicyResource extends CRUDBase { }, if: (form_data) => form_data.target_type === 'api_scope' }, + { + name: 'Target', + field: 'target_id', + required: true, + type: 'select.dynamic', + options: { + resource: 'ldap/Machine', + display: machine => `${machine.name}${machine.host_name ? ' (' + machine.host_name + ')' : ''}`, + value: 'id', + }, + if: (form_data) => form_data.target_type === 'machine' + }, + { + name: 'Target', + field: 'target_id', + required: true, + type: 'select.dynamic', + options: { + resource: 'ldap/MachineGroup', + display: group => `${group.name} (${(group.machine_ids || []).length} computers)`, + value: 'id', + }, + if: (form_data) => form_data.target_type === 'machine_group' + }, ], /*handlers: { insert: { diff --git a/app/controllers/api/v1/IAM.controller.js b/app/controllers/api/v1/IAM.controller.js index ced6e9b..30511d6 100644 --- a/app/controllers/api/v1/IAM.controller.js +++ b/app/controllers/api/v1/IAM.controller.js @@ -111,9 +111,9 @@ class IAMController extends Controller { .message(`${req.T('common.invalid')} access_type. ${req.T('api:must_one')} allow, deny.`) .api() - if ( !['application', 'api_scope'].includes(req.body.target_type) ) + if ( !['application', 'api_scope', 'machine', 'machine_group'].includes(req.body.target_type) ) return res.status(400) - .message(`${req.T('common.invalid')} target_type. ${req.T('api:must_one')} application, api_scope.`) + .message(`${req.T('common.invalid')} target_type. ${req.T('api:must_one')} application, api_scope, machine, machine_group.`) .api() // Make sure the target_id is valid @@ -130,6 +130,20 @@ class IAMController extends Controller { return res.status(400) .message(`${req.T('common.invalid')} target_id.`) .api() + } else if ( req.body.target_type === 'machine' ) { + const Machine = this.models.get('ldap:Machine') + const machine = await Machine.findById(req.body.target_id) + if ( !machine || !machine.active || !req.user.can(`ldap:machine:${machine.id}:view`) ) + return res.status(400) + .message(`${req.T('common.invalid')} target_id.`) + .api() + } else if ( req.body.target_type === 'machine_group' ) { + const MachineGroup = this.models.get('ldap:MachineGroup') + const group = await MachineGroup.findById(req.body.target_id) + if ( !group || !group.active || !req.user.can(`ldap:machine_group:${group.id}:view`) ) + return res.status(400) + .message(`${req.T('common.invalid')} target_id.`) + .api() } const policy = new Policy({ @@ -195,9 +209,9 @@ class IAMController extends Controller { .message(`${req.T('common.invalid')} access_type. ${req.T('api.must_one')} allow, deny.`) .api() - if ( !['application', 'api_scope'].includes(req.body.target_type) ) + if ( !['application', 'api_scope', 'machine', 'machine_group'].includes(req.body.target_type) ) return res.status(400) - .message(`${req.T('common.invalid')} target_type. ${req.T('api.must_one')} application, api_scope.`) + .message(`${req.T('common.invalid')} target_type. ${req.T('api.must_one')} application, api_scope, machine, machine_group.`) .api() // Make sure the target_id is valid @@ -214,6 +228,20 @@ class IAMController extends Controller { return res.status(400) .message(`${req.T('common.invalid')} target_id.`) .api() + } else if ( req.body.target_type === 'machine' ) { + const Machine = this.models.get('ldap:Machine') + const machine = await Machine.findById(req.body.target_id) + if ( !machine || !machine.active || !req.user.can(`ldap:machine:${machine.id}:view`) ) + return res.status(400) + .message(`${req.T('common.invalid')} target_id.`) + .api() + } else if ( req.body.target_type === 'machine_group' ) { + const MachineGroup = this.models.get('ldap:MachineGroup') + const group = await MachineGroup.findById(req.body.target_id) + if ( !group || !group.active || !req.user.can(`ldap:machine_group:${group.id}:view`) ) + return res.status(400) + .message(`${req.T('common.invalid')} target_id.`) + .api() } policy.entity_type = req.body.entity_type diff --git a/app/models/iam/Policy.model.js b/app/models/iam/Policy.model.js index dddf70f..ed9dbe2 100644 --- a/app/models/iam/Policy.model.js +++ b/app/models/iam/Policy.model.js @@ -12,7 +12,7 @@ class PolicyModel extends Model { entity_type: String, // user | group entity_id: String, access_type: String, // allow | deny - target_type: { type: String, default: 'application' }, // application | api_scope + target_type: { type: String, default: 'application' }, // application | api_scope | machine | machine_group target_id: String, active: { type: Boolean, default: true }, } @@ -132,6 +132,18 @@ class PolicyModel extends Model { target_display = `Application: ${app.name}` } else if ( this.target_type === 'api_scope' ) { target_display = `API Scope: ${this.target_id}` + } else if ( this.target_type === 'machine' ) { + const Machine = this.models.get('ldap:Machine') + const machine = await Machine.findById(this.target_id) + target_display = `Computer: ${machine.name}` + + if ( machine.host_name ) { + target_display += ` (${machine.host_name})` + } + } else if ( this.target_type === 'machine_group' ) { + const MachineGroup = this.models.get('ldap:MachineGroup') + const group = await MachineGroup.findById(this.target_id) + target_display = `Computer Group: ${group.name} (${group.machine_ids.length} computers)` } return {