From 34f87418f367e78137609a024c02fd1df6e168f4 Mon Sep 17 00:00:00 2001 From: Thomas Duval Date: Tue, 7 Nov 2017 11:20:15 +0100 Subject: Add additional files for the GUI component. Change-Id: I3753740b42501fa5f370e57c9e0284230438c13d --- .../assignments/assignments-edit.tpl.html | 165 +++++++ .../parameter/assignments/assignments.edit.dir.js | 439 +++++++++++++++++ .../policy/edit/parameter/data/data-edit.tpl.html | 110 +++++ .../parameter/perimeter/perimeter-edit.tpl.html | 166 +++++++ .../edit/parameter/perimeter/perimeter.edit.dir.js | 437 +++++++++++++++++ .../edit/parameter/rules/rules-edit.tpl.html | 341 +++++++++++++ .../policy/edit/parameter/rules/rules.edit.dir.js | 537 +++++++++++++++++++++ .../moon/policy/parameters/rules.service.js | 56 +++ 8 files changed, 2251 insertions(+) create mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments-edit.tpl.html create mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments.edit.dir.js create mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/data/data-edit.tpl.html create mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-edit.tpl.html create mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.edit.dir.js create mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules-edit.tpl.html create mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules.edit.dir.js create mode 100755 moonv4/moon_gui/static/app/services/moon/policy/parameters/rules.service.js (limited to 'moonv4') diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments-edit.tpl.html b/moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments-edit.tpl.html new file mode 100755 index 00000000..9069dcd0 --- /dev/null +++ b/moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments-edit.tpl.html @@ -0,0 +1,165 @@ +
+ +
+ +
+ + +
+ + + +
+ +
+ +
+ + + + + +
+
+ +
+ +
+ Policy is required +
+ +
+ +
+ + +
+ + + +
+ +
+ +
+ + + + + +
+
+ +
+ +
+ Perimeter is required +
+ +
+ +
+ + +
+ + + +
+ +
+ +
+ + + + + +
+
+ +
+ +
+ Category is required +
+ +
+ +
+ + +
+ + + +
+ +
+ +
+ + + + + +
+
+ +
+ +
+ Data is required +
+ +
+ +
+ +
+ +
+ + +
+ + + +
+ +
    + +
  • + + + +
  • + +
