diff options
Diffstat (limited to 'moon_gui/static/app')
118 files changed, 15644 insertions, 0 deletions
diff --git a/moon_gui/static/app/authentication/authentication.controller.js b/moon_gui/static/app/authentication/authentication.controller.js new file mode 100755 index 00000000..ce38bc5f --- /dev/null +++ b/moon_gui/static/app/authentication/authentication.controller.js @@ -0,0 +1,58 @@ +/** + * @author Samy Abdallah + */ +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('AuthenticationController', AuthenticationController); + + AuthenticationController.$inject = ['authenticationService', '$translate', 'alertService', '$state', '$rootScope']; + + function AuthenticationController(authenticationService, $translate, alertService, $state, $rootScope) { + + var vm = this; + + vm.login = login; + vm.loading = false; + + vm.credentials = { + username : '', + password : '' + }; + + activate(); + + function activate(){ + if($rootScope.connected){ + $state.go('moon.dashboard'); + } + } + + function login(){ + vm.loading = true; + authenticationService.Login(vm.credentials, loginSuccess, loginError); + } + + function loginSuccess() { + + $translate('moon.login.success').then( function(translatedValue) { + alertService.alertSuccess(translatedValue); + $state.go('moon.dashboard'); + vm.loading = false; + }); + + } + + function loginError(reason) { + + $translate('moon.login.error', { errorCode: reason.status }).then( function(translatedValue) { + alertService.alertError(translatedValue); + vm.loading = false; + }); + + } + } +})();
\ No newline at end of file diff --git a/moon_gui/static/app/authentication/authentication.tpl.html b/moon_gui/static/app/authentication/authentication.tpl.html new file mode 100755 index 00000000..77d1646b --- /dev/null +++ b/moon_gui/static/app/authentication/authentication.tpl.html @@ -0,0 +1,28 @@ +<div class="col-md-6 col-md-offset-3"> + + <h2 data-translate="moon.login.titlePage">Login</h2> + + <form name="form" ng-submit="form.$valid && auth.login()" novalidate> + + <div class="form-group" ng-class="{ 'has-error': form.$submitted && form.username.$invalid }"> + <label for="username" data-translate="moon.login.username" >Username</label> + <input type="text" id="username" name="username" class="form-control" ng-model="auth.credentials.username" required /> + <div ng-messages="form.$submitted && form.username.$error" class="help-block"> + <div ng-message="required" data-translate="moon.login.check.username.required" >Username is required</div> + </div> + </div> + + <div class="form-group" ng-class="{ 'has-error': form.$submitted && form.password.$invalid }"> + <label for="password" data-translate="moon.login.password" >Password</label> + <input type="password" id="password" name="password" class="form-control" ng-model="auth.credentials.password" required /> + <div ng-messages="form.$submitted && form.password.$error" class="help-block"> + <div ng-message="required" data-translate="moon.login.check.password.required">Password is required</div> + </div> + </div> + + <div class="form-group"> + <button ng-disabled="auth.loading" class="btn btn-primary" data-translate="moon.login.login" >Login</button> + <img ng-if="auth.loading" src="assets/img/ajax-loader.gif" /> + </div> + </form> +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/common/404/404.tpl.html b/moon_gui/static/app/common/404/404.tpl.html new file mode 100755 index 00000000..61e0420c --- /dev/null +++ b/moon_gui/static/app/common/404/404.tpl.html @@ -0,0 +1,3 @@ +<div data-translate="moon.global.404">Not found!</div> + +<div> Go <a href="" ui-sref="moon.project.list">Projects ?</a></div>
\ No newline at end of file diff --git a/moon_gui/static/app/common/compatibility/compatibility.tpl.html b/moon_gui/static/app/common/compatibility/compatibility.tpl.html new file mode 100755 index 00000000..0e32dc4f --- /dev/null +++ b/moon_gui/static/app/common/compatibility/compatibility.tpl.html @@ -0,0 +1,26 @@ +<div class="modal" tabindex="-1" data-role="modalCompatibility"> + + <div class="modal-dialog"> + + <div class="modal-content"> + + <div class="modal-header"> + <button type="button" class="close" ng-click="$hide()">×</button> + <h4 class="modal-title" data-translate="moon.compatibility.title"></h4> + </div> + + <div class="modal-body"> + <span data-translate="moon.compatibility.content"></span> + </div> + + <div class="modal-footer"> + <div class="btn-toolbar" style="float: right;"> + <button ng-click="$hide()" class="btn btn-default" data-translate="moon.compatibility.close">Close</button> + </div> + </div> + + </div> + + </div> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/common/footer/footer.controller.js b/moon_gui/static/app/common/footer/footer.controller.js new file mode 100755 index 00000000..d7506840 --- /dev/null +++ b/moon_gui/static/app/common/footer/footer.controller.js @@ -0,0 +1,54 @@ +/** + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('FooterController', FooterController); + + FooterController.$inject = ['$modal', 'versionService']; + + function FooterController($modal, versionService) { + + var footer = this; + + footer.version = null; + footer.browsersModal = null; + footer.showBrowsersCompliance = showBrowsersCompliance; + + newBrowsersModal(); + currentVersion(); + + function newBrowsersModal() { + + footer.browsersModal = $modal({ template: 'html/common/compatibility/compatibility.tpl.html', show: false }); + + return footer.browsersModal; + + } + + function showBrowsersCompliance() { + footer.browsersModal.$promise.then(footer.browsersModal.show); + } + + function currentVersion() { + + var _self = footer; + + versionService.version.get().$promise.then(function(data) { + + _self.version = (data.version) ? data.version : 'SNAPSHOT'; + + return _self.version; + + }); + + } + + } + +})();
\ No newline at end of file diff --git a/moon_gui/static/app/common/footer/footer.tpl.html b/moon_gui/static/app/common/footer/footer.tpl.html new file mode 100755 index 00000000..aacb392d --- /dev/null +++ b/moon_gui/static/app/common/footer/footer.tpl.html @@ -0,0 +1,7 @@ +<div class="container footer" ng-controller="FooterController as footer"> + <div class="row"> + <div class="pull-right"> + <span>v<span ng-bind="footer.version"></span></span> - <a href="" ng-click="footer.showBrowsersCompliance()" data-translate="moon.compatibility.label">browser compatibility</a> + </div> + </div> +</div> diff --git a/moon_gui/static/app/common/header/header.controller.js b/moon_gui/static/app/common/header/header.controller.js new file mode 100755 index 00000000..13ef4d6f --- /dev/null +++ b/moon_gui/static/app/common/header/header.controller.js @@ -0,0 +1,56 @@ +/** + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('HeaderController', HeaderController); + + HeaderController.$inject = ['$translate', 'menuService', 'authenticationService', 'alertService']; + + function HeaderController($translate, menuService, authenticationService, alertService) { + + var header = this; + + /* + * + */ + + header.isProjectTabActive = menuService.isProjectTabActive; + header.isPDPTabActive = menuService.isPDPTabActive; + header.isLogsTabActive = menuService.isLogsTabActive; + header.isPolicyTabActive = menuService.isPolicyTabActive; + header.isModelTabActive = menuService.isModelTabActive; + header.changeLocale = changeLocale; + header.logout = logout; + header.currentLanguage = $translate.use(); + + header.getUser = authenticationService.GetUser; + + /* + * + */ + + function changeLocale(localeKey, event) { + + event.preventDefault(); + $translate.use(localeKey); + $translate.preferredLanguage(localeKey); + header.currentLanguage = localeKey; + + } + + function logout(){ + + authenticationService.Logout(); + $translate('moon.logout.success').then( function(translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + } + } +})();
\ No newline at end of file diff --git a/moon_gui/static/app/common/header/header.tpl.html b/moon_gui/static/app/common/header/header.tpl.html new file mode 100755 index 00000000..f703fa79 --- /dev/null +++ b/moon_gui/static/app/common/header/header.tpl.html @@ -0,0 +1,52 @@ +<div class="container banner" ng-controller="HeaderController as header"> + + <div class="row"> + + <div class="col-md-3 sub-banner"> + <a ui-sref="moon.dashboard"><img src="assets/img/logo-orange.gif" alt="Orange" /> </a> + <img src="assets/img/logo-openstack.png" alt="OpenStack" /> + </div> + + <div class="col-md-6 center-block"> + <h1 data-translate="moon.global.applicationName">Moon UI</h1> + </div> + + <div class="col-md-3"> + + <span class="pull-right"> + + <a href="" ng-click="header.changeLocale('fr', $event)" ng-class="{'strong' : header.currentLanguage === 'fr'}"><img src="assets/img/arrow-link.gif" alt="fr_" />fr</a> + <a href="" ng-click="header.changeLocale('en', $event)" ng-class="{'strong' : header.currentLanguage === 'en'}"><img src="assets/img/arrow-link.gif" alt="en_" />en</a> + + <a href="" ng-if="connected" ng-click="header.logout()" class="left30"> + <span class="glyphicon glyphicon-log-out"></span> + <span data-translate="moon.logout.title">Logout</span>(<span ng-bind="header.getUser().token.user.name"></span>) + </a> + + <a href="" ng-if="!connected" class="left30"> + <span class="glyphicon glyphicon-log-in"></span> + <span data-translate="moon.login.title">Login</span> + </a> + </span> + + </div> + + </div> + + <div class="row"> + <toaster-container toaster-options="{'position-class': 'toast-top-right', 'close-button': true}"></toaster-container> + </div> + + <div class="row" ng-if="connected"> + + <ul class="nav nav-tabs"> + <li ng-class="{active: header.isProjectTabActive()}"><a ui-sref="moon.project.list" data-translate="moon.menu.project">Projects</a></li> + <li ng-class="{active: header.isModelTabActive()}"><a ui-sref="moon.model.list" data-translate="moon.menu.model">Models</a></li> + <li ng-class="{active: header.isPolicyTabActive()}"><a ui-sref="moon.policy.list" data-translate="moon.menu.policy">Policy</a></li> + <li ng-class="{active: header.isPDPTabActive()}"><a ui-sref="moon.pdp.list" data-translate="moon.menu.pdp">PDP</a></li> + <!--<li ng-class="{active: header.isLogsTabActive()}"><a ui-sref="moon.logs" data-translate="moon.menu.logs">Logs</a></li>--> + </ul> + + </div> + +</div> diff --git a/moon_gui/static/app/common/loader/loader.dir.js b/moon_gui/static/app/common/loader/loader.dir.js new file mode 100755 index 00000000..ba40c121 --- /dev/null +++ b/moon_gui/static/app/common/loader/loader.dir.js @@ -0,0 +1,19 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .directive('moonLoader', moonLoader); + + moonLoader.$inject = []; + + function moonLoader() { + + return { + templateUrl : 'html/common/loader/loader.tpl.html', + restrict : 'E' + }; + } + +})(); diff --git a/moon_gui/static/app/common/loader/loader.tpl.html b/moon_gui/static/app/common/loader/loader.tpl.html new file mode 100755 index 00000000..51da439f --- /dev/null +++ b/moon_gui/static/app/common/loader/loader.tpl.html @@ -0,0 +1 @@ +<img src="assets/img/ajax-loader.gif" />
\ No newline at end of file diff --git a/moon_gui/static/app/common/waiting/waiting.tpl.html b/moon_gui/static/app/common/waiting/waiting.tpl.html new file mode 100755 index 00000000..6c042635 --- /dev/null +++ b/moon_gui/static/app/common/waiting/waiting.tpl.html @@ -0,0 +1,15 @@ +<div class="modal" tabindex="-1" data-role="modalWaiting"> + + <div class="modal-dialog"> + + <div class="modal-content"> + + <div class="modal-body centered"> + <img src="assets/img/ajax-waiting.gif" /> + </div> + + </div> + + </div> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/dashboard/dashboard.tpl.html b/moon_gui/static/app/dashboard/dashboard.tpl.html new file mode 100755 index 00000000..67184bcc --- /dev/null +++ b/moon_gui/static/app/dashboard/dashboard.tpl.html @@ -0,0 +1,14 @@ +<div class="container"> + + <div class="row"> + + <h1 data-translate="moon.dashboard.content">Moon:Software-Defined Security Framework</h1> + </div> + + <div class="row"> + + <img src="assets/img/et.jpg" alt="ET" class="img-responsive img-dashboard"/> + + </div> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/logs/logs.controller.js b/moon_gui/static/app/logs/logs.controller.js new file mode 100755 index 00000000..e48e2b8b --- /dev/null +++ b/moon_gui/static/app/logs/logs.controller.js @@ -0,0 +1,16 @@ +/** + * @author Samy Abdallah + */ +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('LogsController', LogsController); + + function LogsController() { + + } + +})();
\ No newline at end of file diff --git a/moon_gui/static/app/logs/logs.tpl.html b/moon_gui/static/app/logs/logs.tpl.html new file mode 100755 index 00000000..fecc0289 --- /dev/null +++ b/moon_gui/static/app/logs/logs.tpl.html @@ -0,0 +1,3 @@ +<div class="container"> + Logs +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/model/action/model-add.tpl.html b/moon_gui/static/app/model/action/model-add.tpl.html new file mode 100755 index 00000000..dee53a97 --- /dev/null +++ b/moon_gui/static/app/model/action/model-add.tpl.html @@ -0,0 +1,66 @@ +<div ng-controller="ModelAddController as add" class="modal" tabindex="-1" data-role="modalAddModel"> + + <div class="modal-dialog"> + + <div class="modal-content"> + + <div class="modal-header"> + <button type="button" class="close" ng-click="$hide()">×</button> + <h4 class="modal-title" data-translate="moon.model.add.title"></h4> + </div> + + <div class="modal-body"> + + <form class="form-horizontal" role="form" name="add.form"> + + <div class="form-group" ng-class="{'has-error': add.form.name.$invalid && add.form.name.$dirty}"> + + <label for="name" class="col-sm-3 control-label" data-translate="moon.model.add.form.name">Name</label> + + <div class="col-sm-6"> + + <input name="name" id="name" class="form-control" type="text" data-ng-model="add.model.name" required /> + + <div class="help-block" ng-show="add.form.name.$dirty && add.form.name.$invalid"> + <small class="error" ng-show="add.form.name.$error.required" data-translate="moon.model.add.check.name.required">Name is required</small> + </div> + + </div> + </div> + + <div class="form-group"> + + <label for="description" class="col-sm-3 control-label" data-translate="moon.model.add.form.description">Description</label> + <div class="col-sm-6"> + <textarea id="description" name="description" class="form-control" data-ng-model="add.model.description"></textarea> + </div> + + </div> + + </form> + + </div> + + <div class="modal-footer"> + + <div class="btn-toolbar" style="float: right;"> + + <a href="" ng-click="$hide()" class="btn btn-default"> + <span data-translate="moon.model.add.action.cancel">Cancel</span> + </a> + + <a href="" ng-disabled="add.loading" ng-click="add.create()" class="btn btn-warning"> + <span class="glyphicon glyphicon-save"></span> + <span data-translate="moon.model.add.action.create">Create Model</span> + </a> + <moon-loader ng-if="add.loading"></moon-loader> + + </div> + + </div> + + </div> + + </div> + +</div> diff --git a/moon_gui/static/app/model/action/model-delete.tpl.html b/moon_gui/static/app/model/action/model-delete.tpl.html new file mode 100755 index 00000000..cde16d0e --- /dev/null +++ b/moon_gui/static/app/model/action/model-delete.tpl.html @@ -0,0 +1,39 @@ +<div ng-controller="ModelDeleteController as del" class="modal" tabindex="-1" data-role="modalDeleteModel"> + + <div class="modal-dialog"> + + <div class="modal-content"> + + <div class="modal-header"> + <button type="button" class="close" ng-click="$hide()">×</button> + <h4 class="modal-title" data-translate="moon.model.remove.title"></h4> + </div> + + <div class="modal-body"> + + <p><span data-translate="moon.model.remove.content.query" data-translate-values="{ modelName: del.model.name }"></span></p> + + </div> + + <div class="modal-footer"> + <div class="btn-toolbar" style="float: right;"> + + <a href="" ng-click="$hide()" class="btn btn-default"> + <span data-translate="moon.model.remove.action.cancel">Cancel</span> + </a> + + <a href="" ng-disabled="del.loading" ng-click="del.remove()" class="btn btn-warning"> + <span class="glyphicon glyphicon-trash"></span> + <span data-translate="moon.model.remove.action.delete">Delete</span> + </a> + + <moon-loader ng-if="del.loading" ></moon-loader> + + </div> + </div> + + </div> + + </div> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/model/action/model-view.tpl.html b/moon_gui/static/app/model/action/model-view.tpl.html new file mode 100755 index 00000000..46c295c7 --- /dev/null +++ b/moon_gui/static/app/model/action/model-view.tpl.html @@ -0,0 +1,41 @@ +<div ng-controller="ModelViewController as view" class="modal" tabindex="-1" data-role="modalViewProject"> + + <div class="modal-dialog"> + + <div class="modal-content"> + + <div class="modal-header"> + <button type="button" class="close" ng-click="$hide()">×</button> + <h4 class="modal-title" data-translate="moon.model.view.title" data-translate-values="{modelName: view.model.name}"></h4> + </div> + <div class="modal-body"> + <dl class="dl-horizontal"> + <dt data-translate="moon.model.view.id">Id</dt> + <dd ng-bind="view.model.id"></dd> + <dt data-translate="moon.model.view.name">Name</dt> + <dd ng-bind="view.model.name"></dd> + <dt data-translate="moon.model.view.description">Description</dt> + <dd ng-bind="view.model.description"></dd> + </dl> + + <div ng-if="view.meta_rules_values"> + <moon-meta-rules-list mapped-model="view.model" edit-mode="false"></moon-meta-rules-list> + </div> + + <div ng-if="!view.meta_rules_values"> + <moon-loader></moon-loader> + </div> + + </div> + + <div class="modal-footer top10"> + <div class="btn-toolbar" style="float: right;"> + <button ng-click="$hide()" class="btn btn-default" data-translate="moon.model.view.action.close">Close</button> + </div> + </div> + + </div> + + </div> + +</div> diff --git a/moon_gui/static/app/model/action/model.controller.add.js b/moon_gui/static/app/model/action/model.controller.add.js new file mode 100755 index 00000000..11d3abf4 --- /dev/null +++ b/moon_gui/static/app/model/action/model.controller.add.js @@ -0,0 +1,71 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('ModelAddController', ModelAddController); + + ModelAddController.$inject = ['$scope', 'modelService', 'alertService', '$translate', 'formService', 'utilService']; + + function ModelAddController($scope, modelService, alertService, $translate, formService, utilService) { + + var add = this; + + /* + * + */ + + add.form = {}; + + add.loading = false; + + add.model = { name: null, description: null, meta_rules : [] }; + + add.create = createModel; + + function createModel() { + + if(formService.isInvalid(add.form)) { + + formService.checkFieldsValidity(add.form); + + } else { + + add.loading = true; + + modelService.data.create({}, add.model, createSuccess, createError); + + } + + function createSuccess(data) { + + var createdModel = utilService.transformOne(data, 'models'); + + $translate('moon.model.add.success', { modelName: createdModel.name }).then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + add.loading = false; + + $scope.$emit('event:modelCreatedSuccess', createdModel); + + } + + function createError(reason) { + + $translate('moon.model.add.error', { modelName: add.model.name }).then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + add.loading = false; + + $scope.$emit('event:modelCreatedError', add.project); + + } + + } + + } + +})(); diff --git a/moon_gui/static/app/model/action/model.controller.delete.js b/moon_gui/static/app/model/action/model.controller.delete.js new file mode 100755 index 00000000..5d9dae1a --- /dev/null +++ b/moon_gui/static/app/model/action/model.controller.delete.js @@ -0,0 +1,72 @@ +/** + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('ModelDeleteController', ModelDeleteController); + + ModelDeleteController.$inject = ['$scope', '$translate', 'alertService', 'modelService']; + + function ModelDeleteController($scope, $translate, alertService, modelService) { + + var del = this; + + /* + * + */ + + del.model = $scope.model; + del.loading = false; + + del.remove = deleteModel; + + activate(); + + /** + * + */ + + function activate(){ + + } + + + function deleteModel(){ + + del.loading = true; + + modelService.delete(del.model, deleteSuccess, deleteError); + + function deleteSuccess(data) { + + $translate('moon.model.remove.success', { modelName: del.model.name }).then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + del.loading = false; + + $scope.$emit('event:modelDeletedSuccess', del.model); + + } + + function deleteError(reason) { + + $translate('moon.model.remove.error', { modelName: del.model.name, errorCode: reason.data.error.code, message : reason.data.error.message } ).then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + del.loading = false; + + $scope.$emit('event:modelDeletedError', del.model); + + } + + } + } + +})(); diff --git a/moon_gui/static/app/model/action/model.controller.view.js b/moon_gui/static/app/model/action/model.controller.view.js new file mode 100755 index 00000000..7605eecf --- /dev/null +++ b/moon_gui/static/app/model/action/model.controller.view.js @@ -0,0 +1,53 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('ModelViewController', ModelViewController); + + ModelViewController.$inject = ['$scope', 'metaRuleService']; + + function ModelViewController($scope, metaRuleService) { + + var view = this; + + /* + * + */ + + view.model = $scope.model; + + view.meta_rules_values = false; + + activate(); + + function activate(){ + + if(view.model.meta_rules.length > 0 ){ + + findMetaRules(); + + }else{ + + view.meta_rules_values = []; + + } + + } + + function findMetaRules(){ + + metaRuleService.findSomeWithMetaData(view.model.meta_rules).then(function(metaRules){ + + view.meta_rules_values = metaRules; + + view.model.meta_rules_values = metaRules; + + }); + + } + + } + +})(); diff --git a/moon_gui/static/app/model/edit/metadata/metadata-edit.tpl.html b/moon_gui/static/app/model/edit/metadata/metadata-edit.tpl.html new file mode 100755 index 00000000..2616be1c --- /dev/null +++ b/moon_gui/static/app/model/edit/metadata/metadata-edit.tpl.html @@ -0,0 +1,99 @@ +<div> + + <div class="col-md-4 col-sm-4 col-xs-4"> + <a class="btn btn-primary" type="button" style="white-space: normal;" ng-click="edit.fromList = !edit.fromList"> + <span ng-if="!edit.fromList" data-translate="moon.model.metadata.edit.action.list">Add from the list</span> + <span ng-if="edit.fromList" data-translate="moon.model.metadata.edit.action.new">Add a new Category</span> + </a> + </div> + + <div class="col-md-8 col-sm-8 col-xs-8"> + + <form name="selectMetaData" ng-if="edit.fromList" class="form-horizontal" role="form" > + + <div class="form-group" > + + <ui-select ng-model="edit.selectedMetaData" name="object"> + + <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match> + <ui-select-choices repeat="ametaData in edit.list"> + <div ng-value="ametaData" ng-bind="ametaData.name"></div> + </ui-select-choices> + + </ui-select> + + </div> + + <div class="form-group"> + + <div class="pull-left col-md-4 col-sm-4 col-xs-4"> + + <a href="" ng-disabled="edit.loading || !edit.selectedMetaData" ng-click="edit.deleteMetaData()" class="btn btn-warning"> + <span class="glyphicon glyphicon-trash"></span> + <span data-translate="moon.model.metadata.edit.action.delete">Delete</span> + </a> + + </div> + + <div class="pull-right col-md-7 col-md-offset-1 col-sm-7 col-sm-offset-1 col-xs-7 col-xs-offset-1 "> + + <a href="" ng-disabled="edit.loading || !edit.selectedMetaData" ng-click="edit.addToMetaRule()" class="btn btn-warning" style="white-space: normal;"> + <span class="glyphicon glyphicon-link"></span> + <span data-translate="moon.model.metadata.edit.action.add">Add the selected Category</span> + </a> + + </div> + + </div> + + <moon-loader ng-if="edit.loading"></moon-loader> + + </form> + + <form ng-if="!edit.fromList" class="form-horizontal" role="form" name="edit.form"> + + <div class="form-group" ng-class="{'has-error': edit.form.name.$invalid && edit.form.name.$dirty}"> + + <label for="name" class="col-sm-3 control-label" data-translate="moon.model.metadata.edit.name">Name</label> + + <div class="col-sm-6"> + + <input name="name" id="name" class="form-control" type="text" data-ng-model="edit.metaData.name" required /> + + <div class="help-block" ng-show="edit.form.name.$dirty && edit.form.name.$invalid"> + <small class="error" ng-show="edit.form.name.$error.required" data-translate="moon.model.metadata.edit.check.name.required">Name is required</small> + </div> + + </div> + + </div> + + <div class="form-group"> + + <label for="description" class="col-sm-3 control-label" data-translate="moon.model.metadata.edit.description">Description</label> + <div class="col-sm-6"> + <textarea id="description" name="description" class="form-control" data-ng-model="edit.metaData.description"></textarea> + </div> + + </div> + + <div class="form-group"> + + <div class="pull-right"> + + <a href="" ng-disabled="edit.loading" ng-click="edit.create()" class="btn btn-warning"> + <span class="glyphicon glyphicon-save"></span> + <span data-translate="moon.model.metadata.edit.action.create">Create</span> + </a> + + <moon-loader ng-if="edit.loading"></moon-loader> + + </div> + + </div> + + </form> + + </div> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/model/edit/metadata/metadata-list.tpl.html b/moon_gui/static/app/model/edit/metadata/metadata-list.tpl.html new file mode 100755 index 00000000..30a42dbc --- /dev/null +++ b/moon_gui/static/app/model/edit/metadata/metadata-list.tpl.html @@ -0,0 +1,491 @@ +<div> + <!-- + !shortDisplay allow to display more details than shortDisplay. + It will display panels row by row and each panels list have a table with more columns + --> + <div ng-if="!list.shortDisplay"> + + <div class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.model.metadata.subject.title">List of associated Subject Categories</h4> + + </div> + + <div class="panel-body"> + + <div class="table-responsive"> + + <table class="table table-striped"> + + <thead> + <tr> + <th data-translate="moon.model.metadata.table.id">Id</th> + <th data-translate="moon.model.metadata.table.name">Name</th> + <th data-translate="moon.model.metadata.table.description">Description</th> + <th ng-if="list.editMode" data-translate="moon.model.metadata.table.action.title"></th> + </tr> + </thead> + + <moon-loader ng-if="list.loadingCatSub"></moon-loader> + + <tbody ng-if="!list.loadingCatSub && list.getSubjectCategories().length > 0"> + <tr ng-repeat="(key, value) in list.catSub"> + <td ng-bind="value.id"></td> + <td ng-bind="value.name"></td> + <td ng-bind="value.description"></td> + <td ng-if="list.editMode"> + + <a href="" ng-if="!value.loader" ng-click="list.unMapSub(value)"> + <span class="glyphicon glyphicon-transfer"></span> + <span class="control-label" data-translate="moon.model.metadata.action.remove">Remove</span> + </a> + + <!--<div ng-if="!value.loader" class="dropdown"> + + <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown"> + <span data-translate="moon.model.metadata.table.action.title">Actions</span> + <span class="caret"></span> + </button> + + <ul class="dropdown-menu"> + + <li> + <a href="" ng-click="list.unMapSub(value)" > + <span class="glyphicon glyphicon-transfer"></span> + <span class="control-label" data-translate="moon.model.metadata.action.remove">Remove</span> + </a> + </li> + + <li class="divider"></li> + + <li> + <a href="" ng-click="list.deleteSub(value)"> + <span class="glyphicon glyphicon-trash"></span> + <span class="control-label" data-translate="moon.model.metadata.table.action.delete">Delete</span> + </a> + </li> + + </ul> + + </div>--> + + <div ng-if="value.loader"> + + <moon-loader></moon-loader> + + </div> + + </td> + + </tr> + </tbody> + + + <tbody ng-if="!list.loadingCatSub && list.catSub.length === 0"> + <tr> + <td data-translate="moon.model.metadata.subject.notFound">There is no Subjects</td> + <td></td> + <td></td> + <td ng-if="list.editMode"></td> + </tr> + </tbody> + + </table> + + </div> + + </div> + + </div> + + <div ng-if="list.editMode" class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.model.metadata.subject.add.title">Add a Subject Category</h4> + + </div> + + <div class="panel-body"> + + <moon-meta-data-edit meta-rule="list.metaRule" + meta-data-type="list.typeOfSubject"></moon-meta-data-edit> + + </div> + + </div> + + <div class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.model.metadata.object.title">List associated of Object Categories</h4> + + </div> + + <div class="panel-body"> + + <div class="table-responsive"> + + <table class="table table-striped"> + + <thead> + <tr> + <th data-translate="moon.model.metadata.table.id">Id</th> + <th data-translate="moon.model.metadata.table.name">Name</th> + <th data-translate="moon.model.metadata.table.description">Description</th> + <th ng-if="list.editMode" data-translate="moon.model.metadata.table.action.title"></th> + + </tr> + </thead> + + <moon-loader ng-if="list.loadingCatObj"></moon-loader> + + <tbody ng-if="!list.loadingCatObj && list.catObj.length > 0"> + <tr ng-repeat="(key, value) in list.catObj"> + <td ng-bind="value.id"></td> + <td ng-bind="value.name"></td> + <td ng-bind="value.description"></td> + <td ng-if="list.editMode"> + + <a href="" ng-if="!value.loader" ng-click="list.unMapObj(value)"> + <span class="glyphicon glyphicon-transfer"></span> + <span class="control-label" data-translate="moon.model.metadata.action.remove">Remove</span> + </a> + + + <!--<div ng-if="!value.loader" class="dropdown"> + + <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown"> + <span data-translate="moon.model.metadata.table.action.title">Actions</span> + <span class="caret"></span> + </button> + + <ul class="dropdown-menu"> + + <li> + <a href="" ng-click="list.unMapObj(value)" > + <span class="glyphicon glyphicon-transfer"></span> + <span class="control-label" data-translate="moon.model.metadata.action.remove">Remove</span> + </a> + </li> + + <li class="divider"></li> + + <li> + <a href="" ng-click="list.deleteObj(value)"> + <span class="glyphicon glyphicon-trash"></span> + <span class="control-label" data-translate="moon.model.metadata.table.action.delete">Delete</span> + </a> + </li> + + </ul> + + </div>--> + + <div ng-if="value.loader"> + + <moon-loader></moon-loader> + + </div> + + </td> + </tr> + </tbody> + + <tbody ng-if="!list.loadingCatObj && list.catObj.length === 0"> + <tr> + <td data-translate="moon.model.metadata.object.notFound">There is no Objects</td> + <td></td> + <td></td> + <td ng-if="list.editMode"></td> + </tr> + </tbody> + + </table> + + </div> + + </div> + + </div> + + <div ng-if="list.editMode" class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.model.metadata.object.add.title">Add an Object Category</h4> + + </div> + + <div class="panel-body"> + + <moon-meta-data-edit meta-rule="list.metaRule" meta-data-type="list.typeOfObject"></moon-meta-data-edit> + + </div> + + </div> + + <div class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.model.metadata.action.title">List associated of Action Categories</h4> + + </div> + + <div class="panel-body"> + + <div class="table-responsive"> + + <table class="table table-striped"> + + <thead> + <tr> + <th data-translate="moon.model.metadata.table.id">Id</th> + <th data-translate="moon.model.metadata.table.name">Name</th> + <th data-translate="moon.model.metadata.table.description">Description</th> + <th ng-if="list.editMode" data-translate="moon.model.metadata.table.action.title"></th> + </tr> + </thead> + + <moon-loader ng-if="list.loadingCatAct"></moon-loader> + + <tbody ng-if="!list.loadingCatAct && list.catAct.length > 0"> + <tr ng-repeat="(key, value) in list.catAct"> + <td ng-bind="value.id"></td> + <td ng-bind="value.name"></td> + <td ng-bind="value.description"></td> + <td ng-if="list.editMode"> + + <a href="" ng-if="!value.loader" ng-click="list.unMapAct(value)"> + <span class="glyphicon glyphicon-transfer"></span> + <span class="control-label" data-translate="moon.model.metadata.action.remove">Remove</span> + </a> + + <!--<div ng-if="!value.loader" class="dropdown"> + + <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown"> + <span data-translate="moon.model.metadata.table.action.title">Actions</span> + <span class="caret"></span> + </button> + + <ul class="dropdown-menu"> + + <li> + <a href="" ng-click="list.unMapAct(value)" > + <span class="glyphicon glyphicon-transfer"></span> + <span class="control-label" data-translate="moon.model.metadata.action.remove">Remove</span> + </a> + </li> + + <li class="divider"></li> + + <li> + <a href="" ng-click="list.deleteAct(value)"> + <span class="glyphicon glyphicon-trash"></span> + <span class="control-label" data-translate="moon.model.metadata.table.action.delete">Delete</span> + </a> + </li> + + </ul> + + </div>--> + + <div ng-if="value.loader"> + + <moon-loader></moon-loader> + + </div> + + </td> + </tr> + </tbody> + + <tbody ng-if="!list.loadingCatAct && list.catAct.length === 0"> + <tr> + <td data-translate="moon.model.metadata.action.notFound">There is no Actions</td> + <td></td> + <td></td> + <td ng-if="list.editMode"></td> + </tr> + </tbody> + + </table> + + </div> + + </div> + + </div> + + <div ng-if="list.editMode" class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.model.metadata.action.add.title">Add an Action Category</h4> + + </div> + + <div class="panel-body">. + + <moon-meta-data-edit meta-rule="list.metaRule" meta-data-type="list.typeOfAction"></moon-meta-data-edit> + + </div> + + </div> + + </div> + + <!-- + !shortDisplay allow to display less details than shortDisplay. + It will display 3 panels on the same row, each panels have a table with on columns (name) + --> + <div ng-if="list.shortDisplay"> + + <div class="row"> + + <div class="col-md-4"> + + <div class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.model.metadata.subject.title">List of associated Subject Categories</h4> + + </div> + + <div class="panel-body"> + + <div class="table-responsive"> + + <table class="table table-striped"> + + <thead> + <tr> + <th data-translate="moon.model.metadata.table.name">Name</th> + </tr> + </thead> + + <moon-loader ng-if="list.loadingCatSub"></moon-loader> + + <tbody ng-if="!list.loadingCatSub && list.getSubjectCategories().length > 0"> + <tr ng-repeat="(key, value) in list.catSub"> + <td ng-bind="value.name"></td> + </tr> + </tbody> + + + <tbody ng-if="!list.loadingCatSub && list.catSub.length === 0"> + <tr> + <td data-translate="moon.model.metadata.subject.notFound">There is no Subjects</td> + </tr> + </tbody> + + </table> + + </div> + + </div> + + </div> + + </div> + + <div class="col-md-4"> + + <div class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.model.metadata.object.title">List associated of Object Categories</h4> + + </div> + + <div class="panel-body"> + + <div class="table-responsive"> + + <table class="table table-striped"> + + <thead> + <tr> + <th data-translate="moon.model.metadata.table.name">Name</th> + </tr> + </thead> + + <moon-loader ng-if="list.loadingCatObj"></moon-loader> + + <tbody ng-if="!list.loadingCatObj && list.catObj.length > 0"> + <tr ng-repeat="(key, value) in list.catObj"> + <td ng-bind="value.name"></td> + </tr> + </tbody> + + <tbody ng-if="!list.loadingCatObj && list.catObj.length === 0"> + <tr> + <td data-translate="moon.model.metadata.object.notFound">There is no Objects</td> + </tr> + </tbody> + + </table> + + </div> + + </div> + + </div> + + </div> + + <div class="col-md-4"> + + <div class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.model.metadata.action.title">List associated of Action Categories</h4> + + </div> + + <div class="panel-body"> + + <div class="table-responsive"> + + <table class="table table-striped"> + + <thead> + <tr> + <th data-translate="moon.model.metadata.table.name">Name</th> + </tr> + </thead> + + <moon-loader ng-if="list.loadingCatAct"></moon-loader> + + <tbody ng-if="!list.loadingCatAct && list.catAct.length > 0"> + <tr ng-repeat="(key, value) in list.catAct"> + <td ng-bind="value.name"></td> + </tr> + </tbody> + + <tbody ng-if="!list.loadingCatAct && list.catAct.length === 0"> + <tr> + <td data-translate="moon.model.metadata.action.notFound">There is no Actions</td> + </tr> + </tbody> + + </table> + + </div> + + </div> + + </div> + + </div> + + </div> + </div> +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/model/edit/metadata/metadata.edit.dir.js b/moon_gui/static/app/model/edit/metadata/metadata.edit.dir.js new file mode 100755 index 00000000..10df83b0 --- /dev/null +++ b/moon_gui/static/app/model/edit/metadata/metadata.edit.dir.js @@ -0,0 +1,332 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .directive('moonMetaDataEdit', moonMetaDataEdit); + + moonMetaDataEdit.$inject = []; + + function moonMetaDataEdit() { + + return { + templateUrl : 'html/model/edit/metadata/metadata-edit.tpl.html', + bindToController : true, + controller : moonMetaDataEditController, + controllerAs : 'edit', + scope : { + //Type can be 'ACTION', 'OBJECT', 'SUBJECT' + metaDataType: '=', + metaRule : '=' + }, + restrict : 'E', + replace : true + }; + } + + angular + .module('moon') + .controller('moonMetaDataEditController', moonMetaDataEditController); + + moonMetaDataEditController.$inject = ['$scope', 'metaDataService', 'META_DATA_CST', 'alertService', + '$translate', 'formService', 'metaRuleService', 'utilService']; + + function moonMetaDataEditController($scope, metaDataService, META_DATA_CST, alertService, + $translate, formService, metaRuleService, utilService) { + + var edit = this; + + edit.metaDataType = $scope.edit.metaDataType; + edit.metaRule = $scope.edit.metaRule; + + edit.fromList = true; + + edit.laoading = false; + + edit.form = {}; + + edit.metaData = { name: null, description: null}; + + edit.list = []; + + edit.create = createMetaData; + edit.addToMetaRule = addToMetaRule; + edit.deleteMetaData = deleteMetaData; + + activate(); + + /* + * + */ + + function activate(){ + + switch(edit.metaDataType){ + + case META_DATA_CST.TYPE.SUBJECT: + + metaDataService.subject.findAllWithCallback(callBackList); + break; + + case META_DATA_CST.TYPE.OBJECT: + + metaDataService.object.findAllWithCallback(callBackList); + break; + + case META_DATA_CST.TYPE.ACTION: + + metaDataService.action.findAllWithCallback(callBackList); + break; + + default : + + edit.list = []; + break; + + } + + function callBackList(list){ + + edit.list = list; + + } + + } + + /** + * Add + */ + + function addToMetaRule(){ + + if(!edit.selectedMetaData){ + + return; + + } + + var metaRuleToSend = edit.metaRule; + + switch(edit.metaDataType){ + + case META_DATA_CST.TYPE.SUBJECT: + + metaRuleToSend.subject_categories.push(edit.selectedMetaData.id); + break; + + case META_DATA_CST.TYPE.OBJECT: + + metaRuleToSend.object_categories.push(edit.selectedMetaData.id); + break; + + case META_DATA_CST.TYPE.ACTION: + + metaRuleToSend.action_categories.push(edit.selectedMetaData.id); + break; + } + + metaRuleService.update(metaRuleToSend, updateMetaRuleSuccess, updateMetaRuleError); + + function updateMetaRuleSuccess(data){ + + $translate('moon.model.metarules.update.success', { metaRuleName: metaRuleToSend.name }).then( function(translatedValue) { + + alertService.alertSuccess(translatedValue); + + }); + + metaRuleToSend = utilService.transformOne(data, 'meta_rules'); + + $scope.$emit('event:updateMetaRuleFromMetaDataAddSuccess', metaRuleToSend); + + stopLoading(); + + } + + function updateMetaRuleError(reason){ + + $translate('moon.model.metarules.update.error', { metaRuleName: metaRuleToSend.name, reason: reason.message}).then( function(translatedValue) { + + alertService.alertError(translatedValue); + + }); + + stopLoading(); + + } + + } + + /** + * Create + */ + + function createMetaData() { + + if(formService.isInvalid(edit.form)) { + + formService.checkFieldsValidity(edit.form); + + } else { + + startLoading(); + + var metaDataToSend = angular.copy(edit.metaData); + + switch(edit.metaDataType){ + + case META_DATA_CST.TYPE.SUBJECT: + + metaDataService.subject.add(metaDataToSend, createSuccess, createError); + break; + + case META_DATA_CST.TYPE.OBJECT: + + metaDataService.object.add(metaDataToSend, createSuccess, createError); + break; + + case META_DATA_CST.TYPE.ACTION: + + metaDataService.action.add(metaDataToSend, createSuccess, createError); + break; + } + + } + + function createSuccess(data) { + + var created = {}; + + switch(edit.metaDataType){ + + case META_DATA_CST.TYPE.SUBJECT: + + created = utilService.transformOne(data, 'subject_categories'); + break; + + case META_DATA_CST.TYPE.OBJECT: + + created = utilService.transformOne(data, 'object_categories'); + break; + + case META_DATA_CST.TYPE.ACTION: + + created = utilService.transformOne(data, 'action_categories'); + break; + } + + $translate('moon.model.metadata.edit.create.success', { name: created.name }).then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + stopLoading(); + + edit.list.push(created); + + displayList(); + + } + + function createError(reason) { + + $translate('moon.model.metadata.edit.create.error', { name: metaDataToSend.name }).then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + stopLoading(); + + } + + } + + function deleteMetaData(){ + + if(!edit.selectedMetaData){ + + return; + + } + + startLoading(); + + var metaDataToDelete = angular.copy(edit.selectedMetaData); + + switch(edit.metaDataType){ + case META_DATA_CST.TYPE.SUBJECT: + + metaDataService.subject.delete(metaDataToDelete, deleteSuccess, deleteError); + break; + + case META_DATA_CST.TYPE.OBJECT: + + metaDataService.object.delete(metaDataToDelete, deleteSuccess, deleteError); + break; + + case META_DATA_CST.TYPE.ACTION: + + metaDataService.action.delete(metaDataToDelete, deleteSuccess, deleteError); + break; + } + + + function deleteSuccess(data) { + + $translate('moon.model.metadata.edit.delete.success', { name: metaDataToDelete.name }).then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + metaRuleService.findOneWithMetaData(edit.metaRule.id).then( function(metaRule){ + + edit.metaRule = metaRule; + + cleanSelectedValue(); + + activate(); + + stopLoading(); + + $scope.$emit('event:deleteMetaDataFromMetaDataAddSuccess', edit.metaRule); + + }); + + } + + function deleteError(reason) { + + $translate('moon.model.metadata.edit.delete.error', { name: metaDataToDelete.name }).then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + stopLoading(); + + } + } + + function cleanSelectedValue(){ + + delete edit.selectedMetaData; + + } + + function startLoading(){ + + edit.loading = true; + + } + + function stopLoading(){ + + edit.loading = false; + + } + + function displayList(){ + + edit.fromList = true; + + } + + } + +})();
\ No newline at end of file diff --git a/moon_gui/static/app/model/edit/metadata/metadata.list.dir.js b/moon_gui/static/app/model/edit/metadata/metadata.list.dir.js new file mode 100755 index 00000000..beb2ed86 --- /dev/null +++ b/moon_gui/static/app/model/edit/metadata/metadata.list.dir.js @@ -0,0 +1,372 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .directive('moonMetaDataList', moonMetaDataList); + + moonMetaDataList.$inject = []; + + function moonMetaDataList() { + + return { + templateUrl : 'html/model/edit/metadata/metadata-list.tpl.html', + bindToController : true, + controller : moonMetaDataListController, + controllerAs : 'list', + scope : { + metaRule: '=', + editMode: '=', + // shortDisplay : boolean value + shortDisplay: '=' + }, + restrict : 'E', + replace : true + }; + } + + angular + .module('moon') + .controller('moonMetaDataListController', moonMetaDataListController); + + moonMetaDataListController.$inject = ['$scope', '$rootScope', 'metaDataService', '$translate', 'alertService', 'metaRuleService', 'META_DATA_CST', 'utilService']; + + function moonMetaDataListController($scope, $rootScope, metaDataService, $translate, alertService, metaRuleService, META_DATA_CST, utilService){ + + var list = this; + + list.metaRule = $scope.list.metaRule; + list.editMode = $scope.list.editMode; + list.shortDisplay = $scope.list.shortDisplay; + + list.typeOfSubject = META_DATA_CST.TYPE.SUBJECT; + list.typeOfObject = META_DATA_CST.TYPE.OBJECT; + list.typeOfAction = META_DATA_CST.TYPE.ACTION; + + list.unMapSub = unMapSub; + list.unMapObj = unMapObj; + list.unMapAct = unMapAct; + + // list.deleteSub = deleteSub; + // list.deleteObj = deleteObj; + // list.deleteAct = deleteAct; + + list.getSubjectCategories = getSubjectCategories; + list.getObjectCategories = getObjectCategories; + list.getActionCategories = getActionCategories; + + activate(); + + function activate(){ + + manageSubjectCategories(); + + manageObjectCategories(); + + manageActionCategories(); + + } + + var rootListeners = { + + 'event:updateMetaRuleFromMetaDataAddSuccess': $rootScope.$on('event:updateMetaRuleFromMetaDataAddSuccess', updateMetaRuleCategories), + + 'event:deleteMetaDataFromMetaDataAddSuccess': $rootScope.$on('event:deleteMetaDataFromMetaDataAddSuccess', deleteMetaRuleCategories) + + }; + + for (var unbind in rootListeners) { + $scope.$on('$destroy', rootListeners[unbind]); + } + + + function manageSubjectCategories(){ + + list.loadingCatSub = true; + + metaDataService.subject.findSomeWithCallback(list.metaRule.subject_categories, function(categories){ + + list.catSub = categories; + list.loadingCatSub = false; + + }); + } + + function manageObjectCategories(){ + + list.loadingCatObj = true; + + metaDataService.object.findSomeWithCallback(list.metaRule.object_categories, function(categories){ + + list.catObj = categories; + list.loadingCatObj = false; + + }); + + } + + function manageActionCategories(){ + + list.loadingCatAct = true; + + metaDataService.action.findSomeWithCallback(list.metaRule.action_categories, function(categories){ + + list.catAct = categories; + list.loadingCatAct = false; + + }); + + } + + + /** + * UnMap + */ + + function unMapSub(subject){ + + subject.loader = true; + + var metaRuleToSend = angular.copy(list.metaRule); + + metaRuleToSend.subject_categories = _.without(metaRuleToSend.subject_categories, subject.id); + + metaRuleService.update(metaRuleToSend, updateMetaRuleSuccess, updateMetaRuleError); + + function updateMetaRuleSuccess(data){ + + $translate('moon.model.metarules.update.success', { metaRuleName: list.metaRule.name }).then( function(translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + list.metaRule = metaRuleService.findMetaDataFromMetaRule(utilService.transformOne(data, 'meta_rules')); + + activate(); + + subject.loader = false; + + } + + function updateMetaRuleError(reason){ + + $translate('moon.model.metarules.update.error', { metaRuleName: list.metaRule.name, reason: reason.message}).then( function(translatedValue) { + alertService.alertError(translatedValue); + }); + + subject.loader = false; + + } + + } + + function unMapObj(object){ + + object.loader = true; + + var metaRuleToSend = angular.copy(list.metaRule); + + metaRuleToSend.object_categories = _.without(metaRuleToSend.object_categories, object.id); + + metaRuleService.update(metaRuleToSend, updateMetaRuleSuccess, updateMetaRuleError); + + function updateMetaRuleSuccess(data){ + + $translate('moon.model.metarules.update.success', { metaRuleName: list.metaRule.name }).then( function(translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + list.metaRule = metaRuleService.findMetaDataFromMetaRule(utilService.transformOne(data, 'meta_rules')); + + activate(); + + object.loader = false; + + } + + function updateMetaRuleError(reason){ + + $translate('moon.model.metarules.update.error', { metaRuleName: list.metaRule.name, reason: reason.message}).then( function(translatedValue) { + alertService.alertError(translatedValue); + }); + + object.loader = false; + + } + + } + + function unMapAct(action){ + + action.loader = true; + + var metaRuleToSend = angular.copy(list.metaRule); + + metaRuleToSend.action_categories = _.without(metaRuleToSend.action_categories, action.id); + + metaRuleService.update(metaRuleToSend, updateMetaRuleSuccess, updateMetaRuleError); + + function updateMetaRuleSuccess(data){ + + $translate('moon.model.metarules.update.success', { metaRuleName: list.metaRule.name }).then( function(translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + list.metaRule = metaRuleService.findMetaDataFromMetaRule(utilService.transformOne(data, 'meta_rules')); + + activate(); + + action.loader = false; + + } + + function updateMetaRuleError(reason){ + + $translate('moon.model.metarules.update.error', { metaRuleName: list.metaRule.name, reason: reason.message}).then( function(translatedValue) { + alertService.alertError(translatedValue); + }); + + action.loader = false; + + } + + } + + // /** + // * Delete + // */ + // + // function deleteSub(subject){ + // + // subject.loader = true; + // + // metaDataService.subject.delete(subject, deleteSubSuccess, deleteSubError); + // + // function deleteSubSuccess(data){ + // + // $translate('moon.model.metadata.subject.delete.success', { subjectName: subject.name }).then( function(translatedValue) { + // alertService.alertSuccess(translatedValue); + // }); + // + // removeSubFromSubList(subject); + // + // subject.loader = false; + // + // } + // + // function deleteSubError(reason){ + // + // $translate('moon.model.metadata.subject.delete.error', + // { subjectName: subject.name, reason: reason.message}).then( function(translatedValue) { + // alertService.alertError(translatedValue); + // }); + // + // subject.loader = false; + // + // } + // } + // + // function deleteObj(object){ + // + // object.loader = true; + // + // metaDataService.object.delete(object, deleteObjSuccess, deleteObjError); + // + // function deleteObjSuccess(data){ + // + // $translate('moon.model.metadata.object.delete.success', { objectName: object.name }).then( function(translatedValue) { + // alertService.alertSuccess(translatedValue); + // }); + // + // removeObjFromObjList(object); + // /*list.catSub = metaDataService.subject.findSome(list.metaRule.subject_categories); + // list.catObj = metaDataService.object.findSome(list.metaRule.object_categories); + // list.catAct = metaDataService.action.findSome(list.metaRule.action_categories);*/ + // + // object.loader = false; + // + // } + // + // function deleteObjError(reason){ + // + // $translate('moon.model.metadata.object.delete.error', { objectName: object.name, reason: reason.message}).then( function(translatedValue) { + // alertService.alertError(translatedValue); + // }); + // + // object.loader = false; + // } + // } + // + // function deleteAct(action){ + // + // action.loader = true; + // + // metaDataService.action.delete(action, deleteActSuccess, deleteActError); + // + // function deleteActSuccess(data){ + // + // $translate('moon.model.metadata.action.delete.success', { actionName: action.name }).then( function(translatedValue) { + // alertService.alertSuccess(translatedValue); + // }); + // + // removeActFromActList(action); + // + // action.loader = false; + // + // } + // + // function deleteActError(reason){ + // + // $translate('moon.model.metadata.action.delete.error', { actionName: action.name, reason: reason.message}).then( function(translatedValue) { + // alertService.alertError(translatedValue); + // }); + // + // action.loader = false; + // + // } + // } + + function getSubjectCategories(){ + return list.catSub ? list.catSub : []; + } + + function getObjectCategories(){ + return list.catObj ? list.catObj : []; + } + + function getActionCategories(){ + return list.catAct ? list.catAct : []; + } + + // function removeSubFromSubList(subject){ + // list.catSub = _.without(list.catSub, subject); + // } + // + // function removeObjFromObjList(object){ + // list.catObj = _.without(list.catObj, object); + // } + // + // function removeActFromActList(action){ + // list.catAct = _.without(list.catAct, action); + // } + + function updateMetaRuleCategories( event, metaRule){ + + list.metaRule = metaRule; + + activate(); + + } + + + function deleteMetaRuleCategories( event, metaRule){ + + list.metaRule = metaRule; + + activate(); + + } + + } + +})();
\ No newline at end of file diff --git a/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-add.tpl.html b/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-add.tpl.html new file mode 100755 index 00000000..a721e6d0 --- /dev/null +++ b/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-add.tpl.html @@ -0,0 +1,50 @@ +<div class="row"> + + <form class="form-horizontal" role="form" name="add.form"> + + <div class="form-group" ng-class="{'has-error': add.form.name.$invalid && add.form.name.$dirty}"> + + <label for="name" class="col-sm-3 control-label" data-translate="moon.model.metarules.add.form.name">Name</label> + + <div class="col-sm-6"> + + <input name="name" id="name" class="form-control" type="text" data-ng-model="add.metaRule.name" required /> + + <div class="help-block" ng-show="add.form.name.$dirty && add.form.name.$invalid"> + <small class="error" ng-show="add.form.name.$error.required" data-translate="moon.model.metarules.add.check.name.required">Name is required</small> + </div> + + </div> + </div> + + <div class="form-group"> + + <label for="description" class="col-sm-3 control-label" data-translate="moon.model.metarules.add.form.description">Description</label> + <div class="col-sm-6"> + <textarea id="description" name="description" class="form-control" data-ng-model="add.metaRule.description"></textarea> + </div> + + </div> + + + <div class="form-group"> + + <div class="col-sm-8"> + + <div class="pull-right"> + + <a href="" ng-disabled="add.loading" ng-click="add.create()" class="btn btn-warning"> + <span class="glyphicon glyphicon-save"></span> + <span data-translate="moon.model.metarules.add.action.create">Create</span> + </a> + + <moon-loader ng-if="add.loading"></moon-loader> + + </div> + + </div> + + </div> + </form> + +</div> diff --git a/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-map.tpl.html b/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-map.tpl.html new file mode 100755 index 00000000..1830204b --- /dev/null +++ b/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-map.tpl.html @@ -0,0 +1,102 @@ +<div ng-controller="moonMetaRulesMapController as map" class="modal" tabindex="-1" data-role="MapMetaRules"> + + <div class="modal-dialog"> + + <div class="modal-content"> + + <div class="modal-header"> + + <button type="button" class="close" ng-click="$hide()">×</button> + <h4 class="modal-title" data-translate="moon.model.metarules.map.title"></h4> + + </div> + + <div class="modal-body"> + + <div class="row"> + + <div class="col-sm-3"> + + <button class="btn btn-primary" style="white-space: normal;" ng-click="map.addMetaRuleToList = !map.addMetaRuleToList"> + + <span ng-if="!map.addMetaRuleToList" data-translate="moon.model.metarules.map.action.new">Add a new Meta Rule</span> + <span ng-if="map.addMetaRuleToList" data-translate="moon.model.metarules.map.action.list">List of Meta Rules</span> + + </button> + + </div> + + <div class="col-sm-9"> + + <form class="form-horizontal" role="form" name="map.form"> + + <div class="form-group" ng-if="!map.addMetaRuleToList"> + + <label class="col-sm-3 control-label" data-translate="moon.model.metarules.map.form.list">List of Meta Rule</label> + + <div class="col-sm-9"> + + <ui-select ng-model="map.selectedMetaRule" name="object"> + + <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match> + <ui-select-choices repeat="ametaRule in map.metaRules"> + <div ng-value="ametaRule" ng-bind="ametaRule.name"></div> + </ui-select-choices> + + </ui-select> + + </div> + + </div> + + <div class="form-group" ng-if="!map.addMetaRuleToList"> + + <moon-loader ng-if="map.metaRulesLoading || map.mappingLoading" ></moon-loader> + + <div class="col-sm-5"> + <a href="" ng-disabled="map.metaRulesLoading || map.mappingLoading || !map.selectedMetaRule" ng-click="map.deleteMetaRule()" class="btn btn-warning" style="white-space: normal;"> + <span class="glyphicon glyphicon-trash"></span> + <span data-translate="moon.model.metarules.map.action.delete">Delete the selected Meta Rule</span> + </a> + </div> + + <div class="col-sm-5 col-sm-offset-2"> + <a href="" ng-disabled="map.metaRulesLoading || map.mappingLoading || !map.selectedMetaRule" ng-click="map.mapToModel()" class="btn btn-warning" style="white-space: normal;"> + <span class="glyphicon glyphicon-link"></span> + <span data-translate="moon.model.metarules.map.action.add">Add the selected Meta Rule</span> + </a> + </div> + + </div> + + <div class="form-group" ng-if="map.addMetaRuleToList"> + + <moon-meta-rules-add></moon-meta-rules-add> + + </div> + + </form> + + </div> + + </div> + + </div> + + <div class="modal-footer"> + + <div class="btn-toolbar" style="float: right;"> + + <a href="" ng-click="$hide()" class="btn btn-default"> + <span data-translate="moon.model.metarules.add.action.cancel">Cancel</span> + </a> + + </div> + + </div> + + </div> + + </div> + +</div> diff --git a/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-unmap.tpl.html b/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-unmap.tpl.html new file mode 100755 index 00000000..bb02aba2 --- /dev/null +++ b/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-unmap.tpl.html @@ -0,0 +1,35 @@ +<div ng-controller="MetaRulesUnMapController as unmap" class="modal" tabindex="-1" data-role="modalUnMapMetaRule"> + + <div class="modal-dialog"> + + <div class="modal-content"> + + <div class="modal-header"> + <button type="button" class="close" ng-click="$hide()">×</button> + <h4 class="modal-title" data-translate="moon.model.metarules.unmap.title"></h4> + </div> + + <div class="modal-body"> + <span data-translate="moon.model.metarules.unmap.content" data-translate-values="{ modelName: unmap.model.name, metaRuleName: unmap.metaRule.name }"></span> + </div> + + <div class="modal-footer"> + + <div class="btn-toolbar" style="float: right;"> + <a href="" ng-click="$hide()" class="btn btn-default"> + <span data-translate="moon.model.metarules.unmap.action.cancel">Cancel</span> + </a> + <a href="" ng-disabled="unmap.unMappingLoading" ng-click="unmap.unmap()" class="btn btn-warning"> + <span class="glyphicon glyphicon-transfer"></span> + <span data-translate="moon.model.metarules.unmap.action.unmap">Unmap</span> + </a> + <moon-loader ng-if="unmap.unMappingLoading" ></moon-loader> + </div> + + </div> + + </div> + + </div> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.controller.add.js b/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.controller.add.js new file mode 100755 index 00000000..a95951fa --- /dev/null +++ b/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.controller.add.js @@ -0,0 +1,99 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .directive('moonMetaRulesAdd', moonMetaRulesAdd); + + moonMetaRulesAdd.$inject = []; + + function moonMetaRulesAdd() { + + return { + templateUrl : 'html/model/edit/metarules/action/mapping/metarules-add.tpl.html', + bindToController : true, + controller : moonMetaRulesAddController, + controllerAs : 'add', + scope : { + metaRules : '=' + }, + restrict : 'E', + replace : true + }; + } + + + angular + .module('moon') + .controller('moonMetaRulesAddController', moonMetaRulesAddController); + + moonMetaRulesAddController.$inject = ['$scope', 'metaRuleService', 'alertService', '$translate', 'formService', 'utilService']; + + function moonMetaRulesAddController($scope, metaRuleService, alertService, $translate, formService, utilService) { + + var add = this; + + /* + * + */ + + add.laoading = false; + + add.form = {}; + + add.metaRule = { name: null, description: null, subject_categories : [], object_categories : [], action_categories : [] }; + + add.create = createMetaRule; + + activate(); + + function activate(){ + + } + + function createMetaRule() { + + if(formService.isInvalid(add.form)) { + + formService.checkFieldsValidity(add.form); + + } else { + + add.loading = true; + + metaRuleService.data.create({}, add.metaRule, createSuccess, createError); + + } + + function createSuccess(data) { + + var createdMetaRule = utilService.transformOne(data, 'meta_rules'); + + $translate('moon.model.metarules.add.success', { metaRuleName: createdMetaRule.name }).then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + add.loading = false; + + $scope.$emit('event:metaRuleCreatedSuccess', createdMetaRule); + + } + + function createError(reason) { + + $translate('moon.model.metarules.add.error', { metaRuleName: add.metaRule.name }).then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + add.loading = false; + + $scope.$emit('event:metaRuleCreatedError', add.project); + + } + + } + + } + +})(); diff --git a/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.map.controller.js b/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.map.controller.js new file mode 100755 index 00000000..cf9ba06c --- /dev/null +++ b/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.map.controller.js @@ -0,0 +1,213 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('moonMetaRulesMapController', moonMetaRulesMapController); + + moonMetaRulesMapController.$inject = ['$scope', '$rootScope', 'alertService', '$translate', 'formService', 'metaRuleService', 'modelService', 'utilService']; + + function moonMetaRulesMapController($scope, $rootScope, alertService, $translate, formService, metaRuleService, modelService, utilService ) { + + var map = this; + + /* + * + */ + + map.metaRules = []; + + map.model = $scope.model; + + map.addMetaRuleToList = false; + + map.mapToModel = mapToModel; + + map.deleteMetaRule = deleteMetaRule; + + activate(); + + function activate() { + + resolveMetaRules(); + + } + + /* + * ---- events + */ + var rootListeners = { + + 'event:metaRuleCreatedSuccess': $rootScope.$on('event:metaRuleCreatedSuccess', metaRuleCreatedSuccess), + 'event:metaRuleCreatedError': $rootScope.$on('event:metaRuleCreatedError', metaRuleCreatedError) + + }; + + for (var unbind in rootListeners) { + $scope.$on('$destroy', rootListeners[unbind]); + } + + + /* + * + */ + + function resolveMetaRules() { + + map.metaRulesLoading = true; + + metaRuleService.findAllWithCallback( + function(metaRules){ + map.metaRules = metaRules; + map.metaRulesLoading = false; + } + ); + + } + + function mapToModel() { + + if (formService.isInvalid(map.form)) { + + formService.checkFieldsValidity(map.form); + + } else { + + map.mappingLoading = true; + + var modelToSend = angular.copy(map.model); + + modelToSend.meta_rules.push(map.selectedMetaRule.id); + + modelService.update(modelToSend, mapSuccess, mapError); + + } + + function mapSuccess(data) { + + var modelReceived = utilService.transformOne(data, 'models'); + + metaRuleService.findSomeWithMetaData(modelReceived.meta_rules).then(function(metaRules){ + + modelReceived.meta_rules_values = metaRules; + + $translate('moon.model.metarules.map.success', { + + modelName: modelReceived.name, + metaRuleName: map.selectedMetaRule.name + + }).then(function (translatedValue) { + + alertService.alertSuccess(translatedValue); + + }); + + map.mappingLoading = false; + + $scope.$emit('event:metaRuleMapToModelSuccess', modelReceived); + + }); + + } + + function mapError(response) { + + $translate('moon.model.metarules.map.error', { + + modelName: map.model.name, + metaRuleName: map.selectedMetaRule.name + + }).then(function (translatedValue) { + + alertService.alertError(translatedValue); + + }); + + map.mappingLoading = false; + + } + } + + function cleanSelectedValue(){ + + delete map.selectedMetaRule; + + } + + + function deleteMetaRule(){ + + if(!map.selectedMetaRule){ + + return; + + } + + map.mappingLoading = true; + + var metaRuleTodelete = angular.copy(map.selectedMetaRule); + + metaRuleService.delete(metaRuleTodelete, deleteSuccess, deleteError); + + function deleteSuccess(data) { + + $translate('moon.model.metarules.delete.success', { metaRuleName: metaRuleTodelete.name }).then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + cleanSelectedValue(); + + map.mappingLoading = false; + + resolveMetaRules(); + + // later this event will have to be catch, because the model can use the deleted MetaRule + $scope.$emit('event:deleteMetaRule', metaRuleTodelete); + + } + + function deleteError(reason) { + + $translate('moon.model.metarules.delete.error', { metaRuleName: metaRuleTodelete.name }).then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + map.mappingLoading = false; + + } + } + + + + + + + /** + * This function will add a metaRule to the current list of metaRules + * @param event + * @param metaRule {...} metaRule to add + */ + function metaRuleCreatedSuccess(event, metaRule) { + + map.metaRules.push(metaRule); + showList(); + + } + + /** + * This function hide the add MetaRule Modal + * @param event + */ + function metaRuleCreatedError(event) { + + } + + function showList(){ + map.addMetaRuleToList = false; + } + + } + + +})();
\ No newline at end of file diff --git a/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.unmap.controller.js b/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.unmap.controller.js new file mode 100755 index 00000000..30f32d51 --- /dev/null +++ b/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.unmap.controller.js @@ -0,0 +1,74 @@ +/** + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('MetaRulesUnMapController', MetaRulesUnMapController); + + MetaRulesUnMapController.$inject = ['$scope', '$translate', 'alertService', 'modelService']; + + function MetaRulesUnMapController($scope, $translate, alertService, modelService) { + + var unmap = this; + + /* + * + */ + + unmap.model = $scope.model; + unmap.metaRule = $scope.metaRule; + + unmap.unMappingLoading = false; + + unmap.unmap = unMapModelToMetaRule; + + /* + * + */ + + function unMapModelToMetaRule() { + + unmap.unMappingLoading = true; + + var modelToUpdate = angular.copy(unmap.model); + + modelToUpdate.meta_rules = _.without(modelToUpdate.meta_rules, unmap.metaRule.id); + + modelService.update(modelToUpdate, unMapSuccess, unMapError); + + function unMapSuccess(data) { + + $translate('moon.model.metarules.unmap.success', { modelName: unmap.model.name, metaRuleName: unmap.metaRule.name }) + .then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + unmap.unMappingLoading = false; + + $scope.$emit('event:metaRuleUnMappedToModelSuccess', modelToUpdate); + + } + + function unMapError(reason) { + + $translate('moon.model.metarules.unmap.error', { modelName: unmap.model.name, metaRuleName: unmap.metaRule.name }) + .then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + unmap.unMappingLoading = false; + + $scope.$emit('event:metaRuleUnMappedToModelError'); + + } + + } + + } + +})(); diff --git a/moon_gui/static/app/model/edit/metarules/action/metarules-edit-basic.tpl.html b/moon_gui/static/app/model/edit/metarules/action/metarules-edit-basic.tpl.html new file mode 100755 index 00000000..b6136195 --- /dev/null +++ b/moon_gui/static/app/model/edit/metarules/action/metarules-edit-basic.tpl.html @@ -0,0 +1,67 @@ +<div class="row"> + + <form class="form-horizontal" role="form" name="edit.form"> + + <div class="form-group"> + + <label for="id" class="col-sm-3 control-label" data-translate="moon.model.metarules.edit.basic.form.id">Id</label> + + <div class="col-sm-6"> + + <input name="id" id="id" disabled class="form-control" type="text" data-ng-model="edit.metaRuleToEdit.id" required /> + + </div> + + </div> + + <div class="form-group" ng-class="{'has-error': edit.form.name.$invalid && edit.form.name.$dirty}"> + + <label for="name" class="col-sm-3 control-label" data-translate="moon.model.metarules.edit.basic.form.name">Name</label> + + <div class="col-sm-6"> + + <input name="name" id="name" class="form-control" type="text" data-ng-model="edit.metaRuleToEdit.name" required /> + + <div class="help-block" ng-show="edit.form.name.$dirty && edit.form.name.$invalid"> + <small class="error" ng-show="edit.form.name.$error.required" data-translate="moon.model.metarules.edit.basic.check.name.required">Name is required</small> + </div> + + </div> + + </div> + + <div class="form-group"> + + <label for="description" class="col-sm-3 control-label" data-translate="moon.model.metarules.edit.basic.form.description">Description</label> + <div class="col-sm-6"> + <textarea id="description" name="description" class="form-control" data-ng-model="edit.metaRuleToEdit.description"></textarea> + </div> + + </div> + + <div class="form-group"> + + <div class="col-sm-2 col-sm-offset-3"> + + <a href="" ng-disabled="edit.loading" ng-click="edit.init()" class="btn btn-default"> + <span data-translate="moon.model.metarules.edit.basic.action.init">Init</span> + </a> + + </div> + + <div class="col-sm-4 col-sm-offset-2"> + + <a href="" ng-disabled="edit.loading" ng-click="edit.editMetaRule()" class="btn btn-warning"> + <span class="glyphicon glyphicon-save"></span> + <span data-translate="moon.model.metarules.edit.basic.action.update">Update</span> + </a> + + <moon-loader ng-if="edit.loading"></moon-loader> + + </div> + + </div> + + </form> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/model/edit/metarules/action/metarules-edit.tpl.html b/moon_gui/static/app/model/edit/metarules/action/metarules-edit.tpl.html new file mode 100755 index 00000000..7b074448 --- /dev/null +++ b/moon_gui/static/app/model/edit/metarules/action/metarules-edit.tpl.html @@ -0,0 +1,62 @@ +<div ng-controller="MetaRulesEditController as edit" class="modal" tabindex="-1" data-role="modalViewProject"> + + <div class="modal-dialog"> + + <div class="modal-content"> + + <div class="modal-header"> + <button type="button" class="close" ng-click="$hide()">×</button> + <h4 class="modal-title" data-translate="moon.model.metarules.edit.title" data-translate-values="{metaRuleName: edit.metaRule.name}"></h4> + </div> + + <div class="modal-body"> + + <div class="panel panel-default"> + + <div class="panel-heading"> + + <h4> + <span data-translate="moon.model.edit.basic.title" >Basic Information</span> + <a href="" ng-click="edit.editBasic = !edit.editBasic"> + <span data-translate="moon.model.metarules.edit.update">Update</span> + <span class="glyphicon glyphicon-cog"></span> + </a> + </h4> + + </div> + + <div class="panel-body"> + + <div ng-if="edit.editBasic"> + <moon-meta-rules-edit-basic meta-rule="edit.metaRule"></moon-meta-rules-edit-basic> + </div> + + <div ng-if="!edit.editBasic"> + <dl class="dl-horizontal"> + <dt>Id</dt> + <dd ng-bind="edit.metaRule.id"></dd> + <dt>Name</dt> + <dd ng-bind="edit.metaRule.name"></dd> + <dt>Description</dt> + <dd ng-bind="edit.metaRule.description"></dd> + </dl> + </div> + </div> + + </div> + + <moon-meta-data-list edit-mode="true" meta-rule="edit.metaRule"></moon-meta-data-list> + + </div> + + <div class="modal-footer top10"> + <div class="btn-toolbar" style="float: right;"> + <button ng-click="$hide()" class="btn btn-default" data-translate="moon.model.view.action.close">Close</button> + </div> + </div> + + </div> + + </div> + +</div> diff --git a/moon_gui/static/app/model/edit/metarules/action/metarules.controller.edit.js b/moon_gui/static/app/model/edit/metarules/action/metarules.controller.edit.js new file mode 100755 index 00000000..b2ebc45d --- /dev/null +++ b/moon_gui/static/app/model/edit/metarules/action/metarules.controller.edit.js @@ -0,0 +1,49 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('MetaRulesEditController', MetaRulesEditController); + + MetaRulesEditController.$inject = ['$scope', '$rootScope']; + + function MetaRulesEditController($scope, $rootScope) { + + var edit = this; + + edit.metaRule = $scope.metaRule; + + activate(); + + function activate(){ + } + + + /* + * ---- events + */ + var rootListeners = { + + 'event:metaRuleBasicUpdatedSuccess': $rootScope.$on('event:metaRuleBasicUpdatedSuccess', metaRuleUpdatedSuccess) + + }; + + for (var unbind in rootListeners) { + $scope.$on('$destroy', rootListeners[unbind]); + } + + /** + * When the MetaRule is updated, this function refresh the current metaRule with the new changes + * @param event + * @param metaRule + */ + function metaRuleUpdatedSuccess(event, metaRule){ + + edit.metaRule = metaRule; + + } + + } + +})(); diff --git a/moon_gui/static/app/model/edit/metarules/action/metarules.edit.basic.dir.js b/moon_gui/static/app/model/edit/metarules/action/metarules.edit.basic.dir.js new file mode 100755 index 00000000..603e7a33 --- /dev/null +++ b/moon_gui/static/app/model/edit/metarules/action/metarules.edit.basic.dir.js @@ -0,0 +1,98 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .directive('moonMetaRulesEditBasic', moonMetaRulesEditBasic); + + moonMetaRulesEditBasic.$inject = []; + + function moonMetaRulesEditBasic() { + + return { + templateUrl : 'html/model/edit/metarules/action/metarules-edit-basic.tpl.html', + bindToController : true, + controller : moonMetaRulesEditBasicController, + controllerAs : 'edit', + scope : { + metaRule : '=' + }, + restrict : 'E', + replace : true + }; + + } + + angular + .module('moon') + .controller('moonMetaRulesEditBasicController', moonMetaRulesEditBasicController); + + moonMetaRulesEditBasicController.$inject = ['$scope', 'metaRuleService', 'formService', 'alertService', '$translate', 'utilService']; + + function moonMetaRulesEditBasicController($scope, metaRuleService, formService, alertService, $translate, utilService){ + + var edit = this; + + edit.editMetaRule = editMetaRule; + edit.init = init; + + edit.form = {}; + + activate(); + + function activate(){ + + edit.metaRule = $scope.edit.metaRule; + + edit.metaRuleToEdit = angular.copy(edit.metaRule); + + } + + function editMetaRule(){ + + if(formService.isInvalid(edit.form)) { + + formService.checkFieldsValidity(edit.form); + + }else{ + + edit.loading = true; + + metaRuleService.update(edit.metaRuleToEdit, updateSuccess, updateError); + + } + + function updateSuccess(data) { + + var updatedMetaRule = utilService.transformOne(data, 'meta_rules'); + + $translate('moon.model.metarules.edit.basic.success', { metaRuleName: updatedMetaRule.name }).then( function(translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + edit.loading = false; + + $scope.$emit('event:metaRuleBasicUpdatedSuccess', updatedMetaRule); + + } + + function updateError(reason) { + + $translate('moon.model.edit.basic.error', { metaRuleName: edit.metaRule.name }).then( function(translatedValue) { + alertService.alertError(translatedValue); + }); + + edit.loading = false; + + } + } + + function init(){ + + edit.metaRuleToEdit = angular.copy(edit.metaRule); + + } + } + +})(); diff --git a/moon_gui/static/app/model/edit/metarules/metarules-list.tpl.html b/moon_gui/static/app/model/edit/metarules/metarules-list.tpl.html new file mode 100755 index 00000000..ebe307c3 --- /dev/null +++ b/moon_gui/static/app/model/edit/metarules/metarules-list.tpl.html @@ -0,0 +1,138 @@ +<div> + + + <div><h4 data-translate="moon.model.metarules.title">List of Meta Rules</h4></div> + + <div class="table-responsive" data-role="table"> + <table class="table table-striped table-hover" ng-table="list.table"> + + <colgroup> + <col class="col-md-2" /> + <col class="col-md-2" /> + <col class="col-md-1" /> + <col class="col-md-1" /> + <col class="col-md-1" /> + <col class="col-md-2" /> + </colgroup> + + <thead> + + <tr> + + <th class="customTables sortable" + ng-class="{ 'sort-asc': list.table.isSortBy('name', 'asc'), 'sort-desc': list.table.isSortBy('name', 'desc') }" + ng-click="list.table.sorting('name', list.table.isSortBy('name', 'asc') ? 'desc' : 'asc')"> + <div data-translate="moon.model.metarules.table.name">Name</div> + </th> + + <th class="customTables sortable" + ng-class="{ 'sort-asc': list.table.isSortBy('description', 'asc'), 'sort-desc': list.table.isSortBy('description', 'desc') }" + ng-click="list.table.sorting('description', list.table.isSortBy('description', 'asc') ? 'desc' : 'asc')"> + <div data-translate="moon.model.metarules.table.description">Description</div> + </th> + + <th class="customTables sortable"> + <div data-translate="moon.model.metarules.table.metadata.subject.number">Number of Subjects</div> + </th> + + <th class="customTables sortable"> + <div data-translate="moon.model.metarules.table.metadata.object.number">Number of Subjects</div> + </th> + + <th class="customTables sortable"> + <div data-translate="moon.model.metarules.table.metadata.action.number">Number of Actions</div> + </th> + + <th class="customTables"> + <div data-translate="moon.model.metarules.action.title">Actions</div> + </th> + </tr> + + </thead> + + <tbody ng-if="!list.hasMetaRules()"> + <tr> + <td colspan="2"><span data-translate="moon.model.metarules.table.notFound">There is no Meta Rules</span></td> + </tr> + </tbody> + + <tbody ng-if="list.hasMetaRules()"> + + <tr ng-repeat="aMetaRules in $data | filter:list.search.find | orderBy:sort:reverse"> + <td ng-bind="aMetaRules.name"></td> + <td ng-bind="aMetaRules.description"></td> + <td ng-bind="aMetaRules.subject_categories.length"></td> + <td ng-bind="aMetaRules.object_categories.length"></td> + <td ng-bind="aMetaRules.action_categories.length"></td> + <td> + + <div ng-if="list.editMode"> + + <div ng-if="!value.loader" class="dropdown"> + + <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown"> + <span data-translate="moon.model.metadata.table.action.title">Actions</span> + <span class="caret"></span> + </button> + + <ul class="dropdown-menu"> + + <li> + <a href="" ng-click="list.unmap.showModal(aMetaRules)" > + <span class="glyphicon glyphicon-transfer"></span> + <span class="control-label" data-translate="moon.model.metarules.action.remove">Remove</span> + </a> + </li> + + <li> + <a href="" ng-click="list.edit.showModal(aMetaRules)"> + <span class="glyphicon glyphicon-cog"></span> + <span class="control-label" data-translate="moon.model.metarules.action.edit">Edit</span> + </a> + </li> + + </ul> + + </div> + + </div> + + <div ng-if="!list.editMode"> + + <a href="" ng-click="list.showDetail(aMetaRules)"> + + <span ng-if="aMetaRules.id !== list.getShowDetailValue().id"> + <span class="glyphicon glyphicon-eye-open"></span> + <span class="control-label" data-translate="moon.model.metarules.action.detail.open">Consult</span> + </span> + + <span ng-if="aMetaRules.id === list.getShowDetailValue().id"> + <span class="glyphicon glyphicon-eye-close"></span> + <span class="control-label" data-translate="moon.model.metarules.action.detail.close">Close</span> + </span> + + </a> + + </div> + + </td> + </tr> + + </tbody> + + </table> + + <div ng-if="list.showDetailValue"> + <moon-meta-data-list edit-mode="list.editMode" meta-rule="list.getShowDetailValue()"></moon-meta-data-list> + </div> + + </div> + + <div class="form-group" ng-if="list.editMode"> + <a href="" ng-click="list.map.showModal()" class="btn btn-default"> + <span class="glyphicon glyphicon-link"></span> + <span data-translate="moon.model.metarules.action.settings">Settings</span> + </a> + </div> + +</div> diff --git a/moon_gui/static/app/model/edit/metarules/metarules.list.dir.js b/moon_gui/static/app/model/edit/metarules/metarules.list.dir.js new file mode 100755 index 00000000..120b6a8b --- /dev/null +++ b/moon_gui/static/app/model/edit/metarules/metarules.list.dir.js @@ -0,0 +1,240 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .directive('moonMetaRulesList', moonMetaRulesList); + + moonMetaRulesList.$inject = []; + + function moonMetaRulesList() { + + return { + templateUrl : 'html/model/edit/metarules/metarules-list.tpl.html', + bindToController : true, + controller : moonMetaRulesListController, + controllerAs : 'list', + scope : { + // if edit and delete possibilities are displayed + // Value are True or False + editMode : '=', + mappedModel : '=' + }, + restrict : 'E', + replace : true + }; + } + + angular + .module('moon') + .controller('moonMetaRulesListController', moonMetaRulesListController); + + moonMetaRulesListController.$inject = ['$scope', '$rootScope', 'NgTableParams', '$filter', '$modal', 'metaRuleService']; + + function moonMetaRulesListController($scope, $rootScope, NgTableParams, $filter, $modal, metaRuleService ){ + + var list = this; + + list.table = {}; + + list.editMode = $scope.list.editMode; + list.model = $scope.list.mappedModel; + list.metaRules = list.model.meta_rules_values; + + list.getMetaRules = getMetaRules; + list.hasMetaRules = hasMetaRules; + list.showDetail = showDetail; + list.getSubjectList = getSubjectList; + list.getObjectList = getObjectList; + list.getActionlist = getActionlist; + list.getShowDetailValue = getShowDetailValue; + + list.showDetailValue = false; + + list.subject_list = []; + list.object_list = []; + list.action_list = []; + + list.edit = { modal: $modal({ template: 'html/model/edit/metarules/action/metarules-edit.tpl.html', show: false }), + showModal: showEditModal }; + + /*list.edit.modal.result.finally(function(){ + console.log('CATCHING'); + });*/ + + + list.map = { modal: $modal({ template: 'html/model/edit/metarules/action/mapping/metarules-map.tpl.html', show: false }), + showModal: showMapModal }; + + list.unmap = { modal: $modal({ template: 'html/model/edit/metarules/action/mapping/metarules-unmap.tpl.html', show: false }), + showModal: showUnmapModal }; + + activate(); + + function activate(){ + + newMetaRulesTable(); + + } + + /* + * ---- events + */ + var rootListeners = { + + 'event:metaRuleMapToModelSuccess': $rootScope.$on('event:metaRuleMapToModelSuccess', updateModelFromMapSuccess), + + 'event:metaRuleUnMappedToModelSuccess': $rootScope.$on('event:metaRuleUnMappedToModelSuccess', modelUnmappedSuccess), + 'event:metaRuleUnMappedToModelError': $rootScope.$on('event:metaRuleUnMappedToModelError', modelUnmappedError) + + }; + + for (var unbind in rootListeners) { + $scope.$on('$destroy', rootListeners[unbind]); + } + + + + function newMetaRulesTable() { + + list.table = new NgTableParams({ + + page: 1, // show first page + count: 10, // count per page + sorting: { + name: 'asc' // initial sorting + } + + }, { + + total: function () { return list.getMetaRules().length; }, // length of data + getData: function($defer, params) { + + var orderedData = params.sorting() ? $filter('orderBy')(list.getMetaRules(), params.orderBy()) : list.getMetaRules(); + $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count())); + + }, + $scope: { $data: {} } + + }); + + return list.table; + + } + + /** + * If the directive is not in editMode and displaying MetaData Content, if the editMode change to true, MetaData Content need to be hidden + */ + $scope.$watch('list.editMode', function(newValue, oldValue){ + list.showDetailValue = false; + }); + + function getMetaRules() { + return (list.metaRules) ? list.metaRules : []; + } + + function hasMetaRules() { + return list.getMetaRules().length > 0; + } + + function showDetail(aMetaRule){ + + if(aMetaRule.id === getShowDetailValue().id){ + + list.showDetailValue = false; + list.subject_list = []; + list.object_list = []; + list.action_list = []; + + }else{ + + list.subject_list = aMetaRule.subject_categories_values; + list.object_list = aMetaRule.object_categories_values; + list.action_list = aMetaRule.action_categories_values; + list.showDetailValue = aMetaRule; + + } + + } + + function showEditModal(aMetaRule) { + list.edit.modal.$scope.metaRule = aMetaRule; + list.edit.modal.$promise.then(list.edit.modal.show); + } + + function getShowDetailValue(){ + return list.showDetailValue; + } + + function getSubjectList(){ + return list.subject_list; + } + + function getObjectList(){ + return list.object_list; + } + + function getActionlist(){ + return list.action_list; + } + + /* + * ---- add + */ + function showMapModal() { + list.map.modal.$scope.model = list.model; + list.map.modal.$promise.then(list.map.modal.show); + } + + function refreshRules(){ + + list.metaRules = list.model.meta_rules_values; + list.table.total(list.getMetaRules().length); + list.table.reload(); + + } + + function updateModelFromMapSuccess(event, model){ + + list.model = model; + + refreshRules(); + + list.map.modal.hide(); + + } + + /* + * ---- unmap + */ + + function showUnmapModal(metaRule) { + + list.unmap.modal.$scope.model = list.model; + list.unmap.modal.$scope.metaRule = metaRule; + list.unmap.modal.$promise.then(list.unmap.modal.show); + + } + + function modelUnmappedSuccess(event, model) { + + list.model = model; + + metaRuleService.findSomeWithCallback(list.model.meta_rules, function(meta_rules){ + + list.model.meta_rules_values = meta_rules; + refreshRules(); + list.unmap.modal.hide(); + + }); + + } + + function modelUnmappedError(event) { + list.unmap.modal.hide(); + } + + } + +})(); diff --git a/moon_gui/static/app/model/edit/model-edit-basic.tpl.html b/moon_gui/static/app/model/edit/model-edit-basic.tpl.html new file mode 100755 index 00000000..bd73b4ef --- /dev/null +++ b/moon_gui/static/app/model/edit/model-edit-basic.tpl.html @@ -0,0 +1,65 @@ +<div class="row"> + + <form class="form-horizontal" role="form" name="edit.form"> + + <div class="form-group"> + + <label for="id" class="col-sm-3 control-label" data-translate="moon.model.edit.basic.form.id">Id</label> + + <div class="col-sm-6"> + + <input name="id" id="id" disabled class="form-control" type="text" data-ng-model="edit.modelToEdit.id" required /> + + </div> + + </div> + + <div class="form-group" ng-class="{'has-error': edit.form.name.$invalid && edit.form.name.$dirty}"> + + <label for="name" class="col-sm-3 control-label" data-translate="moon.model.edit.basic.form.name">Name</label> + + <div class="col-sm-6"> + + <input name="name" id="name" class="form-control" type="text" data-ng-model="edit.modelToEdit.name" required /> + + <div class="help-block" ng-show="edit.form.name.$dirty && edit.form.name.$invalid"> + <small class="error" ng-show="edit.form.name.$error.required" data-translate="moon.model.edit.basic.check.name.required">Name is required</small> + </div> + + </div> + + </div> + + <div class="form-group"> + + <label for="description" class="col-sm-3 control-label" data-translate="moon.model.edit.basic.form.description">Description</label> + <div class="col-sm-6"> + <textarea id="description" name="description" class="form-control" data-ng-model="edit.modelToEdit.description"></textarea> + </div> + + </div> + + <div class="form-group"> + + <div class="col-sm-2 col-sm-offset-3"> + + <a href="" ng-disabled="edit.loading" ng-click="edit.init()" class="btn btn-default"> + <span data-translate="moon.model.edit.basic.action.init">Init</span> + </a> + </div> + + <div class="col-sm-4 col-sm-offset-2"> + + <a href="" ng-disabled="edit.loading" ng-click="edit.editModel()" class="btn btn-warning"> + <span class="glyphicon glyphicon-save"></span> + <span data-translate="moon.model.edit.basic.action.update">Update</span> + </a> + + <moon-loader ng-if="edit.loading"></moon-loader> + </div> + + </div> + + </form> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/model/edit/model-edit.tpl.html b/moon_gui/static/app/model/edit/model-edit.tpl.html new file mode 100755 index 00000000..4955f441 --- /dev/null +++ b/moon_gui/static/app/model/edit/model-edit.tpl.html @@ -0,0 +1,70 @@ +<div class="container"> + + <div class="row"> + <h3 class="pull-left" data-translate="moon.model.edit.title" data-translate-values="{ modelName: edit.model.name }">Edit</h3> + </div> + + <div class="panel panel-default"> + + <div class="panel-heading"> + + <span data-translate="moon.model.edit.basic.title" >Basic Information</span> + <a href="" ng-click="edit.editBasic = !edit.editBasic"> + <span data-translate="moon.model.edit.update">Update</span> + <span class="glyphicon glyphicon-cog"></span> + </a> + + </div> + + <div class="panel-body"> + + <div ng-if="edit.editBasic"> + <moon-model-edit-basic model="edit.model"></moon-model-edit-basic> + </div> + + <div ng-if="!edit.editBasic"> + <dl class="dl-horizontal"> + + <dt data-translate="moon.model.edit.basic.form.id">Id</dt> + <dd ng-bind="edit.model.id"></dd> + + <dt data-translate="moon.model.edit.basic.form.name">Name</dt> + <dd ng-bind="edit.model.name"></dd> + + <dt data-translate="moon.model.edit.basic.form.description">Description</dt> + <dd ng-bind="edit.model.description"></dd> + + </dl> + </div> + </div> + + </div> + + <div class="panel panel-default"> + + <div class="panel-heading"> + + <span data-translate="moon.model.edit.metarules.title" >Meta Rule</span> + <!--<a href="" ng-click="edit.editMetaRules = !edit.editMetaRules"> + <span data-translate="moon.model.edit.update">Update</span> + <span class="glyphicon glyphicon-cog"></span> + </a>--> + + </div> + + <div class="panel-body" ng-if="edit.model.meta_rules_values"> + <div class=""> + + <moon-meta-rules-list mapped-model="edit.model" edit-mode="edit.editMetaRules"></moon-meta-rules-list> + + </div> + </div> + + <div class="panel-body" ng-if="!edit.model.meta_rules_values"> + <moon-loader></moon-loader> + </div> + + </div> + + +</div> diff --git a/moon_gui/static/app/model/edit/model.controller.edit.js b/moon_gui/static/app/model/edit/model.controller.edit.js new file mode 100755 index 00000000..3e10a533 --- /dev/null +++ b/moon_gui/static/app/model/edit/model.controller.edit.js @@ -0,0 +1,61 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('ModelEditController', ModelEditController); + + ModelEditController.$inject = ['$scope', '$rootScope', 'model', 'metaRuleService']; + + function ModelEditController($scope, $rootScope, model, metaRuleService) { + + var edit = this; + + edit.model = model; + + edit.editBasic = false; + + edit.editMetaRules = true; + + activate(); + + function activate(){ + + } + + /* + * ---- events + */ + var rootListeners = { + + 'event:modelUpdatedSuccess': $rootScope.$on('event:modelUpdatedSuccess', modelUpdatedSuccess), + + 'event:updateModelFromMetaRuleAddSuccess': $rootScope.$on('event:updateModelFromMetaRuleAddSuccess', modelUpdatedSuccess) + + }; + + for (var unbind in rootListeners) { + $scope.$on('$destroy', rootListeners[unbind]); + } + + /** + * When the model is updated, this function refresh the current model with the new changes + * @param event + * @param model + */ + function modelUpdatedSuccess(event, model){ + + edit.model = model; + + metaRuleService.findSomeWithCallback(model.meta_rules, function(metaRules){ + + edit.model.meta_rules_values = metaRules; + + }); + + } + + } + +})(); diff --git a/moon_gui/static/app/model/edit/model.edit.basic.dir.js b/moon_gui/static/app/model/edit/model.edit.basic.dir.js new file mode 100755 index 00000000..54bb7071 --- /dev/null +++ b/moon_gui/static/app/model/edit/model.edit.basic.dir.js @@ -0,0 +1,97 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .directive('moonModelEditBasic', moonModelEditBasic); + + moonModelEditBasic.$inject = []; + + function moonModelEditBasic() { + + return { + templateUrl : 'html/model/edit/model-edit-basic.tpl.html', + bindToController : true, + controller : moonModelEditBasicController, + controllerAs : 'edit', + scope : { + model : '=' + }, + restrict : 'E', + replace : true + }; + } + + angular + .module('moon') + .controller('moonModelEditBasicController', moonModelEditBasicController); + + moonModelEditBasicController.$inject = ['$scope', 'modelService', 'formService', 'alertService', '$translate', 'utilService']; + + function moonModelEditBasicController($scope, modelService, formService, alertService, $translate, utilService){ + + var edit = this; + + edit.editModel = editModel; + edit.init = init; + + edit.form = {}; + + activate(); + + function activate(){ + + edit.model = $scope.edit.model; + + edit.modelToEdit = angular.copy(edit.model); + + } + + function editModel(){ + + if(formService.isInvalid(edit.form)) { + + formService.checkFieldsValidity(edit.form); + + }else{ + + edit.loading = true; + + modelService.update(edit.modelToEdit, updateSuccess, updateError); + + } + + function updateSuccess(data) { + + var updatedModel = utilService.transformOne(data, 'models'); + + $translate('moon.model.edit.basic.success', { modelName: updatedModel.name }).then( function(translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + edit.loading = false; + + $scope.$emit('event:modelUpdatedSuccess', updatedModel); + + } + + function updateError(reason) { + + $translate('moon.model.edit.basic.error', { modelName: edit.model.name }).then( function(translatedValue) { + alertService.alertError(translatedValue); + }); + + edit.loading = false; + + } + } + + function init(){ + + edit.modelToEdit = angular.copy(edit.model); + + } + } + +})(); diff --git a/moon_gui/static/app/model/model-list.tpl.html b/moon_gui/static/app/model/model-list.tpl.html new file mode 100755 index 00000000..89c682cc --- /dev/null +++ b/moon_gui/static/app/model/model-list.tpl.html @@ -0,0 +1,123 @@ +<div class="container"> + + <div> + <form class="form-inline pull-right"> + <div class="form-group"> + <div> + <input id="searchProject" data-ng-model="list.search.query" type="text" class="form-control" placeholder="{{'moon.model.list.search.placeholder' | translate}}" /> + </div> + </div> + <div class="form-group"> + <div> + <button type="submit" class="btn btn-danger" data-ng-click="list.search.reset()" data-translate="moon.model.list.search.reset">Reset</button> + </div> + </div> + </form> + </div> + + <div> </div> + <div> </div> + <div> </div> + + <div class="row"> + + <div class="table-responsive" data-role="table"> + + <table class="table table-striped table-hover" ng-table="list.table"> + + <thead> + + <tr> + + <th class="customTables sortable" + ng-class="{ 'sort-asc': list.table.isSortBy('name', 'asc'), 'sort-desc': list.table.isSortBy('name', 'desc') }" + ng-click="list.table.sorting('name', list.table.isSortBy('name', 'asc') ? 'desc' : 'asc')"> + <div data-translate="moon.model.list.table.name">Name</div> + </th> + + <th class="customTables sortable" + ng-class="{ 'sort-asc': list.table.isSortBy('description', 'asc'), 'sort-desc': list.table.isSortBy('description', 'desc') }" + ng-click="list.table.sorting('description', list.table.isSortBy('description', 'asc') ? 'desc' : 'asc')"> + <div data-translate="moon.model.list.table.description">Description</div> + </th> + + <th class="customTables sortable"> + <div data-translate="moon.model.list.table.metaRules.number">Number of Meta Rules</div> + </th> + + <th class="customTables"> + <div data-translate="moon.model.list.action.title">Actions</div> + </th> + </tr> + + </thead> + + <tbody ng-if="!list.hasModels()"> + <tr> + <td colspan="2"><span data-translate="moon.model.list.table.notFound">There is no Models</span></td> + </tr> + </tbody> + + <tbody ng-if="list.hasModels()"> + + <tr ng-repeat="aModel in $data | filter:list.search.find | orderBy:sort:reverse"> + <td ng-bind="aModel.name"></td> + <td ng-bind="aModel.description"></td> + <td ng-bind="aModel.meta_rules.length"></td> + <td> + <div class="dropdown"> + <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown"> + <span data-translate="moon.model.list.action.title">Actions</span> + <span class="caret"></span> + </button> + <ul class="dropdown-menu"> + + <!-- <li> + <a href="" ng-click="list.view.showModal(aModel)"> + <span class="glyphicon glyphicon-eye-open"></span> + <span class="control-label" data-translate="moon.model.list.action.detail">Detail</span> + </a> + </li>--> + + <li> + <a href="" ui-sref="moon.model.edit({id: aModel.id})"> + <span class="glyphicon glyphicon-cog"></span> + <span class="control-label" data-translate="moon.model.list.action.edit">Edit</span> + </a> + </li> + + <li class="divider"></li> + + <li> + <a href="" ng-click="list.del.showModal(aModel)"> + <span class="glyphicon glyphicon-trash"></span> + <span class="control-label" data-translate="moon.model.list.action.delete">Delete</span> + </a> + </li> + + </ul> + </div> + </td> + + </tr> + + </tbody> + + </table> + + </div> + + <div class="container"> + + <div class="form-inline form-group"> + <a href="" ng-click="list.add.showModal()" class="btn btn-default"> + <span class="glyphicon glyphicon-plus-sign"></span> + <span data-translate="moon.model.list.action.add">Add Model</span> + </a> + </div> + + </div> + + </div> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/model/model.controller.list.js b/moon_gui/static/app/model/model.controller.list.js new file mode 100755 index 00000000..5021a57e --- /dev/null +++ b/moon_gui/static/app/model/model.controller.list.js @@ -0,0 +1,195 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('ModelListController', ModelListController); + + ModelListController.$inject = ['$scope', '$rootScope', 'models', 'NgTableParams', '$filter', '$modal']; + + function ModelListController($scope, $rootScope, models, NgTableParams, $filter, $modal) { + + var list = this; + + list.models = models; + + list.table = {}; + + list.search = { query: '', + find: searchModel, + reset: searchReset }; + + list.getModels = getModels; + list.hasModels = hasModels; + list.deleteModel = deleteModel; + list.refreshModels = refreshModels; + + list.add = { modal: $modal({ template: 'html/model/action/model-add.tpl.html', show: false }), + showModal: showAddModal }; + + list.view = { modal: $modal({ template: 'html/model/action/model-view.tpl.html', show: false }), + showModal: showViewModal }; + + list.del = { modal: $modal({ template: 'html/model/action/model-delete.tpl.html', show: false }), + showModal: showDeleteModal }; + + activate(); + + function activate(){ + newModelsTable(); + } + + + /* + * ---- events + */ + var rootListeners = { + + 'event:modelCreatedSuccess': $rootScope.$on('event:modelCreatedSuccess', modelCreatedSuccess), + 'event:modelCreatedError': $rootScope.$on('event:modelCreatedError', modelCreatedError), + + 'event:modelDeletedSuccess': $rootScope.$on('event:modelDeletedSuccess', modelDeletedSuccess), + 'event:modelDeletedError': $rootScope.$on('event:modelDeletedError', modelDeletedError) + + + }; + + for (var unbind in rootListeners) { + $scope.$on('$destroy', rootListeners[unbind]); + } + + + function newModelsTable() { + + list.table = new NgTableParams({ + + page: 1, // show first page + count: 10, // count per page + sorting: { + name: 'asc' // initial sorting + } + + }, { + + total: function () { return list.getModels().length; }, // length of data + getData: function($defer, params) { + + var orderedData = params.sorting() ? $filter('orderBy')(list.getModels(), params.orderBy()) : list.getModels(); + $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count())); + + }, + $scope: { $data: {} } + + }); + + return list.table; + + } + + function getModels() { + return (list.models) ? list.models : []; + } + + function hasModels() { + return list.getModels().length > 0; + } + + /** + * Blank the search field + */ + function searchReset() { + list.search.query = ''; + } + + /* + * ---- search + */ + + function searchModel(model){ + return (model.name.indexOf(list.search.query) !== -1 || model.description.indexOf(list.search.query) !== -1); + } + + /* + * ---- add + */ + function showAddModal() { + list.add.modal.$promise.then(list.add.modal.show); + } + + function addModel(model) { + list.models.push(model); + } + + /** + * Refresh the table + */ + function refreshModels(){ + list.table.total(list.models.length); + list.table.reload(); + } + + /** + * This function will add a model to the current list of models and refresh the table + * @param event + * @param model + */ + function modelCreatedSuccess(event, model) { + addModel(model); + refreshModels(); + list.add.modal.hide(); + } + + /** + * This function hide the add modal + * @param event + */ + function modelCreatedError(event) { + list.add.modal.hide(); + } + + /* + * ---- view + */ + + function showViewModal(model) { + + list.view.modal.$scope.model = model; + list.view.modal.$promise.then(list.view.modal.show); + + } + + + /* + * ---- delete + */ + + function showDeleteModal(model) { + + list.del.modal.$scope.model = model; + list.del.modal.$promise.then(list.del.modal.show); + + } + + function deleteModel(model) { + list.models = _.chain(list.models).reject({id: model.id}).value(); + } + + + function modelDeletedSuccess(event, model) { + + list.deleteModel(model); + list.refreshModels(); + + list.del.modal.hide(); + + } + + function modelDeletedError(event, model) { + list.del.modal.hide(); + } + + + } + +})(); diff --git a/moon_gui/static/app/moon.constants.js b/moon_gui/static/app/moon.constants.js new file mode 100644 index 00000000..9681e3dc --- /dev/null +++ b/moon_gui/static/app/moon.constants.js @@ -0,0 +1,79 @@ +/** +# Copyright 2014 Orange +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .constant('DEFAULT_CST', { + DOMAIN: { + DEFAULT: 'Default' + } + }) + .constant('SECURITY_PIPELINE_CST', { + TYPE: { + POLICY: 'policy' + } + }) + .constant('META_DATA_CST', { + TYPE: { + SUBJECT: 'SUBJECT', + OBJECT: 'OBJECT', + ACTION: 'ACTION' + } + }) + .constant('PERIMETER_CST', { + TYPE: { + SUBJECT: 'SUBJECT', + OBJECT: 'OBJECT', + ACTION: 'ACTION' + } + }) + .constant('DATA_CST', { + TYPE: { + SUBJECT: 'SUBJECT', + OBJECT: 'OBJECT', + ACTION: 'ACTION' + } + }) + .constant('ASSIGNMENTS_CST', { + TYPE: { + SUBJECT: 'SUBJECT', + OBJECT: 'OBJECT', + ACTION: 'ACTION' + } + }) + .constant('REST_URI', { + PDP : 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}/pdp/', + MODELS : 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}/models/', + METARULES: 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}/meta_rules/', + RULES: 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}/rules/', + POLICIES: 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}/policies/', + METADATA: { + subject : 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}/subject_categories/', + object : 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}/object_categories/', + action : 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}/action_categories/' + }, + PERIMETERS :{ + subject : 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}/subjects/', + object : 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}/objects/', + action : 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}/actions/' + }, + KEYSTONE : 'http://{{KEYSTONE_HOST}}:{{KEYSTONE_PORT}}/v3/' + }); +})(); diff --git a/moon_gui/static/app/moon.module.js b/moon_gui/static/app/moon.module.js new file mode 100755 index 00000000..a653f8f3 --- /dev/null +++ b/moon_gui/static/app/moon.module.js @@ -0,0 +1,362 @@ +/** +# Copyright 2015 Orange +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + */ + +(function() { + + 'use strict'; + + var moon = angular + + .module('moon', ['ngResource', + 'ngRoute', + 'ui.router', + 'ngMessages', + 'ui.bootstrap', + 'ngTable', + 'ngCookies', + 'ngStorage', + 'pascalprecht.translate', + 'ngAnimate', + 'mgcrea.ngStrap', + 'NgSwitchery', + 'ui.select', + 'toaster']) + + .config(configure) + .run(runner); + + /* + * configure + */ + + configure.$inject = ['$urlRouterProvider', '$translateProvider', '$stateProvider', 'uiSelectConfig']; + + function configure($urlRouterProvider, $translateProvider, $stateProvider, uiSelectConfig) { + + /* + * translate + */ + + $translateProvider + .useStaticFilesLoader({ + prefix: 'assets/i18n/', + suffix: '.json' + }) + .preferredLanguage('en') + .useCookieStorage(); + + /* + * ui-select + */ + + uiSelectConfig.theme = 'selectize'; + + /* + * routes + */ + + $urlRouterProvider.when('', '/project'); + $urlRouterProvider.when('/', '/project'); + $urlRouterProvider.otherwise('/404'); + + configureDefaultRoutes($stateProvider); + + configureDashboard($stateProvider); + + configureAuthRoutes($stateProvider); + + configureProjectRoutes($stateProvider); + + configureModelRoutes($stateProvider); + + configurePDPRoutes($stateProvider); + + configurePolicyRoutes($stateProvider); + + configureLogsRoutes($stateProvider); + + } + + function configureDefaultRoutes($stateProvider) { + + $stateProvider + + .state('moon', { + abstract: true, + template: '<div ui-view></div>' + }) + + .state('moon.404', { + url: '/404', + templateUrl: 'html/common/404/404.tpl.html' + }); + + return $stateProvider; + + } + + function configureDashboard($stateProvider){ + + $stateProvider + + .state('moon.dashboard',{ + url: '/dashboard', + templateUrl: 'html/dashboard/dashboard.tpl.html' + }); + + return $stateProvider; + + } + + function configureAuthRoutes($stateProvider){ + + $stateProvider + + .state('moon.auth', { + abstract: true, + template: '<div ui-view></div>' + }) + + .state('moon.auth.login', { + url: '/login', + templateUrl: 'html/authentication/authentication.tpl.html', + controller: 'AuthenticationController', + controllerAs: 'auth' + }); + + return $stateProvider; + } + + function configureModelRoutes($stateProvider) { + + $stateProvider + + .state('moon.model', { + abstract: true, + template: '<div ui-view></div>' + }) + + .state('moon.model.list', { + url: '/model', + templateUrl: 'html/model/model-list.tpl.html', + controller: 'ModelListController', + controllerAs: 'list', + resolve: { + models: ['modelService', function(modelService) { + return modelService.findAll(); + }] + } + }) + + .state('moon.model.edit', { + url: '/model/:id', + templateUrl: 'html/model/edit/model-edit.tpl.html', + controller: 'ModelEditController', + controllerAs: 'edit', + resolve: { + model: ['$stateParams','modelService', function($stateParams, modelService) { + return modelService.findOneWithMetaRules($stateParams.id); + }] + } + }); + + + return $stateProvider; + + } + + function configureProjectRoutes($stateProvider) { + + $stateProvider + + .state('moon.project', { + abstract: true, + template: '<div ui-view></div>' + }) + + .state('moon.project.list', { + url: '/project', + templateUrl: 'html/project/project-list.tpl.html', + controller: 'ProjectListController', + controllerAs: 'list', + resolve: { + projects: ['projectService', function(projectService) { + return projectService.findAll(); + }] + } + }); + + return $stateProvider; + + } + + function configurePDPRoutes($stateProvider) { + + $stateProvider + + .state('moon.pdp', { + abstract: true, + template: '<div ui-view></div>' + }) + + .state('moon.pdp.list', { + url: '/pdp', + templateUrl: 'html/pdp/pdp-list.tpl.html', + controller: 'PDPListController', + controllerAs: 'list', + resolve: { + pdps: ['pdpService', function(pdpService) { + return pdpService.findAll(); + }] + } + }) + + .state('moon.pdp.edit', { + url: '/pdp/:id', + templateUrl: 'html/pdp/edit/pdp-edit.tpl.html', + controller: 'PDPEditController', + controllerAs: 'edit', + resolve: { + pdp: ['$stateParams','pdpService', function($stateParams, pdpService) { + return pdpService.findOne($stateParams.id); + }] + } + }); + + return $stateProvider; + + } + + function configurePolicyRoutes($stateProvider) { + + $stateProvider + + .state('moon.policy', { + abstract: true, + template: '<div ui-view></div>' + }) + + .state('moon.policy.list', { + url: '/policy', + templateUrl: 'html/policy/policy-list.tpl.html', + controller: 'PolicyListController', + controllerAs: 'list', + resolve: { + policies: ['policyService', function(policyService) { + return policyService.findAll(); + }] + } + }) + + .state('moon.policy.edit', { + url: '/policy/:id', + templateUrl: 'html/policy/edit/policy-edit.tpl.html', + controller: 'PolicyEditController', + controllerAs: 'edit', + resolve: { + policy: ['$stateParams','policyService', function($stateParams, policyService) { + return policyService.findOne($stateParams.id); + }] + } + }); + + + return $stateProvider; + + } + + function configureLogsRoutes($stateProvider){ + + $stateProvider + + .state('moon.logs', { + url: '/logs', + templateUrl: 'html/logs/logs.tpl.html', + controller: 'LogsController', + controllerAs: 'logs' + }); + + return $stateProvider; + } + + /* + * runner + */ + + runner.$inject = ['$rootScope', '$modal', '$translate', 'alertService', 'authenticationService', '$sessionStorage', '$location']; + + function runner($rootScope, $modal, $translate, alertService, authenticationService, $sessionStorage, $location) { + + $rootScope.connected = authenticationService.IsConnected(); + + $rootScope.transitionModal = $modal({ scope: $rootScope, template: 'html/common/waiting/waiting.tpl.html', backdrop: 'static', show: false }); + + $rootScope.$on('$stateChangeStart', stateChangeStart); + $rootScope.$on('$stateChangeSuccess', stateChangeSuccess); + $rootScope.$on('$stateChangeError', stateChangeError); + $rootScope.$on('$locationChangeStart', locationChangeStart); + + // keep user logged in after page refresh + if (authenticationService.IsConnected()) { + authenticationService.SetTokenHeader(authenticationService.GetTokenHeader()); + } + + // redirect to login page if not logged in and trying to access a restricted pages + function locationChangeStart(event, next, current) { + var publicPages = ['/login']; + var restrictedPage = publicPages.indexOf($location.path()) === -1; + if (restrictedPage && !$sessionStorage.currentUser) { + $location.path('/login'); + } + } + + function stateChangeStart() { + $rootScope.connected = authenticationService.IsConnected(); + $rootScope.transitionModal.$promise.then($rootScope.transitionModal.show); + } + + function stateChangeSuccess() { + $rootScope.transitionModal.hide(); + } + + function stateChangeError(event, toState, toParams, fromState, fromParams, error) { + + var stacktrace = getStacktrace(event, toState, toParams, fromState, fromParams, error); + + $translate('moon.global.error', { stacktrace: stacktrace }).then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + $rootScope.transitionModal.hide(); + + } + + function getStacktrace(event, toState, toParams, fromState, fromParams, error) { + + var stacktrace = {}; + + stacktrace.status = error.status; + stacktrace.message = error.statusText; + stacktrace.state = toState; + stacktrace.params = toParams; + + return stacktrace; + + } + + } + +})(); diff --git a/moon_gui/static/app/pdp/action/pdp-add.tpl.html b/moon_gui/static/app/pdp/action/pdp-add.tpl.html new file mode 100755 index 00000000..f83fb85c --- /dev/null +++ b/moon_gui/static/app/pdp/action/pdp-add.tpl.html @@ -0,0 +1,88 @@ +<div ng-controller="PDPAddController as add" class="modal" tabindex="-1" data-role="modalAddPDP"> + + <div class="modal-dialog"> + + <div class="modal-content"> + + <div class="modal-header"> + <button type="button" class="close" ng-click="$hide()">×</button> + <h4 class="modal-title" data-translate="moon.pdp.add.title"></h4> + </div> + + <div class="modal-body"> + + <form class="form-horizontal" role="form" name="add.form"> + + <div class="form-group" ng-class="{'has-error': add.form.name.$invalid && add.form.name.$dirty}"> + + <label for="name" class="col-sm-3 control-label" data-translate="moon.pdp.add.form.name">Name</label> + + <div class="col-sm-6"> + + <input name="name" id="name" class="form-control" type="text" data-ng-model="add.pdp.name" required /> + + <div class="help-block" ng-show="add.form.name.$dirty && add.form.name.$invalid"> + <small class="error" ng-show="add.form.name.$error.required" data-translate="moon.pdp.add.check.name.required">Name is required</small> + </div> + + </div> + </div> + + <div class="form-group" ng-class="{'has-error': add.form.policy.$dirty && (add.form.policy.$invalid || !add.selectedPolicy)}"> + + <label class="col-sm-3 control-label" data-translate="moon.pdp.add.form.policy">Policy</label> + + <div class="col-sm-6" ng-if="!add.loadingPolicies"> + + <ui-select ng-model="add.selectedPolicy" name="policy" required> + <ui-select-match placeholder="(None)">{{$select.selected.name}}</ui-select-match> + <ui-select-choices repeat="policy in add.policies"> + <div ng-value="policy">{{policy.name}}</div> + </ui-select-choices> + </ui-select> + + <div class="help-block" ng-show="add.form.policy.$dirty && (add.form.policy.$invalid || !add.selectedPolicy)"> + <small class="error" ng-show="add.form.policy.$error.required" data-translate="moon.pdp.add.check.policy.required">Policy is required</small> + </div> + + </div> + + <div class="col-sm-6" ng-if="add.loadingPolicies"> + <moon-loader ng-if="add.loadingPolicies" ></moon-loader> + </div> + + </div> + + <div class="form-group"> + + <label for="description" class="col-sm-3 control-label" data-translate="moon.pdp.add.form.description">Description</label> + <div class="col-sm-6"> + <textarea name="description" id="description" class="form-control" ng-model="add.pdp.description"></textarea> + </div> + + </div> + + </form> + + </div> + + <div class="modal-footer"> + + <div class="btn-toolbar" style="float: right;"> + <a href="" ng-click="$hide()" class="btn btn-default"> + <span data-translate="moon.pdp.add.action.cancel">Cancel</span> + </a> + <a href="" ng-disabled="add.loading" ng-click="add.create(add.pdp)" class="btn btn-warning"> + <span class="glyphicon glyphicon-save"></span> + <span data-translate="moon.pdp.add.action.create">Create</span> + </a> + <moon-loader ng-if="add.loading"></moon-loader> + </div> + + </div> + + </div> + + </div> + +</div> diff --git a/moon_gui/static/app/pdp/action/pdp-delete.tpl.html b/moon_gui/static/app/pdp/action/pdp-delete.tpl.html new file mode 100755 index 00000000..167ba417 --- /dev/null +++ b/moon_gui/static/app/pdp/action/pdp-delete.tpl.html @@ -0,0 +1,35 @@ +<div ng-controller="PDPDeleteController as del" class="modal" tabindex="-1" data-role="modalDeletePDP"> + + <div class="modal-dialog"> + + <div class="modal-content"> + + <div class="modal-header"> + <button type="button" class="close" ng-click="$hide()">×</button> + <h4 class="modal-title" data-translate="moon.pdp.remove.title"></h4> + </div> + + <div class="modal-body"> + <span data-translate="moon.pdp.remove.content" data-translate-values="{ pdpName: del.pdp.name}"></span> + </div> + + <div class="modal-footer"> + <div class="btn-toolbar" style="float: right;"> + <a href="" ng-click="$hide()" class="btn btn-default"> + <span data-translate="moon.pdp.remove.action.cancel">Cancel</span> + </a> + + <a href="" ng-disabled="del.loading" ng-click="del.remove()" class="btn btn-warning"> + <span class="glyphicon glyphicon-trash"></span> + <span data-translate="moon.pdp.remove.action.delete">Delete</span> + </a> + + <moon-loader ng-if="del.loading"></moon-loader> + </div> + </div> + + </div> + + </div> + +</div> diff --git a/moon_gui/static/app/pdp/action/pdp.controller.add.js b/moon_gui/static/app/pdp/action/pdp.controller.add.js new file mode 100755 index 00000000..d1c34c79 --- /dev/null +++ b/moon_gui/static/app/pdp/action/pdp.controller.add.js @@ -0,0 +1,108 @@ +/** + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('PDPAddController', PDPAddController); + + PDPAddController.$inject = ['$scope', '$translate', 'alertService', 'formService', 'pdpService', 'policyService', 'utilService']; + + function PDPAddController($scope, $translate, alertService, formService, pdpService, policyService, utilService) { + + var add = this; + + /* + * + */ + + add.form = {}; + + add.pdp = {}; + + add.policies = []; + + add.selectedPolicy = null; + + add.loading = false; + add.loadingPolicies = true; + + add.create = createPDP; + + resolvePolicies(); + + /* + * + */ + + /** + * This function return an array of all policies/template ids + */ + function resolvePolicies() { + + policyService.findAllWithCallback(function(policies){ + + add.policies = policies; + add.loadingPolicies = false; + }); + + } + + function createPDP(pdp) { + + if(formService.isInvalid(add.form)) { + + formService.checkFieldsValidity(add.form); + + } else { + + add.loading = true; + + pdpService.data.pdp.create({}, { + + name: add.pdp.name, + description: add.pdp.description, + security_pipeline: [add.selectedPolicy.id], + keystone_project_id: null + + }, createSuccess, createError); + + } + + function createSuccess(data) { + + $translate('moon.pdp.add.success', { pdpName: pdp.name }) + .then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + var createdPdp = utilService.transformOne(data, 'pdps'); + + add.loading = false; + + $scope.$emit('event:pdpCreatedSuccess', createdPdp); + + } + + function createError(reason) { + + $translate('moon.pdp.add.error', { pdpName: pdp.name }) + .then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + add.loading = false; + + $scope.$emit('event:pdpCreatedError'); + + } + + } + + } + +})(); diff --git a/moon_gui/static/app/pdp/action/pdp.controller.delete.js b/moon_gui/static/app/pdp/action/pdp.controller.delete.js new file mode 100755 index 00000000..62557864 --- /dev/null +++ b/moon_gui/static/app/pdp/action/pdp.controller.delete.js @@ -0,0 +1,66 @@ +/** + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('PDPDeleteController', PDPDeleteController); + + PDPDeleteController.$inject = ['$scope', '$translate', 'alertService', 'pdpService']; + + function PDPDeleteController($scope, $translate, alertService, pdpService) { + + var del = this; + + /* + * + */ + + del.pdp = $scope.pdp; + del.loading = false; + del.remove = deletePDP; + + /* + * + */ + + function deletePDP() { + del.loading = true; + + pdpService.data.pdp.remove({pdp_id: del.pdp.id}, deleteSuccess, deleteError); + + function deleteSuccess(data) { + + $translate('moon.pdp.remove.success', { pdpName: del.pdp.name }) + .then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + del.loading = false; + + $scope.$emit('event:pdpDeletedSuccess', del.pdp); + + } + + function deleteError(reason) { + + $translate('moon.pdp.remove.error', { pdpName: del.pdp.name }) + .then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + del.loading = false; + + $scope.$emit('event:pdpDeletedError', del.pdp); + + } + + } + + } + +})(); diff --git a/moon_gui/static/app/pdp/edit/pdp-edit-basic.tpl.html b/moon_gui/static/app/pdp/edit/pdp-edit-basic.tpl.html new file mode 100755 index 00000000..887d81ca --- /dev/null +++ b/moon_gui/static/app/pdp/edit/pdp-edit-basic.tpl.html @@ -0,0 +1,65 @@ +<div class="row"> + + <form class="form-horizontal" role="form" name="edit.form"> + + <div class="form-group"> + + <label for="id" class="col-sm-3 control-label" data-translate="moon.pdp.edit.basic.form.id">Id</label> + + <div class="col-sm-6"> + + <input name="id" id="id" disabled class="form-control" type="text" data-ng-model="edit.pdpToEdit.id" required /> + + </div> + + </div> + + <div class="form-group" ng-class="{'has-error': edit.form.name.$invalid && edit.form.name.$dirty}"> + + <label for="name" class="col-sm-3 control-label" data-translate="moon.pdp.edit.basic.form.name">Name</label> + + <div class="col-sm-6"> + + <input name="name" id="name" class="form-control" type="text" data-ng-model="edit.pdpToEdit.name" required /> + + <div class="help-block" ng-show="edit.form.name.$dirty && edit.form.name.$invalid"> + <small class="error" ng-show="edit.form.name.$error.required" data-translate="moon.pdp.edit.basic.check.name.required">Name is required</small> + </div> + + </div> + + </div> + + <div class="form-group"> + + <label for="description" class="col-sm-3 control-label" data-translate="moon.pdp.edit.basic.form.description">Description</label> + <div class="col-sm-6"> + <textarea id="description" name="description" class="form-control" data-ng-model="edit.pdpToEdit.description"></textarea> + </div> + + </div> + + <div class="form-group"> + + <div class="col-sm-2 col-sm-offset-3"> + + <a href="" ng-disabled="edit.loading" ng-click="edit.init()" class="btn btn-default"> + <span data-translate="moon.pdp.edit.basic.action.init">Init</span> + </a> + </div> + + <div class="col-sm-4 col-sm-offset-2"> + + <a href="" ng-disabled="edit.loading" ng-click="edit.editPdp()" class="btn btn-warning"> + <span class="glyphicon glyphicon-save"></span> + <span data-translate="moon.pdp.edit.basic.action.update">Update</span> + </a> + + <moon-loader ng-if="edit.loading"></moon-loader> + </div> + + </div> + + </form> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/pdp/edit/pdp-edit.tpl.html b/moon_gui/static/app/pdp/edit/pdp-edit.tpl.html new file mode 100755 index 00000000..1fbd555a --- /dev/null +++ b/moon_gui/static/app/pdp/edit/pdp-edit.tpl.html @@ -0,0 +1,64 @@ +<div class="container"> + + <div class="row"> + <h3 class="pull-left" data-translate="moon.pdp.edit.title" data-translate-values="{ pdpName: edit.pdp.name }">Edit</h3> + </div> + + <div class="row"> + <div class="panel panel-default"> + + <div class="panel-heading"> + + <h4> + <span data-translate="moon.pdp.edit.basic.title" >Basic Information</span> + <a href="" ng-click="edit.editBasic = !edit.editBasic"> + <span data-translate="moon.pdp.edit.update">Update</span> + <span class="glyphicon glyphicon-cog"></span> + </a> + </h4> + + </div> + + <div class="panel-body"> + + <div ng-if="edit.editBasic"> + <moon-p-d-p-edit-basic pdp="edit.pdp"></moon-p-d-p-edit-basic> + </div> + + <div ng-if="!edit.editBasic"> + <dl class="dl-horizontal"> + <dt>Id</dt> + <dd ng-bind="edit.pdp.id"></dd> + <dt>Name</dt> + <dd ng-bind="edit.pdp.name"></dd> + <dt>Description</dt> + <dd ng-bind="edit.pdp.description"></dd> + </dl> + </div> + + </div> + + </div> + + <div class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.pdp.edit.policy.title" >Policies</h4> + + </div> + + <div class="panel-body"> + + <div class="row"> + + <moon-policy-mapped-list pdp="edit.pdp"></moon-policy-mapped-list> + + </div> + + </div> + + </div> + </div> + +</div> diff --git a/moon_gui/static/app/pdp/edit/pdp.controller.edit.js b/moon_gui/static/app/pdp/edit/pdp.controller.edit.js new file mode 100755 index 00000000..41b73098 --- /dev/null +++ b/moon_gui/static/app/pdp/edit/pdp.controller.edit.js @@ -0,0 +1,50 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('PDPEditController', PDPEditController); + + PDPEditController.$inject = ['$scope', '$rootScope', 'pdp', '$stateParams']; + + function PDPEditController($scope, $rootScope, pdp, $stateParams) { + + var edit = this; + + edit.pdp = pdp; + + edit.editBasic = false; + + activate(); + + function activate(){ + + } + + /* + * ---- events + */ + var rootListeners = { + + 'event:pdpUpdatedSuccess': $rootScope.$on('event:pdpUpdatedSuccess', pdpUpdatedSuccess) + + }; + + for (var unbind in rootListeners) { + $scope.$on('$destroy', rootListeners[unbind]); + } + + /** + * When the model is updated, this function refresh the current model with the new changes + * @param event + * @param pdp + */ + function pdpUpdatedSuccess(event, pdp){ + + edit.pdp = pdp; + + } + } + +})(); diff --git a/moon_gui/static/app/pdp/edit/pdp.edit.basic.dir.js b/moon_gui/static/app/pdp/edit/pdp.edit.basic.dir.js new file mode 100755 index 00000000..402422b6 --- /dev/null +++ b/moon_gui/static/app/pdp/edit/pdp.edit.basic.dir.js @@ -0,0 +1,97 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .directive('moonPDPEditBasic', moonPDPEditBasic); + + moonPDPEditBasic.$inject = []; + + function moonPDPEditBasic() { + + return { + templateUrl : 'html/pdp/edit/pdp-edit-basic.tpl.html', + bindToController : true, + controller : moonPDPEditBasicController, + controllerAs : 'edit', + scope : { + pdp : '=' + }, + restrict : 'E', + replace : true + }; + } + + angular + .module('moon') + .controller('moonPDPEditBasicController', moonPDPEditBasicController); + + moonPDPEditBasicController.$inject = ['$scope', 'pdpService', 'formService', 'alertService', '$translate', 'utilService']; + + function moonPDPEditBasicController($scope, pdpService, formService, alertService, $translate, utilService){ + + var edit = this; + + edit.editPdp = editPdp; + edit.init = init; + + edit.form = {}; + + activate(); + + function activate(){ + + edit.pdp = $scope.edit.pdp; + + edit.pdpToEdit = angular.copy(edit.pdp); + + } + + function editPdp(){ + + if(formService.isInvalid(edit.form)) { + + formService.checkFieldsValidity(edit.form); + + }else{ + + edit.loading = true; + + pdpService.update(edit.pdpToEdit, updateSuccess, updateError); + + } + + function updateSuccess(data) { + + var updatedPdp = utilService.transformOne(data, 'pdps'); + + $translate('moon.pdp.edit.basic.success', { pdpName: updatedPdp.name }).then( function(translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + edit.loading = false; + + $scope.$emit('event:pdpUpdatedSuccess', updatedPdp); + + } + + function updateError(reason) { + + $translate('moon.pdp.edit.basic.error', { pdpName: edit.pdp.name }).then( function(translatedValue) { + alertService.alertError(translatedValue); + }); + + edit.loading = false; + + } + } + + function init(){ + + edit.pdpToEdit = angular.copy(edit.pdp); + + } + } + +})(); diff --git a/moon_gui/static/app/pdp/pdp-list.tpl.html b/moon_gui/static/app/pdp/pdp-list.tpl.html new file mode 100755 index 00000000..8aa4e653 --- /dev/null +++ b/moon_gui/static/app/pdp/pdp-list.tpl.html @@ -0,0 +1,133 @@ + +<div class="container"> + + <div> + <form class="form-inline pull-right"> + <div class="form-group"> + <div> + <input id="searchPDP" data-ng-model="list.search.query" type="text" class="form-control" placeholder="{{'moon.pdp.list.search.placeholder' | translate}}" /> + </div> + </div> + <div class="form-group"> + <div> + <button type="submit" class="btn btn-danger" data-ng-click="list.search.reset()" data-translate="moon.pdp.list.search.reset">Reset</button> + </div> + </div> + </form> + </div> + + <div> </div> + <div> </div> + <div> </div> + + <div class="row" > + + <div class="table-responsive" data-role="table"> + + <table class="table table-striped table-hover" ng-table="list.table"> + + <thead> + + <tr> + + <th class="customTables sortable" + ng-class="{ 'sort-asc': list.table.isSortBy('name', 'asc'), 'sort-desc': list.table.isSortBy('name', 'desc') }" + ng-click="list.table.sorting('name', list.table.isSortBy('name', 'asc') ? 'desc' : 'asc')"> + <div data-translate="moon.pdp.list.table.name">Name</div> + </th> + + <th class="customTables sortable" + ng-class="{ 'sort-asc': list.table.isSortBy('security_pipeline', 'asc'), 'sort-desc': list.table.isSortBy('security_pipeline', 'desc') }" + ng-click="list.table.sorting('security_pipeline', list.table.isSortBy('policy', 'asc') ? 'desc' : 'asc')"> + <div data-translate="moon.pdp.list.table.security_pipeline.number">Number of Securities</div> + </th> + + <th class="customTables" + ng-class="{ 'sort-asc': list.table.isSortBy('project', 'asc'), 'sort-desc': list.table.isSortBy('project', 'desc') }" + ng-click="list.table.sorting('project', list.table.isSortBy('project', 'asc') ? 'desc' : 'asc')"> + <div data-translate="moon.pdp.list.table.project">Project</div> + </th> + + <th class="customTables"> + <div data-translate="moon.pdp.list.action.title">Actions</div> + </th> + + </tr> + + </thead> + + <tbody ng-if="!list.hasPDPs()"> + <tr> + <td colspan="12"><span data-translate="moon.pdp.list.table.notFound">There is no PDP</span></td> + </tr> + </tbody> + + <tbody ng-if="list.hasPDPs()"> + + <tr ng-repeat="pdp in $data | filter:list.search.find | orderBy:sort:reverse"> + <td ng-bind="list.getPDPName(pdp)"></td> + <td ng-bind="list.getSecPipelineFromPdp(pdp).length"></td> + <td> + <div ng-if="list.isMapped(pdp)"> + + <div ng-if="!list.getProjectFromPDP(pdp)"> + <moon-loader ng-if="!list.getProjectFromPDP(pdp)" ></moon-loader> + <em data-translate="moon.pdp.list.table.loading.project">Loading Project</em> + </div> + + <div ng-if="list.getProjectFromPDP(pdp)"> + <span ng-bind="pdp.project.name"></span> + </div> + + </div> + + <div ng-if="!list.isMapped(pdp)"> + <span data-translate="moon.pdp.list.table.mapping.map">Is not mapped</span> + </div> + </td> + <td> + <div class="dropdown"> + <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown"> + <span data-translate="moon.pdp.list.action.title">Actions</span> + <span class="caret"></span> + </button> + <ul class="dropdown-menu"> + + <li> + <a href="" ui-sref="moon.pdp.edit({id: pdp.id})"> + <span class="glyphicon glyphicon-cog"></span> + <span class="control-label" data-translate="moon.pdp.list.action.edit">Edit</span> + </a> + </li> + + <li class="divider"></li> + + <li> + <a href="" ng-click="list.del.showModal(pdp)"> + <span class="glyphicon glyphicon-trash"></span> + <span class="control-label" data-translate="moon.pdp.list.action.delete">Delete</span> + </a> + </li> + </ul> + </div> + </td> + + </tr> + + </tbody> + + </table> + + </div> + + <div class="container"> + <div class="form-inline form-group"> + <a href="" ng-click="list.add.showModal()" class="btn btn-default"> + <span class="glyphicon glyphicon-plus-sign"></span> + <span data-translate="moon.pdp.list.action.add">Add PDP</span> + </a> + </div> + </div> + + </div> +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/pdp/pdp.controller.list.js b/moon_gui/static/app/pdp/pdp.controller.list.js new file mode 100755 index 00000000..a831cfe3 --- /dev/null +++ b/moon_gui/static/app/pdp/pdp.controller.list.js @@ -0,0 +1,284 @@ +/** + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('PDPListController', PDPListController); + + PDPListController.$inject = [ + '$rootScope', + '$scope', + '$filter', + '$modal', + 'NgTableParams', + 'pdps', + 'projectService']; + + function PDPListController($rootScope, + $scope, + $filter, + $modal, + NgTableParams, + pdps, + projectService) { + + var list = this; + + list.pdps = pdps; + list.mappings = []; + + + list.getPDPs = getPDPs; + list.hasPDPs = hasPDPs; + list.getPDPName = getPDPName; + list.isMapped = isMapped; + list.getProjectFromPDP = getProjectFromPDP; + list.getidFromPDP = getidFromPDP; + + list.table = {}; + + list.addPDP = addPDP; + list.deletePDP = deletePDP; + list.refreshPDPs = refreshPDPs; + list.updatePDPs = updatePDPs; + + list.getMappedProjectName = getMappedProjectName; + list.getSecPipelineFromPdp = getSecPipelineFromPdp; + + list.search = { query: '', + find: searchPDP, + reset: searchReset }; + + list.add = { modal: $modal({ template: 'html/pdp/action/pdp-add.tpl.html', show: false }), + showModal: showAddModal }; + + list.del = { modal: $modal({ template: 'html/pdp/action/pdp-delete.tpl.html', show: false }), + showModal: showDeleteModal }; + + activate(); + + function activate(){ + newPDPsTable(); + } + + /* + * ---- events + */ + + var rootListeners = { + + 'event:pdpCreatedSuccess': $rootScope.$on('event:pdpCreatedSuccess', pdpCreatedSuccess), + 'event:pdpCreatedError': $rootScope.$on('event:pdpCreatedError', pdpCreatedError), + + 'event:pdpDeletedSuccess': $rootScope.$on('event:pdpDeletedSuccess', pdpDeletedSuccess), + 'event:pdpDeletedError': $rootScope.$on('event:pdpDeletedError', pdpDeletedError), + + }; + + _.each(rootListeners, function(unbind){ + $scope.$on('$destroy', rootListeners[unbind]); + }); + + /* + * + */ + + /** + * Function getting an array of PDP JSON + * @return An array of valid pdp. + */ + function getPDPs() { + return (list.pdps) ? list.pdps : []; + } + + function hasPDPs() { + return list.getPDPs().length > 0; + } + + function addPDP(pdp) { + list.pdps.push(pdp); + } + + function deletePDP(pdp) { + + list.pdps = _.chain(list.pdps).reject({id: pdp.id}).value(); + + } + + function refreshPDPs() { + + list.table.total(list.pdps.length); + list.table.reload(); + + } + + function updatePDPs(pdp) { + + _(_.values(list.getPDPs())).each(function(anPDP) { + if(anPDP.id === pdp.id) { + //@todo: Determine what this code should have been designed to do + anPDP = _.clone(pdp); + } + }); + + return list.pdps; + + } + + /** + * Get the id from an PDP + * @param pdp The inspected pdp + * @returns {*} Its UUID + */ + function getidFromPDP(pdp) { + return pdp.id; + } + + function getMappedProjectName(pdp) { + return pdp.tenant.name; + } + + /** + * Get the name of the PDP + * @param pdp The PDP to inspect + * @returns {*} Its name. + */ + function getPDPName(pdp) { + return (pdp) ? pdp.name : ''; + } + + function isMapped(pdp) { + return !_.isNull(pdp.keystone_project_id); + } + + /** + * Prerequisite : before calling this method, isMapped should return true before + * @param pdp + * @returns false or {*}, false if the project is currently loading + */ + function getProjectFromPDP(pdp) { + + if(_.has(pdp, 'project')){ + return pdp.project; + } + + // if the call has not been made + if(!_.has(pdp, 'callPdpInProgress')){ + + pdp.callPdpInProgress = true; + + projectService.findOne(pdp.keystone_project_id, function(project){ + pdp.callPdpInProgress = false; + pdp.project = project; + return pdp.project; + }); + } + + // if the call is in progress return false + return false; + } + + /** + * Generate a table item, directly usable by the rendering engine + * @returns {{}|*} the table + */ + function newPDPsTable() { + + list.table = new NgTableParams({ + + page: 1, // show first page + count: 10, // count per page + + }, { + + total: function () { return list.getPDPs().length; }, // length of data + getData: function($defer, params) { + + var orderedData = params.sorting() ? $filter('orderBy')(list.getPDPs(), params.orderBy()) : list.getPDPs(); + $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count())); + + }, + $scope: { $data: {} } + + }); + + return list.table; + + } + + + /* + * --- search + */ + + /** + * Indicate if an pdp having a specified name exists + * @param pdp Searched name + * @returns {boolean} True if a corresponding pdp is found, false otherwise + */ + function searchPDP(pdp){ + return list.getPDPName(pdp).indexOf(list.search.query) !== -1 || list.getSecPipelineFromPdp(pdp).indexOf(list.search.query) !== -1 ; + } + + function getSecPipelineFromPdp(pdp){ + return (pdp.security_pipeline) ? pdp.security_pipeline : []; + } + + /** + * Blank the search field + */ + function searchReset() { + list.search.query = ''; + } + + /* + * ---- add + */ + + function showAddModal() { + list.add.modal.$promise.then(list.add.modal.show); + } + + function pdpCreatedSuccess(event, pdp) { + + list.addPDP(pdp); + list.refreshPDPs(); + + list.add.modal.hide(); + + } + + function pdpCreatedError(event, pdp) { + list.add.modal.hide(); + } + + /* + * ---- delete + */ + + function showDeleteModal(pdp) { + list.del.modal.$scope.pdp = pdp; + list.del.modal.$promise.then(list.del.modal.show); + } + + function pdpDeletedSuccess(event, pdp) { + + list.deletePDP(pdp); + list.refreshPDPs(); + + list.del.modal.hide(); + + } + + function pdpDeletedError() { + list.del.modal.hide(); + } + + } + +})(); diff --git a/moon_gui/static/app/policy/action/mapping/policy-map.tpl.html b/moon_gui/static/app/policy/action/mapping/policy-map.tpl.html new file mode 100755 index 00000000..8b787f14 --- /dev/null +++ b/moon_gui/static/app/policy/action/mapping/policy-map.tpl.html @@ -0,0 +1,64 @@ +<div ng-controller="PolicyMapController as map" class="modal" tabindex="-1" data-role="modalMappingPolicy"> + + <div class="modal-dialog"> + + <div class="modal-content"> + + <div class="modal-header"> + <button type="button" class="close" ng-click="$hide()">×</button> + <h4 class="modal-title" data-translate="moon.policy.map.title" data-translate-values="{ pdpName: map.pdp.name}"></h4> + </div> + + <div class="modal-body"> + + <form class="form-horizontal" role="form" name="map.form"> + + <div class="form-group" ng-class="{'has-error': map.form.policy.$dirty && (map.form.policy.$invalid || !map.selectedPolicy)}"> + + <label class="col-sm-3 control-label" data-translate="moon.policy.map.form.list">List of Policies</label> + + <div class="col-sm-6"> + + <ui-select ng-model="map.selectedPolicy" name="policy" required> + <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match> + <ui-select-choices repeat="policy in map.policies"> + <div ng-bind="policy.name" ng-value="policy"></div> + </ui-select-choices> + </ui-select> + + <moon-loader ng-if="map.policiesLoading"></moon-loader> + + <div class="help-block" ng-show="map.form.policy.$dirty && (map.form.policy.$invalid || !map.selectedPolicy)"> + <small class="error" ng-show="map.form.policy.$error.required" data-translate="moon.policy.map.check.policy.required">Policy is required</small> + </div> + + </div> + + </div> + + </form> + + </div> + + <div class="modal-footer"> + <div class="btn-toolbar" style="float: right;"> + + <a href="" ng-click="$hide()" class="btn btn-default"> + <span data-translate="moon.policy.map.action.cancel">Cancel</span> + </a> + + <a href="" ng-disabled="map.mappingLoading" ng-click="map.map()" class="btn btn-warning"> + <span class="glyphicon glyphicon-link"></span> + <span data-translate="moon.policy.map.action.map">Map</span> + </a> + + <moon-loader ng-if="map.mappingLoading"></moon-loader> + + </div> + </div> + + </div> + + </div> + +</div> diff --git a/moon_gui/static/app/policy/action/mapping/policy-unmap.tpl.html b/moon_gui/static/app/policy/action/mapping/policy-unmap.tpl.html new file mode 100755 index 00000000..a2cda52a --- /dev/null +++ b/moon_gui/static/app/policy/action/mapping/policy-unmap.tpl.html @@ -0,0 +1,33 @@ +<div ng-controller="PolicyUnMapController as unmap" class="modal" tabindex="-1" data-role="modalUnmapPolicy"> + + <div class="modal-dialog"> + + <div class="modal-content"> + + <div class="modal-header"> + <button type="button" class="close" ng-click="$hide()">×</button> + <h4 class="modal-title" data-translate="moon.policy.unmap.title"></h4> + </div> + + <div class="modal-body"> + <span data-translate="moon.policy.unmap.content" data-translate-values="{ policyName: unmap.policy.name, pdpName: unmap.pdp.name }"></span> + </div> + + <div class="modal-footer"> + <div class="btn-toolbar" style="float: right;"> + <a href="" ng-click="$hide()" class="btn btn-default"> + <span data-translate="moon.policy.unmap.action.cancel">Cancel</span> + </a> + <a href="" ng-disabled="unmap.unMappingLoading" ng-click="unmap.unmap()" class="btn btn-warning"> + <span class="glyphicon glyphicon-transfer"></span> + <span data-translate="moon.policy.unmap.action.unmap">Unmap</span> + </a> + <moon-loader ng-if="unmap.unMappingLoading"></moon-loader> + </div> + </div> + + </div> + + </div> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/policy/action/mapping/policy.controller.map.js b/moon_gui/static/app/policy/action/mapping/policy.controller.map.js new file mode 100755 index 00000000..6ad8caa7 --- /dev/null +++ b/moon_gui/static/app/policy/action/mapping/policy.controller.map.js @@ -0,0 +1,106 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('PolicyMapController', PolicyMapController); + + PolicyMapController.$inject = ['$scope', 'alertService', '$translate', 'formService', 'policyService', 'pdpService', 'utilService']; + + function PolicyMapController($scope, alertService, $translate, formService, policyService, pdpService, utilService ) { + + var map = this; + + /* + * + */ + + map.pdps = []; + + map.pdp = $scope.pdp; + + map.addPolicyToList = false; + + map.map = mapToPdp; + + activate(); + + function activate() { + + resolvePolicies(); + + } + + function resolvePolicies() { + + map.policiesLoading = true; + + policyService.findAllWithCallback(function(policies){ + map.policies = policies; + map.policiesLoading = false; + } + ); + + } + + function mapToPdp() { + + if (formService.isInvalid(map.form)) { + + formService.checkFieldsValidity(map.form); + + } else { + + map.mappingLoading = true; + + var pdpToSend = angular.copy(map.pdp); + + pdpToSend.security_pipeline.push(map.selectedPolicy.id); + + pdpService.update(pdpToSend, mapSuccess, mapError); + + } + + function mapSuccess(data) { + + var pdpReceived = utilService.transformOne(data, 'pdps'); + + + $translate('moon.policy.map.success', {pdpName: pdpReceived.name, policyName: map.selectedPolicy.name}).then(function (translatedValue) { + + alertService.alertSuccess(translatedValue); + + }); + + map.mappingLoading = false; + + $scope.$emit('event:policyMapToPdpSuccess', pdpReceived); + + } + + function mapError(response) { + + $translate('moon.policy.map.error', { + + pdpName: map.pdp.name, + policyName: map.selectedPolicy.name + + }).then(function (translatedValue) { + + alertService.alertError(translatedValue); + + }); + + map.mappingLoading = false; + + $scope.$emit('event:policyMapToPdpError'); + + } + } + + + + } + +})();
\ No newline at end of file diff --git a/moon_gui/static/app/policy/action/mapping/policy.controller.unmap.js b/moon_gui/static/app/policy/action/mapping/policy.controller.unmap.js new file mode 100755 index 00000000..d309ec0f --- /dev/null +++ b/moon_gui/static/app/policy/action/mapping/policy.controller.unmap.js @@ -0,0 +1,74 @@ +/** + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('PolicyUnMapController', PolicyUnMapController); + + PolicyUnMapController.$inject = ['$scope', '$translate', 'alertService', 'pdpService', 'utilService']; + + function PolicyUnMapController($scope, $translate, alertService, pdpService, utilService) { + + var unmap = this; + + /* + * + */ + + unmap.pdp = $scope.pdp; + unmap.policy = $scope.policy; + + unmap.unMappingLoading = false; + + unmap.unmap = unMapPolicyToPdp; + + /* + * + */ + + function unMapPolicyToPdp() { + + unmap.unMappingLoading = true; + + var pdpToUpdate = angular.copy(unmap.pdp); + + pdpToUpdate.security_pipeline = _.without(pdpToUpdate.security_pipeline, unmap.policy.id); + + pdpService.update(pdpToUpdate, unMapSuccess, unMapError); + + function unMapSuccess(data) { + + $translate('moon.policy.unmap.success', { pdpName: unmap.pdp.name, policyName: unmap.policy.name }) + .then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + unmap.unMappingLoading = false; + + $scope.$emit('event:policyUnMappedToPdpSuccess', utilService.transformOne(data, 'pdps')); + + } + + function unMapError(reason) { + + $translate('moon.policy.unmap.error', { pdpName: unmap.pdp.name, policyName: unmap.policy.name }) + .then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + unmap.unMappingLoading = false; + + $scope.$emit('event:policyUnMappedToPdpError'); + + } + + } + + } + +})(); diff --git a/moon_gui/static/app/policy/action/policy-add.tpl.html b/moon_gui/static/app/policy/action/policy-add.tpl.html new file mode 100755 index 00000000..d20c41be --- /dev/null +++ b/moon_gui/static/app/policy/action/policy-add.tpl.html @@ -0,0 +1,113 @@ +<div ng-controller="PolicyAddController as add" class="modal" tabindex="-1" data-role="modalAddPolicy"> + + <div class="modal-dialog"> + + <div class="modal-content"> + + <div class="modal-header"> + <button type="button" class="close" ng-click="$hide()">×</button> + <h4 class="modal-title" data-translate="moon.policy.add.title"></h4> + </div> + + <div class="modal-body"> + + <form class="form-horizontal" role="form" name="add.form"> + + <div class="form-group" ng-class="{'has-error': add.form.name.$invalid && add.form.name.$dirty}"> + + <label for="name" class="col-sm-3 control-label" data-translate="moon.policy.add.form.name">Name</label> + + <div class="col-sm-6"> + + <input name="name" id="name" class="form-control" type="text" data-ng-model="add.policy.name" required /> + + <div class="help-block" ng-show="add.form.name.$dirty && add.form.name.$invalid"> + <small class="error" ng-show="add.form.name.$error.required" data-translate="moon.policy.add.check.name.required">Name is required</small> + </div> + + </div> + + </div> + + + <div class="form-group" ng-class="{'has-error': add.form.genre.$dirty && (add.form.genre.$invalid || !add.selectedGenre)}"> + + <label class="col-sm-3 control-label" data-translate="moon.policy.add.form.genre">Genre</label> + + <div class="col-sm-6"> + + <ui-select ng-model="add.selectedGenre" name="genre" required> + <ui-select-match placeholder="(None)">{{$select.selected}}</ui-select-match> + <ui-select-choices repeat="genre in add.genres"> + <div ng-value="genre">{{genre}}</div> + </ui-select-choices> + </ui-select> + + <div class="help-block" ng-show="add.form.genre.$dirty && (add.form.genre.$invalid || !add.selectedPolicy)"> + <small class="error" ng-show="add.form.genre.$error.required" data-translate="moon.policy.add.check.genre.required">Genre is required</small> + </div> + + </div> + + </div> + + <div class="form-group" ng-class="{'has-error': add.form.model.$dirty && (add.form.model.$invalid || !add.selectedModel)}"> + + <label class="col-sm-3 control-label" data-translate="moon.policy.add.form.model">Models</label> + + <div class="col-sm-6"> + + <ui-select ng-model="add.selectedModel" name="model" required> + <ui-select-match placeholder="(None)">{{$select.selected.name}}</ui-select-match> + <ui-select-choices repeat="model in add.models"> + <div ng-value="model">{{model.name}}</div> + </ui-select-choices> + </ui-select> + + <moon-loader ng-if="add.modelsLoading"></moon-loader> + + <div class="help-block" ng-show="add.form.model.$dirty && (add.form.model.$invalid || !add.selectedModel)"> + <small class="error" ng-show="add.form.model.$error.required" data-translate="moon.policy.add.check.model.required">Model is required</small> + </div> + + </div> + + </div> + + + <div class="form-group"> + + <label for="description" class="col-sm-3 control-label" data-translate="moon.policy.add.form.description">Description</label> + <div class="col-sm-6"> + <textarea id="description" name="description" class="form-control" data-ng-model="add.policy.description"></textarea> + </div> + + </div> + + </form> + + </div> + + <div class="modal-footer"> + + <div class="btn-toolbar" style="float: right;"> + + <a href="" ng-click="$hide()" class="btn btn-default"> + <span data-translate="moon.policy.add.action.cancel">Cancel</span> + </a> + + <a href="" ng-disabled="add.loading" ng-click="add.create()" class="btn btn-warning"> + <span class="glyphicon glyphicon-save"></span> + <span data-translate="moon.policy.add.action.create">Create Policy</span> + </a> + <moon-loader ng-if="add.loading"></moon-loader> + + </div> + + </div> + + </div> + + </div> + +</div> diff --git a/moon_gui/static/app/policy/action/policy-delete.tpl.html b/moon_gui/static/app/policy/action/policy-delete.tpl.html new file mode 100755 index 00000000..3b5df88b --- /dev/null +++ b/moon_gui/static/app/policy/action/policy-delete.tpl.html @@ -0,0 +1,40 @@ +<div ng-controller="PolicyDeleteController as del" class="modal" tabindex="-1" data-role="modalDeletePolicy"> + + <div class="modal-dialog"> + + <div class="modal-content"> + + <div class="modal-header"> + <button type="button" class="close" ng-click="$hide()">×</button> + <h4 class="modal-title" data-translate="moon.policy.remove.title"></h4> + </div> + + <div class="modal-body"> + <p><span data-translate="moon.policy.remove.content.query" data-translate-values="{ policyName: del.policy.name }"></span></p> + + </div> + + <div class="modal-footer"> + + <div class="btn-toolbar" style="float: right;"> + + <a href="" ng-click="$hide()" class="btn btn-default"> + <span data-translate="moon.policy.remove.action.cancel">Cancel</span> + </a> + + <a href="" ng-disabled="del.loading" ng-click="del.remove()" class="btn btn-warning"> + <span class="glyphicon glyphicon-trash"></span> + <span data-translate="moon.policy.remove.action.delete">Delete</span> + </a> + + <moon-loader ng-if="del.loading" ></moon-loader> + + </div> + + </div> + + </div> + + </div> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/policy/action/policy.controller.add.js b/moon_gui/static/app/policy/action/policy.controller.add.js new file mode 100755 index 00000000..0320c2e9 --- /dev/null +++ b/moon_gui/static/app/policy/action/policy.controller.add.js @@ -0,0 +1,113 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('PolicyAddController', PolicyAddController); + + PolicyAddController.$inject = ['$scope', '$translate', 'alertService', 'formService', 'policyService', 'utilService', 'modelService']; + + function PolicyAddController($scope, $translate, alertService, formService, policyService, utilService, modelService) { + + var add = this; + + /* + * + */ + + add.loading = false; + + add.form = {}; + + add.policy = {name: null, genre: null, description: null, model_id: null}; + + add.genres = ['admin', 'authz']; + + add.models = []; + + add.modelsLoading = true; + + add.create = createPolicy; + + + activate(); + + function activate(){ + + resolveModels(); + + } + + /* + * + */ + + function resolveModels() { + + modelService.findAllWithCallBack(resolveModelsCallback); + + } + + function resolveModelsCallback(models) { + + add.models = models; + + add.modelsLoading = false; + + } + + + function createPolicy() { + + if(formService.isInvalid(add.form)) { + + formService.checkFieldsValidity(add.form); + + } else { + + + add.loading = true; + + policyService.data.policy.create({}, { + + name: add.policy.name, + description: add.policy.description, + genre: [add.selectedGenre], + model_id: add.selectedModel.id + + }, createSuccess, createError); + + } + + function createSuccess(data) { + + var createdPolicy = utilService.transformOne(data, 'policies'); + + $translate('moon.policy.add.success', { policyName: createdPolicy.name }).then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + add.loading = false; + + $scope.$emit('event:policyCreatedSuccess', createdPolicy); + + } + + function createError(reason) { + + $translate('moon.policy.add.error', { policyName: add.model.name }).then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + add.loading = false; + + $scope.$emit('event:policyCreatedError', add.project); + + } + + } + + } + +})(); diff --git a/moon_gui/static/app/policy/action/policy.controller.delete.js b/moon_gui/static/app/policy/action/policy.controller.delete.js new file mode 100755 index 00000000..9a718ddc --- /dev/null +++ b/moon_gui/static/app/policy/action/policy.controller.delete.js @@ -0,0 +1,69 @@ + +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('PolicyDeleteController', PolicyDeleteController); + + PolicyDeleteController.$inject = ['$scope', '$translate', 'alertService', 'policyService']; + + function PolicyDeleteController($scope, $translate, alertService, policyService) { + + var del = this; + + /* + * + */ + + del.policy = $scope.policy; + del.loading = false; + + del.remove = deletePolicy; + + activate(); + + /** + * + */ + + function activate(){ + + } + + + function deletePolicy(){ + + del.loading = true; + + policyService.delete(del.policy, deleteSuccess, deleteError); + + function deleteSuccess(data) { + + $translate('moon.policy.remove.success', { policyName: del.policy.name }).then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + del.loading = false; + + $scope.$emit('event:policyDeletedSuccess', del.policy); + + } + + function deleteError(reason) { + + $translate('moon.policy.remove.error', { policyName: del.policy.name, errorCode: reason.data.error.code, message : reason.data.error.message } ).then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + del.loading = false; + + $scope.$emit('event:policyDeletedError', del.policy); + + } + + } + } + +})(); diff --git a/moon_gui/static/app/policy/edit/parameter/assignments/assignments-edit.tpl.html b/moon_gui/static/app/policy/edit/parameter/assignments/assignments-edit.tpl.html new file mode 100755 index 00000000..9069dcd0 --- /dev/null +++ b/moon_gui/static/app/policy/edit/parameter/assignments/assignments-edit.tpl.html @@ -0,0 +1,165 @@ +<div> + + <div class="col-md-12 col-sm-12 col-xs-12"> + + <form ng-if="!edit.fromList" class="form-horizontal" role="form" name="edit.form"> + + <!-- Select Policy --> + <div class="form-group" ng-class="{'has-error': edit.form.policyList.$invalid && edit.form.policyList.$dirty}" > + + <label for="policyList" class="col-sm-3 control-label" data-translate="moon.policy.assignments.edit.policies">Policy List</label> + + <div class="col-sm-6" ng-if="edit.loadingPolicies" > + <moon-loader></moon-loader> + </div> + + <div class="col-sm-6" ng-if="!edit.loadingPolicies" > + + <ui-select ng-model="edit.selectedPolicy" name="policyList" id="policyList" required> + + <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match> + <ui-select-choices repeat="aPolicy in edit.policyList"> + <div ng-value="aPolicy" ng-bind="aPolicy.name"></div> + </ui-select-choices> + + </ui-select> + + <div class="help-block" ng-show="edit.form.policyList.$dirty && edit.form.policyList.$invalid"> + <small class="error" ng-show="edit.form.policyList.$error.required" data-translate="moon.policy.assignments.edit.check.policy.required">Policy is required</small> + </div> + + </div> + + </div> + + <!-- Select Perimeter --> + <div class="form-group" ng-class="{'has-error': edit.form.perimeterList.$invalid && edit.form.perimeterList.$dirty}" > + + <label for="perimeterList" class="col-sm-3 control-label" data-translate="moon.policy.assignments.edit.perimeters">Perimeter List</label> + + <div class="col-sm-6" ng-if="edit.loadingPerimeters" > + <moon-loader></moon-loader> + </div> + + <div class="col-sm-6" ng-if="!edit.loadingPerimeters" > + + <ui-select ng-model="edit.selectedPerimeter" name="perimeterList" id="perimeterList" required> + + <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match> + <ui-select-choices repeat="aPerimeter in edit.perimeterList"> + <div ng-value="aPerimeter" ng-bind="aPerimeter.name"></div> + </ui-select-choices> + + </ui-select> + + <div class="help-block" ng-show="edit.form.perimeterList.$dirty && edit.form.perimeterList.$invalid"> + <small class="error" ng-show="edit.form.perimeterList.$error.required" data-translate="moon.policy.assignments.edit.check.perimeter.required">Perimeter is required</small> + </div> + + </div> + + </div> + + <!-- Select Category --> + <div class="form-group" ng-class="{'has-error': edit.form.categoryList.$invalid && edit.form.categoryList.$dirty}" > + + <label for="categoryList" class="col-sm-3 control-label" data-translate="moon.policy.assignments.edit.categories">Category List</label> + + <div class="col-sm-6" ng-if="edit.loadingCategories" > + <moon-loader></moon-loader> + </div> + + <div class="col-sm-6" ng-if="!edit.loadingCategories" > + + <ui-select ng-model="edit.selectedCategory" name="categoryList" id="categoryList" required> + + <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match> + <ui-select-choices repeat="aCategory in edit.categoryList"> + <div ng-value="aCategory" ng-bind="aCategory.name"></div> + </ui-select-choices> + + </ui-select> + + <div class="help-block" ng-show="edit.form.categoryList.$dirty && edit.form.categoryList.$invalid"> + <small class="error" ng-show="edit.form.categoryList.$error.required" data-translate="moon.policy.assignments.edit.check.category.required">Category is required</small> + </div> + + </div> + + </div> + + <!-- Select Data --> + <div class="form-group" ng-if="edit.selectedCategory" ng-class="{'has-error': edit.form.dataList.$invalid && edit.form.dataList.$dirty}" > + + <label for="dataList" class="col-sm-3 control-label" data-translate="moon.policy.assignments.edit.data">Data List</label> + + <div class="col-sm-6" ng-if="edit.loadingData" > + <moon-loader></moon-loader> + </div> + + <div class="col-sm-4" ng-if="!edit.loadingData" > + + <ui-select ng-model="edit.selectedData" name="dataList" id="dataList"> + + <ui-select-match placeholder="(None)" ng-bind="edit.getName($select.selected)"></ui-select-match> + <ui-select-choices repeat="aData in edit.dataToBeSelected"> + <div ng-value="aData" ng-bind="edit.getName(aData)"></div> + </ui-select-choices> + + </ui-select> + + <div class="help-block" ng-show="edit.form.dataList.$dirty && edit.form.dataList.$invalid || !edit.assignementsAttributeValid"> + <small class="error" ng-show="edit.form.dataList.$error.required || !edit.assignementsAttributeValid" data-translate="moon.policy.assignments.edit.check.data.required">Data is required</small> + </div> + + </div> + + <div class="col-sm-2 text-center"> + <a href="" ng-if="edit.selectedData" + ng-click="edit.addSelectedData()"><span style="font-size:1.5em; line-height: 1.5em;" class="glyphicon glyphicon-plus-sign"></span></a> + </div> + + </div> + + <!-- Selected DataList --> + <div class="form-group" ng-if="!edit.loadingData"> + + <label class="col-sm-3 control-label" data-translate="moon.policy.assignments.edit.selectedData">Selected Data)</label> + + <div class="col-sm-6"> + + <ul> + + <li ng-repeat="(key, value) in edit.selectedDataList"> + + <span ng-bind="edit.getName(value)" ></span> <a href="" ng-click="edit.removeSelectedData(value)"><span style="font-size:1.5em; line-height: 1.5em" class="glyphicon glyphicon-remove"></span></a> + + </li> + + </ul> + + </div> + + </div> + + <div class="form-group"> + + <div class="pull-right"> + + <a href="" ng-disabled="edit.loading" ng-click="edit.create()" class="btn btn-warning"> + <span class="glyphicon glyphicon-save"></span> + <span data-translate="moon.policy.assignments.edit.action.create">Create</span> + </a> + + <moon-loader ng-if="edit.loading"></moon-loader> + + </div> + + </div> + + + </form> + + </div> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/policy/edit/parameter/assignments/assignments-list.tpl.html b/moon_gui/static/app/policy/edit/parameter/assignments/assignments-list.tpl.html new file mode 100755 index 00000000..34bbc7a8 --- /dev/null +++ b/moon_gui/static/app/policy/edit/parameter/assignments/assignments-list.tpl.html @@ -0,0 +1,335 @@ +<div> + <div class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.policy.assignments.subject.title">List of associated Subjects</h4> + + </div> + + <div class="panel-body"> + + <div class="table-responsive"> + + <table class="table table-striped"> + + <thead> + <tr> + <th data-translate="moon.policy.assignments.table.perimeter.name">Perimeter name</th> + <th data-translate="moon.policy.assignments.table.category.name">Category name</th> + <th data-translate="moon.policy.assignments.table.data.name">Data name</th></tr> + </thead> + + <moon-loader ng-if="list.loadingSub"></moon-loader> + + <tbody ng-if="!list.loadingSub && list.getSubjects().length > 0"> + + <tr ng-repeat="(key, value) in list.subjects"> + + <td> + + <div ng-if="!list.getPerimeterFromAssignment(value, list.typeOfSubject)"> + <moon-loader ng-if="!list.getPerimeterFromAssignment(value)" ></moon-loader> + <em data-translate="moon.policy.assignments.table.loading.perimeter">Loading </em> + </div> + + <div ng-if="list.getPerimeterFromAssignment(value)"> + <span ng-bind="value.perimeter.name"></span> + </div> + + </td> + + <td> + + <div ng-if="!list.getCategoryFromAssignment(value, list.typeOfSubject)"> + <moon-loader ng-if="!list.getCategoryFromAssignment(value)" ></moon-loader> + <em data-translate="moon.policy.assignments.table.loading.category">Loading </em> + </div> + + <div ng-if="list.getCategoryFromAssignment(value)"> + <span ng-bind="value.category.name"></span> + </div> + + </td> + + <td> + + <span ng-repeat="(index, id) in value.assignments"> + + <span ng-if="!list.getDataFromAssignmentsIndex(index, value, list.typeOfSubject)"> + <moon-loader ng-if="!list.getDataFromAssignmentsIndex(index, value, list.typeOfSubject)" ></moon-loader> + </span> + + <span ng-if="list.getDataFromAssignmentsIndex(index, value, list.typeOfSubject)"> + <span ng-bind="value.assignments_value[index].data.name"></span> + <a href="" ng-if="!value.loader" ng-click="list.deleteSub(value, value.assignments_value[index].data.id)" > + <span>(</span><span class="glyphicon glyphicon-transfer"></span><span>)</span> + </a> + <span ng-if="index < value.assignments.length-1">, </span> + </span> + + </span> + + </td> + + <td> + + <div ng-if="value.loader"> + + <moon-loader></moon-loader> + + </div> + + </td> + + </tr> + </tbody> + + + <tbody ng-if="!list.loadingSub && list.getSubjects().length === 0"> + <tr> + <td data-translate="moon.policy.assignments.subject.notFound">There is no Subjects</td> + <td></td> + <td></td> + </tr> + </tbody> + + </table> + + </div> + + </div> + + </div> + + <div ng-if="list.editMode" class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.policy.assignments.subject.add.title">Add a Subject Category</h4> + + </div> + + <div class="panel-body"> + + <moon-assignments-edit policy="list.policy" assignments-type="list.typeOfSubject"></moon-assignments-edit> + + </div> + + </div> + + <div class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.policy.assignments.object.title">List associated of Objects</h4> + + </div> + + <div class="panel-body"> + + <div class="table-responsive"> + + <table class="table table-striped"> + + <thead> + <tr> + <th data-translate="moon.policy.assignments.table.perimeter.name">Perimeter name</th> + <th data-translate="moon.policy.assignments.table.category.name">Category name</th> + <th data-translate="moon.policy.assignments.table.data.name">Data name</th> + </tr> + </thead> + + <moon-loader ng-if="list.loadingObj"></moon-loader> + + <tbody ng-if="!list.loadingObj && list.getObjects().length > 0"> + <tr ng-repeat="(key, value) in list.objects"> + <td> + + <div ng-if="!list.getPerimeterFromAssignment(value, list.typeOfObject)"> + <moon-loader ng-if="!list.getPerimeterFromAssignment(value)" ></moon-loader> + <em data-translate="moon.policy.assignments.table.loading.perimeter">Loading </em> + </div> + + <div ng-if="list.getPerimeterFromAssignment(value)"> + <span ng-bind="value.perimeter.name"></span> + </div> + + </td> + + <td> + + <div ng-if="!list.getCategoryFromAssignment(value, list.typeOfObject)"> + <moon-loader ng-if="!list.getCategoryFromAssignment(value)" ></moon-loader> + <em data-translate="moon.policy.assignments.table.loading.category">Loading </em> + </div> + + <div ng-if="list.getCategoryFromAssignment(value)"> + <span ng-bind="value.category.name"></span> + </div> + + </td> + + <td> + <span ng-repeat="(index, id) in value.assignments"> + + <span ng-if="!list.getDataFromAssignmentsIndex(index, value, list.typeOfObject)"> + <moon-loader ng-if="!list.getDataFromAssignmentsIndex(index, value, list.typeOfObject)" ></moon-loader> + </span> + + <span ng-if="list.getDataFromAssignmentsIndex(index, value, list.typeOfObject)"> + + <span ng-if="value.assignments_value[index].data.name" ng-bind="value.assignments_value[index].data.name"></span> + <span ng-if="value.assignments_value[index].data.value.name" ng-bind="value.assignments_value[index].data.value.name"></span> + <a href="" ng-if="!value.loader" ng-click="list.deleteObj(value, value.assignments_value[index].data.id)" > + <span>(</span><span class="glyphicon glyphicon-transfer"></span><span>)</span> + </a> + <span ng-if="index < value.assignments.length-1">, </span> + </span> + + </span> + </td> + + </tr> + </tbody> + + <tbody ng-if="!list.loadingObj && list.getObjects().length === 0"> + <tr> + <td data-translate="moon.policy.assignments.object.notFound">There is no Objects</td> + <td></td> + <td></td> + </tr> + </tbody> + + </table> + + </div> + + </div> + + </div> + + <div ng-if="list.editMode" class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.policy.assignments.object.add.title">Add an Object Category</h4> + + </div> + + <div class="panel-body"> + + <moon-assignments-edit policy="list.policy" assignments-type="list.typeOfObject"></moon-assignments-edit> + + </div> + + </div> + + <div class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.policy.assignments.action.title">List associated of Actions</h4> + + </div> + + <div class="panel-body"> + + <div class="table-responsive"> + + <table class="table table-striped"> + + <thead> + <tr> + <th data-translate="moon.policy.assignments.table.perimeter.name">Perimeter name</th> + <th data-translate="moon.policy.assignments.table.category.name">Category name</th> + <th data-translate="moon.policy.assignments.table.data.name">Data name</th> + </tr> + </thead> + + <moon-loader ng-if="list.loadingAct"></moon-loader> + + <tbody ng-if="!list.loadingAct && list.getActions().length > 0"> + <tr ng-repeat="(key, value) in list.actions"> + + <td> + <div ng-if="!list.getPerimeterFromAssignment(value, list.typeOfAction)"> + <moon-loader ng-if="!list.getPerimeterFromAssignment(value)" ></moon-loader> + <em data-translate="moon.policy.assignments.table.loading.perimeter">Loading </em> + </div> + + <div ng-if="list.getPerimeterFromAssignment(value)"> + <span ng-bind="value.perimeter.name"></span> + </div> + </td> + + <td> + + <div ng-if="!list.getCategoryFromAssignment(value, list.typeOfAction)"> + <moon-loader ng-if="!list.getCategoryFromAssignment(value)" ></moon-loader> + <em data-translate="moon.policy.assignments.table.loading.category">Loading </em> + </div> + + <div ng-if="list.getCategoryFromAssignment(value)"> + <span ng-bind="value.category.name"></span> + </div> + + </td> + + <td> + + <span ng-repeat="(index, id) in value.assignments"> + + <span ng-if="!list.getDataFromAssignmentsIndex(index, value, list.typeOfAction)"> + <moon-loader ng-if="!list.getDataFromAssignmentsIndex(index, value, list.typeOfAction)" ></moon-loader> + </span> + + <span ng-if="list.getDataFromAssignmentsIndex(index, value, list.typeOfAction)"> + <span ng-if="value.assignments_value[index].data.name" ng-bind="value.assignments_value[index].data.name"></span> + <span ng-if="value.assignments_value[index].data.value.name" ng-bind="value.assignments_value[index].data.value.name"></span> + <a href="" ng-if="!value.loader" ng-click="list.deleteAct(value, value.assignments_value[index].data.id)" > + <span>(</span><span class="glyphicon glyphicon-transfer"></span><span>)</span> + </a> + <span ng-if="index < value.assignments.length-1">, </span> + </span> + + </span> + + </td> + </tr> + </tbody> + + <tbody ng-if="!list.loadingAct && list.getActions().length === 0"> + <tr> + <td data-translate="moon.policy.assignments.action.notFound">There is no Actions</td> + <td></td> + <td></td> + </tr> + </tbody> + + </table> + + </div> + + + </div> + + </div> + + <div ng-if="list.editMode" class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.policy.assignments.action.add.title">Add an Action Category</h4> + + </div> + + <div class="panel-body">. + + <moon-assignments-edit policy="list.policy" assignments-type="list.typeOfAction"></moon-assignments-edit> + + </div> + + </div> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/policy/edit/parameter/assignments/assignments.edit.dir.js b/moon_gui/static/app/policy/edit/parameter/assignments/assignments.edit.dir.js new file mode 100755 index 00000000..5297eccb --- /dev/null +++ b/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/moon_gui/static/app/policy/edit/parameter/assignments/assignments.list.dir.js b/moon_gui/static/app/policy/edit/parameter/assignments/assignments.list.dir.js new file mode 100755 index 00000000..22931e4d --- /dev/null +++ b/moon_gui/static/app/policy/edit/parameter/assignments/assignments.list.dir.js @@ -0,0 +1,393 @@ +(function () { + + 'use strict'; + + angular + .module('moon') + .directive('moonAssignmentsList', moonAssignmentsList); + + moonAssignmentsList.$inject = []; + + function moonAssignmentsList() { + + return { + templateUrl: 'html/policy/edit/parameter/assignments/assignments-list.tpl.html', + bindToController: true, + controller: moonAssignmentsListController, + controllerAs: 'list', + scope: { + policy: '=', + editMode: '=' + }, + restrict: 'E', + replace: true + }; + } + + angular + .module('moon') + .controller('moonAssignmentsListController', moonAssignmentsListController); + + moonAssignmentsListController.$inject = ['$scope', '$rootScope', 'assignmentsService', '$translate', 'alertService', + 'policyService', 'ASSIGNMENTS_CST', 'utilService', 'metaDataService', 'perimeterService', 'dataService']; + + function moonAssignmentsListController($scope, $rootScope, assignmentsService, $translate, alertService, + policyService, ASSIGNMENTS_CST, utilService, metaDataService, perimeterService, dataService) { + + var list = this; + + list.policy = $scope.list.policy; + list.editMode = $scope.list.editMode; + + list.typeOfSubject = ASSIGNMENTS_CST.TYPE.SUBJECT; + list.typeOfObject = ASSIGNMENTS_CST.TYPE.OBJECT; + list.typeOfAction = ASSIGNMENTS_CST.TYPE.ACTION; + + list.deleteSub = deleteSub; + list.deleteObj = deleteObj; + list.deleteAct = deleteAct; + + list.getSubjects = getSubjects; + list.getObjects = getObjects; + list.getActions = getActions; + + list.getCategoryFromAssignment = getCategoryFromAssignment; + list.getPerimeterFromAssignment = getPerimeterFromAssignment; + list.getDataFromAssignmentsIndex = getDataFromAssignmentsIndex; + + activate(); + + function activate() { + + manageSubjects(); + + manageObjects(); + + manageActions(); + + } + + var rootListeners = { + + 'event:createAssignmentsFromAssignmentsEditSuccess': $rootScope.$on('event:createAssignmentsFromAssignmentsEditSuccess', updateList) + + }; + + _.each(rootListeners, function(unbind){ + $scope.$on('$destroy', rootListeners[unbind]); + }); + + function manageSubjects() { + + list.loadingSub = true; + + assignmentsService.subject.findAllFromPolicyWithCallback(list.policy.id, function (data) { + + list.subjects = data; + list.loadingSub = false; + + }); + } + + function manageObjects() { + + list.loadingObj = true; + + assignmentsService.object.findAllFromPolicyWithCallback(list.policy.id, function (data) { + + list.objects = data; + list.loadingObj = false; + + }); + + } + + function manageActions() { + + list.loadingAct = true; + + assignmentsService.action.findAllFromPolicyWithCallback(list.policy.id, function (data) { + + list.actions = data; + list.loadingAct = false; + + }); + + } + + function getPerimeterFromAssignment(assignment, type) { + + if (_.has(assignment, 'perimeter')) { + return assignment.perimeter; + } + + // if the call has not been made + if (!_.has(assignment, 'callPerimeterInProgress')) { + + assignment.callPerimeterInProgress = true; + + switch (type) { + + case ASSIGNMENTS_CST.TYPE.SUBJECT: + perimeterService.subject.findOneFromPolicyWithCallback(list.policy.id, assignment.subject_id, setPerimeterToAssignment); + break; + + case ASSIGNMENTS_CST.TYPE.OBJECT: + perimeterService.object.findOneFromPolicyWithCallback(list.policy.id, assignment.object_id, setPerimeterToAssignment); + break; + + case ASSIGNMENTS_CST.TYPE.ACTION: + perimeterService.action.findOneFromPolicyWithCallback(list.policy.id, assignment.action_id, setPerimeterToAssignment); + break; + + } + + } + + // if the call is in progress return false + return false; + + function setPerimeterToAssignment(perimeter) { + + assignment.callPerimeterInProgress = false; + assignment.perimeter = perimeter; + + } + } + + function getCategoryFromAssignment(data, type) { + + if (_.has(data, 'category')) { + return data.category; + } + + // if the call has not been made + if (!_.has(data, 'callCategoryInProgress')) { + + data.callCategoryInProgress = true; + + switch (type) { + + case ASSIGNMENTS_CST.TYPE.SUBJECT: + metaDataService.subject.findOne(data.subject_cat_id, setCategoryToData); + break; + + case ASSIGNMENTS_CST.TYPE.OBJECT: + metaDataService.object.findOne(data.object_cat_id, setCategoryToData); + break; + + case ASSIGNMENTS_CST.TYPE.ACTION: + metaDataService.action.findOne(data.action_cat_id, setCategoryToData); + break; + + } + + } + + // if the call is in progress return false + return false; + + function setCategoryToData(category) { + + data.callCategoryInProgress = false; + data.category = category; + + } + } + + /** + * @param index + * @param assignment + * @param type + */ + function getDataFromAssignmentsIndex(index, assignment, type) { + + if (!_.has(assignment, 'assignments_value')) { + // setting an array which will contains every value of the category + assignment.assignments_value = Array.apply(null, new Array(assignment.assignments.length)).map(function () { + return { + data: {} + }; + }); + } + + if (_.has(assignment.assignments_value[index], 'callDataInProgress') && !assignment.assignments_value[index].callDataInProgress) { + return assignment.assignments_value[index].data; + } + + // if the call has not been made + if (!_.has(assignment.assignments_value[index], 'callDataInProgress')) { + + assignment.assignments_value[index].callDataInProgress = true; + + switch (type) { + + case ASSIGNMENTS_CST.TYPE.SUBJECT: + dataService.subject.data.findOne(list.policy.id, assignment.category_id, assignment.assignments[index], setDataToAssignment); + break; + + case ASSIGNMENTS_CST.TYPE.OBJECT: + dataService.object.data.findOne(list.policy.id, assignment.category_id, assignment.assignments[index], setDataToAssignment); + break; + + case ASSIGNMENTS_CST.TYPE.ACTION: + dataService.action.data.findOne(list.policy.id, assignment.category_id, assignment.assignments[index], setDataToAssignment); + break; + + } + + } + + // if the call is in progress return false + return false; + + function setDataToAssignment(data) { + + assignment.assignments_value[index].callDataInProgress = false; + assignment.assignments_value[index].data = data; + + } + } + + /** + * Delete + */ + + function deleteSub(subject, dataId) { + + subject.loader = true; + + assignmentsService.subject.delete(list.policy.id, subject.subject_id, subject.subject_cat_id, dataId, deleteSubSuccess, deleteSubError); + + function deleteSubSuccess(data) { + + $translate('moon.policy.assignments.subject.delete.success').then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + manageSubjects(); + + subject.loader = false; + + } + + function deleteSubError(reason) { + + $translate('moon.policy.assignments.subject.delete.error', { + subjectName: subject.name, + reason: reason.message + }).then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + subject.loader = false; + + } + } + + function deleteObj(object, dataId) { + + object.loader = true; + + assignmentsService.object.delete(list.policy.id, object.object_id, object.object_cat_id, dataId, deleteObjSuccess, deleteObjError); + + function deleteObjSuccess(data) { + + $translate('moon.policy.assignments.object.delete.success').then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + manageObjects(); + + object.loader = false; + + } + + function deleteObjError(reason) { + + $translate('moon.policy.assignments.object.delete.error', { + objectName: object.name, + reason: reason.message + }).then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + object.loader = false; + } + } + + function deleteAct(action, dataId) { + + action.loader = true; + + assignmentsService.action.delete(list.policy.id, action.action_id, action.action_cat_id, dataId, deleteActSuccess, deleteActError); + + function deleteActSuccess(data) { + + $translate('moon.policy.assignments.action.delete.success').then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + manageActions(); + + action.loader = false; + + } + + function deleteActError(reason) { + + $translate('moon.policy.assignments.action.delete.error', { + actionName: action.name, + reason: reason.message + }).then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + action.loader = false; + + } + } + + function getSubjects() { + return list.subjects ? list.subjects : []; + } + + function getObjects() { + return list.objects ? list.objects : []; + } + + function getActions() { + return list.actions ? list.actions : []; + } + + function updateList(event, type) { + + switch(type){ + + case ASSIGNMENTS_CST.TYPE.SUBJECT: + + manageSubjects(); + break; + + case ASSIGNMENTS_CST.TYPE.OBJECT: + + manageObjects(); + break; + + case ASSIGNMENTS_CST.TYPE.ACTION: + + manageActions(); + break; + + default : + + activate(); + break; + + } + + } + + } + +})();
\ No newline at end of file diff --git a/moon_gui/static/app/policy/edit/parameter/data/data-edit.tpl.html b/moon_gui/static/app/policy/edit/parameter/data/data-edit.tpl.html new file mode 100755 index 00000000..3f11a641 --- /dev/null +++ b/moon_gui/static/app/policy/edit/parameter/data/data-edit.tpl.html @@ -0,0 +1,110 @@ +<div> + + <div class="col-md-12 col-sm-12 col-xs-12"> + + <form ng-if="!edit.fromList" class="form-horizontal" role="form" name="edit.form"> + + <div class="form-group" ng-class="{'has-error': edit.form.name.$invalid && edit.form.name.$dirty}"> + + <label for="name" class="col-sm-3 control-label" + data-translate="moon.policy.data.edit.name">Name</label> + + <div class="col-sm-6"> + + <input name="name" id="name" class="form-control" type="text" data-ng-model="edit.data.name" + required/> + + <div class="help-block" ng-show="edit.form.name.$dirty && edit.form.name.$invalid"> + <small class="error" ng-show="edit.form.name.$error.required" + data-translate="moon.policy.data.edit.check.name.required">Name is required + </small> + </div> + + </div> + + </div> + + <div class="form-group"> + + <label for="description" class="col-sm-3 control-label" + data-translate="moon.policy.data.edit.description">Description</label> + <div class="col-sm-6"> + <textarea id="description" name="description" class="form-control" + data-ng-model="edit.data.description"></textarea> + </div> + + </div> + + <div class="form-group" + ng-class="{'has-error': edit.form.policyList.$invalid && edit.form.policyList.$dirty}"> + + <label for="policyList" class="col-sm-3 control-label" data-translate="moon.policy.data.edit.policies">Policy + List </label> + + <div class="col-sm-6"> + + <ui-select ng-model="edit.selectedPolicy" name="policyList" id="policyList" required> + + <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match> + <ui-select-choices repeat="aPolicy in edit.policyList"> + <div ng-value="aPolicy" ng-bind="aPolicy.name"></div> + </ui-select-choices> + + </ui-select> + + <div class="help-block" ng-show="edit.form.policyList.$dirty && edit.form.policyList.$invalid"> + <small class="error" ng-show="edit.form.policyList.$error.required" + data-translate="moon.policy.data.edit.check.policy.required">Policy is required + </small> + </div> + + </div> + + </div> + + <div class="form-group" + ng-class="{'has-error': edit.form.categoryList.$invalid && edit.form.categoryList.$dirty}"> + + <label for="categoryList" class="col-sm-3 control-label" + data-translate="moon.policy.data.edit.categories">Category List </label> + + <div class="col-sm-6"> + + <ui-select ng-model="edit.selectedCategory" name="categoryList" id="categoryList" required> + + <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match> + <ui-select-choices repeat="aCategory in edit.categoriesToBeSelected"> + <div ng-value="aCategory" ng-bind="aCategory.name"></div> + </ui-select-choices> + + </ui-select> + + <div class="help-block" ng-show="edit.form.categoryList.$dirty && edit.form.categoryList.$invalid"> + <small class="error" ng-show="edit.form.categoryList.$error.required" + data-translate="moon.policy.data.edit.check.category.required">Category is required + </small> + </div> + + </div> + </div> + + <div class="form-group"> + + <div class="pull-right"> + + <a href="" ng-disabled="edit.loading" ng-click="edit.create()" class="btn btn-warning"> + <span class="glyphicon glyphicon-save"></span> + <span data-translate="moon.policy.data.edit.action.create">Create</span> + </a> + + <moon-loader ng-if="edit.loading"></moon-loader> + + </div> + + </div> + + </form> + + </div> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/policy/edit/parameter/data/data-list.tpl.html b/moon_gui/static/app/policy/edit/parameter/data/data-list.tpl.html new file mode 100755 index 00000000..b69a4eed --- /dev/null +++ b/moon_gui/static/app/policy/edit/parameter/data/data-list.tpl.html @@ -0,0 +1,390 @@ +<div> + <div class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.policy.data.subject.title">List of associated Subjects</h4> + + </div> + + <div class="panel-body"> + + <div class="table-responsive"> + + <table class="table table-striped"> + + <thead> + <tr> + <th data-translate="moon.policy.data.table.name">Name</th> + <th data-translate="moon.policy.data.table.description">Description</th> + <th data-translate="moon.policy.data.table.category.name">Category</th> + <th data-translate="moon.policy.data.table.action.title"></th> + </tr> + </thead> + + <moon-loader ng-if="list.loadingSub"></moon-loader> + + <tbody ng-if="!list.loadingSub && list.getSubjects().length > 0"> + <tr ng-repeat="(key, value) in list.subjects"> + <td ng-bind="value.name"></td> + <td ng-bind="value.description"></td> + <td> + + <div ng-if="!list.getCategoryFromData(value, list.typeOfSubject)"> + <moon-loader ng-if="!list.getCategoryFromData(value)" ></moon-loader> + <em data-translate="moon.policy.list.table.loading.category">Loading </em> + </div> + + <div ng-if="list.getCategoryFromData(value)"> + <span ng-bind="value.category.name"></span> + </div> + + </td> + + <td> + + <a href="" ng-if="!value.loader" ng-click="list.deleteSub(value)" > + <span class="glyphicon glyphicon-transfer"></span> + <span class="control-label" data-translate="moon.policy.data.table.action.delete">Delete</span> + </a> + + <div ng-if="value.loader"> + + <moon-loader></moon-loader> + + </div> + + </td> + + + <!--<td> + + <div class="dropdown"> + + <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown"> + <span data-translate="moon.policy.data.table.action.title">Actions</span> + <span class="caret"></span> + </button> + + <ul class="dropdown-menu"> + + <li> + <a href="" ng-click="list.unMapSub(value)" > + <span class="glyphicon glyphicon-transfer"></span> + <span class="control-label" data-translate="moon.model.metarules.action.unmap">Unmap</span> + </a> + </li> + + <li class="divider"></li> + + <li> + <a href="" ng-click="list.deleteSub(value)"> + <span class="glyphicon glyphicon-trash"></span> + <span class="control-label" data-translate="moon.policy.data.table.action.delete">Delete</span> + </a> + </li> + + </ul> + + </div> + + <div ng-if="value.loader"> + + <moon-loader></moon-loader> + + </div> + + </td>--> + + </tr> + </tbody> + + + <tbody ng-if="!list.loadingSub && list.getSubjects().length === 0"> + <tr> + <td colspan="4" data-translate="moon.policy.data.subject.notFound">There is no Subjects</td> + </tr> + </tbody> + + </table> + + </div> + + </div> + + </div> + + <div ng-if="list.editMode" class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.policy.data.subject.add.title">Add a Subject Category</h4> + + </div> + + <div class="panel-body"> + + <moon-data-edit policy="list.policy" mn-data-type="list.typeOfSubject"></moon-data-edit> + + </div> + + </div> + + <div class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.policy.data.object.title">List associated of Objects</h4> + + </div> + + <div class="panel-body"> + + <div class="table-responsive"> + + <table class="table table-striped"> + + <thead> + <tr> + <th data-translate="moon.policy.data.table.name">Name</th> + <th data-translate="moon.policy.data.table.description">Description</th> + <th data-translate="moon.policy.data.table.category.name">Category</th> + <th data-translate="moon.policy.data.table.action.title">Actions</th> + </tr> + </thead> + + <moon-loader ng-if="list.loadingObj"></moon-loader> + + <tbody ng-if="!list.loadingObj && list.getObjects().length > 0"> + <tr ng-repeat="(key, value) in list.objects"> + <td ng-bind="value.value.name"></td> + <td ng-bind="value.value.description"></td> + <td> + + <div ng-if="!list.getCategoryFromData(value, list.typeOfObject)"> + <moon-loader ng-if="!list.getCategoryFromData(value)" ></moon-loader> + <em data-translate="moon.policy.list.table.loading.category">Loading </em> + </div> + + <div ng-if="list.getCategoryFromData(value)"> + <span ng-bind="value.category.name"></span> + </div> + + </td> + + <td> + + <a href="" ng-if="!value.loader" ng-click="list.deleteObj(value)" > + <span class="glyphicon glyphicon-transfer"></span> + <span class="control-label" data-translate="moon.policy.data.table.action.delete">Delete</span> + </a> + + <div ng-if="value.loader"> + + <moon-loader></moon-loader> + + </div> + + </td> + <!--<td> + + <div class="dropdown"> + + <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown"> + <span data-translate="moon.policy.data.table.action.title">Actions</span> + <span class="caret"></span> + </button> + + <ul class="dropdown-menu"> + + <li> + <a href="" ng-click="list.unMapObj(value)" > + <span class="glyphicon glyphicon-transfer"></span> + <span class="control-label" data-translate="moon.model.metarules.action.unmap">Unmap</span> + </a> + </li> + + <li class="divider"></li> + + <li> + <a href="" ng-click="list.deleteObj(value)"> + <span class="glyphicon glyphicon-trash"></span> + <span class="control-label" data-translate="moon.policy.data.table.action.delete">Delete</span> + </a> + </li> + + </ul> + + </div> + + <div ng-if="value.loader"> + + <moon-loader></moon-loader> + + </div> + + </td> + </tr>--> + </tbody> + + <tbody ng-if="!list.loadingObj && list.getObjects().length === 0"> + <tr> + + <td colspan="4" data-translate="moon.policy.data.object.notFound">There is no Objects</td> + + </tr> + </tbody> + + </table> + + </div> + + </div> + + </div> + + <div ng-if="list.editMode" class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.policy.data.object.add.title">Add an Object Category</h4> + + </div> + + <div class="panel-body"> + + <moon-data-edit policy="list.policy" mn-data-type="list.typeOfObject"></moon-data-edit> + + </div> + + </div> + + <div class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.policy.data.action.title">List associated of Actions</h4> + + </div> + + <div class="panel-body"> + + <div class="table-responsive"> + + <table class="table table-striped"> + + <thead> + <tr> + <th data-translate="moon.policy.data.table.name">Name</th> + <th data-translate="moon.policy.data.table.description">Description</th> + <th data-translate="moon.policy.data.table.category.name">Category</th> + <th data-translate="moon.policy.data.table.action.title">Actions</th> + </tr> + </thead> + + <moon-loader ng-if="list.loadingAct"></moon-loader> + + <tbody ng-if="!list.loadingAct && list.getActions().length > 0"> + <tr ng-repeat="(key, value) in list.actions"> + <td ng-bind="value.value.name"></td> + <td ng-bind="value.value.description"></td> + <td> + + <div ng-if="!list.getCategoryFromData(value, list.typeOfAction)"> + <moon-loader ng-if="!list.getCategoryFromData(value)" ></moon-loader> + <em data-translate="moon.policy.list.table.loading.category">Loading </em> + </div> + + <div ng-if="list.getCategoryFromData(value)"> + <span ng-bind="value.category.name"></span> + </div> + + </td> + + <td> + + <a href="" ng-if="!value.loader" ng-click="list.deleteSub(value)" > + <span class="glyphicon glyphicon-transfer"></span> + <span class="control-label" data-translate="moon.policy.data.table.action.delete">Delete</span> + </a> + + <div ng-if="value.loader"> + + <moon-loader></moon-loader> + + </div> + + </td> + <!--<td> + + <div class="dropdown"> + + <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown"> + <span data-translate="moon.policy.data.table.action.title">Actions</span> + <span class="caret"></span> + </button> + + <ul class="dropdown-menu"> + + <li> + <a href="" ng-click="list.unMapAct(value)" > + <span class="glyphicon glyphicon-transfer"></span> + <span class="control-label" data-translate="moon.model.metarules.action.unmap">Unmap</span> + </a> + </li> + + <li class="divider"></li> + + <li> + <a href="" ng-click="list.deleteAct(value)"> + <span class="glyphicon glyphicon-trash"></span> + <span class="control-label" data-translate="moon.policy.data.table.action.delete">Delete</span> + </a> + </li> + + </ul> + + </div> + + <div ng-if="value.loader"> + + <moon-loader></moon-loader> + + </div> + + </td>--> + </tr> + </tbody> + + <tbody ng-if="!list.loadingAct && list.getActions().length === 0"> + <tr> + <td colspan="4" data-translate="moon.policy.data.action.notFound">There is no Actions</td> + </tr> + </tbody> + + </table> + + </div> + + + </div> + + </div> + + <div ng-if="list.editMode" class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.policy.data.action.add.title">Add an Action Category</h4> + + </div> + + <div class="panel-body">. + + <moon-data-edit policy="list.policy" mn-data-type="list.typeOfAction"></moon-data-edit> + + </div> + + </div> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/policy/edit/parameter/data/data.edit.dir.js b/moon_gui/static/app/policy/edit/parameter/data/data.edit.dir.js new file mode 100755 index 00000000..57ad0c9b --- /dev/null +++ b/moon_gui/static/app/policy/edit/parameter/data/data.edit.dir.js @@ -0,0 +1,260 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .directive('moonDataEdit', moonDataEdit); + + moonDataEdit.$inject = []; + + function moonDataEdit() { + + return { + templateUrl : 'html/policy/edit/parameter/data/data-edit.tpl.html', + bindToController : true, + controller : moonDataEditController, + controllerAs : 'edit', + scope : { + //Type can be 'ACTION', 'OBJECT', 'SUBJECT' + mnDataType: '=', + policy : '=' + }, + restrict : 'E', + replace : true + }; + + } + + angular + .module('moon') + .controller('moonDataEditController', moonDataEditController); + + moonDataEditController.$inject = ['$scope', 'dataService', 'DATA_CST', 'alertService', '$translate', + 'formService', 'policyService', 'utilService', 'metaDataService']; + + function moonDataEditController($scope, dataService, DATA_CST, alertService, $translate, + formService, policyService, utilService, metaDataService) { + + var edit = this; + + edit.dataType = $scope.edit.mnDataType; + edit.policy = $scope.edit.policy; + + edit.fromList = false; + + edit.loading = false; + + edit.form = {}; + + edit.data = { name: null, description: null}; + + edit.list = []; + edit.policyList = []; + edit.categoriesToBeSelected = []; + + edit.create = createData; + + activate(); + + /* + * + */ + + function activate(){ + + loadAllCategories(); + loadAllPolicies(); + + switch(edit.dataType){ + + case DATA_CST.TYPE.SUBJECT: + + dataService.subject.findAllFromPolicyWithCallback(edit.policy.id, callBackList); + break; + + case DATA_CST.TYPE.OBJECT: + + dataService.object.findAllFromPolicyWithCallback(edit.policy.id, callBackList); + break; + + case DATA_CST.TYPE.ACTION: + + dataService.action.findAllFromPolicyWithCallback(edit.policy.id, callBackList); + break; + + default : + + edit.list = []; + break; + + } + + function callBackList(list){ + + // For each Data, there is a check about the mapping between the Data and the policy + _.each(list, function (element) { + if (element.policy_id !== edit.policy.id) { + + edit.list.push(element); + + } + }); + + } + + } + + function loadAllCategories(){ + + switch(edit.dataType){ + + case DATA_CST.TYPE.SUBJECT: + + metaDataService.subject.findAllWithCallback(callBackList); + break; + + case DATA_CST.TYPE.OBJECT: + + metaDataService.object.findAllWithCallback(callBackList); + break; + + case DATA_CST.TYPE.ACTION: + + metaDataService.action.findAllWithCallback(callBackList); + break; + + default : + + edit.categoriesToBeSelected = []; + break; + + } + + function callBackList(list){ + + edit.categoriesToBeSelected = list; + + } + } + + function loadAllPolicies() { + + edit.policyList = []; + + policyService.findAllWithCallback( function(data) { + + _.each(data, function(element){ + + if(element.id === edit.policy.id){ + edit.selectedPolicy = element; + } + + }); + + edit.policyList = data; + + }); + } + + + /** + * Create + */ + + function createData() { + + if(formService.isInvalid(edit.form)) { + + formService.checkFieldsValidity(edit.form); + + } else { + + startLoading(); + + var dataToSend = angular.copy(edit.data); + + switch(edit.dataType){ + + case DATA_CST.TYPE.SUBJECT: + + dataService.subject.add(dataToSend, edit.policy.id, edit.selectedCategory.id, createSuccess, createError); + break; + + case DATA_CST.TYPE.OBJECT: + + dataService.object.add(dataToSend, edit.policy.id, edit.selectedCategory.id, createSuccess, createError); + break; + + case DATA_CST.TYPE.ACTION: + + dataService.action.add(dataToSend, edit.policy.id, edit.selectedCategory.id, createSuccess, createError); + break; + } + + } + + /** + * @param data + */ + function createSuccess(data) { + + var created = {}; + + switch(edit.dataType){ + + case DATA_CST.TYPE.SUBJECT: + + created = utilService.transformOne(data['subject_data'], 'data'); + break; + + case DATA_CST.TYPE.OBJECT: + + created = utilService.transformOne(data['object_data'], 'data'); + break; + + case DATA_CST.TYPE.ACTION: + + created = utilService.transformOne(data['action_data'], 'data'); + break; + } + + $translate('moon.policy.data.edit.create.success', { name: created.name }).then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + $scope.$emit('event:createDataFromDataEditSuccess', created, edit.dataType); + + stopLoading(); + + edit.list.push(created); + + } + + function createError(reason) { + + $translate('moon.policy.data.edit.create.error', { name: dataToSend.name }).then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + stopLoading(); + + } + + } + + function startLoading(){ + + edit.loading = true; + + } + + function stopLoading(){ + + edit.loading = false; + + } + + } + +})();
\ No newline at end of file diff --git a/moon_gui/static/app/policy/edit/parameter/data/data.list.dir.js b/moon_gui/static/app/policy/edit/parameter/data/data.list.dir.js new file mode 100755 index 00000000..23a7e535 --- /dev/null +++ b/moon_gui/static/app/policy/edit/parameter/data/data.list.dir.js @@ -0,0 +1,293 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .directive('moonDataList', moonDataList); + + moonDataList.$inject = []; + + function moonDataList() { + + return { + templateUrl : 'html/policy/edit/parameter/data/data-list.tpl.html', + bindToController : true, + controller : moonDataListController, + controllerAs : 'list', + scope : { + policy: '=', + editMode : '=' + }, + restrict : 'E', + replace : true + }; + } + + angular + .module('moon') + .controller('moonDataListController', moonDataListController); + + moonDataListController.$inject = ['$scope', '$rootScope', 'dataService', '$translate', 'alertService', 'DATA_CST', 'metaDataService']; + + function moonDataListController($scope, $rootScope, dataService, $translate, alertService, DATA_CST, metaDataService){ + + var list = this; + + list.policy = $scope.list.policy; + list.editMode = $scope.list.editMode; + + list.typeOfSubject = DATA_CST.TYPE.SUBJECT; + list.typeOfObject = DATA_CST.TYPE.OBJECT; + list.typeOfAction = DATA_CST.TYPE.ACTION; + + list.deleteSub = deleteSub; + list.deleteObj = deleteObj; + list.deleteAct = deleteAct; + + list.getSubjects = getSubjects; + list.getObjects = getObjects; + list.getActions = getActions; + + list.getCategoryFromData = getCategoryFromData; + + activate(); + + function activate(){ + + manageSubjects(); + + manageObjects(); + + manageActions(); + + } + + var rootListeners = { + + 'event:createDataFromDataEditSuccess': $rootScope.$on('event:createDataFromDataEditSuccess', addDataToList) + + }; + + _.each(rootListeners, function(unbind){ + $scope.$on('$destroy', rootListeners[unbind]); + }); + + + function manageSubjects(){ + + list.loadingSub = true; + + dataService.subject.findAllFromPolicyWithCallback(list.policy.id, function(data){ + + list.subjects = data; + list.loadingSub = false; + + }); + } + + function manageObjects(){ + + list.loadingObj = true; + + dataService.object.findAllFromPolicyWithCallback(list.policy.id, function(data){ + + list.objects = data; + list.loadingObj = false; + + }); + + } + + function manageActions(){ + + list.loadingAct = true; + + dataService.action.findAllFromPolicyWithCallback(list.policy.id, function(data){ + + list.actions = data; + list.loadingAct = false; + + }); + + } + + function getCategoryFromData(data, type) { + + if(_.has(data, 'category')){ + return data.category; + } + + // if the call has not been made + if(!_.has(data, 'callCategoryInProgress')){ + + data.callCategoryInProgress = true; + + switch(type){ + + case DATA_CST.TYPE.SUBJECT: + metaDataService.subject.findOne(data.category_id, setCategoryToData); + break; + + case DATA_CST.TYPE.OBJECT: + metaDataService.object.findOne(data.category_id, setCategoryToData); + break; + + case DATA_CST.TYPE.ACTION: + metaDataService.action.findOne(data.category_id, setCategoryToData); + break; + + } + + } + + // if the call is in progress return false + return false; + + function setCategoryToData(category){ + + data.callCategoryInProgress = false; + data.category = category; + + } + } + + /** + * Delete + */ + + function deleteSub(subject){ + + subject.loader = true; + + dataService.subject.delete(subject, list.policy.id, subject.category_id, deleteSubSuccess, deleteSubError); + + function deleteSubSuccess(data){ + + $translate('moon.policy.data.subject.delete.success', { subjectName: subject.name }).then( function(translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + removeSubFromSubList(subject); + + subject.loader = false; + + } + + function deleteSubError(reason){ + + $translate('moon.policy.data.subject.delete.error', { subjectName: subject.name, reason: reason.message}).then( function(translatedValue) { + alertService.alertError(translatedValue); + }); + + subject.loader = false; + + } + } + + function deleteObj(object){ + + object.loader = true; + + dataService.object.delete(object, list.policy.id, object.category_id, deleteObjSuccess, deleteObjError); + + function deleteObjSuccess(data){ + + $translate('moon.policy.data.object.delete.success', { objectName: object.name }).then( function(translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + removeObjFromObjList(object); + + object.loader = false; + + } + + function deleteObjError(reason){ + + $translate('moon.policy.data.object.delete.error', { objectName: object.name, reason: reason.message}).then( function(translatedValue) { + alertService.alertError(translatedValue); + }); + + object.loader = false; + } + } + + function deleteAct(action){ + + action.loader = true; + + dataService.action.delete(action, list.policy.id, action.category_id, deleteActSuccess, deleteActError); + + function deleteActSuccess(data){ + + $translate('moon.policy.data.action.delete.success', { actionName: action.name }).then( function(translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + removeActFromActList(action); + + action.loader = false; + + } + + function deleteActError(reason){ + + $translate('moon.policy.data.action.delete.error', { actionName: action.name, reason: reason.message}).then( function(translatedValue) { + alertService.alertError(translatedValue); + }); + + action.loader = false; + + } + } + + function getSubjects(){ + return list.subjects ? list.subjects : []; + } + + function getObjects(){ + return list.objects ? list.objects : []; + } + + function getActions(){ + return list.actions ? list.actions : []; + } + + function removeSubFromSubList(subject){ + list.subjects = _.without(list.subjects, subject); + } + + function removeObjFromObjList(object){ + list.objects = _.without(list.objects, object); + } + + function removeActFromActList(action){ + list.actions = _.without(list.actions, action); + } + + function addDataToList( event, data, typeOfData){ + + switch(typeOfData){ + + case DATA_CST.TYPE.SUBJECT: + + list.subjects.push(data); + break; + + case DATA_CST.TYPE.OBJECT: + + list.objects.push(data); + break; + + case DATA_CST.TYPE.ACTION: + + list.actions.push(data); + break; + } + + } + + } + +})();
\ No newline at end of file diff --git a/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-edit.tpl.html b/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-edit.tpl.html new file mode 100755 index 00000000..fa2f93c0 --- /dev/null +++ b/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-edit.tpl.html @@ -0,0 +1,166 @@ +<div> + + <div class="col-md-4 col-sm-4 col-xs-4"> + <a class="btn btn-primary" type="button" style="white-space: normal;" ng-click="edit.fromList = !edit.fromList"> + <span ng-if="!edit.fromList" data-translate="moon.policy.perimeter.edit.action.list">Add from the list</span> + <span ng-if="edit.fromList" data-translate="moon.policy.perimeter.edit.action.new">Add a new Perimeter</span> + </a> + </div> + + <div class="col-md-8 col-sm-8 col-xs-8"> + + <form name="selectMetaData" ng-if="edit.fromList" class="form-horizontal" role="form" > + + <div class="form-group" > + + <ui-select ng-model="edit.selectedPerimeter" name="object"> + + <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match> + <ui-select-choices repeat="aPerimeter in edit.list"> + <div ng-value="aPerimeter" ng-bind="aPerimeter.name"></div> + </ui-select-choices> + + </ui-select> + + </div> + + <div class="form-group"> + + <div class="pull-left col-md-4 col-sm-4 col-xs-4"> + + <a href="" ng-disabled="edit.loading || !edit.selectedPerimeter" ng-click="edit.deletePerimeter()" class="btn btn-warning"> + <span class="glyphicon glyphicon-trash"></span> + <span data-translate="moon.policy.perimeter.edit.action.delete">Delete</span> + </a> + + </div> + + <div class="pull-right col-md-7 col-md-offset-1 col-sm-7 col-sm-offset-1 col-xs-7 col-xs-offset-1 "> + + <a href="" ng-disabled="edit.loading || !edit.selectedPerimeter" ng-click="edit.addToPolicy()" class="btn btn-warning" style="white-space: normal;"> + <span class="glyphicon glyphicon-link"></span> + <span data-translate="moon.policy.perimeter.edit.action.add">Add the selected Perimeter</span> + </a> + + </div> + + </div> + + <moon-loader ng-if="edit.loading"></moon-loader> + + </form> + + <form ng-if="!edit.fromList" class="form-horizontal" role="form" name="edit.form"> + + <div class="form-group" ng-class="{'has-error': edit.form.name.$invalid && edit.form.name.$dirty}"> + + <label for="name" class="col-sm-3 control-label" data-translate="moon.policy.perimeter.edit.name">Name</label> + + <div class="col-sm-6"> + + <input name="name" id="name" class="form-control" type="text" data-ng-model="edit.perimeter.name" required /> + + <div class="help-block" ng-show="edit.form.name.$dirty && edit.form.name.$invalid"> + <small class="error" ng-show="edit.form.name.$error.required" data-translate="moon.policy.perimeter.edit.check.name.required">Name is required</small> + </div> + + </div> + + </div> + + <div class="form-group"> + + <label for="description" class="col-sm-3 control-label" data-translate="moon.policy.perimeter.edit.description">Description</label> + <div class="col-sm-6"> + <textarea id="description" name="description" class="form-control" data-ng-model="edit.perimeter.description"></textarea> + </div> + + </div> + + <!-- + <div class="form-group"> + + <label for="partnerId" class="col-sm-3 control-label" data-translate="moon.policy.perimeter.edit.partnerId">Partner Id</label> + + <div class="col-sm-6"> + <input name="partnerId" id="partnerId" class="form-control" type="text" data-ng-model="edit.perimeter.partnerId" /> + </div> + + </div> + --> + + + <div class="form-group" ng-if="edit.perimeterType === edit.subjectType" ng-class="{'has-error': edit.form.email.$invalid && edit.form.email.$dirty}"> + + <label for="email" class="col-sm-3 control-label" data-translate="moon.policy.perimeter.edit.email">Email</label> + + <div class="col-sm-6"> + <input name="email" id="email" class="form-control" type="email" data-ng-model="edit.perimeter.email" /> + </div> + + </div> + + + <div class="form-group" > + + <label for="policyList" class="col-sm-3 control-label" data-translate="moon.policy.perimeter.edit.policies">Policy List </label> + + <div class="col-sm-5"> + + <ui-select ng-model="edit.selectedPolicy" id="policyList"> + + <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match> + <ui-select-choices repeat="aPolicy in edit.policiesToBeSelected"> + <div ng-value="aPolicy" ng-bind="aPolicy.name"></div> + </ui-select-choices> + + </ui-select> + + </div> + + <div class="col-sm-1 text-center"> + <a href="" ng-click="edit.addPolicyToPerimeter()"><span style="font-size:1.5em; line-height: 1.5em;" class="glyphicon glyphicon-plus-sign"></span></a> + </div> + + </div> + + <div class="form-group"> + + <label class="col-sm-3 control-label" data-translate="moon.policy.perimeter.edit.selectedPolicies">Selected Policies</label> + + <div class="col-sm-6"> + + <ul> + + <li ng-repeat="(key, value) in edit.selectedPolicyList"> + + <span ng-bind="value.name" ></span> <a href="" ng-click="edit.removeSelectedPolicy(value)"><span style="font-size:1.5em; line-height: 1.5em" class="glyphicon glyphicon-remove"></span></a> + + </li> + + </ul> + + </div> + + </div> + + <div class="form-group"> + + <div class="pull-right"> + + <a href="" ng-disabled="edit.loading" ng-click="edit.create()" class="btn btn-warning"> + <span class="glyphicon glyphicon-save"></span> + <span data-translate="moon.policy.perimeter.edit.action.create">Create</span> + </a> + + <moon-loader ng-if="edit.loading"></moon-loader> + + </div> + + </div> + + </form> + + </div> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-list.tpl.html b/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-list.tpl.html new file mode 100755 index 00000000..a94d663e --- /dev/null +++ b/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-list.tpl.html @@ -0,0 +1,240 @@ +<div> + <div class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.policy.perimeter.subject.title">List of associated Subjects</h4> + + </div> + + <div class="panel-body"> + + <div class="table-responsive"> + + <table class="table table-striped"> + + <thead> + <tr> + <th data-translate="moon.policy.perimeter.table.name">Name</th> + <th data-translate="moon.policy.perimeter.table.description">Description</th> + <th data-translate="moon.policy.perimeter.table.email">Email</th> + <th data-translate="moon.policy.perimeter.table.action.title"></th> + </tr> + </thead> + + <moon-loader ng-if="list.loadingSub"></moon-loader> + + <tbody ng-if="!list.loadingSub && list.getSubjects().length > 0"> + <tr ng-repeat="(key, value) in list.subjects"> + <td ng-bind="value.name"></td> + <td ng-bind="value.description"></td> + <td ng-bind="value.email"></td> + <td> + + <a href="" ng-if="!value.loader" ng-click="list.unMapSub(value)" > + <span class="glyphicon glyphicon-transfer"></span> + <span class="control-label" data-translate="moon.policy.perimeter.table.action.unmap">Unmap</span> + </a> + + <div ng-if="value.loader"> + + <moon-loader></moon-loader> + + </div> + + </td> + + </tr> + </tbody> + + + <tbody ng-if="!list.loadingSub && list.getSubjects().length === 0"> + <tr> + <td data-translate="moon.policy.perimeter.subject.notFound">There is no Subjects</td> + <td></td> + <td></td> + <td></td> + </tr> + </tbody> + + </table> + + </div> + + </div> + + </div> + + <div ng-if="list.editMode" class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.policy.perimeter.subject.add.title">Add a Subject Category</h4> + + </div> + + <div class="panel-body"> + + <moon-perimeter-edit policy="list.policy" perimeter-type="list.typeOfSubject"></moon-perimeter-edit> + + </div> + + </div> + + + <div class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.policy.perimeter.object.title">List associated of Objects</h4> + + </div> + + <div class="panel-body"> + + <div class="table-responsive"> + + <table class="table table-striped"> + + <thead> + <tr> + <th data-translate="moon.policy.perimeter.table.name">Name</th> + <th data-translate="moon.policy.perimeter.table.description">Description</th> + <th data-translate="moon.policy.perimeter.table.action.title"></th> + </tr> + </thead> + + <moon-loader ng-if="list.loadingObj"></moon-loader> + + <tbody ng-if="!list.loadingObj && list.getObjects().length > 0"> + <tr ng-repeat="(key, value) in list.objects"> + <td ng-bind="value.name"></td> + <td ng-bind="value.description"></td> + <td> + + <a href="" ng-if="!value.loader" ng-click="list.unMapObj(value)" > + <span class="glyphicon glyphicon-transfer"></span> + <span class="control-label" data-translate="moon.policy.perimeter.table.action.unmap">Unmap</span> + </a> + + <div ng-if="value.loader"> + + <moon-loader></moon-loader> + + </div> + + </td> + </tr> + </tbody> + + <tbody ng-if="!list.loadingObj && list.getObjects().length === 0"> + <tr> + <td data-translate="moon.policy.perimeter.object.notFound">There is no Objects</td> + <td></td> + <td></td> + </tr> + </tbody> + + </table> + + </div> + + </div> + + </div> + + <div ng-if="list.editMode" class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.policy.perimeter.object.add.title">Add an Object Category</h4> + + </div> + + <div class="panel-body"> + + <moon-perimeter-edit policy="list.policy" perimeter-type="list.typeOfObject"></moon-perimeter-edit> + + </div> + + </div> + + <div class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.policy.perimeter.action.title">List associated of Actions</h4> + + </div> + + <div class="panel-body"> + + <div class="table-responsive"> + + <table class="table table-striped"> + + <thead> + <tr> + <th data-translate="moon.policy.perimeter.table.name">Name</th> + <th data-translate="moon.policy.perimeter.table.description">Description</th> + <th data-translate="moon.policy.perimeter.table.action.title"></th> + </tr> + </thead> + + <moon-loader ng-if="list.loadingAct"></moon-loader> + + <tbody ng-if="!list.loadingAct && list.getActions().length > 0"> + <tr ng-repeat="(key, value) in list.actions"> + <td ng-bind="value.name"></td> + <td ng-bind="value.description"></td> + <td> + + <a href="" ng-if="!value.loader" ng-click="list.unMapAct(value)" > + <span class="glyphicon glyphicon-transfer"></span> + <span class="control-label" data-translate="moon.policy.perimeter.table.action.unmap">Unmap</span> + </a> + + <div ng-if="value.loader"> + + <moon-loader></moon-loader> + + </div> + + </td> + </tr> + </tbody> + + <tbody ng-if="!list.loadingAct && list.getActions().length === 0"> + <tr> + <td data-translate="moon.policy.perimeter.action.notFound">There is no Actions</td> + <td></td> + <td></td> + </tr> + </tbody> + + </table> + + </div> + + + </div> + + </div> + + <div ng-if="list.editMode" class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.policy.perimeter.action.add.title">Add an Action Category</h4> + + </div> + + <div class="panel-body">. + + <moon-perimeter-edit policy="list.policy" perimeter-type="list.typeOfAction"></moon-perimeter-edit> + + </div> + + </div> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.edit.dir.js b/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.edit.dir.js new file mode 100755 index 00000000..a96741fe --- /dev/null +++ b/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/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.list.dir.js b/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.list.dir.js new file mode 100755 index 00000000..dffa7783 --- /dev/null +++ b/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.list.dir.js @@ -0,0 +1,284 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .directive('moonPerimeterList', moonPerimeterList); + + moonPerimeterList.$inject = []; + + function moonPerimeterList() { + + return { + templateUrl : 'html/policy/edit/parameter/perimeter/perimeter-list.tpl.html', + bindToController : true, + controller : moonPerimeterListController, + controllerAs : 'list', + scope : { + policy: '=', + editMode : '=' + }, + restrict : 'E', + replace : true + }; + + } + + angular + .module('moon') + .controller('moonPerimeterListController', moonPerimeterListController); + + moonPerimeterListController.$inject = ['$scope', '$rootScope', 'perimeterService', '$translate', 'alertService', 'PERIMETER_CST']; + + function moonPerimeterListController($scope, $rootScope, perimeterService, $translate, alertService, PERIMETER_CST){ + + var list = this; + + list.policy = $scope.list.policy; + list.editMode = $scope.list.editMode; + + list.typeOfSubject = PERIMETER_CST.TYPE.SUBJECT; + list.typeOfObject = PERIMETER_CST.TYPE.OBJECT; + list.typeOfAction = PERIMETER_CST.TYPE.ACTION; + + list.unMapSub = unMapSub; + list.unMapObj = unMapObj; + list.unMapAct = unMapAct; + + list.getSubjects = getSubjects; + list.getObjects = getObjects; + list.getActions = getActions; + + activate(); + + function activate(){ + + manageSubjects(); + + manageObjects(); + + manageActions(); + + } + + var rootListeners = { + + 'event:deletePerimeterFromPerimeterAddSuccess': $rootScope.$on('event:deletePerimeterFromPerimeterAddSuccess', deletePolicy), + 'event:createAssignmentsFromAssignmentsEditSuccess': $rootScope.$on('event:createAssignmentsFromAssignmentsEditSuccess', addAssignmentsToPolicy) + + }; + + _.each(rootListeners, function(unbind){ + $scope.$on('$destroy', rootListeners[unbind]); + }); + + + function manageSubjects(){ + + list.loadingSub = true; + + perimeterService.subject.findAllFromPolicyWithCallback(list.policy.id, function(perimeters){ + + list.subjects = perimeters; + list.loadingSub = false; + + }); + } + + function manageObjects(){ + + list.loadingObj = true; + + perimeterService.object.findAllFromPolicyWithCallback(list.policy.id, function(perimeters){ + + list.objects = perimeters; + list.loadingObj = false; + + }); + + } + + function manageActions(){ + + list.loadingAct = true; + + perimeterService.action.findAllFromPolicyWithCallback(list.policy.id, function(perimeters){ + + list.actions = perimeters; + list.loadingAct = false; + + }); + + } + + /** + * UnMap + */ + + function unMapSub(perimeter){ + + perimeter.policy_list = _.without(perimeter.policy_list, list.policy.id); + + perimeter.loader = true; + + var perimeterToSend = angular.copy(perimeter); + + perimeterService.subject.unMapPerimeterFromPolicy(list.policy.id , perimeter.id, updatePerimeterSuccess, updatePerimeterError); + + function updatePerimeterSuccess(data){ + + $translate('moon.policy.perimeter.update.success', { perimeterName: perimeterToSend.name }).then( function(translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + $scope.$emit('event:unMapPerimeterFromPerimeterList', perimeter, PERIMETER_CST.TYPE.SUBJECT); + + activate(); + + perimeter.loader = false; + } + + function updatePerimeterError(reason){ + + $translate('moon.policy.perimeter.update.error', { perimeterName: perimeter.name, reason: reason.message}).then( function(translatedValue) { + alertService.alertError(translatedValue); + }); + + perimeter.loader = false; + + } + + } + + function unMapObj(perimeter){ + + perimeter.policy_list = _.without(perimeter.policy_list, list.policy.id); + + perimeter.loader = true; + + var perimeterToSend = angular.copy(perimeter); + + perimeterService.object.unMapPerimeterFromPolicy(list.policy.id , perimeter.id, updatePerimeterSuccess, updatePerimeterError); + + function updatePerimeterSuccess(data){ + + $translate('moon.policy.perimeter.update.success', { perimeterName: perimeterToSend.name }).then( function(translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + $scope.$emit('event:unMapPerimeterFromPerimeterList', perimeter, PERIMETER_CST.TYPE.OBJECT); + + activate(); + + perimeter.loader = false; + } + + function updatePerimeterError(reason){ + + $translate('moon.policy.perimeter.update.error', { perimeterName: perimeter.name, reason: reason.message}).then( function(translatedValue) { + alertService.alertError(translatedValue); + }); + + perimeter.loader = false; + + } + + } + + function unMapAct(perimeter){ + + perimeter.policy_list = _.without(perimeter.policy_list, list.policy.id); + + perimeter.loader = true; + + var perimeterToSend = angular.copy(perimeter); + + perimeterService.action.unMapPerimeterFromPolicy(list.policy.id , perimeter.id, updatePerimeterSuccess, updatePerimeterError); + + function updatePerimeterSuccess(data){ + + $translate('moon.policy.perimeter.update.success', { perimeterName: perimeterToSend.name }).then( function(translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + $scope.$emit('event:unMapPerimeterFromPerimeterList', perimeter, PERIMETER_CST.TYPE.ACTION); + + activate(); + + perimeter.loader = false; + } + + function updatePerimeterError(reason){ + + $translate('moon.policy.perimeter.update.error', { perimeterName: perimeter.name, reason: reason.message}).then( function(translatedValue) { + alertService.alertError(translatedValue); + }); + + perimeter.loader = false; + + } + + } + + function getSubjects(){ + return list.subjects ? list.subjects : []; + } + + function getObjects(){ + return list.objects ? list.objects : []; + } + + function getActions(){ + return list.actions ? list.actions : []; + } + + function removeSubFromSubList(subject){ + list.subjects = _.without(list.subjects, subject); + } + + function removeObjFromObjList(object){ + list.objects = _.without(list.objects, object); + } + + function removeActFromActList(action){ + list.actions = _.without(list.actions, action); + } + + function deletePolicy( event, policy){ + + list.policy = policy; + + activate(); + + } + + function addAssignmentsToPolicy( event, assignments, type){ + + switch (type) { + + case PERIMETER_CST.TYPE.SUBJECT: + + list.subjects.push(assignments); + break; + + case PERIMETER_CST.TYPE.OBJECT: + + list.objects.push(assignments); + break; + + case PERIMETER_CST.TYPE.ACTION: + + list.actions.push(assignments); + break; + + default : + break; + + } + + } + + } + +})();
\ No newline at end of file diff --git a/moon_gui/static/app/policy/edit/parameter/rules/rules-edit.tpl.html b/moon_gui/static/app/policy/edit/parameter/rules/rules-edit.tpl.html new file mode 100755 index 00000000..685046a5 --- /dev/null +++ b/moon_gui/static/app/policy/edit/parameter/rules/rules-edit.tpl.html @@ -0,0 +1,341 @@ +<div> + + <div class="col-md-12 col-sm-12 col-xs-12"> + + <form ng-if="!edit.fromList" class="form-horizontal" role="form" name="edit.form"> + + <!-- Select Policy --> + <div class="form-group" ng-class="{'has-error': edit.form.policyList.$invalid && edit.form.policyList.$dirty}" > + + <label for="policyList" class="col-sm-3 control-label" data-translate="moon.policy.rules.edit.action.add.policies">Policy List</label> + + <div class="col-sm-6" > + + <ui-select ng-model="edit.selectedPolicy" name="policyList" id="policyList" required> + + <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match> + <ui-select-choices repeat="aPolicy in edit.policyList"> + <div ng-value="aPolicy" ng-bind="aPolicy.name"></div> + </ui-select-choices> + + </ui-select> + + <div class="help-block" ng-show="edit.form.policyList.$dirty && edit.form.policyList.$invalid"> + <small class="error" ng-show="edit.form.policyList.$error.required" data-translate="moon.policy.rules.edit.action.add.check.policy.required">Policy is required</small> + </div> + + </div> + + </div> + + <div ng-if="!edit.selectedPolicy.meta_rules_values"> + <div class="col-sm-6 col-sm-offset-3"> + <moon-loader></moon-loader> + </div> + </div> + + <div ng-if="edit.selectedPolicy.meta_rules_values"> + + <!-- Select Meta Rules --> + <div class="form-group" ng-class="{'has-error': edit.form.metaRulesList.$invalid && edit.form.metaRulesList.$dirty}" > + + <label for="metaRulesList" class="col-sm-3 control-label" data-translate="moon.policy.rules.edit.action.add.metarules">MetaRules List</label> + + <div class="col-sm-6" > + + <ui-select ng-model="edit.selectedMetaRules" name="metaRulesList" id="metaRulesList" required> + + <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match> + <ui-select-choices repeat="aMetaRules in edit.selectedPolicy.meta_rules_values"> + <div ng-value="aMetaRules" ng-bind="aMetaRules.name"></div> + </ui-select-choices> + + </ui-select> + + <div class="help-block" ng-show="edit.form.metaRulesList.$dirty && edit.form.metaRulesList.$invalid"> + <small class="error" ng-show="edit.form.metaRulesList.$error.required" data-translate="moon.policy.rules.edit.action.add.check.metarules.required">A MetaRules is required</small> + </div> + + </div> + + <div> + <a href="" ng-if="edit.selectedMetaRules" ng-click="edit.showDetailselectedMetaRules = !edit.showDetailselectedMetaRules"> + + <span ng-if="!edit.showDetailselectedMetaRules"> + <span data-translate="moon.policy.rules.edit.action.add.details.show">Show</span> + <span class="glyphicon glyphicon-eye-open"></span> + </span> + + <span ng-if="edit.showDetailselectedMetaRules"> + <span data-translate="moon.policy.rules.edit.action.add.details.close">Close</span> + <span class="glyphicon glyphicon-eye-close"></span> + </span> + + </a> + </div> + + </div> + + <div class="form-group" ng-if="edit.showDetailselectedMetaRules && edit.selectedMetaRules"> + <moon-meta-data-list edit-mode="edit.editMode" meta-rule="edit.selectedMetaRules" short-display="true"></moon-meta-data-list> + </div> + + <!-- Select Data --> + <div class="form-group" ng-if="edit.selectedMetaRules"> + + <div class="col-md-4"> + + <div ng-if="edit.selectedMetaRules.subject_categories.length > 0"> + + <div class="row"> + + <div ng-if="!edit.data.loadingSubjects"> + + <label for="subjectsList" class="col-sm-3 control-label" data-translate="moon.policy.rules.edit.action.add.categories.subject" data-translate-values="{ number: edit.selectedMetaRules.subject_categories.length }">Select Subject(s)</label> + + <div class="col-sm-7" > + + <ui-select ng-model="edit.selectedSubject" name="subjectsList" id="subjectsList" required> + + <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match> + <ui-select-choices repeat="aSubject in edit.data.subjectsToBeSelected"> + <div ng-value="aSubject" ng-bind="aSubject.name"></div> + </ui-select-choices> + + </ui-select> + + <div class="help-block" ng-show="edit.form.subjectsList.$dirty && edit.form.subjectsList.$invalid || !edit.numberOfSelectedSubjectValid"> + <small class="error" ng-show="edit.form.subjectsList.$error.required || !edit.numberOfSelectedSubjectValid" data-translate="moon.policy.rules.edit.action.add.check.subject.required" data-translate-values="{ number: edit.selectedMetaRules.subject_categories.length }">Some subject are required</small> + </div> + + </div> + + <div class="col-sm-2 text-center"> + <a href="" ng-if="edit.selectedSubject && !edit.isNumberSelectedDataAtMaximum(edit.data.subjectCST)" + ng-click="edit.addDataToRules(edit.data.subjectCST)"><span style="font-size:1.5em; line-height: 1.5em;" class="glyphicon glyphicon-plus-sign"></span></a> + </div> + + </div> + + <div ng-if="edit.data.loadingSubjects"> + + <moon-loader></moon-loader> + + </div> + + </div> + + <div class="row" ng-if="!edit.data.loadingSubjects"> + + <div class="form-group"> + + <label class="col-sm-3 control-label" data-translate="moon.policy.rules.edit.action.add.selectedSubjects">Selected Subjcet(s)</label> + + <div class="col-sm-6"> + + <ul> + + <li ng-repeat="(key, value) in edit.data.selectedSubjectsList"> + + <span ng-bind="value.name" ></span> <a href="" ng-click="edit.removeSelectedDataFromRules(value, edit.data.subjectCST)"><span style="font-size:1.5em; line-height: 1.5em" class="glyphicon glyphicon-remove"></span></a> + + </li> + + </ul> + + </div> + + </div> + + </div> + + </div> + + <div ng-if="edit.selectedMetaRules.subject_categories.length === 0"> + + </div> + + </div> + + <div class="col-md-4"> + + <div ng-if="edit.selectedMetaRules.object_categories.length > 0"> + + <div class="row"> + + <div ng-if="!edit.data.loadingObjects"> + + <label for="objectsList" class="col-sm-3 control-label" data-translate="moon.policy.rules.edit.action.add.categories.object" data-translate-values="{ number: edit.selectedMetaRules.object_categories.length }">Select Object(s)</label> + + <div class="col-sm-7" > + + <ui-select ng-model="edit.selectedObject" name="objectsList" id="objectsList" required> + + <ui-select-match placeholder="(None)" ng-bind="$select.selected.value.name"></ui-select-match> + <ui-select-choices repeat="aObject in edit.data.objectsToBeSelected"> + <div ng-value="aObject" ng-bind="aObject.value.name"></div> + </ui-select-choices> + + </ui-select> + + <div class="help-block" ng-show="edit.form.objectsList.$dirty && edit.form.objectsList.$invalid || !edit.numberOfSelectedObjecttValid"> + <small class="error" ng-show="edit.form.objectsList.$error.required || !edit.numberOfSelectedObjecttValid" data-translate="moon.policy.rules.edit.action.add.check.object.required" data-translate-values="{ number: edit.selectedMetaRules.object_categories.length }">Some objects are required</small> + </div> + + </div> + + <div class="col-sm-2 text-center"> + <a href="" ng-if="edit.selectedObject && !edit.isNumberSelectedDataAtMaximum(edit.data.objectCST)" + ng-click="edit.addDataToRules(edit.data.objectCST)"><span style="font-size:1.5em; line-height: 1.5em;" class="glyphicon glyphicon-plus-sign"></span></a> + </div> + + </div> + + <div ng-if="edit.data.loadingObjects"> + + <moon-loader></moon-loader> + + </div> + + </div> + + <div class="row" ng-if="!edit.data.loadingObjects"> + + <div class="form-group"> + + <label class="col-sm-3 control-label" data-translate="moon.policy.rules.edit.action.add.selectedObjects">Selected Objcet(s)</label> + + <div class="col-sm-6"> + + <ul> + + <li ng-repeat="(key, value) in edit.data.selectedObjectsList"> + + <span ng-bind="value.value.name" ></span> <a href="" ng-click="edit.removeSelectedDataFromRules(value, edit.data.objectCST)"><span style="font-size:1.5em; line-height: 1.5em" class="glyphicon glyphicon-remove"></span></a> + + </li> + + </ul> + + </div> + </div> + + </div> + + </div> + + <div ng-if="edit.selectedMetaRules.object_categories.length === 0"> + + </div> + + </div> + + <div class="col-md-4"> + + <div ng-if="edit.selectedMetaRules.action_categories.length > 0"> + + <div class="row"> + + <div ng-if="!edit.data.loadingActions"> + + <label for="actionsList" class="col-sm-3 control-label" data-translate="moon.policy.rules.edit.action.add.categories.action" data-translate-values="{ number: edit.selectedMetaRules.action_categories.length }">Select Action(s)</label> + + <div class="col-sm-7" > + + <ui-select ng-model="edit.selectedAction" name="actionsList" id="actionsList" required> + + <ui-select-match placeholder="(None)" ng-bind="$select.selected.value.name"></ui-select-match> + <ui-select-choices repeat="aAction in edit.data.actionsToBeSelected"> + <div ng-value="aAction" ng-bind="aAction.value.name"></div> + </ui-select-choices> + + </ui-select> + + <div class="help-block" ng-show="edit.form.actionsList.$dirty && edit.form.actionsList.$invalid || !edit.numberOfSelectedActionsValid"> + <small class="error" ng-show="edit.form.actionsList.$error.required || !edit.numberOfSelectedActionsValid" data-translate="moon.policy.rules.edit.action.add.check.action.required" data-translate-values="{ number: edit.selectedMetaRules.action_categories.length }">Some action are required</small> + </div> + </div> + + <div class="col-sm-2 text-center"> + <a href="" ng-if="edit.selectedAction && !edit.isNumberSelectedDataAtMaximum(edit.data.actionCST)" + ng-click="edit.addDataToRules(edit.data.actionCST)"><span style="font-size:1.5em; line-height: 1.5em;" class="glyphicon glyphicon-plus-sign"></span></a> + </div> + + </div> + + <div ng-if="edit.data.loadingActions"> + + <moon-loader></moon-loader> + + </div> + + </div> + + <div class="row" ng-if="!edit.data.loadingActions"> + + <div class="form-group"> + + <label class="col-sm-3 control-label" data-translate="moon.policy.rules.edit.action.add.selectedActions">Selected Action(s)</label> + + <div class="col-sm-6"> + + <ul> + + <li ng-repeat="(key, value) in edit.data.selectedActionsList"> + + <span ng-bind="value.value.name" ></span> <a href="" ng-click="edit.removeSelectedDataFromRules(value, edit.data.actionCST)"><span style="font-size:1.5em; line-height: 1.5em" class="glyphicon glyphicon-remove"></span></a> + + </li> + + </ul> + + </div> + </div> + + </div> + + </div> + + <div ng-if="edit.selectedMetaRules.action_categories.length === 0"> + + </div> + + </div> + + </div> + + <div class="form-group" ng-class="{'has-error': edit.form.instructions.$invalid && edit.form.instructions.$dirty || !edit.instructionsValid}"> + + <label for="instructions" class="col-sm-3 control-label" data-translate="moon.policy.rules.edit.action.add.instructions">Instruction</label> + + <div class="col-sm-6"> + <textarea id="instructions" name="instructions" class="form-control" ng-model="edit.rules.instructions" rows="6" required></textarea> + <div class="help-block" ng-show="edit.form.instructions.$dirty && edit.form.instructions.$invalid || !edit.instructionsValid "> + <small class="error" data-translate="moon.policy.rules.edit.action.add.check.instructions.required">An instructions is required</small> + </div> + </div> + + </div> + + <div class="form-group"> + + <div class="pull-right"> + + <a href="" ng-disabled="edit.loading" ng-click="edit.create()" class="btn btn-warning"> + <span class="glyphicon glyphicon-save"></span> + <span data-translate="moon.policy.rules.edit.action.create">Create</span> + </a> + + <moon-loader ng-if="edit.loading"></moon-loader> + + </div> + + </div> + + </div> + + </form> + + </div> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/policy/edit/parameter/rules/rules-list.tpl.html b/moon_gui/static/app/policy/edit/parameter/rules/rules-list.tpl.html new file mode 100755 index 00000000..76ac4365 --- /dev/null +++ b/moon_gui/static/app/policy/edit/parameter/rules/rules-list.tpl.html @@ -0,0 +1,134 @@ +<div> + + <div class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.policy.rules.edit.title">List of associated Subjects</h4> + + </div> + + <div class="panel-body"> + + <div class="table-responsive" data-role="table"> + + <table class="table table-striped table-hover" ng-table="list.table"> + + <thead> + + <tr> + + <th class="customTables sortable" + ng-class="{ 'sort-asc': list.table.isSortBy('description', 'asc'), 'sort-desc': list.table.isSortBy('description', 'desc') }" + ng-click="list.table.sorting('description', list.table.isSortBy('description', 'asc') ? 'desc' : 'asc')"> + <div data-translate="moon.policy.rules.list.table.metaRule">Meta Rule</div> + </th> + + <th class="customTables sortable"> + <div data-translate="moon.policy.rules.list.table.rule">Rule</div> + </th> + + <th class="customTables sortable"> + <div data-translate="moon.policy.rules.list.table.instructions">Instruction</div> + </th> + + <th class="customTables sortable"> + <div data-translate="moon.policy.rules.list.table.action.title">Actions</div> + </th> + </tr> + + </thead> + + <moon-loader ng-if="list.loadingRules"></moon-loader> + + <tbody ng-if="!list.loadingRules && !list.hasRules()"> + <tr> + <td colspan="4"><span data-translate="moon.policy.rules.list.table.notFound">There is no Rules</span></td> + </tr> + </tbody> + + <tbody ng-if="!list.loadingRules && list.hasRules()"> + + <tr ng-repeat="aRule in $data | filter:list.search.find | orderBy:sort:reverse"> + <td> + <span ng-if="!list.getMetaRuleFromRule(aRule)"> + <moon-loader ng-if="!list.getMetaRuleFromRule(aRule)" ></moon-loader> + <em data-translate="moon.policy.rules.list.table.loading.metaRule">Loading </em> + </span> + + <span ng-if="list.getMetaRuleFromRule(aRule)"> + <span ng-bind="aRule.meta_rule.name"></span> + </span> + </td> + + <td> + + <span ng-if="!list.getMetaRuleFromRule(aRule)"> + <moon-loader ng-if="!list.getMetaRuleFromRule(aRule)" ></moon-loader> + <em data-translate="moon.policy.rules.list.table.loading.metaRule">Loading </em> + </span> + + <span ng-if="list.getMetaRuleFromRule(aRule)" ng-repeat="(key, value) in aRule.rule"> + + <span ng-if="!list.getCategoryFromRuleIndex(key, aRule)"> + <moon-loader ng-if="!list.getCategoryFromRuleIndex(key, aRule)" ></moon-loader> + </span> + + <span ng-if="list.getCategoryFromRuleIndex(key, aRule)"> + <span ng-if="aRule.rule_value[key].category.name" ng-bind="aRule.rule_value[key].category.name"></span> + <span ng-if="aRule.rule_value[key].category.value.name" ng-bind="aRule.rule_value[key].category.value.name"></span> + <span ng-if="key < aRule.rule.length-1">,</span> + </span> + + </span> + + </td> + + <td> + <pre ng-bind="aRule.instructions | json "></pre> + </td> + + <td> + + <a href="" ng-if="!aRule.loader" ng-click="list.deleteRules(aRule)" > + <span class="glyphicon glyphicon-transfer"></span> + <span class="control-label" data-translate="moon.policy.rules.list.table.action.delete">Delete</span> + </a> + + <div ng-if="aRule.loader"> + + <moon-loader></moon-loader> + + </div> + + </td> + + </tr> + + </tbody> + + </table> + + </div> + + </div> + + </div> + + <div ng-if="list.editMode" class="panel panel-default"> + + <div class="panel-heading"> + + <h4 data-translate="moon.policy.rules.edit.action.add.title">Add a Rules</h4> + + </div> + + <div class="panel-body">. + + <moon-rules-edit policy="list.policy"></moon-rules-edit> + + </div> + + </div> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/policy/edit/parameter/rules/rules.edit.dir.js b/moon_gui/static/app/policy/edit/parameter/rules/rules.edit.dir.js new file mode 100755 index 00000000..b7bb7614 --- /dev/null +++ b/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/moon_gui/static/app/policy/edit/parameter/rules/rules.list.dir.js b/moon_gui/static/app/policy/edit/parameter/rules/rules.list.dir.js new file mode 100755 index 00000000..5c3e7457 --- /dev/null +++ b/moon_gui/static/app/policy/edit/parameter/rules/rules.list.dir.js @@ -0,0 +1,302 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .directive('moonRulesList', moonRulesList); + + moonRulesList.$inject = []; + + function moonRulesList() { + + return { + templateUrl : 'html/policy/edit/parameter/rules/rules-list.tpl.html', + bindToController : true, + controller : moonRulesListController, + controllerAs : 'list', + scope : { + policy: '=', + editMode : '=' + }, + restrict : 'E', + replace : true + }; + } + + angular + .module('moon') + .controller('moonRulesListController', moonRulesListController); + + moonRulesListController.$inject = [ '$scope', '$rootScope', 'NgTableParams', '$filter', 'metaRuleService', 'rulesService', 'dataService', '$translate', 'alertService' ]; + + function moonRulesListController( $scope, $rootScope, NgTableParams, $filter, metaRuleService, rulesService, dataService, $translate, alertService ) { + + var list = this; + + list.rules = []; + list.editMode = $scope.list.editMode; + + list.loadingRules = true; + + list.table = {}; + + list.getRules = getRules; + list.hasRules = hasRules; + list.refreshRules = refreshRules; + list.deleteRules = deleteRules; + + list.getMetaRuleFromRule = getMetaRuleFromRule; + list.getCategoryFromRuleIndex = getCategoryFromRuleIndex; + + list.isRuleIndexSubjectCategory = isRuleIndexSubjectCategory; + list.isRuleIndexObjectCategory = isRuleIndexObjectCategory; + list.isRuleIndexActionCategory = isRuleIndexActionCategory; + + activate(); + + function activate(){ + + newRulesTable(); + + manageRules(); + + } + + var rootListeners = { + + 'event:createRulesFromDataRulesSuccess': $rootScope.$on('event:createRulesFromDataRulesSuccess', addRulesToList) + + }; + + _.each(rootListeners, function(unbind){ + $scope.$on('$destroy', rootListeners[unbind]); + }); + + function manageRules(){ + + rulesService.findAllFromPolicyWithCallback(list.policy.id, function(data){ + + list.rules = data; + list.loadingRules = false; + + refreshRules(); + + }); + } + + function newRulesTable() { + + list.table = new NgTableParams({ + + page: 1, // show first page + count: 10 // count per page + + }, { + + total: function () { return list.getRules().length; }, // length of data + getData: function($defer, params) { + + var orderedData = params.sorting() ? $filter('orderBy')(list.getRules(), params.orderBy()) : list.getRules(); + $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count())); + + }, + $scope: { $data: {} } + + }); + + return list.table; + + } + + function getMetaRuleFromRule(rule) { + + if(_.has(rule, 'meta_rule')){ + return rule.meta_rule; + } + + // if the call has not been made + if(!_.has(rule, 'callMetaRuleInProgress')){ + + rule.callMetaRuleInProgress = true; + + metaRuleService.findOneWithCallback(rule.meta_rule_id, function(meta_rule){ + + rule.callMetaRuleInProgress = false; + rule.meta_rule = meta_rule; + + }); + + } + + // if the call is in progress return false + return false; + } + + + /** + * Prerequisite : meta Rule must be completely loader + * Depending on the meta_rule, the rule array will be filled by subject(s), object(s) or an action(s) + * the only way to know if rule[i] contains a subject/object/action is to check + * how many subject/object/action are associated to a MetaRule + * For example if the associated MetaRule contains 2 subjects, 1 object and 2 actions + * then the 2 first elements of rule array are 2 subject, the third one will be an object, and the 2 last will be action + * @param index + * @param rule + */ + function getCategoryFromRuleIndex(index, rule){ + + if(!_.has(rule, 'rule_value')){ + // setting an array which will contains every value of the category + rule.rule_value = Array.apply(null, new Array(rule.rule.length)).map(function(){ + return { + category: {} + }; + }); + } + + if(_.has(rule.rule_value[index], 'callCategoryInProgress') && !rule.rule_value[index].callCategoryInProgress ){ + return rule.rule_value[index].category; + } + + // if the call has not been made + if(!_.has(rule.rule_value[index], 'callCategoryInProgress')){ + + rule.rule_value[index].callCategoryInProgress = true; + + var categoryId = 0; + + if(list.isRuleIndexSubjectCategory(index, rule)){ + + categoryId = rule.meta_rule.subject_categories[index]; + + dataService.subject.data.findOne(list.policy.id, categoryId, rule.rule[index], function(category){ + + rule.rule_value[index].callCategoryInProgress = false; + rule.rule_value[index].category = category; + + }); + + }else if(list.isRuleIndexObjectCategory(index, rule)){ + + + categoryId = rule.meta_rule.object_categories[index - rule.meta_rule.subject_categories.length ]; + + dataService.object.data.findOne(list.policy.id, categoryId, rule.rule[index], function(category){ + + rule.rule_value[index].callCategoryInProgress = false; + rule.rule_value[index].category = category; + + }); + + + }else if(list.isRuleIndexActionCategory(index, rule)){ + + categoryId = rule.meta_rule.action_categories[index - rule.meta_rule.subject_categories.length - rule.meta_rule.object_categories.length ]; + + dataService.action.data.findOne(list.policy.id, categoryId, rule.rule[index], function(category){ + + rule.rule_value[index].callCategoryInProgress = false; + rule.rule_value[index].category = category; + + }); + + }else{ + + rule.rule_value[index].callCategoryInProgress = false; + rule.rule_value[index].category = { + name : 'ERROR' + }; + } + + } + + // if the call is in progress return false + return false; + } + + function isRuleIndexSubjectCategory(index, rule){ + + var ind = index + 1; + + return ind <= rule.meta_rule.subject_categories.length; + + } + + function isRuleIndexObjectCategory(index, rule){ + + var ind = index + 1; + + return rule.meta_rule.subject_categories.length < ind && ind <= ( rule.meta_rule.object_categories.length + rule.meta_rule.subject_categories.length ); + + } + + function isRuleIndexActionCategory(index, rule){ + + var ind = index + 1; + + return ( rule.meta_rule.object_categories.length + rule.meta_rule.subject_categories.length ) < ind && ind <= ( rule.meta_rule.object_categories.length + rule.meta_rule.subject_categories.length + rule.meta_rule.action_categories.length); + + } + + function getRules() { + return (list.rules) ? list.rules : []; + } + + function hasRules() { + return list.getRules().length > 0; + } + + /** + * Refresh the table + */ + function refreshRules(){ + list.table.total(list.rules.length); + list.table.reload(); + } + + function addRulesToList(event, rules){ + list.rules.push(rules); + refreshRules(); + } + + /** + * Delete + */ + function deleteRules(rules){ + + rules.loader = true; + + rulesService.delete(rules.id, list.policy.id, deleteRulesSuccess, deleteRulesError ); + + function deleteRulesSuccess(){ + + $translate('moon.policy.rules.edit.action.add.delete.success').then( function(translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + removeRulesFromList(rules); + refreshRules(); + + rules.loader = false; + + } + + function deleteRulesError(reason){ + + $translate('moon.policy.rules.edit.action.add.delete.success', {reason: reason.message}).then( function(translatedValue) { + alertService.alertError(translatedValue); + }); + + rules.loader = false; + + } + + } + + function removeRulesFromList(rules){ + list.rules = _.without(list.rules, rules); + } + } + +})();
\ No newline at end of file diff --git a/moon_gui/static/app/policy/edit/policy-edit-basic.tpl.html b/moon_gui/static/app/policy/edit/policy-edit-basic.tpl.html new file mode 100755 index 00000000..f55c1d05 --- /dev/null +++ b/moon_gui/static/app/policy/edit/policy-edit-basic.tpl.html @@ -0,0 +1,89 @@ +<div class="row"> + + <form class="form-horizontal" role="form" name="edit.form"> + + <div class="form-group"> + + <label for="id" class="col-sm-3 control-label" data-translate="moon.policy.edit.basic.form.id">Id</label> + + <div class="col-sm-6"> + + <input name="id" id="id" disabled class="form-control" type="text" data-ng-model="edit.policyToEdit.id" required /> + + </div> + + </div> + + <div class="form-group" ng-class="{'has-error': edit.form.name.$invalid && edit.form.name.$dirty}"> + + <label for="name" class="col-sm-3 control-label" data-translate="moon.policy.edit.basic.form.name">Name</label> + + <div class="col-sm-6"> + + <input name="name" id="name" class="form-control" type="text" data-ng-model="edit.policyToEdit.name" required /> + + <div class="help-block" ng-show="edit.form.name.$dirty && edit.form.name.$invalid"> + <small class="error" ng-show="edit.form.name.$error.required" data-translate="moon.policy.edit.basic.check.name.required">Name is required</small> + </div> + + </div> + + </div> + + + <div class="form-group" ng-class="{'has-error': edit.form.model.$dirty && (edit.form.model.$invalid || !edit.selectedModel)}"> + + <label class="col-sm-3 control-label" data-translate="moon.policy.edit.basic.form.model">Models</label> + + <div class="col-sm-6"> + + <ui-select ng-model="edit.selectedModel" name="model" required> + <ui-select-match placeholder="(None)">{{$select.selected.name}}</ui-select-match> + <ui-select-choices repeat="model in edit.models"> + <div ng-value="model">{{model.name}}</div> + </ui-select-choices> + </ui-select> + + <moon-loader ng-if="edit.modelsLoading"></moon-loader> + + <div class="help-block" ng-show="edit.form.model.$dirty && (edit.form.model.$invalid || !edit.selectedModel)"> + <small class="error" ng-show="edit.form.model.$error.required" data-translate="moon.policy.edit.basic.check.model.required">Model is required</small> + </div> + + </div> + + </div> + + <div class="form-group"> + + <label for="description" class="col-sm-3 control-label" data-translate="moon.policy.edit.basic.form.description">Description</label> + <div class="col-sm-6"> + <textarea id="description" name="description" class="form-control" data-ng-model="edit.policyToEdit.description"></textarea> + </div> + + </div> + + <div class="form-group"> + + <div class="col-sm-2 col-sm-offset-3"> + + <a href="" ng-disabled="edit.loading" ng-click="edit.init()" class="btn btn-default"> + <span data-translate="moon.policy.edit.basic.action.init">Init</span> + </a> + </div> + + <div class="col-sm-4 col-sm-offset-2"> + + <a href="" ng-disabled="edit.loading" ng-click="edit.editPolicy()" class="btn btn-warning"> + <span class="glyphicon glyphicon-save"></span> + <span data-translate="moon.policy.edit.basic.action.update">Update</span> + </a> + + <moon-loader ng-if="edit.loading"></moon-loader> + </div> + + </div> + + </form> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/policy/edit/policy-edit.tpl.html b/moon_gui/static/app/policy/edit/policy-edit.tpl.html new file mode 100755 index 00000000..a1a6a54a --- /dev/null +++ b/moon_gui/static/app/policy/edit/policy-edit.tpl.html @@ -0,0 +1,202 @@ +<div class="container"> + + <div class="row"> + <h3 class="pull-left" data-translate="moon.policy.edit.title" data-translate-values="{ policyName: edit.policy.name }">Edit</h3> + </div> + + <div class="panel panel-default"> + + <div class="panel-heading"> + + <span data-translate="moon.policy.edit.basic.title" >Basic Information</span> + <a href="" ng-click="edit.editBasic = !edit.editBasic"> + <span data-translate="moon.policy.edit.update">Update</span> + <span class="glyphicon glyphicon-cog"></span> + </a> + + </div> + + <div class="panel-body"> + + <div ng-if="edit.editBasic"> + <moon-policy-edit-basic policy="edit.policy"></moon-policy-edit-basic> + </div> + + <div ng-if="!edit.editBasic"> + + <dl class="dl-horizontal"> + + <dt data-translate="moon.policy.edit.basic.form.id">Id</dt> + <dd ng-bind="edit.policy.id"></dd> + + <dt data-translate="moon.policy.edit.basic.form.name">Name</dt> + <dd ng-bind="edit.policy.name"></dd> + + <dt data-translate="moon.policy.edit.basic.form.genre">Genre</dt> + <dd ng-bind="edit.policy.genre"></dd> + + <dt data-translate="moon.policy.edit.basic.form.model">Model</dt> + <dd> + + <span ng-if="edit.loadingModel"> + <moon-loader ng-if="edit.loadingModel"></moon-loader> + </span> + <span ng-if="!edit.loadingModel"> + <span ng-bind="edit.policy.model.name" ></span> + </span> + + </dd> + + <dt data-translate="moon.policy.edit.basic.form.description">Description</dt> + <dd ng-bind="edit.policy.description"></dd> + + </dl> + + </div> + + </div> + + </div> + + <div class="panel panel-default"> + + <div class="panel-heading"> + + <span data-translate="moon.policy.edit.perimeter.title" >Perimeters</span> + + <a href="" ng-click="edit.showPerimeters = !edit.showPerimeters"> + + <span ng-if="!edit.showPerimeters"> + <span data-translate="moon.policy.edit.show.open">Show</span> + <span class="glyphicon glyphicon-eye-open"></span> + </span> + + <span ng-if="edit.showPerimeters"> + <span data-translate="moon.policy.edit.show.close">Show</span> + <span class="glyphicon glyphicon-eye-close"></span> + </span> + + </a> + + <!--<a href="" ng-if="edit.showPerimeters"> + <span data-translate="moon.policy.edit.update">Update</span> + <span class="glyphicon glyphicon-cog"></span> + </a>--> + + </div> + + <div class="panel-body" ng-if="edit.showPerimeters"> + + <moon-perimeter-list edit-mode="true" policy="edit.policy" ></moon-perimeter-list> + + </div> + + </div> + + <div class="panel panel-default"> + + <div class="panel-heading"> + + <span data-translate="moon.policy.edit.data.title" >Data</span> + + <a href="" ng-click="edit.showData = !edit.showData"> + + <span ng-if="!edit.showData"> + <span data-translate="moon.policy.edit.show.open">Show</span> + <span class="glyphicon glyphicon-eye-open"></span> + </span> + + <span ng-if="edit.showData"> + <span data-translate="moon.policy.edit.show.close">Show</span> + <span class="glyphicon glyphicon-eye-close"></span> + </span> + + </a> + + <!--<a href="" ng-if="edit.showData"> + <span data-translate="moon.policy.edit.update">Update</span> + <span class="glyphicon glyphicon-cog"></span> + </a>--> + + </div> + + <div class="panel-body" ng-if="edit.showData" > <!-- --> + + <moon-data-list edit-mode="true" policy="edit.policy" ></moon-data-list> + + </div> + + </div> + + <div class="panel panel-default"> + + <div class="panel-heading"> + + <span data-translate="moon.policy.edit.rules.title" >Rules</span> + + <a href="" ng-click="edit.showRules = !edit.showRules"> + + <span ng-if="!edit.showRules"> + <span data-translate="moon.policy.edit.show.open">Show</span> + <span class="glyphicon glyphicon-eye-open"></span> + </span> + + <span ng-if="edit.showRules"> + <span data-showRules="moon.policy.edit.show.close">Close</span> + <span class="glyphicon glyphicon-eye-close"></span> + </span> + + </a> + + <!--<a href="" ng-if="edit.showRules"> + <span data-translate="moon.policy.edit.update">Update</span> + <span class="glyphicon glyphicon-cog"></span> + </a>--> + + </div> + + <div class="panel-body" ng-if="edit.showRules"> + + <moon-rules-list edit-mode="true" policy="edit.policy" ></moon-rules-list> + + </div> + + </div> + + + <div class="panel panel-default"> + + <div class="panel-heading"> + + <span data-translate="moon.policy.edit.assignments.title" >Assignments</span> + + <a href="" ng-click="edit.showAssignments = !edit.showAssignments"> + + <span ng-if="!edit.showAssignments"> + <span data-translate="moon.policy.edit.show.open">Show</span> + <span class="glyphicon glyphicon-eye-open"></span> + </span> + + <span ng-if="edit.showAssignments"> + <span data-showRules="moon.policy.edit.show.close">Close</span> + <span class="glyphicon glyphicon-eye-close"></span> + </span> + + </a> + + <!--<a href="" ng-if="edit.showRules"> + <span data-translate="moon.policy.edit.update">Update</span> + <span class="glyphicon glyphicon-cog"></span> + </a>--> + + </div> + + <div class="panel-body" ng-if="edit.showAssignments"> + + <moon-assignments-list edit-mode="true" policy="edit.policy" ></moon-assignments-list> + + </div> + + </div> + +</div> diff --git a/moon_gui/static/app/policy/edit/policy.controller.edit.js b/moon_gui/static/app/policy/edit/policy.controller.edit.js new file mode 100755 index 00000000..123ee58b --- /dev/null +++ b/moon_gui/static/app/policy/edit/policy.controller.edit.js @@ -0,0 +1,74 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('PolicyEditController', PolicyEditController); + + PolicyEditController.$inject = ['$scope', '$rootScope', 'policy', 'modelService']; + + function PolicyEditController($scope, $rootScope, policy, modelService) { + + var edit = this; + + edit.policy = policy; + + edit.editBasic = false; + + edit.showPerimeters = false; + edit.showData = false; + edit.showRules = false; + edit.showAssignments = false; + + + activate(); + + function activate(){ + + manageModel(); + + } + + function manageModel(){ + + edit.loadingModel = true; + + modelService.findOneWithCallback( edit.policy.model_id, function(model){ + + edit.loadingModel = false; + edit.policy.model = model; + + }); + + } + + /* + * ---- events + */ + var rootListeners = { + + 'event:policyUpdatedSuccess': $rootScope.$on('event:policyUpdatedSuccess', policyUpdatedSuccess) + + }; + + for (var unbind in rootListeners) { + $scope.$on('$destroy', rootListeners[unbind]); + } + + /** + * When the model is updated, this function refresh the current model with the new changes + * @param event + * @param policy + */ + function policyUpdatedSuccess(event, policy){ + + edit.policy = policy; + + manageModel(); + + } + + } + +})(); diff --git a/moon_gui/static/app/policy/edit/policy.edit.basic.dir.js b/moon_gui/static/app/policy/edit/policy.edit.basic.dir.js new file mode 100755 index 00000000..c32d9e69 --- /dev/null +++ b/moon_gui/static/app/policy/edit/policy.edit.basic.dir.js @@ -0,0 +1,134 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .directive('moonPolicyEditBasic', moonPolicyEditBasic); + + moonPolicyEditBasic.$inject = []; + + function moonPolicyEditBasic() { + + return { + templateUrl : 'html/policy/edit/policy-edit-basic.tpl.html', + bindToController : true, + controller : moonPolicyEditBasicController, + controllerAs : 'edit', + scope : { + policy : '=' + }, + restrict : 'E', + replace : true + }; + } + + angular + .module('moon') + .controller('moonPolicyEditBasicController', moonPolicyEditBasicController); + + moonPolicyEditBasicController.$inject = ['$scope', 'policyService', 'formService', 'alertService', '$translate', 'utilService', 'modelService']; + + function moonPolicyEditBasicController($scope, policyService, formService, alertService, $translate, utilService, modelService){ + + var edit = this; + + edit.editPolicy = editPolicy; + edit.init = init; + + edit.form = {}; + edit.modelsLoading = true; + + + activate(); + + function activate(){ + + edit.policy = $scope.edit.policy; + + edit.policyToEdit = angular.copy(edit.policy); + + console.log(edit.policyToEdit); + + resolveModels(); + + } + + /* + * + */ + + function resolveModels() { + + modelService.findAllWithCallBack(resolveModelsCallback); + + } + + function resolveModelsCallback(models) { + + edit.models = models; + + _.each(models, function(model){ + + if(model.id === edit.policy.model_id){ + edit.selectedModel = model; + } + + }); + + edit.modelsLoading = false; + + } + + + function editPolicy(){ + + if(formService.isInvalid(edit.form)) { + + formService.checkFieldsValidity(edit.form); + + }else{ + + edit.loading = true; + + delete edit.policyToEdit.model; + + edit.policyToEdit.model_id = edit.selectedModel.id; + + policyService.update(edit.policyToEdit, updateSuccess, updateError); + + } + + function updateSuccess(data) { + + var updatedPolicy = utilService.transformOne(data, 'policies'); + + $translate('moon.policy.edit.basic.success', { policyName: updatedPolicy.name }).then( function(translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + edit.loading = false; + + $scope.$emit('event:policyUpdatedSuccess', updatedPolicy); + + } + + function updateError(reason) { + + $translate('moon.policy.edit.basic.error', { policyName: edit.policy.name }).then( function(translatedValue) { + alertService.alertError(translatedValue); + }); + + edit.loading = false; + + } + } + + function init(){ + + edit.policyToEdit = angular.copy(edit.policy); + + } + } + +})(); diff --git a/moon_gui/static/app/policy/policy-list.tpl.html b/moon_gui/static/app/policy/policy-list.tpl.html new file mode 100755 index 00000000..aeb90f0b --- /dev/null +++ b/moon_gui/static/app/policy/policy-list.tpl.html @@ -0,0 +1,131 @@ +<div class="container"> + + <div> + <form class="form-inline pull-right"> + <div class="form-group"> + <div> + <input id="searcPolicy" data-ng-model="list.search.query" type="text" class="form-control" placeholder="{{'moon.policy.list.search.placeholder' | translate}}" /> + </div> + </div> + <div class="form-group"> + <div> + <button type="submit" class="btn btn-danger" data-ng-click="list.search.reset()" data-translate="moon.policy.list.search.reset">Reset</button> + </div> + </div> + </form> + </div> + + <div> </div> + <div> </div> + <div> </div> + + + <div class="row" > + + <div class="table-responsive" data-role="table"> + + <table class="table table-striped table-hover" ng-table="list.table"> + + <colgroup> + <col class="col-md-4" /> + <col class="col-md-2" /> + <col class="col-md-2" /> + <col class="col-md-1" /> + </colgroup> + + <thead> + + <tr> + + <th class="customTables sortable" + ng-class="{ 'sort-asc': list.table.isSortBy('name', 'asc'), 'sort-desc': list.table.isSortBy('name', 'desc') }" + ng-click="list.table.sorting('name', list.table.isSortBy('name', 'asc') ? 'desc' : 'asc')"> + <div data-translate="moon.policy.list.table.name">Name</div> + </th> + + <th class="customTables sortable" + ng-class="{ 'sort-asc': list.table.isSortBy('genre', 'asc'), 'sort-desc': list.table.isSortBy('genre', 'desc') }" + ng-click="list.table.sorting('genre', list.table.isSortBy('genre', 'asc') ? 'desc' : 'asc')"> + <div data-translate="moon.policy.list.table.genre">Genre</div> + </th> + + <th class="customTables sortable" + ng-class="{ 'sort-asc': list.table.isSortBy('description', 'asc'), 'sort-desc': list.table.isSortBy('description', 'desc') }" + ng-click="list.table.sorting('description', list.table.isSortBy('description', 'asc') ? 'desc' : 'asc')"> + <div data-translate="moon.policy.list.table.description">Description</div> + </th> + + <th class="customTables sortable"> + <div data-translate="moon.policy.list.action.title">Actions</div> + </th> + + </tr> + + </thead> + + <tbody ng-if="!list.hasPolicies()"> + <tr> + <td colspan="12"><span data-translate="moon.policy.list.table.notFound">There is no policy</span></td> + </tr> + </tbody> + + <tbody ng-if="list.hasPolicies()"> + + <tr ng-repeat="policy in $data | filter:list.search.find | orderBy:sort:reverse"> + + <td ng-bind="policy.name"></td> + + <td ng-bind="policy.genre"></td> + + <td ng-bind="policy.description"></td> + + <td> + <div class="dropdown"> + <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown"> + <span data-translate="moon.policy.list.action.title">Actions</span> + <span class="caret"></span> + </button> + <ul class="dropdown-menu"> + + <li> + <a href="" ui-sref="moon.policy.edit({id: policy.id})"> + <span class="glyphicon glyphicon-cog"></span> + <span class="control-label" data-translate="moon.policy.list.action.edit">Edit</span> + </a> + </li> + + <li class="divider"></li> + + <li> + <a href="" ng-click="list.del.showModal(policy)"> + <span class="glyphicon glyphicon-trash"></span> + <span class="control-label" data-translate="moon.policy.list.action.delete">Delete</span> + </a> + </li> + + </ul> + </div> + </td> + + </tr> + + </tbody> + + </table> + + </div> + + <div class="container"> + + <div class="form-inline form-group"> + <a href="" ng-click="list.add.showModal()" class="btn btn-default"> + <span class="glyphicon glyphicon-plus-sign"></span> + <span data-translate="moon.policy.list.action.add">Add Model</span> + </a> + </div> + + </div> + + </div> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/policy/policy-mapped-list.tpl.html b/moon_gui/static/app/policy/policy-mapped-list.tpl.html new file mode 100755 index 00000000..127dae3b --- /dev/null +++ b/moon_gui/static/app/policy/policy-mapped-list.tpl.html @@ -0,0 +1,88 @@ +<div class="container"> + + <div class="row" ng-if="list.loadingPolicies"> + <moon-loader ng-if="list.loadingPolicies"></moon-loader> + </div> + + <div class="row" ng-if="!list.loadingPolicies" > + + <div class="table-responsive" data-role="table"> + + <table class="table table-striped table-hover" ng-table="list.table"> + + <colgroup> + <col class="col-md-4" /> + <col class="col-md-2" /> + <col class="col-md-2" /> + <col class="col-md-1" /> + </colgroup> + + <thead> + + <tr> + + <th class="customTables sortable" + ng-class="{ 'sort-asc': list.table.isSortBy('name', 'asc'), 'sort-desc': list.table.isSortBy('name', 'desc') }" + ng-click="list.table.sorting('name', list.table.isSortBy('name', 'asc') ? 'desc' : 'asc')"> + <div data-translate="moon.policy.list.table.name">Name</div> + </th> + + <th class="customTables sortable" + ng-class="{ 'sort-asc': list.table.isSortBy('genre', 'asc'), 'sort-desc': list.table.isSortBy('genre', 'desc') }" + ng-click="list.table.sorting('genre', list.table.isSortBy('genre', 'asc') ? 'desc' : 'asc')"> + <div data-translate="moon.policy.list.table.genre">Genre</div> + </th> + + <th class="customTables sortable" + ng-class="{ 'sort-asc': list.table.isSortBy('description', 'asc'), 'sort-desc': list.table.isSortBy('description', 'desc') }" + ng-click="list.table.sorting('description', list.table.isSortBy('description', 'asc') ? 'desc' : 'asc')"> + <div data-translate="moon.policy.list.table.description">Description</div> + </th> + + <th class="customTables sortable"> + <div data-translate="moon.policy.list.action.title">Actions</div> + </th> + </tr> + + </thead> + + <tbody ng-if="!list.hasPolicies()"> + <tr> + <td colspan="12"><span data-translate="moon.policy.list.table.notFound">There is no policy</span></td> + </tr> + </tbody> + + <tbody ng-if="list.hasPolicies()"> + + <tr ng-repeat="policy in $data | filter:list.search.find | orderBy:sort:reverse"> + <td ng-bind="policy.name"></td> + <td ng-bind="policy.genre"></td> + <td ng-bind="policy.description"></td> + <td> + <a href="" ng-click="list.unmap.showModal(policy)"> + <span class="glyphicon glyphicon-transfer"></span> + <em data-translate="moon.policy.list.action.unmap">Unmap</em> + </a> + </td> + </tr> + + </tbody> + + </table> + + </div> + + <div class="container"> + + <div class="form-inline form-group"> + <a href="" ng-click="list.map.showModal()" class="btn btn-default"> + <span class="glyphicon glyphicon-link"></span> + <em data-translate="moon.policy.list.action.map">Map a Policy to PDP</em> + </a> + </div> + + </div> + + </div> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/policy/policy.controller.list.js b/moon_gui/static/app/policy/policy.controller.list.js new file mode 100755 index 00000000..fc2c6503 --- /dev/null +++ b/moon_gui/static/app/policy/policy.controller.list.js @@ -0,0 +1,175 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('PolicyListController', PolicyListController); + + PolicyListController.$inject = ['$scope', 'policies', 'NgTableParams', '$filter', '$modal', '$rootScope']; + + function PolicyListController($scope, policies, NgTableParams, $filter, $modal, $rootScope) { + + var list = this; + + list.policies = policies; + + list.getPolicies = getPolicies; + list.hasPolicies = hasPolicies; + list.addPolicy = addPolicy; + list.refreshPolicies = refreshPolicies; + list.deletePolicy = deletePolicy; + + list.table = {}; + + list.search = { query: '', + find: searchPolicy, + reset: searchReset }; + + list.add = { modal: $modal({ template: 'html/policy/action/policy-add.tpl.html', show: false }), + showModal: showAddModal }; + + list.del = { modal: $modal({ template: 'html/policy/action/policy-delete.tpl.html', show: false }), + showModal: showDeleteModal }; + + activate(); + + function activate(){ + + newPoliciesTable(); + + } + + + /* + * ---- events + */ + + var rootListeners = { + + 'event:policyCreatedSuccess': $rootScope.$on('event:policyCreatedSuccess', policyCreatedSuccess), + 'event:policyCreatedError': $rootScope.$on('event:policyCreatedError', policyCreatedError), + + 'event:policyDeletedSuccess': $rootScope.$on('event:policyDeletedSuccess', policyDeletedSuccess), + 'event:policyDeletedError': $rootScope.$on('event:policyDeletedError', policyDeletedError) + + }; + + for (var unbind in rootListeners) { + $scope.$on('$destroy', rootListeners[unbind]); + } + + function getPolicies() { + return (list.policies) ? list.policies : []; + } + + function hasPolicies() { + return list.getPolicies().length > 0; + } + + function newPoliciesTable() { + + list.table = new NgTableParams({ + + page: 1, // show first page + count: 10, // count per page + sorting: { + name: 'asc', + genre: 'asc' + } + + }, { + + total: function () { return list.getPolicies().length; }, // length of data + getData: function($defer, params) { + + var orderedData = params.sorting() ? $filter('orderBy')(list.getPolicies(), params.orderBy()) : list.getPolicies(); + $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count())); + + }, + $scope: { $data: {} } + + }); + + return list.table; + + } + + + /* + * ---- search + */ + + function searchPolicy(policy){ + return (policy.name.indexOf(list.search.query) !== -1 || policy.genre.indexOf(list.search.query) !== -1 || policy.description.indexOf(list.search.query) !== -1); + } + + function searchReset() { + list.search.query = ''; + } + + /* + * ---- add + */ + function showAddModal() { + list.add.modal.$promise.then(list.add.modal.show); + } + + function policyCreatedSuccess(event, pdp) { + + list.addPolicy(pdp); + list.refreshPolicies(); + + list.add.modal.hide(); + + } + + function policyCreatedError(event, pdp) { + list.add.modal.hide(); + } + + function addPolicy(policy) { + list.policies.push(policy); + } + + function refreshPolicies() { + + list.table.total(list.policies.length); + list.table.reload(); + + } + + /* + * ---- delete + */ + + function showDeleteModal(policy) { + + list.del.modal.$scope.policy = policy; + list.del.modal.$promise.then(list.del.modal.show); + + } + + function deletePolicy(policy) { + + list.policies = _.chain(list.policies).reject({id: policy.id}).value(); + + } + + function policyDeletedSuccess(event, policy) { + + list.deletePolicy(policy); + list.refreshPolicies(); + + list.del.modal.hide(); + + } + + function policyDeletedError(event, policy) { + list.del.modal.hide(); + } + + + } + +})(); diff --git a/moon_gui/static/app/policy/policy.mapped.list.dir.js b/moon_gui/static/app/policy/policy.mapped.list.dir.js new file mode 100755 index 00000000..78bb3b8d --- /dev/null +++ b/moon_gui/static/app/policy/policy.mapped.list.dir.js @@ -0,0 +1,202 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .directive('moonPolicyMappedList', moonPolicyMappedList); + + moonPolicyMappedList.$inject = []; + + function moonPolicyMappedList() { + + return { + templateUrl : 'html/policy/policy-mapped-list.tpl.html', + bindToController : true, + controller : moonPolicyMappedListController, + controllerAs : 'list', + scope : { + pdp : '=' + }, + restrict : 'E', + replace : true + }; + } + + angular + .module('moon') + .controller('moonPolicyMappedListController', moonPolicyMappedListController); + + moonPolicyMappedListController.$inject = ['$scope', '$rootScope', 'NgTableParams', '$modal', '$filter', 'policyService']; + + function moonPolicyMappedListController($scope, $rootScope, NgTableParams, $modal, $filter, policyService){ + + var list = this; + + list.table = {}; + + + list.pdp = $scope.list.pdp; + + list.getPolicies = getPolicies; + list.hasPolicies = hasPolicies; + list.refreshPolicies = refreshPolicies; + + list.loadingPolicies = true; + + list.policies = []; + + + activate(); + + function activate() { + + loadPolicices(false); + + } + + /** + * + * @param refresh boolean, if !refresh then newPolicYtable will be called, if refresh, then refreshPolicies is called + */ + function loadPolicices(refresh){ + + if(_.isUndefined( list.pdp.security_pipeline)){ + return; + } + list.policiesId = list.pdp.security_pipeline; + + policyService.findSomeWithCallback(list.policiesId, function(policies){ + + list.policies = policies; + + list.loadingPolicies = false; + + if(refresh){ + + refreshPolicies(); + + }else{ + + newMPolicyTable(); + + } + + }); + + } + + list.map = { modal: $modal({ template: 'html/policy/action/mapping/policy-map.tpl.html', show: false }), + showModal: showMapModal }; + + list.unmap = { modal: $modal({ template: 'html/policy/action/mapping/policy-unmap.tpl.html', show: false }), + showModal: showUnmapModal }; + + /* + * ---- events + */ + var rootListeners = { + + 'event:policyMapToPdpSuccess': $rootScope.$on('event:policyMapToPdpSuccess', policyMapToPdpSuccess), + 'event:policyMapToPdpError': $rootScope.$on('event:policyMapToPdpError', policyMapToPdpError), + + 'event:policyUnMappedToPdpSuccess': $rootScope.$on('event:policyUnMappedToPdpSuccess', policyUnmappedSuccess), + 'event:policyUnMappedToPdpError': $rootScope.$on('event:policyUnMappedToPdpError', policyUnmappedError) + + }; + + for (var unbind in rootListeners) { + $scope.$on('$destroy', rootListeners[unbind]); + } + + + + function newMPolicyTable() { + + list.table = new NgTableParams({ + + page: 1, // show first page + count: 10 // count per page + + }, { + + total: function () { return list.getPolicies().length; }, // length of data + getData: function($defer, params) { + + var orderedData = params.sorting() ? $filter('orderBy')(list.getPolicies(), params.orderBy()) : list.getPolicies(); + $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count())); + + }, + $scope: { $data: {} } + + }); + + return list.table; + + } + + + function getPolicies() { + return (list.policies) ? list.policies : []; + } + + function hasPolicies() { + return list.getPolicies().length > 0; + } + + function refreshPolicies(){ + + list.table.total(list.getPolicies().length); + list.table.reload(); + + } + + function showMapModal(){ + list.map.modal.$scope.pdp = list.pdp; + list.map.modal.$promise.then(list.map.modal.show); + } + + function showUnmapModal(policy){ + + list.unmap.modal.$scope.pdp = list.pdp; + list.unmap.modal.$scope.policy = policy; + + list.unmap.modal.$promise.then(list.unmap.modal.show); + + } + + function policyMapToPdpSuccess(event, pdp){ + + list.pdp = pdp; + + loadPolicices(true); + + list.map.modal.hide(); + + } + + + function policyMapToPdpError(event) { + + list.map.modal.hide(); + + } + + function policyUnmappedSuccess(event, pdp) { + + list.pdp = pdp; + + loadPolicices(true); + + list.unmap.modal.hide(); + + } + + function policyUnmappedError(event) { + list.unmap.modal.hide(); + } + + + } + +})(); diff --git a/moon_gui/static/app/project/action/mapping/project-map.tpl.html b/moon_gui/static/app/project/action/mapping/project-map.tpl.html new file mode 100755 index 00000000..5ffd98e2 --- /dev/null +++ b/moon_gui/static/app/project/action/mapping/project-map.tpl.html @@ -0,0 +1,62 @@ +<div ng-controller="ProjectMapController as map" class="modal" tabindex="-1" data-role="modalMappingProject"> + + <div class="modal-dialog"> + + <div class="modal-content"> + + <div class="modal-header"> + <button type="button" class="close" ng-click="$hide()">×</button> + <h4 class="modal-title" data-translate="moon.project.map.title" data-translate-values="{projectName: map.project.name}"></h4> + </div> + + <div class="modal-body"> + + <form class="form-horizontal" role="form" name="map.form"> + + <div class="form-group" ng-class="{'has-error': map.form.pdp.$dirty && (map.form.pdp.$invalid || !map.selectedPDP)}"> + + <label class="col-sm-3 control-label" data-translate="moon.project.map.form.pdp">PDP</label> + + <div class="col-sm-6"> + + <ui-select ng-model="map.selectedPDP" name="pdp" required> + <ui-select-match placeholder="(None)" ng-bind="$select.selected.name"></ui-select-match> + <ui-select-choices repeat="pdp in map.pdps"> + <div ng-bind="pdp.name" ng-value="pdp"></div> + </ui-select-choices> + </ui-select> + + <img ng-if="map.pdpsLoading" src="assets/img/ajax-loader.gif" /> + + <div class="help-block" ng-show="map.form.pdp.$dirty && (map.form.pdp.$invalid || !map.selectedPDP)"> + <small class="error" ng-show="map.form.pdp.$error.required" data-translate="moon.project.map.check.pdp.required">PDP is required</small> + </div> + + </div> + + </div> + + </form> + + </div> + + <div class="modal-footer"> + <div class="btn-toolbar" style="float: right;"> + <a href="" ng-click="$hide()" class="btn btn-default"> + <span data-translate="moon.project.map.action.cancel">Cancel</span> + </a> + <a href="" ng-disabled="map.mappingLoading" ng-click="map.map()" class="btn btn-warning"> + <span class="glyphicon glyphicon-link"></span> + <span data-translate="moon.project.map.action.map">Map</span> + </a> + + <img ng-if="map.mappingLoading" src="assets/img/ajax-loader.gif" /> + + </div> + </div> + + </div> + + </div> + +</div> diff --git a/moon_gui/static/app/project/action/mapping/project-unmap.tpl.html b/moon_gui/static/app/project/action/mapping/project-unmap.tpl.html new file mode 100755 index 00000000..5cc5c6dd --- /dev/null +++ b/moon_gui/static/app/project/action/mapping/project-unmap.tpl.html @@ -0,0 +1,33 @@ +<div ng-controller="ProjectUnMapController as unmap" class="modal" tabindex="-1" data-role="modalUnmapProject"> + + <div class="modal-dialog"> + + <div class="modal-content"> + + <div class="modal-header"> + <button type="button" class="close" ng-click="$hide()">×</button> + <h4 class="modal-title" data-translate="moon.project.unmap.title"></h4> + </div> + + <div class="modal-body"> + <span data-translate="moon.project.unmap.content" data-translate-values="{ projectName: unmap.project.name, pdpName: unmap.project.mapping.authz.pdp.name }"></span> + </div> + + <div class="modal-footer"> + <div class="btn-toolbar" style="float: right;"> + <a href="" ng-click="$hide()" class="btn btn-default"> + <span data-translate="moon.project.unmap.action.cancel">Cancel</span> + </a> + <a href="" ng-disabled="unmap.unMappingLoading" ng-click="unmap.unmap()" class="btn btn-warning"> + <span class="glyphicon glyphicon-transfer"></span> + <span data-translate="moon.project.unmap.action.unmap">Unmap</span> + </a> + <img ng-if="unmap.unMappingLoading" src="assets/img/ajax-loader.gif" /> + </div> + </div> + + </div> + + </div> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/project/action/mapping/project.controller.map.js b/moon_gui/static/app/project/action/mapping/project.controller.map.js new file mode 100755 index 00000000..afa2bfc0 --- /dev/null +++ b/moon_gui/static/app/project/action/mapping/project.controller.map.js @@ -0,0 +1,107 @@ +/** + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('ProjectMapController', ProjectMapController); + + ProjectMapController.$inject = ['$scope', '$translate', 'alertService', 'formService', 'pdpService']; + + function ProjectMapController($scope, $translate, alertService, formService, pdpService) { + + var map = this; + + /* + * + */ + + map.form = {}; + + map.project = $scope.project; + + map.pdps = []; + + map.pdpsLoading = true; + + map.selectedPDP = null; + + map.map = mapProject; + + activate(); + + function activate(){ + + resolvePDPs(); + + } + + /* + * + */ + + function resolvePDPs() { + + pdpService.findAllWithCallBack(resolveMappedProjects); + + } + + function resolveMappedProjects(pdps) { + + map.pdps = _.filter(pdps, function(pdp){ + return _.isNull(pdp.keystone_project_id); + }); + + map.pdpsLoading = false; + + } + + function mapProject() { + + if(formService.isInvalid(map.form)) { + + formService.checkFieldsValidity(map.form); + + } else { + + map.mappingLoading = true; + + pdpService.map( map.selectedPDP, map.project.id, mapSuccess, mapError); + + } + + function mapSuccess(data) { + + map.project.pdp = map.selectedPDP; + + $translate('moon.project.map.success', { projectName: map.project.name, pdpName: map.selectedPDP.name }).then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + map.mappingLoading = false; + + $scope.$emit('event:projectMappedSuccess', map.project); + + } + + function mapError(response) { + + $translate('moon.project.map.error', { projectName: map.project.name, pdpName: map.selectedPDP.name }).then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + map.mappingLoading = false; + + $scope.$emit('event:projectMappedError', map.project); + + } + + } + + } + +})(); diff --git a/moon_gui/static/app/project/action/mapping/project.controller.unmap.js b/moon_gui/static/app/project/action/mapping/project.controller.unmap.js new file mode 100755 index 00000000..911b30ff --- /dev/null +++ b/moon_gui/static/app/project/action/mapping/project.controller.unmap.js @@ -0,0 +1,74 @@ +/** + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('ProjectUnMapController', ProjectUnMapController); + + ProjectUnMapController.$inject = ['$scope', '$translate', 'alertService', 'pdpService']; + + function ProjectUnMapController($scope, $translate, alertService, pdpService) { + + var unmap = this; + + /* + * + */ + + unmap.project = $scope.project; + unmap.unMappingLoading = false; + + unmap.unmap = unMapProject; + + /* + * + */ + + function unMapProject() { + + + unmap.unMappingLoading = true; + + var pdpName = unmap.project.pdp.name; + + pdpService.unMap(unmap.project.pdp, unMapSuccess, unMapError); + + function unMapSuccess(data) { + + $translate('moon.project.unmap.success', { projectName: unmap.project.name, pdpName: pdpName }) + .then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + unmap.unMappingLoading = false; + + delete unmap.project.mapping; + delete unmap.project.pdp; + + $scope.$emit('event:projectUnmappedSuccess', unmap.project); + + } + + function unMapError(reason) { + + $translate('moon.project.unmap.error', { projectName: unmap.project.name, pdpName: pdpName }) + .then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + unmap.unMappingLoading = false; + + $scope.$emit('event:projectUnmappedError', unmap.project); + + } + + } + + } + +})(); diff --git a/moon_gui/static/app/project/action/project-add.tpl.html b/moon_gui/static/app/project/action/project-add.tpl.html new file mode 100755 index 00000000..a90dcfa1 --- /dev/null +++ b/moon_gui/static/app/project/action/project-add.tpl.html @@ -0,0 +1,89 @@ +<div ng-controller="ProjectAddController as add" class="modal" tabindex="-1" data-role="modalAddProject"> + + <div class="modal-dialog"> + + <div class="modal-content"> + + <div class="modal-header"> + <button type="button" class="close" ng-click="$hide()">×</button> + <h4 class="modal-title" data-translate="moon.project.add.title"></h4> + </div> + + <div class="modal-body"> + + <form class="form-horizontal" role="form" name="add.form"> + + <div class="form-group" ng-class="{'has-error': add.form.name.$invalid && add.form.name.$dirty}"> + + <label for="name" class="col-sm-3 control-label" data-translate="moon.project.add.form.name">Name</label> + + <div class="col-sm-6"> + + <input name="name" id="name" class="form-control" type="text" data-ng-model="add.project.project.name" required /> + + <div class="help-block" ng-show="add.form.name.$dirty && add.form.name.$invalid"> + <small class="error" ng-show="add.form.name.$error.required" data-translate="moon.project.add.check.name.required">Name is required</small> + </div> + + </div> + </div> + + <div class="form-group"> + <label for="description" class="col-sm-3 control-label" data-translate="moon.project.add.form.description">Description</label> + <div class="col-sm-6"> + <textarea id="description" name="description" class="form-control" data-ng-model="add.project.project.description"></textarea> + </div> + </div> + + <div class="form-group"> + <label for="enabled" class="col-sm-3 control-label" data-translate="moon.project.add.form.enabled">Enabled</label> + <div class="col-sm-6"> + <div class="radio"> + <input type="checkbox" id="enabled" name="enabled" class="js-switch" data-ng-model="add.project.project.enabled" ui-switch /> + </div> + </div> + </div> + + <div class="form-group" ng-class="{'has-error': add.form.domain.$invalid && add.form.domain.$dirty}"> + + <label for="domain" class="col-sm-3 control-label" data-translate="moon.project.add.form.domain">Domain</label> + + <div class="col-sm-6"> + + <input name="domain" id="domain" type="text" class="form-control" data-ng-model="add.project.project.domain" required /> + + <div class="help-block" ng-show="add.form.domain.$dirty && add.form.domain.$invalid"> + <small class="error" ng-show="add.form.domain.$error.required" data-translate="moon.project.add.check.domain.required">Domain is required</small> + </div> + + </div> + + </div> + + </form> + + </div> + + <div class="modal-footer"> + + <div class="btn-toolbar" style="float: right;"> + + <a href="" ng-click="$hide()" class="btn btn-default"> + <span data-translate="moon.project.add.action.cancel">Cancel</span> + </a> + + <a href="" ng-disabled="add.loading" ng-click="add.create()" class="btn btn-warning"> + <span class="glyphicon glyphicon-save"></span> + <span data-translate="moon.project.add.action.create">Create</span> + </a> + <img ng-if="add.loading" src="assets/img/ajax-loader.gif" /> + + </div> + + </div> + + </div> + + </div> + +</div> diff --git a/moon_gui/static/app/project/action/project-delete.tpl.html b/moon_gui/static/app/project/action/project-delete.tpl.html new file mode 100755 index 00000000..96b4f2e3 --- /dev/null +++ b/moon_gui/static/app/project/action/project-delete.tpl.html @@ -0,0 +1,45 @@ +<div ng-controller="ProjectDeleteController as del" class="modal" tabindex="-1" data-role="modalDeleteProject"> + + <div class="modal-dialog"> + + <div class="modal-content"> + + <div class="modal-header"> + <button type="button" class="close" ng-click="$hide()">×</button> + <h4 class="modal-title" data-translate="moon.project.remove.title"></h4> + </div> + + <div class="modal-body"> + <p><span data-translate="moon.project.remove.content.query" data-translate-values="{ projectName: del.project.name }"></span></p> + + <p ng-if="del.loadingPDP"><img src="assets/img/ajax-loader.gif" /></p> + + <div ng-if="!del.loadingPDP"> + <p ng-if="!del.isProjectMapped()"><span data-translate="moon.project.remove.content.isNotMapped">This Project is not map with any PDP</span></p> + <p ng-if="del.isProjectMapped()"> + <span data-translate="moon.project.remove.content.isMapped" data-translate-values="{ pdpName: del.project.pdp.name }"></span> + </p> + </div> + + </div> + + <div class="modal-footer"> + <div class="btn-toolbar" style="float: right;"> + + <a href="" ng-click="$hide()" class="btn btn-default"> + <span data-translate="moon.project.remove.action.cancel">Cancel</span> + </a> + <a href="" ng-disabled="del.loading || del.loadingPDP" ng-click="del.remove()" class="btn btn-warning"> + <span class="glyphicon glyphicon-trash"></span> + <span data-translate="moon.project.remove.action.delete">Delete</span> + </a> + <img ng-if="del.loading" src="assets/img/ajax-loader.gif" /> + + </div> + </div> + + </div> + + </div> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/project/action/project-view.tpl.html b/moon_gui/static/app/project/action/project-view.tpl.html new file mode 100755 index 00000000..3228c915 --- /dev/null +++ b/moon_gui/static/app/project/action/project-view.tpl.html @@ -0,0 +1,194 @@ +<div ng-controller="ProjectViewController as view" class="modal" tabindex="-1" data-role="modalViewProject"> + + <div class="modal-dialog"> + + <div class="modal-content"> + + <div class="modal-header"> + <button type="button" class="close" ng-click="$hide()">×</button> + <h4 class="modal-title" data-translate="moon.project.view.title" data-translate-values="{projectName: view.project.name}"></h4> + </div> + <div class="modal-body"> + <dl class="dl-horizontal"> + <dt>Id</dt> + <dd ng-bind="view.project.id"></dd> + <dt>Name</dt> + <dd ng-bind="view.project.name"></dd> + <dt>Is_domain</dt> + <dd ng-bind="view.project.is_domain"></dd> + <dt>Link</dt> + <dd ng-bind="view.project.links.self"></dd> + <dt>enabled</dt> + <dd ng-bind="view.project.enabled"></dd> + <dt>Parent id</dt> + <dd ng-bind="view.project.parent_id"></dd> + <dt>Domain id</dt> + <dd ng-bind="view.project.domain_id"></dd> + <dt>Description</dt> + <dd ng-bind="view.project.description"></dd> + </dl> + </div> + + <!--<div class="modal-body">--> + <!----> + <!--<!– objects –>--> + <!----> + <!--<div class="row">--> + <!--<div class="col-md-12">--> + <!--<h1 class="pull-left" data-translate="moon.project.view.object.title">Objects</h1>--> + <!--</div>--> + <!--</div>--> + <!----> + <!--<div class="row top05">--> + <!--<div class="col-md-3"><label data-translate="moon.project.view.object.name">Name</label></div>--> + <!--<div class="col-md-7"><label data-translate="moon.project.view.object.description">Description</label></div>--> + <!--<div class="col-md-2"><label data-translate="moon.project.view.object.enabled">Enabled</label></div>--> + <!--</div>--> + <!----> + <!--<div class="row" ng-if="view.objectsLoading">--> + <!--<div class="col-md-12"><img src="assets/img/ajax-loader.gif" /> <em data-translate="moon.project.view.object.loading">Loading Objects</em></div>--> + <!--</div>--> + <!----> + <!--<div class="row" ng-if="!view.objectsLoading && !view.hasObjects()">--> + <!--<div class="col-md-12" data-translate="moon.project.view.object.notFound">Objects not found</div>--> + <!--</div>--> + <!----> + <!--<div class="row" ng-if="!view.objectsLoading && view.hasObjects()" ng-repeat="object in view.objects">--> + <!--<div class="col-md-3">{{object.name}}</div> --> + <!--<div class="col-md-7">{{object.description}}</div>--> + <!--<div class="col-md-2">--> + <!--<span ng-if="object.enabled" class="glyphicon glyphicon-ok"></span>--> + <!--</div>--> + <!--</div>--> + <!----> + <!--<!– subjects –>--> + <!----> + <!--<div class="row top10">--> + <!--<div class="col-md-12">--> + <!--<h1 class="pull-left" data-translate="moon.project.view.subject.title">Subjects</h1>--> + <!--</div>--> + <!--</div>--> + <!----> + <!--<div class="row top05">--> + <!--<div class="col-md-3"><label data-translate="moon.project.view.subject.name">Name</label></div>--> + <!--<div class="col-md-3"><label data-translate="moon.project.view.subject.domain">Domain</label></div>--> + <!--<div class="col-md-4"><label data-translate="moon.project.view.subject.mail">Mail</label></div>--> + <!--<div class="col-md-2"><label data-translate="moon.project.view.subject.enabled">Enabled</label></div>--> + <!--</div>--> + <!----> + <!--<div class="row">--> + <!--<div class="col-md-3">--> + <!--<ui-select ng-model="view.selectedSubject" on-select="view.resolveRoles($item); view.resolveGroups($item)">--> + <!--<ui-select-match placeholder="(None)">{{$select.selected.name}}</ui-select-match>--> + <!--<ui-select-choices repeat="subject in view.subjects">--> + <!--<div ng-value="subject">{{subject.name}}</div>--> + <!--</ui-select-choices>--> + <!--</ui-select>--> + <!--<img ng-if="view.subjectsLoading" src="assets/img/ajax-loader.gif" />--> + <!--</div> --> + <!--<div class="col-md-3">{{view.selectedSubject.domain}}</div>--> + <!--<div class="col-md-4">{{view.selectedSubject.mail}}</div>--> + <!--<div class="col-md-2">--> + <!--<div ng-if="view.selectedSubject != null">--> + <!--<span ng-if="view.selectedSubject.enabled" class="glyphicon glyphicon-ok"></span>--> + <!--</div>--> + <!--</div>--> + <!--</div>--> + <!----> + <!--<!– roles –>--> + <!----> + <!--<div ng-if="view.hasSelectedSubject()">--> + <!----> + <!--<div class="row top10">--> + <!--<div class="col-md-12">--> + <!--<h1 class="pull-left" data-translate="moon.project.view.role.title">Roles</h1>--> + <!--</div>--> + <!--</div>--> + <!----> + <!--<div class="row top05">--> + <!----> + <!--<div class="col-md-3"><label data-translate="moon.project.view.role.value">Value</label></div>--> + <!--<div class="col-md-5"><label data-translate="moon.project.view.role.description">Description</label></div>--> + <!--<div class="col-md-2"><label data-translate="moon.project.view.role.assigned">Assigned</label></div>--> + <!--<div class="col-md-2"><label data-translate="moon.project.view.role.enabled">Enabled</label></div>--> + <!----> + <!--</div>--> + <!----> + <!--<div class="row" ng-if="view.rolesLoading">--> + <!--<div class="col-md-12"><img src="assets/img/ajax-loader.gif" /> <em data-translate="moon.project.view.role.loading">Loading Roles</em></div>--> + <!--</div>--> + <!----> + <!--<div class="row" ng-if="!view.rolesLoading && !view.hasRoles()">--> + <!--<div class="col-md-12" data-translate="moon.project.view.role.notFound">Roles not found</div>--> + <!--</div>--> + <!----> + <!--<div class="row" ng-if="!view.rolesLoading && view.hasRoles()" ng-repeat="role in view.roles">--> + <!----> + <!--<div class="col-md-3" ng-bind="role.value"></div>--> + <!--<div class="col-md-5" ng-bind="role.description"></div>--> + <!--<div class="col-md-2">--> + <!--<span ng-if="view.isRoleAssigned(role)" class="glyphicon glyphicon-ok"></span>--> + <!--</div>--> + <!--<div class="col-md-2">--> + <!--<span ng-if="role.enabled" class="glyphicon glyphicon-ok"></span>--> + <!--</div>--> + <!----> + <!--</div>--> + <!----> + <!--</div>--> + <!----> + <!--<!– groups –>--> + <!----> + <!--<div ng-if="view.hasSelectedSubject()">--> + <!----> + <!--<div class="row top10">--> + <!--<div class="col-md-12">--> + <!--<h1 class="pull-left" data-translate="moon.project.view.group.title">Groups</h1>--> + <!--</div>--> + <!--</div>--> + <!----> + <!--<div class="row top05">--> + <!----> + <!--<div class="col-md-3"><label data-translate="moon.project.view.group.value">Value</label></div>--> + <!--<div class="col-md-5"><label data-translate="moon.project.view.group.description">Description</label></div>--> + <!--<div class="col-md-2"><label data-translate="moon.project.view.group.assigned">Assigned</label></div>--> + <!--<div class="col-md-2"><label data-translate="moon.project.view.group.enabled">Enabled</label></div>--> + <!----> + <!--</div>--> + <!----> + <!--<div class="row" ng-if="view.groupsLoading">--> + <!--<div class="col-md-12"><img src="assets/img/ajax-loader.gif" /> <em data-translate="moon.project.view.group.loading">Loading Groups</em></div>--> + <!--</div>--> + <!----> + <!--<div class="row" ng-if="!view.groupsLoading && !view.hasGroups()">--> + <!--<div class="col-md-12" data-translate="moon.project.view.group.notFound">Groups not found</div>--> + <!--</div>--> + <!----> + <!--<div class="row" ng-if="!view.groupsLoading && view.hasGroups()" ng-repeat="group in view.groups">--> + <!----> + <!--<div class="col-md-3">{{group.value}}</div>--> + <!--<div class="col-md-5">{{group.description}}</div>--> + <!--<div class="col-md-2">--> + <!--<span ng-if="view.isGroupAssigned(group)" class="glyphicon glyphicon-ok"></span>--> + <!--</div>--> + <!--<div class="col-md-2">--> + <!--<span ng-if="group.enabled" class="glyphicon glyphicon-ok"></span>--> + <!--</div>--> + <!----> + <!--</div>--> + <!----> + <!--</div>--> + <!----> + <!--</div>--> + <!----> + <div class="modal-footer top10"> + <div class="btn-toolbar" style="float: right;"> + <button ng-click="$hide()" class="btn btn-default" data-translate="moon.project.view.action.close">Close</button> + </div> + </div> + + </div> + + </div> + +</div> diff --git a/moon_gui/static/app/project/action/project.controller.add.js b/moon_gui/static/app/project/action/project.controller.add.js new file mode 100755 index 00000000..4d12b75d --- /dev/null +++ b/moon_gui/static/app/project/action/project.controller.add.js @@ -0,0 +1,78 @@ +/** + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('ProjectAddController', ProjectAddController); + + ProjectAddController.$inject = ['$scope', '$translate', 'alertService', 'formService', 'projectService', 'DEFAULT_CST']; + + function ProjectAddController($scope, $translate, alertService, formService, projectService, DEFAULT_CST) { + + var add = this; + + /* + * + */ + + add.form = {}; + + add.loading = false; + + //@todo: verify if enable argument is understood serrver-side + add.project = { project: {name: null, description: null, enabled: true, domain: DEFAULT_CST.DOMAIN.DEFAULT} }; + add.create= createProject; + + /* + * ---- create + */ + + function createProject() { + + if(formService.isInvalid(add.form)) { + + formService.checkFieldsValidity(add.form); + + } else { + + add.loading = true; + + projectService.data.projects.create({}, add.project, createSuccess, createError); + + } + + function createSuccess(data) { + + var created = data.project; + $translate('moon.project.add.success', { projectName: created.name }).then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + add.loading = false; + + $scope.$emit('event:projectCreatedSuccess', created); + + } + + function createError(reason) { + + $translate('moon.project.add.error', { projectName: add.project.project.name }).then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + add.loading = false; + + $scope.$emit('event:projectCreatedError', add.project); + + } + + } + + } + +})(); diff --git a/moon_gui/static/app/project/action/project.controller.delete.js b/moon_gui/static/app/project/action/project.controller.delete.js new file mode 100755 index 00000000..4f18f8e6 --- /dev/null +++ b/moon_gui/static/app/project/action/project.controller.delete.js @@ -0,0 +1,134 @@ +/** + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('ProjectDeleteController', ProjectDeleteController); + + ProjectDeleteController.$inject = ['$scope', '$translate', 'alertService', 'projectService', 'pdpService']; + + function ProjectDeleteController($scope, $translate, alertService, projectService, pdpService) { + + var del = this; + + /* + * + */ + + del.project = $scope.project; + del.loading = false; + del.loadingPDP = true; + del.remove = deleteProjectAndMapping; + del.isProjectMapped = isProjectMapped; + del.pdps = []; + + activate(); + + /** + * + */ + + function activate(){ + + resolvePDPs(); + + } + + function resolvePDPs() { + + pdpService.findAllWithCallBack(function(data){ + + del.pdps = data; + + pdpService.mapPdpsToProject(del.project, del.pdps); + + del.loadingPDP = false; + + }); + + } + + function isProjectMapped(){ + return _.has(del.project, 'pdp'); + } + + /* + * ---- delete + */ + + + function deleteProjectAndMapping() { + + del.loading = true; + + + if(isProjectMapped() ) { + + removeMapping(deleteProject); + + }else{ + deleteProject(); + } + + } + + function removeMapping(callbackSuccess){ + + + var pdpName = unmap.project.pdp.name; + + pdpService.unMap(unmap.project, callbackSuccess, deleteMappingError); + + + function deleteMappingError(reason) { + + $translate('moon.project.remove.mapping.remove.error', { pdpName: pdpName} ).then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + del.loading = false; + + $scope.$emit('event:projectDeletedError', del.project); + + } + + + } + + function deleteProject(){ + + projectService.data.projects.remove({project_id: del.project.id}, deleteSuccess, deleteError); + + function deleteSuccess(data) { + + $translate('moon.project.remove.success', { projectName: del.project.name }).then(function (translatedValue) { + alertService.alertSuccess(translatedValue); + }); + + del.loading = false; + + $scope.$emit('event:projectDeletedSuccess', del.project); + + } + + function deleteError(reason) { + + $translate('moon.project.remove.error', { projectName: del.project.name, errorCode: reason.data.error.code, message : reason.data.error.message } ).then(function (translatedValue) { + alertService.alertError(translatedValue); + }); + + del.loading = false; + + $scope.$emit('event:projectDeletedError', del.project); + + } + + } + } + +})(); diff --git a/moon_gui/static/app/project/action/project.controller.view.js b/moon_gui/static/app/project/action/project.controller.view.js new file mode 100755 index 00000000..fe98a507 --- /dev/null +++ b/moon_gui/static/app/project/action/project.controller.view.js @@ -0,0 +1,216 @@ +/** + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('ProjectViewController', ProjectViewController); + + ProjectViewController.$inject = ['$q', '$scope', '$translate', 'alertService', 'projectService']; + + function ProjectViewController($q, $scope, $translate, alertService, projectService) { + + var view = this; + + /* + * + */ + + view.project = $scope.project; + + // view.subjects = []; + // view.subjectsLoading = true; + // view.selectedSubject = null; + // view.hasSubjects = hasSubjects; + // view.hasSelectedSubject = hasSelectedSubject; + // + // view.objects = []; + // view.objectsLoading = true; + // view.hasObjects = hasObjects; + // + // view.roles = []; + // view.groups = []; + // view.roleAssignments = []; + // view.groupAssignments = []; + // + // view.hasRoles = hasRoles; + // view.hasGroups = hasGroups; + // + // view.isRoleAssigned = isRoleAssigned; + // view.isGroupAssigned = isGroupAssigned; + // + // view.resolveRoles = resolveRoles; + // view.resolveGroups = resolveGroups; + // + // //resolveObjects(); + // //resolveSubjects(); + // + // /* + // * ---- objects + // */ + // + // function resolveObjects() { + // + // projectService.data.object.query({project_uuid: view.project.id}).$promise.then(resolveSuccess, resolveError); + // + // function resolveSuccess(data) { + // + // view.objectsLoading = false; + // view.objects = data.objects; + // + // } + // + // function resolveError(reason) { + // + // view.objectsLoading = false; + // + // $translate('moon.project.view.object.error').then(function (translatedValue) { + // alertService.alertError(translatedValue); + // }); + // + // } + // + // } + // + // function hasObjects() { + // return view.objects.length > 0; + // } + // + // /* + // * ---- subjects + // */ + // + // function resolveSubjects() { + // + // projectService.data.subject.query({project_uuid: view.project.uuid}).$promise.then(resolveSuccess, resolveError); + // + // function resolveSuccess(data) { + // + // view.subjectsLoading = false; + // view.subjects = data.users; + // + // } + // + // function resolveError(reason) { + // + // view.subjectsLoading = false; + // + // $translate('moon.project.view.subject.error').then(function (translatedValue) { + // alertService.alertError(translatedValue); + // }); + // + // } + // + // } + // + // function hasSubjects() { + // return view.subjects.lenght > 0; + // } + // + // function hasSelectedSubject() { + // return view.selectedSubject != null; + // } + // + // /* + // * ---- role + // */ + // + // function isRoleAssigned(role) { + // + // return _(view.roleAssignment.attributes).find(function(role_uuid) { + // return role.uuid === role_uuid; + // }).length !== 0; + // + // } + // + // function hasRoles() { + // return view.roles.length > 0; + // } + // + // function resolveRoles(subject) { + // + // view.rolesLoading = true; + // + // view.roles = []; + // view.roleAssignment = null; + // + // var promises = { roles: projectService.data.subjectRole.get({project_uuid: view.project.uuid, user_uuid: subject.uuid}).$promise, + // roleAssigment: projectService.data.roleAssigment.get({project_uuid: view.project.uuid, user_uuid: subject.uuid}).$promise }; + // + // $q.all(promises).then(resolveSuccess, resolveError); + // + // function resolveSuccess(data) { + // + // view.rolesLoading = false; + // view.roles = data.roles.roles; + // view.roleAssignment = _.first(data.roleAssigment.role_assignments); + // + // } + // + // function resolveError(reason) { + // + // view.rolesLoading = false; + // + // $translate('moon.project.view.role.error').then(function (translatedValue) { + // alertService.alertError(translatedValue); + // }); + // + // } + // + // } + // + // /* + // * ---- group + // */ + // + // function isGroupAssigned(group) { + // + // return _($scope.view.groupAssignment.attributes).find(function(group_uuid) { + // return group.uuid === group_uuid; + // }).length !== 0; + // + // } + // + // function hasGroups() { + // return view.groups.length > 0; + // } + // + // function resolveGroups(subject) { + // + // view.groupsLoading = true; + // + // view.groups = []; + // view.groupAssignment = null; + // + // var promises = { groups: projectService.data.subjectGroup.get({project_uuid: view.project.uuid, user_uuid: subject.uuid}).$promise, + // groupAssignment: projectService.data.groupAssigment.get({project_uuid: view.project.uuid, user_uuid: subject.uuid}).$promise }; + // + // $q.all(promises).then(resolveSuccess, resolveError); + // + // function resolveSuccess(data) { + // + // view.groupsLoading = false; + // view.groups = data.groups.groups; + // view.groupAssignment = _.first(data.groupAssignment.group_assignments); + // + // } + // + // function resolveError(reason) { + // + // view.groupsLoading = false; + // + // $translate('moon.project.view.group.error').then(function (translatedValue) { + // alertService.alertError(translatedValue); + // }); + // + // } + // + // } + // + } + +})(); diff --git a/moon_gui/static/app/project/project-list.tpl.html b/moon_gui/static/app/project/project-list.tpl.html new file mode 100755 index 00000000..82a3745e --- /dev/null +++ b/moon_gui/static/app/project/project-list.tpl.html @@ -0,0 +1,157 @@ + +<div class="container"> + + <div> + <form class="form-inline pull-right"> + <div class="form-group"> + <div> + <input id="searchProject" data-ng-model="list.search.query" type="text" class="form-control" placeholder="{{'moon.project.list.search.placeholder' | translate}}" /> + </div> + </div> + <div class="form-group"> + <div> + <button type="submit" class="btn btn-danger" data-ng-click="list.search.reset()" data-translate="moon.project.list.search.reset">Reset</button> + </div> + </div> + </form> + </div> + + <div> </div> + <div> </div> + <div> </div> + + <div class="row"> + + <div class="table-responsive" data-role="table"> + + <table class="table table-striped table-hover" ng-table="list.table"> + + <colgroup> + <col class="col-md-2" /> + <col class="col-md-2" /> + <col class="col-md-1" /> + <col class="col-md-1" /> + <col class="col-md-2" /> + <col class="col-md-1" /> + </colgroup> + + <thead> + + <tr> + + <th class="customTables sortable" + ng-class="{ 'sort-asc': list.table.isSortBy('name', 'asc'), 'sort-desc': list.table.isSortBy('name', 'desc') }" + ng-click="list.table.sorting('name', list.table.isSortBy('name', 'asc') ? 'desc' : 'asc')"> + <div data-translate="moon.project.list.table.name">Name</div> + </th> + + <th class="customTables sortable" + ng-class="{ 'sort-asc': list.table.isSortBy('domain', 'asc'), 'sort-desc': list.table.isSortBy('domain', 'desc') }" + ng-click="list.table.sorting('domain', list.table.isSortBy('domain', 'asc') ? 'desc' : 'asc')"> + <div data-translate="moon.project.list.table.domain">Domain</div> + </th> + + <th class="customTables sortable" + ng-class="{ 'sort-asc': list.table.isSortBy('enabled', 'asc'), 'sort-desc': list.table.isSortBy('enabled', 'desc') }" + ng-click="list.table.sorting('enabled', list.table.isSortBy('enabled', 'asc') ? 'desc' : 'asc')"> + <div data-translate="moon.project.list.table.enabled">Enabled</div> + </th> + + <th class="customTables sortable" + ng-class="{ 'sort-asc': list.table.isSortBy('description', 'asc'), 'sort-desc': list.table.isSortBy('description', 'desc') }" + ng-click="list.table.sorting('description', list.table.isSortBy('description', 'asc') ? 'desc' : 'asc')"> + <div data-translate="moon.project.list.table.description">Description</div> + </th> + + <th class="customTables"> + <div data-translate="moon.project.list.table.mapping">Mapping</div> + </th> + + <th class="customTables"> + <div data-translate="moon.project.list.action.title">Actions</div> + </th> + + </tr> + + </thead> + + <tbody ng-if="!list.hasProjects()"> + <tr> + <td colspan="2"><span data-translate="moon.project.list.table.notFound">There is no Projects</span></td> + </tr> + </tbody> + + <tbody ng-if="list.hasProjects()"> + + <tr ng-repeat="aProject in $data | filter:list.search.find | orderBy:sort:reverse"> + <td ng-bind="aProject.name"></td> + <td ng-bind="aProject.domain_id"></td> + <td> + <span ng-if="aProject.enabled" class="glyphicon glyphicon-ok"></span> + </td> + <td ng-bind="aProject.description"></td> + <td> + + <div ng-if="list.loadingPDPs"> + <img src="assets/img/ajax-loader.gif" /> <em data-translate="moon.project.list.table.loading.pdp">Loading PDP</em> + </div> + + <div ng-if="!list.loadingPDPs"> + <a href="" ng-if="!list.isProjectMapped(aProject)" ng-click="list.map.showModal(aProject)"> + <span class="glyphicon glyphicon-link"></span> <em data-translate="moon.project.list.action.map">Map to a PDP</em> + </a> + + <div ng-if="list.isProjectMapped(aProject)"> + + <span ng-bind="list.getMappedPDPName(aProject)"></span> + (<a href="" ng-click="list.unmap.showModal(aProject)"> + <span class="glyphicon glyphicon-transfer"></span> <em data-translate="moon.project.list.action.unmap">Unmap to a PDP</em> + </a>) + + </div> + </div> + + </td> + <td> + <div class="dropdown"> + <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown"> + <span data-translate="moon.project.list.action.title">Actions</span> + <span class="caret"></span> + </button> + <ul class="dropdown-menu"> + <li> + <a href="" ng-click="list.view.showModal(aProject)"> + <span class="glyphicon glyphicon-eye-open"></span> + <span class="control-label" data-translate="moon.project.list.action.detail">Detail</span> + </a> + </li> + <li> + <a href="" ng-click="list.del.showModal(aProject)"> + <span class="glyphicon glyphicon-trash"></span> + <span class="control-label" data-translate="moon.project.list.action.delete">Delete</span> + </a> + </li> + </ul> + </div> + </td> + + </tr> + + </tbody> + + </table> + + </div> + + <div class="container"> + <div class="form-inline form-group"> + <a href="" ng-click="list.add.showModal()" class="btn btn-default"> + <span class="glyphicon glyphicon-plus-sign"></span> + <span data-translate="moon.project.list.action.add">Add Project</span> + </a> + </div> + </div> + + </div> + +</div>
\ No newline at end of file diff --git a/moon_gui/static/app/project/project.controller.list.js b/moon_gui/static/app/project/project.controller.list.js new file mode 100755 index 00000000..b1cb2056 --- /dev/null +++ b/moon_gui/static/app/project/project.controller.list.js @@ -0,0 +1,310 @@ +/** + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .controller('ProjectListController', ProjectListController); + + ProjectListController.$inject = ['$rootScope', '$scope', '$filter', '$modal', 'ngTableParams', 'pdpService', 'projects']; + + function ProjectListController($rootScope, $scope, $filter, $modal, ngTableParams, pdpService, projects) { + + var list = this; + + /* + * + */ + + list.projects = projects; + list.pdps = []; + + list.getProjects = getProjects; + list.hasProjects = hasProjects; + list.isProjectMapped = isProjectMapped; + + list.table = {}; + + list.addProject = addProject; + list.deleteProject = deleteProject; + list.refreshProjects = refreshProjects; + + list.getMappedPDPName = getMappedPDPName; + list.getPdpFromProject = getPdpFromProject; + + list.search = { query: '', + find: searchProject, + reset: searchReset }; + + list.add = { modal: $modal({ template: 'html/project/action/project-add.tpl.html', show: false }), + showModal: showAddModal }; + + list.del = { modal: $modal({ template: 'html/project/action/project-delete.tpl.html', show: false }), + showModal: showDeleteModal }; + + list.map = { modal: $modal({ template: 'html/project/action/mapping/project-map.tpl.html', show: false }), + showModal: showMapModal }; + + list.unmap = { modal: $modal({ template: 'html/project/action/mapping/project-unmap.tpl.html', show: false }), + showModal: showUnmapModal }; + + list.view = { modal: $modal({ template: 'html/project/action/project-view.tpl.html', show: false }), + showModal: showViewModal }; + + activate(); + + + function activate(){ + + list.loadingPDPs = true; + + newProjectsTable(); + + pdpService.findAllWithCallBack(function(data){ + + list.pdps = data; + + pdpService.mapPdpsToProjects(list.projects, list.pdps); + + list.loadingPDPs = false; + + }); + } + + + /* + * ---- events + */ + + var rootListeners = { + + 'event:projectCreatedSuccess': $rootScope.$on('event:projectCreatedSuccess', projectCreatedSuccess), + 'event:projectCreatedError': $rootScope.$on('event:projectCreatedError', projectCreatedError), + + 'event:projectDeletedSuccess': $rootScope.$on('event:projectDeletedSuccess', projectDeletedSuccess), + 'event:projectDeletedError': $rootScope.$on('event:projectDeletedError', projectDeletedError), + + 'event:projectMappedSuccess': $rootScope.$on('event:projectMappedSuccess', projectMappedSuccess), + 'event:projectMappedError': $rootScope.$on('event:projectMappedError', projectMappedError), + + 'event:projectUnmappedSuccess': $rootScope.$on('event:projectUnmappedSuccess', projectUnmappedSuccess), + 'event:projectUnmappedError': $rootScope.$on('event:projectUnmappedError', projectUnmappedError) + + }; + + for (var unbind in rootListeners) { + $scope.$on('$destroy', rootListeners[unbind]); + } + + /* + * ---- table + */ + + /** + * Get projects array from the Keystone Moon. + * @return an array containing projects JSON + */ + function getProjects() { + return (list.projects) ? list.projects : []; + } + + function hasProjects() { + return list.getProjects().length > 0; + } + + function isProjectMapped(project){ + return _.has(project, 'pdp'); + } + + /** + * Prerequisite, isProjectMapped should return true + * @param project + * @returns {*} + */ + function getPdpFromProject(project){ + return project.pdp; + } + + function addProject(project) { + list.projects.push(project); + } + + function deleteProject(project) { + list.projects = _.chain(list.projects).reject({id: project.id}).value(); + } + + function refreshProjects() { + + list.table.total(list.projects.length); + list.table.reload(); + + } + + function newProjectsTable() { + + list.table = new ngTableParams({ + + page: 1, // show first page + count: 10, // count per page + sorting: { + name: 'asc' // initial sorting + } + + }, { + + total: function () { return list.getProjects().length; }, // length of data + getData: function($defer, params) { + + var orderedData = params.sorting() ? $filter('orderBy')(list.getProjects(), params.orderBy()) : list.getProjects(); + $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count())); + + }, + $scope: { $data: {} } + + }); + + return list.table; + + } + + /** + * + * @param project should have project.mapping.authz.pdp.name attribute + */ + function getMappedPDPName(project) { + return _.has(project, 'pdp') ? project.pdp.name : 'error'; + } + + /* + * ---- search + */ + + function searchProject(project){ + return (project.name.indexOf(list.search.query) !== -1 || project.description.indexOf(list.search.query) !== -1); + } + + function searchReset() { + list.search.query = ''; + } + + /* + * ---- add + */ + + function showAddModal() { + list.add.modal.$promise.then(list.add.modal.show); + } + + function projectCreatedSuccess(event, project) { + + list.addProject(project); + list.refreshProjects(); + + list.add.modal.hide(); + + } + + function projectCreatedError(event, project) { + list.add.modal.hide(); + } + + /* + * ---- delete + */ + + function showDeleteModal(project) { + + list.del.modal.$scope.project = project; + list.del.modal.$promise.then(list.del.modal.show); + + } + + function projectDeletedSuccess(event, project) { + + list.deleteProject(project); + list.refreshProjects(); + + list.del.modal.hide(); + + } + + function projectDeletedError(event, project) { + list.del.modal.hide(); + } + + /* + * ---- map + */ + + function showMapModal(project) { + + list.map.modal.$scope.project = project; + list.map.modal.$promise.then(list.map.modal.show); + + } + + function projectMappedSuccess(event, project) { + + activate(); + list.map.modal.hide(); + + } + + function projectMappedError(event, project) { + list.map.modal.hide(); + } + + /* + * ---- unmap + */ + + function showUnmapModal(project) { + + list.unmap.modal.$scope.project = project; + list.unmap.modal.$promise.then(list.unmap.modal.show); + + } + + function projectUnmappedSuccess(event, project) { + + + var index = _.findIndex(list.projects, function(aProject){ + return project.id === aProject.id; + }); + + if(index === -1){ + list.unmap.modal.hide(); + return false; + } + + list.projects[index] = project; + + list.refreshProjects(); + + list.unmap.modal.hide(); + + } + + function projectUnmappedError(event, project) { + list.unmap.modal.hide(); + } + + + /* + * ---- view + */ + + function showViewModal(project) { + + list.view.modal.$scope.project = project; + list.view.modal.$promise.then(list.view.modal.show); + + } + + } + +})(); diff --git a/moon_gui/static/app/services/gui/alert.service.js b/moon_gui/static/app/services/gui/alert.service.js new file mode 100755 index 00000000..8435eab1 --- /dev/null +++ b/moon_gui/static/app/services/gui/alert.service.js @@ -0,0 +1,39 @@ +/** + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .factory('alertService', alertService); + + alertService.$inject = [ 'toaster']; + + function alertService( toaster) { + + var service = {}; + + service.alertError = alertError; + service.alertSuccess = alertSuccess; + service.alertInfo = alertInfo; + + return service; + + function alertError(msg){ + toaster.pop('error', null, msg, 5000); + } + + function alertSuccess(msg){ + toaster.pop('success', null, msg, 5000); + } + + function alertInfo(msg){ + toaster.pop('note', null, msg, 5000); + } + + } + +})(); diff --git a/moon_gui/static/app/services/gui/browser.service.js b/moon_gui/static/app/services/gui/browser.service.js new file mode 100755 index 00000000..88c693a8 --- /dev/null +++ b/moon_gui/static/app/services/gui/browser.service.js @@ -0,0 +1,47 @@ +/** + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .factory('browserService', browserService); + + function browserService() { + + var service = {}; + + service.sayWho = sayWho; + + return service; + + function sayWho() { + + var ua= navigator.userAgent, tem, + + M= ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || []; + + if(/trident/i.test(M[1])){ + tem= /\brv[ :]+(\d+)/g.exec(ua) || []; + return 'IE '+(tem[1] || ''); + } + + if(M[1]=== 'Chrome'){ + tem= ua.match(/\bOPR\/(\d+)/); + if(tem!= null){ return 'Opera '+tem[1];} + } + + M= M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?']; + + if((tem= ua.match(/version\/(\d+)/i))!= null) M.splice(1, 1, tem[1]); + + return M.join(' '); + + }; + + }; + +})(); diff --git a/moon_gui/static/app/services/gui/form.service.js b/moon_gui/static/app/services/gui/form.service.js new file mode 100755 index 00000000..e436593c --- /dev/null +++ b/moon_gui/static/app/services/gui/form.service.js @@ -0,0 +1,47 @@ +/** + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .factory('formService', formService); + + function formService() { + + var service = {}; + + service.isInvalid = isInvalid; + service.checkFieldsValidity = checkFieldsValidity; + + return service; + + function isInvalid(form) { + return form.$invalid; + } + + function checkFieldsValidity(form) { + + var validationErrorKeys = _.keys(form.$error); + + _(validationErrorKeys).each(function(anErrorKey) { + + var formFields = _.values(form.$error[anErrorKey]); + + _(formFields).each(function(aFormField) { + + aFormField.$dirty = true; + aFormField.$setValidity(anErrorKey, false); + + }); + + }); + + } + + } + +})(); diff --git a/moon_gui/static/app/services/gui/menu.service.js b/moon_gui/static/app/services/gui/menu.service.js new file mode 100755 index 00000000..fd90a2fa --- /dev/null +++ b/moon_gui/static/app/services/gui/menu.service.js @@ -0,0 +1,49 @@ +/** + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .factory('menuService', menuService); + + menuService.$inject = ['$state']; + + function menuService($state) { + + var service = {}; + + service.isProjectTabActive = isProjectTabActive; + service.isPDPTabActive = isPDPTabActive; + service.isPolicyTabActive = isPolicyTabActive; + service.isLogsTabActive = isLogsTabActive; + service.isModelTabActive = isModelTabActive; + + return service; + + function isProjectTabActive() { + return $state.includes('moon.project'); + } + + function isPDPTabActive() { + return $state.includes('moon.pdp'); + } + + function isPolicyTabActive(){ + return $state.includes('moon.policy'); + } + + function isLogsTabActive(){ + return $state.includes('moon.logs'); + } + + function isModelTabActive(){ + return $state.includes('moon.model'); + } + + } + +})(); diff --git a/moon_gui/static/app/services/gui/security.pipeline.service.js b/moon_gui/static/app/services/gui/security.pipeline.service.js new file mode 100755 index 00000000..3831e487 --- /dev/null +++ b/moon_gui/static/app/services/gui/security.pipeline.service.js @@ -0,0 +1,29 @@ +(function() { + + 'use strict'; + + angular + .module('moon') + .factory('securityPipelineService', securityPipelineService); + + securityPipelineService.$inject = ['SECURITY_PIPELINE_CST','policyService']; + + function securityPipelineService(SECURITY_PIPELINE_CST, policyService) { + var service = {}; + + service.findAll = findAll; + + return service; + + function findAll(type){ + switch(type){ + case SECURITY_PIPELINE_CST.TYPE.POLICY : + return policyService.findAll(); + default : + return policyService.findAll(); + } + + } + } + +})(); diff --git a/moon_gui/static/app/services/gui/util.service.js b/moon_gui/static/app/services/gui/util.service.js new file mode 100755 index 00000000..7274244a --- /dev/null +++ b/moon_gui/static/app/services/gui/util.service.js @@ -0,0 +1,66 @@ +/** + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .factory('utilService', utilService); + + utilService.$inject = []; + + function utilService() { + + return { + + + /** + * Transforms an answer from server and return an array of objects instead the @param data + + * @param data object : { + * 'typeOfTheRreturnedObject' : { + * 'idObject1' : {....}, + * 'idObject2' : {....} + * } + * } + * @param typeOfObject + * @returns {Array} + */ + transform : function(data, typeOfObject){ + + var result = []; + + _.each(data[typeOfObject],function(item, key){ + item.id = key; + result.push(item); + }); + + return result; + }, + + /** + * same as transform but with only one object + * @param data + * @param typeOfObject the first elem of the dictonnary + */ + transformOne : function(data, typeOfObject){ + + var result = []; + + _.each(data[typeOfObject], function (item, key) { + item.id = key; + result.push(item); + }); + + return result[0]; + + } + + }; + + } + +})(); diff --git a/moon_gui/static/app/services/gui/version.service.js b/moon_gui/static/app/services/gui/version.service.js new file mode 100755 index 00000000..5f9f2786 --- /dev/null +++ b/moon_gui/static/app/services/gui/version.service.js @@ -0,0 +1,27 @@ +/** + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .factory('versionService', versionService); + + versionService.$inject = ['$resource']; + + function versionService($resource) { + + return { + + version: $resource('version.json', {}, { + get: {method: 'GET', isArray: false} + }) + + }; + + } + +})(); diff --git a/moon_gui/static/app/services/moon/model/model.service.js b/moon_gui/static/app/services/moon/model/model.service.js new file mode 100755 index 00000000..a676fc1a --- /dev/null +++ b/moon_gui/static/app/services/moon/model/model.service.js @@ -0,0 +1,105 @@ +/** + * @author Samy Abdallah + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .factory('modelService', modelService); + + modelService.$inject = ['$resource', 'REST_URI', 'metaRuleService', 'utilService']; + + function modelService($resource, REST_URI, metaRuleService, utilService) { + + return { + + data: $resource(REST_URI.MODELS + ':model_id', {}, { + get: {method: 'GET'}, + query: {method: 'GET'}, + create: {method: 'POST'}, + remove: {method: 'DELETE'}, + update: {method: 'PATCH'} + }), + + findAll: function () { + + return this.data.query().$promise.then(function (data) { + + return utilService.transform(data, 'models'); + + }); + + }, + + + findAllWithCallBack : function (callback){ + + return this.data.query().$promise.then(function (data) { + + callback( utilService.transform(data, 'models')); + + }); + + }, + + findOneWithCallback : function(modelId, callback){ + + return this.data.get({model_id: modelId}).$promise.then(function (data) { + + callback(utilService.transformOne(data, 'models')); + + }); + + }, + + findOneWithMetaRules: function (modelId) { + + return this.data.get({model_id: modelId}).$promise.then(function (data) { + + var res = utilService.transformOne(data, 'models'); + + if(res.meta_rules.length > 0){ + + metaRuleService.findSomeWithMetaData(res.meta_rules).then(function(metaRules){ + + res.meta_rules_values = metaRules; + res.id = modelId; + + return res; + + }); + + }else{ + + res.meta_rules_values = []; + res.id = modelId; + + } + + return res; + + }); + + }, + + delete: function (model, callbackSuccess, callbackError ) { + + delete model.meta_rules_values; + + this.data.remove({model_id: model.id}, model, callbackSuccess, callbackError); + + }, + + update: function (model, callbackSuccess, callbackError) { + + delete model.meta_rules_values; + this.data.update({model_id: model.id}, model, callbackSuccess, callbackError); + + } + + } + } +})();
\ No newline at end of file diff --git a/moon_gui/static/app/services/moon/pdp.service.js b/moon_gui/static/app/services/moon/pdp.service.js new file mode 100755 index 00000000..822f7414 --- /dev/null +++ b/moon_gui/static/app/services/moon/pdp.service.js @@ -0,0 +1,128 @@ +/** + * service allowing the client to interact with pdp + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .factory('pdpService', pdpService); + + pdpService.$inject = ['$q', '$resource','REST_URI', 'utilService']; + + function pdpService($q, $resource, REST_URI, utilService) { + + return { + + data: { + + pdp: $resource(REST_URI.PDP + ':pdp_id', {}, { + query: { method: 'GET', isArray: false }, + get: { method: 'GET', isArray: false }, + create: { method: 'POST' }, + update: { method:'PATCH'}, + remove: { method: 'DELETE' } + }) + + }, + + findAll: function() { + + return this.data.pdp.query().$promise.then(function (data) { + + return utilService.transform(data, 'pdps'); + + }); + + }, + + findAllWithCallBack : function (callback){ + + return this.data.pdp.query().$promise.then(function (data) { + + callback( utilService.transform(data, 'pdps')); + + }); + + }, + + findOne: function(id) { + + return this.data.pdp.get({pdp_id: id}).$promise.then(function (data) { + + return utilService.transformOne(data, 'pdps'); + + }); + + }, + + unMap: function(pdp, callbackSuccess, callbackError){ + + pdp.keystone_project_id = null; + + if(_.has(pdp, 'project')){ + delete pdp.project; + } + + this.data.pdp.update({pdp_id: pdp.id}, pdp, callbackSuccess, callbackError); + + }, + + map: function(pdp, projectId, callbackSuccess, callbackError){ + + pdp.keystone_project_id = projectId; + + this.data.pdp.update({pdp_id: pdp.id}, pdp, callbackSuccess, callbackError); + }, + + update: function (pdp, callbackSuccess, callbackError) { + + this.data.pdp.update({pdp_id: pdp.id}, pdp, callbackSuccess, callbackError); + + }, + + mapPdpsToProjects : mapPdpsToProjects, + + mapPdpsToProject : mapPdpsToProject + + }; + + /** + * Will assign each project to it related pdp + * @param projects a list of Project, a new attribute pdp will be add, if the related pdp is existing in @param pdps + * @param pdps a list of Pdp + */ + function mapPdpsToProjects(projects, pdps){ + + _.each(projects, function(project){ + + return mapPdpsToProject(project, pdps); + + }); + } + + function mapPdpsToProject(project, pdps){ + + if (_.isNull(project.keystone_project_id)){ + return false; + } + + var index = _.findIndex(pdps, function(pdp){ + return project.id === pdp.keystone_project_id; + }); + + if(index === -1){ + return false; + } + + project.pdp = pdps[index]; + + return true; + } + + } + +})(); diff --git a/moon_gui/static/app/services/moon/policy/parameters/assignements.service.js b/moon_gui/static/app/services/moon/policy/parameters/assignements.service.js new file mode 100755 index 00000000..ca138b45 --- /dev/null +++ b/moon_gui/static/app/services/moon/policy/parameters/assignements.service.js @@ -0,0 +1,133 @@ +/** + * @author Samy Abdallah + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .factory('assignmentsService', assignmentsService); + + assignmentsService.$inject = ['$resource', 'REST_URI', 'utilService']; + + function assignmentsService($resource, REST_URI, utilService) { + + var data = { + + subject: { + + policy: $resource(REST_URI.POLICIES + ':policy_id/subject_assignments/:perimeter_id/:category_id/:data_id', {}, { + get: {method: 'GET'}, + create: {method: 'POST'}, + remove: {method: 'DELETE'} + }) + + }, + + + object: { + + policy: $resource(REST_URI.POLICIES + ':policy_id/object_assignments/:perimeter_id/:category_id/:data_id', {}, { + get: {method: 'GET'}, + create: {method: 'POST'}, + remove: {method: 'DELETE'} + }) + + }, + + action: { + + policy: $resource(REST_URI.POLICIES + ':policy_id/action_assignments/:perimeter_id/:category_id/:data_id', {}, { + get: {method: 'GET'}, + create: {method: 'POST'}, + remove: {method: 'DELETE'} + }) + + } + + }; + + return { + + subject : { + + delete: function (policyId, perimeterId, categoryId, dataId, callbackSuccess, callbackError ) { + + data.subject.policy.remove({policy_id: policyId, perimeter_id: perimeterId, category_id: categoryId, data_id: dataId}, {}, callbackSuccess, callbackError); + + }, + + add:function (subject, policyId, callbackSuccess, callbackError ) { + + data.subject.policy.create({policy_id: policyId}, subject, callbackSuccess, callbackError); + + }, + + findAllFromPolicyWithCallback: function(policyId, callback){ + + data.subject.policy.get({policy_id: policyId}).$promise.then(function(data) { + + callback(utilService.transform(data, 'subject_assignments')); + + }); + + } + }, + + object : { + + + delete: function (policyId, perimeterId, categoryId, dataId, callbackSuccess, callbackError ) { + + data.object.policy.remove({policy_id: policyId, perimeter_id: perimeterId, category_id: categoryId, data_id: dataId}, {}, callbackSuccess, callbackError); + + }, + + add:function (object, policyId, callbackSuccess, callbackError ) { + + data.object.policy.create({policy_id: policyId}, object, callbackSuccess, callbackError); + + }, + + findAllFromPolicyWithCallback: function(policyId, callback){ + + data.object.policy.get({policy_id: policyId}).$promise.then(function(data) { + + callback(utilService.transform(data, 'object_assignments')); + + }); + + } + }, + + action : { + + delete: function (policyId, perimeterId, categoryId, dataId, callbackSuccess, callbackError ) { + + data.action.policy.remove({policy_id: policyId, perimeter_id: perimeterId, category_id: categoryId, data_id: dataId}, {}, callbackSuccess, callbackError); + + }, + + add:function (action, policyId, callbackSuccess, callbackError ) { + + data.action.policy.create({policy_id: policyId}, action, callbackSuccess, callbackError); + + }, + + findAllFromPolicyWithCallback: function(policyId, callback){ + + data.action.policy.get({policy_id: policyId}).$promise.then(function(data) { + + callback(utilService.transform(data, 'action_assignments')); + + }); + + } + } + + }; + + } +})();
\ No newline at end of file diff --git a/moon_gui/static/app/services/moon/policy/parameters/data.service.js b/moon_gui/static/app/services/moon/policy/parameters/data.service.js new file mode 100755 index 00000000..1bbd3b24 --- /dev/null +++ b/moon_gui/static/app/services/moon/policy/parameters/data.service.js @@ -0,0 +1,249 @@ +/** + * @author Samy Abdallah + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .factory('dataService', dataService); + + dataService.$inject = ['$resource', 'REST_URI', 'utilService']; + + function dataService($resource, REST_URI, utilService) { + + var data = { + + subject: { + + policy: $resource(REST_URI.POLICIES + ':policy_id/subject_data/:subject_id/:category_id/:data_id', {}, { + get: {method: 'GET'}, + create: {method: 'POST'}, + remove: {method: 'DELETE'} + }) + + }, + + object: { + + policy: $resource(REST_URI.POLICIES + ':policy_id/object_data/:object_id/:category_id/:data_id', {}, { + get: {method: 'GET', isArray: false}, + create: {method: 'POST'}, + remove: {method: 'DELETE'} + }) + + }, + + action: { + + policy: $resource(REST_URI.POLICIES + ':policy_id/action_data/:action_id/:category_id/:data_id', {}, { + get: {method: 'GET', isArray: false}, + create: {method: 'POST'}, + remove: {method: 'DELETE'} + }) + + } + + }; + + return { + + subject : { + + findAllFromPolicyWithCallback: function(policyId, callback){ + + data.subject.policy.get({policy_id: policyId}).$promise.then(function(data) { + + callback(utilService.transform(data['subject_data'][0], 'data')); + + }); + + }, + + findAllFromCategoriesWithCallback: function(policyId, categoryId, callback){ + + data.subject.policy.get({policy_id: policyId, category_id: categoryId}).$promise.then(function(data) { + + if(data['subject_data'][0]) { + + callback(utilService.transform(data['subject_data'][0], 'data')); + + }else{ + + callback([]) + + } + + }); + + }, + + delete: function (subject, policyId, categoryId, callbackSuccess, callbackError ) { + + data.subject.policy.remove({policy_id: policyId, category_id: categoryId, data_id: subject.id}, subject, callbackSuccess, callbackError); + + }, + + add: function (subject, policyId, categoryId, callbackSuccess, callbackError ) { + + data.subject.policy.create({policy_id: policyId, category_id: categoryId}, subject, callbackSuccess, callbackError); + + }, + + data: { + + findOne: function(policyId, subjectId, dataId, callback){ + + data.subject.policy.get({policy_id: policyId, subject_id: subjectId, data_id : dataId}).$promise.then(function(data) { + + if(data['subject_data'][0]){ + + callback(utilService.transformOne(data['subject_data'][0], 'data')); + + }else{ + + callback({ }); + + } + + }); + + } + } + }, + + object : { + + findAllFromPolicyWithCallback: function(policyId, callback){ + + data.object.policy.get({policy_id: policyId}).$promise.then(function(data) { + + callback(utilService.transform(data['object_data'][0], 'data')); + + }); + + }, + + findAllFromCategoriesWithCallback: function(policyId, categoryId, callback){ + + data.object.policy.get({policy_id: policyId, category_id: categoryId}).$promise.then(function(data) { + + if(data['object_data'][0]) { + + callback(utilService.transform(data['object_data'][0], 'data')); + + }else{ + + callback([]) + + } + + }); + + }, + + delete: function (object, policyId, categoryId, callbackSuccess, callbackError ) { + + data.object.policy.remove({policy_id: policyId, category_id: categoryId, data_id: object.id}, object, callbackSuccess, callbackError); + + }, + + add:function (object, policyId, categoryId, callbackSuccess, callbackError ) { + + data.object.policy.create({policy_id: policyId, category_id: categoryId}, object, callbackSuccess, callbackError); + + }, + + data: { + + findOne: function(policyId, objectId, dataId, callback){ + + data.object.policy.get({policy_id: policyId, object_id: objectId, data_id : dataId}).$promise.then(function(data) { + + if(data['object_data'][0]){ + + callback(utilService.transformOne(data['object_data'][0], 'data')); + + }else{ + + callback({ }); + + } + + }); + + } + } + }, + + action : { + + findAllFromPolicyWithCallback: function(policyId, callback){ + + data.action.policy.get({policy_id: policyId}).$promise.then(function(data) { + + callback(utilService.transform(data['action_data'][0], 'data')); + + }); + + }, + + findAllFromCategoriesWithCallback: function(policyId, categoryId, callback){ + + data.action.policy.get({policy_id: policyId, category_id: categoryId}).$promise.then(function(data) { + + if(data['action_data'][0]) { + + callback(utilService.transform(data['action_data'][0], 'data')); + + }else{ + + callback([]) + + } + + }); + + }, + + delete: function (action, policyId, categoryId, callbackSuccess, callbackError ) { + + data.action.policy.remove({policy_id: policyId, category_id: categoryId, data_id: action.id}, action, callbackSuccess, callbackError); + + }, + + add:function (action, policyId, categoryId, callbackSuccess, callbackError ) { + + data.action.policy.create({policy_id: policyId, category_id: categoryId}, action, callbackSuccess, callbackError); + + }, + + + data: { + + findOne: function(policyId, actionId, dataId, callback){ + + data.action.policy.get({policy_id: policyId, action_id: actionId, data_id : dataId}).$promise.then(function(data) { + + if(data['action_data'][0]){ + + callback(utilService.transformOne(data['action_data'][0], 'data')); + + }else{ + + callback({ }); + + } + + }); + + } + } + } + + }; + + } +})();
\ No newline at end of file diff --git a/moon_gui/static/app/services/moon/policy/parameters/perimeter.service.js b/moon_gui/static/app/services/moon/policy/parameters/perimeter.service.js new file mode 100755 index 00000000..42e7288a --- /dev/null +++ b/moon_gui/static/app/services/moon/policy/parameters/perimeter.service.js @@ -0,0 +1,460 @@ +/** + * @author Samy Abdallah + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .factory('perimeterService', perimeterService); + + perimeterService.$inject = ['$resource', 'REST_URI', '$q', 'utilService']; + + function perimeterService($resource, REST_URI, $q, utilService) { + + var data = { + + subject: { + + perimeter: $resource(REST_URI.PERIMETERS.subject + ':subject_id', {}, { + get: {method: 'GET', isArray: false}, + create: {method: 'POST'}, + remove: {method: 'DELETE'}, + update: { method: 'PATCH' } + }), + + policy: $resource(REST_URI.POLICIES + ':policy_id/subjects/:subject_id', {}, { + get: {method: 'GET'}, + create: {method: 'POST'}, + remove: {method: 'DELETE'}, + update: { method: 'PATCH' } + }) + + }, + + object: { + + perimeter: $resource(REST_URI.PERIMETERS.object + ':object_id', {}, { + get: {method: 'GET', isArray: false}, + create: {method: 'POST'}, + remove: {method: 'DELETE'}, + update: { method: 'PATCH' } + }), + + policy: $resource(REST_URI.POLICIES + ':policy_id/objects/:object_id', {}, { + get: {method: 'GET', isArray: false}, + create: {method: 'POST'}, + remove: {method: 'DELETE'}, + update: { method: 'PATCH' } + }) + + }, + + action: { + + perimeter: $resource(REST_URI.PERIMETERS.action + ':action_id', {}, { + get: {method: 'GET', isArray: false}, + create: {method: 'POST'}, + remove: {method: 'DELETE'}, + update: { method: 'PATCH' } + }), + + policy: $resource(REST_URI.POLICIES + ':policy_id/actions/:action_id', {}, { + get: {method: 'GET', isArray: false}, + create: {method: 'POST'}, + remove: {method: 'DELETE'}, + update: { method: 'PATCH' } + }) + + } + + }; + + return { + + subject : { + + findOne: function(subjectId, callback){ + + data.subject.perimeter.get({subject_id: subjectId}).$promise.then(function(data) { + + callback(utilService.transformOne(data, 'subjects')); + + }); + + }, + + findOneReturningPromise: function (subjectId){ + + return data.subject.perimeter.get({subject_id: subjectId}).$promise; + + }, + + findSome: function(subjectListId) { + + var _self = this; + + if(subjectListId.length === 0){ + return []; + } + + var promises = _(subjectListId).map( function(subjectId) { + + return _self.findOneReturningPromise(subjectId); + + }); + + return $q.all(promises).then( function(result) { + + return _(result).map( function(resource) { + + return utilService.transformOne(resource, 'subjects'); + + }); + + }); + + }, + + unMapPerimeterFromPolicy: function(policyId, subjectId, callbackSuccess, callbackError ){ + + data.subject.policy.remove({policy_id: policyId, subject_id: subjectId}, {}, callbackSuccess, callbackError); + + }, + + findAllFromPolicyWithCallback: function(policyId, callback){ + + data.subject.policy.get({policy_id: policyId}).$promise.then(function(data) { + + callback(utilService.transform(data, 'subjects')); + + }); + + }, + + findOneFromPolicyWithCallback: function(policyId, subjectId, callback){ + + data.subject.policy.get({policy_id: policyId, subject_id: subjectId}).$promise.then(function(data) { + + callback(utilService.transformOne(data, 'subjects')); + + }); + + }, + + findAll: function(){ + + return data.subject.perimeter.get().$promise.then(function(data) { + + return utilService.transform(data, 'subjects'); + + }); + }, + + findAllWithCallback: function(callback){ + + return data.subject.perimeter.get().$promise.then(function(data) { + + callback(utilService.transform(data, 'subjects')); + + }); + + }, + + delete: function (subject, callbackSuccess, callbackError ) { + + data.subject.perimeter.remove({subject_id: subject.id}, subject, callbackSuccess, callbackError); + + }, + + add: function (subject, callbackSuccess, callbackError ) { + + data.subject.perimeter.create({}, subject, callbackSuccess, callbackError); + + }, + + update: function(subject, callbackSuccess, callbackError){ + + data.subject.perimeter.update({subject_id: subject.id}, subject, callbackSuccess, callbackError); + + } + }, + + object : { + + findOne: function(objectId, callback){ + + data.object.perimeter.get({object_id: objectId}).$promise.then(function(data) { + + callback(utilService.transformOne(data, 'objects')); + + }); + + }, + + findOneReturningPromise: function(objectId){ + + return data.object.perimeter.get({object_id: objectId}).$promise; + + }, + + findSome: function(objectListId) { + + + var _self = this; + + if(objectListId.length === 0){ + return []; + } + + var promises = _(objectListId).map( function(objectId) { + + return _self.findOneReturningPromise(objectId); + + }); + + return $q.all(promises).then( function(result) { + + return _(result).map( function(resource) { + + return utilService.transformOne(resource, 'objects'); + + }); + + }); + + }, + + unMapPerimeterFromPolicy: function(policyId, objectId, callbackSuccess, callbackError ){ + + data.object.policy.remove({policy_id: policyId, object_id: objectId}, {}, callbackSuccess, callbackError); + + }, + + findSomeWithCallback: function(objectListId, callback){ + + var _self = this; + + if(objectListId.length === 0){ + callback([]); + } + + var promises = _(objectListId).map( function(subjectId) { + + return _self.findOneReturningPromise(subjectId); + + }); + + $q.all(promises).then( function(result) { + + callback( _(result).map( function(resource) { + + return utilService.transformOne(resource, 'objects'); + + })); + + }); + + }, + + findAll : function(){ + + return data.object.perimeter.get().$promise.then(function(data) { + + return utilService.transform(data, 'objects'); + + }); + + }, + + findAllFromPolicyWithCallback: function(policyId, callback){ + + data.object.policy.get({policy_id: policyId}).$promise.then(function(data) { + + callback(utilService.transform(data, 'objects')); + + }); + + }, + + findOneFromPolicyWithCallback: function(policyId, objectId, callback){ + + + data.object.policy.get({policy_id: policyId, object_id: objectId}).$promise.then(function(data) { + + callback(utilService.transformOne(data, 'objects')); + + }); + + }, + + findAllWithCallback: function(callback){ + + return data.object.perimeter.get().$promise.then(function(data) { + + callback(utilService.transform(data, 'objects')); + + }); + + }, + + delete: function (object, callbackSuccess, callbackError ) { + + data.object.perimeter.remove({object_id: object.id}, object, callbackSuccess, callbackError); + + }, + + add:function (object, callbackSuccess, callbackError ) { + + data.object.perimeter.create({}, object, callbackSuccess, callbackError); + + }, + + update: function(object, callbackSuccess, callbackError){ + + data.object.perimeter.update({object_id: object.id}, object, callbackSuccess, callbackError); + + } + }, + + action : { + + findOne: function(actionId, callback){ + + data.action.perimeter.get({actionId: actionId}).$promise.then(function(data) { + + callback(utilService.transformOne(data, 'actions')); + + }); + + }, + + findOneReturningPromise: function(actionId){ + + return data.action.perimeter.get({actionId: actionId}).$promise; + + }, + + findSome: function(actionListId) { + + var _self = this; + + if(actionListId.length === 0){ + return []; + } + + var promises = _(actionListId).map( function(actionId) { + + return _self.findOneReturningPromise(actionId); + + }); + + return $q.all(promises).then( function(result) { + + return _(result).map( function(resource) { + + return utilService.transformOne(resource, 'actions'); + + }); + + }); + + }, + + unMapPerimeterFromPolicy: function(policyId, actionId, callbackSuccess, callbackError){ + + data.action.policy.remove({policy_id: policyId, action_id: actionId}, {}, callbackSuccess, callbackError); + + }, + + findSomeWithCallback: function(actionListId, callback){ + + var _self = this; + + if(actionListId.length === 0){ + callback([]); + } + + var promises = _(actionListId).map( function(subjectId) { + + return _self.findOneReturningPromise(subjectId); + + }); + + $q.all(promises).then( function(result) { + + callback( _(result).map( function(resource) { + + return utilService.transformOne(resource, 'actions'); + + })); + + }); + + }, + + findAll : function(){ + + return data.action.perimeter.get().$promise.then(function(data) { + + return utilService.transform(data, 'actions'); + + }); + + }, + + findAllFromPolicyWithCallback: function(policyId, callback){ + + data.action.policy.get({policy_id: policyId}).$promise.then(function(data) { + + callback(utilService.transform(data, 'actions')); + + }); + + }, + + findOneFromPolicyWithCallback: function(policyId, actionId, callback){ + + data.action.policy.get({policy_id: policyId, action_id: actionId}).$promise.then(function(data) { + + callback(utilService.transformOne(data, 'actions')); + + }); + + }, + + findAllWithCallback: function(callback){ + + return data.action.perimeter.get().$promise.then(function(data) { + + callback(utilService.transform(data, 'actions')); + + }); + + }, + + delete: function (action, callbackSuccess, callbackError ) { + + data.action.perimeter.remove({action_id: action.id}, action, callbackSuccess, callbackError); + + }, + + add:function (action, callbackSuccess, callbackError ) { + + data.action.perimeter.create({}, action, callbackSuccess, callbackError); + + }, + + update: function(action, callbackSuccess, callbackError){ + + data.action.perimeter.update({action_id: action.id}, action, callbackSuccess, callbackError); + + } + } + + }; + + } +})();
\ No newline at end of file diff --git a/moon_gui/static/app/services/moon/policy/parameters/rule.service.js b/moon_gui/static/app/services/moon/policy/parameters/rule.service.js new file mode 100644 index 00000000..b1a350ae --- /dev/null +++ b/moon_gui/static/app/services/moon/policy/parameters/rule.service.js @@ -0,0 +1,49 @@ +/** + * @author Samy Abdallah + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .factory('ruleService', ruleService); + + ruleService.$inject = ['$resource', 'REST_URI', 'utilService']; + + function ruleService($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'} + }) + + }, + + findAllFromPolicyWithCallback: function(policyId, callback){ + + this.data.policy.get({policy_id: policyId}).$promise.then(function(data) { + + console.log('ruleService - findAllFromPolicyWithCallback()'); + console.log(data); + + var array = data['rules']; + + console.log(JSON.stringify(array)); + callback(utilService.transform(array, 'rules')); + + }); + + } + + + } + + } +})();
\ No newline at end of file diff --git a/moon_gui/static/app/services/moon/policy/parameters/rules.service.js b/moon_gui/static/app/services/moon/policy/parameters/rules.service.js new file mode 100755 index 00000000..76b24011 --- /dev/null +++ b/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 diff --git a/moon_gui/static/app/services/moon/policy/policy.service.js b/moon_gui/static/app/services/moon/policy/policy.service.js new file mode 100755 index 00000000..5ad31421 --- /dev/null +++ b/moon_gui/static/app/services/moon/policy/policy.service.js @@ -0,0 +1,108 @@ +/** + * Service providing access to the tenants + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .factory('policyService', policyService); + + policyService.$inject = ['$resource', 'REST_URI', 'utilService', '$q']; + + function policyService($resource, REST_URI, utilService, $q) { + + return { + + data: { + + policy: $resource(REST_URI.POLICIES + ':policy_id', {}, { + query: {method: 'GET'}, + create: { method: 'POST' }, + update: { method: 'PATCH' }, + remove: { method: 'DELETE' } + }) + + }, + + findAll: function () { + + return this.data.policy.query().$promise.then(function (data) { + + return utilService.transform(data, 'policies'); + + }); + + }, + + findAllWithCallback: function (callback) { + + return this.data.policy.query().$promise.then(function (data) { + + callback(utilService.transform(data, 'policies')); + + }); + + }, + + findOneReturningPromise: function(policyId){ + + return this.data.policy.get({policy_id: policyId}).$promise; + + }, + + findSomeWithCallback: function(policyListId, callback){ + + var _self = this; + + if(policyListId.length === 0){ + callback([]); + } + + var promises = _(policyListId).map( function(policyId) { + + return _self.findOneReturningPromise(policyId); + + }); + + $q.all(promises).then( function(result) { + + callback( _(result).map( function(resource) { + + return utilService.transformOne(resource, 'policies'); + + })); + + }); + + }, + + findOne: function (policyId) { + + return this.data.policy.get({policy_id: policyId}).$promise.then(function (data) { + + return utilService.transformOne(data, 'policies'); + + }); + + }, + + update: function (policy, callbackSuccess, callbackError) { + + this.data.policy.update({policy_id: policy.id}, policy, callbackSuccess, callbackError); + + }, + + delete: function (policy, callbackSuccess, callbackError ) { + + this.data.policy.remove({policy_id: policy.id}, policy, callbackSuccess, callbackError); + + } + + } + } + +})(); diff --git a/moon_gui/static/app/services/moon/rule/metadata.service.js b/moon_gui/static/app/services/moon/rule/metadata.service.js new file mode 100755 index 00000000..8c68b2ef --- /dev/null +++ b/moon_gui/static/app/services/moon/rule/metadata.service.js @@ -0,0 +1,354 @@ +/** + * @author Samy Abdallah + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .factory('metaDataService', metaDataService); + + metaDataService.$inject = ['$resource', 'REST_URI', '$q', 'utilService']; + + function metaDataService($resource, REST_URI, $q, utilService) { + + var data = { + + subject: $resource(REST_URI.METADATA.subject + ':subject_id', {}, { + get: {method: 'GET', isArray: false}, + create: {method: 'POST'}, + remove: {method: 'DELETE'} + }), + + + object: $resource(REST_URI.METADATA.object + ':object_id', {}, { + get: {method: 'GET', isArray: false}, + create: {method: 'POST'}, + remove: {method: 'DELETE'} + }), + + action: $resource(REST_URI.METADATA.action + ':action_id', {}, { + get: {method: 'GET', isArray: false}, + create: {method: 'POST'}, + remove: {method: 'DELETE'} + }) + + }; + + return { + + subject : { + + findOne: function(subjectId, callback){ + + data.subject.get({subject_id: subjectId}).$promise.then(function(data) { + + callback(utilService.transformOne(data, 'subject_categories')); + + }); + + }, + + findOneReturningPromise: function (subjectId){ + + return data.subject.get({subject_id: subjectId}).$promise; + + }, + + findSome: function(subjectListId) { + + var _self = this; + + if(subjectListId.length === 0){ + return []; + } + + var promises = _(subjectListId).map( function(subjectId) { + + return _self.findOneReturningPromise(subjectId); + + }); + + return $q.all(promises).then( function(result) { + + return _(result).map( function(resource) { + + return utilService.transformOne(resource, 'subject_categories'); + + }); + + }); + + }, + + findSomeWithCallback: function(subjectListId, callback){ + + var _self = this; + + if(subjectListId.length === 0){ + callback([]); + } + + var promises = _(subjectListId).map( function(subjectId) { + + return _self.findOneReturningPromise(subjectId); + + }); + + $q.all(promises).then( function(result) { + + callback( _(result).map( function(resource) { + + return utilService.transformOne(resource, 'subject_categories'); + + })); + + }); + + }, + + findAll: function(){ + + return data.subject.get().$promise.then(function(data) { + + return utilService.transform(data, 'subject_categories'); + + }); + }, + + findAllWithCallback: function(callback){ + + return data.subject.get().$promise.then(function(data) { + + callback(utilService.transform(data, 'subject_categories')); + + }); + + }, + + delete: function (subject, callbackSuccess, callbackError ) { + + data.subject.remove({subject_id: subject.id}, subject, callbackSuccess, callbackError); + + }, + + add: function (subject, callbackSuccess, callbackError ) { + + data.subject.create({}, subject, callbackSuccess, callbackError); + + } + }, + + object : { + + findOne: function(objectId, callback){ + + data.object.get({object_id: objectId}).$promise.then(function(data) { + + callback(utilService.transformOne(data, 'object_categories')); + + }) + + }, + + findOneReturningPromise: function(objectId){ + + return data.object.get({object_id: objectId}).$promise; + + }, + + findSome: function(objectListId) { + + + var _self = this; + + if(objectListId.length === 0){ + return []; + } + + var promises = _(objectListId).map( function(objectId) { + + return _self.findOneReturningPromise(objectId); + + }); + + return $q.all(promises).then( function(result) { + + return _(result).map( function(resource) { + + return utilService.transformOne(resource, 'object_categories'); + + }); + + }); + + }, + + findSomeWithCallback: function(objectListId, callback){ + + var _self = this; + + if(objectListId.length === 0){ + callback([]); + } + + var promises = _(objectListId).map( function(objectId) { + + return _self.findOneReturningPromise(objectId); + + }); + + $q.all(promises).then( function(result) { + + callback( _(result).map( function(resource) { + + return utilService.transformOne(resource, 'object_categories'); + + })); + + }); + + }, + + findAll : function(){ + + return data.object.get().$promise.then(function(data) { + + return utilService.transform(data, 'object_categories'); + + }); + + }, + + findAllWithCallback: function(callback){ + + return data.object.get().$promise.then(function(data) { + + callback(utilService.transform(data, 'object_categories')); + + }); + + }, + + delete: function (object, callbackSuccess, callbackError ) { + + data.object.remove({object_id: object.id}, object, callbackSuccess, callbackError); + + }, + + add:function (object, callbackSuccess, callbackError ) { + + data.object.create({}, object, callbackSuccess, callbackError); + + } + }, + + action : { + + findOne: function(actionId, callback){ + + data.action.get({action_id: actionId}).$promise.then(function(data) { + + callback(utilService.transformOne(data, 'action_categories')); + + }) + + }, + + findOneReturningPromise: function(actionId){ + + return data.action.get({action_id: actionId}).$promise; + + }, + + findSome: function(actionListId) { + + var _self = this; + + if(actionListId.length === 0){ + return []; + } + + var promises = _(actionListId).map( function(actionId) { + + return _self.findOneReturningPromise(actionId); + + }); + + return $q.all(promises).then( function(result) { + + return _(result).map( function(resource) { + + return utilService.transformOne(resource, 'action_categories'); + + }); + + }); + + }, + + findSomeWithCallback: function(actionListId, callback){ + + var _self = this; + + if(actionListId.length === 0){ + callback([]); + } + + var promises = _(actionListId).map( function(actionId) { + + return _self.findOneReturningPromise(actionId); + + }); + + $q.all(promises).then( function(result) { + + callback( _(result).map( function(resource) { + + return utilService.transformOne(resource, 'action_categories'); + + })); + + }); + + }, + + findAll : function(){ + + return data.action.get().$promise.then(function(data) { + + return utilService.transform(data, 'action_categories'); + + }); + + }, + + findAllWithCallback: function(callback){ + + return data.action.get().$promise.then(function(data) { + + callback(utilService.transform(data, 'action_categories')); + + }); + + }, + + delete: function (action, callbackSuccess, callbackError ) { + + data.action.remove({action_id: action.id}, action, callbackSuccess, callbackError); + + }, + + add:function (action, callbackSuccess, callbackError ) { + + data.action.create({}, action, callbackSuccess, callbackError); + + } + } + + }; + + } +})();
\ No newline at end of file diff --git a/moon_gui/static/app/services/moon/rule/metarule.service.js b/moon_gui/static/app/services/moon/rule/metarule.service.js new file mode 100755 index 00000000..2679fc5b --- /dev/null +++ b/moon_gui/static/app/services/moon/rule/metarule.service.js @@ -0,0 +1,208 @@ +/** + * @author Samy Abdallah + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .factory('metaRuleService', metaRuleService); + + metaRuleService.$inject = ['$resource', 'REST_URI', 'metaDataService', '$q', 'utilService']; + + function metaRuleService($resource, REST_URI, metaDataService, $q, utilService) { + + return { + + data: $resource(REST_URI.METARULES + ':metarule_id', {}, { + query: {method: 'GET' }, + get: {method: 'GET', isArray: false}, + update: {method: 'PATCH'}, + create: { method: 'POST' }, + remove: { method: 'DELETE' } + }), + + + findAll: function () { + + return this.data.query().$promise.then(function (data) { + + return utilService.transform(data, 'meta_rules'); + + }); + + }, + + findAllWithCallback : function (callback) { + + this.data.query().$promise.then(function (data) { + + callback(utilService.transform(data, 'meta_rules')); + + }); + + }, + + findSomeWithMetaData : function(metaRuleListId){ + + var _self = this; + + if(metaRuleListId.length === 0){ + return []; + } + + var promises = _(metaRuleListId).map(function(objectId) { + + return _self.findOneReturningPromise(objectId); + + }); + + return $q.all(promises).then(function(result) { + + return _(result).map(function(resource) { + + var metaRule = utilService.transformOne(resource, 'meta_rules'); + + metaRule = _self.findMetaDataFromMetaRule(metaRule); + + return metaRule; + + }); + + }); + + + }, + + findSomeWithCallback : function(metaRuleListId, callback){ + + var _self = this; + + if(metaRuleListId.length === 0){ + return []; + } + + var promises = _(metaRuleListId).map(function(objectId) { + + return _self.findOneReturningPromise(objectId); + + }); + + return $q.all(promises).then(function(result) { + + callback( _(result).map(function(resource) { + + return utilService.transformOne(resource, 'meta_rules'); + + })); + + }); + + + }, + + findOneReturningPromise: function(metaRuleId){ + + return this.data.get({metarule_id: metaRuleId}).$promise; + + }, + + findOne : function(metaRuleId){ + + return this.data.get({metarule_id: metaRuleId}).$promise.then(function(data) { + + return utilService.transformOne(data, 'meta_rules'); + + }); + + }, + + findOneWithCallback: function(metaRuleId, callback){ + + this.data.get({metarule_id: metaRuleId}).$promise.then(function(data) { + + callback(utilService.transformOne(data, 'meta_rules')); + + }); + + }, + + findOneWithMetaData: function(metaRuleId){ + + var _self = this; + + return this.data.get({metarule_id: metaRuleId}).$promise.then(function(data) { + + var metaRule = utilService.transformOne(data, 'meta_rules'); + + metaRule = _self.findMetaDataFromMetaRule(metaRule); + + return metaRule; + + }); + + }, + + findMetaDataFromMetaRule : function (metaRule){ + + if(metaRule.subject_categories.length > 0){ + + metaDataService.subject.findSome(metaRule.subject_categories).then(function(categories){ + metaRule.subject_categories_values = categories; + }); + + }else{ + + metaRule.subject_categories_values = []; + + } + + if(metaRule.object_categories.length > 0){ + + metaDataService.object.findSome(metaRule.object_categories).then(function(categories){ + metaRule.object_categories_values = categories; + }); + + }else{ + + metaRule.object_categories_values = []; + + } + + if(metaRule.action_categories.length > 0){ + + metaDataService.action.findSome(metaRule.action_categories).then(function(categories){ + metaRule.action_categories_values = categories; + }); + + + }else{ + + metaRule.action_categories_values = []; + + } + + return metaRule; + }, + + delete: function (metaRule, callbackSuccess, callbackError ) { + + this.data.remove({metarule_id: metaRule.id}, metaRule, callbackSuccess, callbackError); + + }, + + update: function(metaRule, callbackSuccess, callbackError){ + + delete metaRule.subject_categories_values; + delete metaRule.object_categories_values; + delete metaRule.action_categories_values; + + this.data.update({metarule_id: metaRule.id}, metaRule, callbackSuccess, callbackError); + + } + }; + + } +})();
\ No newline at end of file diff --git a/moon_gui/static/app/services/partner/authentication.service.js b/moon_gui/static/app/services/partner/authentication.service.js new file mode 100755 index 00000000..b6d3f36d --- /dev/null +++ b/moon_gui/static/app/services/partner/authentication.service.js @@ -0,0 +1,106 @@ +/** + * @author Samy Abdallah + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .factory('authenticationService', authenticationService); + + authenticationService.$inject = ['$resource', 'REST_URI', '$sessionStorage', '$http', '$location']; + + function authenticationService($resource, REST_URI, $sessionStorage, $http, $location) { + + return { + data: $resource(REST_URI.KEYSTONE + 'auth/tokens', {}, { + login: { method: 'POST' , + /** + * Transform Response is needed to add headers into the response object + * @param data + * @param headersGetter + * @returns {{}} + */ + transformResponse : function (data, headersGetter) { + var response = {}; + response.data = angular.fromJson(data) ; + response.headers = headersGetter(); + return response; + } + }, + logout: { method: 'DELETE' } + }), + + /** + * + * @param credentials object : {username : '', password : ''} + * @param callbackSuccess + * @param callbackError + * @constructor + */ + Login : function (credentials, callbackSuccess, callbackError){ + var requestData = { + auth:{ + identity:{ + methods:[ + 'password' + ], + password:{ + user:{ + name: credentials.username, + domain:{ + name:'Default' + }, + password: credentials.password + } + } + }, + scope: { + project: { + name:'admin', + domain:{ + name:'Default' + } + } + } + } + }; + this.data.login({}, requestData, function (response){ + $sessionStorage.currentUser = response.data; + $sessionStorage.currentUser.connectionToken = response.headers['x-subject-token']; + SetTokenHeader(response.headers['x-subject-token']); + callbackSuccess(); + }, callbackError); + }, + IsConnected : IsConnected, + SetTokenHeader : SetTokenHeader, + GetTokenHeader : GetTokenHeader, + GetUser : GetUser, + Logout : Logout + }; + + function IsConnected(){ + return _.has($sessionStorage, 'currentUser'); + } + + function Logout(){ + delete $sessionStorage.currentUser; + $http.defaults.headers.common['X-Auth-Token'] = ''; + $location.path('/'); + } + + function GetUser(){ + return $sessionStorage.currentUser; + } + + function GetTokenHeader(){ + return $sessionStorage.currentUser.connectionToken; + } + + function SetTokenHeader(token){ + $http.defaults.headers.common['X-Auth-Token'] = token; + } + } +})();
\ No newline at end of file diff --git a/moon_gui/static/app/services/partner/nova.service.js b/moon_gui/static/app/services/partner/nova.service.js new file mode 100755 index 00000000..38e2a0fc --- /dev/null +++ b/moon_gui/static/app/services/partner/nova.service.js @@ -0,0 +1,35 @@ +/** + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .factory('novaService', novaService); + + novaService.$inject = ['$resource']; + + function novaService($resource) { + + return { + + data: { + + image: $resource('./pip/nova/images', {}, { + query: {method: 'GET', isArray: false} + }), + + flavor: $resource('./pip/nova/flavors', {}, { + query: {method: 'GET', isArray: false} + }) + + } + + }; + + } + +})(); diff --git a/moon_gui/static/app/services/partner/project.service.js b/moon_gui/static/app/services/partner/project.service.js new file mode 100755 index 00000000..4ec27f2e --- /dev/null +++ b/moon_gui/static/app/services/partner/project.service.js @@ -0,0 +1,60 @@ +/** + * Service providing access to the tenants + * @author arnaud marhin<arnaud.marhin@orange.com> + */ + +(function() { + + 'use strict'; + + angular + .module('moon') + .factory('projectService', projectService); + + projectService.$inject = [ '$resource' , 'REST_URI' ]; + + function projectService( $resource, REST_URI) { + + return { + + data: { + + projects: $resource(REST_URI.KEYSTONE + 'projects/:project_id', {}, { + query: {method: 'GET', isArray: false}, + get: { method: 'GET', isArray: false }, + create: { method: 'POST' }, + remove: { method: 'DELETE' } + }) + + }, + + findOne: function(project_id, callback){ + + return this.data.projects.get({project_id: project_id}).$promise.then(function(data) { + + callback(data.project); + + }); + + }, + + findAll: function() { + + return this.data.projects.query().$promise.then(function(listProjects) { + + var result = []; + + _.each(listProjects['projects'], function(item){ + result.push(item); + }); + + return result; + }); + + } + + }; + + } + +})(); |