+ +
+ +
+ +
+ +
+ + + + Create + + + + +
+ +
+ + +
+ +
+ +
\ No newline at end of file diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments.edit.dir.js b/moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments.edit.dir.js new file mode 100755 index 00000000..5297eccb --- /dev/null +++ b/moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments.edit.dir.js @@ -0,0 +1,439 @@ +(function () { + + 'use strict'; + + angular + .module('moon') + .directive('moonAssignmentsEdit', moonAssignmentsEdit); + + moonAssignmentsEdit.$inject = []; + + function moonAssignmentsEdit() { + + return { + templateUrl: 'html/policy/edit/parameter/assignments/assignments-edit.tpl.html', + bindToController: true, + controller: moonAssignmentsEditController, + controllerAs: 'edit', + scope: { + //Type can be 'ACTION', 'OBJECT', 'SUBJECT' + assignmentsType: '=', + policy: '=' + }, + restrict: 'E', + replace: true + }; + } + + angular + .module('moon') + .controller('moonAssignmentsEditController', moonAssignmentsEditController); + + moonAssignmentsEditController.$inject = ['$scope', 'assignmentsService', 'alertService', '$translate', 'formService', + 'policyService', 'utilService', 'perimeterService', 'ASSIGNMENTS_CST', + 'metaDataService', 'dataService']; + + function moonAssignmentsEditController($scope, assignmentsService, alertService, $translate, formService, + policyService, utilService, perimeterService, ASSIGNMENTS_CST, + metaDataService, dataService ) { + + var edit = this; + + edit.assignmentsType = $scope.edit.assignmentsType; + edit.policy = $scope.edit.policy; + + edit.laoading = false; + + edit.form = {}; + + edit.policyList = []; + edit.loadingPolicies = true; + + edit.categoryList = []; + edit.loadingCategories = true; + + edit.perimeterList = []; + edit.loadingPerimeters = true; + + edit.dataList = []; + edit.dataToBeSelected = []; + edit.selectedDataList = []; + edit.loadingData = true; + + edit.assignementsAttributeValid = true; + + edit.addSelectedData = addSelectedData; + edit.removeSelectedData = removeSelectedData; + edit.getName = getName; + edit.create = createAssignments; + + activate(); + + /* + * + */ + + function activate() { + + edit.assignments = {id: null, category_id: null, data_id: null, policy_id: null}; + + loadAllPolicies(); + loadAllCategories(); + + } + + function createAssignments() { + + edit.assignementsAttributeValid = true; + + manageSelectedDataListy(); + + if(formService.isInvalid(edit.form)) { + + formService.checkFieldsValidity(edit.form); + + }else if(edit.assignementsAttributeValid){ + + startLoading(); + + var throwEvent = false; + edit.assignments.id = edit.selectedPerimeter.id; + edit.assignments.category_id = edit.selectedCategory.id; + edit.assignments.policy_id = edit.selectedPolicy.id; + + var selectedDataListTemp = angular.copy(edit.selectedDataList); + + _.each(selectedDataListTemp, function(elem){ + + edit.assignments.data_id = elem.id; + + var assignmentsToSend = angular.copy(edit.assignments); + + switch(edit.assignmentsType){ + + case ASSIGNMENTS_CST.TYPE.SUBJECT: + + assignmentsService.subject.add(assignmentsToSend, edit.policy.id, createSuccess, createError); + break; + + case ASSIGNMENTS_CST.TYPE.OBJECT: + + assignmentsService.object.add(assignmentsToSend, edit.policy.id, createSuccess, createError); + break; + + case ASSIGNMENTS_CST.TYPE.ACTION: + + assignmentsService.action.add(assignmentsToSend, edit.policy.id, createSuccess, createError); + break; + + default : + + break; + + } + + }); + + throwEvent = true; + + } + + function createSuccess(data) { + + var created = {}; + + switch(edit.assignmentsType){ + + case ASSIGNMENTS_CST.TYPE.SUBJECT: + + created = utilService.transformOne(data, 'subject_assignments'); + break; + + case ASSIGNMENTS_CST.TYPE.OBJECT: + + created = utilService.transformOne(data, 'object_assignments'); + break; + + case ASSIGNMENTS_CST.TYPE.ACTION: + + created = utilService.transformOne(data, 'action_assignments'); + break; + + default: + + break; + + } + + $translate('moon.policy.assignments.edit.create.success').then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + if(throwEvent && created.policy_id === edit.policy.id){ + + $scope.$emit('event:createAssignmentsFromAssignmentsEditSuccess', edit.assignmentsType); + + activate(); + + stopLoading(); + + }else if(throwEvent){ + + activate(); + + stopLoading(); + + } + + } + + function createError(reason) { + + $translate('moon.policy.rules.edit.action.add.create.error').then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + stopLoading(); + + } + + } + + $scope.$watch('edit.selectedPolicy', function(newValue){ + + if(!_.isUndefined(newValue)){ + + loadRelatedPerimeters(); + + } + + }); + + + $scope.$watch('edit.selectedCategory', function(newValue){ + + clearSelectedCategories(); + + if(!_.isUndefined(newValue)){ + + loadRelatedData(newValue.id); + + } + + }); + + function loadAllPolicies() { + + edit.policyList = []; + edit.loadingPolicies = true; + + policyService.findAllWithCallback( function(data) { + + _.each(data, function(element){ + + if(element.id === edit.policy.id){ + edit.selectedPolicy = element; + } + + }); + + edit.policyList = data; + edit.loadingPolicies = false; + + }); + } + + function loadRelatedPerimeters(){ + + edit.perimeterList = []; + edit.loadingPerimeters = true; + + switch(edit.assignmentsType){ + + case ASSIGNMENTS_CST.TYPE.SUBJECT: + + perimeterService.subject.findAllFromPolicyWithCallback(edit.selectedPolicy.id, callBackList); + break; + + case ASSIGNMENTS_CST.TYPE.OBJECT: + + perimeterService.object.findAllFromPolicyWithCallback(edit.selectedPolicy.id,callBackList); + break; + + case ASSIGNMENTS_CST.TYPE.ACTION: + + perimeterService.action.findAllFromPolicyWithCallback(edit.selectedPolicy.id, callBackList); + break; + + default : + + edit.perimeterList = []; + edit.loadingPerimeters = false; + break; + + } + + function callBackList(list){ + + edit.perimeterList = list; + + edit.loadingPerimeters = false; + + } + } + + function loadAllCategories(){ + + edit.categoryList = []; + edit.loadingCategories = true; + + switch(edit.assignmentsType){ + + case ASSIGNMENTS_CST.TYPE.SUBJECT: + + metaDataService.subject.findAllWithCallback(callBackList); + break; + + case ASSIGNMENTS_CST.TYPE.OBJECT: + + metaDataService.object.findAllWithCallback(callBackList); + break; + + case ASSIGNMENTS_CST.TYPE.ACTION: + + metaDataService.action.findAllWithCallback(callBackList); + break; + + default : + + edit.categoryList = []; + edit.loadingCategories = false; + break; + + } + + function callBackList(list){ + + edit.categoryList = list; + edit.loadingCategories = false; + + } + } + + function loadRelatedData(categoryId){ + + edit.dataList = []; + edit.dataToBeSelected = []; + edit.selectedDataList = []; + edit.loadingData = true; + + switch(edit.assignmentsType){ + + case ASSIGNMENTS_CST.TYPE.SUBJECT: + + dataService.subject.findAllFromCategoriesWithCallback(edit.selectedPolicy.id, categoryId, callBackList); + break; + + case ASSIGNMENTS_CST.TYPE.OBJECT: + + dataService.object.findAllFromCategoriesWithCallback(edit.selectedPolicy.id, categoryId, callBackList); + break; + + case ASSIGNMENTS_CST.TYPE.ACTION: + + dataService.action.findAllFromCategoriesWithCallback(edit.selectedPolicy.id, categoryId, callBackList); + break; + + default : + + edit.loadingData = false; + break; + + } + + function callBackList(list){ + + edit.dataList = list; + edit.dataToBeSelected = angular.copy(edit.dataList); + edit.selectedDataList = []; + edit.loadingData = false; + + } + + } + + function addSelectedData(){ + + edit.dataToBeSelected = _.without(edit.dataToBeSelected, edit.selectedData); + edit.selectedDataList.push(edit.selectedData); + clearSelectedCategories(); + + } + + function removeSelectedData(data){ + + edit.dataToBeSelected.push(data); + edit.selectedDataList = _.without(edit.selectedDataList, data); + + } + + function clearSelectedCategories(){ + + edit.selectedData = undefined; + + } + + function getName(assignment){ + + if(_.isUndefined(assignment)) return '(None)'; + + switch(edit.assignmentsType){ + + case ASSIGNMENTS_CST.TYPE.SUBJECT: + + return assignment.name; + + case ASSIGNMENTS_CST.TYPE.OBJECT: + + return assignment.value.name; + + + case ASSIGNMENTS_CST.TYPE.ACTION: + + return assignment.value.name; + + default : + + return assignment.name; + + } + + } + + function manageSelectedDataListy(){ + + if (edit.selectedDataList.length >= 1 ){ + + edit.assignementsAttributeValid = true; + + }else{ + + edit.assignementsAttributeValid = false; + + } + } + + function startLoading(){ + + edit.loading = true; + + } + + function stopLoading(){ + + edit.loading = false; + + } + } + +})(); \ No newline at end of file diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/data/data-edit.tpl.html b/moonv4/moon_gui/static/app/policy/edit/parameter/data/data-edit.tpl.html new file mode 100755 index 00000000..3f11a641 --- /dev/null +++ b/moonv4/moon_gui/static/app/policy/edit/parameter/data/data-edit.tpl.html @@ -0,0 +1,110 @@ +
+ +
+ +
+ +
+ + + +
+ + + +
+ Name is required + +
+ +
+ +
+ +
+ + +
+ +
+ +
+ +
+ + + +
+ + + + + +
+
+ +
+ +
+ Policy is required + +
+ +
+ +
+ +
+ + + +
+ + + + + +
+
+ +
+ +
+ Category is required + +
+ +
+
+ +
+ +
+ + + + Create + + + + +
+ +
+ +
+ +
+ +
\ No newline at end of file diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-edit.tpl.html b/moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-edit.tpl.html new file mode 100755 index 00000000..fa2f93c0 --- /dev/null +++ b/moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-edit.tpl.html @@ -0,0 +1,166 @@ +
+ + + +
+ +
+ +
+ + + + + +
+
+ +
+ +
+ + + + + +
+ +
+ +
+ + + +
+ + + +
+ Name is required +
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + +
+ + + +
+ +
+ +
+ + +
+ + + +
+ + + + + +
+
+ +
+ +
+ +
+ +
+ +
+ +
+ + + +
+ +
    + +
  • + + + +
  • + +
+ +
+ +
+ +
+ +
+ + + + Create + + + + +
+ +
+ +
+ +
+ +
\ No newline at end of file diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.edit.dir.js b/moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.edit.dir.js new file mode 100755 index 00000000..a96741fe --- /dev/null +++ b/moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.edit.dir.js @@ -0,0 +1,437 @@ +(function () { + + 'use strict'; + + angular + .module('moon') + .directive('moonPerimeterEdit', moonPerimeterEdit); + + moonPerimeterEdit.$inject = []; + + function moonPerimeterEdit() { + + return { + templateUrl: 'html/policy/edit/parameter/perimeter/perimeter-edit.tpl.html', + bindToController: true, + controller: moonPerimeterEditController, + controllerAs: 'edit', + scope: { + //Type can be 'ACTION', 'OBJECT', 'SUBJECT' + perimeterType: '=', + policy: '=' + }, + restrict: 'E', + replace: true + }; + } + + + angular + .module('moon') + .controller('moonPerimeterEditController', moonPerimeterEditController); + + moonPerimeterEditController.$inject = ['$scope', '$rootScope', + 'perimeterService', 'PERIMETER_CST', 'alertService', + '$translate', 'formService', 'policyService', 'utilService']; + + function moonPerimeterEditController($scope, $rootScope, + perimeterService, PERIMETER_CST, alertService, + $translate, formService, policyService, utilService) { + + var edit = this; + + edit.perimeterType = $scope.edit.perimeterType; + // This variable is used in the view in order to display or not display email field + edit.subjectType = PERIMETER_CST.TYPE.SUBJECT; + edit.policy = $scope.edit.policy; + + edit.fromList = true; + + edit.loading = false; + + edit.form = {}; + + edit.perimeter = {name: null, description: null, partner_id: null, policy_list: [], email: null}; + + edit.list = []; + edit.policyList = []; + edit.policiesToBeSelected = []; + edit.selectedPolicyList = []; // List of Policies to be added to a new perimeter + + edit.create = createPerimeter; + edit.addToPolicy = addToPolicy; + edit.addPolicyToPerimeter = addPolicyToPerimeter; + edit.clearSelectedPolicies = clearSelectedPolicies; + edit.removeSelectedPolicy = removeSelectedPolicy; + edit.deletePerimeter = deletePerimeter; + + activate(); + + /* + * + */ + + function activate() { + + loadAllPolicies(); + + switch (edit.perimeterType) { + + case PERIMETER_CST.TYPE.SUBJECT: + + perimeterService.subject.findAllWithCallback(callBackList); + break; + + case PERIMETER_CST.TYPE.OBJECT: + + perimeterService.object.findAllWithCallback(callBackList); + break; + + case PERIMETER_CST.TYPE.ACTION: + + perimeterService.action.findAllWithCallback(callBackList); + break; + + default : + + edit.list = []; + break; + + } + + function callBackList(list) { + + // For each Perimeter, there is a check about the mapping between the perimeter and the policy + _.each(list, function (element) { + + if (_.indexOf(element.policy_list, edit.policy.id) === -1) { + + edit.list.push(element); + + } + + }); + + } + + } + + var rootListeners = { + + 'event:unMapPerimeterFromPerimeterList': $rootScope.$on('event:unMapPerimeterFromPerimeterList', manageUnMappedPerimeter) + + }; + + _.each(rootListeners, function(unbind){ + $scope.$on('$destroy', rootListeners[unbind]); + }); + + + function loadAllPolicies() { + + edit.policyList = []; + + policyService.findAllWithCallback( function(data) { + + edit.policyList = data; + edit.policiesToBeSelected = angular.copy(edit.policyList); + + }); + } + + function addPolicyToPerimeter() { + + if (!edit.selectedPolicy || _.contains(edit.perimeter.policy_list, edit.selectedPolicy.id)) { + return; + } + + edit.perimeter.policy_list.push(edit.selectedPolicy.id); + edit.selectedPolicyList.push(edit.selectedPolicy); + edit.policiesToBeSelected = _.without(edit.policiesToBeSelected, edit.selectedPolicy); + + } + + function clearSelectedPolicies() { + + edit.perimeter.policy_list = []; + edit.selectedPolicyList = []; + edit.policiesToBeSelected = angular.copy(edit.policyList); + + } + + function removeSelectedPolicy(policy) { + + edit.policiesToBeSelected.push(policy); + edit.perimeter.policy_list = _.without(edit.perimeter.policy_list, policy.id); + edit.selectedPolicyList = _.without(edit.selectedPolicyList, policy); + + } + + /** + * Add + */ + + function addToPolicy() { + + if (!edit.selectedPerimeter) { + + return; + + } + + startLoading(); + + var perimeterToSend = edit.selectedPerimeter; + + perimeterToSend.policy_list.push(edit.policy.id); + + switch (edit.perimeterType) { + + case PERIMETER_CST.TYPE.SUBJECT: + + perimeterService.subject.update(perimeterToSend, updatePerimeterSuccess, updatePerimeterError); + break; + + case PERIMETER_CST.TYPE.OBJECT: + + perimeterService.object.update(perimeterToSend, updatePerimeterSuccess, updatePerimeterError); + break; + + case PERIMETER_CST.TYPE.ACTION: + + perimeterService.action.update(perimeterToSend, updatePerimeterSuccess, updatePerimeterError); + break; + } + + + function updatePerimeterSuccess(data) { + + $translate('moon.perimeter.update.success', {policyName: perimeterToSend.name}).then(function (translatedValue) { + + alertService.alertSuccess(translatedValue); + + }); + + stopLoading(); + + } + + function updatePerimeterError(reason) { + + $translate('moon.policy.update.error', { + policyName: perimeterToSend.name, + reason: reason.message + }).then(function (translatedValue) { + + alertService.alertError(translatedValue); + + }); + + stopLoading(); + + } + + } + + /** + * Create + */ + + function createPerimeter() { + + if (formService.isInvalid(edit.form)) { + + formService.checkFieldsValidity(edit.form); + + } else { + + startLoading(); + + var perimeterToSend = angular.copy(edit.perimeter); + + switch (edit.perimeterType) { + + case PERIMETER_CST.TYPE.SUBJECT: + + perimeterService.subject.add(perimeterToSend, createSuccess, createError); + break; + + case PERIMETER_CST.TYPE.OBJECT: + + perimeterService.object.add(perimeterToSend, createSuccess, createError); + break; + + case PERIMETER_CST.TYPE.ACTION: + + perimeterService.action.add(perimeterToSend, createSuccess, createError); + break; + } + + } + + function createSuccess(data) { + + var created = {}; + + switch (edit.perimeterType) { + + case PERIMETER_CST.TYPE.SUBJECT: + + created = utilService.transformOne(data, 'subjects'); + break; + + case PERIMETER_CST.TYPE.OBJECT: + + created = utilService.transformOne(data, 'objects'); + break; + + case PERIMETER_CST.TYPE.ACTION: + + created = utilService.transformOne(data, 'actions'); + break; + } + + $translate('moon.policy.perimeter.edit.create.success', {name: created.name}).then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + stopLoading(); + + /** + * If during the creating the created assignments has be mapped with the current policy, then it is not required to push the new Assignments in the list + */ + if (_.indexOf(created.policy_list, edit.policy.id) === -1) { + + edit.list.push(created); + + }else{ + + $scope.$emit('event:createAssignmentsFromAssignmentsEditSuccess', created, edit.perimeterType); + + } + + displayList(); + + clearSelectedPolicies(); + + } + + function createError(reason) { + + $translate('moon.policy.perimeter.edit.create.error', {name: perimeterToSend.name}).then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + stopLoading(); + + } + + } + + /** + * Delete + */ + function deletePerimeter() { + + if (!edit.selectedPerimeter) { + + return; + + } + + startLoading(); + + var perimeterToDelete = angular.copy(edit.selectedPerimeter); + + switch (edit.perimeterType) { + case PERIMETER_CST.TYPE.SUBJECT: + + perimeterService.subject.delete(perimeterToDelete, deleteSuccess, deleteError); + break; + + case PERIMETER_CST.TYPE.OBJECT: + + perimeterService.object.delete(perimeterToDelete, deleteSuccess, deleteError); + break; + + case PERIMETER_CST.TYPE.ACTION: + + perimeterService.action.delete(perimeterToDelete, deleteSuccess, deleteError); + break; + } + + + function deleteSuccess(data) { + + $translate('moon.policy.perimeter.edit.delete.success', {name: perimeterToDelete.name}) + .then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + policyService.findOneReturningPromise(edit.policy.id).then(function (data) { + + edit.policy = utilService.transformOne(data, 'policies'); + + cleanSelectedValue(); + activate(); + stopLoading(); + + $scope.$emit('event:deletePerimeterFromPerimeterAddSuccess', edit.policy); + + }); + + } + + function deleteError(reason) { + + $translate('moon.policy.perimeter.edit.delete.error', {name: perimeterToDelete.name}).then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + stopLoading(); + + } + } + + function cleanSelectedValue() { + + delete edit.selectedPerimeter; + + } + + function startLoading() { + + edit.loading = true; + + } + + function stopLoading() { + + edit.loading = false; + + } + + function displayList() { + + edit.fromList = true; + + } + + /** + * If A perimeter has been unMapped, maybe it has to be display into the available list of Perimeter + * @param perimeter + * @param type + */ + function manageUnMappedPerimeter(event, perimeter, type){ + + if(type === edit.perimeterType && _.indexOf(perimeter.policy_list, edit.policy.id) === -1){ + + edit.list.push(perimeter); + + } + + } + + } + +})(); \ No newline at end of file diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules-edit.tpl.html b/moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules-edit.tpl.html new file mode 100755 index 00000000..685046a5 --- /dev/null +++ b/moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules-edit.tpl.html @@ -0,0 +1,341 @@ +
+ +
+ +
+ + +
+ + + +
+ + + + + +
+
+ +
+ +
+ Policy is required +
+ +
+ +
+ +
+
+ +
+
+ +
+ + +
+ + + +
+ + + + + +
+
+ +
+ +
+ A MetaRules is required +
+ +
+ + + +
+ +
+ +
+ + +
+ +
+ +
+ +
+ +
+ + + +
+ + + + + +
+
+ +
+ +
+ Some subject are required +
+ +
+ +
+ +
+ +
+ +
+ + + +
+ +
+ +
+ +
+ + + +
+ +
    + +
  • + + + +
  • + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ + + +
+ + + + + +
+
+ +
+ +
+ Some objects are required +
+ +
+ +
+ +
+ +
+ +
+ + + +
+ +
+ +
+ +
+ + + +
+ +
    + +
  • + + + +
  • + +
+ +
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ + + +
+ + + + + +
+
+ +
+ +
+ Some action are required +
+
+ +
+ +
+ +
+ +
+ + + +
+ +
+ +
+ +
+ + + +
+ +
    + +
  • + + + +
  • + +
+ +
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ + + +
+ +
+ An instructions is required +
+
+ +
+ +
+ +
+ + + + Create + + + + +
+ +
+ +
+ +
+ +
+ +
\ No newline at end of file diff --git a/moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules.edit.dir.js b/moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules.edit.dir.js new file mode 100755 index 00000000..b7bb7614 --- /dev/null +++ b/moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules.edit.dir.js @@ -0,0 +1,537 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .directive('moonRulesEdit', moonRulesEdit); + + moonRulesEdit.$inject = []; + + function moonRulesEdit() { + + return { + templateUrl : 'html/policy/edit/parameter/rules/rules-edit.tpl.html', + bindToController : true, + controller : moonRulesEditController, + controllerAs : 'edit', + scope : { + policy : '=' + }, + restrict : 'E', + replace : true + }; + + } + + angular + .module('moon') + .controller('moonRulesEditController', moonRulesEditController); + + moonRulesEditController.$inject = ['$scope', 'rulesService', 'alertService', '$translate', + 'formService', 'policyService', 'utilService', 'metaRuleService', 'metaDataService', 'modelService', 'dataService', 'DATA_CST']; + + function moonRulesEditController($scope, rulesService, alertService, $translate, + formService, policyService, utilService, metaRuleService, metaDataService, modelService, dataService, DATA_CST) { + + var edit = this; + + edit.policy = $scope.edit.policy; + edit.editMode = true; + + edit.fromList = false; + + edit.loading = false; + + edit.form = {}; + edit.showDetailselectedMetaRules = false; + + edit.list = []; + edit.policyList = []; + + edit.categories = { + subject : [], + loadingSubjects: true, + object : [], + loadingObjects: true, + action : [], + loadingActions : true + }; + + edit.data = {}; // this object is filled in declareDataObject(): + + edit.create = createRules; + edit.addDataToRules = addDataToRules; + edit.removeSelectedDataFromRules = removeSelectedDataFromRules; + edit.isNumberSelectedDataAtMaximum = isNumberSelectedDataAtMaximum; + + //this variable is related to checks on Instruction field which is in JSON + edit.instructionsValid = true; + edit.numberOfSelectedSubjectValid = true; + edit.numberOfSelectedObjecttValid = true; + edit.numberOfSelectedActionsValid = true; + + activate(); + + /* + * + */ + function activate(){ + + edit.rules = {meta_rule_id: null, rule: [], policy_id: null, instructions: '[{"decision": "grant"}]', enabled: true}; + declareDataObject(); + loadAllPolicies(); + clearSelectedMetaRules(); + + } + + function loadAllPolicies() { + + edit.policyList = []; + + policyService.findAllWithCallback( function(data) { + + _.each(data, function(element){ + + if(element.id === edit.policy.id){ + edit.selectedPolicy = element; + } + + }); + + edit.policyList = data; + + }); + } + + $scope.$watch('edit.selectedPolicy', function(newValue){ + + clearSelectedMetaRules(); + + if(!_.isUndefined(newValue)){ + + loadRelatedMetaRules(); + + } + + }); + + $scope.$watch('edit.selectedMetaRules', function(newValue){ + + clearSelectedData(); + + edit.categories = { + subject : [], + loadingSubjects: true, + object : [], + loadingObjects: true, + action : [], + loadingActions : true + }; + + declareDataObject(); + + if(!_.isUndefined(newValue)){ + + loadRelatedCategoriesAndData(newValue.subject_categories, newValue.object_categories, newValue.action_categories); + + } + + }); + + /** + * To get the related MetaRules, it is required to : + * - Get the model related to the policy + * - Get the metaRules associated to the model + * - Get the MetaData associated to the metaRules + */ + function loadRelatedMetaRules() { + + edit.selectedPolicy.meta_rules_values = undefined; + + modelService.findOneWithCallback(edit.selectedPolicy.model_id, function(model){ + + metaRuleService.findSomeWithCallback(model.meta_rules, function(metaRules){ + + edit.selectedPolicy.meta_rules_values = metaRules; + + }); + + }); + + } + + /** + * Load categories from arrays of id in args + * @param subjectsCategories, list of subject id related to the metaRule + * @param objectCategories, list of object id related to the metaRule + * @param actionsCategories, list of action id related to the metaRule + */ + function loadRelatedCategoriesAndData(subjectsCategories, objectCategories, actionsCategories){ + + metaDataService.subject.findSomeWithCallback(subjectsCategories, function(list){ + + edit.categories.subject = list; + edit.categories.loadingSubjects = false; + + _.each(edit.categories.subject, function(aSubject){ + + dataService.subject.findAllFromCategoriesWithCallback(edit.selectedPolicy.id, aSubject.id, function(subjects){ + + edit.data.subject = subjects; + edit.data.loadingSubjects = false; + edit.data.subjectsToBeSelected = angular.copy(edit.data.subject); + + }); + + }); + + }); + + metaDataService.object.findSomeWithCallback(objectCategories, function(list){ + + edit.categories.object = list; + edit.categories.loadingObjects = false; + + _.each(edit.categories.object, function(aObject){ + + dataService.object.findAllFromCategoriesWithCallback(edit.selectedPolicy.id, aObject.id, function(objects){ + + edit.data.object = objects; + edit.data.loadingObjects = false; + edit.data.objectsToBeSelected = angular.copy(edit.data.object); + + }); + + }); + + }); + + metaDataService.action.findSomeWithCallback(actionsCategories, function(list){ + + edit.categories.action = list; + edit.categories.loadingActions = false; + + _.each(edit.categories.action, function(aAction){ + + dataService.action.findAllFromCategoriesWithCallback(edit.selectedPolicy.id, aAction.id, function(actions){ + + edit.data.action = actions; + edit.data.loadingActions = false; + edit.data.actionsToBeSelected = angular.copy(edit.data.action); + + }); + + }); + + }); + + } + + /** + * createRules, create Rules depending of what has been filled in the view + */ + function createRules() { + + edit.instructionsValid = true; + edit.numberOfSelectedSubjectValid = true; + edit.numberOfSelectedObjecttValid = true; + edit.numberOfSelectedActionsValid = true; + + manageInstructionContent(); + // bellow function is called here in order to display errors into the view + manageNumberOfSelectedData(); + + if(formService.isInvalid(edit.form)) { + + formService.checkFieldsValidity(edit.form); + + //manageNumberOfSelectedData is call again in order to check if errors have been display into the view + }else if(edit.instructionsValid && manageNumberOfSelectedData()){ + + startLoading(); + buildRulesArray(); + + edit.rules.meta_rule_id = edit.selectedMetaRules.id; + edit.rules.policy_id = edit.selectedPolicy.id; + + var rulesToSend = angular.copy(edit.rules); + rulesToSend.instructions = JSON.parse(edit.rules.instructions); + + rulesService.add(rulesToSend, edit.policy.id, createSuccess, createError); + } + + + function createSuccess(data) { + + var created = utilService.transformOne(data, 'rules'); + + $translate('moon.policy.rules.edit.action.add.create.success').then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + $scope.$emit('event:createRulesFromDataRulesSuccess', created); + + activate(); + + stopLoading(); + + } + + function createError(reason) { + + $translate('moon.policy.rules.edit.action.add.create.error').then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + stopLoading(); + + } + + } + + /** + * if instructions attribute is not good then edit.instructionsValid is set to false + * it will allow the view to display an error + */ + function manageInstructionContent(){ + + if (!isInstructionValid(edit.rules.instructions)){ + + edit.instructionsValid = false; + + }else{ + + edit.instructionsValid = true; + + } + } + + /** + * return true if the user has selected the number required of Selected Data (subject, object or action) + * if one is missing then return false + * it will also set numberOfSelected(Subject/Object/Action)Valid to true or false in order to display errors form in the view + * @returns {boolean} + */ + function manageNumberOfSelectedData(){ + + isNumberSelectedDataAtMaximum(DATA_CST.TYPE.SUBJECT) ? + edit.numberOfSelectedSubjectValid = true: edit.numberOfSelectedSubjectValid = false; + isNumberSelectedDataAtMaximum(DATA_CST.TYPE.OBJECT) ? + edit.numberOfSelectedObjecttValid = true: edit.numberOfSelectedObjecttValid = false; + isNumberSelectedDataAtMaximum(DATA_CST.TYPE.ACTION) ? + edit.numberOfSelectedActionsValid = true: edit.numberOfSelectedActionsValid = false; + + return edit.numberOfSelectedSubjectValid && edit.numberOfSelectedObjecttValid && edit.numberOfSelectedActionsValid; + } + + /** + * Check if the variables in param is not undefined and if it is a JSON + * It is used for instructions attribute of a Rules object + * @param str + * @returns {boolean|*} + */ + function isInstructionValid(str){ + + return !_.isUndefined(str) && isJsonString(str); + + } + + function isJsonString(str) { + + var item = null; + + try { + item = JSON.parse(str); + } catch (e) { + + return false; + } + + if (typeof item === 'object' && item !== null) { + + return true; + } + + return false; + } + + function startLoading(){ + + edit.loading = true; + + } + + function stopLoading(){ + + edit.loading = false; + + } + + /** + * allow to clear selected values in the form + */ + function clearSelectedMetaRules(){ + + edit.selectedMetaRules = undefined; + + clearSelectedData(); + + } + + function clearSelectedData(){ + + edit.selectedSubject = undefined; + edit.selectedObject = undefined; + edit.selectedAction = undefined; + + } + + /** + * check if the number of Selected Data is equal to the number of categories associated to the metaRule + * @param typeCST : 'SUBJECT', 'OBJECT', 'ACTION' + * @returns {boolean} + */ + function isNumberSelectedDataAtMaximum(typeCST){ + + if(!edit.selectedMetaRules){ + return false; + } + + switch (typeCST) { + + case DATA_CST.TYPE.SUBJECT: + + return edit.data.selectedSubjectsList.length === edit.selectedMetaRules.subject_categories.length; + + case DATA_CST.TYPE.OBJECT: + + return edit.data.selectedObjectsList.length === edit.selectedMetaRules.object_categories.length; + + case DATA_CST.TYPE.ACTION: + + return edit.data.selectedActionsList.length === edit.selectedMetaRules.action_categories.length; + } + } + + /** + * Add a data to an array of selected value (SUBJECT/OBJECT/ACTION) + * those arrays will used in the create function in order to filled the rule attribute of a rules object + * it will remove the selected value from the possible value to be selected once the data is added + * @param typeCST + */ + function addDataToRules(typeCST){ + + switch (typeCST) { + case DATA_CST.TYPE.SUBJECT: + + if (!edit.selectedSubject || isNumberSelectedDataAtMaximum(typeCST) + || _.contains(edit.data.selectedSubjectsList, edit.selectedSubject)) { + return; + } + + edit.data.selectedSubjectsList.push(edit.selectedSubject); + edit.data.subjectsToBeSelected = _.without(edit.data.subjectsToBeSelected, edit.selectedSubject); + + break; + case DATA_CST.TYPE.OBJECT: + + if (!edit.selectedObject || isNumberSelectedDataAtMaximum(typeCST) + || _.contains(edit.data.selectedObjectsList, edit.selectedObject)) { + return; + } + + edit.data.selectedObjectsList.push(edit.selectedObject); + edit.data.objectsToBeSelected = _.without(edit.data.objectsToBeSelected, edit.selectedObject); + + break; + + case DATA_CST.TYPE.ACTION: + if (!edit.selectedAction || isNumberSelectedDataAtMaximum(typeCST) + || _.contains(edit.data.selectedActionsList, edit.selectedAction)) { + return; + } + + edit.data.selectedActionsList.push(edit.selectedAction); + edit.data.actionsToBeSelected = _.without(edit.data.actionsToBeSelected, edit.selectedAction); + + break; + } + + } + + /** + * Remove a selected value, + * refresh the list of possible value to be selected with the removed selected value + * @param data + * @param typeCST + */ + function removeSelectedDataFromRules(data, typeCST) { + + switch (typeCST) { + + case DATA_CST.TYPE.SUBJECT: + + edit.data.subjectsToBeSelected.push(data); + edit.data.selectedSubjectsList = _.without(edit.data.selectedSubjectsList, data); + break; + + case DATA_CST.TYPE.OBJECT: + + edit.data.objectsToBeSelected.push(data); + edit.data.selectedObjectsList = _.without(edit.data.selectedObjectsList, data); + break; + + case DATA_CST.TYPE.ACTION: + + edit.data.actionsToBeSelected.push(data); + edit.data.selectedActionsList = _.without(edit.data.selectedActionsList, data); + break; + } + + } + + /** + * fill edit.rules.rule array with the selected data + * it will first add subject list, object list and then action list + */ + function buildRulesArray(){ + + _.each(edit.data.selectedSubjectsList, pushInRulesTab); + _.each(edit.data.selectedObjectsList, pushInRulesTab); + _.each(edit.data.selectedActionsList, pushInRulesTab); + + function pushInRulesTab(elem){ + edit.rules.rule.push(elem.id); + } + } + + /** + * Declare the data object which contains attributes related to data, + * values to be selected, values selected, loader... + */ + function declareDataObject(){ + + edit.data = { + subject : [], // List of subjects related to the policy + loadingSubjects: true, // allow to know if a call to the API is in progress + subjectsToBeSelected : [], // List of subjects the user can select + selectedSubjectsList: [], // List of subjects selected by the user from subjectsToBeSelected + subjectCST : DATA_CST.TYPE.SUBJECT, + object : [], + loadingObjects: true, + objectsToBeSelected: [], + selectedObjectsList: [], + objectCST : DATA_CST.TYPE.OBJECT, + action : [], + loadingActions : true, + actionsToBeSelected : [], + selectedActionsList: [], + actionCST : DATA_CST.TYPE.ACTION + } + + } + + } + +})(); \ No newline at end of file diff --git a/moonv4/moon_gui/static/app/services/moon/policy/parameters/rules.service.js b/moonv4/moon_gui/static/app/services/moon/policy/parameters/rules.service.js new file mode 100755 index 00000000..76b24011 --- /dev/null +++ b/moonv4/moon_gui/static/app/services/moon/policy/parameters/rules.service.js @@ -0,0 +1,56 @@ +/** + * @author Samy Abdallah + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .factory('rulesService', rulesService); + + rulesService.$inject = ['$resource', 'REST_URI', 'utilService']; + + function rulesService($resource, REST_URI, utilService) { + + return { + + data: { + + policy: $resource(REST_URI.POLICIES + ':policy_id/rules/:rule_id', {}, { + get: {method: 'GET'}, + create: {method: 'POST'}, + remove: {method: 'DELETE'} + }) + + }, + + add: function (rules, policyId, callbackSuccess, callbackError ) { + + this.data.policy.create({policy_id: policyId}, rules, callbackSuccess, callbackError); + + }, + + delete: function (ruleId, policyId, callbackSuccess, callbackError ) { + + this.data.policy.remove({policy_id: policyId, rule_id: ruleId}, {}, callbackSuccess, callbackError); + + }, + + findAllFromPolicyWithCallback: function(policyId, callback){ + + this.data.policy.get({policy_id: policyId}).$promise.then(function(data) { + + callback(data.rules.rules); + //callback(utilService.transform(data['rules'], 'rules')); + + }); + + } + + + } + + } +})(); \ No newline at end of file -- cgit 1.2.3-korg