From 7bb53c64da2dcf88894bfd31503accdd81498f3d Mon Sep 17 00:00:00 2001 From: Thomas Duval Date: Wed, 3 Jun 2020 10:06:52 +0200 Subject: Update to new version 5.4 Signed-off-by: Thomas Duval Change-Id: Idcd868133d75928a1ffd74d749ce98503e0555ea --- old/external_policy_checker/Changelog | 13 + old/external_policy_checker/Dockerfile | 8 + old/external_policy_checker/README.md | 46 + .../conf/templates/cinder.policy.json | 99 + .../conf/templates/glance.policy.json | 61 + .../conf/templates/keystone.policy.json | 250 +++ .../conf/templates/neutron.policy.json | 235 +++ .../conf/templates/nova.policy.json | 488 +++++ .../external_policy_checker/__init__.py | 1 + .../external_policy_checker/__main__.py | 9 + .../external_policy_checker/conf_installer.py | 83 + .../external_policy_checker/server.py | 135 ++ old/external_policy_checker/requirements.txt | 1 + old/external_policy_checker/setup.cfg | 2 + old/external_policy_checker/setup.py | 47 + old/moon_authz/Changelog | 39 + old/moon_authz/Dockerfile | 15 + old/moon_authz/LICENSE | 202 +++ old/moon_authz/MANIFEST.in | 9 + old/moon_authz/README.md | 8 + old/moon_authz/moon_authz/__init__.py | 6 + old/moon_authz/moon_authz/__main__.py | 4 + old/moon_authz/moon_authz/api/__init__.py | 0 old/moon_authz/moon_authz/api/authorization.py | 397 +++++ old/moon_authz/moon_authz/api/update.py | 42 + old/moon_authz/moon_authz/http_server.py | 142 ++ old/moon_authz/moon_authz/server.py | 56 + old/moon_authz/requirements.txt | 5 + old/moon_authz/setup.py | 47 + old/moon_authz/tests/unit_python/conftest.py | 29 + old/moon_authz/tests/unit_python/mock_pods.py | 545 ++++++ old/moon_authz/tests/unit_python/requirements.txt | 5 + old/moon_authz/tests/unit_python/test_authz.py | 116 ++ old/moon_authz/tests/unit_python/utilities.py | 182 ++ old/moon_bouchon/Dockerfile | 8 + old/moon_bouchon/README.md | 42 + old/moon_bouchon/moon_bouchon/__init__.py | 7 + old/moon_bouchon/moon_bouchon/__main__.py | 9 + old/moon_bouchon/moon_bouchon/server.py | 138 ++ old/moon_bouchon/requirements.txt | 1 + old/moon_bouchon/setup.cfg | 2 + old/moon_bouchon/setup.py | 47 + old/moon_bouchon/tests/test_interface.py | 61 + old/moon_bouchon/tests/test_wrapper.py | 38 + old/moon_dashboard/.gitignore | 1 + old/moon_dashboard/.gitlab-ci.yml | 64 + old/moon_dashboard/Dockerfile | 38 + old/moon_dashboard/LICENSE | 0 old/moon_dashboard/MANIFEST.in | 3 + old/moon_dashboard/README.md | 40 + old/moon_dashboard/README.rst | 39 + old/moon_dashboard/babel-django.cfg | 5 + old/moon_dashboard/babel-djangojs.cfg | 14 + old/moon_dashboard/moon/__init__.py | 0 old/moon_dashboard/moon/api/__init__.py | 0 old/moon_dashboard/moon/api/moon_api.py | 0 old/moon_dashboard/moon/dashboard.py | 13 + old/moon_dashboard/moon/enabled/_32000_moon.py | 19 + old/moon_dashboard/moon/model/__init__.py | 0 old/moon_dashboard/moon/model/panel.py | 23 + .../moon/model/templates/model/index.html | 16 + old/moon_dashboard/moon/model/tests.py | 19 + old/moon_dashboard/moon/model/urls.py | 20 + old/moon_dashboard/moon/model/views.py | 22 + old/moon_dashboard/moon/pdp/__init__.py | 0 old/moon_dashboard/moon/pdp/panel.py | 23 + .../moon/pdp/templates/pdp/index.html | 16 + old/moon_dashboard/moon/pdp/tests.py | 19 + old/moon_dashboard/moon/pdp/urls.py | 20 + old/moon_dashboard/moon/pdp/views.py | 22 + old/moon_dashboard/moon/policy/__init__.py | 0 old/moon_dashboard/moon/policy/panel.py | 23 + .../moon/policy/templates/policy/index.html | 16 + old/moon_dashboard/moon/policy/tests.py | 19 + old/moon_dashboard/moon/policy/urls.py | 20 + old/moon_dashboard/moon/policy/views.py | 22 + .../moon/static/moon/js/angular-resource.js | 863 +++++++++ .../moon/static/moon/js/import.service.js | 27 + .../moon/static/moon/js/moon.module.js | 29 + .../moon/static/moon/js/util.service.js | 140 ++ .../moon/static/moon/js/util.service.spec.js | 86 + .../moon/static/moon/model/model.controller.js | 316 ++++ .../moon/static/moon/model/model.html | 139 ++ .../moon/static/moon/model/model.service.js | 291 +++ .../moon/static/moon/model/model.service.spec.js | 288 +++ .../moon/static/moon/pdp/pdp.controller.js | 125 ++ old/moon_dashboard/moon/static/moon/pdp/pdp.html | 41 + .../moon/static/moon/pdp/pdp.service.js | 123 ++ .../moon/static/moon/pdp/pdp.service.spec.js | 143 ++ .../moon/static/moon/policy/policy.controller.js | 341 ++++ .../moon/static/moon/policy/policy.html | 214 +++ .../moon/static/moon/policy/policy.service.js | 428 +++++ .../moon/static/moon/policy/policy.service.spec.js | 487 +++++ old/moon_dashboard/moon/static/moon/scss/moon.scss | 58 + old/moon_dashboard/moon/templates/moon/base.html | 11 + old/moon_dashboard/run.sh | 42 + old/moon_dashboard/setup.cfg | 24 + old/moon_dashboard/setup.py | 14 + old/moon_forming/.gitignore | 105 ++ old/moon_forming/Changelog | 11 + old/moon_forming/Dockerfile | 17 + old/moon_forming/README.md | 47 + old/moon_forming/conf2consul.py | 104 ++ old/moon_forming/config_moon.sh | 39 + old/moon_gui/.gitignore | 4 + old/moon_gui/.jshintrc | 59 + old/moon_gui/DEV.md | 49 + old/moon_gui/Dockerfile | 18 + old/moon_gui/README.md | 71 + old/moon_gui/delivery/assets/css/main.css | 10 + .../assets/fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20335 bytes .../assets/fonts/glyphicons-halflings-regular.svg | 229 +++ .../assets/fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 41280 bytes .../assets/fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23320 bytes old/moon_gui/delivery/assets/i18n/en.json | 1357 ++++++++++++++ old/moon_gui/delivery/assets/i18n/fr.json | 1357 ++++++++++++++ old/moon_gui/delivery/assets/img/ajax-loader.gif | Bin 0 -> 673 bytes old/moon_gui/delivery/assets/img/ajax-waiting.gif | Bin 0 -> 10819 bytes old/moon_gui/delivery/assets/img/arrow-link.gif | Bin 0 -> 87 bytes old/moon_gui/delivery/assets/img/et.jpg | Bin 0 -> 31641 bytes old/moon_gui/delivery/assets/img/favicon.ico | Bin 0 -> 318 bytes .../delivery/assets/img/logo-openstack.png | Bin 0 -> 3180 bytes old/moon_gui/delivery/assets/img/logo-orange.gif | Bin 0 -> 981 bytes .../html/authentication/authentication.tpl.html | 1 + old/moon_gui/delivery/html/common/404/404.tpl.html | 1 + .../common/compatibility/compatibility.tpl.html | 1 + .../delivery/html/common/footer/footer.tpl.html | 1 + .../delivery/html/common/header/header.tpl.html | 1 + .../delivery/html/common/loader/loader.tpl.html | 1 + .../delivery/html/common/waiting/waiting.tpl.html | 1 + .../delivery/html/dashboard/dashboard.tpl.html | 1 + old/moon_gui/delivery/html/logs/logs.tpl.html | 1 + .../delivery/html/model/action/model-add.tpl.html | 1 + .../html/model/action/model-delete.tpl.html | 1 + .../delivery/html/model/action/model-view.tpl.html | 1 + .../model/edit/metadata/metadata-edit.tpl.html | 1 + .../model/edit/metadata/metadata-list.tpl.html | 88 + .../action/mapping/metarules-add.tpl.html | 1 + .../action/mapping/metarules-map.tpl.html | 1 + .../action/mapping/metarules-unmap.tpl.html | 1 + .../metarules/action/metarules-edit-basic.tpl.html | 1 + .../edit/metarules/action/metarules-edit.tpl.html | 1 + .../model/edit/metarules/metarules-list.tpl.html | 1 + .../html/model/edit/model-edit-basic.tpl.html | 1 + .../delivery/html/model/edit/model-edit.tpl.html | 4 + .../delivery/html/model/model-list.tpl.html | 6 + .../delivery/html/pdp/action/pdp-add.tpl.html | 1 + .../delivery/html/pdp/action/pdp-delete.tpl.html | 1 + .../delivery/html/pdp/edit/pdp-edit-basic.tpl.html | 1 + .../delivery/html/pdp/edit/pdp-edit.tpl.html | 1 + old/moon_gui/delivery/html/pdp/pdp-list.tpl.html | 1 + .../html/policy/action/mapping/policy-map.tpl.html | 1 + .../policy/action/mapping/policy-unmap.tpl.html | 1 + .../html/policy/action/policy-add.tpl.html | 1 + .../html/policy/action/policy-delete.tpl.html | 1 + .../assignments/assignments-edit.tpl.html | 1 + .../assignments/assignments-list.tpl.html | 1 + .../policy/edit/parameter/data/data-edit.tpl.html | 1 + .../policy/edit/parameter/data/data-list.tpl.html | 113 ++ .../parameter/perimeter/perimeter-edit.tpl.html | 11 + .../parameter/perimeter/perimeter-list.tpl.html | 1 + .../edit/parameter/rules/rules-edit.tpl.html | 1 + .../edit/parameter/rules/rules-list.tpl.html | 1 + .../html/policy/edit/policy-edit-basic.tpl.html | 1 + .../delivery/html/policy/edit/policy-edit.tpl.html | 13 + .../delivery/html/policy/policy-list.tpl.html | 1 + .../html/policy/policy-mapped-list.tpl.html | 1 + .../project/action/mapping/project-map.tpl.html | 1 + .../project/action/mapping/project-unmap.tpl.html | 1 + .../html/project/action/project-add.tpl.html | 1 + .../html/project/action/project-delete.tpl.html | 1 + .../html/project/action/project-view.tpl.html | 1 + .../delivery/html/project/project-list.tpl.html | 1 + old/moon_gui/delivery/index.html | 34 + old/moon_gui/delivery/js/app.js | 4 + old/moon_gui/delivery/js/modules.js | 20 + old/moon_gui/delivery/version.json | 1 + old/moon_gui/gulpfile.js | 213 +++ old/moon_gui/package.json | 54 + old/moon_gui/run.sh | 17 + .../authentication/authentication.controller.js | 58 + .../app/authentication/authentication.tpl.html | 28 + old/moon_gui/static/app/common/404/404.tpl.html | 3 + .../common/compatibility/compatibility.tpl.html | 26 + .../static/app/common/footer/footer.controller.js | 54 + .../static/app/common/footer/footer.tpl.html | 7 + .../static/app/common/header/header.controller.js | 56 + .../static/app/common/header/header.tpl.html | 52 + .../static/app/common/loader/loader.dir.js | 19 + .../static/app/common/loader/loader.tpl.html | 1 + .../static/app/common/waiting/waiting.tpl.html | 15 + .../static/app/dashboard/dashboard.tpl.html | 14 + old/moon_gui/static/app/logs/logs.controller.js | 16 + old/moon_gui/static/app/logs/logs.tpl.html | 3 + .../static/app/model/action/model-add.tpl.html | 66 + .../static/app/model/action/model-delete.tpl.html | 39 + .../static/app/model/action/model-view.tpl.html | 41 + .../app/model/action/model.controller.add.js | 71 + .../app/model/action/model.controller.delete.js | 72 + .../app/model/action/model.controller.view.js | 53 + .../app/model/edit/metadata/metadata-edit.tpl.html | 99 + .../app/model/edit/metadata/metadata-list.tpl.html | 491 +++++ .../app/model/edit/metadata/metadata.edit.dir.js | 332 ++++ .../app/model/edit/metadata/metadata.list.dir.js | 374 ++++ .../action/mapping/metarules-add.tpl.html | 50 + .../action/mapping/metarules-map.tpl.html | 102 ++ .../action/mapping/metarules-unmap.tpl.html | 35 + .../action/mapping/metarules.controller.add.js | 99 + .../action/mapping/metarules.map.controller.js | 213 +++ .../action/mapping/metarules.unmap.controller.js | 74 + .../metarules/action/metarules-edit-basic.tpl.html | 67 + .../edit/metarules/action/metarules-edit.tpl.html | 62 + .../metarules/action/metarules.controller.edit.js | 49 + .../metarules/action/metarules.edit.basic.dir.js | 100 ++ .../model/edit/metarules/metarules-list.tpl.html | 138 ++ .../app/model/edit/metarules/metarules.list.dir.js | 241 +++ .../app/model/edit/model-edit-basic.tpl.html | 65 + .../static/app/model/edit/model-edit.tpl.html | 70 + .../static/app/model/edit/model.controller.edit.js | 61 + .../static/app/model/edit/model.edit.basic.dir.js | 97 + old/moon_gui/static/app/model/model-list.tpl.html | 123 ++ .../static/app/model/model.controller.list.js | 195 ++ old/moon_gui/static/app/moon.constants.js | 79 + old/moon_gui/static/app/moon.module.js | 362 ++++ .../static/app/pdp/action/pdp-add.tpl.html | 88 + .../static/app/pdp/action/pdp-delete.tpl.html | 35 + .../static/app/pdp/action/pdp.controller.add.js | 108 ++ .../static/app/pdp/action/pdp.controller.delete.js | 66 + .../static/app/pdp/edit/pdp-edit-basic.tpl.html | 65 + old/moon_gui/static/app/pdp/edit/pdp-edit.tpl.html | 64 + .../static/app/pdp/edit/pdp.controller.edit.js | 50 + .../static/app/pdp/edit/pdp.edit.basic.dir.js | 97 + old/moon_gui/static/app/pdp/pdp-list.tpl.html | 133 ++ old/moon_gui/static/app/pdp/pdp.controller.list.js | 284 +++ .../app/policy/action/mapping/policy-map.tpl.html | 64 + .../policy/action/mapping/policy-unmap.tpl.html | 33 + .../policy/action/mapping/policy.controller.map.js | 106 ++ .../action/mapping/policy.controller.unmap.js | 74 + .../static/app/policy/action/policy-add.tpl.html | 113 ++ .../app/policy/action/policy-delete.tpl.html | 40 + .../app/policy/action/policy.controller.add.js | 113 ++ .../app/policy/action/policy.controller.delete.js | 69 + .../assignments/assignments-edit.tpl.html | 165 ++ .../assignments/assignments-list.tpl.html | 335 ++++ .../parameter/assignments/assignments.edit.dir.js | 439 +++++ .../parameter/assignments/assignments.list.dir.js | 393 ++++ .../policy/edit/parameter/data/data-edit.tpl.html | 83 + .../policy/edit/parameter/data/data-list.tpl.html | 390 ++++ .../policy/edit/parameter/data/data.edit.dir.js | 258 +++ .../policy/edit/parameter/data/data.list.dir.js | 293 +++ .../parameter/perimeter/perimeter-edit.tpl.html | 166 ++ .../parameter/perimeter/perimeter-list.tpl.html | 240 +++ .../edit/parameter/perimeter/perimeter.edit.dir.js | 437 +++++ .../edit/parameter/perimeter/perimeter.list.dir.js | 284 +++ .../edit/parameter/rules/rules-edit.tpl.html | 341 ++++ .../edit/parameter/rules/rules-list.tpl.html | 134 ++ .../policy/edit/parameter/rules/rules.edit.dir.js | 537 ++++++ .../policy/edit/parameter/rules/rules.list.dir.js | 302 ++++ .../app/policy/edit/policy-edit-basic.tpl.html | 89 + .../static/app/policy/edit/policy-edit.tpl.html | 202 +++ .../app/policy/edit/policy.controller.edit.js | 88 + .../app/policy/edit/policy.edit.basic.dir.js | 134 ++ .../static/app/policy/policy-list.tpl.html | 131 ++ .../static/app/policy/policy-mapped-list.tpl.html | 88 + .../static/app/policy/policy.controller.list.js | 175 ++ .../static/app/policy/policy.mapped.list.dir.js | 202 +++ .../project/action/mapping/project-map.tpl.html | 62 + .../project/action/mapping/project-unmap.tpl.html | 33 + .../action/mapping/project.controller.map.js | 107 ++ .../action/mapping/project.controller.unmap.js | 74 + .../static/app/project/action/project-add.tpl.html | 89 + .../app/project/action/project-delete.tpl.html | 45 + .../app/project/action/project-view.tpl.html | 194 ++ .../app/project/action/project.controller.add.js | 78 + .../project/action/project.controller.delete.js | 134 ++ .../app/project/action/project.controller.view.js | 216 +++ .../static/app/project/project-list.tpl.html | 157 ++ .../static/app/project/project.controller.list.js | 310 ++++ .../static/app/services/gui/alert.service.js | 39 + .../static/app/services/gui/browser.service.js | 47 + .../static/app/services/gui/form.service.js | 47 + .../static/app/services/gui/menu.service.js | 49 + .../app/services/gui/security.pipeline.service.js | 29 + .../static/app/services/gui/util.service.js | 66 + .../static/app/services/gui/version.service.js | 27 + .../app/services/moon/model/model.service.js | 105 ++ .../static/app/services/moon/pdp.service.js | 128 ++ .../moon/policy/parameters/assignements.service.js | 133 ++ .../moon/policy/parameters/data.service.js | 249 +++ .../moon/policy/parameters/perimeter.service.js | 460 +++++ .../moon/policy/parameters/rule.service.js | 49 + .../moon/policy/parameters/rules.service.js | 56 + .../app/services/moon/policy/policy.service.js | 108 ++ .../app/services/moon/rule/metadata.service.js | 354 ++++ .../app/services/moon/rule/metarule.service.js | 208 +++ .../app/services/partner/authentication.service.js | 106 ++ .../static/app/services/partner/nova.service.js | 35 + .../static/app/services/partner/project.service.js | 60 + old/moon_gui/static/favicon.ico | Bin 0 -> 318 bytes old/moon_gui/static/i18n/en.json | 1357 ++++++++++++++ old/moon_gui/static/i18n/fr.json | 1357 ++++++++++++++ old/moon_gui/static/img/ajax-loader.gif | Bin 0 -> 673 bytes old/moon_gui/static/img/ajax-waiting.gif | Bin 0 -> 10819 bytes old/moon_gui/static/img/arrow-link.gif | Bin 0 -> 87 bytes old/moon_gui/static/img/et.jpg | Bin 0 -> 31641 bytes old/moon_gui/static/img/logo-openstack.png | Bin 0 -> 3180 bytes old/moon_gui/static/img/logo-orange.gif | Bin 0 -> 981 bytes old/moon_gui/static/styles/main.css | 173 ++ old/moon_gui/static/version.json | 3 + old/moon_gui/templates/index.html | 31 + old/moon_interface/Changelog | 36 + old/moon_interface/Dockerfile | 15 + old/moon_interface/LICENSE | 202 +++ old/moon_interface/MANIFEST.in | 9 + old/moon_interface/README.md | 9 + old/moon_interface/moon_interface/__init__.py | 6 + old/moon_interface/moon_interface/__main__.py | 4 + old/moon_interface/moon_interface/api/__init__.py | 0 old/moon_interface/moon_interface/api/authz.py | 162 ++ old/moon_interface/moon_interface/api/generic.py | 96 + old/moon_interface/moon_interface/api/update.py | 49 + .../moon_interface/authz_requests.py | 163 ++ old/moon_interface/moon_interface/http_server.py | 146 ++ old/moon_interface/moon_interface/server.py | 43 + old/moon_interface/requirements.txt | 5 + old/moon_interface/setup.py | 47 + .../tests/unit_python/api/__init__.py | 0 .../tests/unit_python/api/test_authz.py | 83 + old/moon_interface/tests/unit_python/conftest.py | 689 +++++++ .../tests/unit_python/requirements.txt | 5 + old/moon_manager/.gitignore | 104 ++ old/moon_manager/Changelog | 73 + old/moon_manager/Dockerfile | 15 + old/moon_manager/LICENSE | 202 +++ old/moon_manager/MANIFEST.in | 9 + old/moon_manager/README.md | 8 + old/moon_manager/moon_manager/__init__.py | 6 + old/moon_manager/moon_manager/__main__.py | 4 + old/moon_manager/moon_manager/api/__init__.py | 0 old/moon_manager/moon_manager/api/assignments.py | 391 ++++ .../moon_manager/api/base_exception.py | 17 + old/moon_manager/moon_manager/api/data.py | 311 ++++ old/moon_manager/moon_manager/api/generic.py | 144 ++ old/moon_manager/moon_manager/api/json_export.py | 279 +++ old/moon_manager/moon_manager/api/json_import.py | 584 ++++++ old/moon_manager/moon_manager/api/json_utils.py | 282 +++ old/moon_manager/moon_manager/api/meta_data.py | 246 +++ old/moon_manager/moon_manager/api/meta_rules.py | 152 ++ old/moon_manager/moon_manager/api/models.py | 117 ++ old/moon_manager/moon_manager/api/pdp.py | 214 +++ old/moon_manager/moon_manager/api/perimeter.py | 375 ++++ old/moon_manager/moon_manager/api/policies.py | 125 ++ old/moon_manager/moon_manager/api/rules.py | 135 ++ old/moon_manager/moon_manager/api/slaves.py | 111 ++ old/moon_manager/moon_manager/http_server.py | 162 ++ old/moon_manager/moon_manager/server.py | 39 + old/moon_manager/requirements.txt | 5 + old/moon_manager/setup.py | 47 + old/moon_manager/tests/functional_pod/conftest.py | 12 + .../tests/functional_pod/json/mls.json | 89 + .../tests/functional_pod/json/rbac.json | 85 + .../tests/functional_pod/run_functional_tests.sh | 11 + .../tests/functional_pod/test_manager.py | 116 ++ .../tests/functional_pod/test_models.py | 79 + .../unit_python/api/import_export_utilities.py | 202 +++ .../tests/unit_python/api/meta_data_test.py | 238 +++ .../tests/unit_python/api/meta_rules_test.py | 162 ++ .../tests/unit_python/api/test_assignement.py | 280 +++ .../tests/unit_python/api/test_assignemnt.py | 270 +++ .../tests/unit_python/api/test_data.py | 239 +++ .../tests/unit_python/api/test_export.py | 282 +++ .../tests/unit_python/api/test_import.py | 510 ++++++ .../tests/unit_python/api/test_meta_data.py | 305 ++++ .../tests/unit_python/api/test_meta_rules.py | 415 +++++ old/moon_manager/tests/unit_python/api/test_pdp.py | 164 ++ .../tests/unit_python/api/test_perimeter.py | 1028 +++++++++++ .../tests/unit_python/api/test_policies.py | 342 ++++ .../tests/unit_python/api/test_rules.py | 129 ++ .../tests/unit_python/api/test_unit_models.py | 352 ++++ .../tests/unit_python/api/utilities.py | 26 + old/moon_manager/tests/unit_python/conftest.py | 254 +++ .../tests/unit_python/helpers/__init__.py | 0 .../tests/unit_python/helpers/assignment_helper.py | 49 + .../tests/unit_python/helpers/category_helper.py | 40 + .../tests/unit_python/helpers/data_builder.py | 260 +++ .../tests/unit_python/helpers/data_helper.py | 99 + .../tests/unit_python/helpers/meta_rule_helper.py | 49 + .../tests/unit_python/helpers/model_helper.py | 48 + .../tests/unit_python/helpers/pdp_helper.py | 23 + .../tests/unit_python/helpers/policy_helper.py | 63 + .../tests/unit_python/requirements.txt | 5 + old/moon_orchestrator/Changelog | 36 + old/moon_orchestrator/Dockerfile | 15 + old/moon_orchestrator/LICENSE | 202 +++ old/moon_orchestrator/MANIFEST.in | 10 + old/moon_orchestrator/README.md | 4 + .../moon_orchestrator/__init__.py | 6 + .../moon_orchestrator/__main__.py | 4 + .../moon_orchestrator/api/__init__.py | 0 .../moon_orchestrator/api/generic.py | 99 + .../moon_orchestrator/api/pods.py | 174 ++ .../moon_orchestrator/api/slaves.py | 46 + old/moon_orchestrator/moon_orchestrator/drivers.py | 487 +++++ .../moon_orchestrator/http_server.py | 167 ++ old/moon_orchestrator/moon_orchestrator/server.py | 39 + old/moon_orchestrator/requirements.txt | 7 + old/moon_orchestrator/setup.py | 50 + .../tests/unit_python/conftest.py | 18 + .../tests/unit_python/mock_pods.py | 417 +++++ .../tests/unit_python/requirements.txt | 5 + .../tests/unit_python/test_pods.py | 287 +++ .../tests/unit_python/test_slaves.py | 17 + .../tests/unit_python/utilities.py | 171 ++ old/moon_pythonfunctest/Dockerfile | 9 + old/moon_pythonfunctest/README.md | 8 + old/moon_pythonfunctest/run_func_test.sh | 15 + old/moon_pythonunittest/Dockerfile | 8 + old/moon_pythonunittest/README.md | 8 + old/moon_pythonunittest/requirements.txt | 11 + old/moon_pythonunittest/run_tests.sh | 19 + old/moon_wrapper/Changelog | 47 + old/moon_wrapper/Dockerfile | 15 + old/moon_wrapper/LICENSE | 202 +++ old/moon_wrapper/MANIFEST.in | 9 + old/moon_wrapper/README.md | 8 + old/moon_wrapper/moon_wrapper/__init__.py | 6 + old/moon_wrapper/moon_wrapper/__main__.py | 4 + old/moon_wrapper/moon_wrapper/api/__init__.py | 0 old/moon_wrapper/moon_wrapper/api/generic.py | 134 ++ old/moon_wrapper/moon_wrapper/api/oslowrapper.py | 127 ++ old/moon_wrapper/moon_wrapper/api/slaveupdate.py | 87 + old/moon_wrapper/moon_wrapper/http_server.py | 144 ++ old/moon_wrapper/moon_wrapper/server.py | 32 + old/moon_wrapper/requirements.txt | 5 + old/moon_wrapper/setup.py | 47 + old/moon_wrapper/tests/README.md | 35 + old/moon_wrapper/tests/unit_python/api/__init__.py | 0 .../tests/unit_python/api/test_wrapper.py | 72 + old/moon_wrapper/tests/unit_python/conftest.py | 722 ++++++++ .../tests/unit_python/requirements.txt | 5 + old/python_moonclient/.gitignore | 106 ++ old/python_moonclient/Changelog | 78 + old/python_moonclient/LICENSE | 202 +++ old/python_moonclient/MANIFEST.in | 10 + old/python_moonclient/README.md | 33 + .../python_moonclient/__init__.py | 6 + .../python_moonclient/cli/__init__.py | 0 .../python_moonclient/cli/authz.py | 55 + .../python_moonclient/cli/export.py | 32 + .../python_moonclient/cli/import.py | 28 + .../python_moonclient/cli/models.py | 159 ++ .../python_moonclient/cli/parser.py | 98 + .../python_moonclient/cli/pdps.py | 190 ++ .../python_moonclient/cli/policies.py | 264 +++ .../python_moonclient/cli/projects.py | 54 + .../python_moonclient/cli/slaves.py | 120 ++ .../python_moonclient/core/__init__.py | 0 .../python_moonclient/core/authz.py | 180 ++ .../python_moonclient/core/check_tools.py | 458 +++++ .../python_moonclient/core/cli_exceptions.py | 4 + .../python_moonclient/core/config.py | 64 + .../python_moonclient/core/json_export.py | 26 + .../python_moonclient/core/json_import.py | 29 + .../python_moonclient/core/models.py | 279 +++ .../python_moonclient/core/pdp.py | 194 ++ .../python_moonclient/core/policies.py | 673 +++++++ .../python_moonclient/core/slaves.py | 59 + old/python_moonclient/python_moonclient/moon.py | 37 + old/python_moonclient/requirements.txt | 4 + old/python_moonclient/setup.py | 75 + .../tests/unit_python/__init__.py | 0 .../unit_python/conf/conf_action_assignments.py | 51 + .../unit_python/conf/conf_action_categories.py | 32 + .../tests/unit_python/conf/conf_action_data.py | 66 + .../tests/unit_python/conf/conf_actions.py | 111 ++ .../tests/unit_python/conf/conf_all.py | 1 + .../tests/unit_python/conf/conf_meta_rules.py | 44 + .../tests/unit_python/conf/conf_models.py | 94 + .../unit_python/conf/conf_object_assignments.py | 51 + .../unit_python/conf/conf_object_categories.py | 31 + .../tests/unit_python/conf/conf_object_data.py | 67 + .../tests/unit_python/conf/conf_objects.py | 112 ++ .../tests/unit_python/conf/conf_pdps.py | 95 + .../tests/unit_python/conf/conf_policies.py | 78 + .../tests/unit_python/conf/conf_projects.py | 44 + .../tests/unit_python/conf/conf_rules.py | 46 + .../unit_python/conf/conf_subject_assignments.py | 51 + .../unit_python/conf/conf_subject_categories.py | 30 + .../tests/unit_python/conf/conf_subject_data.py | 67 + .../tests/unit_python/conf/conf_subjects.py | 112 ++ .../tests/unit_python/conftest.py | 52 + .../tests/unit_python/mock_config.py | 64 + .../tests/unit_python/requirements.txt | 2 + .../tests/unit_python/test_config.py | 8 + .../tests/unit_python/test_models.py | 38 + .../tests/unit_python/test_pdp.py | 17 + .../tests/unit_python/test_policies.py | 161 ++ .../tests/unit_python/utilities.py | 153 ++ old/python_moondb/.gitignore | 106 ++ old/python_moondb/Changelog | 128 ++ old/python_moondb/LICENSE | 202 +++ old/python_moondb/MANIFEST.in | 10 + old/python_moondb/README.md | 32 + old/python_moondb/bin/drop_tables.sql | 18 + old/python_moondb/python_moondb/__init__.py | 6 + old/python_moondb/python_moondb/api/__init__.py | 0 old/python_moondb/python_moondb/api/keystone.py | 105 ++ old/python_moondb/python_moondb/api/managers.py | 16 + old/python_moondb/python_moondb/api/model.py | 338 ++++ old/python_moondb/python_moondb/api/pdp.py | 51 + old/python_moondb/python_moondb/api/policy.py | 751 ++++++++ .../python_moondb/backends/__init__.py | 96 + old/python_moondb/python_moondb/backends/sql.py | 1884 ++++++++++++++++++++ old/python_moondb/python_moondb/core.py | 228 +++ old/python_moondb/python_moondb/db_manager.py | 82 + .../python_moondb/migrate_repo/__init__.py | 0 .../migrate_repo/versions/001_moon.py | 267 +++ .../migrate_repo/versions/__init__.py | 0 old/python_moondb/requirements.txt | 4 + old/python_moondb/setup.py | 54 + old/python_moondb/tests/unit_python/conftest.py | 145 ++ .../tests/unit_python/helpers/__init__.py | 0 .../tests/unit_python/helpers/assignment_helper.py | 49 + .../tests/unit_python/helpers/category_helper.py | 54 + .../tests/unit_python/helpers/data_helper.py | 98 + .../tests/unit_python/helpers/meta_rule_helper.py | 48 + .../tests/unit_python/helpers/mock_data.py | 156 ++ .../tests/unit_python/helpers/model_helper.py | 47 + .../tests/unit_python/helpers/pdp_helper.py | 23 + .../tests/unit_python/helpers/policy_helper.py | 72 + .../tests/unit_python/mock_components.py | 27 + .../tests/unit_python/mock_keystone.py | 33 + .../tests/unit_python/models/__init__.py | 0 .../tests/unit_python/models/test_categories.py | 111 ++ .../tests/unit_python/models/test_meta_rules.py | 403 +++++ .../tests/unit_python/models/test_models.py | 622 +++++++ .../tests/unit_python/policies/__init__.py | 0 .../tests/unit_python/policies/mock_data.py | 74 + .../tests/unit_python/policies/test_assignments.py | 235 +++ .../tests/unit_python/policies/test_data.py | 707 ++++++++ .../tests/unit_python/policies/test_policies.py | 643 +++++++ .../tests/unit_python/requirements.txt | 4 + .../tests/unit_python/test_keystone.py | 53 + old/python_moondb/tests/unit_python/test_pdp.py | 149 ++ old/python_moondb/tests/unit_python/utilities.py | 136 ++ old/python_moonutilities/.gitignore | 105 ++ old/python_moonutilities/Changelog | 157 ++ old/python_moonutilities/Jenkinsfile | 10 + old/python_moonutilities/LICENSE | 202 +++ old/python_moonutilities/MANIFEST.in | 10 + old/python_moonutilities/README.md | 33 + .../python_moonutilities/__init__.py | 6 + .../python_moonutilities/cache.py | 703 ++++++++ .../python_moonutilities/configuration.py | 124 ++ .../python_moonutilities/context.py | 353 ++++ .../python_moonutilities/exceptions.py | 833 +++++++++ .../python_moonutilities/misc.py | 116 ++ .../python_moonutilities/request_wrapper.py | 22 + .../python_moonutilities/security_functions.py | 331 ++++ old/python_moonutilities/requirements.txt | 3 + old/python_moonutilities/setup.py | 42 + .../tests/unit_python/conftest.py | 14 + .../tests/unit_python/mock_repo/__init__.py | 42 + .../unit_python/mock_repo/components_utilities.py | 136 ++ .../tests/unit_python/mock_repo/data.py | 315 ++++ .../tests/unit_python/mock_repo/urls.py | 150 ++ .../tests/unit_python/requirements.txt | 1 + .../tests/unit_python/test_cache.py | 452 +++++ .../tests/unit_python/test_configuration.py | 166 ++ .../tests/unit_python/test_validated_input.py | 154 ++ old/tests/functional/README.md | 27 + old/tests/functional/run_tests.sh | 18 + old/tests/functional/run_tests_for_component.sh | 27 + .../functional/scenario_available/delegation.py | 40 + old/tests/functional/scenario_available/mls.py | 59 + old/tests/functional/scenario_available/rbac.py | 61 + .../scenario_available/rbac_custom_100.py | 89 + .../scenario_available/rbac_custom_1000.py | 89 + .../scenario_available/rbac_custom_50.py | 89 + .../functional/scenario_available/rbac_large.py | 233 +++ .../functional/scenario_available/rbac_mls.py | 50 + old/tests/functional/scenario_available/session.py | 60 + .../functional/scenario_available/session_large.py | 389 ++++ old/tests/functional/scenario_enabled/mls.py | 1 + old/tests/functional/scenario_enabled/rbac.py | 1 + old/tests/functional/scenario_tests/mls.py | 59 + old/tests/functional/scenario_tests/rbac.py | 61 + old/tests/performance/README.md | 80 + old/tests/python_unit/README.md | 5 + old/tests/python_unit/run_tests.sh | 17 + old/tools/bin/README.md | 8 + old/tools/bin/api2rst.py | 145 ++ old/tools/bin/bootstrap.py | 235 +++ old/tools/bin/build_all.sh | 36 + old/tools/bin/build_all_pip.sh | 16 + old/tools/bin/delete_orchestrator.sh | 61 + old/tools/bin/get_keystone_token.py | 71 + old/tools/bin/moon_lib_upload.sh | 27 + old/tools/bin/set_auth.src | 7 + old/tools/bin/start.sh | 39 + old/tools/moon_jenkins/Dockerfile | 8 + old/tools/moon_jenkins/README.md | 37 + old/tools/moon_jenkins/docker-compose.yml | 20 + .../images/Create Multibranch Pipeline.png | Bin 0 -> 55639 bytes .../images/Git Source Multibranch Pipeline.png | Bin 0 -> 31054 bytes .../images/Multibranch Pipeline Log.png | Bin 0 -> 55231 bytes .../images/Select Source Multibranch Pipeline.png | Bin 0 -> 23375 bytes old/tools/moon_jenkins/plugins.txt | 100 ++ old/tools/moon_jenkins/security.groovy | 20 + old/tools/moon_keystone/Dockerfile | 25 + old/tools/moon_keystone/README.md | 26 + old/tools/moon_keystone/run.sh | 81 + old/tools/moon_kubernetes/README.md | 141 ++ old/tools/moon_kubernetes/conf/moon.conf | 90 + old/tools/moon_kubernetes/conf/password_moon.txt | 1 + old/tools/moon_kubernetes/conf/password_root.txt | 1 + old/tools/moon_kubernetes/init_k8s_moon.sh | 280 +++ old/tools/moon_kubernetes/templates/consul.yaml | 33 + old/tools/moon_kubernetes/templates/db.yaml | 55 + old/tools/moon_kubernetes/templates/keystone.yaml | 39 + old/tools/moon_kubernetes/templates/kube-dns.yaml | 183 ++ .../moon_kubernetes/templates/moon_forming.yaml | 30 + .../moon_kubernetes/templates/moon_functest.yaml | 27 + old/tools/moon_kubernetes/templates/moon_gui.yaml | 42 + .../moon_kubernetes/templates/moon_manager.yaml | 33 + .../templates/moon_orchestrator.yaml | 40 + old/tools/openstack/README.md | 73 + old/tools/openstack/glance/policy.json | 62 + old/tools/openstack/nova/policy.json | 488 +++++ old/tools/policies/generate_opst_policy.py | 167 ++ .../policies/policy.json.d/cinder.policy.json | 104 ++ .../policies/policy.json.d/glance.policy.json | 63 + .../policies/policy.json.d/keystone.policy.json | 260 +++ .../policies/policy.json.d/neutron.policy.json | 235 +++ old/tools/policies/policy.json.d/nova.policy.json | 485 +++++ 635 files changed, 70583 insertions(+) create mode 100644 old/external_policy_checker/Changelog create mode 100644 old/external_policy_checker/Dockerfile create mode 100644 old/external_policy_checker/README.md create mode 100644 old/external_policy_checker/conf/templates/cinder.policy.json create mode 100644 old/external_policy_checker/conf/templates/glance.policy.json create mode 100644 old/external_policy_checker/conf/templates/keystone.policy.json create mode 100644 old/external_policy_checker/conf/templates/neutron.policy.json create mode 100644 old/external_policy_checker/conf/templates/nova.policy.json create mode 100644 old/external_policy_checker/external_policy_checker/__init__.py create mode 100644 old/external_policy_checker/external_policy_checker/__main__.py create mode 100644 old/external_policy_checker/external_policy_checker/conf_installer.py create mode 100644 old/external_policy_checker/external_policy_checker/server.py create mode 100644 old/external_policy_checker/requirements.txt create mode 100644 old/external_policy_checker/setup.cfg create mode 100644 old/external_policy_checker/setup.py create mode 100644 old/moon_authz/Changelog create mode 100644 old/moon_authz/Dockerfile create mode 100644 old/moon_authz/LICENSE create mode 100644 old/moon_authz/MANIFEST.in create mode 100644 old/moon_authz/README.md create mode 100644 old/moon_authz/moon_authz/__init__.py create mode 100644 old/moon_authz/moon_authz/__main__.py create mode 100644 old/moon_authz/moon_authz/api/__init__.py create mode 100644 old/moon_authz/moon_authz/api/authorization.py create mode 100644 old/moon_authz/moon_authz/api/update.py create mode 100644 old/moon_authz/moon_authz/http_server.py create mode 100644 old/moon_authz/moon_authz/server.py create mode 100644 old/moon_authz/requirements.txt create mode 100644 old/moon_authz/setup.py create mode 100644 old/moon_authz/tests/unit_python/conftest.py create mode 100644 old/moon_authz/tests/unit_python/mock_pods.py create mode 100644 old/moon_authz/tests/unit_python/requirements.txt create mode 100644 old/moon_authz/tests/unit_python/test_authz.py create mode 100644 old/moon_authz/tests/unit_python/utilities.py create mode 100644 old/moon_bouchon/Dockerfile create mode 100644 old/moon_bouchon/README.md create mode 100644 old/moon_bouchon/moon_bouchon/__init__.py create mode 100644 old/moon_bouchon/moon_bouchon/__main__.py create mode 100644 old/moon_bouchon/moon_bouchon/server.py create mode 100644 old/moon_bouchon/requirements.txt create mode 100644 old/moon_bouchon/setup.cfg create mode 100644 old/moon_bouchon/setup.py create mode 100644 old/moon_bouchon/tests/test_interface.py create mode 100644 old/moon_bouchon/tests/test_wrapper.py create mode 100644 old/moon_dashboard/.gitignore create mode 100644 old/moon_dashboard/.gitlab-ci.yml create mode 100644 old/moon_dashboard/Dockerfile create mode 100644 old/moon_dashboard/LICENSE create mode 100644 old/moon_dashboard/MANIFEST.in create mode 100644 old/moon_dashboard/README.md create mode 100644 old/moon_dashboard/README.rst create mode 100644 old/moon_dashboard/babel-django.cfg create mode 100644 old/moon_dashboard/babel-djangojs.cfg create mode 100644 old/moon_dashboard/moon/__init__.py create mode 100644 old/moon_dashboard/moon/api/__init__.py create mode 100644 old/moon_dashboard/moon/api/moon_api.py create mode 100644 old/moon_dashboard/moon/dashboard.py create mode 100644 old/moon_dashboard/moon/enabled/_32000_moon.py create mode 100644 old/moon_dashboard/moon/model/__init__.py create mode 100644 old/moon_dashboard/moon/model/panel.py create mode 100644 old/moon_dashboard/moon/model/templates/model/index.html create mode 100644 old/moon_dashboard/moon/model/tests.py create mode 100644 old/moon_dashboard/moon/model/urls.py create mode 100644 old/moon_dashboard/moon/model/views.py create mode 100644 old/moon_dashboard/moon/pdp/__init__.py create mode 100644 old/moon_dashboard/moon/pdp/panel.py create mode 100644 old/moon_dashboard/moon/pdp/templates/pdp/index.html create mode 100644 old/moon_dashboard/moon/pdp/tests.py create mode 100644 old/moon_dashboard/moon/pdp/urls.py create mode 100644 old/moon_dashboard/moon/pdp/views.py create mode 100644 old/moon_dashboard/moon/policy/__init__.py create mode 100644 old/moon_dashboard/moon/policy/panel.py create mode 100644 old/moon_dashboard/moon/policy/templates/policy/index.html create mode 100644 old/moon_dashboard/moon/policy/tests.py create mode 100644 old/moon_dashboard/moon/policy/urls.py create mode 100644 old/moon_dashboard/moon/policy/views.py create mode 100644 old/moon_dashboard/moon/static/moon/js/angular-resource.js create mode 100755 old/moon_dashboard/moon/static/moon/js/import.service.js create mode 100755 old/moon_dashboard/moon/static/moon/js/moon.module.js create mode 100755 old/moon_dashboard/moon/static/moon/js/util.service.js create mode 100755 old/moon_dashboard/moon/static/moon/js/util.service.spec.js create mode 100644 old/moon_dashboard/moon/static/moon/model/model.controller.js create mode 100644 old/moon_dashboard/moon/static/moon/model/model.html create mode 100755 old/moon_dashboard/moon/static/moon/model/model.service.js create mode 100755 old/moon_dashboard/moon/static/moon/model/model.service.spec.js create mode 100644 old/moon_dashboard/moon/static/moon/pdp/pdp.controller.js create mode 100644 old/moon_dashboard/moon/static/moon/pdp/pdp.html create mode 100755 old/moon_dashboard/moon/static/moon/pdp/pdp.service.js create mode 100755 old/moon_dashboard/moon/static/moon/pdp/pdp.service.spec.js create mode 100644 old/moon_dashboard/moon/static/moon/policy/policy.controller.js create mode 100644 old/moon_dashboard/moon/static/moon/policy/policy.html create mode 100755 old/moon_dashboard/moon/static/moon/policy/policy.service.js create mode 100755 old/moon_dashboard/moon/static/moon/policy/policy.service.spec.js create mode 100644 old/moon_dashboard/moon/static/moon/scss/moon.scss create mode 100644 old/moon_dashboard/moon/templates/moon/base.html create mode 100644 old/moon_dashboard/run.sh create mode 100644 old/moon_dashboard/setup.cfg create mode 100644 old/moon_dashboard/setup.py create mode 100644 old/moon_forming/.gitignore create mode 100644 old/moon_forming/Changelog create mode 100644 old/moon_forming/Dockerfile create mode 100644 old/moon_forming/README.md create mode 100644 old/moon_forming/conf2consul.py create mode 100644 old/moon_forming/config_moon.sh create mode 100644 old/moon_gui/.gitignore create mode 100644 old/moon_gui/.jshintrc create mode 100644 old/moon_gui/DEV.md create mode 100644 old/moon_gui/Dockerfile create mode 100644 old/moon_gui/README.md create mode 100644 old/moon_gui/delivery/assets/css/main.css create mode 100644 old/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.eot create mode 100644 old/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.svg create mode 100644 old/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.ttf create mode 100644 old/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.woff create mode 100755 old/moon_gui/delivery/assets/i18n/en.json create mode 100755 old/moon_gui/delivery/assets/i18n/fr.json create mode 100755 old/moon_gui/delivery/assets/img/ajax-loader.gif create mode 100755 old/moon_gui/delivery/assets/img/ajax-waiting.gif create mode 100755 old/moon_gui/delivery/assets/img/arrow-link.gif create mode 100644 old/moon_gui/delivery/assets/img/et.jpg create mode 100755 old/moon_gui/delivery/assets/img/favicon.ico create mode 100755 old/moon_gui/delivery/assets/img/logo-openstack.png create mode 100755 old/moon_gui/delivery/assets/img/logo-orange.gif create mode 100644 old/moon_gui/delivery/html/authentication/authentication.tpl.html create mode 100644 old/moon_gui/delivery/html/common/404/404.tpl.html create mode 100644 old/moon_gui/delivery/html/common/compatibility/compatibility.tpl.html create mode 100644 old/moon_gui/delivery/html/common/footer/footer.tpl.html create mode 100644 old/moon_gui/delivery/html/common/header/header.tpl.html create mode 100644 old/moon_gui/delivery/html/common/loader/loader.tpl.html create mode 100644 old/moon_gui/delivery/html/common/waiting/waiting.tpl.html create mode 100644 old/moon_gui/delivery/html/dashboard/dashboard.tpl.html create mode 100644 old/moon_gui/delivery/html/logs/logs.tpl.html create mode 100644 old/moon_gui/delivery/html/model/action/model-add.tpl.html create mode 100644 old/moon_gui/delivery/html/model/action/model-delete.tpl.html create mode 100644 old/moon_gui/delivery/html/model/action/model-view.tpl.html create mode 100644 old/moon_gui/delivery/html/model/edit/metadata/metadata-edit.tpl.html create mode 100644 old/moon_gui/delivery/html/model/edit/metadata/metadata-list.tpl.html create mode 100644 old/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-add.tpl.html create mode 100644 old/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-map.tpl.html create mode 100644 old/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-unmap.tpl.html create mode 100644 old/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit-basic.tpl.html create mode 100644 old/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit.tpl.html create mode 100644 old/moon_gui/delivery/html/model/edit/metarules/metarules-list.tpl.html create mode 100644 old/moon_gui/delivery/html/model/edit/model-edit-basic.tpl.html create mode 100644 old/moon_gui/delivery/html/model/edit/model-edit.tpl.html create mode 100644 old/moon_gui/delivery/html/model/model-list.tpl.html create mode 100644 old/moon_gui/delivery/html/pdp/action/pdp-add.tpl.html create mode 100644 old/moon_gui/delivery/html/pdp/action/pdp-delete.tpl.html create mode 100644 old/moon_gui/delivery/html/pdp/edit/pdp-edit-basic.tpl.html create mode 100644 old/moon_gui/delivery/html/pdp/edit/pdp-edit.tpl.html create mode 100644 old/moon_gui/delivery/html/pdp/pdp-list.tpl.html create mode 100644 old/moon_gui/delivery/html/policy/action/mapping/policy-map.tpl.html create mode 100644 old/moon_gui/delivery/html/policy/action/mapping/policy-unmap.tpl.html create mode 100644 old/moon_gui/delivery/html/policy/action/policy-add.tpl.html create mode 100644 old/moon_gui/delivery/html/policy/action/policy-delete.tpl.html create mode 100644 old/moon_gui/delivery/html/policy/edit/parameter/assignments/assignments-edit.tpl.html create mode 100644 old/moon_gui/delivery/html/policy/edit/parameter/assignments/assignments-list.tpl.html create mode 100644 old/moon_gui/delivery/html/policy/edit/parameter/data/data-edit.tpl.html create mode 100644 old/moon_gui/delivery/html/policy/edit/parameter/data/data-list.tpl.html create mode 100644 old/moon_gui/delivery/html/policy/edit/parameter/perimeter/perimeter-edit.tpl.html create mode 100644 old/moon_gui/delivery/html/policy/edit/parameter/perimeter/perimeter-list.tpl.html create mode 100644 old/moon_gui/delivery/html/policy/edit/parameter/rules/rules-edit.tpl.html create mode 100644 old/moon_gui/delivery/html/policy/edit/parameter/rules/rules-list.tpl.html create mode 100644 old/moon_gui/delivery/html/policy/edit/policy-edit-basic.tpl.html create mode 100644 old/moon_gui/delivery/html/policy/edit/policy-edit.tpl.html create mode 100644 old/moon_gui/delivery/html/policy/policy-list.tpl.html create mode 100644 old/moon_gui/delivery/html/policy/policy-mapped-list.tpl.html create mode 100644 old/moon_gui/delivery/html/project/action/mapping/project-map.tpl.html create mode 100644 old/moon_gui/delivery/html/project/action/mapping/project-unmap.tpl.html create mode 100644 old/moon_gui/delivery/html/project/action/project-add.tpl.html create mode 100644 old/moon_gui/delivery/html/project/action/project-delete.tpl.html create mode 100644 old/moon_gui/delivery/html/project/action/project-view.tpl.html create mode 100644 old/moon_gui/delivery/html/project/project-list.tpl.html create mode 100644 old/moon_gui/delivery/index.html create mode 100644 old/moon_gui/delivery/js/app.js create mode 100644 old/moon_gui/delivery/js/modules.js create mode 100755 old/moon_gui/delivery/version.json create mode 100644 old/moon_gui/gulpfile.js create mode 100644 old/moon_gui/package.json create mode 100644 old/moon_gui/run.sh create mode 100755 old/moon_gui/static/app/authentication/authentication.controller.js create mode 100755 old/moon_gui/static/app/authentication/authentication.tpl.html create mode 100755 old/moon_gui/static/app/common/404/404.tpl.html create mode 100755 old/moon_gui/static/app/common/compatibility/compatibility.tpl.html create mode 100755 old/moon_gui/static/app/common/footer/footer.controller.js create mode 100755 old/moon_gui/static/app/common/footer/footer.tpl.html create mode 100755 old/moon_gui/static/app/common/header/header.controller.js create mode 100755 old/moon_gui/static/app/common/header/header.tpl.html create mode 100755 old/moon_gui/static/app/common/loader/loader.dir.js create mode 100755 old/moon_gui/static/app/common/loader/loader.tpl.html create mode 100755 old/moon_gui/static/app/common/waiting/waiting.tpl.html create mode 100755 old/moon_gui/static/app/dashboard/dashboard.tpl.html create mode 100755 old/moon_gui/static/app/logs/logs.controller.js create mode 100755 old/moon_gui/static/app/logs/logs.tpl.html create mode 100755 old/moon_gui/static/app/model/action/model-add.tpl.html create mode 100755 old/moon_gui/static/app/model/action/model-delete.tpl.html create mode 100755 old/moon_gui/static/app/model/action/model-view.tpl.html create mode 100755 old/moon_gui/static/app/model/action/model.controller.add.js create mode 100755 old/moon_gui/static/app/model/action/model.controller.delete.js create mode 100755 old/moon_gui/static/app/model/action/model.controller.view.js create mode 100755 old/moon_gui/static/app/model/edit/metadata/metadata-edit.tpl.html create mode 100755 old/moon_gui/static/app/model/edit/metadata/metadata-list.tpl.html create mode 100755 old/moon_gui/static/app/model/edit/metadata/metadata.edit.dir.js create mode 100755 old/moon_gui/static/app/model/edit/metadata/metadata.list.dir.js create mode 100755 old/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-add.tpl.html create mode 100755 old/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-map.tpl.html create mode 100755 old/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-unmap.tpl.html create mode 100755 old/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.controller.add.js create mode 100755 old/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.map.controller.js create mode 100755 old/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.unmap.controller.js create mode 100755 old/moon_gui/static/app/model/edit/metarules/action/metarules-edit-basic.tpl.html create mode 100755 old/moon_gui/static/app/model/edit/metarules/action/metarules-edit.tpl.html create mode 100755 old/moon_gui/static/app/model/edit/metarules/action/metarules.controller.edit.js create mode 100755 old/moon_gui/static/app/model/edit/metarules/action/metarules.edit.basic.dir.js create mode 100755 old/moon_gui/static/app/model/edit/metarules/metarules-list.tpl.html create mode 100755 old/moon_gui/static/app/model/edit/metarules/metarules.list.dir.js create mode 100755 old/moon_gui/static/app/model/edit/model-edit-basic.tpl.html create mode 100755 old/moon_gui/static/app/model/edit/model-edit.tpl.html create mode 100755 old/moon_gui/static/app/model/edit/model.controller.edit.js create mode 100755 old/moon_gui/static/app/model/edit/model.edit.basic.dir.js create mode 100755 old/moon_gui/static/app/model/model-list.tpl.html create mode 100755 old/moon_gui/static/app/model/model.controller.list.js create mode 100644 old/moon_gui/static/app/moon.constants.js create mode 100755 old/moon_gui/static/app/moon.module.js create mode 100755 old/moon_gui/static/app/pdp/action/pdp-add.tpl.html create mode 100755 old/moon_gui/static/app/pdp/action/pdp-delete.tpl.html create mode 100755 old/moon_gui/static/app/pdp/action/pdp.controller.add.js create mode 100755 old/moon_gui/static/app/pdp/action/pdp.controller.delete.js create mode 100755 old/moon_gui/static/app/pdp/edit/pdp-edit-basic.tpl.html create mode 100755 old/moon_gui/static/app/pdp/edit/pdp-edit.tpl.html create mode 100755 old/moon_gui/static/app/pdp/edit/pdp.controller.edit.js create mode 100755 old/moon_gui/static/app/pdp/edit/pdp.edit.basic.dir.js create mode 100755 old/moon_gui/static/app/pdp/pdp-list.tpl.html create mode 100755 old/moon_gui/static/app/pdp/pdp.controller.list.js create mode 100755 old/moon_gui/static/app/policy/action/mapping/policy-map.tpl.html create mode 100755 old/moon_gui/static/app/policy/action/mapping/policy-unmap.tpl.html create mode 100755 old/moon_gui/static/app/policy/action/mapping/policy.controller.map.js create mode 100755 old/moon_gui/static/app/policy/action/mapping/policy.controller.unmap.js create mode 100755 old/moon_gui/static/app/policy/action/policy-add.tpl.html create mode 100755 old/moon_gui/static/app/policy/action/policy-delete.tpl.html create mode 100755 old/moon_gui/static/app/policy/action/policy.controller.add.js create mode 100755 old/moon_gui/static/app/policy/action/policy.controller.delete.js create mode 100755 old/moon_gui/static/app/policy/edit/parameter/assignments/assignments-edit.tpl.html create mode 100755 old/moon_gui/static/app/policy/edit/parameter/assignments/assignments-list.tpl.html create mode 100755 old/moon_gui/static/app/policy/edit/parameter/assignments/assignments.edit.dir.js create mode 100755 old/moon_gui/static/app/policy/edit/parameter/assignments/assignments.list.dir.js create mode 100755 old/moon_gui/static/app/policy/edit/parameter/data/data-edit.tpl.html create mode 100755 old/moon_gui/static/app/policy/edit/parameter/data/data-list.tpl.html create mode 100755 old/moon_gui/static/app/policy/edit/parameter/data/data.edit.dir.js create mode 100755 old/moon_gui/static/app/policy/edit/parameter/data/data.list.dir.js create mode 100755 old/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-edit.tpl.html create mode 100755 old/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-list.tpl.html create mode 100755 old/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.edit.dir.js create mode 100755 old/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.list.dir.js create mode 100755 old/moon_gui/static/app/policy/edit/parameter/rules/rules-edit.tpl.html create mode 100755 old/moon_gui/static/app/policy/edit/parameter/rules/rules-list.tpl.html create mode 100755 old/moon_gui/static/app/policy/edit/parameter/rules/rules.edit.dir.js create mode 100755 old/moon_gui/static/app/policy/edit/parameter/rules/rules.list.dir.js create mode 100755 old/moon_gui/static/app/policy/edit/policy-edit-basic.tpl.html create mode 100755 old/moon_gui/static/app/policy/edit/policy-edit.tpl.html create mode 100755 old/moon_gui/static/app/policy/edit/policy.controller.edit.js create mode 100755 old/moon_gui/static/app/policy/edit/policy.edit.basic.dir.js create mode 100755 old/moon_gui/static/app/policy/policy-list.tpl.html create mode 100755 old/moon_gui/static/app/policy/policy-mapped-list.tpl.html create mode 100755 old/moon_gui/static/app/policy/policy.controller.list.js create mode 100755 old/moon_gui/static/app/policy/policy.mapped.list.dir.js create mode 100755 old/moon_gui/static/app/project/action/mapping/project-map.tpl.html create mode 100755 old/moon_gui/static/app/project/action/mapping/project-unmap.tpl.html create mode 100755 old/moon_gui/static/app/project/action/mapping/project.controller.map.js create mode 100755 old/moon_gui/static/app/project/action/mapping/project.controller.unmap.js create mode 100755 old/moon_gui/static/app/project/action/project-add.tpl.html create mode 100755 old/moon_gui/static/app/project/action/project-delete.tpl.html create mode 100755 old/moon_gui/static/app/project/action/project-view.tpl.html create mode 100755 old/moon_gui/static/app/project/action/project.controller.add.js create mode 100755 old/moon_gui/static/app/project/action/project.controller.delete.js create mode 100755 old/moon_gui/static/app/project/action/project.controller.view.js create mode 100755 old/moon_gui/static/app/project/project-list.tpl.html create mode 100755 old/moon_gui/static/app/project/project.controller.list.js create mode 100755 old/moon_gui/static/app/services/gui/alert.service.js create mode 100755 old/moon_gui/static/app/services/gui/browser.service.js create mode 100755 old/moon_gui/static/app/services/gui/form.service.js create mode 100755 old/moon_gui/static/app/services/gui/menu.service.js create mode 100755 old/moon_gui/static/app/services/gui/security.pipeline.service.js create mode 100755 old/moon_gui/static/app/services/gui/util.service.js create mode 100755 old/moon_gui/static/app/services/gui/version.service.js create mode 100755 old/moon_gui/static/app/services/moon/model/model.service.js create mode 100755 old/moon_gui/static/app/services/moon/pdp.service.js create mode 100755 old/moon_gui/static/app/services/moon/policy/parameters/assignements.service.js create mode 100755 old/moon_gui/static/app/services/moon/policy/parameters/data.service.js create mode 100755 old/moon_gui/static/app/services/moon/policy/parameters/perimeter.service.js create mode 100644 old/moon_gui/static/app/services/moon/policy/parameters/rule.service.js create mode 100755 old/moon_gui/static/app/services/moon/policy/parameters/rules.service.js create mode 100755 old/moon_gui/static/app/services/moon/policy/policy.service.js create mode 100755 old/moon_gui/static/app/services/moon/rule/metadata.service.js create mode 100755 old/moon_gui/static/app/services/moon/rule/metarule.service.js create mode 100755 old/moon_gui/static/app/services/partner/authentication.service.js create mode 100755 old/moon_gui/static/app/services/partner/nova.service.js create mode 100755 old/moon_gui/static/app/services/partner/project.service.js create mode 100755 old/moon_gui/static/favicon.ico create mode 100755 old/moon_gui/static/i18n/en.json create mode 100755 old/moon_gui/static/i18n/fr.json create mode 100755 old/moon_gui/static/img/ajax-loader.gif create mode 100755 old/moon_gui/static/img/ajax-waiting.gif create mode 100755 old/moon_gui/static/img/arrow-link.gif create mode 100644 old/moon_gui/static/img/et.jpg create mode 100755 old/moon_gui/static/img/logo-openstack.png create mode 100755 old/moon_gui/static/img/logo-orange.gif create mode 100644 old/moon_gui/static/styles/main.css create mode 100755 old/moon_gui/static/version.json create mode 100644 old/moon_gui/templates/index.html create mode 100644 old/moon_interface/Changelog create mode 100644 old/moon_interface/Dockerfile create mode 100644 old/moon_interface/LICENSE create mode 100644 old/moon_interface/MANIFEST.in create mode 100644 old/moon_interface/README.md create mode 100644 old/moon_interface/moon_interface/__init__.py create mode 100644 old/moon_interface/moon_interface/__main__.py create mode 100644 old/moon_interface/moon_interface/api/__init__.py create mode 100644 old/moon_interface/moon_interface/api/authz.py create mode 100644 old/moon_interface/moon_interface/api/generic.py create mode 100644 old/moon_interface/moon_interface/api/update.py create mode 100644 old/moon_interface/moon_interface/authz_requests.py create mode 100644 old/moon_interface/moon_interface/http_server.py create mode 100644 old/moon_interface/moon_interface/server.py create mode 100644 old/moon_interface/requirements.txt create mode 100644 old/moon_interface/setup.py create mode 100644 old/moon_interface/tests/unit_python/api/__init__.py create mode 100644 old/moon_interface/tests/unit_python/api/test_authz.py create mode 100644 old/moon_interface/tests/unit_python/conftest.py create mode 100644 old/moon_interface/tests/unit_python/requirements.txt create mode 100644 old/moon_manager/.gitignore create mode 100644 old/moon_manager/Changelog create mode 100644 old/moon_manager/Dockerfile create mode 100644 old/moon_manager/LICENSE create mode 100644 old/moon_manager/MANIFEST.in create mode 100644 old/moon_manager/README.md create mode 100644 old/moon_manager/moon_manager/__init__.py create mode 100644 old/moon_manager/moon_manager/__main__.py create mode 100644 old/moon_manager/moon_manager/api/__init__.py create mode 100644 old/moon_manager/moon_manager/api/assignments.py create mode 100644 old/moon_manager/moon_manager/api/base_exception.py create mode 100644 old/moon_manager/moon_manager/api/data.py create mode 100644 old/moon_manager/moon_manager/api/generic.py create mode 100644 old/moon_manager/moon_manager/api/json_export.py create mode 100644 old/moon_manager/moon_manager/api/json_import.py create mode 100644 old/moon_manager/moon_manager/api/json_utils.py create mode 100644 old/moon_manager/moon_manager/api/meta_data.py create mode 100644 old/moon_manager/moon_manager/api/meta_rules.py create mode 100644 old/moon_manager/moon_manager/api/models.py create mode 100644 old/moon_manager/moon_manager/api/pdp.py create mode 100644 old/moon_manager/moon_manager/api/perimeter.py create mode 100644 old/moon_manager/moon_manager/api/policies.py create mode 100644 old/moon_manager/moon_manager/api/rules.py create mode 100644 old/moon_manager/moon_manager/api/slaves.py create mode 100644 old/moon_manager/moon_manager/http_server.py create mode 100644 old/moon_manager/moon_manager/server.py create mode 100644 old/moon_manager/requirements.txt create mode 100644 old/moon_manager/setup.py create mode 100644 old/moon_manager/tests/functional_pod/conftest.py create mode 100644 old/moon_manager/tests/functional_pod/json/mls.json create mode 100644 old/moon_manager/tests/functional_pod/json/rbac.json create mode 100644 old/moon_manager/tests/functional_pod/run_functional_tests.sh create mode 100644 old/moon_manager/tests/functional_pod/test_manager.py create mode 100644 old/moon_manager/tests/functional_pod/test_models.py create mode 100644 old/moon_manager/tests/unit_python/api/import_export_utilities.py create mode 100644 old/moon_manager/tests/unit_python/api/meta_data_test.py create mode 100644 old/moon_manager/tests/unit_python/api/meta_rules_test.py create mode 100644 old/moon_manager/tests/unit_python/api/test_assignement.py create mode 100644 old/moon_manager/tests/unit_python/api/test_assignemnt.py create mode 100644 old/moon_manager/tests/unit_python/api/test_data.py create mode 100644 old/moon_manager/tests/unit_python/api/test_export.py create mode 100644 old/moon_manager/tests/unit_python/api/test_import.py create mode 100644 old/moon_manager/tests/unit_python/api/test_meta_data.py create mode 100644 old/moon_manager/tests/unit_python/api/test_meta_rules.py create mode 100644 old/moon_manager/tests/unit_python/api/test_pdp.py create mode 100644 old/moon_manager/tests/unit_python/api/test_perimeter.py create mode 100644 old/moon_manager/tests/unit_python/api/test_policies.py create mode 100644 old/moon_manager/tests/unit_python/api/test_rules.py create mode 100644 old/moon_manager/tests/unit_python/api/test_unit_models.py create mode 100644 old/moon_manager/tests/unit_python/api/utilities.py create mode 100644 old/moon_manager/tests/unit_python/conftest.py create mode 100644 old/moon_manager/tests/unit_python/helpers/__init__.py create mode 100644 old/moon_manager/tests/unit_python/helpers/assignment_helper.py create mode 100644 old/moon_manager/tests/unit_python/helpers/category_helper.py create mode 100644 old/moon_manager/tests/unit_python/helpers/data_builder.py create mode 100644 old/moon_manager/tests/unit_python/helpers/data_helper.py create mode 100644 old/moon_manager/tests/unit_python/helpers/meta_rule_helper.py create mode 100644 old/moon_manager/tests/unit_python/helpers/model_helper.py create mode 100644 old/moon_manager/tests/unit_python/helpers/pdp_helper.py create mode 100644 old/moon_manager/tests/unit_python/helpers/policy_helper.py create mode 100644 old/moon_manager/tests/unit_python/requirements.txt create mode 100644 old/moon_orchestrator/Changelog create mode 100644 old/moon_orchestrator/Dockerfile create mode 100644 old/moon_orchestrator/LICENSE create mode 100644 old/moon_orchestrator/MANIFEST.in create mode 100644 old/moon_orchestrator/README.md create mode 100644 old/moon_orchestrator/moon_orchestrator/__init__.py create mode 100644 old/moon_orchestrator/moon_orchestrator/__main__.py create mode 100644 old/moon_orchestrator/moon_orchestrator/api/__init__.py create mode 100644 old/moon_orchestrator/moon_orchestrator/api/generic.py create mode 100644 old/moon_orchestrator/moon_orchestrator/api/pods.py create mode 100644 old/moon_orchestrator/moon_orchestrator/api/slaves.py create mode 100644 old/moon_orchestrator/moon_orchestrator/drivers.py create mode 100644 old/moon_orchestrator/moon_orchestrator/http_server.py create mode 100644 old/moon_orchestrator/moon_orchestrator/server.py create mode 100644 old/moon_orchestrator/requirements.txt create mode 100644 old/moon_orchestrator/setup.py create mode 100644 old/moon_orchestrator/tests/unit_python/conftest.py create mode 100644 old/moon_orchestrator/tests/unit_python/mock_pods.py create mode 100644 old/moon_orchestrator/tests/unit_python/requirements.txt create mode 100644 old/moon_orchestrator/tests/unit_python/test_pods.py create mode 100644 old/moon_orchestrator/tests/unit_python/test_slaves.py create mode 100644 old/moon_orchestrator/tests/unit_python/utilities.py create mode 100644 old/moon_pythonfunctest/Dockerfile create mode 100644 old/moon_pythonfunctest/README.md create mode 100755 old/moon_pythonfunctest/run_func_test.sh create mode 100644 old/moon_pythonunittest/Dockerfile create mode 100644 old/moon_pythonunittest/README.md create mode 100644 old/moon_pythonunittest/requirements.txt create mode 100644 old/moon_pythonunittest/run_tests.sh create mode 100644 old/moon_wrapper/Changelog create mode 100644 old/moon_wrapper/Dockerfile create mode 100644 old/moon_wrapper/LICENSE create mode 100644 old/moon_wrapper/MANIFEST.in create mode 100644 old/moon_wrapper/README.md create mode 100644 old/moon_wrapper/moon_wrapper/__init__.py create mode 100644 old/moon_wrapper/moon_wrapper/__main__.py create mode 100644 old/moon_wrapper/moon_wrapper/api/__init__.py create mode 100644 old/moon_wrapper/moon_wrapper/api/generic.py create mode 100644 old/moon_wrapper/moon_wrapper/api/oslowrapper.py create mode 100644 old/moon_wrapper/moon_wrapper/api/slaveupdate.py create mode 100644 old/moon_wrapper/moon_wrapper/http_server.py create mode 100644 old/moon_wrapper/moon_wrapper/server.py create mode 100644 old/moon_wrapper/requirements.txt create mode 100644 old/moon_wrapper/setup.py create mode 100644 old/moon_wrapper/tests/README.md create mode 100644 old/moon_wrapper/tests/unit_python/api/__init__.py create mode 100644 old/moon_wrapper/tests/unit_python/api/test_wrapper.py create mode 100644 old/moon_wrapper/tests/unit_python/conftest.py create mode 100644 old/moon_wrapper/tests/unit_python/requirements.txt create mode 100644 old/python_moonclient/.gitignore create mode 100644 old/python_moonclient/Changelog create mode 100644 old/python_moonclient/LICENSE create mode 100644 old/python_moonclient/MANIFEST.in create mode 100644 old/python_moonclient/README.md create mode 100644 old/python_moonclient/python_moonclient/__init__.py create mode 100644 old/python_moonclient/python_moonclient/cli/__init__.py create mode 100644 old/python_moonclient/python_moonclient/cli/authz.py create mode 100644 old/python_moonclient/python_moonclient/cli/export.py create mode 100644 old/python_moonclient/python_moonclient/cli/import.py create mode 100644 old/python_moonclient/python_moonclient/cli/models.py create mode 100644 old/python_moonclient/python_moonclient/cli/parser.py create mode 100644 old/python_moonclient/python_moonclient/cli/pdps.py create mode 100644 old/python_moonclient/python_moonclient/cli/policies.py create mode 100644 old/python_moonclient/python_moonclient/cli/projects.py create mode 100644 old/python_moonclient/python_moonclient/cli/slaves.py create mode 100644 old/python_moonclient/python_moonclient/core/__init__.py create mode 100644 old/python_moonclient/python_moonclient/core/authz.py create mode 100644 old/python_moonclient/python_moonclient/core/check_tools.py create mode 100644 old/python_moonclient/python_moonclient/core/cli_exceptions.py create mode 100644 old/python_moonclient/python_moonclient/core/config.py create mode 100644 old/python_moonclient/python_moonclient/core/json_export.py create mode 100644 old/python_moonclient/python_moonclient/core/json_import.py create mode 100644 old/python_moonclient/python_moonclient/core/models.py create mode 100644 old/python_moonclient/python_moonclient/core/pdp.py create mode 100644 old/python_moonclient/python_moonclient/core/policies.py create mode 100644 old/python_moonclient/python_moonclient/core/slaves.py create mode 100644 old/python_moonclient/python_moonclient/moon.py create mode 100644 old/python_moonclient/requirements.txt create mode 100644 old/python_moonclient/setup.py create mode 100644 old/python_moonclient/tests/unit_python/__init__.py create mode 100644 old/python_moonclient/tests/unit_python/conf/conf_action_assignments.py create mode 100644 old/python_moonclient/tests/unit_python/conf/conf_action_categories.py create mode 100644 old/python_moonclient/tests/unit_python/conf/conf_action_data.py create mode 100644 old/python_moonclient/tests/unit_python/conf/conf_actions.py create mode 100644 old/python_moonclient/tests/unit_python/conf/conf_all.py create mode 100644 old/python_moonclient/tests/unit_python/conf/conf_meta_rules.py create mode 100644 old/python_moonclient/tests/unit_python/conf/conf_models.py create mode 100644 old/python_moonclient/tests/unit_python/conf/conf_object_assignments.py create mode 100644 old/python_moonclient/tests/unit_python/conf/conf_object_categories.py create mode 100644 old/python_moonclient/tests/unit_python/conf/conf_object_data.py create mode 100644 old/python_moonclient/tests/unit_python/conf/conf_objects.py create mode 100644 old/python_moonclient/tests/unit_python/conf/conf_pdps.py create mode 100644 old/python_moonclient/tests/unit_python/conf/conf_policies.py create mode 100644 old/python_moonclient/tests/unit_python/conf/conf_projects.py create mode 100644 old/python_moonclient/tests/unit_python/conf/conf_rules.py create mode 100644 old/python_moonclient/tests/unit_python/conf/conf_subject_assignments.py create mode 100644 old/python_moonclient/tests/unit_python/conf/conf_subject_categories.py create mode 100644 old/python_moonclient/tests/unit_python/conf/conf_subject_data.py create mode 100644 old/python_moonclient/tests/unit_python/conf/conf_subjects.py create mode 100644 old/python_moonclient/tests/unit_python/conftest.py create mode 100644 old/python_moonclient/tests/unit_python/mock_config.py create mode 100644 old/python_moonclient/tests/unit_python/requirements.txt create mode 100644 old/python_moonclient/tests/unit_python/test_config.py create mode 100644 old/python_moonclient/tests/unit_python/test_models.py create mode 100644 old/python_moonclient/tests/unit_python/test_pdp.py create mode 100644 old/python_moonclient/tests/unit_python/test_policies.py create mode 100644 old/python_moonclient/tests/unit_python/utilities.py create mode 100644 old/python_moondb/.gitignore create mode 100644 old/python_moondb/Changelog create mode 100644 old/python_moondb/LICENSE create mode 100644 old/python_moondb/MANIFEST.in create mode 100644 old/python_moondb/README.md create mode 100644 old/python_moondb/bin/drop_tables.sql create mode 100644 old/python_moondb/python_moondb/__init__.py create mode 100644 old/python_moondb/python_moondb/api/__init__.py create mode 100644 old/python_moondb/python_moondb/api/keystone.py create mode 100644 old/python_moondb/python_moondb/api/managers.py create mode 100644 old/python_moondb/python_moondb/api/model.py create mode 100644 old/python_moondb/python_moondb/api/pdp.py create mode 100644 old/python_moondb/python_moondb/api/policy.py create mode 100644 old/python_moondb/python_moondb/backends/__init__.py create mode 100644 old/python_moondb/python_moondb/backends/sql.py create mode 100644 old/python_moondb/python_moondb/core.py create mode 100644 old/python_moondb/python_moondb/db_manager.py create mode 100644 old/python_moondb/python_moondb/migrate_repo/__init__.py create mode 100644 old/python_moondb/python_moondb/migrate_repo/versions/001_moon.py create mode 100644 old/python_moondb/python_moondb/migrate_repo/versions/__init__.py create mode 100644 old/python_moondb/requirements.txt create mode 100644 old/python_moondb/setup.py create mode 100644 old/python_moondb/tests/unit_python/conftest.py create mode 100644 old/python_moondb/tests/unit_python/helpers/__init__.py create mode 100644 old/python_moondb/tests/unit_python/helpers/assignment_helper.py create mode 100644 old/python_moondb/tests/unit_python/helpers/category_helper.py create mode 100644 old/python_moondb/tests/unit_python/helpers/data_helper.py create mode 100644 old/python_moondb/tests/unit_python/helpers/meta_rule_helper.py create mode 100644 old/python_moondb/tests/unit_python/helpers/mock_data.py create mode 100644 old/python_moondb/tests/unit_python/helpers/model_helper.py create mode 100644 old/python_moondb/tests/unit_python/helpers/pdp_helper.py create mode 100644 old/python_moondb/tests/unit_python/helpers/policy_helper.py create mode 100644 old/python_moondb/tests/unit_python/mock_components.py create mode 100644 old/python_moondb/tests/unit_python/mock_keystone.py create mode 100755 old/python_moondb/tests/unit_python/models/__init__.py create mode 100644 old/python_moondb/tests/unit_python/models/test_categories.py create mode 100644 old/python_moondb/tests/unit_python/models/test_meta_rules.py create mode 100644 old/python_moondb/tests/unit_python/models/test_models.py create mode 100644 old/python_moondb/tests/unit_python/policies/__init__.py create mode 100644 old/python_moondb/tests/unit_python/policies/mock_data.py create mode 100755 old/python_moondb/tests/unit_python/policies/test_assignments.py create mode 100755 old/python_moondb/tests/unit_python/policies/test_data.py create mode 100755 old/python_moondb/tests/unit_python/policies/test_policies.py create mode 100644 old/python_moondb/tests/unit_python/requirements.txt create mode 100644 old/python_moondb/tests/unit_python/test_keystone.py create mode 100755 old/python_moondb/tests/unit_python/test_pdp.py create mode 100644 old/python_moondb/tests/unit_python/utilities.py create mode 100644 old/python_moonutilities/.gitignore create mode 100644 old/python_moonutilities/Changelog create mode 100644 old/python_moonutilities/Jenkinsfile create mode 100644 old/python_moonutilities/LICENSE create mode 100644 old/python_moonutilities/MANIFEST.in create mode 100644 old/python_moonutilities/README.md create mode 100644 old/python_moonutilities/python_moonutilities/__init__.py create mode 100644 old/python_moonutilities/python_moonutilities/cache.py create mode 100644 old/python_moonutilities/python_moonutilities/configuration.py create mode 100644 old/python_moonutilities/python_moonutilities/context.py create mode 100644 old/python_moonutilities/python_moonutilities/exceptions.py create mode 100644 old/python_moonutilities/python_moonutilities/misc.py create mode 100644 old/python_moonutilities/python_moonutilities/request_wrapper.py create mode 100644 old/python_moonutilities/python_moonutilities/security_functions.py create mode 100644 old/python_moonutilities/requirements.txt create mode 100644 old/python_moonutilities/setup.py create mode 100644 old/python_moonutilities/tests/unit_python/conftest.py create mode 100644 old/python_moonutilities/tests/unit_python/mock_repo/__init__.py create mode 100644 old/python_moonutilities/tests/unit_python/mock_repo/components_utilities.py create mode 100644 old/python_moonutilities/tests/unit_python/mock_repo/data.py create mode 100644 old/python_moonutilities/tests/unit_python/mock_repo/urls.py create mode 100644 old/python_moonutilities/tests/unit_python/requirements.txt create mode 100644 old/python_moonutilities/tests/unit_python/test_cache.py create mode 100644 old/python_moonutilities/tests/unit_python/test_configuration.py create mode 100644 old/python_moonutilities/tests/unit_python/test_validated_input.py create mode 100644 old/tests/functional/README.md create mode 100755 old/tests/functional/run_tests.sh create mode 100644 old/tests/functional/run_tests_for_component.sh create mode 100644 old/tests/functional/scenario_available/delegation.py create mode 100644 old/tests/functional/scenario_available/mls.py create mode 100644 old/tests/functional/scenario_available/rbac.py create mode 100644 old/tests/functional/scenario_available/rbac_custom_100.py create mode 100644 old/tests/functional/scenario_available/rbac_custom_1000.py create mode 100644 old/tests/functional/scenario_available/rbac_custom_50.py create mode 100644 old/tests/functional/scenario_available/rbac_large.py create mode 100644 old/tests/functional/scenario_available/rbac_mls.py create mode 100644 old/tests/functional/scenario_available/session.py create mode 100644 old/tests/functional/scenario_available/session_large.py create mode 120000 old/tests/functional/scenario_enabled/mls.py create mode 120000 old/tests/functional/scenario_enabled/rbac.py create mode 100644 old/tests/functional/scenario_tests/mls.py create mode 100644 old/tests/functional/scenario_tests/rbac.py create mode 100644 old/tests/performance/README.md create mode 100644 old/tests/python_unit/README.md create mode 100644 old/tests/python_unit/run_tests.sh create mode 100644 old/tools/bin/README.md create mode 100644 old/tools/bin/api2rst.py create mode 100644 old/tools/bin/bootstrap.py create mode 100644 old/tools/bin/build_all.sh create mode 100644 old/tools/bin/build_all_pip.sh create mode 100644 old/tools/bin/delete_orchestrator.sh create mode 100644 old/tools/bin/get_keystone_token.py create mode 100644 old/tools/bin/moon_lib_upload.sh create mode 100644 old/tools/bin/set_auth.src create mode 100755 old/tools/bin/start.sh create mode 100644 old/tools/moon_jenkins/Dockerfile create mode 100644 old/tools/moon_jenkins/README.md create mode 100644 old/tools/moon_jenkins/docker-compose.yml create mode 100644 old/tools/moon_jenkins/images/Create Multibranch Pipeline.png create mode 100644 old/tools/moon_jenkins/images/Git Source Multibranch Pipeline.png create mode 100644 old/tools/moon_jenkins/images/Multibranch Pipeline Log.png create mode 100644 old/tools/moon_jenkins/images/Select Source Multibranch Pipeline.png create mode 100644 old/tools/moon_jenkins/plugins.txt create mode 100644 old/tools/moon_jenkins/security.groovy create mode 100644 old/tools/moon_keystone/Dockerfile create mode 100644 old/tools/moon_keystone/README.md create mode 100644 old/tools/moon_keystone/run.sh create mode 100644 old/tools/moon_kubernetes/README.md create mode 100644 old/tools/moon_kubernetes/conf/moon.conf create mode 100644 old/tools/moon_kubernetes/conf/password_moon.txt create mode 100644 old/tools/moon_kubernetes/conf/password_root.txt create mode 100644 old/tools/moon_kubernetes/init_k8s_moon.sh create mode 100644 old/tools/moon_kubernetes/templates/consul.yaml create mode 100644 old/tools/moon_kubernetes/templates/db.yaml create mode 100644 old/tools/moon_kubernetes/templates/keystone.yaml create mode 100644 old/tools/moon_kubernetes/templates/kube-dns.yaml create mode 100644 old/tools/moon_kubernetes/templates/moon_forming.yaml create mode 100644 old/tools/moon_kubernetes/templates/moon_functest.yaml create mode 100644 old/tools/moon_kubernetes/templates/moon_gui.yaml create mode 100644 old/tools/moon_kubernetes/templates/moon_manager.yaml create mode 100644 old/tools/moon_kubernetes/templates/moon_orchestrator.yaml create mode 100644 old/tools/openstack/README.md create mode 100644 old/tools/openstack/glance/policy.json create mode 100644 old/tools/openstack/nova/policy.json create mode 100644 old/tools/policies/generate_opst_policy.py create mode 100644 old/tools/policies/policy.json.d/cinder.policy.json create mode 100644 old/tools/policies/policy.json.d/glance.policy.json create mode 100644 old/tools/policies/policy.json.d/keystone.policy.json create mode 100644 old/tools/policies/policy.json.d/neutron.policy.json create mode 100644 old/tools/policies/policy.json.d/nova.policy.json (limited to 'old') diff --git a/old/external_policy_checker/Changelog b/old/external_policy_checker/Changelog new file mode 100644 index 00000000..cd4ffb7e --- /dev/null +++ b/old/external_policy_checker/Changelog @@ -0,0 +1,13 @@ +# Copyright 2018 Orange +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + + +CHANGES +======= + +1.0.0 +----- +- First version of the external_policy_checker + diff --git a/old/external_policy_checker/Dockerfile b/old/external_policy_checker/Dockerfile new file mode 100644 index 00000000..ed013935 --- /dev/null +++ b/old/external_policy_checker/Dockerfile @@ -0,0 +1,8 @@ +FROM python:3 + +ADD . /root +RUN pip install -r /root/requirements.txt --upgrade +WORKDIR /root +RUN pip install . + +CMD ["python", "-m", "moon_bouchon"] \ No newline at end of file diff --git a/old/external_policy_checker/README.md b/old/external_policy_checker/README.md new file mode 100644 index 00000000..ac44af0e --- /dev/null +++ b/old/external_policy_checker/README.md @@ -0,0 +1,46 @@ +#External Policy Checker + +OpenStack component (like Nova, Glance, Cinder, ...) must populate 3 attributes to allow computing an authorization. +Those 3 attributes are: +- target +- credentials +- rule +In all those attributes, we must find the following information: +- In the 'credentials' attribute: + - the user ID: this is given in general by Keystone + - the project ID: this is given in general by Keystone + - as a proposal, the domain ID: this is given in general by Keystone +- In the 'target' attribute: + - the resource ID (ie nova virtual machine ID, Glance image ID, ...): this must come from the component source of the request (Nova, Glance, …) +- In the 'rule' attribute: + - the action name: this must come from the component source of the request (Nova, Glance, ) + +This server must be used to verify that all information given from OpenStack components can be retrieved in those attributes. + + +## Usage: + +### server + +To start the server locally: + + cd external_policy_checker + python3 server.py + +To start the server as a docker container: + + docker run -ti -p 8080:8080 moon_platform/external_policy_checker:latest + +### API + +Here are the API, you can request: + + POST /policy_checker + POST /authz/grant + POST /authz/deny + +The `/policy_checker` allows to check if all information can be retrieve. +The `/authz/grant` will always send a "True" response. +The `/authz/deny` will always send a "False" response. + + diff --git a/old/external_policy_checker/conf/templates/cinder.policy.json b/old/external_policy_checker/conf/templates/cinder.policy.json new file mode 100644 index 00000000..7716e00b --- /dev/null +++ b/old/external_policy_checker/conf/templates/cinder.policy.json @@ -0,0 +1,99 @@ +{ + + "volume:create": "{{wrapper}}", + "volume:delete": "{{wrapper}}", + "volume:get": "{{wrapper}}", + "volume:get_all": "{{wrapper}}", + "volume:get_volume_metadata": "{{wrapper}}", + "volume:delete_volume_metadata": "{{wrapper}}", + "volume:update_volume_metadata": "{{wrapper}}", + "volume:get_volume_admin_metadata": "{{wrapper}}", + "volume:update_volume_admin_metadata": "{{wrapper}}", + "volume:get_snapshot": "{{wrapper}}", + "volume:get_all_snapshots": "{{wrapper}}", + "volume:create_snapshot": "{{wrapper}}", + "volume:delete_snapshot": "{{wrapper}}", + "volume:update_snapshot": "{{wrapper}}", + "volume:extend": "{{wrapper}}", + "volume:update_readonly_flag": "{{wrapper}}", + "volume:retype": "{{wrapper}}", + "volume:update": "{{wrapper}}", + + "volume_extension:types_manage": "{{wrapper}}", + "volume_extension:types_extra_specs": "{{wrapper}}", + "volume_extension:access_types_qos_specs_id": "{{wrapper}}", + "volume_extension:access_types_extra_specs": "{{wrapper}}", + "volume_extension:volume_type_access": "{{wrapper}}", + "volume_extension:volume_type_access:addProjectAccess": "{{wrapper}}", + "volume_extension:volume_type_access:removeProjectAccess": "{{wrapper}}", + "volume_extension:volume_type_encryption": "{{wrapper}}", + "volume_extension:volume_encryption_metadata": "{{wrapper}}", + "volume_extension:extended_snapshot_attributes": "{{wrapper}}", + "volume_extension:volume_image_metadata": "{{wrapper}}", + + "volume_extension:quotas:show": "{{wrapper}}", + "volume_extension:quotas:update": "{{wrapper}}", + "volume_extension:quotas:delete": "{{wrapper}}", + "volume_extension:quota_classes": "{{wrapper}}", + "volume_extension:quota_classes:validate_setup_for_nested_quota_use": "{{wrapper}}", + + "volume_extension:volume_admin_actions:reset_status": "{{wrapper}}", + "volume_extension:snapshot_admin_actions:reset_status": "{{wrapper}}", + "volume_extension:backup_admin_actions:reset_status": "{{wrapper}}", + "volume_extension:volume_admin_actions:force_delete": "{{wrapper}}", + "volume_extension:volume_admin_actions:force_detach": "{{wrapper}}", + "volume_extension:snapshot_admin_actions:force_delete": "{{wrapper}}", + "volume_extension:backup_admin_actions:force_delete": "{{wrapper}}", + "volume_extension:volume_admin_actions:migrate_volume": "{{wrapper}}", + "volume_extension:volume_admin_actions:migrate_volume_completion": "{{wrapper}}", + + "volume_extension:volume_host_attribute": "{{wrapper}}", + "volume_extension:volume_tenant_attribute": "{{wrapper}}", + "volume_extension:volume_mig_status_attribute": "{{wrapper}}", + "volume_extension:hosts": "{{wrapper}}", + "volume_extension:services:index": "{{wrapper}}", + "volume_extension:services:update" : "{{wrapper}}", + + "volume_extension:volume_manage": "{{wrapper}}", + "volume_extension:volume_unmanage": "{{wrapper}}", + + "volume_extension:capabilities": "{{wrapper}}", + + "volume:create_transfer": "{{wrapper}}", + "volume:accept_transfer": "{{wrapper}}", + "volume:delete_transfer": "{{wrapper}}", + "volume:get_all_transfers": "{{wrapper}}", + + "volume_extension:replication:promote": "{{wrapper}}", + "volume_extension:replication:reenable": "{{wrapper}}", + + "volume:enable_replication": "{{wrapper}}", + "volume:disable_replication": "{{wrapper}}", + "volume:failover_replication": "{{wrapper}}", + "volume:list_replication_targets": "{{wrapper}}", + + "backup:create" : "{{wrapper}}", + "backup:delete": "{{wrapper}}", + "backup:get": "{{wrapper}}", + "backup:get_all": "{{wrapper}}", + "backup:restore": "{{wrapper}}", + "backup:backup-import": "{{wrapper}}", + "backup:backup-export": "{{wrapper}}", + + "snapshot_extension:snapshot_actions:update_snapshot_status": "{{wrapper}}", + "snapshot_extension:snapshot_manage": "{{wrapper}}", + "snapshot_extension:snapshot_unmanage": "{{wrapper}}", + + "consistencygroup:create" : "{{wrapper}}", + "consistencygroup:delete": "{{wrapper}}", + "consistencygroup:update": "{{wrapper}}", + "consistencygroup:get": "{{wrapper}}", + "consistencygroup:get_all": "{{wrapper}}", + + "consistencygroup:create_cgsnapshot" : "{{wrapper}}", + "consistencygroup:delete_cgsnapshot": "{{wrapper}}", + "consistencygroup:get_cgsnapshot": "{{wrapper}}", + "consistencygroup:get_all_cgsnapshots": "{{wrapper}}", + + "scheduler_extension:scheduler_stats:get_pools" : "{{wrapper}}" +} diff --git a/old/external_policy_checker/conf/templates/glance.policy.json b/old/external_policy_checker/conf/templates/glance.policy.json new file mode 100644 index 00000000..ec79d381 --- /dev/null +++ b/old/external_policy_checker/conf/templates/glance.policy.json @@ -0,0 +1,61 @@ +{ + + "add_image": "{{wrapper}}", + "delete_image": "{{wrapper}}", + "get_image": "{{wrapper}}", + "get_images": "{{wrapper}}", + "modify_image": "{{wrapper}}", + "publicize_image": "{{wrapper}}", + "communitize_image": "{{wrapper}}", + "copy_from": "{{wrapper}}", + + "download_image": "{{wrapper}}", + "upload_image": "{{wrapper}}", + + "delete_image_location": "{{wrapper}}", + "get_image_location": "{{wrapper}}", + "set_image_location": "{{wrapper}}", + + "add_member": "{{wrapper}}", + "delete_member": "{{wrapper}}", + "get_member": "{{wrapper}}", + "get_members": "{{wrapper}}", + "modify_member": "{{wrapper}}", + + "manage_image_cache": "{{wrapper}}", + + "get_task": "{{wrapper}}", + "get_tasks": "{{wrapper}}", + "add_task": "{{wrapper}}", + "modify_task": "{{wrapper}}", + "tasks_api_access": "{{wrapper}}", + + "deactivate": "{{wrapper}}", + "reactivate": "{{wrapper}}", + + "get_metadef_namespace": "{{wrapper}}", + "get_metadef_namespaces":"{{wrapper}}", + "modify_metadef_namespace":"{{wrapper}}", + "add_metadef_namespace":"{{wrapper}}", + + "get_metadef_object":"{{wrapper}}", + "get_metadef_objects":"{{wrapper}}", + "modify_metadef_object":"{{wrapper}}", + "add_metadef_object":"{{wrapper}}", + + "list_metadef_resource_types":"{{wrapper}}", + "get_metadef_resource_type":"{{wrapper}}", + "add_metadef_resource_type_association":"{{wrapper}}", + + "get_metadef_property":"{{wrapper}}", + "get_metadef_properties":"{{wrapper}}", + "modify_metadef_property":"{{wrapper}}", + "add_metadef_property":"{{wrapper}}", + + "get_metadef_tag":"{{wrapper}}", + "get_metadef_tags":"{{wrapper}}", + "modify_metadef_tag":"{{wrapper}}", + "add_metadef_tag":"{{wrapper}}", + "add_metadef_tags":"{{wrapper}}" + +} diff --git a/old/external_policy_checker/conf/templates/keystone.policy.json b/old/external_policy_checker/conf/templates/keystone.policy.json new file mode 100644 index 00000000..7fc967d5 --- /dev/null +++ b/old/external_policy_checker/conf/templates/keystone.policy.json @@ -0,0 +1,250 @@ +{ + + "identity:get_region": "{{wrapper}}", + "identity:list_regions": "{{wrapper}}", + "identity:create_region": "{{wrapper}}", + "identity:update_region": "{{wrapper}}", + "identity:delete_region": "{{wrapper}}", + + "identity:get_service": "{{wrapper}}", + "identity:list_services": "{{wrapper}}", + "identity:create_service": "{{wrapper}}", + "identity:update_service": "{{wrapper}}", + "identity:delete_service": "{{wrapper}}", + + "identity:get_endpoint": "{{wrapper}}", + "identity:list_endpoints": "{{wrapper}}", + "identity:create_endpoint": "{{wrapper}}", + "identity:update_endpoint": "{{wrapper}}", + "identity:delete_endpoint": "{{wrapper}}", + + "identity:get_registered_limit": "{{wrapper}}", + "identity:list_registered_limits": "{{wrapper}}", + "identity:create_registered_limits": "{{wrapper}}", + "identity:update_registered_limits": "{{wrapper}}", + "identity:delete_registered_limit": "{{wrapper}}", + + "identity:get_limit": "{{wrapper}}", + "identity:list_limits": "{{wrapper}}", + "identity:create_limits": "{{wrapper}}", + "identity:update_limits": "{{wrapper}}", + "identity:delete_limit": "{{wrapper}}", + + "identity:get_domain": "{{wrapper}}", + "identity:list_domains": "{{wrapper}}", + "identity:create_domain": "{{wrapper}}", + "identity:update_domain": "{{wrapper}}", + "identity:delete_domain": "{{wrapper}}", + + "admin_and_matching_target_project_domain_id": "{{wrapper}}", + "admin_and_matching_project_domain_id": "{{wrapper}}", + "identity:get_project": "{{wrapper}}", + "identity:list_projects": "{{wrapper}}", + "identity:list_user_projects": "{{wrapper}}", + "identity:create_project": "{{wrapper}}", + "identity:update_project": "{{wrapper}}", + "identity:delete_project": "{{wrapper}}", + "identity:create_project_tag": "{{wrapper}}", + "identity:delete_project_tag": "{{wrapper}}", + "identity:get_project_tag": "{{wrapper}}", + "identity:list_project_tags": "{{wrapper}}", + "identity:delete_project_tags": "{{wrapper}}", + "identity:update_project_tags": "{{wrapper}}", + + "admin_and_matching_target_user_domain_id": "{{wrapper}}", + "admin_and_matching_user_domain_id": "{{wrapper}}", + "identity:get_user": "{{wrapper}}", + "identity:list_users": "{{wrapper}}", + "identity:create_user": "{{wrapper}}", + "identity:update_user": "{{wrapper}}", + "identity:delete_user": "{{wrapper}}", + + "admin_and_matching_target_group_domain_id": "{{wrapper}}", + "admin_and_matching_group_domain_id": "{{wrapper}}", + "identity:get_group": "{{wrapper}}", + "identity:list_groups": "{{wrapper}}", + "identity:list_groups_for_user": "{{wrapper}}", + "identity:create_group": "{{wrapper}}", + "identity:update_group": "{{wrapper}}", + "identity:delete_group": "{{wrapper}}", + "identity:list_users_in_group": "{{wrapper}}", + "identity:remove_user_from_group": "{{wrapper}}", + "identity:check_user_in_group": "{{wrapper}}", + "identity:add_user_to_group": "{{wrapper}}", + + "identity:get_credential": "{{wrapper}}", + "identity:list_credentials": "{{wrapper}}", + "identity:create_credential": "{{wrapper}}", + "identity:update_credential": "{{wrapper}}", + "identity:delete_credential": "{{wrapper}}", + + "identity:ec2_get_credential": "{{wrapper}}", + "identity:ec2_list_credentials": "{{wrapper}}", + "identity:ec2_create_credential": "{{wrapper}}", + "identity:ec2_delete_credential": "{{wrapper}}", + + "identity:get_role": "{{wrapper}}", + "identity:list_roles": "{{wrapper}}", + "identity:create_role": "{{wrapper}}", + "identity:update_role": "{{wrapper}}", + "identity:delete_role": "{{wrapper}}", + + "identity:get_domain_role": "{{wrapper}}", + "identity:list_domain_roles": "{{wrapper}}", + "identity:create_domain_role": "{{wrapper}}", + "identity:update_domain_role": "{{wrapper}}", + "identity:delete_domain_role": "{{wrapper}}", + "domain_admin_matches_domain_role": "{{wrapper}}", + "get_domain_roles": "{{wrapper}}", + "domain_admin_matches_target_domain_role": "{{wrapper}}", + "project_admin_matches_target_domain_role": "{{wrapper}}", + "list_domain_roles": "{{wrapper}}", + "domain_admin_matches_filter_on_list_domain_roles": "{{wrapper}}", + "project_admin_matches_filter_on_list_domain_roles": "{{wrapper}}", + "admin_and_matching_prior_role_domain_id": "{{wrapper}}", + "implied_role_matches_prior_role_domain_or_global": "{{wrapper}}", + + "identity:get_implied_role": "{{wrapper}}", + "identity:list_implied_roles": "{{wrapper}}", + "identity:create_implied_role": "{{wrapper}}", + "identity:delete_implied_role": "{{wrapper}}", + "identity:list_role_inference_rules": "{{wrapper}}", + "identity:check_implied_role": "{{wrapper}}", + + "identity:list_system_grants_for_user": "{{wrapper}}", + "identity:check_system_grant_for_user": "{{wrapper}}", + "identity:create_system_grant_for_user": "{{wrapper}}", + "identity:revoke_system_grant_for_user": "{{wrapper}}", + + "identity:list_system_grants_for_group": "{{wrapper}}", + "identity:check_system_grant_for_group": "{{wrapper}}", + "identity:create_system_grant_for_group": "{{wrapper}}", + "identity:revoke_system_grant_for_group": "{{wrapper}}", + + "identity:check_grant": "{{wrapper}}", + "identity:list_grants": "{{wrapper}}", + "identity:create_grant": "{{wrapper}}", + "identity:revoke_grant": "{{wrapper}}", + "domain_admin_for_grants": "{{wrapper}}", + "domain_admin_for_global_role_grants": "{{wrapper}}", + "domain_admin_for_domain_role_grants": "{{wrapper}}", + "domain_admin_grant_match": "{{wrapper}}", + "project_admin_for_grants": "{{wrapper}}", + "project_admin_for_global_role_grants": "{{wrapper}}", + "project_admin_for_domain_role_grants": "{{wrapper}}", + "domain_admin_for_list_grants": "{{wrapper}}", + "project_admin_for_list_grants": "{{wrapper}}", + + "admin_on_domain_filter": "{{wrapper}}", + "admin_on_project_filter": "{{wrapper}}", + "admin_on_domain_of_project_filter": "{{wrapper}}", + "identity:list_role_assignments": "{{wrapper}}", + "identity:list_role_assignments_for_tree": "{{wrapper}}", + "identity:get_policy": "{{wrapper}}", + "identity:list_policies": "{{wrapper}}", + "identity:create_policy": "{{wrapper}}", + "identity:update_policy": "{{wrapper}}", + "identity:delete_policy": "{{wrapper}}", + + "identity:check_token": "{{wrapper}}", + "identity:validate_token": "{{wrapper}}", + "identity:validate_token_head": "{{wrapper}}", + "identity:revocation_list": "{{wrapper}}", + "identity:revoke_token": "{{wrapper}}", + + "identity:create_trust": "{{wrapper}}", + "identity:list_trusts": "{{wrapper}}", + "identity:list_roles_for_trust": "{{wrapper}}", + "identity:get_role_for_trust": "{{wrapper}}", + "identity:delete_trust": "{{wrapper}}", + "identity:get_trust": "{{wrapper}}", + + "identity:create_consumer": "{{wrapper}}", + "identity:get_consumer": "{{wrapper}}", + "identity:list_consumers": "{{wrapper}}", + "identity:delete_consumer": "{{wrapper}}", + "identity:update_consumer": "{{wrapper}}", + + "identity:authorize_request_token": "{{wrapper}}", + "identity:list_access_token_roles": "{{wrapper}}", + "identity:get_access_token_role": "{{wrapper}}", + "identity:list_access_tokens": "{{wrapper}}", + "identity:get_access_token": "{{wrapper}}", + "identity:delete_access_token": "{{wrapper}}", + + "identity:list_projects_for_endpoint": "{{wrapper}}", + "identity:add_endpoint_to_project": "{{wrapper}}", + "identity:check_endpoint_in_project": "{{wrapper}}", + "identity:list_endpoints_for_project": "{{wrapper}}", + "identity:remove_endpoint_from_project": "{{wrapper}}", + + "identity:create_endpoint_group": "{{wrapper}}", + "identity:list_endpoint_groups": "{{wrapper}}", + "identity:get_endpoint_group": "{{wrapper}}", + "identity:update_endpoint_group": "{{wrapper}}", + "identity:delete_endpoint_group": "{{wrapper}}", + "identity:list_projects_associated_with_endpoint_group": "{{wrapper}}", + "identity:list_endpoints_associated_with_endpoint_group": "{{wrapper}}", + "identity:get_endpoint_group_in_project": "{{wrapper}}", + "identity:list_endpoint_groups_for_project": "{{wrapper}}", + "identity:add_endpoint_group_to_project": "{{wrapper}}", + "identity:remove_endpoint_group_from_project": "{{wrapper}}", + + "identity:create_identity_provider": "{{wrapper}}", + "identity:list_identity_providers": "{{wrapper}}", + "identity:get_identity_provider": "{{wrapper}}", + "identity:update_identity_provider": "{{wrapper}}", + "identity:delete_identity_provider": "{{wrapper}}", + + "identity:create_protocol": "{{wrapper}}", + "identity:update_protocol": "{{wrapper}}", + "identity:get_protocol": "{{wrapper}}", + "identity:list_protocols": "{{wrapper}}", + "identity:delete_protocol": "{{wrapper}}", + + "identity:create_mapping": "{{wrapper}}", + "identity:get_mapping": "{{wrapper}}", + "identity:list_mappings": "{{wrapper}}", + "identity:delete_mapping": "{{wrapper}}", + "identity:update_mapping": "{{wrapper}}", + + "identity:create_service_provider": "{{wrapper}}", + "identity:list_service_providers": "{{wrapper}}", + "identity:get_service_provider": "{{wrapper}}", + "identity:update_service_provider": "{{wrapper}}", + "identity:delete_service_provider": "{{wrapper}}", + + "identity:get_auth_catalog": "{{wrapper}}", + "identity:get_auth_projects": "{{wrapper}}", + "identity:get_auth_domains": "{{wrapper}}", + "identity:get_auth_system": "{{wrapper}}", + + "identity:list_projects_for_user": "{{wrapper}}", + "identity:list_domains_for_user": "{{wrapper}}", + + "identity:list_revoke_events": "{{wrapper}}", + + "identity:create_policy_association_for_endpoint": "{{wrapper}}", + "identity:check_policy_association_for_endpoint": "{{wrapper}}", + "identity:delete_policy_association_for_endpoint": "{{wrapper}}", + "identity:create_policy_association_for_service": "{{wrapper}}", + "identity:check_policy_association_for_service": "{{wrapper}}", + "identity:delete_policy_association_for_service": "{{wrapper}}", + "identity:create_policy_association_for_region_and_service": "{{wrapper}}", + "identity:check_policy_association_for_region_and_service": "{{wrapper}}", + "identity:delete_policy_association_for_region_and_service": "{{wrapper}}", + "identity:get_policy_for_endpoint": "{{wrapper}}", + "identity:list_endpoints_for_policy": "{{wrapper}}", + + "identity:create_domain_config": "{{wrapper}}", + "identity:get_domain_config": "{{wrapper}}", + "identity:get_security_compliance_domain_config": "{{wrapper}}", + "identity:update_domain_config": "{{wrapper}}", + "identity:delete_domain_config": "{{wrapper}}", + "identity:get_domain_config_default": "{{wrapper}}", + + "identity:get_application_credential": "{{wrapper}}", + "identity:list_application_credentials": "{{wrapper}}", + "identity:create_application_credential": "{{wrapper}}", + "identity:delete_application_credential": "{{wrapper}}", +} diff --git a/old/external_policy_checker/conf/templates/neutron.policy.json b/old/external_policy_checker/conf/templates/neutron.policy.json new file mode 100644 index 00000000..d0ab0b63 --- /dev/null +++ b/old/external_policy_checker/conf/templates/neutron.policy.json @@ -0,0 +1,235 @@ +{ + "context_is_admin": "role:admin or user_name:neutron", + "owner": "{{wrapper}}", + "admin_or_owner": "{{wrapper}}", + "context_is_advsvc": "role:advsvc", + "admin_or_network_owner": "{{wrapper}}", + "admin_owner_or_network_owner": "{{wrapper}}", + "admin_only": "{{wrapper}}", + "regular_user": "{{wrapper}}", + "admin_or_data_plane_int": "{{wrapper}}", + "shared": "{{wrapper}}", + "shared_subnetpools": "{{wrapper}}", + "shared_address_scopes": "{{wrapper}}", + "external": "{{wrapper}}", + "default": "{{wrapper}}", + + "create_subnet": "{{wrapper}}", + "create_subnet:segment_id": "{{wrapper}}", + "create_subnet:service_types": "{{wrapper}}", + "get_subnet": "{{wrapper}}", + "get_subnet:segment_id": "{{wrapper}}", + "update_subnet": "{{wrapper}}", + "update_subnet:service_types": "{{wrapper}}", + "delete_subnet": "{{wrapper}}", + + "create_subnetpool": "{{wrapper}}", + "create_subnetpool:shared": "{{wrapper}}", + "create_subnetpool:is_default": "{{wrapper}}", + "get_subnetpool": "{{wrapper}}", + "update_subnetpool": "{{wrapper}}", + "update_subnetpool:is_default": "{{wrapper}}", + "delete_subnetpool": "{{wrapper}}", + + "create_address_scope": "{{wrapper}}", + "create_address_scope:shared": "{{wrapper}}", + "get_address_scope": "{{wrapper}}", + "update_address_scope": "{{wrapper}}", + "update_address_scope:shared": "{{wrapper}}", + "delete_address_scope": "{{wrapper}}", + + "create_network": "{{wrapper}}", + "get_network": "{{wrapper}}", + "get_network:router:external": "{{wrapper}}", + "get_network:segments": "{{wrapper}}", + "get_network:provider:network_type": "{{wrapper}}", + "get_network:provider:physical_network": "{{wrapper}}", + "get_network:provider:segmentation_id": "{{wrapper}}", + "get_network:queue_id": "{{wrapper}}", + "get_network_ip_availabilities": "{{wrapper}}", + "get_network_ip_availability": "{{wrapper}}", + "create_network:shared": "{{wrapper}}", + "create_network:router:external": "{{wrapper}}", + "create_network:is_default": "{{wrapper}}", + "create_network:segments": "{{wrapper}}", + "create_network:provider:network_type": "{{wrapper}}", + "create_network:provider:physical_network": "{{wrapper}}", + "create_network:provider:segmentation_id": "{{wrapper}}", + "update_network": "{{wrapper}}", + "update_network:segments": "{{wrapper}}", + "update_network:shared": "{{wrapper}}", + "update_network:provider:network_type": "{{wrapper}}", + "update_network:provider:physical_network": "{{wrapper}}", + "update_network:provider:segmentation_id": "{{wrapper}}", + "update_network:router:external": "{{wrapper}}", + "delete_network": "{{wrapper}}", + + "create_segment": "{{wrapper}}", + "get_segment": "{{wrapper}}", + "update_segment": "{{wrapper}}", + "delete_segment": "{{wrapper}}", + + "network_device": "{{wrapper}}", + "create_port": "{{wrapper}}", + "create_port:device_owner": "{{wrapper}}", + "create_port:mac_address": "{{wrapper}}", + "create_port:fixed_ips:ip_address": "{{wrapper}}", + "create_port:fixed_ips:subnet_id": "{{wrapper}}", + "create_port:port_security_enabled": "{{wrapper}}", + "create_port:binding:host_id": "{{wrapper}}", + "create_port:binding:profile": "{{wrapper}}", + "create_port:mac_learning_enabled": "{{wrapper}}", + "create_port:allowed_address_pairs": "{{wrapper}}", + "get_port": "{{wrapper}}", + "get_port:queue_id": "{{wrapper}}", + "get_port:binding:vif_type": "{{wrapper}}", + "get_port:binding:vif_details": "{{wrapper}}", + "get_port:binding:host_id": "{{wrapper}}", + "get_port:binding:profile": "{{wrapper}}", + "update_port": "{{wrapper}}", + "update_port:device_owner": "{{wrapper}}", + "update_port:mac_address": "{{wrapper}}", + "update_port:fixed_ips:ip_address": "{{wrapper}}", + "update_port:fixed_ips:subnet_id": "{{wrapper}}", + "update_port:port_security_enabled": "{{wrapper}}", + "update_port:binding:host_id": "{{wrapper}}", + "update_port:binding:profile": "{{wrapper}}", + "update_port:mac_learning_enabled": "{{wrapper}}", + "update_port:allowed_address_pairs": "{{wrapper}}", + "update_port:data_plane_status": "{{wrapper}}", + "delete_port": "{{wrapper}}", + + "get_router:ha": "{{wrapper}}", + "create_router": "{{wrapper}}", + "create_router:external_gateway_info:enable_snat": "{{wrapper}}", + "create_router:distributed": "{{wrapper}}", + "create_router:ha": "{{wrapper}}", + "get_router": "{{wrapper}}", + "get_router:distributed": "{{wrapper}}", + "update_router": "{{wrapper}}", + "update_router:external_gateway_info": "{{wrapper}}", + "update_router:external_gateway_info:network_id": "{{wrapper}}", + "update_router:external_gateway_info:enable_snat": "{{wrapper}}", + "update_router:distributed": "{{wrapper}}", + "update_router:ha": "{{wrapper}}", + "delete_router": "{{wrapper}}", + + "add_router_interface": "{{wrapper}}", + "remove_router_interface": "{{wrapper}}", + + "create_router:external_gateway_info:external_fixed_ips": "{{wrapper}}", + "update_router:external_gateway_info:external_fixed_ips": "{{wrapper}}", + + "create_qos_queue": "{{wrapper}}", + "get_qos_queue": "{{wrapper}}", + + "update_agent": "{{wrapper}}", + "delete_agent": "{{wrapper}}", + "get_agent": "{{wrapper}}", + + "create_dhcp-network": "{{wrapper}}", + "delete_dhcp-network": "{{wrapper}}", + "get_dhcp-networks": "{{wrapper}}", + "create_l3-router": "{{wrapper}}", + "delete_l3-router": "{{wrapper}}", + "get_l3-routers": "{{wrapper}}", + "get_dhcp-agents": "{{wrapper}}", + "get_l3-agents": "{{wrapper}}", + "get_loadbalancer-agent": "{{wrapper}}", + "get_loadbalancer-pools": "{{wrapper}}", + "get_agent-loadbalancers": "{{wrapper}}", + "get_loadbalancer-hosting-agent": "{{wrapper}}", + + "create_floatingip": "{{wrapper}}", + "create_floatingip:floating_ip_address": "{{wrapper}}", + "update_floatingip": "{{wrapper}}", + "delete_floatingip": "{{wrapper}}", + "get_floatingip": "{{wrapper}}", + + "create_network_profile": "{{wrapper}}", + "update_network_profile": "{{wrapper}}", + "delete_network_profile": "{{wrapper}}", + "get_network_profiles": "{{wrapper}}", + "get_network_profile": "{{wrapper}}", + "update_policy_profiles": "{{wrapper}}", + "get_policy_profiles": "{{wrapper}}", + "get_policy_profile": "{{wrapper}}", + + "create_metering_label": "{{wrapper}}", + "delete_metering_label": "{{wrapper}}", + "get_metering_label": "{{wrapper}}", + + "create_metering_label_rule": "{{wrapper}}", + "delete_metering_label_rule": "{{wrapper}}", + "get_metering_label_rule": "{{wrapper}}", + + "get_service_provider": "{{wrapper}}", + "get_lsn": "{{wrapper}}", + "create_lsn": "{{wrapper}}", + + "create_flavor": "{{wrapper}}", + "update_flavor": "{{wrapper}}", + "delete_flavor": "{{wrapper}}", + "get_flavors": "{{wrapper}}", + "get_flavor": "{{wrapper}}", + "create_service_profile": "{{wrapper}}", + "update_service_profile": "{{wrapper}}", + "delete_service_profile": "{{wrapper}}", + "get_service_profiles": "{{wrapper}}", + "get_service_profile": "{{wrapper}}", + + "get_policy": "{{wrapper}}", + "create_policy": "{{wrapper}}", + "update_policy": "{{wrapper}}", + "delete_policy": "{{wrapper}}", + "get_policy_bandwidth_limit_rule": "{{wrapper}}", + "create_policy_bandwidth_limit_rule": "{{wrapper}}", + "delete_policy_bandwidth_limit_rule": "{{wrapper}}", + "update_policy_bandwidth_limit_rule": "{{wrapper}}", + "get_policy_dscp_marking_rule": "{{wrapper}}", + "create_policy_dscp_marking_rule": "{{wrapper}}", + "delete_policy_dscp_marking_rule": "{{wrapper}}", + "update_policy_dscp_marking_rule": "{{wrapper}}", + "get_rule_type": "{{wrapper}}", + "get_policy_minimum_bandwidth_rule": "{{wrapper}}", + "create_policy_minimum_bandwidth_rule": "{{wrapper}}", + "delete_policy_minimum_bandwidth_rule": "{{wrapper}}", + "update_policy_minimum_bandwidth_rule": "{{wrapper}}", + + "restrict_wildcard": "{{wrapper}}", + "create_rbac_policy": "{{wrapper}}", + "create_rbac_policy:target_tenant": "{{wrapper}}", + "update_rbac_policy": "{{wrapper}}", + "update_rbac_policy:target_tenant": "{{wrapper}}", + "get_rbac_policy": "{{wrapper}}", + "delete_rbac_policy": "{{wrapper}}", + + "create_flavor_service_profile": "{{wrapper}}", + "delete_flavor_service_profile": "{{wrapper}}", + "get_flavor_service_profile": "{{wrapper}}", + "get_auto_allocated_topology": "{{wrapper}}", + + "create_trunk": "{{wrapper}}", + "get_trunk": "{{wrapper}}", + "delete_trunk": "{{wrapper}}", + "get_subports": "{{wrapper}}", + "add_subports": "{{wrapper}}", + "remove_subports": "{{wrapper}}", + + "get_security_groups": "{{wrapper}}", + "get_security_group": "{{wrapper}}", + "create_security_group": "{{wrapper}}", + "update_security_group": "{{wrapper}}", + "delete_security_group": "{{wrapper}}", + "get_security_group_rules": "{{wrapper}}", + "get_security_group_rule": "{{wrapper}}", + "create_security_group_rule": "{{wrapper}}", + "delete_security_group_rule": "{{wrapper}}", + + "get_loggable_resources": "{{wrapper}}", + "create_log": "{{wrapper}}", + "update_log": "{{wrapper}}", + "delete_log": "{{wrapper}}", + "get_logs": "{{wrapper}}", + "get_log": "{{wrapper}}", +} diff --git a/old/external_policy_checker/conf/templates/nova.policy.json b/old/external_policy_checker/conf/templates/nova.policy.json new file mode 100644 index 00000000..e5de675f --- /dev/null +++ b/old/external_policy_checker/conf/templates/nova.policy.json @@ -0,0 +1,488 @@ +{ + "context_is_admin": "role:admin", + "admin_or_owner": "is_admin:True or project_id:%(project_id)s", + "default": "{{wrapper}}", + + "cells_scheduler_filter:TargetCellFilter": "{{wrapper}}", + + "compute:create": "{{wrapper}}", + "compute:create:attach_network": "{{wrapper}}", + "compute:create:attach_volume": "{{wrapper}}", + "compute:create:forced_host": "{{wrapper}}", + + "compute:get": "{{wrapper}}", + "compute:get_all": "{{wrapper}}", + "compute:get_all_tenants": "{{wrapper}}", + + "compute:update": "{{wrapper}}", + + "compute:get_instance_metadata": "{{wrapper}}", + "compute:get_all_instance_metadata": "{{wrapper}}", + "compute:get_all_instance_system_metadata": "{{wrapper}}", + "compute:update_instance_metadata": "{{wrapper}}", + "compute:delete_instance_metadata": "{{wrapper}}", + + "compute:get_instance_faults": "{{wrapper}}", + "compute:get_diagnostics": "{{wrapper}}", + "compute:get_instance_diagnostics": "{{wrapper}}", + + "compute:start": "{{wrapper}}", + "compute:stop": "{{wrapper}}", + + "compute:get_lock": "{{wrapper}}", + "compute:lock": "{{wrapper}}", + "compute:unlock": "{{wrapper}}", + "compute:unlock_override": "{{wrapper}}", + + "compute:get_vnc_console": "{{wrapper}}", + "compute:get_spice_console": "{{wrapper}}", + "compute:get_rdp_console": "{{wrapper}}", + "compute:get_serial_console": "{{wrapper}}", + "compute:get_mks_console": "{{wrapper}}", + "compute:get_console_output": "{{wrapper}}", + + "compute:reset_network": "{{wrapper}}", + "compute:inject_network_info": "{{wrapper}}", + "compute:add_fixed_ip": "{{wrapper}}", + "compute:remove_fixed_ip": "{{wrapper}}", + + "compute:attach_volume": "{{wrapper}}", + "compute:detach_volume": "{{wrapper}}", + "compute:swap_volume": "{{wrapper}}", + + "compute:attach_interface": "{{wrapper}}", + "compute:detach_interface": "{{wrapper}}", + + "compute:set_admin_password": "{{wrapper}}", + + "compute:rescue": "{{wrapper}}", + "compute:unrescue": "{{wrapper}}", + + "compute:suspend": "{{wrapper}}", + "compute:resume": "{{wrapper}}", + + "compute:pause": "{{wrapper}}", + "compute:unpause": "{{wrapper}}", + + "compute:shelve": "{{wrapper}}", + "compute:shelve_offload": "{{wrapper}}", + "compute:unshelve": "{{wrapper}}", + + "compute:snapshot": "{{wrapper}}", + "compute:snapshot_volume_backed": "{{wrapper}}", + "compute:backup": "{{wrapper}}", + + "compute:resize": "{{wrapper}}", + "compute:confirm_resize": "{{wrapper}}", + "compute:revert_resize": "{{wrapper}}", + + "compute:rebuild": "{{wrapper}}", + "compute:reboot": "{{wrapper}}", + "compute:delete": "{{wrapper}}", + "compute:soft_delete": "{{wrapper}}", + "compute:force_delete": "{{wrapper}}", + + "compute:security_groups:add_to_instance": "{{wrapper}}", + "compute:security_groups:remove_from_instance": "{{wrapper}}", + + "compute:delete": "{{wrapper}}", + "compute:soft_delete": "{{wrapper}}", + "compute:force_delete": "{{wrapper}}", + "compute:restore": "{{wrapper}}", + + "compute:volume_snapshot_create": "{{wrapper}}", + "compute:volume_snapshot_delete": "{{wrapper}}", + + "admin_api": "{{wrapper}}", + "compute_extension:accounts": "{{wrapper}}", + "compute_extension:admin_actions": "{{wrapper}}", + "compute_extension:admin_actions:pause": "{{wrapper}}", + "compute_extension:admin_actions:unpause": "{{wrapper}}", + "compute_extension:admin_actions:suspend": "{{wrapper}}", + "compute_extension:admin_actions:resume": "{{wrapper}}", + "compute_extension:admin_actions:lock": "{{wrapper}}", + "compute_extension:admin_actions:unlock": "{{wrapper}}", + "compute_extension:admin_actions:resetNetwork": "{{wrapper}}", + "compute_extension:admin_actions:injectNetworkInfo": "{{wrapper}}", + "compute_extension:admin_actions:createBackup": "{{wrapper}}", + "compute_extension:admin_actions:migrateLive": "{{wrapper}}", + "compute_extension:admin_actions:resetState": "{{wrapper}}", + "compute_extension:admin_actions:migrate": "{{wrapper}}", + "compute_extension:aggregates": "{{wrapper}}", + "compute_extension:agents": "{{wrapper}}", + "compute_extension:attach_interfaces": "{{wrapper}}", + "compute_extension:baremetal_nodes": "{{wrapper}}", + "compute_extension:cells": "{{wrapper}}", + "compute_extension:cells:create": "{{wrapper}}", + "compute_extension:cells:delete": "{{wrapper}}", + "compute_extension:cells:update": "{{wrapper}}", + "compute_extension:cells:sync_instances": "{{wrapper}}", + "compute_extension:certificates": "{{wrapper}}", + "compute_extension:cloudpipe": "{{wrapper}}", + "compute_extension:cloudpipe_update": "{{wrapper}}", + "compute_extension:config_drive": "{{wrapper}}", + "compute_extension:console_output": "{{wrapper}}", + "compute_extension:consoles": "{{wrapper}}", + "compute_extension:createserverext": "{{wrapper}}", + "compute_extension:deferred_delete": "{{wrapper}}", + "compute_extension:disk_config": "{{wrapper}}", + "compute_extension:evacuate": "{{wrapper}}", + "compute_extension:extended_server_attributes": "{{wrapper}}", + "compute_extension:extended_status": "{{wrapper}}", + "compute_extension:extended_availability_zone": "{{wrapper}}", + "compute_extension:extended_ips": "{{wrapper}}", + "compute_extension:extended_ips_mac": "{{wrapper}}", + "compute_extension:extended_vif_net": "{{wrapper}}", + "compute_extension:extended_volumes": "{{wrapper}}", + "compute_extension:fixed_ips": "{{wrapper}}", + "compute_extension:flavor_access": "{{wrapper}}", + "compute_extension:flavor_access:addTenantAccess": "{{wrapper}}", + "compute_extension:flavor_access:removeTenantAccess": "{{wrapper}}", + "compute_extension:flavor_disabled": "{{wrapper}}", + "compute_extension:flavor_rxtx": "{{wrapper}}", + "compute_extension:flavor_swap": "{{wrapper}}", + "compute_extension:flavorextradata": "{{wrapper}}", + "compute_extension:flavorextraspecs:index": "{{wrapper}}", + "compute_extension:flavorextraspecs:show": "{{wrapper}}", + "compute_extension:flavorextraspecs:create": "{{wrapper}}", + "compute_extension:flavorextraspecs:update": "{{wrapper}}", + "compute_extension:flavorextraspecs:delete": "{{wrapper}}", + "compute_extension:flavormanage": "{{wrapper}}", + "compute_extension:floating_ip_dns": "{{wrapper}}", + "compute_extension:floating_ip_pools": "{{wrapper}}", + "compute_extension:floating_ips": "{{wrapper}}", + "compute_extension:floating_ips_bulk": "{{wrapper}}", + "compute_extension:fping": "{{wrapper}}", + "compute_extension:fping:all_tenants": "{{wrapper}}", + "compute_extension:hide_server_addresses": "{{wrapper}}", + "compute_extension:hosts": "{{wrapper}}", + "compute_extension:hypervisors": "{{wrapper}}", + "compute_extension:image_size": "{{wrapper}}", + "compute_extension:instance_actions": "{{wrapper}}", + "compute_extension:instance_actions:events": "{{wrapper}}", + "compute_extension:instance_usage_audit_log": "{{wrapper}}", + "compute_extension:keypairs": "{{wrapper}}", + "compute_extension:keypairs:index": "{{wrapper}}", + "compute_extension:keypairs:show": "{{wrapper}}", + "compute_extension:keypairs:create": "{{wrapper}}", + "compute_extension:keypairs:delete": "{{wrapper}}", + "compute_extension:multinic": "{{wrapper}}", + "compute_extension:networks": "{{wrapper}}", + "compute_extension:networks:view": "{{wrapper}}", + "compute_extension:networks_associate": "{{wrapper}}", + "compute_extension:os-tenant-networks": "{{wrapper}}", + "compute_extension:quotas:show": "{{wrapper}}", + "compute_extension:quotas:update": "{{wrapper}}", + "compute_extension:quotas:delete": "{{wrapper}}", + "compute_extension:quota_classes": "{{wrapper}}", + "compute_extension:rescue": "{{wrapper}}", + "compute_extension:security_group_default_rules": "{{wrapper}}", + "compute_extension:security_groups": "{{wrapper}}", + "compute_extension:server_diagnostics": "{{wrapper}}", + "compute_extension:server_groups": "{{wrapper}}", + "compute_extension:server_password": "{{wrapper}}", + "compute_extension:server_usage": "{{wrapper}}", + "compute_extension:services": "{{wrapper}}", + "compute_extension:shelve": "{{wrapper}}", + "compute_extension:shelveOffload": "{{wrapper}}", + "compute_extension:simple_tenant_usage:show": "{{wrapper}}", + "compute_extension:simple_tenant_usage:list": "{{wrapper}}", + "compute_extension:unshelve": "{{wrapper}}", + "compute_extension:users": "{{wrapper}}", + "compute_extension:virtual_interfaces": "{{wrapper}}", + "compute_extension:virtual_storage_arrays": "{{wrapper}}", + "compute_extension:volumes": "{{wrapper}}", + "compute_extension:volume_attachments:index": "{{wrapper}}", + "compute_extension:volume_attachments:show": "{{wrapper}}", + "compute_extension:volume_attachments:create": "{{wrapper}}", + "compute_extension:volume_attachments:update": "{{wrapper}}", + "compute_extension:volume_attachments:delete": "{{wrapper}}", + "compute_extension:volumetypes": "{{wrapper}}", + "compute_extension:availability_zone:list": "{{wrapper}}", + "compute_extension:availability_zone:detail": "{{wrapper}}", + "compute_extension:used_limits_for_admin": "{{wrapper}}", + "compute_extension:migrations:index": "{{wrapper}}", + "compute_extension:os-assisted-volume-snapshots:create": "{{wrapper}}", + "compute_extension:os-assisted-volume-snapshots:delete": "{{wrapper}}", + "compute_extension:console_auth_tokens": "{{wrapper}}", + "compute_extension:os-server-external-events:create": "{{wrapper}}", + + "network:get_all": "{{wrapper}}", + "network:get": "{{wrapper}}", + "network:create": "{{wrapper}}", + "network:delete": "{{wrapper}}", + "network:associate": "{{wrapper}}", + "network:disassociate": "{{wrapper}}", + "network:get_vifs_by_instance": "{{wrapper}}", + "network:allocate_for_instance": "{{wrapper}}", + "network:deallocate_for_instance": "{{wrapper}}", + "network:validate_networks": "{{wrapper}}", + "network:get_instance_uuids_by_ip_filter": "{{wrapper}}", + "network:get_instance_id_by_floating_address": "{{wrapper}}", + "network:setup_networks_on_host": "{{wrapper}}", + "network:get_backdoor_port": "{{wrapper}}", + + "network:get_floating_ip": "{{wrapper}}", + "network:get_floating_ip_pools": "{{wrapper}}", + "network:get_floating_ip_by_address": "{{wrapper}}", + "network:get_floating_ips_by_project": "{{wrapper}}", + "network:get_floating_ips_by_fixed_address": "{{wrapper}}", + "network:allocate_floating_ip": "{{wrapper}}", + "network:associate_floating_ip": "{{wrapper}}", + "network:disassociate_floating_ip": "{{wrapper}}", + "network:release_floating_ip": "{{wrapper}}", + "network:migrate_instance_start": "{{wrapper}}", + "network:migrate_instance_finish": "{{wrapper}}", + + "network:get_fixed_ip": "{{wrapper}}", + "network:get_fixed_ip_by_address": "{{wrapper}}", + "network:add_fixed_ip_to_instance": "{{wrapper}}", + "network:remove_fixed_ip_from_instance": "{{wrapper}}", + "network:add_network_to_project": "{{wrapper}}", + "network:get_instance_nw_info": "{{wrapper}}", + + "network:get_dns_domains": "{{wrapper}}", + "network:add_dns_entry": "{{wrapper}}", + "network:modify_dns_entry": "{{wrapper}}", + "network:delete_dns_entry": "{{wrapper}}", + "network:get_dns_entries_by_address": "{{wrapper}}", + "network:get_dns_entries_by_name": "{{wrapper}}", + "network:create_private_dns_domain": "{{wrapper}}", + "network:create_public_dns_domain": "{{wrapper}}", + "network:delete_dns_domain": "{{wrapper}}", + "network:attach_external_network": "{{wrapper}}", + "network:get_vif_by_mac_address": "{{wrapper}}", + + "os_compute_api:servers:detail:get_all_tenants": "{{wrapper}}", + "os_compute_api:servers:index:get_all_tenants": "{{wrapper}}", + "os_compute_api:servers:confirm_resize": "{{wrapper}}", + "os_compute_api:servers:create": "{{wrapper}}", + "os_compute_api:servers:create:attach_network": "{{wrapper}}", + "os_compute_api:servers:create:attach_volume": "{{wrapper}}", + "os_compute_api:servers:create:forced_host": "{{wrapper}}", + "os_compute_api:servers:delete": "{{wrapper}}", + "os_compute_api:servers:update": "{{wrapper}}", + "os_compute_api:servers:detail": "{{wrapper}}", + "os_compute_api:servers:index": "{{wrapper}}", + "os_compute_api:servers:reboot": "{{wrapper}}", + "os_compute_api:servers:rebuild": "{{wrapper}}", + "os_compute_api:servers:resize": "{{wrapper}}", + "os_compute_api:servers:revert_resize": "{{wrapper}}", + "os_compute_api:servers:show": "{{wrapper}}", + "os_compute_api:servers:create_image": "{{wrapper}}", + "os_compute_api:servers:create_image:allow_volume_backed": "{{wrapper}}", + "os_compute_api:servers:start": "{{wrapper}}", + "os_compute_api:servers:stop": "{{wrapper}}", + "os_compute_api:os-access-ips:discoverable": "{{wrapper}}", + "os_compute_api:os-access-ips": "{{wrapper}}", + "os_compute_api:os-admin-actions": "{{wrapper}}", + "os_compute_api:os-admin-actions:discoverable": "{{wrapper}}", + "os_compute_api:os-admin-actions:reset_network": "{{wrapper}}", + "os_compute_api:os-admin-actions:inject_network_info": "{{wrapper}}", + "os_compute_api:os-admin-actions:reset_state": "{{wrapper}}", + "os_compute_api:os-admin-password": "{{wrapper}}", + "os_compute_api:os-admin-password:discoverable": "{{wrapper}}", + "os_compute_api:os-aggregates:discoverable": "{{wrapper}}", + "os_compute_api:os-aggregates:index": "{{wrapper}}", + "os_compute_api:os-aggregates:create": "{{wrapper}}", + "os_compute_api:os-aggregates:show": "{{wrapper}}", + "os_compute_api:os-aggregates:update": "{{wrapper}}", + "os_compute_api:os-aggregates:delete": "{{wrapper}}", + "os_compute_api:os-aggregates:add_host": "{{wrapper}}", + "os_compute_api:os-aggregates:remove_host": "{{wrapper}}", + "os_compute_api:os-aggregates:set_metadata": "{{wrapper}}", + "os_compute_api:os-agents": "{{wrapper}}", + "os_compute_api:os-agents:discoverable": "{{wrapper}}", + "os_compute_api:os-attach-interfaces": "{{wrapper}}", + "os_compute_api:os-attach-interfaces:discoverable": "{{wrapper}}", + "os_compute_api:os-baremetal-nodes": "{{wrapper}}", + "os_compute_api:os-baremetal-nodes:discoverable": "{{wrapper}}", + "os_compute_api:os-block-device-mapping-v1:discoverable": "{{wrapper}}", + "os_compute_api:os-cells": "{{wrapper}}", + "os_compute_api:os-cells:create": "{{wrapper}}", + "os_compute_api:os-cells:delete": "{{wrapper}}", + "os_compute_api:os-cells:update": "{{wrapper}}", + "os_compute_api:os-cells:sync_instances": "{{wrapper}}", + "os_compute_api:os-cells:discoverable": "{{wrapper}}", + "os_compute_api:os-certificates:create": "{{wrapper}}", + "os_compute_api:os-certificates:show": "{{wrapper}}", + "os_compute_api:os-certificates:discoverable": "{{wrapper}}", + "os_compute_api:os-cloudpipe": "{{wrapper}}", + "os_compute_api:os-cloudpipe:discoverable": "{{wrapper}}", + "os_compute_api:os-config-drive": "{{wrapper}}", + "os_compute_api:os-consoles:discoverable": "{{wrapper}}", + "os_compute_api:os-consoles:create": "{{wrapper}}", + "os_compute_api:os-consoles:delete": "{{wrapper}}", + "os_compute_api:os-consoles:index": "{{wrapper}}", + "os_compute_api:os-consoles:show": "{{wrapper}}", + "os_compute_api:os-console-output:discoverable": "{{wrapper}}", + "os_compute_api:os-console-output": "{{wrapper}}", + "os_compute_api:os-remote-consoles": "{{wrapper}}", + "os_compute_api:os-remote-consoles:discoverable": "{{wrapper}}", + "os_compute_api:os-create-backup:discoverable": "{{wrapper}}", + "os_compute_api:os-create-backup": "{{wrapper}}", + "os_compute_api:os-deferred-delete": "{{wrapper}}", + "os_compute_api:os-deferred-delete:discoverable": "{{wrapper}}", + "os_compute_api:os-disk-config": "{{wrapper}}", + "os_compute_api:os-disk-config:discoverable": "{{wrapper}}", + "os_compute_api:os-evacuate": "{{wrapper}}", + "os_compute_api:os-evacuate:discoverable": "{{wrapper}}", + "os_compute_api:os-extended-server-attributes": "{{wrapper}}", + "os_compute_api:os-extended-server-attributes:discoverable": "{{wrapper}}", + "os_compute_api:os-extended-status": "{{wrapper}}", + "os_compute_api:os-extended-status:discoverable": "{{wrapper}}", + "os_compute_api:os-extended-availability-zone": "{{wrapper}}", + "os_compute_api:os-extended-availability-zone:discoverable": "{{wrapper}}", + "os_compute_api:extensions": "{{wrapper}}", + "os_compute_api:extension_info:discoverable": "{{wrapper}}", + "os_compute_api:os-extended-volumes": "{{wrapper}}", + "os_compute_api:os-extended-volumes:discoverable": "{{wrapper}}", + "os_compute_api:os-fixed-ips": "{{wrapper}}", + "os_compute_api:os-fixed-ips:discoverable": "{{wrapper}}", + "os_compute_api:os-flavor-access": "{{wrapper}}", + "os_compute_api:os-flavor-access:discoverable": "{{wrapper}}", + "os_compute_api:os-flavor-access:remove_tenant_access": "{{wrapper}}", + "os_compute_api:os-flavor-access:add_tenant_access": "{{wrapper}}", + "os_compute_api:os-flavor-rxtx": "{{wrapper}}", + "os_compute_api:os-flavor-rxtx:discoverable": "{{wrapper}}", + "os_compute_api:flavors:discoverable": "{{wrapper}}", + "os_compute_api:os-flavor-extra-specs:discoverable": "{{wrapper}}", + "os_compute_api:os-flavor-extra-specs:index": "{{wrapper}}", + "os_compute_api:os-flavor-extra-specs:show": "{{wrapper}}", + "os_compute_api:os-flavor-extra-specs:create": "{{wrapper}}", + "os_compute_api:os-flavor-extra-specs:update": "{{wrapper}}", + "os_compute_api:os-flavor-extra-specs:delete": "{{wrapper}}", + "os_compute_api:os-flavor-manage:discoverable": "{{wrapper}}", + "os_compute_api:os-flavor-manage": "{{wrapper}}", + "os_compute_api:os-floating-ip-dns": "{{wrapper}}", + "os_compute_api:os-floating-ip-dns:discoverable": "{{wrapper}}", + "os_compute_api:os-floating-ip-dns:domain:update": "{{wrapper}}", + "os_compute_api:os-floating-ip-dns:domain:delete": "{{wrapper}}", + "os_compute_api:os-floating-ip-pools": "{{wrapper}}", + "os_compute_api:os-floating-ip-pools:discoverable": "{{wrapper}}", + "os_compute_api:os-floating-ips": "{{wrapper}}", + "os_compute_api:os-floating-ips:discoverable": "{{wrapper}}", + "os_compute_api:os-floating-ips-bulk": "{{wrapper}}", + "os_compute_api:os-floating-ips-bulk:discoverable": "{{wrapper}}", + "os_compute_api:os-fping": "{{wrapper}}", + "os_compute_api:os-fping:discoverable": "{{wrapper}}", + "os_compute_api:os-fping:all_tenants": "{{wrapper}}", + "os_compute_api:os-hide-server-addresses": "{{wrapper}}", + "os_compute_api:os-hide-server-addresses:discoverable": "{{wrapper}}", + "os_compute_api:os-hosts": "{{wrapper}}", + "os_compute_api:os-hosts:discoverable": "{{wrapper}}", + "os_compute_api:os-hypervisors": "{{wrapper}}", + "os_compute_api:os-hypervisors:discoverable": "{{wrapper}}", + "os_compute_api:images:discoverable": "{{wrapper}}", + "os_compute_api:image-size": "{{wrapper}}", + "os_compute_api:image-size:discoverable": "{{wrapper}}", + "os_compute_api:os-instance-actions": "{{wrapper}}", + "os_compute_api:os-instance-actions:discoverable": "{{wrapper}}", + "os_compute_api:os-instance-actions:events": "{{wrapper}}", + "os_compute_api:os-instance-usage-audit-log": "{{wrapper}}", + "os_compute_api:os-instance-usage-audit-log:discoverable": "{{wrapper}}", + "os_compute_api:ips:discoverable": "{{wrapper}}", + "os_compute_api:ips:index": "{{wrapper}}", + "os_compute_api:ips:show": "{{wrapper}}", + "os_compute_api:os-keypairs:discoverable": "{{wrapper}}", + "os_compute_api:os-keypairs": "{{wrapper}}", + "os_compute_api:os-keypairs:index": "{{wrapper}}", + "os_compute_api:os-keypairs:show": "{{wrapper}}", + "os_compute_api:os-keypairs:create": "{{wrapper}}", + "os_compute_api:os-keypairs:delete": "{{wrapper}}", + "os_compute_api:limits:discoverable": "{{wrapper}}", + "os_compute_api:limits": "{{wrapper}}", + "os_compute_api:os-lock-server:discoverable": "{{wrapper}}", + "os_compute_api:os-lock-server:lock": "{{wrapper}}", + "os_compute_api:os-lock-server:unlock": "{{wrapper}}", + "os_compute_api:os-lock-server:unlock:unlock_override": "{{wrapper}}", + "os_compute_api:os-migrate-server:discoverable": "{{wrapper}}", + "os_compute_api:os-migrate-server:migrate": "{{wrapper}}", + "os_compute_api:os-migrate-server:migrate_live": "{{wrapper}}", + "os_compute_api:os-multinic": "{{wrapper}}", + "os_compute_api:os-multinic:discoverable": "{{wrapper}}", + "os_compute_api:os-networks": "{{wrapper}}", + "os_compute_api:os-networks:view": "{{wrapper}}", + "os_compute_api:os-networks:discoverable": "{{wrapper}}", + "os_compute_api:os-networks-associate": "{{wrapper}}", + "os_compute_api:os-networks-associate:discoverable": "{{wrapper}}", + "os_compute_api:os-pause-server:discoverable": "{{wrapper}}", + "os_compute_api:os-pause-server:pause": "{{wrapper}}", + "os_compute_api:os-pause-server:unpause": "{{wrapper}}", + "os_compute_api:os-pci:pci_servers": "{{wrapper}}", + "os_compute_api:os-pci:discoverable": "{{wrapper}}", + "os_compute_api:os-pci:index": "{{wrapper}}", + "os_compute_api:os-pci:detail": "{{wrapper}}", + "os_compute_api:os-pci:show": "{{wrapper}}", + "os_compute_api:os-personality:discoverable": "{{wrapper}}", + "os_compute_api:os-preserve-ephemeral-rebuild:discoverable": "{{wrapper}}", + "os_compute_api:os-quota-sets:discoverable": "{{wrapper}}", + "os_compute_api:os-quota-sets:show": "{{wrapper}}", + "os_compute_api:os-quota-sets:defaults": "{{wrapper}}", + "os_compute_api:os-quota-sets:update": "{{wrapper}}", + "os_compute_api:os-quota-sets:delete": "{{wrapper}}", + "os_compute_api:os-quota-sets:detail": "{{wrapper}}", + "os_compute_api:os-quota-class-sets:update": "{{wrapper}}", + "os_compute_api:os-quota-class-sets:show": "{{wrapper}}", + "os_compute_api:os-quota-class-sets:discoverable": "{{wrapper}}", + "os_compute_api:os-rescue": "{{wrapper}}", + "os_compute_api:os-rescue:discoverable": "{{wrapper}}", + "os_compute_api:os-scheduler-hints:discoverable": "{{wrapper}}", + "os_compute_api:os-security-group-default-rules:discoverable": "{{wrapper}}", + "os_compute_api:os-security-group-default-rules": "{{wrapper}}", + "os_compute_api:os-security-groups": "{{wrapper}}", + "os_compute_api:os-security-groups:discoverable": "{{wrapper}}", + "os_compute_api:os-server-diagnostics": "{{wrapper}}", + "os_compute_api:os-server-diagnostics:discoverable": "{{wrapper}}", + "os_compute_api:os-server-password": "{{wrapper}}", + "os_compute_api:os-server-password:discoverable": "{{wrapper}}", + "os_compute_api:os-server-usage": "{{wrapper}}", + "os_compute_api:os-server-usage:discoverable": "{{wrapper}}", + "os_compute_api:os-server-groups": "{{wrapper}}", + "os_compute_api:os-server-groups:discoverable": "{{wrapper}}", + "os_compute_api:os-services": "{{wrapper}}", + "os_compute_api:os-services:discoverable": "{{wrapper}}", + "os_compute_api:server-metadata:discoverable": "{{wrapper}}", + "os_compute_api:server-metadata:index": "{{wrapper}}", + "os_compute_api:server-metadata:show": "{{wrapper}}", + "os_compute_api:server-metadata:delete": "{{wrapper}}", + "os_compute_api:server-metadata:create": "{{wrapper}}", + "os_compute_api:server-metadata:update": "{{wrapper}}", + "os_compute_api:server-metadata:update_all": "{{wrapper}}", + "os_compute_api:servers:discoverable": "{{wrapper}}", + "os_compute_api:os-shelve:shelve": "{{wrapper}}", + "os_compute_api:os-shelve:shelve:discoverable": "{{wrapper}}", + "os_compute_api:os-shelve:shelve_offload": "{{wrapper}}", + "os_compute_api:os-simple-tenant-usage:discoverable": "{{wrapper}}", + "os_compute_api:os-simple-tenant-usage:show": "{{wrapper}}", + "os_compute_api:os-simple-tenant-usage:list": "{{wrapper}}", + "os_compute_api:os-suspend-server:discoverable": "{{wrapper}}", + "os_compute_api:os-suspend-server:suspend": "{{wrapper}}", + "os_compute_api:os-suspend-server:resume": "{{wrapper}}", + "os_compute_api:os-tenant-networks": "{{wrapper}}", + "os_compute_api:os-tenant-networks:discoverable": "{{wrapper}}", + "os_compute_api:os-shelve:unshelve": "{{wrapper}}", + "os_compute_api:os-user-data:discoverable": "{{wrapper}}", + "os_compute_api:os-virtual-interfaces": "{{wrapper}}", + "os_compute_api:os-virtual-interfaces:discoverable": "{{wrapper}}", + "os_compute_api:os-volumes": "{{wrapper}}", + "os_compute_api:os-volumes:discoverable": "{{wrapper}}", + "os_compute_api:os-volumes-attachments:index": "{{wrapper}}", + "os_compute_api:os-volumes-attachments:show": "{{wrapper}}", + "os_compute_api:os-volumes-attachments:create": "{{wrapper}}", + "os_compute_api:os-volumes-attachments:update": "{{wrapper}}", + "os_compute_api:os-volumes-attachments:delete": "{{wrapper}}", + "os_compute_api:os-volumes-attachments:discoverable": "{{wrapper}}", + "os_compute_api:os-availability-zone:list": "{{wrapper}}", + "os_compute_api:os-availability-zone:discoverable": "{{wrapper}}", + "os_compute_api:os-availability-zone:detail": "{{wrapper}}", + "os_compute_api:os-used-limits": "{{wrapper}}", + "os_compute_api:os-used-limits:discoverable": "{{wrapper}}", + "os_compute_api:os-migrations:index": "{{wrapper}}", + "os_compute_api:os-migrations:discoverable": "{{wrapper}}", + "os_compute_api:os-assisted-volume-snapshots:create": "{{wrapper}}", + "os_compute_api:os-assisted-volume-snapshots:delete": "{{wrapper}}", + "os_compute_api:os-assisted-volume-snapshots:discoverable": "{{wrapper}}", + "os_compute_api:os-console-auth-tokens": "{{wrapper}}", + "os_compute_api:os-server-external-events:create": "{{wrapper}}", +} diff --git a/old/external_policy_checker/external_policy_checker/__init__.py b/old/external_policy_checker/external_policy_checker/__init__.py new file mode 100644 index 00000000..a4e2017f --- /dev/null +++ b/old/external_policy_checker/external_policy_checker/__init__.py @@ -0,0 +1 @@ +__version__ = "0.1" diff --git a/old/external_policy_checker/external_policy_checker/__main__.py b/old/external_policy_checker/external_policy_checker/__main__.py new file mode 100644 index 00000000..4499a96b --- /dev/null +++ b/old/external_policy_checker/external_policy_checker/__main__.py @@ -0,0 +1,9 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + + +import moon_bouchon.server + +moon_bouchon.server.main() diff --git a/old/external_policy_checker/external_policy_checker/conf_installer.py b/old/external_policy_checker/external_policy_checker/conf_installer.py new file mode 100644 index 00000000..ec45003b --- /dev/null +++ b/old/external_policy_checker/external_policy_checker/conf_installer.py @@ -0,0 +1,83 @@ +import shutil +import logging +import argparse +import os +from uuid import uuid4 +import glob + +logger = logging.getLogger(__name__) + +COMPONENTS = ( + "cinder", + "nova", + "neutron", + "glance", + "keystone" +) + + +def init(): + parser = argparse.ArgumentParser() + parser.add_argument("--verbose", '-v', action='store_true', help='verbose mode') + parser.add_argument("--debug", '-d', action='store_true', help='debug mode') + parser.add_argument("--templates", '-t', help='set template directory', default="templates/") + parser.add_argument("--out-dir", '-o', help='if set, copy the files in this directory', default=None) + parser.add_argument("wrapper_url", help='Wrapper URL to use', nargs="*", + default=["http://127.0.0.1:8080/policy_checker"]) + args = parser.parse_args() + logging_format = "%(levelname)s: %(message)s" + if args.verbose: + logging.basicConfig(level=logging.INFO, format=logging_format) + if args.debug: + logging.basicConfig(level=logging.DEBUG, format=logging_format) + return args + + +def update_templates(templates_dir, wrapper_url): + tmp_dir = os.path.join("/tmp", str(uuid4())) + wrapper_url = wrapper_url[0].strip('"').strip("'") + os.mkdir(tmp_dir) + for comp in COMPONENTS: + input_file = os.path.join(templates_dir, comp + ".policy.json") + output_file = os.path.join(tmp_dir, comp + ".policy.json") + output_fd = open(output_file, "w") + for line in open(input_file): + output_fd.write(line.replace("{{wrapper}}", wrapper_url)) + return tmp_dir + + +def remove_tmp_files(tmp_dir): + for _filename in glob.glob(os.path.join(tmp_dir, "*")): + logger.debug("{} {}".format(_filename, os.path.isfile(_filename))) + if os.path.isfile(_filename): + logger.debug("Trying to delete {}".format(_filename)) + os.remove(_filename) + logger.debug("Delete done") + os.removedirs(tmp_dir) + + +def main(templates_dir, wrapper_url, out_dir=None): + logger.info("Moving configuration files") + tmp_dir = update_templates(templates_dir, wrapper_url) + if out_dir: + logger.info("Moving to {}".format(out_dir)) + try: + os.mkdir(out_dir) + except FileExistsError: + logger.warning("Output directory exists, writing on it!") + for comp in COMPONENTS: + logger.info("Moving {}".format(comp)) + shutil.copy(os.path.join(tmp_dir, comp + ".policy.json"), + os.path.join(out_dir, comp + ".policy.json")) + else: + logger.info("Moving to /etc") + for comp in COMPONENTS: + logger.info("Moving {}".format(comp)) + shutil.copy(os.path.join(tmp_dir, comp + ".policy.json"), + os.path.join("etc", comp, "policy.json")) + remove_tmp_files(tmp_dir) + + +if __name__ == "__main__": + args = init() + main(args.templates, args.wrapper_url, args.out_dir) diff --git a/old/external_policy_checker/external_policy_checker/server.py b/old/external_policy_checker/external_policy_checker/server.py new file mode 100644 index 00000000..cbb4a933 --- /dev/null +++ b/old/external_policy_checker/external_policy_checker/server.py @@ -0,0 +1,135 @@ +# Copyright 2018 Orange +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +import sys +import flask +from flask import Flask +from flask import request +import json +import logging +import random + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) +app = Flask(__name__) + + +def test_target(data, result): + if "resource_id" in data: + result["resource_id"] = data['object_id'] + if "object_id" in data: + result["resource_id"] = data['object_id'] + if 'project_id' in data: + result["project_id"] = data['project_id'] + if 'user_id' in data: + result["user_id"] = data['user_id'] + + +def test_credentials(data, result): + if 'project_id' in data: + result["project_id"] = data['project_id'] + if 'user_id' in data: + result["user_id"] = data['user_id'] + if 'project_domain_id' in data: + result["domain_id"] = data['project_domain_id'] + + +def test_rule(data, result): + result['action_name'] = data + + +def test_data(): + data = request.form + result = { + "user_id": "", + "project_id": "", + "action_name": "", + "resource_id": "", + "domain_id": "", + } + if not dict(request.form): + data = json.loads(request.data.decode("utf-8")) + try: + target = json.loads(data.get('target', {})) + except Exception: + raise Exception("Error reading target") + try: + credentials = json.loads(data.get('credentials', {})) + except Exception: + raise Exception("Error reading credentials") + try: + rule = data.get('rule', "") + except Exception: + raise Exception("Error reading rule") + test_target(target, result) + test_credentials(credentials, result) + test_rule(rule, result) + return_value = True + logger.info("Analysing request with {}".format(rule)) + for key in result: + if not result[key] and key != "domain_id": + return_value = False + logger.error("Attribute {} is absent".format(key)) + if not result[key] and key == "domain_id": + logger.warning("Attribute {} is missing.".format(key)) + return return_value + + +@app.route("/policy_checker", methods=["POST"]) +def checker(): + information_is_complete = False + try: + information_is_complete = test_data() + except Exception as e: + logger.exception(e) + if information_is_complete: + response = flask.make_response("True") + response.headers['content-type'] = 'application/octet-stream' + return response + else: + response = flask.make_response("False") + response.headers['content-type'] = 'application/octet-stream' + return response, 403 + + +def get_target(): + data = request.form + if not dict(request.form): + data = json.loads(request.data.decode("utf-8")) + try: + return json.loads(data.get('target', {})) + except Exception: + raise Exception("Error reading target") + + +@app.route("/authz/grant", methods=["POST"]) +def wrapper_grant(): + logger.info("Requesting wrapper authz with {}".format(get_target())) + response = flask.make_response("True") + response.headers['content-type'] = 'application/octet-stream' + return response + + +@app.route("/authz/deny", methods=["POST"]) +def wrapper_deny(): + logger.info("Requesting wrapper authz with {}".format(get_target())) + response = flask.make_response("False") + response.headers['content-type'] = 'application/octet-stream' + return response, 403 + + +def main(): + port = 8080 + if len(sys.argv) > 1: + try: + port = int(sys.argv[1]) + except ValueError: + logger.error("Argument for Port in command line is not an integer") + sys.exit(1) + app.run(host="0.0.0.0", port=port) + + +if __name__ == "__main__": + main() diff --git a/old/external_policy_checker/requirements.txt b/old/external_policy_checker/requirements.txt new file mode 100644 index 00000000..8ab6294c --- /dev/null +++ b/old/external_policy_checker/requirements.txt @@ -0,0 +1 @@ +flask \ No newline at end of file diff --git a/old/external_policy_checker/setup.cfg b/old/external_policy_checker/setup.cfg new file mode 100644 index 00000000..7c2b2874 --- /dev/null +++ b/old/external_policy_checker/setup.cfg @@ -0,0 +1,2 @@ +[bdist_wheel] +universal = 1 \ No newline at end of file diff --git a/old/external_policy_checker/setup.py b/old/external_policy_checker/setup.py new file mode 100644 index 00000000..acd994a6 --- /dev/null +++ b/old/external_policy_checker/setup.py @@ -0,0 +1,47 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +from setuptools import setup, find_packages +import external_policy_checker + + +setup( + + name='external_policy_checker', + + version=external_policy_checker.__version__, + + packages=find_packages(), + + author="Thomas Duval", + + author_email="thomas.duval@orange.com", + + description="", + + long_description=open('README.md').read(), + + install_requires=["flask"], + + include_package_data=True, + + url='https://git.opnfv.org/cgit/moon', + + classifiers=[ + "Programming Language :: Python", + "Development Status :: 1 - Planning", + "License :: OSI Approved", + "Natural Language :: French", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3", + ], + + entry_points={ + 'console_scripts': [ + 'external_policy_checker = external_policy_checker.server:main', + ], + } + +) diff --git a/old/moon_authz/Changelog b/old/moon_authz/Changelog new file mode 100644 index 00000000..ae1ec4d1 --- /dev/null +++ b/old/moon_authz/Changelog @@ -0,0 +1,39 @@ +# Copyright 2018 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + + +CHANGES +======= + +1.0.0 +----- +- First version of the manager + +2.0.0 +----- +- Version built inside the Keystone component + +3.0.0 +----- +- Version built outside the Keystone component + +4.0.0 +----- +- First micro-architecture version + +4.3.3 +----- +- use the threading capability of Flask app +- set the number of manager to 1 +- update to the latest version of the python-moondb library + +4.3.4 +----- +- apply PyLint rules +- fix a bug in instructions management + +4.4.0 +----- +- add the update API diff --git a/old/moon_authz/Dockerfile b/old/moon_authz/Dockerfile new file mode 100644 index 00000000..7081e31c --- /dev/null +++ b/old/moon_authz/Dockerfile @@ -0,0 +1,15 @@ +FROM python:3 + +LABEL Name=Authz_plugin +LABEL Description="Authz plugin for the Moon platform" +LABEL Maintainer="Thomas Duval" +LABEL Url="https://wiki.opnfv.org/display/moon/Moon+Project+Proposal" + +USER root + +ADD . /root +WORKDIR /root/ +RUN pip3 install --no-cache-dir -r requirements.txt +RUN pip3 install --no-cache-dir . + +CMD ["python3", "-m", "moon_authz"] \ No newline at end of file diff --git a/old/moon_authz/LICENSE b/old/moon_authz/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/old/moon_authz/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/old/moon_authz/MANIFEST.in b/old/moon_authz/MANIFEST.in new file mode 100644 index 00000000..1f674d50 --- /dev/null +++ b/old/moon_authz/MANIFEST.in @@ -0,0 +1,9 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +include README.rst +include LICENSE +include setup.py +include requirements.txt diff --git a/old/moon_authz/README.md b/old/moon_authz/README.md new file mode 100644 index 00000000..696c29a1 --- /dev/null +++ b/old/moon_authz/README.md @@ -0,0 +1,8 @@ +# moon_authz + +This package contains the core module for the Moon project +It is designed to provide authorization features to all OpenStack components. + +For any other information, refer to the parent project: + + https://git.opnfv.org/moon diff --git a/old/moon_authz/moon_authz/__init__.py b/old/moon_authz/moon_authz/__init__.py new file mode 100644 index 00000000..85c245e0 --- /dev/null +++ b/old/moon_authz/moon_authz/__init__.py @@ -0,0 +1,6 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +__version__ = "4.4.0" diff --git a/old/moon_authz/moon_authz/__main__.py b/old/moon_authz/moon_authz/__main__.py new file mode 100644 index 00000000..6f1f9807 --- /dev/null +++ b/old/moon_authz/moon_authz/__main__.py @@ -0,0 +1,4 @@ +from moon_authz.server import create_server + +SERVER = create_server() +SERVER.run() diff --git a/old/moon_authz/moon_authz/api/__init__.py b/old/moon_authz/moon_authz/api/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/old/moon_authz/moon_authz/api/authorization.py b/old/moon_authz/moon_authz/api/authorization.py new file mode 100644 index 00000000..59af295d --- /dev/null +++ b/old/moon_authz/moon_authz/api/authorization.py @@ -0,0 +1,397 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +import itertools +import pickle +import logging +import flask +from flask import request +from flask_restful import Resource +from python_moonutilities import exceptions + +LOGGER = logging.getLogger("moon.authz.api." + __name__) + + +class Authz(Resource): + """ + Endpoint for authz requests + """ + __version__ = "4.3.1" + + __urls__ = ( + "/authz", + "/authz/", + ) + + pdp_id = None + meta_rule_id = None + keystone_project_id = None + payload = None + + def __init__(self, **kwargs): + component_data = kwargs.get("component_data", {}) + self.component_id = component_data['component_id'] + self.pdp_id = component_data['pdp_id'] + self.meta_rule_id = component_data['meta_rule_id'] + self.keystone_project_id = component_data['keystone_project_id'] + self.cache = kwargs.get("cache") + self.context = None + + def post(self): + """Get a response on an authorization request + + :request: + + :return: { + "args": {}, + "ctx": { + "action_name": "4567", + "id": "123456", + "method": "authz", + "object_name": "234567", + "subject_name": "123456", + "user_id": "admin" + }, + "error": { + "code": 500, + "description": "", + "title": "Moon Error" + }, + "intra_extension_id": "123456", + "result": false + } + :internal_api: authz + """ + self.context = pickle.loads(request.data) + self.context.set_cache(self.cache) + self.context.increment_index() + self.context.update_target() + # FIXME (asteroide): force the update but we should not do that + # a better way is to build the bilateral link between Master and Slaves + self.cache.update() + if not self.run(): + raise exceptions.MoonError("Error in the request status={}".format( + self.context.current_state)) + self.context.delete_cache() + response = flask.make_response(pickle.dumps(self.context)) + response.headers['content-type'] = 'application/octet-stream' + return response + + def run(self): + result, message = self.__check_rules() + if result: + return self.__exec_instructions(result) + self.context.current_state = "deny" + # self.__exec_next_state(result) + return + + def __check_rules(self): + scopes_list = list() + current_header_id = self.context.headers[self.context.index] + # Context.update_target(context) + if not self.context.pdp_set: + raise exceptions.PdpUnknown + if current_header_id not in self.context.pdp_set: + raise Exception('Invalid index') + current_pdp = self.context.pdp_set[current_header_id] + category_list = list() + if 'meta_rules' not in current_pdp: + raise exceptions.PdpContentError + try: + category_list.extend(current_pdp["meta_rules"]["subject_categories"]) + category_list.extend(current_pdp["meta_rules"]["object_categories"]) + category_list.extend(current_pdp["meta_rules"]["action_categories"]) + except Exception: + raise exceptions.MetaRuleContentError + if 'target' not in current_pdp: + raise exceptions.PdpContentError + for category in category_list: + scope = list(current_pdp['target'][category]) + if not scope: + LOGGER.warning("Scope in category {} is empty".format(category)) + raise exceptions.AuthzException + scopes_list.append(scope) + # policy_id = self.cache.get_policy_from_meta_rules("admin", current_header_id) + if self.context.current_policy_id not in self.cache.rules: + raise exceptions.PolicyUnknown + if 'rules' not in self.cache.rules[self.context.current_policy_id]: + raise exceptions.RuleUnknown + for item in itertools.product(*scopes_list): + req = list(item) + for rule in self.cache.rules[self.context.current_policy_id]["rules"]: + if req == rule['rule']: + return rule['instructions'], "" + LOGGER.warning("No rule match the request...") + return False, "No rule match the request..." + + def __update_subject_category_in_policy(self, operation, target): + result = False + # try: + # policy_name, category_name, data_name = target.split(":") + # except ValueError: + # LOGGER.error("Cannot understand value in instruction ({})".format(target)) + # return False + # # pdp_set = self.payload["authz_context"]['pdp_set'] + # for meta_rule_id in self.context.pdp_set: + # if meta_rule_id == "effect": + # continue + # if self.context.pdp_set[meta_rule_id]["meta_rules"]["name"] == policy_name: + # for category_id, category_value in self.cache.subject_categories.items(): + # if category_value["name"] == "role": + # subject_category_id = category_id + # break + # else: + # LOGGER.error("Cannot understand category in instruction ({})".format(target)) + # return False + # subject_data_id = None + # for data in PolicyManager.get_subject_data("admin", policy_id, + # category_id=subject_category_id): + # for data_id, data_value in data['data'].items(): + # if data_value["name"] == data_name: + # subject_data_id = data_id + # break + # if subject_data_id: + # break + # else: + # LOGGER.error("Cannot understand data in instruction ({})".format(target)) + # return False + # if operation == "add": + # self.payload["authz_context"]['pdp_set'][meta_rule_id]['target'][ + # subject_category_id].append(subject_data_id) + # elif operation == "delete": + # try: + # self.payload["authz_context"]['pdp_set'][meta_rule_id]['target'][ + # subject_category_id].remove(subject_data_id) + # except ValueError: + # LOGGER.warning("Cannot remove role {} from target".format(data_name)) + # result = True + # break + return result + + def __update_container_chaining(self): + for index in range(len(self.payload["authz_context"]['headers'])): + self.payload["container_chaining"][index]["meta_rule_id"] = \ + self.payload["authz_context"]['headers'][index] + + def __get_container_from_meta_rule(self, meta_rule_id): + for index in range(len(self.payload["authz_context"]['headers'])): + if self.payload["container_chaining"][index]["meta_rule_id"] == meta_rule_id: + return self.payload["container_chaining"][index] + + def __update_headers(self, name): + # context = self.payload["authz_context"] + for meta_rule_id, meta_rule_value in self.context.pdp_set.items(): + if meta_rule_id == "effect": + continue + if meta_rule_value["meta_rules"]["name"] == name: + self.context.headers.append(meta_rule_id) + return True + return False + + # def __exec_next_state(self, rule_found): + # index = self.context.index + # current_meta_rule = self.context.headers[index] + # current_container = self.__get_container_from_meta_rule(current_meta_rule) + # current_container_genre = current_container["genre"] + # try: + # next_meta_rule = self.context.headers[index + 1] + # except IndexError: + # next_meta_rule = None + # if current_container_genre == "authz": + # if rule_found: + # return True + # pass + # if next_meta_rule: + # # next will be session if current is deny and session is unset + # if self.payload["authz_context"]['pdp_set'][next_meta_rule]['effect'] == "unset": + # return notify( + # request_id=self.payload["authz_context"]["request_id"], + # container_id=self.__get_container_from_meta_rule(next_meta_rule)[ + # 'container_id'],payload=self.payload) + # # next will be delegation if current is deny and session is passed or deny and + # delegation is unset + # else: + # LOG.error("Delegation is not developed!") + # + # else: + # # else next will be None and the request is sent to router + # return self.__return_to_router() + # elif current_container_genre == "session": + # pass + # # next will be next container in headers if current is passed + # if self.payload["authz_context"]['pdp_set'][current_meta_rule]['effect'] == "passed": + # return notify( + # request_id=self.payload["authz_context"]["request_id"], + # container_id=self.__get_container_from_meta_rule(next_meta_rule)[ + # 'container_id'],payload=self.payload) + # # next will be None if current is grant and the request is sent to router + # else: + # return self.__return_to_router() + # elif current_container_genre == "delegation": + # LOG.error("Delegation is not developed!") + # # next will be authz if current is deny + # # next will be None if current is grant and the request is sent to router + + # def __return_to_router(self): + # call(endpoint="security_router", + # ctx={"id": self.component_id, + # "call_master": False, + # "method": "return_authz", + # "request_id": self.payload["authz_context"]["request_id"]}, + # method="route", + # args=self.payload["authz_context"]) + + def __exec_instructions(self, instructions): + if type(instructions) is dict: + instructions = [instructions, ] + if type(instructions) not in (list, tuple): + raise exceptions.RuleContentError("Bad instructions format") + for instruction in instructions: + for key in instruction: + if key == "decision": + if instruction["decision"] == "grant": + self.context.current_state = "grant" + LOGGER.info("__exec_instructions True %s" % self.context.current_state) + return True + + self.context.current_state = instruction["decision"].lower() + elif key == "chain": + result = self.__update_headers(**instruction["chain"]) + if not result: + self.context.current_state = "deny" + else: + self.context.current_state = "passed" + elif key == "update": + result = self.__update_subject_category_in_policy(**instruction["update"]) + if not result: + self.context.current_state = "deny" + else: + self.context.current_state = "passed" + LOGGER.info("__exec_instructions False %s" % self.context.current_state) + + # def __update_current_request(self): + # index = self.payload["authz_context"]["index"] + # current_header_id = self.payload["authz_context"]['headers'][index] + # previous_header_id = self.payload["authz_context"]['headers'][index - 1] + # current_policy_id = PolicyManager.get_policy_from_meta_rules("admin", current_header_id) + # previous_policy_id = PolicyManager.get_policy_from_meta_rules("admin", previous_header_id) + # # FIXME (asteroide): must change those lines to be ubiquitous against any type of policy + # if self.payload["authz_context"]['pdp_set'][current_header_id]['meta_rules'][ + # 'name'] == "session": + # subject = self.payload["authz_context"]['current_request'].get("subject") + # subject_category_id = None + # role_names = [] + # for category_id, category_value in ModelManager.get_subject_categories("admin").items(): + # if category_value["name"] == "role": + # subject_category_id = category_id + # break + # for assignment_id, assignment_value in PolicyManager.get_subject_assignments( + # "admin", previous_policy_id, subject, subject_category_id).items(): + # for data_id in assignment_value["assignments"]: + # data = PolicyManager.get_subject_data( + # "admin", previous_policy_id, data_id, subject_category_id) + # for _data in data: + # for key, value in _data["data"].items(): + # role_names.append(value["name"]) + # new_role_ids = [] + # for perimeter_id, perimeter_value in PolicyManager.get_objects( + # "admin", current_policy_id).items(): + # if perimeter_value["name"] in role_names: + # new_role_ids.append(perimeter_id) + # break + # perimeter_id = None + # for perimeter_id, perimeter_value in PolicyManager.get_actions( + # "admin", current_policy_id).items(): + # if perimeter_value["name"] == "*": + # break + # + # self.payload["authz_context"]['current_request']['object'] = new_role_ids[0] + # self.payload["authz_context"]['current_request']['action'] = perimeter_id + # elif self.payload["authz_context"]['pdp_set'][current_header_id]['meta_rules']['name'] == "rbac": + # self.payload["authz_context"]['current_request']['subject'] = \ + # self.payload["authz_context"]['initial_request']['subject'] + # self.payload["authz_context"]['current_request']['object'] = \ + # self.payload["authz_context"]['initial_request']['object'] + # self.payload["authz_context"]['current_request']['action'] = \ + # self.payload["authz_context"]['initial_request']['action'] + + def get_authz(self): + # self.keystone_project_id = payload["id"] + # LOG.info("get_authz {}".format(payload)) + # self.payload = payload + try: + # if "authz_context" not in payload: + # try: + # self.payload["authz_context"] = Context(self.keystone_project_id, + # self.payload["subject_name"], + # self.payload["object_name"], + # self.payload["action_name"], + # self.payload["request_id"]).to_dict() + # except exceptions.SubjectUnknown: + # ctx = { + # "subject_name": self.payload["subject_name"], + # "object_name": self.payload["object_name"], + # "action_name": self.payload["action_name"], + # } + # call("moon_manager", method="update_from_master", ctx=ctx, args={}) + # self.payload["authz_context"] = Context(self.keystone_project_id, + # self.payload["subject_name"], + # self.payload["object_name"], + # self.payload["action_name"], + # self.payload["request_id"]).to_dict() + # except exceptions.ObjectUnknown: + # ctx = { + # "subject_name": self.payload["subject_name"], + # "object_name": self.payload["object_name"], + # "action_name": self.payload["action_name"], + # } + # call("moon_manager", method="update_from_master", ctx=ctx, args={}) + # self.payload["authz_context"] = Context(self.keystone_project_id, + # self.payload["subject_name"], + # self.payload["object_name"], + # self.payload["action_name"], + # self.payload["request_id"]).to_dict() + # except exceptions.ActionUnknown: + # ctx = { + # "subject_name": self.payload["subject_name"], + # "object_name": self.payload["object_name"], + # "action_name": self.payload["action_name"], + # } + # call("moon_manager", method="update_from_master", ctx=ctx, args={}) + # self.payload["authz_context"] = Context(self.keystone_project_id, + # self.payload["subject_name"], + # self.payload["object_name"], + # self.payload["action_name"], + # self.payload["request_id"]).to_dict() + # self.__update_container_chaining() + # else: + # self.payload["authz_context"]["index"] += 1 + # self.__update_current_request() + result, message = self.__check_rules() + current_header_id = self.payload["authz_context"]['headers'][ + self.payload["authz_context"]['index']] + if result: + self.__exec_instructions(result) + else: + self.payload["authz_context"]['pdp_set'][current_header_id]["effect"] = "deny" + self.__exec_next_state(result) + return {"authz": result, + "error": message, + "pdp_id": self.pdp_id, + "args": self.payload} + except Exception as e: + try: + LOGGER.error(self.payload["authz_context"]) + except KeyError: + LOGGER.error("Cannot find \"authz_context\" in context") + LOGGER.error(e, exc_info=True) + return {"authz": False, + "error": str(e), + "pdp_id": self.pdp_id, + "args": self.payload} + + def head(self, uuid=None, subject_name=None, object_name=None, action_name=None): + LOGGER.info("HEAD request") + return "", 200 diff --git a/old/moon_authz/moon_authz/api/update.py b/old/moon_authz/moon_authz/api/update.py new file mode 100644 index 00000000..68b7f0ce --- /dev/null +++ b/old/moon_authz/moon_authz/api/update.py @@ -0,0 +1,42 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. +""" +Authz is the endpoint to get authorization response +""" + +from flask import request +from flask_restful import Resource +import logging + +__version__ = "4.4.0" + +LOGGER = logging.getLogger("moon.authz.api." + __name__) + + +class Update(Resource): + """ + Endpoint for update requests + """ + + __urls__ = ( + "/update", + ) + + def __init__(self, **kwargs): + self.CACHE = kwargs.get("cache") + self.INTERFACE_NAME = kwargs.get("interface_name", "interface") + self.MANAGER_URL = kwargs.get("manager_url", "http://manager:8080") + self.TIMEOUT = 5 + + def put(self): + try: + self.CACHE.update_assignments( + request.form.get("policy_id", None), + request.form.get("perimeter_id", None), + ) + except Exception as e: + LOGGER.exception(e) + return {"result": False, "reason": str(e)} + return {"result": True} diff --git a/old/moon_authz/moon_authz/http_server.py b/old/moon_authz/moon_authz/http_server.py new file mode 100644 index 00000000..86d8a914 --- /dev/null +++ b/old/moon_authz/moon_authz/http_server.py @@ -0,0 +1,142 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +import logging +from flask import Flask +from flask_restful import Resource, Api +from moon_authz import __version__ +from moon_authz.api.authorization import Authz +from moon_authz.api.update import Update +from python_moonutilities.cache import Cache +from python_moonutilities import exceptions + +LOGGER = logging.getLogger("moon.authz.http_server") + +CACHE = Cache() +CACHE.update() + + +class Server: + """Base class for HTTP server""" + + def __init__(self, host="localhost", port=80, api=None, **kwargs): + """Run a server + + :param host: hostname of the server + :param port: port for the running server + :param kwargs: optional parameters + :return: a running server + """ + self._host = host + self._port = port + self._api = api + self._extra = kwargs + + @property + def host(self): + return self._host + + @host.setter + def host(self, name): + self._host = name + + @host.deleter + def host(self): + self._host = "" + + @property + def port(self): + return self._port + + @port.setter + def port(self, number): + self._port = number + + @port.deleter + def port(self): + self._port = 80 + + def run(self): + raise NotImplementedError() + + +__API__ = ( + Authz, Update +) + + +class Root(Resource): + """ + The root of the web service + """ + __urls__ = ("/",) + __methods = ("get", "post", "put", "delete", "options") + + def get(self): + tree = {"/": {"methods": ("get",), + "description": "List all methods for that service."}} + for item in __API__: + tree[item.__name__] = {"urls": item.__urls__} + _methods = [] + for _method in self.__methods: + if _method in dir(item): + _methods.append(_method) + tree[item.__name__]["methods"] = _methods + tree[item.__name__]["description"] = item.__doc__.strip() + return { + "version": __version__, + "tree": tree + } + + def head(self): + return "", 201 + + +class HTTPServer(Server): + def __init__(self, host="localhost", port=38001, **kwargs): + super(HTTPServer, self).__init__(host=host, port=port, **kwargs) + self.component_data = kwargs.get("component_data", {}) + LOGGER.info("HTTPServer port={} {}".format(port, kwargs)) + self.app = Flask(__name__) + self._port = port + self._host = host + self.component_id = kwargs.get("component_id") + self.keystone_project_id = kwargs.get("keystone_project_id") + self.container_chaining = kwargs.get("container_chaining") + self.api = Api(self.app) + self.__set_route() + + # self.__hook_errors() + + @self.app.errorhandler(exceptions.AuthException) + def _auth_exception(error): + return {"error": "Unauthorized"}, 401 + + def __hook_errors(self): + # FIXME (dthom): it doesn't work + def get_404_json(e): + return {"error": "Error", "code": 404, "description": e} + + self.app.register_error_handler(404, get_404_json) + + def get_400_json(e): + return {"error": "Error", "code": 400, "description": e} + + self.app.register_error_handler(400, lambda e: get_400_json) + self.app.register_error_handler(403, exceptions.AuthException) + + def __set_route(self): + self.api.add_resource(Root, '/') + + for api in __API__: + self.api.add_resource(api, *api.__urls__, + resource_class_kwargs={ + "component_data": self.component_data, + "cache": CACHE + } + ) + + def run(self): + self.app.run(host=self._host, port=self._port, threaded=True) # nosec diff --git a/old/moon_authz/moon_authz/server.py b/old/moon_authz/moon_authz/server.py new file mode 100644 index 00000000..d1b5a59b --- /dev/null +++ b/old/moon_authz/moon_authz/server.py @@ -0,0 +1,56 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +import os +import logging +from moon_authz.http_server import HTTPServer as Server +from python_moonutilities import configuration, exceptions + +LOGGER = logging.getLogger("moon.authz.server") + + +def create_server(): + configuration.init_logging() + + component_id = os.getenv("UUID") + component_type = os.getenv("TYPE") + tcp_port = os.getenv("PORT") + pdp_id = os.getenv("PDP_ID") + meta_rule_id = os.getenv("META_RULE_ID") + keystone_project_id = os.getenv("KEYSTONE_PROJECT_ID") + LOGGER.info("component_type={}".format(component_type)) + conf = configuration.get_plugins() + # conf = configuration.get_configuration("plugins/{}".format(component_type)) + # conf["plugins/{}".format(component_type)]['id'] = component_id + if component_type not in conf: + raise exceptions.ConsulComponentNotFound("{} not found".format( + component_type)) + hostname = conf[component_type].get('hostname', component_id) + port = conf[component_type].get('port', tcp_port) + bind = conf[component_type].get('bind', "0.0.0.0") + + LOGGER.info("Starting server with IP {} on port {} bind to {}".format( + hostname, port, bind)) + server = Server( + host=bind, + port=int(port), + component_data={ + 'component_id': component_id, + 'component_type': component_type, + 'pdp_id': pdp_id, + 'meta_rule_id': meta_rule_id, + 'keystone_project_id': keystone_project_id, + } + ) + return server + + +def run(): + server = create_server() + server.run() + + +if __name__ == '__main__': + run() diff --git a/old/moon_authz/requirements.txt b/old/moon_authz/requirements.txt new file mode 100644 index 00000000..8cad7a7a --- /dev/null +++ b/old/moon_authz/requirements.txt @@ -0,0 +1,5 @@ +flask +flask_restful +flask_cors +python_moondb +python_moonutilities diff --git a/old/moon_authz/setup.py b/old/moon_authz/setup.py new file mode 100644 index 00000000..ad99b9f8 --- /dev/null +++ b/old/moon_authz/setup.py @@ -0,0 +1,47 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +from setuptools import setup, find_packages +import moon_authz + + +setup( + + name='moon_authz', + + version=moon_authz.__version__, + + packages=find_packages(), + + author="Thomas Duval", + + author_email="thomas.duval@orange.com", + + description="", + + long_description=open('README.md').read(), + + # install_requires= , + + include_package_data=True, + + url='https://git.opnfv.org/moon', + + classifiers=[ + "Programming Language :: Python", + "Development Status :: 1 - Planning", + "License :: OSI Approved", + "Natural Language :: French", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3", + ], + + entry_points={ + 'console_scripts': [ + 'moon_authz = moon_authz.server:run', + ], + } + +) diff --git a/old/moon_authz/tests/unit_python/conftest.py b/old/moon_authz/tests/unit_python/conftest.py new file mode 100644 index 00000000..a6e62078 --- /dev/null +++ b/old/moon_authz/tests/unit_python/conftest.py @@ -0,0 +1,29 @@ +import pytest +import requests_mock +import mock_pods +import os +from utilities import CONTEXT + + +@pytest.fixture +def context(): + return CONTEXT + + +def set_env_variables(): + os.environ['UUID'] = "1111111111" + os.environ['TYPE'] = "authz" + os.environ['PORT'] = "8081" + os.environ['PDP_ID'] = "b3d3e18abf3340e8b635fd49e6634ccd" + os.environ['META_RULE_ID'] = "f8f49a779ceb47b3ac810f01ef71b4e0" + os.environ['KEYSTONE_PROJECT_ID'] = CONTEXT['project_id'] + + +@pytest.fixture(autouse=True) +def no_requests(monkeypatch): + """ Modify the response from Requests module + """ + set_env_variables() + with requests_mock.Mocker(real_http=True) as m: + mock_pods.register_pods(m) + yield m diff --git a/old/moon_authz/tests/unit_python/mock_pods.py b/old/moon_authz/tests/unit_python/mock_pods.py new file mode 100644 index 00000000..39223a57 --- /dev/null +++ b/old/moon_authz/tests/unit_python/mock_pods.py @@ -0,0 +1,545 @@ +from utilities import CONF, get_b64_conf, COMPONENTS + +pdp_mock = { + "b3d3e18abf3340e8b635fd49e6634ccd": { + "description": "test", + "security_pipeline": [ + "f8f49a779ceb47b3ac810f01ef71b4e0" + ], + "name": "pdp_rbac", + "keystone_project_id": "a64beb1cc224474fb4badd43173e7101" + }, + "pdp_id1": { + "name": "pdp_id1", + "security_pipeline": ["policy_id_1", "policy_id_2"], + "keystone_project_id": "keystone_project_id1", + "description": "...", + }, + "pdp_id12": { + "name": "pdp_id2", + "security_pipeline": ["policy_id_1", "policy_id_2"], + "keystone_project_id": "keystone_project_id2", + "description": "...", + } +} + +meta_rules_mock = { + "f8f49a779ceb47b3ac810f01ef71b4e0": { + "subject_categories": [ + "14e6ae0ba34d458b876c791b73aa17bd" + ], + "action_categories": [ + "241a2a791554421a91c9f1bc564aa94d" + ], + "description": "", + "name": "rbac", + "object_categories": [ + "6d48500f639d4c2cab2b1f33ef93a1e8" + ] + }, + "meta_rule_id1": { + "name": "meta_rule1", + "algorithm": "name of the meta rule algorithm", + "subject_categories": ["subject_category_id1", + "subject_category_id2"], + "object_categories": ["object_category_id1"], + "action_categories": ["action_category_id1"] + }, + "meta_rule_id2": { + "name": "name of the meta rules2", + "algorithm": "name of the meta rule algorithm", + "subject_categories": ["subject_category_id1", + "subject_category_id2"], + "object_categories": ["object_category_id1"], + "action_categories": ["action_category_id1"] + } +} + +policies_mock = { + "f8f49a779ceb47b3ac810f01ef71b4e0": { + "name": "RBAC policy example", + "model_id": "cd923d8633ff4978ab0e99938f5153d6", + "description": "test", + "genre": "authz" + }, + "policy_id_1": { + "name": "test_policy1", + "model_id": "model_id_1", + "genre": "authz", + "description": "test", + }, + "policy_id_2": { + "name": "test_policy2", + "model_id": "model_id_2", + "genre": "authz", + "description": "test", + } +} + +subject_mock = { + "f8f49a779ceb47b3ac810f01ef71b4e0": { + "89ba91c18dd54abfbfde7a66936c51a6": { + "description": "test", + "policy_list": [ + "f8f49a779ceb47b3ac810f01ef71b4e0", + "636cd473324f4c0bbd9102cb5b62a16d" + ], + "name": "testuser", + "email": "mail", + "id": "89ba91c18dd54abfbfde7a66936c51a6", + "extra": {} + } + }, + "policy_id_1": { + "subject_id": { + "name": "subject_name", + "keystone_id": "keystone_project_id1", + "description": "a description" + } + }, + "policy_id_2": { + "subject_id": { + "name": "subject_name", + "keystone_id": "keystone_project_id2", + "description": "a description" + } + } +} + +subject_assignment_mock = { + "826c1156d0284fc9b4b2ddb279f63c52": { + "category_id": "14e6ae0ba34d458b876c791b73aa17bd", + "assignments": [ + "24ea95256c5f4c888c1bb30a187788df", + "6b227b77184c48b6a5e2f3ed1de0c02a", + "31928b17ec90438ba5a2e50ae7650e63", + "4e60f554dd3147af87595fb6b37dcb13", + "7a5541b63a024fa88170a6b59f99ccd7", + "dd2af27812f742029d289df9687d6126" + ], + "id": "826c1156d0284fc9b4b2ddb279f63c52", + "subject_id": "89ba91c18dd54abfbfde7a66936c51a6", + "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0" + }, + "7407ffc1232944279b0cbcb0847c86f7": { + "category_id": "315072d40d774c43a89ff33937ed24eb", + "assignments": [ + "6b227b77184c48b6a5e2f3ed1de0c02a", + "31928b17ec90438ba5a2e50ae7650e63", + "7a5541b63a024fa88170a6b59f99ccd7", + "dd2af27812f742029d289df9687d6126" + ], + "id": "7407ffc1232944279b0cbcb0847c86f7", + "subject_id": "89ba91c18dd54abfbfde7a66936c51a6", + "policy_id": "3e65256389b448cb9897917ea235f0bb" + } +} + +object_mock = { + "f8f49a779ceb47b3ac810f01ef71b4e0": { + "9089b3d2ce5b4e929ffc7e35b55eba1a": { + "name": "vm1", + "description": "test", + "id": "9089b3d2ce5b4e929ffc7e35b55eba1a", + "extra": {}, + "policy_list": [ + "f8f49a779ceb47b3ac810f01ef71b4e0", + "636cd473324f4c0bbd9102cb5b62a16d" + ] + }, + }, + "policy_id_1": { + "object_id": { + "name": "object_name", + "description": "a description" + } + }, + "policy_id_2": { + "object_id": { + "name": "object_name", + "description": "a description" + } + } +} + +object_assignment_mock = { + "201ad05fd3f940948b769ab9214fe295": { + "object_id": "9089b3d2ce5b4e929ffc7e35b55eba1a", + "assignments": [ + "030fbb34002e4236a7b74eeb5fd71e35", + "06bcb8655b9d46a9b90e67ef7c825b50", + "34eb45d7f46d4fb6bc4965349b8e4b83", + "4b7793dbae434c31a77da9d92de9fa8c" + ], + "id": "201ad05fd3f940948b769ab9214fe295", + "category_id": "6d48500f639d4c2cab2b1f33ef93a1e8", + "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0" + }, + "90c5e86f8be34c0298fbd1973e4fb043": { + "object_id": "67b8008a3f8d4f8e847eb628f0f7ca0e", + "assignments": [ + "a098918e915b4b12bccb89f9a3f3b4e4", + "06bcb8655b9d46a9b90e67ef7c825b50", + "7dc76c6142af47c88b60cc2b0df650ba", + "4b7793dbae434c31a77da9d92de9fa8c" + ], + "id": "90c5e86f8be34c0298fbd1973e4fb043", + "category_id": "33aece52d45b4474a20dc48a76800daf", + "policy_id": "3e65256389b448cb9897917ea235f0bb" + } +} + +action_mock = { + "f8f49a779ceb47b3ac810f01ef71b4e0": { + "cdb3df220dc05a6ea3334b994827b068": { + "name": "boot", + "description": "test", + "id": "cdb3df220dc04a6ea3334b994827b068", + "extra": {}, + "policy_list": [ + "f8f49a779ceb47b3ac810f01ef71b4e0", + "636cd473324f4c0bbd9102cb5b62a16d" + ] + }, + "cdb3df220dc04a6ea3334b994827b068": { + "name": "stop", + "description": "test", + "id": "cdb3df220dc04a6ea3334b994827b068", + "extra": {}, + "policy_list": [ + "f8f49a779ceb47b3ac810f01ef71b4e0", + "636cd473324f4c0bbd9102cb5b62a16d" + ] + }, + "9f5112afe9b34a6c894eb87246ccb7aa": { + "name": "start", + "description": "test", + "id": "9f5112afe9b34a6c894eb87246ccb7aa", + "extra": {}, + "policy_list": [ + "f8f49a779ceb47b3ac810f01ef71b4e0", + "636cd473324f4c0bbd9102cb5b62a16d" + ] + } + }, + "policy_id_1": { + "action_id": { + "name": "action_name", + "description": "a description" + } + }, + "policy_id_2": { + "action_id": { + "name": "action_name", + "description": "a description" + } + } +} + +action_assignment_mock = { + "2128e3ffbd1c4ef5be515d625745c2d4": { + "category_id": "241a2a791554421a91c9f1bc564aa94d", + "action_id": "cdb3df220dc05a6ea3334b994827b068", + "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0", + "id": "2128e3ffbd1c4ef5be515d625745c2d4", + "assignments": [ + "570c036781e540dc9395b83098c40ba7", + "7fe17d7a2e3542719f8349c3f2273182", + "015ca6f40338422ba3f692260377d638", + "23d44c17bf88480f83e8d57d2aa1ea79" + ] + }, + "cffb98852f3a4110af7a0ddfc4e19201": { + "category_id": "4a2c5abaeaf644fcaf3ca8df64000d53", + "action_id": "cdb3df220dc04a6ea3334b994827b068", + "policy_id": "3e65256389b448cb9897917ea235f0bb", + "id": "cffb98852f3a4110af7a0ddfc4e19201", + "assignments": [ + "570c036781e540dc9395b83098c40ba7", + "7fe17d7a2e3542719f8349c3f2273182", + "015ca6f40338422ba3f692260377d638", + "23d44c17bf88480f83e8d57d2aa1ea79" + ] + } +} + +models_mock = { + "cd923d8633ff4978ab0e99938f5153d6": { + "name": "RBAC", + "meta_rules": [ + "f8f49a779ceb47b3ac810f01ef71b4e0" + ], + "description": "test" + }, + "model_id_1": { + "name": "test_model", + "description": "test", + "meta_rules": ["meta_rule_id1"] + }, + "model_id_2": { + "name": "test_model", + "description": "test", + "meta_rules": ["meta_rule_id2"] + }, +} + +rules_mock = { + "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0", + "rules": [ + { + "policy_id": "f8f49a779ceb47b3ac810f01ef71b4e0", + "rule": [ + "24ea95256c5f4c888c1bb30a187788df", + "030fbb34002e4236a7b74eeb5fd71e35", + "570c036781e540dc9395b83098c40ba7" + ], + "enabled": True, + "id": "0201a2bcf56943c1904dbac016289b71", + "instructions": [ + { + "decision": "grant" + } + ], + "meta_rule_id": "f8f49a779ceb47b3ac810f01ef71b4e0" + }, + { + "policy_id": "ecc2451c494e47b5bca7250cd324a360", + "rule": [ + "54f574cd2043468da5d65e4f6ed6e3c9", + "6559686961a3490a978f246ac9f85fbf", + "ac0d1f600bf447e8bd2f37b7cc47f2dc" + ], + "enabled": True, + "id": "a83fed666af8436192dfd8b3c83a6fde", + "instructions": [ + { + "decision": "grant" + } + ], + "meta_rule_id": "f8f49a779ceb47b3ac810f01ef71b4e0" + } + ] +} + + +def register_pods(m): + """ Modify the response from Requests module + """ + register_consul(m) + register_pdp(m) + register_meta_rules(m) + register_policies(m) + register_models(m) + register_orchestrator(m) + register_policy_subject(m, "f8f49a779ceb47b3ac810f01ef71b4e0") + # register_policy_subject(m, "policy_id_2") + register_policy_object(m, "f8f49a779ceb47b3ac810f01ef71b4e0") + # register_policy_object(m, "policy_id_2") + register_policy_action(m, "f8f49a779ceb47b3ac810f01ef71b4e0") + # register_policy_action(m, "policy_id_2") + register_policy_subject_assignment(m, "f8f49a779ceb47b3ac810f01ef71b4e0", "89ba91c18dd54abfbfde7a66936c51a6") + register_policy_subject_assignment_list(m, "f8f49a779ceb47b3ac810f01ef71b4e0") + register_policy_subject_assignment(m, "policy_id_2", "subject_id") + # register_policy_subject_assignment_list(m1, "policy_id_2") + register_policy_object_assignment(m, "f8f49a779ceb47b3ac810f01ef71b4e0", "9089b3d2ce5b4e929ffc7e35b55eba1a") + register_policy_object_assignment_list(m, "f8f49a779ceb47b3ac810f01ef71b4e0") + register_policy_object_assignment(m, "policy_id_2", "object_id") + # register_policy_object_assignment_list(m1, "policy_id_2") + register_policy_action_assignment(m, "f8f49a779ceb47b3ac810f01ef71b4e0", "cdb3df220dc05a6ea3334b994827b068") + register_policy_action_assignment_list(m, "f8f49a779ceb47b3ac810f01ef71b4e0") + register_policy_action_assignment(m, "policy_id_2", "action_id") + # register_policy_action_assignment_list(m1, "policy_id_2") + register_rules(m, "f8f49a779ceb47b3ac810f01ef71b4e0") + register_rules(m, "policy_id_1") + register_rules(m, "policy_id_2") + + +def register_consul(m): + for component in COMPONENTS: + m.register_uri( + 'GET', 'http://consul:8500/v1/kv/{}'.format(component), + json=[{'Key': component, 'Value': get_b64_conf(component)}] + ) + m.register_uri( + 'GET', 'http://consul:8500/v1/kv/components_port_start', + json=[ + { + "LockIndex": 0, + "Key": "components_port_start", + "Flags": 0, + "Value": "MzEwMDE=", + "CreateIndex": 9, + "ModifyIndex": 9 + } + ], + ) + m.register_uri( + 'PUT', 'http://consul:8500/v1/kv/components_port_start', + json=[], + ) + m.register_uri( + 'GET', 'http://consul:8500/v1/kv/plugins?recurse=true', + json=[ + { + "LockIndex": 0, + "Key": "plugins/authz", + "Flags": 0, + "Value": "eyJjb250YWluZXIiOiAid3Vrb25nc3VuL21vb25fYXV0aHo6djQuMyIsICJwb3J0IjogODA4MX0=", + "CreateIndex": 14, + "ModifyIndex": 656 + } + ], + ) + m.register_uri( + 'GET', 'http://consul:8500/v1/kv/components?recurse=true', + json=[ + {"Key": key, "Value": get_b64_conf(key)} for key in COMPONENTS + ], + ) + m.register_uri( + 'GET', 'http://consul:8500/v1/kv/plugins/authz', + json=[ + { + "LockIndex": 0, + "Key": "plugins/authz", + "Flags": 0, + "Value": "eyJjb250YWluZXIiOiAid3Vrb25nc3VuL21vb25fYXV0aHo6djQuMyIsICJwb3J0IjogODA4MX0=", + "CreateIndex": 14, + "ModifyIndex": 656 + } + ], + ) + + +def register_orchestrator(m): + m.register_uri( + 'GET', 'http://orchestrator:8083/pods', + json={ + "pods": { + "1234567890": [ + {"name": "wrapper-quiet", "port": 8080, + "container": "wukongsun/moon_wrapper:v4.3.1", + "namespace": "moon"}]}} + ) + + +def register_pdp(m): + m.register_uri( + 'GET', 'http://{}:{}/{}'.format(CONF['components']['manager']['hostname'], + CONF['components']['manager']['port'], 'pdp'), + json={'pdps': pdp_mock} + ) + + +def register_meta_rules(m): + m.register_uri( + 'GET', 'http://{}:{}/{}'.format(CONF['components']['manager']['hostname'], + CONF['components']['manager']['port'], 'meta_rules'), + json={'meta_rules': meta_rules_mock} + ) + + +def register_policies(m): + m.register_uri( + 'GET', 'http://{}:{}/{}'.format(CONF['components']['manager']['hostname'], + CONF['components']['manager']['port'], 'policies'), + json={'policies': policies_mock} + ) + + +def register_models(m): + m.register_uri( + 'GET', 'http://{}:{}/{}'.format(CONF['components']['manager']['hostname'], + CONF['components']['manager']['port'], 'models'), + json={'models': models_mock} + ) + + +def register_policy_subject(m, policy_id): + m.register_uri( + 'GET', 'http://{}:{}/{}/{}/subjects'.format(CONF['components']['manager']['hostname'], + CONF['components']['manager']['port'], 'policies', policy_id), + json={'subjects': subject_mock[policy_id]} + ) + + +def register_policy_object(m, policy_id): + m.register_uri( + 'GET', 'http://{}:{}/{}/{}/objects'.format(CONF['components']['manager']['hostname'], + CONF['components']['manager']['port'], 'policies', policy_id), + json={'objects': object_mock[policy_id]} + ) + + +def register_policy_action(m, policy_id): + m.register_uri( + 'GET', 'http://{}:{}/{}/{}/actions'.format(CONF['components']['manager']['hostname'], + CONF['components']['manager']['port'], 'policies', policy_id), + json={'actions': action_mock[policy_id]} + ) + + +def register_policy_subject_assignment(m, policy_id, subj_id): + m.register_uri( + 'GET', 'http://{}:{}/{}/{}/subject_assignments/{}'.format(CONF['components']['manager']['hostname'], + CONF['components']['manager']['port'], 'policies', + policy_id, + subj_id), + json={'subject_assignments': subject_assignment_mock} + ) + + +def register_policy_subject_assignment_list(m, policy_id): + m.register_uri( + 'GET', 'http://{}:{}/{}/{}/subject_assignments'.format(CONF['components']['manager']['hostname'], + CONF['components']['manager']['port'], 'policies', + policy_id), + json={'subject_assignments': subject_assignment_mock} + ) + + +def register_policy_object_assignment(m, policy_id, obj_id): + m.register_uri( + 'GET', 'http://{}:{}/{}/{}/object_assignments/{}'.format(CONF['components']['manager']['hostname'], + CONF['components']['manager']['port'], 'policies', + policy_id, + obj_id), + json={'object_assignments': object_assignment_mock} + ) + + +def register_policy_object_assignment_list(m, policy_id): + m.register_uri( + 'GET', 'http://{}:{}/{}/{}/object_assignments'.format(CONF['components']['manager']['hostname'], + CONF['components']['manager']['port'], 'policies', + policy_id), + json={'object_assignments': object_assignment_mock} + ) + + +def register_policy_action_assignment(m, policy_id, action_id): + m.register_uri( + 'GET', 'http://{}:{}/{}/{}/action_assignments/{}'.format(CONF['components']['manager']['hostname'], + CONF['components']['manager']['port'], 'policies', + policy_id, + action_id), + json={'action_assignments': action_assignment_mock} + ) + + +def register_policy_action_assignment_list(m, policy_id): + m.register_uri( + 'GET', 'http://{}:{}/{}/{}/action_assignments'.format(CONF['components']['manager']['hostname'], + CONF['components']['manager']['port'], 'policies', + policy_id), + json={'action_assignments': action_assignment_mock} + ) + + +def register_rules(m, policy_id): + m.register_uri( + 'GET', 'http://{}:{}/{}/{}/{}'.format(CONF['components']['manager']['hostname'], + CONF['components']['manager']['port'], 'policies', + policy_id, 'rules'), + json={'rules': rules_mock} + ) \ No newline at end of file diff --git a/old/moon_authz/tests/unit_python/requirements.txt b/old/moon_authz/tests/unit_python/requirements.txt new file mode 100644 index 00000000..21975ce3 --- /dev/null +++ b/old/moon_authz/tests/unit_python/requirements.txt @@ -0,0 +1,5 @@ +flask +flask_cors +flask_restful +python_moondb +python_moonutilities \ No newline at end of file diff --git a/old/moon_authz/tests/unit_python/test_authz.py b/old/moon_authz/tests/unit_python/test_authz.py new file mode 100644 index 00000000..2352fe06 --- /dev/null +++ b/old/moon_authz/tests/unit_python/test_authz.py @@ -0,0 +1,116 @@ +import json +import pickle +import pytest + + +def get_data(data): + return pickle.loads(data) + + +def get_json(data): + return json.loads(data.decode("utf-8")) + + +def run(component_data, cache, context): + from moon_authz.api.authorization import Authz + authz = Authz(component_data=component_data, cache=cache) + authz.context = context + authz.run() + + +def test_authz_true(context): + import moon_authz.server + from python_moonutilities.context import Context + from python_moonutilities.cache import Cache + server = moon_authz.server.create_server() + client = server.app.test_client() + CACHE = Cache() + CACHE.update() + print(CACHE.pdp) + _context = Context(context, CACHE) + req = client.post("/authz", data=pickle.dumps(_context)) + assert req.status_code == 200 + data = get_data(req.data) + assert data + assert isinstance(data, Context) + policy_id = data.headers[0] + assert policy_id + assert "effect" in data.pdp_set[policy_id] + assert data.pdp_set[policy_id]['effect'] == "grant" + + +def test_user_not_allowed(context): + import moon_authz.server + from python_moonutilities.context import Context + from python_moonutilities.cache import Cache + server = moon_authz.server.create_server() + client = server.app.test_client() + CACHE = Cache() + CACHE.update() + context['subject_name'] = "user_not_allowed" + _context = Context(context, CACHE) + req = client.post("/authz", data=pickle.dumps(_context)) + assert req.status_code == 400 + data = get_json(req.data) + assert data + assert isinstance(data, dict) + assert "message" in data + assert data["message"] == "Cannot find subject user_not_allowed" + + +def test_object_not_allowed(context): + import moon_authz.server + from python_moonutilities.context import Context + from python_moonutilities.cache import Cache + server = moon_authz.server.create_server() + client = server.app.test_client() + CACHE = Cache() + CACHE.update() + context['subject_name'] = "testuser" + context['object_name'] = "invalid" + _context = Context(context, CACHE) + req = client.post("/authz", data=pickle.dumps(_context)) + assert req.status_code == 400 + data = get_json(req.data) + assert data + assert isinstance(data, dict) + assert "message" in data + assert data["message"] == "Cannot find object invalid" + + +def test_action_not_allowed(context): + import moon_authz.server + from python_moonutilities.context import Context + from python_moonutilities.cache import Cache + server = moon_authz.server.create_server() + client = server.app.test_client() + CACHE = Cache() + CACHE.update() + context['subject_name'] = "testuser" + context['object_name'] = "vm1" + context['action_name'] = "invalid" + _context = Context(context, CACHE) + req = client.post("/authz", data=pickle.dumps(_context)) + assert req.status_code == 400 + data = get_json(req.data) + assert data + assert isinstance(data, dict) + assert "message" in data + assert data["message"] == "Cannot find action invalid" + + +def test_authz_with_empty_pdp_set(context): + from python_moonutilities.context import Context + from python_moonutilities.cache import Cache + CACHE = Cache() + CACHE.update() + _context = Context(context, CACHE) + component_data = { + 'component_id': 'component_id1', + 'pdp_id': 'pdp_id1', + 'meta_rule_id': 'meta_rule_id1', + 'keystone_project_id': 'keystone_project_id1', + } + with pytest.raises(Exception) as exception_info: + run(component_data, CACHE, _context) + assert str(exception_info.value) == '400: Pdp Unknown' diff --git a/old/moon_authz/tests/unit_python/utilities.py b/old/moon_authz/tests/unit_python/utilities.py new file mode 100644 index 00000000..e3a111bd --- /dev/null +++ b/old/moon_authz/tests/unit_python/utilities.py @@ -0,0 +1,182 @@ +import base64 +import json +import pytest +from uuid import uuid4 + + +CONF = { + "openstack": { + "keystone": { + "url": "http://keystone:5000/v3", + "user": "admin", + "check_token": False, + "password": "p4ssw0rd", + "domain": "default", + "certificate": False, + "project": "admin" + } + }, + "components": { + "wrapper": { + "bind": "0.0.0.0", + "port": 8080, + "container": "wukongsun/moon_wrapper:v4.3", + "timeout": 5, + "hostname": "wrapper" + }, + "manager": { + "bind": "0.0.0.0", + "port": 8082, + "container": "wukongsun/moon_manager:v4.3", + "hostname": "manager" + }, + "port_start": 31001, + "orchestrator": { + "bind": "0.0.0.0", + "port": 8083, + "container": "wukongsun/moon_orchestrator:v4.3", + "hostname": "orchestrator" + }, + "pipeline": { + "interface": { + "bind": "0.0.0.0", + "port": 8080, + "container": "wukongsun/moon_interface:v4.3", + "hostname": "interface" + }, + "authz": { + "bind": "0.0.0.0", + "port": 8081, + "container": "wukongsun/moon_authz:v4.3", + "hostname": "authz" + } + } + }, + "plugins": { + "session": { + "port": 8082, + "container": "asteroide/session:latest" + }, + "authz": { + "port": 8081, + "container": "wukongsun/moon_authz:v4.3" + } + }, + "logging": { + "handlers": { + "file": { + "filename": "/tmp/moon.log", + "class": "logging.handlers.RotatingFileHandler", + "level": "DEBUG", + "formatter": "custom", + "backupCount": 3, + "maxBytes": 1048576 + }, + "console": { + "class": "logging.StreamHandler", + "formatter": "brief", + "level": "INFO", + "stream": "ext://sys.stdout" + } + }, + "formatters": { + "brief": { + "format": "%(levelname)s %(name)s %(message)-30s" + }, + "custom": { + "format": "%(asctime)-15s %(levelname)s %(name)s %(message)s" + } + }, + "root": { + "handlers": [ + "console" + ], + "level": "ERROR" + }, + "version": 1, + "loggers": { + "moon": { + "handlers": [ + "console", + "file" + ], + "propagate": False, + "level": "DEBUG" + } + } + }, + "slave": { + "name": None, + "master": { + "url": None, + "login": None, + "password": None + } + }, + "docker": { + "url": "tcp://172.88.88.1:2376", + "network": "moon" + }, + "database": { + "url": "sqlite:///database.db", + # "url": "mysql+pymysql://moon:p4sswOrd1@db/moon", + "driver": "sql" + }, + "messenger": { + "url": "rabbit://moon:p4sswOrd1@messenger:5672/moon" + } +} + + +CONTEXT = { + "project_id": "a64beb1cc224474fb4badd43173e7101", + "subject_name": "testuser", + "object_name": "vm1", + "action_name": "boot", + "request_id": uuid4().hex, + "interface_name": "interface", + "manager_url": "http://{}:{}".format( + CONF["components"]["manager"]["hostname"], + CONF["components"]["manager"]["port"] + ), + "cookie": uuid4().hex, + "pdp_id": "b3d3e18abf3340e8b635fd49e6634ccd", + "security_pipeline": ["f8f49a779ceb47b3ac810f01ef71b4e0"] + } + + +COMPONENTS = ( + "logging", + "openstack/keystone", + "database", + "slave", + "components/manager", + "components/orchestrator", + "components/pipeline", + + "components/wrapper", +) + + +def get_b64_conf(component=None): + if component == "components": + return base64.b64encode( + json.dumps(CONF["components"]).encode('utf-8')+b"\n").decode('utf-8') + elif component in CONF: + return base64.b64encode( + json.dumps( + CONF[component]).encode('utf-8')+b"\n").decode('utf-8') + elif not component: + return base64.b64encode( + json.dumps(CONF).encode('utf-8')+b"\n").decode('utf-8') + elif "/" in component: + key1, _, key2 = component.partition("/") + return base64.b64encode( + json.dumps( + CONF[key1][key2]).encode('utf-8')+b"\n").decode('utf-8') + + +def get_json(data): + return json.loads(data.decode("utf-8")) + + diff --git a/old/moon_bouchon/Dockerfile b/old/moon_bouchon/Dockerfile new file mode 100644 index 00000000..ed013935 --- /dev/null +++ b/old/moon_bouchon/Dockerfile @@ -0,0 +1,8 @@ +FROM python:3 + +ADD . /root +RUN pip install -r /root/requirements.txt --upgrade +WORKDIR /root +RUN pip install . + +CMD ["python", "-m", "moon_bouchon"] \ No newline at end of file diff --git a/old/moon_bouchon/README.md b/old/moon_bouchon/README.md new file mode 100644 index 00000000..11733cef --- /dev/null +++ b/old/moon_bouchon/README.md @@ -0,0 +1,42 @@ +#Moon Bouchon + +Moon_bouchon is a fake interface to the Moon platform. +Moon platform can be requested through 2 interfaces: + +- ''wrapper'', interface for the OpenStack platform +- ''interface'', interface for other components + +## Usage: + +### server + +To start the server: + + docker run -ti -p 31002:31002 wukongsun/moon_bouchon:v1.0 + # or docker run -dti -p 31002:31002 wukongsun/moon_bouchon:v1.0 + +### wrapper + +Here are the URL, you can request: + + POST /wrapper/authz/grant to request the wrapper component with always a "True" response + POST /wrapper/authz/deny to request the wrapper component with always a "False" response + POST /wrapper/authz to request the wrapper component with always a "True" or "False" response + +In each request you must pass the following data (or similar): + + {'rule': 'start', 'target': '{"target": {"name": "vm0"}, "user_id": "user0"}', 'credentials': 'null'} + +You have examples in the moon_bouchon/tests directory. + +### interface + +Here are the URL, you can request: + + GET /interface/authz/grant//// to request the interface component with always a "True" response + GET /interface/authz/deny//// to request the interface component with always a "False" response + GET /interface/authz//// to request the interface component with always a "True" or "False" response + +You have examples in the moon_bouchon/tests directory. + + diff --git a/old/moon_bouchon/moon_bouchon/__init__.py b/old/moon_bouchon/moon_bouchon/__init__.py new file mode 100644 index 00000000..8811d91d --- /dev/null +++ b/old/moon_bouchon/moon_bouchon/__init__.py @@ -0,0 +1,7 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + + +__version__ = "1.1" diff --git a/old/moon_bouchon/moon_bouchon/__main__.py b/old/moon_bouchon/moon_bouchon/__main__.py new file mode 100644 index 00000000..4499a96b --- /dev/null +++ b/old/moon_bouchon/moon_bouchon/__main__.py @@ -0,0 +1,9 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + + +import moon_bouchon.server + +moon_bouchon.server.main() diff --git a/old/moon_bouchon/moon_bouchon/server.py b/old/moon_bouchon/moon_bouchon/server.py new file mode 100644 index 00000000..29e9101e --- /dev/null +++ b/old/moon_bouchon/moon_bouchon/server.py @@ -0,0 +1,138 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +import sys +import flask +from flask import Flask +from flask import request +import json +import logging +import random + +logger = logging.getLogger(__name__) +app = Flask(__name__) + + +@app.route("/interface/authz/grant///" + "/", + methods=["GET"]) +def interface_grant(project_id, subject_name, object_name, action_name): + logger.info("Requesting interface authz on {} {} {} {}".format( + project_id, subject_name, object_name, action_name)) + return json.dumps({ + "result": True, + "context": { + "project_id": project_id, + "subject_name": subject_name, + "object_name": object_name, + "action_name": action_name + } + }) + + +@app.route("/interface/authz/deny///" + "/", + methods=["GET"]) +def interface_deny(project_id, subject_name, object_name, action_name): + logger.info("Requesting interface authz on {} {} {} {}".format( + project_id, subject_name, object_name, action_name)) + return json.dumps({ + "result": False, + "context": { + "project_id": project_id, + "subject_name": subject_name, + "object_name": object_name, + "action_name": action_name + } + }) + + +@app.route("/interface/authz///" + "/", + methods=["GET"]) +def interface_authz(project_id, subject_name, object_name, action_name): + logger.info("Requesting interface authz on {} {} {} {}".format( + project_id, subject_name, object_name, action_name)) + return json.dumps({ + "result": random.choice((True, False)), + "context": { + "project_id": project_id, + "subject_name": subject_name, + "object_name": object_name, + "action_name": action_name + } + }) + + +def test_data(): + data = request.form + if not dict(request.form): + data = json.loads(request.data.decode("utf-8")) + try: + target = json.loads(data.get('target', {})) + except Exception: + raise Exception("Error reading target") + try: + credentials = json.loads(data.get('credentials', {})) + except Exception: + raise Exception("Error reading credentials") + try: + rule = data.get('rule', "") + except Exception: + raise Exception("Error reading rule") + + +@app.route("/wrapper/authz/grant", methods=["POST"]) +def wrapper_grant(): + logger.info("Requesting wrapper authz") + try: + test_data() + except Exception as e: + logger.exception(e) + return str(e), 400 + response = flask.make_response("True") + response.headers['content-type'] = 'application/octet-stream' + return response + + +@app.route("/wrapper/authz/deny", methods=["POST"]) +def wrapper_deny(): + logger.info("Requesting wrapper authz") + try: + test_data() + except Exception as e: + logger.exception(e) + return str(e), 400 + response = flask.make_response("False") + response.headers['content-type'] = 'application/octet-stream' + return response + + +@app.route("/wrapper/authz", methods=["POST"]) +def wrapper_authz(): + logger.info("Requesting wrapper authz") + try: + test_data() + except Exception as e: + logger.exception(e) + return str(e), 400 + response = flask.make_response(random.choice(("True", "False"))) + response.headers['content-type'] = 'application/octet-stream' + return response + + +def main(): + port = 31002 + if len(sys.argv) > 1: + try: + port = int(sys.argv[1]) + except ValueError: + logger.error("Argument for Port in command line is not an integer") + sys.exit(1) + app.run(host="0.0.0.0", port=port) + + +if __name__ == "__main__": + main() diff --git a/old/moon_bouchon/requirements.txt b/old/moon_bouchon/requirements.txt new file mode 100644 index 00000000..8ab6294c --- /dev/null +++ b/old/moon_bouchon/requirements.txt @@ -0,0 +1 @@ +flask \ No newline at end of file diff --git a/old/moon_bouchon/setup.cfg b/old/moon_bouchon/setup.cfg new file mode 100644 index 00000000..7c2b2874 --- /dev/null +++ b/old/moon_bouchon/setup.cfg @@ -0,0 +1,2 @@ +[bdist_wheel] +universal = 1 \ No newline at end of file diff --git a/old/moon_bouchon/setup.py b/old/moon_bouchon/setup.py new file mode 100644 index 00000000..a875be40 --- /dev/null +++ b/old/moon_bouchon/setup.py @@ -0,0 +1,47 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +from setuptools import setup, find_packages +import moon_bouchon + + +setup( + + name='moon_bouchon', + + version=moon_bouchon.__version__, + + packages=find_packages(), + + author="Thomas Duval", + + author_email="thomas.duval@orange.com", + + description="", + + long_description=open('README.md').read(), + + install_requires=["flask"], + + include_package_data=True, + + url='https://git.opnfv.org/cgit/moon', + + classifiers=[ + "Programming Language :: Python", + "Development Status :: 1 - Planning", + "License :: OSI Approved", + "Natural Language :: French", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3", + ], + + entry_points={ + 'console_scripts': [ + 'moon_bouchon = moon_bouchon.server:main', + ], + } + +) diff --git a/old/moon_bouchon/tests/test_interface.py b/old/moon_bouchon/tests/test_interface.py new file mode 100644 index 00000000..425ba2e5 --- /dev/null +++ b/old/moon_bouchon/tests/test_interface.py @@ -0,0 +1,61 @@ +import requests +from uuid import uuid4 +import pytest + + +@pytest.fixture +def args(): + return { + "project_id": uuid4().hex, + "subject_id": uuid4().hex, + "object_id": uuid4().hex, + "action_id": uuid4().hex + } + + +def test_false(args): + url = "http://127.0.0.1:31002/interface/authz/deny/{project_id}" \ + "/{subject_id}/{object_id}/{action_id}".format(**args) + data = {'rule': 'start', + 'target': '{"target": {"name": "vm0"}, "user_id": "user0"}', + 'credentials': 'null'} + req = requests.get( + url, json=data, + headers={'content-type': "application/x-www-form-urlencode"} + ) + assert req.status_code == 200 + assert "result" in req.json() + assert req.json()["result"] == False + + +def test_true(args): + url = "http://127.0.0.1:31002/interface/authz/grant/{project_id}" \ + "/{subject_id}/{object_id}/{action_id}".format(**args) + + data = {'rule': 'start', + 'target': '{"target": {"name": "vm0"}, "user_id": "user0"}', + 'credentials': 'null'} + req = requests.get( + url, json=data, + headers={'content-type': "application/x-www-form-urlencode"} + ) + assert req.status_code == 200 + assert "result" in req.json() + assert req.json()["result"] == True + + +def test_random(args): + url = "http://127.0.0.1:31002/interface/authz/{project_id}" \ + "/{subject_id}/{object_id}/{action_id}".format(**args) + + data = {'rule': 'start', + 'target': '{"target": {"name": "vm0"}, "user_id": "user0"}', + 'credentials': 'null'} + req = requests.get( + url, json=data, + headers={'content-type': "application/x-www-form-urlencode"} + ) + assert req.status_code == 200 + assert "result" in req.json() + assert req.json()["result"] in (False, True) + diff --git a/old/moon_bouchon/tests/test_wrapper.py b/old/moon_bouchon/tests/test_wrapper.py new file mode 100644 index 00000000..3d5e150c --- /dev/null +++ b/old/moon_bouchon/tests/test_wrapper.py @@ -0,0 +1,38 @@ +import requests + + +def test_false(): + url = "http://127.0.0.1:31002/wrapper/authz/deny" + + data = {'rule': 'start', 'target': '{"target": {"name": "vm0"}, "user_id": "user0"}', 'credentials': 'null'} + req = requests.post( + url, json=data, + headers={'content-type': "application/x-www-form-urlencode"} + ) + assert req.status_code == 200 + assert req.text == "False" + + +def test_true(): + url = "http://127.0.0.1:31002/wrapper/authz/grant" + + data = {'rule': 'start', 'target': '{"target": {"name": "vm0"}, "user_id": "user0"}', 'credentials': 'null'} + req = requests.post( + url, json=data, + headers={'content-type': "application/x-www-form-urlencode"} + ) + assert req.status_code == 200 + assert req.text == "True" + + +def test_random(): + url = "http://127.0.0.1:31002/wrapper/authz" + + data = {'rule': 'start', 'target': '{"target": {"name": "vm0"}, "user_id": "user0"}', 'credentials': 'null'} + req = requests.post( + url, json=data, + headers={'content-type': "application/x-www-form-urlencode"} + ) + assert req.status_code == 200 + assert req.text in ("False", "True") + diff --git a/old/moon_dashboard/.gitignore b/old/moon_dashboard/.gitignore new file mode 100644 index 00000000..61f2dc9f --- /dev/null +++ b/old/moon_dashboard/.gitignore @@ -0,0 +1 @@ +**/__pycache__/ diff --git a/old/moon_dashboard/.gitlab-ci.yml b/old/moon_dashboard/.gitlab-ci.yml new file mode 100644 index 00000000..50fd8a4e --- /dev/null +++ b/old/moon_dashboard/.gitlab-ci.yml @@ -0,0 +1,64 @@ +stages: + - lint + - build + - test + - publish + +variables: + http_proxy: "http://devwatt-proxy.si.fr.intraorange:8080" + https_proxy: "http://devwatt-proxy.si.fr.intraorange:8080" + no_proxy: dind, gitlab.forge.orange-labs.fr + DOCKER_DRIVER: overlay + DOCKER_HOST: tcp://dind:2375 + CONTAINER_RELEASE_IMAGE: moonplatform/$CI_PROJECT_NAME + CONTAINER_TAG: dev + DOCKER_VERSION: "17.12" + +services: + - name: dockerproxy-iva.si.francetelecom.fr/docker:$DOCKER_VERSION-dind + alias: dind +image: dockerproxy-iva.si.francetelecom.fr/docker:$DOCKER_VERSION + +lint-job: + image: dockerfactory-iva.si.francetelecom.fr/docker/orange-dockerfile-lint:0.2.7-alpine3.6-2 + tags: + - rsc + - docker + - shared + stage: lint + script: + - dockerfile_lint -f Dockerfile + +build-job: + stage: build + tags: + - rsc + - docker-privileged + script: + - docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD + - docker build -t $CONTAINER_RELEASE_IMAGE:$CONTAINER_TAG --build-arg http_proxy=$http_proxy --build-arg https_proxy=$http_proxy . + - docker push $CONTAINER_RELEASE_IMAGE:$CONTAINER_TAG + +test-job: + stage: test + tags: + - rsc + - docker-privileged + script: + - docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD + - docker run -e http_proxy=$http_proxy -e https_proxy=$http_proxy $CONTAINER_RELEASE_IMAGE:$CONTAINER_TAG curl http://localhost:8000 + +publish-job: + stage: publish + tags: + - rsc + - docker-privileged + script: + - docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD + - FINAL_TAG=$(grep version setup.cfg | cut -d "=" -f 2) + - echo FINAL_TAG=$FINAL_TAG + - docker pull $CONTAINER_RELEASE_IMAGE:$CONTAINER_TAG + - docker tag $CONTAINER_RELEASE_IMAGE:$CONTAINER_TAG $CONTAINER_RELEASE_IMAGE:$FINAL_TAG + - docker push $CONTAINER_RELEASE_IMAGE:$FINAL_TAG + only: + - master diff --git a/old/moon_dashboard/Dockerfile b/old/moon_dashboard/Dockerfile new file mode 100644 index 00000000..790a2b21 --- /dev/null +++ b/old/moon_dashboard/Dockerfile @@ -0,0 +1,38 @@ +FROM python:3.5 + +LABEL Name=Dashboard +LABEL Description="User interface for the Moon platform" +LABEL Maintainer="Thomas Duval" +LABEL Url="https://wiki.opnfv.org/display/moon/Moon+Project+Proposal" + +ENV MANAGER_HOST="127.0.0.1" +ENV MANAGER_PORT=30001 +ENV KEYSTONE_HOST="127.0.0.1" +ENV KEYSTONE_PORT=5000 +ENV OPENSTACK_HOST="127.0.0.1" +ENV OPENSTACK_KEYSTONE_URL="http://${KEYSTONE_HOST}:${KEYSTONE_PORT}/identity/v3" +ENV SERVER_IP_ADDR="0.0.0.0" + +USER root + +WORKDIR /root/ +ADD . /root + +RUN [ -d horizon ] || git clone https://git.openstack.org/openstack/horizon + +WORKDIR /root/horizon + +# RUN pip install --no-cache-dir pip +RUN pip install --no-cache-dir -c http://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt . + +RUN cp openstack_dashboard/local/local_settings.py.example openstack_dashboard/local/local_settings.py +RUN pip install --no-cache-dir tox + +WORKDIR /root/ + +RUN cp -v moon/enabled/_32000_moon.py horizon/openstack_dashboard/local/enabled/_32000_moon.py +RUN cp -rv moon/ horizon/openstack_dashboard/dashboards/ + +EXPOSE 8000 + +CMD ["/bin/sh", "/root/run.sh"] \ No newline at end of file diff --git a/old/moon_dashboard/LICENSE b/old/moon_dashboard/LICENSE new file mode 100644 index 00000000..e69de29b diff --git a/old/moon_dashboard/MANIFEST.in b/old/moon_dashboard/MANIFEST.in new file mode 100644 index 00000000..1f077b06 --- /dev/null +++ b/old/moon_dashboard/MANIFEST.in @@ -0,0 +1,3 @@ +include setup.py + +recursive-include myplugin *.js *.html *.scss \ No newline at end of file diff --git a/old/moon_dashboard/README.md b/old/moon_dashboard/README.md new file mode 100644 index 00000000..fca52b2d --- /dev/null +++ b/old/moon_dashboard/README.md @@ -0,0 +1,40 @@ +# Moon plugin for Horizon (OpenStack Dashboard) + +## Install Horizon + +https://docs.openstack.org/horizon/latest/install/index.html + +or for developper quick start: + +https://docs.openstack.org/horizon/latest/contributor/quickstart.html + + +## Moon plugin + +Clone the plugin: + +```bash +git clone https://gitlab.forge.orange-labs.fr/moon/dashboard.git +``` + +* ``$plugin`` is the location of moon plugin +* ``$horizon`` is the location of horizon + +Make symbolic link to enabled file: + +```bash +ln -s $plugin/moon/enabled/_32000_moon.py $horizon/openstack_dashboard/local/enabled/_32000_moon.py +``` + +Make symbolic link to dashboard folder: + +```bash +ln -s $plugin/moon/ $horizon/openstack_dashboard/dashboards/moon +``` + +Finish by restarting the Horizon server. + +## Set Moon API endpoint + +Set the endpoint in $plugin/moon/moon/static/moon/js/moon.module.js file + diff --git a/old/moon_dashboard/README.rst b/old/moon_dashboard/README.rst new file mode 100644 index 00000000..de9c4058 --- /dev/null +++ b/old/moon_dashboard/README.rst @@ -0,0 +1,39 @@ +============================================= +Moon plugin for Horizon (OpenStack Dashboard) +============================================= + +Install Horizon +=============== + +https://docs.openstack.org/horizon/latest/install/index.html + +or for developper quick start: + +https://docs.openstack.org/horizon/latest/contributor/quickstart.html + + +Moon plugin +=========== + +Clone the plugin: + +"git clone https://gitlab.forge.orange-labs.fr/moon/dashboard.git" + +* ``plugin`` is the location of moon plugin +* ``horizon`` is the location of horizon + +Make symbolic link to enabled file: + +"ln -s ``plugin`̀`/moon/enabled/_32000_moon.py ``horizon``/openstack_dashboard/local/enabled/_32000_moon.py" + +Make symbolic link to dashboard folder: + +"ln -s ``plugin`̀`/moon/ ``horizon``/openstack_dashboard/dashboards/moon" + +Finish by restarting the Horizon server. + + +Set Moon API endpoint +=========== + +Set the endpoint in ``plugin``/moon/moon/static/moon/js/moon.module.js file \ No newline at end of file diff --git a/old/moon_dashboard/babel-django.cfg b/old/moon_dashboard/babel-django.cfg new file mode 100644 index 00000000..fa906ad8 --- /dev/null +++ b/old/moon_dashboard/babel-django.cfg @@ -0,0 +1,5 @@ +[extractors] +django = django_babel.extract:extract_django + +[python: **.py] +[django: **/templates/**.html] \ No newline at end of file diff --git a/old/moon_dashboard/babel-djangojs.cfg b/old/moon_dashboard/babel-djangojs.cfg new file mode 100644 index 00000000..1c07ba6a --- /dev/null +++ b/old/moon_dashboard/babel-djangojs.cfg @@ -0,0 +1,14 @@ +[extractors] +# We use a custom extractor to find translatable strings in AngularJS +# templates. The extractor is included in horizon.utils for now. +# See http://babel.pocoo.org/docs/messages/#referencing-extraction-methods for +# details on how this works. +angular = horizon.utils.babel_extract_angular:extract_angular + +[javascript: **.js] + +# We need to look into all static folders for HTML files. +# The **/static ensures that we also search within +# /openstack_dashboard/dashboards/XYZ/static which will ensure +# that plugins are also translated. +[angular: **/static/**.html] \ No newline at end of file diff --git a/old/moon_dashboard/moon/__init__.py b/old/moon_dashboard/moon/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/old/moon_dashboard/moon/api/__init__.py b/old/moon_dashboard/moon/api/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/old/moon_dashboard/moon/api/moon_api.py b/old/moon_dashboard/moon/api/moon_api.py new file mode 100644 index 00000000..e69de29b diff --git a/old/moon_dashboard/moon/dashboard.py b/old/moon_dashboard/moon/dashboard.py new file mode 100644 index 00000000..0e3e491e --- /dev/null +++ b/old/moon_dashboard/moon/dashboard.py @@ -0,0 +1,13 @@ +from django.utils.translation import ugettext_lazy as _ + +import horizon + + +class Moon(horizon.Dashboard): + name = _("Moon") + slug = "moon" + panels = ('model','policy','pdp',) # Add your panels here. + default_panel = 'model' # Specify the slug of the default panel. + + +horizon.register(Moon) diff --git a/old/moon_dashboard/moon/enabled/_32000_moon.py b/old/moon_dashboard/moon/enabled/_32000_moon.py new file mode 100644 index 00000000..73198de6 --- /dev/null +++ b/old/moon_dashboard/moon/enabled/_32000_moon.py @@ -0,0 +1,19 @@ +# The name of the dashboard to be added to HORIZON['dashboards']. Required. +DASHBOARD = 'moon' + +# If set to True, this dashboard will not be added to the settings. +DISABLED = False + +# A list of AngularJS modules to be loaded when Angular bootstraps. +ADD_ANGULAR_MODULES = ['moon'] + +# Automatically discover static resources in installed apps +AUTO_DISCOVER_STATIC_FILES = True + +# A list of applications to be added to INSTALLED_APPS. +ADD_INSTALLED_APPS = [ + 'openstack_dashboard.dashboards.moon', +] + +# A list of scss files to be included in the compressed set of files +ADD_SCSS_FILES = ['moon/scss/moon.scss'] diff --git a/old/moon_dashboard/moon/model/__init__.py b/old/moon_dashboard/moon/model/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/old/moon_dashboard/moon/model/panel.py b/old/moon_dashboard/moon/model/panel.py new file mode 100644 index 00000000..9cb65ef0 --- /dev/null +++ b/old/moon_dashboard/moon/model/panel.py @@ -0,0 +1,23 @@ +# 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. + +from django.utils.translation import ugettext_lazy as _ + +import horizon +from openstack_dashboard.dashboards.moon import dashboard + +class Model(horizon.Panel): + name = _("Models") + slug = "model" + + +dashboard.Moon.register(Model) diff --git a/old/moon_dashboard/moon/model/templates/model/index.html b/old/moon_dashboard/moon/model/templates/model/index.html new file mode 100644 index 00000000..db372a02 --- /dev/null +++ b/old/moon_dashboard/moon/model/templates/model/index.html @@ -0,0 +1,16 @@ +{% extends 'base.html' %} +{% load i18n %} +{% block title %}{% trans "Models" %}{% endblock %} + +{% block page_header %} + {% include "horizon/common/_page_header.html" with title=_("Models") %} +{% endblock page_header %} + + + +{% block main %} + + +{% endblock %} + diff --git a/old/moon_dashboard/moon/model/tests.py b/old/moon_dashboard/moon/model/tests.py new file mode 100644 index 00000000..ec988636 --- /dev/null +++ b/old/moon_dashboard/moon/model/tests.py @@ -0,0 +1,19 @@ +# 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. + +from horizon.test import helpers as test + + +class MypanelTests(test.TestCase): + # Unit tests for mypanel. + def test_me(self): + self.assertTrue(1 + 1 == 2) diff --git a/old/moon_dashboard/moon/model/urls.py b/old/moon_dashboard/moon/model/urls.py new file mode 100644 index 00000000..ca9507fb --- /dev/null +++ b/old/moon_dashboard/moon/model/urls.py @@ -0,0 +1,20 @@ +# 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. + +from django.conf.urls import url + +from openstack_dashboard.dashboards.moon.model import views + + +urlpatterns = [ + url(r'^$', views.IndexView.as_view(), name='index'), +] diff --git a/old/moon_dashboard/moon/model/views.py b/old/moon_dashboard/moon/model/views.py new file mode 100644 index 00000000..73509537 --- /dev/null +++ b/old/moon_dashboard/moon/model/views.py @@ -0,0 +1,22 @@ +# 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. + +from horizon import views + + +class IndexView(views.APIView): + # A very simple class-based view... + template_name = 'moon/model/index.html' + + def get_data(self, request, context, *args, **kwargs): + # Add data to the context here... + return context diff --git a/old/moon_dashboard/moon/pdp/__init__.py b/old/moon_dashboard/moon/pdp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/old/moon_dashboard/moon/pdp/panel.py b/old/moon_dashboard/moon/pdp/panel.py new file mode 100644 index 00000000..9c4b3fa3 --- /dev/null +++ b/old/moon_dashboard/moon/pdp/panel.py @@ -0,0 +1,23 @@ +# 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. + +from django.utils.translation import ugettext_lazy as _ + +import horizon +from openstack_dashboard.dashboards.moon import dashboard + +class Pdp(horizon.Panel): + name = _("PDP") + slug = "pdp" + + +dashboard.Moon.register(Pdp) diff --git a/old/moon_dashboard/moon/pdp/templates/pdp/index.html b/old/moon_dashboard/moon/pdp/templates/pdp/index.html new file mode 100644 index 00000000..30ac5f93 --- /dev/null +++ b/old/moon_dashboard/moon/pdp/templates/pdp/index.html @@ -0,0 +1,16 @@ +{% extends 'base.html' %} +{% load i18n %} +{% block title %}{% trans "PDP" %}{% endblock %} + +{% block page_header %} + {% include "horizon/common/_page_header.html" with title=_("PDP") %} +{% endblock page_header %} + + + +{% block main %} + + +{% endblock %} + diff --git a/old/moon_dashboard/moon/pdp/tests.py b/old/moon_dashboard/moon/pdp/tests.py new file mode 100644 index 00000000..ec988636 --- /dev/null +++ b/old/moon_dashboard/moon/pdp/tests.py @@ -0,0 +1,19 @@ +# 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. + +from horizon.test import helpers as test + + +class MypanelTests(test.TestCase): + # Unit tests for mypanel. + def test_me(self): + self.assertTrue(1 + 1 == 2) diff --git a/old/moon_dashboard/moon/pdp/urls.py b/old/moon_dashboard/moon/pdp/urls.py new file mode 100644 index 00000000..a66c8e0c --- /dev/null +++ b/old/moon_dashboard/moon/pdp/urls.py @@ -0,0 +1,20 @@ +# 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. + +from django.conf.urls import url + +from openstack_dashboard.dashboards.moon.pdp import views + + +urlpatterns = [ + url(r'^$', views.IndexView.as_view(), name='index'), +] diff --git a/old/moon_dashboard/moon/pdp/views.py b/old/moon_dashboard/moon/pdp/views.py new file mode 100644 index 00000000..8355a5d5 --- /dev/null +++ b/old/moon_dashboard/moon/pdp/views.py @@ -0,0 +1,22 @@ +# 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. + +from horizon import views + + +class IndexView(views.APIView): + # A very simple class-based view... + template_name = 'moon/pdp/index.html' + + def get_data(self, request, context, *args, **kwargs): + # Add data to the context here... + return context diff --git a/old/moon_dashboard/moon/policy/__init__.py b/old/moon_dashboard/moon/policy/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/old/moon_dashboard/moon/policy/panel.py b/old/moon_dashboard/moon/policy/panel.py new file mode 100644 index 00000000..875a2d76 --- /dev/null +++ b/old/moon_dashboard/moon/policy/panel.py @@ -0,0 +1,23 @@ +# 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. + +from django.utils.translation import ugettext_lazy as _ + +import horizon +from openstack_dashboard.dashboards.moon import dashboard + +class Policy(horizon.Panel): + name = _("Policies") + slug = "policy" + + +dashboard.Moon.register(Policy) diff --git a/old/moon_dashboard/moon/policy/templates/policy/index.html b/old/moon_dashboard/moon/policy/templates/policy/index.html new file mode 100644 index 00000000..67cd9c3d --- /dev/null +++ b/old/moon_dashboard/moon/policy/templates/policy/index.html @@ -0,0 +1,16 @@ +{% extends 'base.html' %} +{% load i18n %} +{% block title %}{% trans "Policies" %}{% endblock %} + +{% block page_header %} + {% include "horizon/common/_page_header.html" with title=_("Policies") %} +{% endblock page_header %} + + + +{% block main %} + + +{% endblock %} + diff --git a/old/moon_dashboard/moon/policy/tests.py b/old/moon_dashboard/moon/policy/tests.py new file mode 100644 index 00000000..ec988636 --- /dev/null +++ b/old/moon_dashboard/moon/policy/tests.py @@ -0,0 +1,19 @@ +# 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. + +from horizon.test import helpers as test + + +class MypanelTests(test.TestCase): + # Unit tests for mypanel. + def test_me(self): + self.assertTrue(1 + 1 == 2) diff --git a/old/moon_dashboard/moon/policy/urls.py b/old/moon_dashboard/moon/policy/urls.py new file mode 100644 index 00000000..81bde0ca --- /dev/null +++ b/old/moon_dashboard/moon/policy/urls.py @@ -0,0 +1,20 @@ +# 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. + +from django.conf.urls import url + +from openstack_dashboard.dashboards.moon.policy import views + + +urlpatterns = [ + url(r'^$', views.IndexView.as_view(), name='index'), +] diff --git a/old/moon_dashboard/moon/policy/views.py b/old/moon_dashboard/moon/policy/views.py new file mode 100644 index 00000000..826c833b --- /dev/null +++ b/old/moon_dashboard/moon/policy/views.py @@ -0,0 +1,22 @@ +# 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. + +from horizon import views + + +class IndexView(views.APIView): + # A very simple class-based view... + template_name = 'moon/policy/index.html' + + def get_data(self, request, context, *args, **kwargs): + # Add data to the context here... + return context diff --git a/old/moon_dashboard/moon/static/moon/js/angular-resource.js b/old/moon_dashboard/moon/static/moon/js/angular-resource.js new file mode 100644 index 00000000..e8bb3014 --- /dev/null +++ b/old/moon_dashboard/moon/static/moon/js/angular-resource.js @@ -0,0 +1,863 @@ +/** + * @license AngularJS v1.5.8 + * (c) 2010-2016 Google, Inc. http://angularjs.org + * License: MIT + */ +(function(window, angular) {'use strict'; + +var $resourceMinErr = angular.$$minErr('$resource'); + +// Helper functions and regex to lookup a dotted path on an object +// stopping at undefined/null. The path must be composed of ASCII +// identifiers (just like $parse) +var MEMBER_NAME_REGEX = /^(\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/; + +function isValidDottedPath(path) { + return (path != null && path !== '' && path !== 'hasOwnProperty' && + MEMBER_NAME_REGEX.test('.' + path)); +} + +function lookupDottedPath(obj, path) { + if (!isValidDottedPath(path)) { + throw $resourceMinErr('badmember', 'Dotted member path "@{0}" is invalid.', path); + } + var keys = path.split('.'); + for (var i = 0, ii = keys.length; i < ii && angular.isDefined(obj); i++) { + var key = keys[i]; + obj = (obj !== null) ? obj[key] : undefined; + } + return obj; +} + +/** + * Create a shallow copy of an object and clear other fields from the destination + */ +function shallowClearAndCopy(src, dst) { + dst = dst || {}; + + angular.forEach(dst, function(value, key) { + delete dst[key]; + }); + + for (var key in src) { + if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) { + dst[key] = src[key]; + } + } + + return dst; +} + +/** + * @ngdoc module + * @name ngResource + * @description + * + * # ngResource + * + * The `ngResource` module provides interaction support with RESTful services + * via the $resource service. + * + * + *
+ * + * See {@link ngResource.$resourceProvider} and {@link ngResource.$resource} for usage. + */ + +/** + * @ngdoc provider + * @name $resourceProvider + * + * @description + * + * Use `$resourceProvider` to change the default behavior of the {@link ngResource.$resource} + * service. + * + * ## Dependencies + * Requires the {@link ngResource } module to be installed. + * + */ + +/** + * @ngdoc service + * @name $resource + * @requires $http + * @requires ng.$log + * @requires $q + * @requires ng.$timeout + * + * @description + * A factory which creates a resource object that lets you interact with + * [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) server-side data sources. + * + * The returned resource object has action methods which provide high-level behaviors without + * the need to interact with the low level {@link ng.$http $http} service. + * + * Requires the {@link ngResource `ngResource`} module to be installed. + * + * By default, trailing slashes will be stripped from the calculated URLs, + * which can pose problems with server backends that do not expect that + * behavior. This can be disabled by configuring the `$resourceProvider` like + * this: + * + * ```js + app.config(['$resourceProvider', function($resourceProvider) { + // Don't strip trailing slashes from calculated URLs + $resourceProvider.defaults.stripTrailingSlashes = false; + }]); + * ``` + * + * @param {string} url A parameterized URL template with parameters prefixed by `:` as in + * `/user/:username`. If you are using a URL with a port number (e.g. + * `http://example.com:8080/api`), it will be respected. + * + * If you are using a url with a suffix, just add the suffix, like this: + * `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')` + * or even `$resource('http://example.com/resource/:resource_id.:format')` + * If the parameter before the suffix is empty, :resource_id in this case, then the `/.` will be + * collapsed down to a single `.`. If you need this sequence to appear and not collapse then you + * can escape it with `/\.`. + * + * @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in + * `actions` methods. If a parameter value is a function, it will be called every time + * a param value needs to be obtained for a request (unless the param was overridden). The function + * will be passed the current data value as an argument. + * + * Each key value in the parameter object is first bound to url template if present and then any + * excess keys are appended to the url search query after the `?`. + * + * Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in + * URL `/path/greet?salutation=Hello`. + * + * If the parameter value is prefixed with `@`, then the value for that parameter will be + * extracted from the corresponding property on the `data` object (provided when calling a + * "non-GET" action method). + * For example, if the `defaultParam` object is `{someParam: '@someProp'}` then the value of + * `someParam` will be `data.someProp`. + * Note that the parameter will be ignored, when calling a "GET" action method (i.e. an action + * method that does not accept a request body) + * + * @param {Object.=} actions Hash with declaration of custom actions that should extend + * the default set of resource actions. The declaration should be created in the format of {@link + * ng.$http#usage $http.config}: + * + * {action1: {method:?, params:?, isArray:?, headers:?, ...}, + * action2: {method:?, params:?, isArray:?, headers:?, ...}, + * ...} + * + * Where: + * + * - **`action`** – {string} – The name of action. This name becomes the name of the method on + * your resource object. + * - **`method`** – {string} – Case insensitive HTTP method (e.g. `GET`, `POST`, `PUT`, + * `DELETE`, `JSONP`, etc). + * - **`params`** – {Object=} – Optional set of pre-bound parameters for this action. If any of + * the parameter value is a function, it will be called every time when a param value needs to + * be obtained for a request (unless the param was overridden). The function will be passed the + * current data value as an argument. + * - **`url`** – {string} – action specific `url` override. The url templating is supported just + * like for the resource-level urls. + * - **`isArray`** – {boolean=} – If true then the returned object for this action is an array, + * see `returns` section. + * - **`transformRequest`** – + * `{function(data, headersGetter)|Array.}` – + * transform function or an array of such functions. The transform function takes the http + * request body and headers and returns its transformed (typically serialized) version. + * By default, transformRequest will contain one function that checks if the request data is + * an object and serializes to using `angular.toJson`. To prevent this behavior, set + * `transformRequest` to an empty array: `transformRequest: []` + * - **`transformResponse`** – + * `{function(data, headersGetter)|Array.}` – + * transform function or an array of such functions. The transform function takes the http + * response body and headers and returns its transformed (typically deserialized) version. + * By default, transformResponse will contain one function that checks if the response looks + * like a JSON string and deserializes it using `angular.fromJson`. To prevent this behavior, + * set `transformResponse` to an empty array: `transformResponse: []` + * - **`cache`** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the + * GET request, otherwise if a cache instance built with + * {@link ng.$cacheFactory $cacheFactory}, this cache will be used for + * caching. + * - **`timeout`** – `{number}` – timeout in milliseconds.
+ * **Note:** In contrast to {@link ng.$http#usage $http.config}, {@link ng.$q promises} are + * **not** supported in $resource, because the same value would be used for multiple requests. + * If you are looking for a way to cancel requests, you should use the `cancellable` option. + * - **`cancellable`** – `{boolean}` – if set to true, the request made by a "non-instance" call + * will be cancelled (if not already completed) by calling `$cancelRequest()` on the call's + * return value. Calling `$cancelRequest()` for a non-cancellable or an already + * completed/cancelled request will have no effect.
+ * - **`withCredentials`** - `{boolean}` - whether to set the `withCredentials` flag on the + * XHR object. See + * [requests with credentials](https://developer.mozilla.org/en/http_access_control#section_5) + * for more information. + * - **`responseType`** - `{string}` - see + * [requestType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType). + * - **`interceptor`** - `{Object=}` - The interceptor object has two optional methods - + * `response` and `responseError`. Both `response` and `responseError` interceptors get called + * with `http response` object. See {@link ng.$http $http interceptors}. + * + * @param {Object} options Hash with custom settings that should extend the + * default `$resourceProvider` behavior. The supported options are: + * + * - **`stripTrailingSlashes`** – {boolean} – If true then the trailing + * slashes from any calculated URL will be stripped. (Defaults to true.) + * - **`cancellable`** – {boolean} – If true, the request made by a "non-instance" call will be + * cancelled (if not already completed) by calling `$cancelRequest()` on the call's return value. + * This can be overwritten per action. (Defaults to false.) + * + * @returns {Object} A resource "class" object with methods for the default set of resource actions + * optionally extended with custom `actions`. The default set contains these actions: + * ```js + * { 'get': {method:'GET'}, + * 'save': {method:'POST'}, + * 'query': {method:'GET', isArray:true}, + * 'remove': {method:'DELETE'}, + * 'delete': {method:'DELETE'} }; + * ``` + * + * Calling these methods invoke an {@link ng.$http} with the specified http method, + * destination and parameters. When the data is returned from the server then the object is an + * instance of the resource class. The actions `save`, `remove` and `delete` are available on it + * as methods with the `$` prefix. This allows you to easily perform CRUD operations (create, + * read, update, delete) on server-side data like this: + * ```js + * var User = $resource('/user/:userId', {userId:'@id'}); + * var user = User.get({userId:123}, function() { + * user.abc = true; + * user.$save(); + * }); + * ``` + * + * It is important to realize that invoking a $resource object method immediately returns an + * empty reference (object or array depending on `isArray`). Once the data is returned from the + * server the existing reference is populated with the actual data. This is a useful trick since + * usually the resource is assigned to a model which is then rendered by the view. Having an empty + * object results in no rendering, once the data arrives from the server then the object is + * populated with the data and the view automatically re-renders itself showing the new data. This + * means that in most cases one never has to write a callback function for the action methods. + * + * The action methods on the class object or instance object can be invoked with the following + * parameters: + * + * - HTTP GET "class" actions: `Resource.action([parameters], [success], [error])` + * - non-GET "class" actions: `Resource.action([parameters], postData, [success], [error])` + * - non-GET instance actions: `instance.$action([parameters], [success], [error])` + * + * + * Success callback is called with (value, responseHeaders) arguments, where the value is + * the populated resource instance or collection object. The error callback is called + * with (httpResponse) argument. + * + * Class actions return empty instance (with additional properties below). + * Instance actions return promise of the action. + * + * The Resource instances and collections have these additional properties: + * + * - `$promise`: the {@link ng.$q promise} of the original server interaction that created this + * instance or collection. + * + * On success, the promise is resolved with the same resource instance or collection object, + * updated with data from server. This makes it easy to use in + * {@link ngRoute.$routeProvider resolve section of $routeProvider.when()} to defer view + * rendering until the resource(s) are loaded. + * + * On failure, the promise is rejected with the {@link ng.$http http response} object, without + * the `resource` property. + * + * If an interceptor object was provided, the promise will instead be resolved with the value + * returned by the interceptor. + * + * - `$resolved`: `true` after first server interaction is completed (either with success or + * rejection), `false` before that. Knowing if the Resource has been resolved is useful in + * data-binding. + * + * The Resource instances and collections have these additional methods: + * + * - `$cancelRequest`: If there is a cancellable, pending request related to the instance or + * collection, calling this method will abort the request. + * + * The Resource instances have these additional methods: + * + * - `toJSON`: It returns a simple object without any of the extra properties added as part of + * the Resource API. This object can be serialized through {@link angular.toJson} safely + * without attaching Angular-specific fields. Notice that `JSON.stringify` (and + * `angular.toJson`) automatically use this method when serializing a Resource instance + * (see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior)). + * + * @example + * + * # Credit card resource + * + * ```js + // Define CreditCard class + var CreditCard = $resource('/user/:userId/card/:cardId', + {userId:123, cardId:'@id'}, { + charge: {method:'POST', params:{charge:true}} + }); + + // We can retrieve a collection from the server + var cards = CreditCard.query(function() { + // GET: /user/123/card + // server returns: [ {id:456, number:'1234', name:'Smith'} ]; + + var card = cards[0]; + // each item is an instance of CreditCard + expect(card instanceof CreditCard).toEqual(true); + card.name = "J. Smith"; + // non GET methods are mapped onto the instances + card.$save(); + // POST: /user/123/card/456 {id:456, number:'1234', name:'J. Smith'} + // server returns: {id:456, number:'1234', name: 'J. Smith'}; + + // our custom method is mapped as well. + card.$charge({amount:9.99}); + // POST: /user/123/card/456?amount=9.99&charge=true {id:456, number:'1234', name:'J. Smith'} + }); + + // we can create an instance as well + var newCard = new CreditCard({number:'0123'}); + newCard.name = "Mike Smith"; + newCard.$save(); + // POST: /user/123/card {number:'0123', name:'Mike Smith'} + // server returns: {id:789, number:'0123', name: 'Mike Smith'}; + expect(newCard.id).toEqual(789); + * ``` + * + * The object returned from this function execution is a resource "class" which has "static" method + * for each action in the definition. + * + * Calling these methods invoke `$http` on the `url` template with the given `method`, `params` and + * `headers`. + * + * @example + * + * # User resource + * + * When the data is returned from the server then the object is an instance of the resource type and + * all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD + * operations (create, read, update, delete) on server-side data. + + ```js + var User = $resource('/user/:userId', {userId:'@id'}); + User.get({userId:123}, function(user) { + user.abc = true; + user.$save(); + }); + ``` + * + * It's worth noting that the success callback for `get`, `query` and other methods gets passed + * in the response that came from the server as well as $http header getter function, so one + * could rewrite the above example and get access to http headers as: + * + ```js + var User = $resource('/user/:userId', {userId:'@id'}); + User.get({userId:123}, function(user, getResponseHeaders){ + user.abc = true; + user.$save(function(user, putResponseHeaders) { + //user => saved user object + //putResponseHeaders => $http header getter + }); + }); + ``` + * + * You can also access the raw `$http` promise via the `$promise` property on the object returned + * + ``` + var User = $resource('/user/:userId', {userId:'@id'}); + User.get({userId:123}) + .$promise.then(function(user) { + $scope.user = user; + }); + ``` + * + * @example + * + * # Creating a custom 'PUT' request + * + * In this example we create a custom method on our resource to make a PUT request + * ```js + * var app = angular.module('app', ['ngResource', 'ngRoute']); + * + * // Some APIs expect a PUT request in the format URL/object/ID + * // Here we are creating an 'update' method + * app.factory('Notes', ['$resource', function($resource) { + * return $resource('/notes/:id', null, + * { + * 'update': { method:'PUT' } + * }); + * }]); + * + * // In our controller we get the ID from the URL using ngRoute and $routeParams + * // We pass in $routeParams and our Notes factory along with $scope + * app.controller('NotesCtrl', ['$scope', '$routeParams', 'Notes', + function($scope, $routeParams, Notes) { + * // First get a note object from the factory + * var note = Notes.get({ id:$routeParams.id }); + * $id = note.id; + * + * // Now call update passing in the ID first then the object you are updating + * Notes.update({ id:$id }, note); + * + * // This will PUT /notes/ID with the note object in the request payload + * }]); + * ``` + * + * @example + * + * # Cancelling requests + * + * If an action's configuration specifies that it is cancellable, you can cancel the request related + * to an instance or collection (as long as it is a result of a "non-instance" call): + * + ```js + // ...defining the `Hotel` resource... + var Hotel = $resource('/api/hotel/:id', {id: '@id'}, { + // Let's make the `query()` method cancellable + query: {method: 'get', isArray: true, cancellable: true} + }); + + // ...somewhere in the PlanVacationController... + ... + this.onDestinationChanged = function onDestinationChanged(destination) { + // We don't care about any pending request for hotels + // in a different destination any more + this.availableHotels.$cancelRequest(); + + // Let's query for hotels in '' + // (calls: /api/hotel?location=) + this.availableHotels = Hotel.query({location: destination}); + }; + ``` + * + */ +angular.module('ngResource', ['ng']). + provider('$resource', function() { + var PROTOCOL_AND_DOMAIN_REGEX = /^https?:\/\/[^\/]*/; + var provider = this; + + /** + * @ngdoc property + * @name $resourceProvider#defaults + * @description + * Object containing default options used when creating `$resource` instances. + * + * The default values satisfy a wide range of usecases, but you may choose to overwrite any of + * them to further customize your instances. The available properties are: + * + * - **stripTrailingSlashes** – `{boolean}` – If true, then the trailing slashes from any + * calculated URL will be stripped.
+ * (Defaults to true.) + * - **cancellable** – `{boolean}` – If true, the request made by a "non-instance" call will be + * cancelled (if not already completed) by calling `$cancelRequest()` on the call's return + * value. For more details, see {@link ngResource.$resource}. This can be overwritten per + * resource class or action.
+ * (Defaults to false.) + * - **actions** - `{Object.}` - A hash with default actions declarations. Actions are + * high-level methods corresponding to RESTful actions/methods on resources. An action may + * specify what HTTP method to use, what URL to hit, if the return value will be a single + * object or a collection (array) of objects etc. For more details, see + * {@link ngResource.$resource}. The actions can also be enhanced or overwritten per resource + * class.
+ * The default actions are: + * ```js + * { + * get: {method: 'GET'}, + * save: {method: 'POST'}, + * query: {method: 'GET', isArray: true}, + * remove: {method: 'DELETE'}, + * delete: {method: 'DELETE'} + * } + * ``` + * + * #### Example + * + * For example, you can specify a new `update` action that uses the `PUT` HTTP verb: + * + * ```js + * angular. + * module('myApp'). + * config(['resourceProvider', function ($resourceProvider) { + * $resourceProvider.defaults.actions.update = { + * method: 'PUT' + * }; + * }); + * ``` + * + * Or you can even overwrite the whole `actions` list and specify your own: + * + * ```js + * angular. + * module('myApp'). + * config(['resourceProvider', function ($resourceProvider) { + * $resourceProvider.defaults.actions = { + * create: {method: 'POST'} + * get: {method: 'GET'}, + * getAll: {method: 'GET', isArray:true}, + * update: {method: 'PUT'}, + * delete: {method: 'DELETE'} + * }; + * }); + * ``` + * + */ + this.defaults = { + // Strip slashes by default + stripTrailingSlashes: true, + + // Make non-instance requests cancellable (via `$cancelRequest()`) + cancellable: false, + + // Default actions configuration + actions: { + 'get': {method: 'GET'}, + 'save': {method: 'POST'}, + 'query': {method: 'GET', isArray: true}, + 'remove': {method: 'DELETE'}, + 'delete': {method: 'DELETE'} + } + }; + + this.$get = ['$http', '$log', '$q', '$timeout', function($http, $log, $q, $timeout) { + + var noop = angular.noop, + forEach = angular.forEach, + extend = angular.extend, + copy = angular.copy, + isFunction = angular.isFunction; + + /** + * We need our custom method because encodeURIComponent is too aggressive and doesn't follow + * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set + * (pchar) allowed in path segments: + * segment = *pchar + * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + * pct-encoded = "%" HEXDIG HEXDIG + * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + * / "*" / "+" / "," / ";" / "=" + */ + function encodeUriSegment(val) { + return encodeUriQuery(val, true). + replace(/%26/gi, '&'). + replace(/%3D/gi, '='). + replace(/%2B/gi, '+'); + } + + + /** + * This method is intended for encoding *key* or *value* parts of query component. We need a + * custom method because encodeURIComponent is too aggressive and encodes stuff that doesn't + * have to be encoded per http://tools.ietf.org/html/rfc3986: + * query = *( pchar / "/" / "?" ) + * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + * pct-encoded = "%" HEXDIG HEXDIG + * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + * / "*" / "+" / "," / ";" / "=" + */ + function encodeUriQuery(val, pctEncodeSpaces) { + return encodeURIComponent(val). + replace(/%40/gi, '@'). + replace(/%3A/gi, ':'). + replace(/%24/g, '$'). + replace(/%2C/gi, ','). + replace(/%20/g, (pctEncodeSpaces ? '%20' : '+')); + } + + function Route(template, defaults) { + this.template = template; + this.defaults = extend({}, provider.defaults, defaults); + this.urlParams = {}; + } + + Route.prototype = { + setUrlParams: function(config, params, actionUrl) { + var self = this, + url = actionUrl || self.template, + val, + encodedVal, + protocolAndDomain = ''; + + var urlParams = self.urlParams = {}; + forEach(url.split(/\W/), function(param) { + if (param === 'hasOwnProperty') { + throw $resourceMinErr('badname', "hasOwnProperty is not a valid parameter name."); + } + if (!(new RegExp("^\\d+$").test(param)) && param && + (new RegExp("(^|[^\\\\]):" + param + "(\\W|$)").test(url))) { + urlParams[param] = { + isQueryParamValue: (new RegExp("\\?.*=:" + param + "(?:\\W|$)")).test(url) + }; + } + }); + url = url.replace(/\\:/g, ':'); + url = url.replace(PROTOCOL_AND_DOMAIN_REGEX, function(match) { + protocolAndDomain = match; + return ''; + }); + + params = params || {}; + forEach(self.urlParams, function(paramInfo, urlParam) { + val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam]; + if (angular.isDefined(val) && val !== null) { + if (paramInfo.isQueryParamValue) { + encodedVal = encodeUriQuery(val, true); + } else { + encodedVal = encodeUriSegment(val); + } + url = url.replace(new RegExp(":" + urlParam + "(\\W|$)", "g"), function(match, p1) { + return encodedVal + p1; + }); + } else { + url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W|$)", "g"), function(match, + leadingSlashes, tail) { + if (tail.charAt(0) == '/') { + return tail; + } else { + return leadingSlashes + tail; + } + }); + } + }); + + // strip trailing slashes and set the url (unless this behavior is specifically disabled) + if (self.defaults.stripTrailingSlashes) { + url = url.replace(/\/+$/, '') || '/'; + } + + // then replace collapse `/.` if found in the last URL path segment before the query + // E.g. `http://url.com/id./format?q=x` becomes `http://url.com/id.format?q=x` + url = url.replace(/\/\.(?=\w+($|\?))/, '.'); + // replace escaped `/\.` with `/.` + config.url = protocolAndDomain + url.replace(/\/\\\./, '/.'); + + + // set params - delegate param encoding to $http + forEach(params, function(value, key) { + if (!self.urlParams[key]) { + config.params = config.params || {}; + config.params[key] = value; + } + }); + } + }; + + + function resourceFactory(url, paramDefaults, actions, options) { + var route = new Route(url, options); + + actions = extend({}, provider.defaults.actions, actions); + + function extractParams(data, actionParams) { + var ids = {}; + actionParams = extend({}, paramDefaults, actionParams); + forEach(actionParams, function(value, key) { + if (isFunction(value)) { value = value(data); } + ids[key] = value && value.charAt && value.charAt(0) == '@' ? + lookupDottedPath(data, value.substr(1)) : value; + }); + return ids; + } + + function defaultResponseInterceptor(response) { + return response.resource; + } + + function Resource(value) { + shallowClearAndCopy(value || {}, this); + } + + Resource.prototype.toJSON = function() { + var data = extend({}, this); + delete data.$promise; + delete data.$resolved; + return data; + }; + + forEach(actions, function(action, name) { + var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method); + var numericTimeout = action.timeout; + var cancellable = angular.isDefined(action.cancellable) ? action.cancellable : + (options && angular.isDefined(options.cancellable)) ? options.cancellable : + provider.defaults.cancellable; + + if (numericTimeout && !angular.isNumber(numericTimeout)) { + $log.debug('ngResource:\n' + + ' Only numeric values are allowed as `timeout`.\n' + + ' Promises are not supported in $resource, because the same value would ' + + 'be used for multiple requests. If you are looking for a way to cancel ' + + 'requests, you should use the `cancellable` option.'); + delete action.timeout; + numericTimeout = null; + } + + Resource[name] = function(a1, a2, a3, a4) { + var params = {}, data, success, error; + + /* jshint -W086 */ /* (purposefully fall through case statements) */ + switch (arguments.length) { + case 4: + error = a4; + success = a3; + //fallthrough + case 3: + case 2: + if (isFunction(a2)) { + if (isFunction(a1)) { + success = a1; + error = a2; + break; + } + + success = a2; + error = a3; + //fallthrough + } else { + params = a1; + data = a2; + success = a3; + break; + } + case 1: + if (isFunction(a1)) success = a1; + else if (hasBody) data = a1; + else params = a1; + break; + case 0: break; + default: + throw $resourceMinErr('badargs', + "Expected up to 4 arguments [params, data, success, error], got {0} arguments", + arguments.length); + } + /* jshint +W086 */ /* (purposefully fall through case statements) */ + + var isInstanceCall = this instanceof Resource; + var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data)); + var httpConfig = {}; + var responseInterceptor = action.interceptor && action.interceptor.response || + defaultResponseInterceptor; + var responseErrorInterceptor = action.interceptor && action.interceptor.responseError || + undefined; + var timeoutDeferred; + var numericTimeoutPromise; + + forEach(action, function(value, key) { + switch (key) { + default: + httpConfig[key] = copy(value); + break; + case 'params': + case 'isArray': + case 'interceptor': + case 'cancellable': + break; + } + }); + + if (!isInstanceCall && cancellable) { + timeoutDeferred = $q.defer(); + httpConfig.timeout = timeoutDeferred.promise; + + if (numericTimeout) { + numericTimeoutPromise = $timeout(timeoutDeferred.resolve, numericTimeout); + } + } + + if (hasBody) httpConfig.data = data; + route.setUrlParams(httpConfig, + extend({}, extractParams(data, action.params || {}), params), + action.url); + + var promise = $http(httpConfig).then(function(response) { + var data = response.data; + + if (data) { + // Need to convert action.isArray to boolean in case it is undefined + // jshint -W018 + if (angular.isArray(data) !== (!!action.isArray)) { + throw $resourceMinErr('badcfg', + 'Error in resource configuration for action `{0}`. Expected response to ' + + 'contain an {1} but got an {2} (Request: {3} {4})', name, action.isArray ? 'array' : 'object', + angular.isArray(data) ? 'array' : 'object', httpConfig.method, httpConfig.url); + } + // jshint +W018 + if (action.isArray) { + value.length = 0; + forEach(data, function(item) { + if (typeof item === "object") { + value.push(new Resource(item)); + } else { + // Valid JSON values may be string literals, and these should not be converted + // into objects. These items will not have access to the Resource prototype + // methods, but unfortunately there + value.push(item); + } + }); + } else { + var promise = value.$promise; // Save the promise + shallowClearAndCopy(data, value); + value.$promise = promise; // Restore the promise + } + } + response.resource = value; + + return response; + }, function(response) { + (error || noop)(response); + return $q.reject(response); + }); + + promise['finally'](function() { + value.$resolved = true; + if (!isInstanceCall && cancellable) { + value.$cancelRequest = angular.noop; + $timeout.cancel(numericTimeoutPromise); + timeoutDeferred = numericTimeoutPromise = httpConfig.timeout = null; + } + }); + + promise = promise.then( + function(response) { + var value = responseInterceptor(response); + (success || noop)(value, response.headers); + return value; + }, + responseErrorInterceptor); + + if (!isInstanceCall) { + // we are creating instance / collection + // - set the initial promise + // - return the instance / collection + value.$promise = promise; + value.$resolved = false; + if (cancellable) value.$cancelRequest = timeoutDeferred.resolve; + + return value; + } + + // instance call + return promise; + }; + + + Resource.prototype['$' + name] = function(params, success, error) { + if (isFunction(params)) { + error = success; success = params; params = {}; + } + var result = Resource[name].call(this, params, this, success, error); + return result.$promise || result; + }; + }); + + Resource.bind = function(additionalParamDefaults) { + return resourceFactory(url, extend({}, paramDefaults, additionalParamDefaults), actions); + }; + + return Resource; + } + + return resourceFactory; + }]; + }); + + +})(window, window.angular); diff --git a/old/moon_dashboard/moon/static/moon/js/import.service.js b/old/moon_dashboard/moon/static/moon/js/import.service.js new file mode 100755 index 00000000..d55c8a19 --- /dev/null +++ b/old/moon_dashboard/moon/static/moon/js/import.service.js @@ -0,0 +1,27 @@ +(function () { + + 'use strict'; + + angular + .module('moon') + .factory('moon.import.service', importService); + + importService.$inject = ['moon.util.service', '$resource', 'moon.URI']; + + function importService(util, $resource, URI) { + var host = URI.API; + var importResource = $resource(host + '/import/', {}, { + create: { method: 'POST' }, + }); + + return { + importData: function importData(data) { + return importResource.create(null, data).$promise.then(success, util.displayErrorFunction('Unable to import data')); + + function success(data) { + util.displaySuccess('Data imported'); + } + } + } + } +})(); \ No newline at end of file diff --git a/old/moon_dashboard/moon/static/moon/js/moon.module.js b/old/moon_dashboard/moon/static/moon/js/moon.module.js new file mode 100755 index 00000000..c8b86439 --- /dev/null +++ b/old/moon_dashboard/moon/static/moon/js/moon.module.js @@ -0,0 +1,29 @@ +/** +# 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', + ]).constant('moon.URI', { + API: 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}', + }) + +})(); diff --git a/old/moon_dashboard/moon/static/moon/js/util.service.js b/old/moon_dashboard/moon/static/moon/js/util.service.js new file mode 100755 index 00000000..29680a43 --- /dev/null +++ b/old/moon_dashboard/moon/static/moon/js/util.service.js @@ -0,0 +1,140 @@ +(function () { + + 'use strict'; + + angular + .module('moon') + .factory('moon.util.service', utilService); + + utilService.$inject = ['horizon.framework.widgets.toast.service']; + + function utilService(toast) { + + + return { + mapToArray: function mapToArray(map, action) { + var result = [] + for (var key in map) { + if (map.hasOwnProperty(key)) { + var item = map[key]; + item.id = key; + if (action != null) { + action(item); + } + result.push(item); + } + } + return result; + }, + + mapIdToItem: function mapIdToItem(array, map) { + if (array) { + for (var index = 0; index < array.length; index++) { + var id = array[index]; + array[index] = map[id]; + } + } + }, + + mapItemToId: function mapItemToId(array) { + if (array) { + for (var index = 0; index < array.length; index++) { + var item = array[index]; + array[index] = item.id; + } + } + }, + + addToMap: function addToMap(array, map) { + if (array) { + for (var index = 0; index < array.length; index++) { + var item = array[index]; + map[item.id] = item; + } + } + }, + + updateObject: function updateObject(object, newObject) { + for (var key in newObject) { + if (newObject.hasOwnProperty(key)) { + object[key] = newObject[key]; + } + } + }, + + cleanObject: function cleanObject(object) { + for (var key in object) { + if (object.hasOwnProperty(key)) { + delete object[key]; + } + } + }, + + pushAll: function pushAll(array, arrayToPush) { + Array.prototype.push.apply(array, arrayToPush); + }, + + indexOf: function indexOf(array, property, value) { + for (var i = 0; i < array.length; i += 1) { + if (array[i][property] === value) { + return i; + } + } + return -1; + }, + + createInternal: function createInternal(data, array, map, action) { + var added = this.mapToArray(data, action) + this.addToMap(added, map); + this.pushAll(array, added); + return added; + }, + + updateInternal: function updateInternal(data, map, action) { + var updated = this.mapToArray(data, action) + var result = [] + for (var index = 0; index < updated.length; index++) { + var item = updated[index]; + this.updateObject(map[item.id], item) + result.push(map[item.id]) + } + return result; + }, + + removeInternal: function removeInternal(id, array, map) { + var old = map[id]; + delete map[old.id]; + array.splice(array.indexOf(old), 1); + return old; + }, + + arrayToTitleMap: function arrayToTitleMap(array) { + return array.map(function (item) { + return { value: item.id, name: item.name } + }).sort(function (itemA, itemB) { + return itemA.name.localeCompare(itemB.name); + }) + }, + + displayErrorFunction: function displayErrorFunction(message) { + return function(response) { + var text = gettext(message); + if (response && response.data && response.data.message) { + text += ' (' + response.data.message + ')' + } + toast.add('error', text); + } + }, + + displaySuccess: function displaySuccess(message) { + toast.add('success', gettext(message)); + }, + + displayError: function displayError(message) { + toast.add('error', gettext(message)); + }, + + } + + } +})(); \ No newline at end of file diff --git a/old/moon_dashboard/moon/static/moon/js/util.service.spec.js b/old/moon_dashboard/moon/static/moon/js/util.service.spec.js new file mode 100755 index 00000000..d8e3ed31 --- /dev/null +++ b/old/moon_dashboard/moon/static/moon/js/util.service.spec.js @@ -0,0 +1,86 @@ +(function () { + 'use strict'; + + describe('moon.util.service', function () { + var service; + + beforeEach(module('horizon.app.core')); + beforeEach(module('horizon.framework')); + beforeEach(module('moon')); + + beforeEach(inject(function ($injector) { + service = $injector.get('moon.util.service'); + })); + + it('should push all', function () { + var a1 = [0, 1, 2]; + var a2 = [3, 4]; + service.pushAll(a1, a2) + + expect(a1.length).toBe(5); + expect(a1).toEqual([0, 1, 2, 3, 4]); + }); + + it('should index of', function () { + var a = [{ name: 'n0' }, { name: 'n1' }, { name: 'n2' }]; + var result = service.indexOf(a, 'name', 'n1'); + + expect(result).toBe(1); + }); + + it('should map to array', function () { + var map = { "a": { name: "a" }, "b": { name: "b" } }; + var result = service.mapToArray(map); + + expect(result.length).toBe(2); + }); + + it('should map ID to item', function () { + var map = { "a": { name: "a" }, "b": { name: "b" } }; + var array = ["a", "b"]; + service.mapIdToItem(array, map); + + expect(array.length).toBe(2); + expect(array[0].name).toBe("a"); + expect(array[1].name).toBe("b"); + }); + + it('should map item to ID', function () { + var array = [{ id: "a" }, { id: "b" }]; + service.mapItemToId(array); + + expect(array.length).toBe(2); + expect(array[0]).toBe("a"); + expect(array[1]).toBe("b"); + }); + + it('should add to map', function () { + var map = { "a": { name: "a" }, "b": { name: "b" } }; + var array = [{ id: "c" }]; + service.addToMap(array, map); + + expect(map.c).toEqual({ id: "c" }); + }); + + it('should update object', function () { + var object = { a: 1, b: "test" }; + var update = { a: 2, c: "test2" }; + service.updateObject(object, update); + + expect(object.a).toBe(2); + expect(object.b).toBe("test"); + expect(object.c).toBe("test2"); + }); + + it('should clean object', function () { + var object = { a: 1, b: "test" }; + service.cleanObject(object); + + expect(object.a).not.toBeDefined(); + expect(object.b).not.toBeDefined(); + expect(object).toEqual({}); + }); + }); + + +})(); \ No newline at end of file diff --git a/old/moon_dashboard/moon/static/moon/model/model.controller.js b/old/moon_dashboard/moon/static/moon/model/model.controller.js new file mode 100644 index 00000000..99a7c7ed --- /dev/null +++ b/old/moon_dashboard/moon/static/moon/model/model.controller.js @@ -0,0 +1,316 @@ +(function () { + 'use strict'; + + angular + .module('moon') + .directive('onReadFile', directive) + .controller('moon.model.controller', controller); + + controller.$inject = ['moon.util.service', 'moon.model.service', 'moon.import.service', 'horizon.framework.widgets.form.ModalFormService']; + + directive.$inject = ['$parse']; + + function directive($parse) { + return { + restrict: 'A', + scope: false, + link: function (scope, element, attrs) { + element.bind('change', function (e) { + + var onFileRead = $parse(attrs.onReadFile); + var reader = new FileReader(); + + reader.onload = function () { + var fileContents = reader.result; + scope.$apply(function () { + onFileRead(scope, { + 'contents': fileContents + }); + }); + }; + reader.readAsText(element[0].files[0]); + }); + } + }; + } + + var categoryMap = { + 'subject': { + addTitle: 'Add Subject Category', + removeTitleFromMetaRule: 'Are you sure to remove from meta rule this Subject Category?', + removeTitle: 'Are you sure to remove this Subject Category?', + listName: 'subject_categories', + serviceListName: 'subjectCategories' + }, + 'object': { + addTitle: 'Add Object Category', + removeTitleFromMetaRule: 'Are you sure to remove from meta rule this Object Category?', + removeTitle: 'Are you sure to remove this Object Category?', + listName: 'object_categories', + serviceListName: 'objectCategories' + }, + 'action': { + addTitle: 'Add Action Category', + removeTitleFromMetaRule: 'Are you sure to remove from meta rule this Action Category?', + removeTitle: 'Are you sure to remove this Action Category?', + listName: 'action_categories', + serviceListName: 'actionCategories' + }, + } + + function controller(util, modelService, importService, ModalFormService) { + var self = this; + self.model = modelService; + self.showOrphan = false; + modelService.initialize(); + + self.importData = function importData(text) { + horizon.modals.modal_spinner(gettext("Loading")) + importService.importData(JSON.parse(text)).then(function () { + modelService.initialize(); + horizon.modals.spinner.modal('hide'); + }) + } + + self.createModel = function createModel() { + var schema = { + type: "object", + properties: { + name: { type: "string", minLength: 2, title: gettext("Name") }, + description: { type: "string", minLength: 2, title: gettext("Description") } + }, + required: ['name', 'description'] + }; + var model = { name: '', description: '' }; + var config = { + title: gettext('Create Model'), + schema: schema, + form: ['name', { key: 'description', type: 'textarea' }], + model: model + }; + ModalFormService.open(config).then(submit); + + function submit(form) { + modelService.createModel(form.model); + } + } + + self.updateModel = function updateModel(model) { + var schema = { + type: "object", + properties: { + name: { type: "string", minLength: 2, title: gettext("Name") }, + description: { type: "string", minLength: 2, title: gettext("Description") } + }, + required: ['name', 'description'] + }; + var config = { + title: gettext('Update Model'), + schema: schema, + form: ['name', { key: 'description', type: 'textarea' }], + model: angular.copy(model) + }; + ModalFormService.open(config).then(submit); + + function submit(form) { + modelService.updateModel(form.model); + } + } + + self.removeModel = function removeModel(model) { + if (confirm(gettext('Are you sure to delete this Model?'))) + modelService.removeModel(model); + } + + self.createMetaRuleFunction = function createMetaRuleFunction(model, titleMap) { + return function () { + var schema = { + type: "object", + properties: { + name: { type: "string", minLength: 2, title: gettext("Name") }, + description: { type: "string", minLength: 2, title: gettext("Description") }, + }, + required: ['name', 'description'] + }; + var metaRule = { name: '', description: '' }; + var config = { + title: gettext('Create Meta Rule'), + schema: schema, + form: [ + 'name', + { key: 'description', type: 'textarea' } + ], + model: metaRule + }; + ModalFormService.open(config).then(submit); + + function submit(form) { + modelService.createMetaRule(form.model).then(function (metaRule) { + titleMap.push({ value: metaRule.id, name: metaRule.name }) + model.id = metaRule.id + }) + } + } + } + + self.addMetaRule = function addMetaRule(model) { + var schema = { + type: "object", + properties: { + id: { type: "string", title: gettext("Select a Meta Rule:") } + }, + required: ['id'] + }; + var titleMap = util.arrayToTitleMap(modelService.metaRules) + var formModel = { id: null } + var config = { + title: gettext('Add Meta Rule'), + schema: schema, + form: [ + { key: 'id', type: 'select', titleMap: titleMap }, + { + key: 'createButton', + type: 'button', + title: gettext('Create Meta Rule'), + icon: 'fa fa-plus', + onClick: self.createMetaRuleFunction(formModel, titleMap) + } + ], + model: formModel + }; + if (modelService.metaRules.length == 1) { + formModel.id = modelService.metaRules[0].id + } + + ModalFormService.open(config).then(submit); + + function submit(form) { + var metaRule = modelService.getMetaRule(form.model.id); + var modelCopy = angular.copy(model); + modelCopy.meta_rules.push(metaRule); + modelService.updateModel(modelCopy); + } + } + + self.updateMetaRule = function updateMetaRule(metaRule) { + var schema = { + type: "object", + properties: { + name: { type: "string", minLength: 2, title: gettext("Name") }, + description: { type: "string", minLength: 2, title: gettext("Description") } + }, + required: ['name', 'description'] + }; + var metaRuleCopy = angular.copy(metaRule); + var config = { + title: gettext('Update Meta Rule'), + schema: schema, + form: ['name', { key: 'description', type: 'textarea' }], + model: metaRuleCopy + }; + ModalFormService.open(config).then(submit); + + function submit(form) { + modelService.updateMetaRule(form.model); + } + } + + self.removeMetaRuleFromModel = function removeMetaRuleFromModel(model, metaRule) { + if (confirm(gettext('Are you sure to remove this Meta Rule from model?'))) { + var modelCopy = angular.copy(model); + modelCopy.meta_rules.splice(model.meta_rules.indexOf(metaRule), 1); + modelService.updateModel(modelCopy); + } + } + + self.removeMetaRule = function removeMetaRule(metaRule) { + if (confirm(gettext('Are you sure to remove this Meta Rule?'))) { + modelService.removeMetaRule(metaRule); + } + } + + self.createCategoryFunction = function createCategoryFunction(type, formModel, titleMap) { + return function () { + var schema = { + type: "object", + properties: { + name: { type: "string", minLength: 2, title: gettext("Name") }, + description: { type: "string", minLength: 2, title: gettext("Description") }, + }, + required: ['name', 'description'] + }; + var metaRule = { name: '', description: '' }; + var config = { + title: gettext('Create Category'), + schema: schema, + form: [ + 'name', + { key: 'description', type: 'textarea' } + ], + model: metaRule + }; + ModalFormService.open(config).then(submit); + + function submit(form) { + modelService.createCategory(type, form.model).then(function (category) { + titleMap.push({ value: category.id, name: category.name }) + formModel.id = category.id + }) + } + } + } + + self.addCategory = function addCategory(type, metaRule) { + var typeValue = categoryMap[type]; + var schema = { + type: "object", + properties: { + id: { type: "string", title: gettext("Select a Category:") } + }, + required: ['id'] + }; + var titleMap = util.arrayToTitleMap(modelService[typeValue.serviceListName]) + var formModel = { id: null } + var config = { + title: gettext(typeValue.addTitle), + schema: schema, + form: [ + { key: 'id', type: 'select', titleMap: titleMap }, + { + key: 'createButton', + type: 'button', + title: gettext('Create Category'), + icon: 'fa fa-plus', + onClick: self.createCategoryFunction(type, formModel, titleMap) + }], + model: formModel + }; + ModalFormService.open(config).then(submit); + + function submit(form) { + var category = modelService.getCategory(type, form.model.id); + var metaRuleCopy = angular.copy(metaRule); + metaRuleCopy[typeValue.listName].push(category); + modelService.updateMetaRule(metaRuleCopy) + } + } + + self.removeCategoryFromMetaRule = function removeCategoryFromMetaRule(type, metaRule, category) { + var typeValue = categoryMap[type]; + if (confirm(gettext(typeValue.removeTitleFromMetaRule))) { + var metaRuleCopy = angular.copy(metaRule); + metaRuleCopy[typeValue.listName].splice(metaRule[typeValue.listName].indexOf(category), 1); + modelService.updateMetaRule(metaRuleCopy); + } + } + + self.removeCategory = function removeCategory(type, category) { + var typeValue = categoryMap[type]; + if (confirm(gettext(typeValue.removeTitle))) { + modelService.removeCategory(type, category); + } + } + + + } +})(); \ No newline at end of file diff --git a/old/moon_dashboard/moon/static/moon/model/model.html b/old/moon_dashboard/moon/static/moon/model/model.html new file mode 100644 index 00000000..97f08910 --- /dev/null +++ b/old/moon_dashboard/moon/static/moon/model/model.html @@ -0,0 +1,139 @@ +
+
+ +

Warning!

+

+ Some metarules or categories are orphan, please check them and delete them if necessary. + Show orphans + Hide orphans +

+
+ +
+
+

Orphan Meta rules

+
+

{$ metaRule.name $}

+ +

{$ metaRule.description $}

+
+
+ +
+

Orphan Subject categories

+
+

{$ subject.name $}

+ +

{$ subject.description $}

+
+
+ +
+

Orphan Object categories

+
+

{$ object.name $}

+ +

{$ object.description $}

+
+
+ +
+

Orphan Action categories

+
+

{$ action.name $}

+ +

{$ action.description $}

+
+
+
+ +
+
+ + + + +
+
+ + +
+
+

{$ model.name $}

+
+ + +
+

{$ model.description $}

+
+ +

{$ model.meta_rules.length $} + meta rule(s) +

+ +
+
+
+

{$ metaRule.name $}

+
+ + +
+

{$ metaRule.description $}

+

+ + + + + + + + + + + + + + + +
+ Subjects + + + Objects + + + Actions + +
+

+ {$ category.name $} + +

+
+

+ {$ category.name $} + +

+
+

+ {$ category.name $} + +

+
+

+
+
+
+
+
+
\ No newline at end of file diff --git a/old/moon_dashboard/moon/static/moon/model/model.service.js b/old/moon_dashboard/moon/static/moon/model/model.service.js new file mode 100755 index 00000000..986eb6b1 --- /dev/null +++ b/old/moon_dashboard/moon/static/moon/model/model.service.js @@ -0,0 +1,291 @@ +(function () { + + 'use strict'; + + angular + .module('moon') + .factory('moon.model.service', modelService); + + modelService.$inject = ['moon.util.service', '$resource', 'moon.URI', '$q']; + + function modelService(util, $resource, URI, $q) { + var host = URI.API; + var modelResource = $resource(host + '/models/' + ':id', {}, { + get: { method: 'GET' }, + query: { method: 'GET' }, + create: { method: 'POST' }, + remove: { method: 'DELETE' }, + update: { method: 'PATCH' } + }); + + var metaRuleResource = $resource(host + '/meta_rules/' + ':id', {}, { + query: { method: 'GET' }, + get: { method: 'GET' }, + update: { method: 'PATCH' }, + create: { method: 'POST' }, + remove: { method: 'DELETE' } + }); + + var subjectCategoryResource = $resource(host + '/subject_categories/' + ':id', {}, { + query: { method: 'GET' }, + get: { method: 'GET' }, + create: { method: 'POST' }, + remove: { method: 'DELETE' } + }); + + var objectCategoryResource = $resource(host + '/object_categories/' + ':id', {}, { + query: { method: 'GET' }, + get: { method: 'GET' }, + create: { method: 'POST' }, + remove: { method: 'DELETE' } + }); + + var actionCategoryResource = $resource(host + '/action_categories/' + ':id', {}, { + query: { method: 'GET' }, + get: { method: 'GET' }, + create: { method: 'POST' }, + remove: { method: 'DELETE' } + }); + + var modelsMap = {}; + var metaRulesMap = {}; + var subjectCategoriesMap = {}; + var objectCategoriesMap = {}; + var actionCategoriesMap = {}; + var models = []; + var metaRules = []; + var orphanMetaRules = []; + var subjectCategories = []; + var objectCategories = []; + var actionCategories = []; + var orphanSubjectCategories = []; + var orphanObjectCategories = []; + var orphanActionCategories = []; + + var categoryMap = { + 'subject': { + resource: subjectCategoryResource, + map: subjectCategoriesMap, + list: subjectCategories, + listName: 'subject_categories' + }, + 'object': { + resource: objectCategoryResource, + map: objectCategoriesMap, + list: objectCategories, + listName: 'object_categories' + }, + 'action': { + resource: actionCategoryResource, + map: actionCategoriesMap, + list: actionCategories, + listName: 'action_categories' + } + } + + function loadModels() { + var queries = { + subjectCategories: subjectCategoryResource.query().$promise, + objectCategories: objectCategoryResource.query().$promise, + actionCategories: actionCategoryResource.query().$promise, + metaRules: metaRuleResource.query().$promise, + models: modelResource.query().$promise, + } + + var result = $q.all(queries).then(function (result) { + createModels(result.models, result.metaRules, result.subjectCategories, result.objectCategories, result.actionCategories) + console.log('moon', 'models initialized') + }) + + return result; + } + + function createModels(modelsData, metarulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData) { + util.cleanObject(modelsMap); + util.cleanObject(metaRulesMap); + util.cleanObject(subjectCategoriesMap); + util.cleanObject(objectCategoriesMap); + util.cleanObject(actionCategoriesMap); + models.splice(0, models.length); + metaRules.splice(0, metaRules.length); + subjectCategories.splice(0, subjectCategories.length); + objectCategories.splice(0, objectCategories.length); + actionCategories.splice(0, actionCategories.length); + if (subjectCategoriesData.subject_categories) createCategoryInternal('subject', subjectCategoriesData.subject_categories); + if (objectCategoriesData.object_categories) createCategoryInternal('object', objectCategoriesData.object_categories); + if (actionCategoriesData.action_categories) createCategoryInternal('action', actionCategoriesData.action_categories); + if (metarulesData.meta_rules) createMetaRuleInternal(metarulesData.meta_rules); + if (modelsData.models) createModelInternal(modelsData.models); + updateOrphan(); + } + + function mapModel(model) { + util.mapIdToItem(model.meta_rules, metaRulesMap); + } + + function createModelInternal(data) { + return util.createInternal(data, models, modelsMap, mapModel); + } + + function updateModelInternal(data) { + return util.updateInternal(data, modelsMap, mapModel); + } + + function removeModelInternal(id) { + return util.removeInternal(id, models, modelsMap); + } + + function mapMetaRule(metaRule) { + util.mapIdToItem(metaRule.subject_categories, subjectCategoriesMap); + util.mapIdToItem(metaRule.object_categories, objectCategoriesMap); + util.mapIdToItem(metaRule.action_categories, actionCategoriesMap); + } + + function createMetaRuleInternal(data) { + return util.createInternal(data, metaRules, metaRulesMap, mapMetaRule); + } + + function updateMetaRuleInternal(data) { + return util.updateInternal(data, metaRulesMap, mapMetaRule); + } + + function removeMetaRuleInternal(id) { + return util.removeInternal(id, metaRules, metaRulesMap); + } + + function createCategoryInternal(type, data) { + var categoryValue = categoryMap[type]; + return util.createInternal(data, categoryValue.list, categoryValue.map) + } + + function removeCategoryInternal(type, id) { + var categoryValue = categoryMap[type]; + return util.removeInternal(id, categoryValue.list, categoryValue.map); + } + + function updateOrphan() { + updateOrphanInternal(metaRules, orphanMetaRules, models, "meta_rules"); + updateOrphanInternal(subjectCategories, orphanSubjectCategories, metaRules, "subject_categories"); + updateOrphanInternal(objectCategories, orphanObjectCategories, metaRules, "object_categories"); + updateOrphanInternal(actionCategories, orphanActionCategories, metaRules, "action_categories"); + } + + function updateOrphanInternal(list, orphanList, parentList, childListName) { + orphanList.splice(0, orphanList.length); + util.pushAll(orphanList, list); + for (var i = 0; i < parentList.length; i++) { + var parent = parentList[i]; + var children = parent[childListName]; + if (children) { + for (var j = 0; j < children.length; j++) { + var child = children[j]; + var notOrphanIndex = util.indexOf(orphanList, "id", child.id); + if (notOrphanIndex >= 0) { + orphanList.splice(notOrphanIndex, 1); + } + } + } + } + } + + + return { + initialize: loadModels, + createModels: createModels, + models: models, + metaRules: metaRules, + orphanMetaRules: orphanMetaRules, + orphanSubjectCategories: orphanSubjectCategories, + orphanObjectCategories: orphanObjectCategories, + orphanActionCategories: orphanActionCategories, + subjectCategories: subjectCategories, + objectCategories: objectCategories, + actionCategories: actionCategories, + getModel: function getModel(id) { + return modelsMap[id]; + }, + createModel: function createModel(model) { + model.meta_rules = []; + modelResource.create(null, model, success, util.displayErrorFunction('Unable to create model')); + + function success(data) { + createModelInternal(data.models); + util.displaySuccess('Model created'); + } + }, + removeModel: function removeModel(model) { + modelResource.remove({ id: model.id }, null, success, util.displayErrorFunction('Unable to remove model')); + + function success(data) { + removeModelInternal(model.id); + updateOrphan(); + util.displaySuccess('Model removed'); + } + }, + updateModel: function updateModel(model) { + util.mapItemToId(model.meta_rules) + modelResource.update({ id: model.id }, model, success, util.displayErrorFunction('Unable to update model')); + + function success(data) { + updateModelInternal(data.models) + updateOrphan(); + util.displaySuccess('Model updated'); + } + }, + getMetaRule: function getMetaRule(id) { + return metaRulesMap[id]; + }, + createMetaRule: function createMetaRule(metaRule) { + metaRule.subject_categories = []; + metaRule.object_categories = []; + metaRule.action_categories = []; + + return metaRuleResource.create(null, metaRule).$promise.then(function (data) { + util.displaySuccess('Meta Rule created'); + return createMetaRuleInternal(data.meta_rules)[0]; + }, util.displayErrorFunction('Unable to create meta rule')) + }, + updateMetaRule: function updateMetaRule(metaRule) { + util.mapItemToId(metaRule.subject_categories); + util.mapItemToId(metaRule.object_categories); + util.mapItemToId(metaRule.action_categories); + metaRuleResource.update({ id: metaRule.id }, metaRule, success, util.displayErrorFunction('Unable to update meta rule')); + + function success(data) { + updateMetaRuleInternal(data.meta_rules); + updateOrphan(); + util.displaySuccess('Meta Rule updated'); + } + }, + removeMetaRule: function removeMetaRule(metaRule) { + metaRuleResource.remove({ id: metaRule.id }, null, success, util.displayErrorFunction('Unable to remove meta rule')); + + function success(data) { + removeMetaRuleInternal(metaRule.id); + updateOrphan(); + util.displaySuccess('Meta Rule removed'); + } + }, + getCategory: function getCategory(type, id) { + return categoryMap[type].map[id]; + }, + createCategory: function createCategory(type, category) { + var categoryValue = categoryMap[type]; + return categoryValue.resource.create({}, category).$promise.then(function (data) { + util.displaySuccess('Category created'); + return createCategoryInternal(type, data[categoryValue.listName])[0]; + }, util.displayErrorFunction('Unable to create category')) + }, + removeCategory: function removeCategory(type, category) { + var categoryValue = categoryMap[type]; + categoryValue.resource.remove({ id: category.id }, null, success, util.displayErrorFunction('Unable to remove category')); + + function success(data) { + removeCategoryInternal(type, category.id); + updateOrphan(); + util.displaySuccess('Category removed'); + } + }, + } + } +})(); \ No newline at end of file diff --git a/old/moon_dashboard/moon/static/moon/model/model.service.spec.js b/old/moon_dashboard/moon/static/moon/model/model.service.spec.js new file mode 100755 index 00000000..04d47793 --- /dev/null +++ b/old/moon_dashboard/moon/static/moon/model/model.service.spec.js @@ -0,0 +1,288 @@ +(function () { + 'use strict'; + + describe('moon.model.service', function () { + var service, $httpBackend, URI; + var modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData; + + function initData() { + modelsData = { + models: + { 'modelId1': { name: 'model1', description: 'mDescription1', meta_rules: ['metaRuleId1'] } } + }; + + subjectCategoriesData = { + subject_categories: + { + 'subjectCategoryId1': { name: 'subjectCategory1', description: 'scDescription1' }, + 'subjectCategoryId2': { name: 'subjectCategory2', description: 'scDescription2' } + }, + }; + objectCategoriesData = { + object_categories: + { + 'objectCategoryId1': { name: 'objectCategory1', description: 'ocDescription1' }, + 'objectCategoryId2': { name: 'objectCategory2', description: 'ocDescription2' } + } + }; + actionCategoriesData = { + action_categories: + { + 'actionCategoryId1': { name: 'actionCategory1', description: 'acDescription1' }, + 'actionCategoryId2': { name: 'actionCategory2', description: 'acDescription2' } + } + }; + metaRulesData = { + meta_rules: + { + 'metaRuleId1': { name: 'metaRule1', description: 'mrDescription1', subject_categories: ['subjectCategoryId1'], object_categories: ['objectCategoryId1'], action_categories: ['actionCategoryId1'] }, + 'metaRuleId2': { name: 'metaRule2', description: 'mrDescription2', subject_categories: [], object_categories: [], action_categories: [] } + } + }; + } + + beforeEach(module('horizon.app.core')); + beforeEach(module('horizon.framework')); + beforeEach(module('moon')); + + beforeEach(inject(function ($injector) { + service = $injector.get('moon.model.service'); + $httpBackend = $injector.get('$httpBackend'); + URI = $injector.get('moon.URI'); + })); + + afterEach(function () { + $httpBackend.verifyNoOutstandingExpectation(); + $httpBackend.verifyNoOutstandingRequest(); + }); + + it('should initialize', function () { + initData(); + $httpBackend.expectGET(URI.API + '/subject_categories').respond(200, subjectCategoriesData); + $httpBackend.expectGET(URI.API + '/object_categories').respond(200, objectCategoriesData); + $httpBackend.expectGET(URI.API + '/action_categories').respond(200, actionCategoriesData); + $httpBackend.expectGET(URI.API + '/meta_rules').respond(200, metaRulesData); + $httpBackend.expectGET(URI.API + '/models').respond(200, modelsData); + + service.initialize(); + $httpBackend.flush(); + + expect(service.models.length).toBe(1); + var model = service.models[0]; + expect(model.id).toBe('modelId1'); + expect(model.name).toBe('model1'); + expect(model.description).toBe('mDescription1'); + + expect(service.metaRules.length).toBe(2); + expect(model.meta_rules.length).toBe(1); + var metaRule = model.meta_rules[0]; + expect(metaRule.id).toBe('metaRuleId1'); + expect(metaRule.name).toBe('metaRule1'); + expect(metaRule.description).toBe('mrDescription1'); + + expect(service.subjectCategories.length).toBe(2); + expect(metaRule.subject_categories.length).toBe(1); + var subjectCategory = metaRule.subject_categories[0]; + expect(subjectCategory.id).toBe('subjectCategoryId1'); + expect(subjectCategory.name).toBe('subjectCategory1'); + expect(subjectCategory.description).toBe('scDescription1'); + + expect(service.objectCategories.length).toBe(2); + expect(metaRule.object_categories.length).toBe(1); + var objectCategory = metaRule.object_categories[0]; + expect(objectCategory.id).toBe('objectCategoryId1'); + expect(objectCategory.name).toBe('objectCategory1'); + expect(objectCategory.description).toBe('ocDescription1'); + + expect(service.actionCategories.length).toBe(2); + expect(metaRule.action_categories.length).toBe(1); + var actionCategory = metaRule.action_categories[0]; + expect(actionCategory.id).toBe('actionCategoryId1'); + expect(actionCategory.name).toBe('actionCategory1'); + expect(actionCategory.description).toBe('acDescription1'); + + expect(service.orphanMetaRules.length).toBe(1); + metaRule = service.orphanMetaRules[0]; + expect(metaRule.id).toBe('metaRuleId2'); + expect(metaRule.name).toBe('metaRule2'); + expect(metaRule.description).toBe('mrDescription2'); + + expect(service.orphanSubjectCategories.length).toBe(1); + subjectCategory = service.orphanSubjectCategories[0]; + expect(subjectCategory.id).toBe('subjectCategoryId2'); + expect(subjectCategory.name).toBe('subjectCategory2'); + expect(subjectCategory.description).toBe('scDescription2'); + + expect(service.orphanObjectCategories.length).toBe(1); + objectCategory = service.orphanObjectCategories[0]; + expect(objectCategory.id).toBe('objectCategoryId2'); + expect(objectCategory.name).toBe('objectCategory2'); + expect(objectCategory.description).toBe('ocDescription2'); + + expect(service.orphanActionCategories.length).toBe(1); + actionCategory = service.orphanActionCategories[0]; + expect(actionCategory.id).toBe('actionCategoryId2'); + expect(actionCategory.name).toBe('actionCategory2'); + expect(actionCategory.description).toBe('acDescription2'); + + }); + + + + it('should create model', function () { + var modelCreatedData = { + models: + { 'modelId1': { name: 'model1', description: 'mDescription1', meta_rules: [] } } + }; + + $httpBackend.expectPOST(URI.API + '/models').respond(200, modelCreatedData); + + service.createModel({ name: 'model1', description: 'mDescription1' }); + $httpBackend.flush(); + + expect(service.models.length).toBe(1); + var model = service.models[0]; + expect(model.id).toBe('modelId1'); + expect(model.name).toBe('model1'); + expect(model.description).toBe('mDescription1'); + }); + + it('should remove model', function () { + initData(); + service.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData); + + $httpBackend.expectDELETE(URI.API + '/models/modelId1').respond(200); + + service.removeModel({ id: 'modelId1' }); + $httpBackend.flush(); + + expect(service.models.length).toBe(0); + + expect(service.orphanMetaRules.length).toBe(2); + }); + + it('should update model', function () { + initData(); + var modelUpdatedData = { + models: + { 'modelId1': { name: 'model2', description: 'mDescription2', meta_rules: ['metaRuleId2'] } } + }; + service.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData); + + $httpBackend.expectPATCH(URI.API + '/models/modelId1').respond(200, modelUpdatedData); + + service.updateModel({ id: 'modelId1', name: 'model2', description: 'mDescription2', meta_rules: service.getMetaRule('metaRuleId2') }); + $httpBackend.flush(); + + expect(service.models.length).toBe(1); + var model = service.models[0]; + expect(model.id).toBe('modelId1'); + expect(model.name).toBe('model2'); + expect(model.description).toBe('mDescription2'); + + expect(model.meta_rules.length).toBe(1); + var metaRule = model.meta_rules[0]; + expect(metaRule.id).toBe('metaRuleId2'); + + expect(service.orphanMetaRules.length).toBe(1); + metaRule = service.orphanMetaRules[0]; + expect(metaRule.id).toBe('metaRuleId1'); + }); + + it('should create meta rule', function () { + var metaRuleCreatedData = { + meta_rules: + { 'metaRuleId1': { name: 'metaRule1', description: 'mrDescription1' } } + }; + + $httpBackend.expectPOST(URI.API + '/meta_rules').respond(200, metaRuleCreatedData); + + service.createMetaRule({ name: 'metaRule1', description: 'mrDescription1' }); + $httpBackend.flush(); + + expect(service.metaRules.length).toBe(1); + var metaRule = service.metaRules[0]; + expect(metaRule.id).toBe('metaRuleId1'); + expect(metaRule.name).toBe('metaRule1'); + expect(metaRule.description).toBe('mrDescription1'); + }); + + it('should update meta rule', function () { + initData(); + var metaRuleUpdatedData = { + meta_rules: + { 'metaRuleId1': { name: 'metaRule2', description: 'mrDescription2', subject_categories: ['subjectCategoryId2'], object_categories: ['objectCategoryId2'], action_categories: ['actionCategoryId2'] } } + }; + service.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData); + + $httpBackend.expectPATCH(URI.API + '/meta_rules/metaRuleId1').respond(200, metaRuleUpdatedData); + + service.updateMetaRule({ id: 'metaRuleId1', name: 'metaRule2', description: 'mrDescription2', subject_categories: [service.getCategory('subject', 'subjectCategoryId2')], object_categories: [service.getCategory('object', 'objectCategoryId2')], action_categories: [service.getCategory('action','actionCategoryId2')] }); + $httpBackend.flush(); + + var metaRule = service.getMetaRule('metaRuleId1'); + expect(metaRule.id).toBe('metaRuleId1'); + expect(metaRule.name).toBe('metaRule2'); + expect(metaRule.description).toBe('mrDescription2'); + + expect(service.orphanSubjectCategories.length).toBe(1); + var subjectCategory = service.orphanSubjectCategories[0]; + expect(subjectCategory.id).toBe('subjectCategoryId1'); + + expect(service.orphanObjectCategories.length).toBe(1); + var objectCategory = service.orphanObjectCategories[0]; + expect(objectCategory.id).toBe('objectCategoryId1'); + + expect(service.orphanActionCategories.length).toBe(1); + var actionCategory = service.orphanActionCategories[0]; + expect(actionCategory.id).toBe('actionCategoryId1'); + }); + + it('should remove meta rule', function () { + initData(); + service.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData); + + $httpBackend.expectDELETE(URI.API + '/meta_rules/metaRuleId2').respond(200); + + service.removeMetaRule(service.getMetaRule('metaRuleId2')); + $httpBackend.flush(); + + expect(service.metaRules.length).toBe(1); + expect(service.orphanMetaRules.length).toBe(0); + }); + + it('should create category', function () { + var categoryCreatedData = { + subject_categories: + { 'subjectCategoryId1': { name: 'subjectCategory1', description: 'scDescription1' } } + }; + + $httpBackend.expectPOST(URI.API + '/subject_categories').respond(200, categoryCreatedData); + + service.createCategory('subject', { name: 'subjectCategory1', description: 'scDescription1' }); + $httpBackend.flush(); + + expect(service.subjectCategories.length).toBe(1); + var subjectCategory = service.subjectCategories[0]; + expect(subjectCategory.id).toBe('subjectCategoryId1'); + expect(subjectCategory.name).toBe('subjectCategory1'); + expect(subjectCategory.description).toBe('scDescription1'); + }); + + it('should remove category', function () { + initData(); + service.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData); + + $httpBackend.expectDELETE(URI.API + '/subject_categories/subjectCategoryId2').respond(200); + + service.removeCategory('subject', service.getCategory('subject', 'subjectCategoryId2')); + $httpBackend.flush(); + + expect(service.subjectCategories.length).toBe(1); + expect(service.orphanSubjectCategories.length).toBe(0); + }); + + }); + + +})(); \ No newline at end of file diff --git a/old/moon_dashboard/moon/static/moon/pdp/pdp.controller.js b/old/moon_dashboard/moon/static/moon/pdp/pdp.controller.js new file mode 100644 index 00000000..1859b1f8 --- /dev/null +++ b/old/moon_dashboard/moon/static/moon/pdp/pdp.controller.js @@ -0,0 +1,125 @@ +(function () { + 'use strict'; + + angular + .module('moon') + .controller('moon.pdp.controller', + controller); + + controller.$inject = ['moon.util.service', 'moon.pdp.service', 'horizon.framework.widgets.form.ModalFormService']; + + function controller(util, pdpService, ModalFormService) { + var self = this; + self.model = pdpService; + pdpService.initialize(); + + self.createPdp = function createPdp() { + var schema = { + type: "object", + properties: { + name: { type: "string", minLength: 2, title: gettext("Name") }, + description: { type: "string", minLength: 2, title: gettext("Description") } + }, + required: ['name', 'description'] + }; + var pdp = { name: '', description: '' }; + var config = { + title: gettext('Create PDP'), + schema: schema, + form: ['name', { key: 'description', type: 'textarea' }], + model: pdp + }; + ModalFormService.open(config).then(submit); + + function submit(form) { + pdpService.createPdp(form.model); + } + } + + self.updatePdp = function updatePdp(pdp) { + var schema = { + type: "object", + properties: { + name: { type: "string", minLength: 2, title: gettext("Name") }, + description: { type: "string", minLength: 2, title: gettext("Description") } + }, + required: ['name', 'description'] + }; + var config = { + title: gettext('Update PDP'), + schema: schema, + form: ['name', { key: 'description', type: 'textarea' }], + model: angular.copy(pdp) + }; + ModalFormService.open(config).then(submit); + + function submit(form) { + pdpService.updatePdp(form.model); + } + } + + self.removePdp = function removePdp(pdp) { + if (confirm(gettext('Are you sure to delete this PDP?'))) + pdpService.removePdp(pdp); + } + + self.addPolicy = function addPolicy(pdp) { + var schema = { + type: "object", + properties: { + id: { type: "string", title: gettext("Select a Policy:") } + }, + required: ['id'] + }; + var titleMap = util.arrayToTitleMap(pdpService.policies) + var config = { + title: gettext('Add Policy'), + schema: schema, + form: [{ key: 'id', type: 'select', titleMap: titleMap }], + model: {} + }; + ModalFormService.open(config).then(submit); + + function submit(form) { + var pdpCopy = angular.copy(pdp); + pdpCopy.security_pipeline.push(pdpService.getPolicy(form.model.id)); + pdpService.updatePdp(pdpCopy); + } + } + + self.removePolicyFromPdp = function removePolicyFromPdp(pdp, policy) { + if (confirm(gettext('Are you sure to remove this Policy from PDP?'))) { + var pdpCopy = angular.copy(pdp); + pdpCopy.security_pipeline.splice(pdp.security_pipeline.indexOf(policy), 1); + pdpService.updatePdp(pdpCopy); + } + } + + self.changeProject = function changeProject(pdp) { + var schema = { + type: "object", + properties: { + id: { type: "string", title: gettext("Select a Project:") } + }, + required: ['id'] + }; + var model = {id : pdp.keystone_project_id}; + + var titleMap = util.arrayToTitleMap(pdpService.projects) + var config = { + title: gettext('Change Project'), + schema: schema, + form: [{ key: 'id', type: 'select', titleMap: titleMap }], + model: model + }; + ModalFormService.open(config).then(submit); + + function submit(form) { + var pdpCopy = angular.copy(pdp); + pdpCopy.project = pdpService.getProject(form.model.id); + pdpService.updatePdp(pdpCopy); + } + } + + } +})(); \ No newline at end of file diff --git a/old/moon_dashboard/moon/static/moon/pdp/pdp.html b/old/moon_dashboard/moon/static/moon/pdp/pdp.html new file mode 100644 index 00000000..2456a261 --- /dev/null +++ b/old/moon_dashboard/moon/static/moon/pdp/pdp.html @@ -0,0 +1,41 @@ +
+
+
+ + +
+
+
+
+

{$ pdp.name $}

+
+ + +
+

{$ pdp.description $}

+

+ Project: {$ pdp.project ? pdp.project.name : 'none' $} + +

+ +
+ +

{$ pdp.security_pipeline.length $} + policy(ies) +

+ +
+
+
+

{$ policy.name $}

+ +

{$ policy.description $}

+
+
+
+
+
+
\ No newline at end of file diff --git a/old/moon_dashboard/moon/static/moon/pdp/pdp.service.js b/old/moon_dashboard/moon/static/moon/pdp/pdp.service.js new file mode 100755 index 00000000..e18971be --- /dev/null +++ b/old/moon_dashboard/moon/static/moon/pdp/pdp.service.js @@ -0,0 +1,123 @@ +(function () { + + 'use strict'; + + angular + .module('moon') + .factory('moon.pdp.service', pdpService); + + pdpService.$inject = ['moon.util.service', '$resource', 'moon.URI', '$q', 'horizon.app.core.openstack-service-api.keystone']; + + function pdpService(util, $resource, URI, $q, keystone) { + var host = URI.API; + + var pdpResource = $resource(host + '/pdp/' + ':id', {}, { + get: { method: 'GET' }, + query: { method: 'GET' }, + create: { method: 'POST' }, + remove: { method: 'DELETE' }, + update: { method: 'PATCH' } + }); + + var policyResource = $resource(host + '/policies/' + ':id', {}, { + query: { method: 'GET' }, + }); + + var pdpsMap = {}; + var pdps = []; + var policiesMap = {}; + var policies = []; + var projectsMap = {}; + var projects = []; + + function loadPdps() { + var queries = { + pdps: pdpResource.query().$promise, + policies: policyResource.query().$promise, + projects: keystone.getProjects() + } + + $q.all(queries).then(function (result) { + createPdps(result.pdps, result.policies, result.projects.data) + console.log('moon', 'pdps initialized', pdps) + }) + } + + function createPdps(pdpsData, policiesData, projectsData) { + pdps.splice(0, pdps.length); + policies.splice(0, policies.length); + projects.splice(0, projects.length); + util.cleanObject(pdpsMap); + util.cleanObject(policiesMap); + util.cleanObject(projectsMap) + + util.createInternal(policiesData.policies, policies, policiesMap); + util.pushAll(projects, projectsData.items); + util.addToMap(projects, projectsMap); + createPdpInternal(pdpsData.pdps); + } + + function mapPdp(pdp) { + util.mapIdToItem(pdp.security_pipeline, policiesMap); + pdp.project = null; + if (pdp.keystone_project_id) { + pdp.project = projectsMap[pdp.keystone_project_id]; + } + } + + function createPdpInternal(data) { + return util.createInternal(data, pdps, pdpsMap, mapPdp); + } + + function updatePdpInternal(data) { + return util.updateInternal(data, pdpsMap, mapPdp); + } + + function removePdpInternal(id) { + return util.removeInternal(id, pdps, pdpsMap); + } + + return { + initialize: loadPdps, + createPdps: createPdps, + pdps: pdps, + policies: policies, + projects: projects, + createPdp: function createPdp(pdp) { + pdp.keystone_project_id = null; + pdp.security_pipeline = []; + pdpResource.create(null, pdp, success, util.displayErrorFunction('Unable to create PDP')); + + function success(data) { + createPdpInternal(data.pdps); + util.displaySuccess('PDP created'); + } + }, + removePdp: function removePdp(pdp) { + pdpResource.remove({ id: pdp.id }, null, success, util.displayErrorFunction('Unable to remove PDP')); + + function success(data) { + removePdpInternal(pdp.id); + util.displaySuccess('PDP removed'); + } + }, + updatePdp: function updatePdp(pdp) { + util.mapItemToId(pdp.security_pipeline); + pdp.keystone_project_id = pdp.project ? pdp.project.id : null; + pdpResource.update({ id: pdp.id }, pdp, success, util.displayErrorFunction('Unable to update PDP')); + + function success(data) { + updatePdpInternal(data.pdps) + util.displaySuccess('PDP updated'); + } + }, + getPolicy: function getPolicy(id) { + return policiesMap[id]; + }, + getProject: function getProject(id) { + return projectsMap[id]; + }, + } + + } +})(); \ No newline at end of file diff --git a/old/moon_dashboard/moon/static/moon/pdp/pdp.service.spec.js b/old/moon_dashboard/moon/static/moon/pdp/pdp.service.spec.js new file mode 100755 index 00000000..4208467f --- /dev/null +++ b/old/moon_dashboard/moon/static/moon/pdp/pdp.service.spec.js @@ -0,0 +1,143 @@ +(function () { + 'use strict'; + + describe('moon.pdp.service', function () { + var service, $httpBackend, URI; + var pdpsData, policiesData, projectsData; + + + function initData() { + pdpsData = { + pdps: + { 'pdpId1': { name: 'pdp1', description: 'pdpDescription1', security_pipeline: ['policyId1'], keystone_project_id: 'projectId1' } } + }; + + policiesData = { + policies: + { + 'policyId1': { name: 'policy1', description: 'pDescription1' }, + 'policyId2': { name: 'policy2', description: 'pDescription2' } + } + }; + + projectsData = { + items: [ + { name: "project1", id: "projectId1" }, + { name: "project2", id: "projectId2" } + ] + }; + + } + + beforeEach(module('horizon.app.core')); + beforeEach(module('horizon.framework')); + beforeEach(module('moon')); + + beforeEach(inject(function ($injector) { + service = $injector.get('moon.pdp.service'); + $httpBackend = $injector.get('$httpBackend'); + URI = $injector.get('moon.URI'); + })); + + afterEach(function () { + $httpBackend.verifyNoOutstandingExpectation(); + $httpBackend.verifyNoOutstandingRequest(); + }); + + it('should initialize', function () { + initData(); + $httpBackend.expectGET(URI.API + '/pdp').respond(200, pdpsData); + $httpBackend.expectGET(URI.API + '/policies').respond(200, policiesData); + $httpBackend.expectGET('/api/keystone/projects/').respond(200, projectsData); + + + service.initialize(); + $httpBackend.flush(); + + expect(service.pdps.length).toBe(1); + var pdp = service.pdps[0]; + expect(pdp.id).toBe('pdpId1'); + expect(pdp.name).toBe('pdp1'); + expect(pdp.description).toBe('pdpDescription1'); + expect(pdp.security_pipeline.length).toBe(1); + expect(pdp.security_pipeline[0].id).toBe('policyId1'); + expect(pdp.keystone_project_id).toBe('projectId1'); + expect(pdp.project.id).toBe('projectId1'); + + expect(service.policies.length).toBe(2); + var policy = service.policies[0]; + expect(policy.id).toBe('policyId1'); + expect(policy.name).toBe('policy1'); + expect(policy.description).toBe('pDescription1'); + + + expect(service.projects.length).toBe(2); + var project = service.projects[0]; + expect(project.id).toBe('projectId1'); + expect(project.name).toBe('project1'); + + }); + + + + it('should create pdp', function () { + var pdpCreatedData = { + pdps: + { 'pdpId1': { name: 'pdp1', description: 'pdpDescription1', security_pipeline: [], keystone_project_id: null } } + }; + + $httpBackend.expectPOST(URI.API + '/pdp').respond(200, pdpCreatedData); + + service.createPdp({ name: 'pdp1', description: 'pdpDescription1' }); + $httpBackend.flush(); + + expect(service.pdps.length).toBe(1); + var pdp = service.pdps[0]; + expect(pdp.id).toBe('pdpId1'); + expect(pdp.name).toBe('pdp1'); + expect(pdp.description).toBe('pdpDescription1'); + expect(pdp.project).toBe(null); + expect(pdp.security_pipeline.length).toBe(0); + }); + + it('should remove pdp', function () { + initData(); + service.createPdps(pdpsData, policiesData, projectsData); + + $httpBackend.expectDELETE(URI.API + '/pdp/pdpId1').respond(200); + + service.removePdp({ id: 'pdpId1' }); + $httpBackend.flush(); + + expect(service.pdps.length).toBe(0); + }); + + it('should update pdp', function () { + initData(); + var pdpUpdatedData = { + pdps: + { 'pdpId1': { name: 'pdp2', description: 'pdpDescription2', security_pipeline: ['policyId2'], keystone_project_id: 'projectId2' } } + }; + service.createPdps(pdpsData, policiesData, projectsData); + + $httpBackend.expectPATCH(URI.API + '/pdp/pdpId1').respond(200, pdpUpdatedData); + + service.updatePdp({ id: 'pdpId1', name: 'pdp2', description: 'pdpDescription2', security_pipeline: [service.getPolicy('policyId2')], project: service.getProject('projectId2') }); + $httpBackend.flush(); + + expect(service.pdps.length).toBe(1); + var pdp = service.pdps[0]; + expect(pdp.id).toBe('pdpId1'); + expect(pdp.name).toBe('pdp2'); + expect(pdp.description).toBe('pdpDescription2'); + expect(pdp.project.id).toBe('projectId2'); + expect(pdp.security_pipeline.length).toBe(1); + expect(pdp.security_pipeline[0].id).toBe('policyId2'); + + }); + + + }); + + +})(); \ No newline at end of file diff --git a/old/moon_dashboard/moon/static/moon/policy/policy.controller.js b/old/moon_dashboard/moon/static/moon/policy/policy.controller.js new file mode 100644 index 00000000..a3cc18f1 --- /dev/null +++ b/old/moon_dashboard/moon/static/moon/policy/policy.controller.js @@ -0,0 +1,341 @@ +(function () { + 'use strict'; + + angular + .module('moon') + .controller('moon.policy.controller', + controller); + + controller.$inject = ['moon.util.service', 'moon.policy.service', 'moon.model.service', 'horizon.framework.widgets.form.ModalFormService']; + + function controller(util, policyService, modelService, ModalFormService) { + var self = this; + var genres = [{ value: 'admin', name: gettext('admin') }, { value: 'authz', name: gettext('authz') }]; + self.model = policyService; + self.selectedRule = null; + self.currentData = null; + policyService.initialize(); + + var dataTitleMaps = {}; + + var categoryMap = { + subject: { + perimeterId: 'subject_id' + }, + object: { + perimeterId: 'object_id' + }, + action: { + perimeterId: 'action_id' + }, + } + + function createAddDataButton(type, index, category, config, policy) { + config.form.push({ + key: type + index + "Button", + type: "button", + title: gettext("Create Data"), + icon: 'fa fa-plus', + onClick: createDataFunction(type, category, policy, config.model, type+index) + }) + } + + function createDataFunction(type, category, policy, formModel, key) { + return function () { + var schema = { + type: "object", + properties: { + name: { type: "string", minLength: 2, title: gettext("Name") }, + description: { type: "string", minLength: 2, title: gettext("Description") }, + }, + required: ['name', 'description'] + }; + var data = { name: '', description: '' }; + var config = { + title: gettext('Create Data of ' + category.name + ' category'), + schema: schema, + form: ['name', { key: 'description', type: 'textarea' }], + model: data + }; + ModalFormService.open(config).then(submit); + + function submit(form) { + policyService.createData(type, policy, category, form.model).then( + function (data) { + util.pushAll(dataTitleMaps[category.id], util.arrayToTitleMap(data)); + formModel[key] = data[0].id + } + ); + } + } + } + + function getOrCreateDataTitleMap(category, data, policy) { + var result = dataTitleMaps[category.id]; + if (!result) { + result = util.arrayToTitleMap(data); + dataTitleMaps[category.id] = result; + } + return result; + } + + function createDataSelect(type, categories, data, config, policy) { + for (var i = 0; i < categories.length; i++) { + var category = categories[i]; + var titleMap = getOrCreateDataTitleMap(category, data, policy); + config.schema.properties[type + i] = { type: "string", title: gettext('Select ' + type + ' data of ' + category.name + ' category') }; + config.form.push({ key: type + i, type: 'select', titleMap: titleMap }); + config.schema.required.push(type + i); + createAddDataButton(type, i, category, config, policy); + } + } + + function pushData(type, model, array) { + var i = 0; + while ((type + i) in model) { + array.push(model[type + i]); + i++; + } + } + + self.createPolicy = function createPolicy() { + var schema = { + type: "object", + properties: { + name: { type: "string", minLength: 2, title: gettext("Name") }, + description: { type: "string", minLength: 2, title: gettext("Description") }, + genre: { type: "string", title: gettext("genre") }, + model_id: { type: "string", title: gettext("Select a Model:") } + }, + required: ['name', 'description', 'genre', 'model_id'] + }; + var policy = { name: '', description: '', model_id: null, genre: '' }; + var titleMap = util.arrayToTitleMap(modelService.models) + var config = { + title: gettext('Create Policy'), + schema: schema, + form: ['name', { key: 'description', type: 'textarea' }, { key: 'genre', type: 'select', titleMap: genres }, { key: 'model_id', type: 'select', titleMap: titleMap }], + model: policy + }; + ModalFormService.open(config).then(submit); + + function submit(form) { + policyService.createPolicy(form.model); + } + } + + self.updatePolicy = function updatePolicy(policy) { + var schema = { + type: "object", + properties: { + name: { type: "string", minLength: 2, title: gettext("Name") }, + description: { type: "string", minLength: 2, title: gettext("Description") }, + genre: { type: "string", title: gettext("Genre") }, + }, + required: ['name', 'description', 'genre'] + }; + var config = { + title: gettext('Update Policy'), + schema: schema, + form: ['name', { key: 'description', type: 'textarea' }, { key: 'genre', type: 'select', titleMap: genres }], + model: { name: policy.name, description: policy.description, model_id: policy.model_id, id: policy.id, genre: policy.genre } + }; + ModalFormService.open(config).then(submit); + + function submit(form) { + policyService.updatePolicy(form.model); + } + } + + self.addRuleWithMetaRule = function addRuleWithMetaRule(policy, metaRule) { + var schema = { + type: "object", + properties: { + instructions: { type: "string", title: gettext("Instructions") } + }, + required: ['instructions'] + }; + + var config = { + title: gettext('Add Rule'), + schema: schema, + form: [], + model: { + instructions: '[{"decision": "grant"}]' + } + }; + dataTitleMaps = {}; + createDataSelect('subject', metaRule.subject_categories, policy.subjectData, config, policy); + createDataSelect('object', metaRule.object_categories, policy.objectData, config, policy); + createDataSelect('action', metaRule.action_categories, policy.actionData, config, policy); + config.form.push({ key: 'instructions', type: 'textarea' }) + + ModalFormService.open(config).then(submit); + + function submit(form) { + var rule = { enabled: true }; + rule.instructions = JSON.parse(form.model.instructions); + rule.meta_rule_id = metaRule.id; + rule.policy_id = policy.id; + rule.rule = []; + pushData('subject', form.model, rule.rule); + pushData('object', form.model, rule.rule); + pushData('action', form.model, rule.rule); + policyService.addRuleToPolicy(policy, rule); + } + } + + self.addRule = function addRule(policy) { + if (policy.model.meta_rules.length == 1) { + self.addRuleWithMetaRule(policy, policy.model.meta_rules[0]); + return; + } + var schema = { + type: "object", + properties: { + metaRuleId: { type: "string", title: gettext("Select a Metarule:") } + }, + required: ['metaRuleId'] + }; + var rule = { metaRuleId: null }; + var titleMap = util.arrayToTitleMap(policy.model.meta_rules); + var config = { + title: gettext('Add Rule'), + schema: schema, + form: [{ key: 'metaRuleId', type: 'select', titleMap: titleMap }], + model: rule + }; + ModalFormService.open(config).then(submit); + + function submit(form) { + self.addRuleWithMetaRule(policy, modelService.getMetaRule(form.model.metaRuleId)); + } + } + + self.removePolicy = function removePolicy(policy) { + if (confirm(gettext('Are you sure to delete this Policy? (Associated perimeter, data an PDP will be deleted too)'))) + policyService.removePolicy(policy); + } + + self.populatePolicy = function populatePolicy(policy) { + policyService.populatePolicy(policy); + } + + self.removeRuleFromPolicy = function removeRuleFromPolicy(policy, rule) { + if (confirm(gettext('Are you sure to delete this Rule?'))) + policyService.removeRuleFromPolicy(policy, rule); + } + + self.showRule = function showRule(rule) { + self.selectedRule = rule; + self.currentData = null; + } + + self.hideRule = function hideRule() { + self.selectedRule = null; + self.currentData = null; + } + + self.assignData = function assignData(type, policy, data) { + self.currentData = { + data: data, + type: type, + loading: true, + perimeters: [], + allPerimeters: [], + assignments: [], + } + + policyService.loadPerimetersAndAssignments(type, policy).then(function (values) { + var category = categoryMap[type]; + self.currentData.loading = false; + self.currentData.perimeters = values.perimeters; + var index; + for (index = 0; index < values.allPerimeters.length; index++) { + var perimeter = values.allPerimeters[index]; + if (perimeter.policy_list.indexOf(policy.id) < 0) { + self.currentData.allPerimeters.push(perimeter); + } + } + for (index = 0; index < values.assignments.length; index++) { + var assignment = values.assignments[index]; + if (assignment.assignments.indexOf(data.id) >= 0) { + var perimeter = values.perimetersMap[assignment[category.perimeterId]]; + self.currentData.assignments.push(perimeter); + self.currentData.perimeters.splice(self.currentData.perimeters.indexOf(perimeter), 1); + } + } + }) + } + + self.createPerimeter = function createPerimeter(type, policy) { + var schema = { + type: "object", + properties: { + name: { type: "string", minLength: 2, title: gettext("Name") }, + description: { type: "string", minLength: 2, title: gettext("Description") }, + }, + required: ['name', 'description'] + }; + if (type == 'subject') { + schema.properties.email = { type: "email", "type": "string", "pattern": "^\\S+@\\S+$", title: gettext("Email") } + schema.required.push('email'); + } + var perimeter = { name: '', description: '' }; + var config = { + title: gettext('Create Perimeter'), + schema: schema, + form: ['name', { key: 'description', type: 'textarea' }], + model: perimeter + }; + if (type == 'subject') { + config.form.push('email'); + } + + ModalFormService.open(config).then(submit); + + function submit(form) { + policyService.createPerimeter(type, policy, form.model).then(function (perimeters) { + util.pushAll(self.currentData.perimeters, perimeters); + }) + } + } + + self.addPerimeter = function addPerimeter(type, policy, perimeter) { + policyService.addPerimeterToPolicy(type, policy, perimeter).then(function () { + self.currentData.allPerimeters.splice(self.currentData.allPerimeters.indexOf(perimeter), 1); + self.currentData.perimeters.push(perimeter); + }) + } + + self.assign = function assign(type, policy, perimeter, data) { + policyService.createAssignment(type, policy, perimeter, data).then(function () { + self.currentData.assignments.push(perimeter); + self.currentData.perimeters.splice(self.currentData.perimeters.indexOf(perimeter), 1); + }) + } + + self.unassign = function unassign(type, policy, perimeter, data) { + policyService.removeAssignment(type, policy, perimeter, data).then(function () { + self.currentData.perimeters.push(perimeter); + self.currentData.assignments.splice(self.currentData.assignments.indexOf(perimeter), 1); + }) + } + + self.removePerimeterFromPolicy = function removePerimeterFromPolicy(type, policy, perimeter) { + if (confirm(gettext('Are you sure to delete this Perimeter? (Associated assignments will be deleted too)'))) + policyService.removePerimeterFromPolicy(type, policy, perimeter).then(function () { + self.currentData.perimeters.splice(self.currentData.perimeters.indexOf(perimeter), 1); + perimeter.policy_list.splice(perimeter.policy_list.indexOf(policy.id), 1); + if (perimeter.policy_list.length > 0) { + self.currentData.allPerimeters.push(perimeter); + } + }) + } + + self.removeData = function removeData(type, policy, data) { + if (confirm(gettext('Are you sure to delete this Data? (Associated assignments and rules will be deleted too)'))) + policyService.removeData(type, policy, data) + } + } +})(); \ No newline at end of file diff --git a/old/moon_dashboard/moon/static/moon/policy/policy.html b/old/moon_dashboard/moon/static/moon/policy/policy.html new file mode 100644 index 00000000..ba13bec2 --- /dev/null +++ b/old/moon_dashboard/moon/static/moon/policy/policy.html @@ -0,0 +1,214 @@ +
+
+
+ + +
+
+ +
+
+

{$ policy.name $}

+
+ + +
+

{$ policy.description $}

+

+ Model: {$ policy.model ? policy.model.name : 'none' $} +

+

+ Genre: + {$ policy.genre ? policy.genre : 'none' $} +

+
+ +

Warning!

+

+ Some data are unused, please check them and delete them if necessary. + Show unused data + Hide unused data +

+
+ +
+
+

Unused Subject data

+
+

{$ subject.name $}

+ +
+
+ +
+

Unused Object data

+
+

{$ object.name $}

+ +
+
+ +
+

Unused Action data

+
+

{$ action.name $}

+ +
+
+ +
+ + +
+ +

Rules

+ +
+
+

Loading rules...

+
+
+
+ + Metarule: + {$ rule.metaRule.name $} +
+ + Rule: + + + {$ data.name $}{$ $last ? '' : ', ' $} + | + + {$ data.name $}{$ $last ? '' : ', ' $} + | + + {$ data.name $}{$ $last ? '' : ', ' $} + +
+ + +
+
+ +
+

+ Metarule: {$ rule.metaRule.name $}

+
+ + +
+

+ + + + + + + + + + + + + + + + + +
+ Subjects + + Objects + + Actions + + Instructions +
+

+ {$ data.name $} + + +

+
+

+ {$ data.name $} + + +

+
+

+ {$ data.name $} + + +

+
+

+                      
+

+

Loading...

+
+
+
+

+ Assign perimeters to {$ ctrl.currentData.data.name $}

+ + +
+
+
+

All perimeters

+
+ + +
+

Click to add

+
+ +
+

Policy perimeters

+
+
+ + {$ perimeter.name $} + + +
+ +
+

Click to assign

+
+
+

Assigned perimeters

+
+ +
+

Click to unassign

+
+
+
+

+
+
+
+
+
+
+
\ No newline at end of file diff --git a/old/moon_dashboard/moon/static/moon/policy/policy.service.js b/old/moon_dashboard/moon/static/moon/policy/policy.service.js new file mode 100755 index 00000000..3781156d --- /dev/null +++ b/old/moon_dashboard/moon/static/moon/policy/policy.service.js @@ -0,0 +1,428 @@ +(function () { + + 'use strict'; + + angular + .module('moon') + .factory('moon.policy.service', policyService); + + policyService.$inject = ['moon.util.service', 'moon.model.service', '$resource', 'moon.URI', '$q', 'horizon.framework.widgets.toast.service']; + + function policyService(util, modelService, $resource, URI, $q, toast) { + var host = URI.API; + + var policyResource = $resource(host + '/policies/' + ':id', {}, { + get: { method: 'GET' }, + query: { method: 'GET' }, + create: { method: 'POST' }, + remove: { method: 'DELETE' }, + update: { method: 'PATCH' } + }); + + var policyRulesResource = $resource(host + '/policies/' + ':policy_id' + '/rules/' + ':rule_id', {}, { + get: { method: 'GET' }, + query: { method: 'GET' }, + create: { method: 'POST' }, + remove: { method: 'DELETE' } + }); + + var policySubjectDataResource = $resource(host + '/policies/' + ':policy_id' + '/subject_data/' + ':category_id' + '/' + ':data_id', {}, { + query: {method: 'GET'}, + create: { method: 'POST' }, + remove: { method: 'DELETE' } + }) + + var policyObjectDataResource = $resource(host + '/policies/' + ':policy_id' + '/object_data/' + ':category_id' + '/' + ':data_id', {}, { + query: {method: 'GET'}, + create: { method: 'POST' }, + remove: { method: 'DELETE' } + }) + + var policyActionDataResource = $resource(host + '/policies/' + ':policy_id' + '/action_data/' + ':category_id' + '/' + ':data_id', {}, { + query: {method: 'GET'}, + create: { method: 'POST' }, + remove: { method: 'DELETE' } + }) + + var policySubjectPerimetersResource = $resource(host + '/policies/' + ':policy_id' + '/subjects/' + ':perimeter_id', {}, { + query: {method: 'GET'}, + create: { method: 'POST' }, + remove: { method: 'DELETE' } + }) + + var policyObjectPerimetersResource = $resource(host + '/policies/' + ':policy_id' + '/objects/' + ':perimeter_id', {}, { + query: {method: 'GET'}, + create: { method: 'POST' }, + remove: { method: 'DELETE' } + }) + + var policyActionPerimetersResource = $resource(host + '/policies/' + ':policy_id' + '/actions/' + ':perimeter_id', {}, { + query: {method: 'GET'}, + create: { method: 'POST' }, + remove: { method: 'DELETE' } + }) + + var subjectPerimetersResource = $resource(host + '/subjects/' + ':perimeter_id', {}, { + query: {method: 'GET'}, + update: { method: 'PATCH' } + }) + + var objectPerimetersResource = $resource(host + '/objects/' + ':perimeter_id', {}, { + query: {method: 'GET'}, + update: { method: 'PATCH' } + }) + + var actionPerimetersResource = $resource(host + '/actions/' + ':perimeter_id', {}, { + query: {method: 'GET'}, + update: { method: 'PATCH' } + }) + + var policySubjectAssignmentsResource = $resource(host + '/policies/' + ':policy_id' + '/subject_assignments/' + ':perimeter_id' + '/' + ':category_id' + '/' + ':data_id', {}, { + query: {method: 'GET'}, + create: { method: 'POST' }, + remove: { method: 'DELETE' } + }) + + var policyObjectAssignmentsResource = $resource(host + '/policies/' + ':policy_id' + '/object_assignments/' + ':perimeter_id' + '/' + ':category_id' + '/' + ':data_id', {}, { + query: {method: 'GET'}, + create: { method: 'POST' }, + remove: { method: 'DELETE' } + }) + + var policyActionAssignmentsResource = $resource(host + '/policies/' + ':policy_id' + '/action_assignments/' + ':perimeter_id' + '/' + ':category_id' + '/' + ':data_id', {}, { + query: {method: 'GET'}, + create: { method: 'POST' }, + remove: { method: 'DELETE' } + }) + + + var categoryMap = { + 'subject': { + resource: policySubjectDataResource, + arrayName: "subjectData", + mapName: "subjectDataMap", + responseName: "subject_data", + policyPerimeterResource: policySubjectPerimetersResource, + perimeterResource: subjectPerimetersResource, + assignmentResource: policySubjectAssignmentsResource, + perimeterResponseName: "subjects", + assignmentResponseName: "subject_assignments", + unusedArrayName: "unusedSubjectData", + }, + 'object': { + resource: policyObjectDataResource, + arrayName: "objectData", + mapName: "objectDataMap", + responseName: "object_data", + policyPerimeterResource: policyObjectPerimetersResource, + perimeterResource: objectPerimetersResource, + assignmentResource: policyObjectAssignmentsResource, + perimeterResponseName: "objects", + assignmentResponseName: "object_assignments", + unusedArrayName: "unusedObjectData", + }, + 'action': { + resource: policyActionDataResource, + arrayName: "actionData", + mapName: "actionDataMap", + responseName: "action_data", + policyPerimeterResource: policyActionPerimetersResource, + perimeterResource: actionPerimetersResource, + assignmentResource: policyActionAssignmentsResource, + perimeterResponseName: "actions", + assignmentResponseName: "action_assignments", + unusedArrayName: "unusedActionData", + } + } + + var policiesMap = {}; + var policies = []; + + function loadPolicies() { + var queries = { + policies: policyResource.query().$promise, + models: modelService.initialize(), + } + + $q.all(queries).then(function (result) { + createPolicies(result.policies); + console.log('moon', 'policies initialized') + }) + } + + function createPolicies(policiesData) { + policies.splice(0, policies.length); + util.cleanObject(policiesMap); + createPolicyInternal(policiesData.policies); + } + + function mapPolicy(policy) { + if (policy.model_id) { + policy.model = modelService.getModel(policy.model_id); + } + } + + function createPolicyInternal(data) { + return util.createInternal(data, policies, policiesMap, mapPolicy); + } + + function removePolicyInternal(id) { + return util.removeInternal(id, policies, policiesMap); + } + + function updatePolicyInternal(data) { + return util.updateInternal(data, policiesMap, mapPolicy); + } + + function removeRuleInternal(policy, rule) { + policy.rules.splice(policy.rules.indexOf(rule), 1); + updateUnusedData(policy); + } + + function loadPolicyRule(policy) { + if (!policy.rules) { + var queries = { + rules: policyRulesResource.query({ policy_id: policy.id }).$promise, + subjectData: policySubjectDataResource.query({ policy_id: policy.id }).$promise, + objectData: policyObjectDataResource.query({ policy_id: policy.id }).$promise, + actionData: policyActionDataResource.query({ policy_id: policy.id }).$promise, + } + + $q.all(queries).then(function (result) { + createRules(policy, result.rules, result.subjectData, result.objectData, result.actionData); + updateUnusedData(policy); + }, util.displayErrorFunction('Unable to load rules')) + } + } + + function updateUnusedData(policy) { + policy.unusedSubjectData.splice(0, policy.unusedSubjectData.length); + util.pushAll(policy.unusedSubjectData, policy.subjectData); + + policy.unusedObjectData.splice(0, policy.unusedObjectData.length); + util.pushAll(policy.unusedObjectData, policy.objectData); + + policy.unusedActionData.splice(0, policy.unusedActionData.length); + util.pushAll(policy.unusedActionData, policy.actionData); + + for (var i = 0; i < policy.rules.length; i++) { + var rule = policy.rules[i]; + removeUsedData(rule.subjectData, policy.unusedSubjectData); + removeUsedData(rule.objectData, policy.unusedObjectData); + removeUsedData(rule.actionData, policy.unusedActionData); + } + } + + function removeUsedData(list, orphanList) { + for (var j = 0; j < list.length; j++) { + var data = list[j]; + var notOrphanIndex = util.indexOf(orphanList, "id", data.id); + if (notOrphanIndex >= 0) { + orphanList.splice(notOrphanIndex, 1); + } + } + } + + function createRules(policy, rulesData, subjectsData, objectsData, actionsData) { + policy.rules = rulesData ? rulesData.rules.rules : []; + policy.subjectDataMap = subjectsData.subject_data.length > 0 ? subjectsData.subject_data[0].data : []; + policy.subjectData = util.mapToArray(policy.subjectDataMap); + policy.objectDataMap = objectsData.object_data.length > 0 ? objectsData.object_data[0].data : []; + policy.objectData = util.mapToArray(policy.objectDataMap); + policy.actionDataMap = actionsData.action_data.length > 0 ? actionsData.action_data[0].data : []; + policy.actionData = util.mapToArray(policy.actionDataMap); + policy.unusedSubjectData = []; + policy.unusedObjectData = []; + policy.unusedActionData = []; + for (var i = 0; i < policy.rules.length; i++) { + var rule = policy.rules[i]; + populateRule(policy, rule); + } + } + + function populateRule(policy, rule) { + if (rule.meta_rule_id) { + rule.metaRule = modelService.getMetaRule(rule.meta_rule_id); + } + if (rule.metaRule) { + var j = 0; + var k, id; + rule.subjectData = []; + rule.objectData = []; + rule.actionData = []; + for (k = 0; k < rule.metaRule.subject_categories.length; k++) { + id = rule.rule[j + k]; + rule.subjectData.push(policy.subjectDataMap[id]); + } + j += k; + for (k = 0; k < rule.metaRule.object_categories.length; k++) { + id = rule.rule[j + k]; + rule.objectData.push(policy.objectDataMap[id]); + } + j += k; + for (k = 0; k < rule.metaRule.action_categories.length; k++) { + id = rule.rule[j + k]; + rule.actionData.push(policy.actionDataMap[id]); + } + } + return rule; + } + + return { + initialize: loadPolicies, + createPolicies: createPolicies, + policies: policies, + getPolicy: function getPolicy(id) { + return policiesMap[id]; + }, + createPolicy: function createPolicy(policy) { + policyResource.create(null, policy, success, util.displayErrorFunction('Unable to create Policy')); + + function success(data) { + createPolicyInternal(data.policies); + util.displaySuccess('Policy created'); + } + }, + removePolicy: function removePolicy(policy) { + policyResource.remove({ id: policy.id }, null, success, util.displayErrorFunction('Unable to remove Policy')); + + function success(data) { + removePolicyInternal(policy.id); + util.displaySuccess('Policy removed'); + } + }, + updatePolicy: function updatePolicy(policy) { + policyResource.update({ id: policy.id }, policy, success, util.displayErrorFunction('Unable to update Policy')); + + function success(data) { + updatePolicyInternal(data.policies) + util.displaySuccess('Policy updated'); + } + }, + populatePolicy: loadPolicyRule, + createRules: createRules, + addRuleToPolicy: function addRuleToPolicy(policy, rule) { + policyRulesResource.create({ policy_id: policy.id }, rule, success, util.displayErrorFunction('Unable to create Rule')); + + function success(data) { + var rules = util.mapToArray(data.rules); + for (var i = 0; i < rules.length; i++) { + var rule = rules[i]; + policy.rules.push(populateRule(policy, rule)) + } + util.displaySuccess('Rule created'); + updateUnusedData(policy); + } + }, + removeRuleFromPolicy: function removeRuleFromPolicy(policy, rule) { + policyRulesResource.remove({ policy_id: policy.id, rule_id: rule.id }, null, success, util.displayErrorFunction('Unable to remove Rule')); + + function success(data) { + removeRuleInternal(policy, rule); + util.displaySuccess('Rule removed'); + } + }, + createData: function createData(type, policy, category, dataCategory) { + var categoryValue = categoryMap[type]; + return categoryValue.resource.create({ policy_id: policy.id, category_id: category.id }, dataCategory).$promise.then( + function (data) { + var result = util.createInternal(data[categoryValue.responseName].data, policy[categoryValue.arrayName], policy[categoryValue.mapName]); + util.displaySuccess('Data created'); + util.pushAll(policy[categoryValue.unusedArrayName], result); + return result; + }, + util.displayErrorFunction('Unable to create Data') + ); + }, + removeData: function removeData(type, policy, data) { + var categoryValue = categoryMap[type]; + return categoryValue.resource.remove({ policy_id: policy.id, category_id: data.category_id, data_id: data.id }).$promise.then( + function (data) { + policy[categoryValue.arrayName].splice(policy.subjectData.indexOf(data), 1); + policy[categoryValue.unusedArrayName].splice(policy.unusedSubjectData.indexOf(data), 1); + delete policy[categoryValue.mapName][data.id]; + util.displaySuccess('Data removed'); + }, + util.displayErrorFunction('Unable to remove Data') + ); + }, + createPerimeter: function createPerimeter(type, policy, perimeter) { + var categoryValue = categoryMap[type]; + return categoryValue.policyPerimeterResource.create({ policy_id: policy.id }, perimeter).$promise.then( + function (data) { + util.displaySuccess('Perimeter created'); + return util.mapToArray(data[categoryValue.perimeterResponseName]); + }, + util.displayErrorFunction('Unable to create Perimeter') + ); + }, + removePerimeterFromPolicy: function removePerimeterFromPolicy(type, policy, perimeter) { + var categoryValue = categoryMap[type]; + + return categoryValue.policyPerimeterResource.remove({ policy_id: policy.id, perimeter_id: perimeter.id }, null).$promise.then( + function (data) { + util.displaySuccess('Perimeter removed'); + return perimeter; + }, + util.displayErrorFunction('Unable to remove Perimeter') + ) + }, + addPerimeterToPolicy: function addPerimeterToPolicy(type, policy, perimeter) { + var categoryValue = categoryMap[type]; + perimeter.policy_list.push(policy.id); + + return categoryValue.perimeterResource.update({ perimeter_id: perimeter.id }, perimeter).$promise.then( + function (data) { + util.displaySuccess('Perimeter added'); + }, + util.displayErrorFunction('Unable to add Perimeter') + ) + }, + loadPerimetersAndAssignments: function loadPerimetersAndAssignments(type, policy) { + var categoryValue = categoryMap[type]; + var queries = { + allPerimeters: categoryValue.perimeterResource.query().$promise, + perimeters: categoryValue.policyPerimeterResource.query({ policy_id: policy.id }).$promise, + assignments: categoryValue.assignmentResource.query({ policy_id: policy.id }).$promise, + } + + return $q.all(queries).then(function (data) { + var result = {}; + result.assignments = util.mapToArray(data.assignments[categoryValue.assignmentResponseName]); + result.perimetersMap = data.perimeters[categoryValue.perimeterResponseName]; + result.perimeters = util.mapToArray(result.perimetersMap); + result.allPerimeters = util.mapToArray(data.allPerimeters[categoryValue.perimeterResponseName]); + return result; + }, util.displayErrorFunction('Unable to load Perimeters')) + + }, + createAssignment: function createAssignment(type, policy, perimeter, data) { + var categoryValue = categoryMap[type]; + var assignment = { + "id": perimeter.id, + "category_id": data.category_id, + "data_id": data.id, + "policy_id": policy.id + } + return categoryValue.assignmentResource.create({ policy_id: policy.id }, assignment).$promise.then( + function (data) { + util.displaySuccess('Assignment created'); + return util.mapToArray(data[categoryValue.assignmentResponseName]); + }, + util.displayErrorFunction('Unable to create Assignment') + ) + }, + removeAssignment: function removeAssignment(type, policy, perimeter, data) { + var categoryValue = categoryMap[type]; + + return categoryValue.assignmentResource.remove({ policy_id: policy.id, perimeter_id: perimeter.id, category_id: data.category_id, data_id: data.id }, null).$promise.then( + function (data) { + util.displaySuccess('Assignment removed'); + }, + util.displayErrorFunction('Unable to remove Assignment') + ) + }, + } + + } +})(); \ No newline at end of file diff --git a/old/moon_dashboard/moon/static/moon/policy/policy.service.spec.js b/old/moon_dashboard/moon/static/moon/policy/policy.service.spec.js new file mode 100755 index 00000000..8d0ca8bf --- /dev/null +++ b/old/moon_dashboard/moon/static/moon/policy/policy.service.spec.js @@ -0,0 +1,487 @@ +(function () { + 'use strict'; + + describe('moon.policy.service', function () { + var service, modelService, $httpBackend, URI; + var policiesData; + var modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData; + var rulesData, subjectsData, objectsData, actionsData; + + + function initData() { + policiesData = { + policies: + { + 'policyId1': { name: 'policy1', description: 'pDescription1', genre: 'genre1', model_id: 'modelId1' }, + } + }; + + modelsData = { + models: + { 'modelId1': { name: 'model1', description: 'mDescription1', meta_rules: ['metaRuleId1'] } } + }; + + subjectCategoriesData = { + subject_categories: + { + 'subjectCategoryId1': { name: 'subjectCategory1', description: 'scDescription1' }, + 'subjectCategoryId2': { name: 'subjectCategory2', description: 'scDescription2' } + }, + }; + objectCategoriesData = { + object_categories: + { + 'objectCategoryId1': { name: 'objectCategory1', description: 'ocDescription1' }, + 'objectCategoryId2': { name: 'objectCategory2', description: 'ocDescription2' } + } + }; + actionCategoriesData = { + action_categories: + { + 'actionCategoryId1': { name: 'actionCategory1', description: 'acDescription1' }, + 'actionCategoryId2': { name: 'actionCategory2', description: 'acDescription2' } + } + }; + metaRulesData = { + meta_rules: + { + 'metaRuleId1': { name: 'metaRule1', description: 'mrDescription1', subject_categories: ['subjectCategoryId1'], object_categories: ['objectCategoryId1'], action_categories: ['actionCategoryId1'] }, + 'metaRuleId2': { name: 'metaRule2', description: 'mrDescription2', subject_categories: [], object_categories: [], action_categories: [] } + } + }; + } + + function initRuleData() { + rulesData = { + rules: { + rules: [ + { meta_rule_id: 'metaRuleId1', rule: ['subjectId1', 'objectId1', 'actionId1'], id: 'ruleId1', instructions: { test: 'test' } } + ] + } + }; + + subjectsData = { + subject_data: + [ + { + data: { + 'subjectId1': { name: 'subject1', description: 'sDescription1' }, + } + } + ] + }; + objectsData = { + object_data: + [ + { + data: { + 'objectId1': { name: 'object1', description: 'oDescription1' }, + } + } + ] + }; + actionsData = { + action_data: + [ + { + data: { + 'actionId1': { name: 'action1', description: 'aDescription1' }, + } + } + ] + }; + } + + beforeEach(module('horizon.app.core')); + beforeEach(module('horizon.framework')); + beforeEach(module('moon')); + + beforeEach(inject(function ($injector) { + service = $injector.get('moon.policy.service'); + modelService = $injector.get('moon.model.service'); + $httpBackend = $injector.get('$httpBackend'); + URI = $injector.get('moon.URI'); + })); + + afterEach(function () { + $httpBackend.verifyNoOutstandingExpectation(); + $httpBackend.verifyNoOutstandingRequest(); + }); + + it('should initialize', function () { + initData(); + $httpBackend.expectGET(URI.API + '/policies').respond(200, policiesData); + $httpBackend.expectGET(URI.API + '/subject_categories').respond(200, subjectCategoriesData); + $httpBackend.expectGET(URI.API + '/object_categories').respond(200, objectCategoriesData); + $httpBackend.expectGET(URI.API + '/action_categories').respond(200, actionCategoriesData); + $httpBackend.expectGET(URI.API + '/meta_rules').respond(200, metaRulesData); + $httpBackend.expectGET(URI.API + '/models').respond(200, modelsData); + + + service.initialize(); + $httpBackend.flush(); + + expect(service.policies.length).toBe(1); + var policy = service.policies[0]; + expect(policy.id).toBe('policyId1'); + expect(policy.name).toBe('policy1'); + expect(policy.description).toBe('pDescription1'); + expect(policy.genre).toBe('genre1'); + expect(policy.model.id).toBe('modelId1'); + + }); + + + + it('should create policy', function () { + initData(); + modelService.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData); + + var policyCreatedData = { + policies: + { 'policyId1': { name: 'policy1', description: 'pDescription1', genre: 'genre1', model_id: 'modelId1' } } + }; + + $httpBackend.expectPOST(URI.API + '/policies').respond(200, policyCreatedData); + + service.createPolicy({ name: 'policy1', description: 'pDescription1', genre: 'genre1', model: modelService.getModel('modelId1') }); + $httpBackend.flush(); + + expect(service.policies.length).toBe(1); + var policy = service.policies[0]; + expect(policy.id).toBe('policyId1'); + expect(policy.name).toBe('policy1'); + expect(policy.description).toBe('pDescription1'); + expect(policy.genre).toBe('genre1'); + expect(policy.model.id).toBe('modelId1'); + }); + + it('should remove policy', function () { + initData(); + modelService.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData); + service.createPolicies(policiesData); + + $httpBackend.expectDELETE(URI.API + '/policies/policyId1').respond(200); + + service.removePolicy({ id: 'policyId1' }); + $httpBackend.flush(); + + expect(service.policies.length).toBe(0); + }); + + it('should update policy', function () { + initData(); + var policyUpdatedData = { + policies: + { 'policyId1': { name: 'policy2', description: 'pDescription2', genre: 'genre2', model_id: 'modelId1' } } + }; + modelService.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData); + service.createPolicies(policiesData); + + $httpBackend.expectPATCH(URI.API + '/policies/policyId1').respond(200, policyUpdatedData); + + service.updatePolicy({ id: 'policyId1', name: 'policy2', description: 'pDescription2', genre: 'genre2', model: modelService.getModel('modelId1') }); + $httpBackend.flush(); + + expect(service.policies.length).toBe(1); + var policy = service.policies[0]; + expect(policy.id).toBe('policyId1'); + expect(policy.name).toBe('policy2'); + expect(policy.description).toBe('pDescription2'); + expect(policy.genre).toBe('genre2'); + expect(policy.model.id).toBe('modelId1'); + + }); + + + it('should populate policy', function () { + initData(); + initRuleData(); + modelService.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData); + service.createPolicies(policiesData); + + var policy = service.getPolicy('policyId1') + + $httpBackend.expectGET(URI.API + '/policies/policyId1/rules').respond(200, rulesData); + $httpBackend.expectGET(URI.API + '/policies/policyId1/subject_data').respond(200, subjectsData); + $httpBackend.expectGET(URI.API + '/policies/policyId1/object_data').respond(200, objectsData); + $httpBackend.expectGET(URI.API + '/policies/policyId1/action_data').respond(200, actionsData); + + service.populatePolicy(policy); + $httpBackend.flush(); + + expect(policy.rules.length).toBe(1); + var rule = policy.rules[0]; + expect(rule.id).toBe('ruleId1'); + expect(rule.metaRule.id).toBe('metaRuleId1'); + expect(rule.instructions.test).toBe('test'); + expect(rule.subjectData.length).toBe(1); + expect(rule.subjectData[0].id).toBe('subjectId1'); + expect(rule.objectData.length).toBe(1); + expect(rule.objectData[0].id).toBe('objectId1'); + expect(rule.actionData.length).toBe(1); + expect(rule.actionData[0].id).toBe('actionId1'); + + expect(policy.subjectData.length).toBe(1); + var subjectData = policy.subjectData[0]; + expect(subjectData.id).toBe('subjectId1'); + expect(subjectData.name).toBe('subject1'); + expect(subjectData.description).toBe('sDescription1'); + + expect(policy.objectData.length).toBe(1); + var objectData = policy.objectData[0]; + expect(objectData.id).toBe('objectId1'); + expect(objectData.name).toBe('object1'); + expect(objectData.description).toBe('oDescription1'); + + expect(policy.actionData.length).toBe(1); + var actionData = policy.actionData[0]; + expect(actionData.id).toBe('actionId1'); + expect(actionData.name).toBe('action1'); + expect(actionData.description).toBe('aDescription1'); + + }); + + + it('should add rule to policy', function () { + initData(); + initRuleData(); + modelService.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData); + service.createPolicies(policiesData); + + + var ruleCreatedData = { + rules: { + 'ruleId1': { meta_rule_id: 'metaRuleId1', rule: ['subjectId1', 'objectId1', 'actionId1'], instructions: { test: 'test' } } + } + }; + + var policy = service.getPolicy('policyId1'); + + service.createRules(policy, null, subjectsData, objectsData, actionsData); + + $httpBackend.expectPOST(URI.API + '/policies/policyId1/rules').respond(200, ruleCreatedData); + + service.addRuleToPolicy(policy, { meta_rule_id: 'metaRuleId1', rule: ['subjectId1', 'objectId1', 'actionId1'], instructions: { test: 'test' } }); + $httpBackend.flush(); + + expect(policy.rules.length).toBe(1); + var rule = policy.rules[0]; + expect(rule.id).toBe('ruleId1'); + expect(rule.metaRule.id).toBe('metaRuleId1'); + expect(rule.subjectData.length).toBe(1); + expect(rule.subjectData[0].id).toBe('subjectId1'); + expect(rule.objectData.length).toBe(1); + expect(rule.objectData[0].id).toBe('objectId1'); + expect(rule.actionData.length).toBe(1); + expect(rule.actionData[0].id).toBe('actionId1'); + + }); + + it('should remove rule from policy', function () { + initData(); + initRuleData(); + modelService.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData); + service.createPolicies(policiesData); + + var policy = service.getPolicy('policyId1'); + + service.createRules(policy, rulesData, subjectsData, objectsData, actionsData); + + $httpBackend.expectDELETE(URI.API + '/policies/policyId1/rules/ruleId1').respond(200); + + service.removeRuleFromPolicy(policy, { id: 'ruleId1' }); + $httpBackend.flush(); + + expect(policy.rules.length).toBe(0); + }); + + + it('should create data', function () { + initData(); + initRuleData(); + modelService.createModels(modelsData, metaRulesData, subjectCategoriesData, objectCategoriesData, actionCategoriesData); + service.createPolicies(policiesData); + + + var dataCreatedData = { + subject_data: { + data: { + 'subjectId1': { name: 'subject1', description: 'sDescription1' }, + } + } + }; + + var policy = service.getPolicy('policyId1'); + policy.subjectData = []; + policy.subjectDataMap = {}; + + $httpBackend.expectPOST(URI.API + '/policies/policyId1/subject_data/subjectCategoryId1').respond(200, dataCreatedData); + + service.createData('subject', policy, modelService.getCategory('subject', 'subjectCategoryId1'), { name: 'subject1', description: 'sDescription1' }); + $httpBackend.flush(); + + expect(policy.subjectData.length).toBe(1); + var subjectData = policy.subjectData[0]; + expect(subjectData.id).toBe('subjectId1'); + expect(subjectData.name).toBe('subject1'); + expect(subjectData.description).toBe('sDescription1'); + + }); + + it('should create perimeter', function () { + var perimeterCreatedData = { + subjects: { + 'subjectId1': { name: 'subject1', description: 'sDescription1' }, + } + }; + + $httpBackend.expectPOST(URI.API + '/policies/policyId1/subjects').respond(200, perimeterCreatedData); + var type = 'subject'; + var policy = { id: 'policyId1' }; + var perimeter = { name: 'subject1', description: 'sDescription1' }; + + var promise = service.createPerimeter(type, policy, perimeter); + $httpBackend.flush(); + + promise.then(function (result) { + expect(result.length).toBe(1); + var perimeter = result[0]; + expect(perimeter.id).toBe('subjectId1'); + expect(perimeter.name).toBe('subject1'); + expect(perimeter.description).toBe('sDescription1'); + }) + }); + + it('should remove perimeter', function () { + $httpBackend.expectDELETE(URI.API + '/policies/policyId1/subjects/subjectId1').respond(200); + var type = 'subject'; + var policy = { id: 'policyId1' }; + var perimeter = { id: 'subjectId1' }; + + var promise = service.removePerimeterFromPolicy(type, policy, perimeter); + $httpBackend.flush(); + + promise.then(function (result) { + expect(result.id).toBe('subjectId1'); + }) + }); + + it('should load perimeters and assignments', function () { + var assignmentsData = { + subject_assignments: { + 'subjectAssignmentId1': { + id: 'subjectAssignmentId1', + policy_id: 'policyId1', + subject_id: 'subjectId1', + category_id: 'subjectCategoryId1', + assignments: ['subjectDataId1'] + }, + } + }; + + var perimetersData = { + subjects: { + 'subjectId1': { name: 'subject1', description: 'sDescription1' }, + } + }; + + var allPerimetersData = { + subjects: { + 'subjectId1': { name: 'subject1', description: 'sDescription1' }, + 'subjectId2': { name: 'subject2', description: 'sDescription2' }, + } + }; + + var type = 'subject'; + var policy = { id: 'policyId1' }; + $httpBackend.expectGET(URI.API + '/subjects').respond(200, allPerimetersData); + $httpBackend.expectGET(URI.API + '/policies/policyId1/subjects').respond(200, perimetersData); + $httpBackend.expectGET(URI.API + '/policies/policyId1/subject_assignments').respond(200, assignmentsData); + + var promise = service.loadPerimetersAndAssignments(type, policy); + + $httpBackend.flush(); + + promise.then(function (result) { + expect(result.perimeters.length).toBe(1); + var perimeter = result.perimeters[0]; + expect(perimeter.id).toBe('subjectId1'); + expect(perimeter.name).toBe('subject1'); + expect(perimeter.description).toBe('sDescription1'); + + expect(result.allPerimeters.length).toBe(2); + perimeter = result.allPerimeters[0]; + expect(perimeter.id).toBe('subjectId1'); + expect(perimeter.name).toBe('subject1'); + expect(perimeter.description).toBe('sDescription1'); + + perimeter = result.allPerimeters[1]; + expect(perimeter.id).toBe('subjectId2'); + expect(perimeter.name).toBe('subject2'); + expect(perimeter.description).toBe('sDescription2'); + + + expect(result.assignments.length).toBe(1); + var assignment = result.assignments[0]; + expect(assignment.id).toBe('subjectAssignmentId1'); + expect(assignment.policy_id).toBe('policyId1'); + expect(assignment.subject_id).toBe('subjectId1'); + expect(assignment.category_id).toBe('subjectCategoryId1'); + expect(assignment.assignments.length).toBe(1); + expect(assignment.assignments[0]).toBe('subjectDataId1'); + }) + + }); + + it('should create assignment', function () { + var assignmentCreatedData = { + subject_assignments: { + 'subjectAssignmentId1': { + id: 'subjectAssignmentId1', + policy_id: 'policyId1', + subject_id: 'subjectId1', + category_id: 'subjectCategoryId1', + assignments: ['subjectDataId1'] + }, + } + }; + + var type = 'subject'; + var policy = { id: 'policyId1' }; + var perimeter = { id: 'subjectId1' }; + var data = { id: 'subjectDataId1', category_id: 'subjectCategoryId1'}; + + $httpBackend.expectPOST(URI.API + '/policies/policyId1/subject_assignments').respond(200, assignmentCreatedData); + var promise = service.createAssignment(type, policy, perimeter, data); + + $httpBackend.flush(); + + promise.then(function (result) { + expect(result.length).toBe(1); + var assignment = result[0]; + expect(assignment.id).toBe('subjectAssignmentId1'); + expect(assignment.policy_id).toBe('policyId1'); + expect(assignment.subject_id).toBe('subjectId1'); + expect(assignment.category_id).toBe('subjectCategoryId1'); + expect(assignment.assignments.length).toBe(1); + expect(assignment.assignments[0]).toBe('subjectDataId1'); + }) + }); + + it('should remove assignment', function () { + var type = 'subject'; + var policy = { id: 'policyId1' }; + var perimeter = { id: 'subjectId1' }; + var data = { id: 'subjectDataId1', category_id: 'subjectCategoryId1'}; + + $httpBackend.expectDELETE(URI.API + '/policies/policyId1/subject_assignments/subjectId1/subjectCategoryId1/subjectDataId1').respond(200); + service.removeAssignment(type, policy, perimeter, data); + $httpBackend.flush(); + }); + + + }); + + +})(); \ No newline at end of file diff --git a/old/moon_dashboard/moon/static/moon/scss/moon.scss b/old/moon_dashboard/moon/static/moon/scss/moon.scss new file mode 100644 index 00000000..3cdbb6e3 --- /dev/null +++ b/old/moon_dashboard/moon/static/moon/scss/moon.scss @@ -0,0 +1,58 @@ +.inline { + display: inline; +} + +.inline-block { + display: inline-block; +} + +summary{ + outline:none; + margin-bottom: 10px; +} + +details { + cursor: default; +} + +.filter { + display: inline-block; + width: auto; + vertical-align: middle; +} + +.categories td { + width: 33%; +} + +.width-200 { + width: 200px; +} + +.height-200 { + height: 200px; +} + +.border { + border: 1px #DDD solid; +} + +.padding-10 { + padding: 10px; +} + +.scroll { + overflow-y: auto; +} + +.mt-5 { + margin-top: 5px; +} + +.input-file { + display: none !important; +} + +.overflow-hidden { + overflow: hidden; +} \ No newline at end of file diff --git a/old/moon_dashboard/moon/templates/moon/base.html b/old/moon_dashboard/moon/templates/moon/base.html new file mode 100644 index 00000000..f07a01ba --- /dev/null +++ b/old/moon_dashboard/moon/templates/moon/base.html @@ -0,0 +1,11 @@ +{% load horizon %}{% jstemplate %}[% extends 'base.html' %] + +[% block sidebar %] + [% include 'horizon/common/_sidebar.html' %] +[% endblock %] + +[% block main %] + [% include "horizon/_messages.html" %] + [% block {{ dash_name }}_main %][% endblock %] +[% endblock %] +{% endjstemplate %} diff --git a/old/moon_dashboard/run.sh b/old/moon_dashboard/run.sh new file mode 100644 index 00000000..9a68ca6e --- /dev/null +++ b/old/moon_dashboard/run.sh @@ -0,0 +1,42 @@ +#!/bin/sh +# sudo docker run -ti --rm -p 8000:8000 -e MANAGER_HOST=localhost -e MANAGER_PORT=30001 -e KEYSTONE_HOST=localhost -e KEYSTONE_PORT=30005 moonplatform/dashboard:dev + +echo ----------------------------------- +export OPENSTACK_KEYSTONE_URL="http://${KEYSTONE_HOST}:${KEYSTONE_PORT}/identity/v3" +echo MANAGER_HOST=${MANAGER_HOST} +echo MANAGER_PORT=${MANAGER_PORT} +echo KEYSTONE_HOST=${KEYSTONE_HOST} +echo KEYSTONE_PORT=${KEYSTONE_PORT} +echo OPENSTACK_HOST=${OPENSTACK_HOST} +echo OPENSTACK_KEYSTONE_URL=${OPENSTACK_KEYSTONE_URL} +echo SERVER_IP_ADDR=${SERVER_IP_ADDR} +echo ----------------------------------- + +CONSTANT_FILE=/root/horizon/openstack_dashboard/dashboards/moon/static/moon/js/moon.module.js + +sed "s/{{MANAGER_HOST}}/${MANAGER_HOST}/g" -i ${CONSTANT_FILE} +sed "s/{{MANAGER_PORT}}/${MANAGER_PORT}/g" -i ${CONSTANT_FILE} +sed "s/{{KEYSTONE_HOST}}/${KEYSTONE_HOST}/g" -i ${CONSTANT_FILE} +sed "s/{{KEYSTONE_PORT}}/${KEYSTONE_PORT}/g" -i ${CONSTANT_FILE} + +cd /root/horizon + +LOCAL_SETTINGS=/root/horizon/openstack_dashboard/local/local_settings.py + +sed "s/OPENSTACK_HOST = \"127.0.0.1\"/OPENSTACK_HOST = \"${OPENSTACK_HOST}\"/" -i ${LOCAL_SETTINGS} +sed "s#OPENSTACK_KEYSTONE_URL = \"http://%s:5000/v3\" % OPENSTACK_HOST#OPENSTACK_KEYSTONE_URL = \"${OPENSTACK_KEYSTONE_URL}\"#" -i ${LOCAL_SETTINGS} +sed "s/#ALLOWED_HOSTS = \['horizon.example.com', \]/ALLOWED_HOSTS = \['${SERVER_IP_ADDR}'\]/" -i ${LOCAL_SETTINGS} + +echo ----------------- +grep OPENSTACK_HOST ${LOCAL_SETTINGS} +grep ALLOWED_HOSTS ${LOCAL_SETTINGS} +echo ----------------- +export NO_PROXY=127.0.0.1,10.0.2.15,10.96.0.0/12,192.168.0.0/16,10.192.118.95,10.192.118.96,keystone,manager,devstack + +echo "${KEYSTONE_HOST} devstack, keystone" | tee -a /etc/hosts + +echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ${CONSTANT_FILE}" +cat ${CONSTANT_FILE} +echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + +tox -e runserver -- 0.0.0.0:8000 diff --git a/old/moon_dashboard/setup.cfg b/old/moon_dashboard/setup.cfg new file mode 100644 index 00000000..9cf3f779 --- /dev/null +++ b/old/moon_dashboard/setup.cfg @@ -0,0 +1,24 @@ +[metadata] +name = moon +version=1.5.0 +summary = A dashboard plugin for Moon +description-file = + README.rst +author = Jonathan Gourdin +author_email = jonathan.gourdin@orange.com +home-page = https://docs.openstack.org/horizon/latest/ +classifiers = [ + Environment :: OpenStack + Framework :: Django + Intended Audience :: Developers + Intended Audience :: System Administrators + License :: OSI Approved :: Apache Software License + Operating System :: POSIX :: Linux + Programming Language :: Python + Programming Language :: Python :: 2 + Programming Language :: Python :: 2.7 + Programming Language :: Python :: 3.5 + +[files] +packages = + moon \ No newline at end of file diff --git a/old/moon_dashboard/setup.py b/old/moon_dashboard/setup.py new file mode 100644 index 00000000..4794e334 --- /dev/null +++ b/old/moon_dashboard/setup.py @@ -0,0 +1,14 @@ +# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT +import setuptools + +# In python < 2.7.4, a lazy loading of package `pbr` will break +# setuptools if some other modules registered functions in `atexit`. +# solution from: http://bugs.python.org/issue15881#msg170215 +try: + import multiprocessing # noqa +except ImportError: + pass + +setuptools.setup( + setup_requires=['pbr>=1.8'], + pbr=True) \ No newline at end of file diff --git a/old/moon_forming/.gitignore b/old/moon_forming/.gitignore new file mode 100644 index 00000000..7bff7318 --- /dev/null +++ b/old/moon_forming/.gitignore @@ -0,0 +1,105 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + diff --git a/old/moon_forming/Changelog b/old/moon_forming/Changelog new file mode 100644 index 00000000..a107efd9 --- /dev/null +++ b/old/moon_forming/Changelog @@ -0,0 +1,11 @@ +CHANGES +======= + +1.4.0 +----- +- Update the python_moondb version to 1.2.10 + +1.4.1 +----- +- Update the python_moondb version to 1.2.16 + diff --git a/old/moon_forming/Dockerfile b/old/moon_forming/Dockerfile new file mode 100644 index 00000000..3a39880b --- /dev/null +++ b/old/moon_forming/Dockerfile @@ -0,0 +1,17 @@ +FROM python:3 + + +LABEL Name=Forming +LABEL Description="Configuration job for the Moon platform" +LABEL Maintainer="Thomas Duval" +LABEL Url="https://wiki.opnfv.org/display/moon/Moon+Project+Proposal" + +USER root + +WORKDIR /usr/src/app +RUN pip install --no-cache-dir --upgrade requests pytest pyyaml python_moonutilities python_moondb python_moonclient + +ADD . /root +WORKDIR /root + +CMD /bin/bash /root/config_moon.sh diff --git a/old/moon_forming/README.md b/old/moon_forming/README.md new file mode 100644 index 00000000..9b755d96 --- /dev/null +++ b/old/moon_forming/README.md @@ -0,0 +1,47 @@ +# Moon Forming +moon_forming is a container to automatize the configuration of the Moon platform + +## Run +```bash +docker run wukongsun/moon_forming:latest +``` + +## Consul +The Moon platform is already configured after the installation. +If you want to see or modify the configuration, go with a web browser +to the following page: `http://localhost:30006`. + +With the consul server, you can update the configuration in the `KEY/VALUE` tab. +There are some configuration items, lots of them are only read when a new K8S pod is started +and not during its life cycle. + +**WARNING: some confidential information are put here in clear text. +This is a known security issue.** + +### Keystone +If you have your own Keystone server, you can point Moon to your Keystone in the +`openstack/keystone` element: `http://localhost:30005/ui/#/dc1/kv/openstack/keystone/edit`. +This configuration element is read every time Moon need it, specially when adding users. + +### Database +The database can also be modified through: `http://localhost:30005/ui/#/dc1/kv/database/edit`. + +**WARNING: the password is in clear text, this is a known security issue.** + +If you want to use your own database server, change the configuration: + + {"url": "mysql+pymysql://my_user:my_secret_password@my_server/moon", "driver": "sql"} + +Then you have to rebuild the database before using it. +This can be done with the following commands: +```bash +kubectl delete -f $MOON_HOME/tools/moon_kubernetes/templates/moon_forming.yaml +kubectl create -f $MOON_HOME/tools/moon_kubernetes/templates/moon_forming.yaml +``` + +## Functional tests + +```bash +cd $MOON_HOME/moon_manager +bash ../tests/functional/run_tests_for_component.sh +``` diff --git a/old/moon_forming/conf2consul.py b/old/moon_forming/conf2consul.py new file mode 100644 index 00000000..df7a6b18 --- /dev/null +++ b/old/moon_forming/conf2consul.py @@ -0,0 +1,104 @@ +import os +import sys +import requests +import yaml +import logging +import json +import base64 + +__version__ = "1.4.1" + +logging.basicConfig(level=logging.INFO) +log = logging.getLogger("moon.conf2consul") +requests_log = logging.getLogger("requests.packages.urllib3") +requests_log.setLevel(logging.WARNING) +requests_log.propagate = True + +if len(sys.argv) == 2: + if os.path.isfile(sys.argv[1]): + CONF_FILENAME = sys.argv[1] + CONSUL_HOST = "consul" + else: + CONF_FILENAME = "moon.conf" + CONSUL_HOST = sys.argv[1] + CONSUL_PORT = 8500 +else: + CONSUL_HOST = sys.argv[1] if len(sys.argv) > 1 else "consul" + CONSUL_PORT = sys.argv[2] if len(sys.argv) > 2 else 8500 + CONF_FILENAME = sys.argv[3] if len(sys.argv) > 3 else "moon.conf" +HEADERS = {"content-type": "application/json"} + + +def search_config_file(): + data_config = None + for _file in ( + CONF_FILENAME, + "conf/moon.conf", + "../moon.conf", + "../conf/moon.conf", + "/etc/moon/moon.conf", + ): + try: + data_config = yaml.safe_load(open(_file)) + except FileNotFoundError: + data_config = None + continue + else: + break + if not data_config: + raise Exception("Configuration file not found...") + return data_config + + +def put(key, value): + url = "http://{host}:{port}/v1/kv/{key}".format(host=CONSUL_HOST, port=CONSUL_PORT, key=key) + log.info(url) + req = requests.put( + url, + headers=HEADERS, + json=value + ) + if req.status_code != 200: + raise Exception("Error connecting to Consul ({}, {})".format(req.status_code, req.text)) + + +def get(key): + url = "http://{host}:{port}/v1/kv/{key}".format(host=CONSUL_HOST, port=CONSUL_PORT, key=key) + req = requests.get(url) + data = req.json() + for item in data: + log.info("{} {} -> {}".format( + req.status_code, + item["Key"], + json.loads(base64.b64decode(item["Value"]).decode("utf-8")) + )) + yield json.loads(base64.b64decode(item["Value"]).decode("utf-8")) + + +def main(): + data_config = search_config_file() + req = requests.head("http://{}:{}/ui/".format(CONSUL_HOST, CONSUL_PORT)) + if req.status_code != 200: + log.critical("Consul is down...") + log.critical("request info: {}/{}".format(req, req.text)) + sys.exit(1) + + put("database", data_config["database"]) + # put("messenger", data_config["messenger"]) + # put("slave", data_config["slave"]) + # put("docker", data_config["docker"]) + put("logging", data_config["logging"]) + # put("components_port_start", data_config["components"]["port_start"]) + + for _key, _value in data_config["components"].items(): + put("components/{}".format(_key), data_config["components"][_key]) + + # for _key, _value in data_config["plugins"].items(): + # put("plugins/{}".format(_key), data_config["plugins"][_key]) + + for _key, _value in data_config["openstack"].items(): + put("openstack/{}".format(_key), data_config["openstack"][_key]) + + +main() + diff --git a/old/moon_forming/config_moon.sh b/old/moon_forming/config_moon.sh new file mode 100644 index 00000000..0a55898f --- /dev/null +++ b/old/moon_forming/config_moon.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +populate_args=$* + +echo "Waiting for Consul (http://consul:8500)" +while ! python -c "import requests; req = requests.get('http://consul:8500')" 2>/dev/null ; do + sleep 5 ; + echo -n "." +done +echo "." +echo "Consul (http://consul:8500) is up." + +python3 /root/conf2consul.py /etc/moon/moon.conf + +echo "Waiting for DB (tcp://db:3306)" +while ! python -c "import socket, sys; s = socket.socket(socket.AF_INET, socket.SOCK_STREAM); s.connect(('db', 3306)); sys.exit(0)" 2>/dev/null ; do + sleep 5 ; + echo -n "." +done +echo "." +echo "Database (http://db:3306) is up." + +moon_db_manager upgrade + +echo "Waiting for Keystone (http://keystone:5000)" +while ! python -c "import requests; req = requests.get('http://keystone:5000')" 2>/dev/null ; do + sleep 5 ; + echo -n "." +done +echo "." +echo "Keystone (http://keystone:5000) is up." + +echo "Waiting for Manager (http://manager:8082)" +while ! python -c "import requests; req = requests.get('http://manager:8082')" 2>/dev/null ; do + sleep 5 ; + echo -n "." +done +echo "." +echo "Manager (http://manager:8082) is up." diff --git a/old/moon_gui/.gitignore b/old/moon_gui/.gitignore new file mode 100644 index 00000000..04bca1bc --- /dev/null +++ b/old/moon_gui/.gitignore @@ -0,0 +1,4 @@ +db.sqlite3 +idea/* +node_modules/* +dist/ \ No newline at end of file diff --git a/old/moon_gui/.jshintrc b/old/moon_gui/.jshintrc new file mode 100644 index 00000000..b9955f87 --- /dev/null +++ b/old/moon_gui/.jshintrc @@ -0,0 +1,59 @@ + +{ + "bitwise": true, + "camelcase": false, + "curly": true, + "eqeqeq": true, + "esversion": 6, + "forin": true, + "freeze": true, + "immed": true, + "indent": 4, + "latedef": "nofunc", + "newcap": true, + "noarg": true, + "noempty": true, + "nonbsp": true, + "nonew": true, + "plusplus": false, + "quotmark": "single", + "undef": true, + "unused": false, + "strict": true, + "maxparams": 20, + "maxdepth": 5, + "maxstatements": 40, + "maxcomplexity": 8, + "maxlen": 160, + "asi": false, + "boss": false, + "debug": false, + "eqnull": true, + "esnext": false, + "evil": false, + "expr": false, + "funcscope": false, + "globalstrict": false, + "iterator": false, + "lastsemic": false, + "laxbreak": false, + "laxcomma": false, + "loopfunc": true, + "maxerr": 50, + "moz": false, + "multistr": false, + "notypeof": false, + "proto": false, + "scripturl": false, + "shadow": false, + "sub": true, + "supernew": false, + "validthis": true, + "noyield": false, + "browser": true, + "node": true, + "globals": { + "angular": false, + "_": false + } +} \ No newline at end of file diff --git a/old/moon_gui/DEV.md b/old/moon_gui/DEV.md new file mode 100644 index 00000000..1bd1ef4c --- /dev/null +++ b/old/moon_gui/DEV.md @@ -0,0 +1,49 @@ +# How-to develop on the Moon platform + +## Install the platform + +Follow the `moon/moonv4/README.md` file. + +## GUI + +The GUI code is located at `moon/moonv4/moon_gui` +The configuration values is at `moonv4/moon_gui/static/app/moon.constants.js` + +To be able to only develop the GUI, you can install the Moon platform and run the GUI outside the platform. +To link the outside GUI to the Moon Manager, you must update the configuration values and specially the +following variables : + +- `{{MANAGER_HOST}}` : the hostname of the Manager (example: 127.0.0.1) +- `{{MANAGER_PORT}}` : the TCP port of the Manager (30001) +- `{{KEYSTONE_HOST}}` : the hostname of the Keystone server (example: 127.0.0.1) +- `{{KEYSTONE_PORT}}` : the TCP port of the Keystone server (30006) + +To run the GUI service, follow the `README.md` file. + +## Current bugs + +1) ~~Models -> "`List of Meta rules`", after updating the meta_rule +"`Actions` -> `edit`" and clicking on `close`, the main screen doesn't refresh~~ + +2) ~~idem if we want to remove the meta_rule~~ + +3) ~~after deleting an action perimeter (`Policy` -> `Add an action` -> `select a perimeter` and delete it), +the dropdown list is not updated~~ + +4) ~~when adding a data subject (`Policy` -> `Data` -> `Add a Data Subject`), only the right category names must +be listed in `Catagory list`. Hide the categories that doesn't belong to that policy.~~ + +5) ~~idem for object data~~ + +6) ~~idem for action data~~ + +7) ~~after adding data (subject, object, action), the dropdown list in `Rules` -> `Add a rules` are not updated +if the page is not manually refresh by the user and if the `Rules` window is already showing.~~ + +8) ~~typographic error in `Add a rules`~~ + +9) ~~in `Data` -> `Add a Data Object`, the `Create Data` never create the data in the backend~~ + +10) ~~Move the `project` tabular to the end~~ + +11) create a simplified version (to be discussed) diff --git a/old/moon_gui/Dockerfile b/old/moon_gui/Dockerfile new file mode 100644 index 00000000..428e1037 --- /dev/null +++ b/old/moon_gui/Dockerfile @@ -0,0 +1,18 @@ +FROM ubuntu:latest + +RUN apt update && apt install git nodejs nodejs-legacy npm apache2 -y +RUN npm install --global gulp-cli + +ENV MANAGER_HOST="127.0.0.1" +ENV MANAGER_PORT=8080 +ENV KEYSTONE_HOST="127.0.0.1" +ENV KEYSTONE_PORT=5000 + +ADD . /root +WORKDIR /root/ + +RUN npm install + +#CMD ["gulp"] +#CMD ["gulp", "webServerDelivery"] +CMD ["sh", "/root/run.sh"] \ No newline at end of file diff --git a/old/moon_gui/README.md b/old/moon_gui/README.md new file mode 100644 index 00000000..ea46b079 --- /dev/null +++ b/old/moon_gui/README.md @@ -0,0 +1,71 @@ +# GUI for the Moon project +This directory contains all the code for the Moon project +It is designed to provide a running GUI of the Moon platform instance. + +## Usage +- Prerequist + - `sudo apt-get install nodejs nodejs-legacy` + - `sudo npm install --global gulp-cli` +- Install all packages + - `cd $MOON_HOME/moon_gui` + - `sudo npm install` +- Run the GUI + - `gulp webServerDelivery` + - Open your web browser + +## Configuration +- build the delivery package: `gulp delivery` +- launch the Web Server: `gulp webServerDelivery` + +## Development +- during the development it is possible to use following commands: `gulp build` +- launch a Web Server: `gulp webServer` +- Gulp webServer will refresh the browser when a file related to the application changed +- it is possible to change some constants (API endpoints): `$MOON_HOME/moon_gui/static/app/moon.constants.js` + +## CORS +The GUI need to connect itself to Keystone and Moon. +Opening CORS to the GUI WebServer is required. +- modify Keystone: `$MOON_HOME/tools/moon_keystone/run.sh` +- modify Moon: `$MOON_HOME/moon_interface/interface/http_server.py` + +## Usage +After authentication, you will see 4 tabs: Project, Models, Policies, PDP: + +* *Projects*: configure mapping between Keystone projects and PDP (Policy Decision Point) +* *Models*: configure templates of policies (for example RBAC or MLS) +* *Policies*: applied models or instantiated models ; +on one policy, you map a authorisation model and set subject, objects and action that will +rely on that model +* *PDP*: Policy Decision Point, this is the link between Policies and Keystone Project + +In the following paragraphs, we will add a new user in OpenStack and allow her to list +all VM on the OpenStack platform. + +First, add a new user and a new project in the OpenStack platform: + + openstack user create --password-prompt demo_user + openstack project create demo + DEMO_USER=$(openstack user list | grep demo_user | cut -d " " -f 2) + DEMO_PROJECT=$(openstack project list | grep demo | cut -d " " -f 2) + openstack role add --user $DEMO_USER --project $DEMO_PROJECT admin + +You have to add the same user in the Moon interface: + +1. go to the `Projects` tab in the Moon interface +1. go to the line corresponding to the new project and click to the `Map to a PDP` link +1. select in the combobox the MLS PDP and click `OK` +1. in the Moon interface, go to the `Policy` tab +1. go to the line corresponding to the MLS policy and click on the `actions->edit` button +1. scroll to the `Perimeters` line and click on the `show` link to show the perimeter configuration +1. go to the `Add a subject` line and click on `Add a new perimeter` +1. set the name of that subject to `demo_user` (*the name must be strictly identical*) +1. in the combobox named `Policy list` select the `MLS` policy and click on the `+` button +1. click on the yellow `Add Perimeter` button +1. go to the `Assignment` line and click on the `show` button +1. under the `Add a Assignments Subject` select the MLS policy, +the new user (`demo_user`), the category `subject_category_level` +1. in the `Select a Data` line, choose the `High` scope and click on the `+` link +1. click on the yellow `Create Assignments` button +1. if you go to the OpenStack platform, the `demo_user` is now allow to connect +to the Nova component (test with `openstack server list` connected with the `demo_user`) \ No newline at end of file diff --git a/old/moon_gui/delivery/assets/css/main.css b/old/moon_gui/delivery/assets/css/main.css new file mode 100644 index 00000000..3aefca39 --- /dev/null +++ b/old/moon_gui/delivery/assets/css/main.css @@ -0,0 +1,10 @@ +/*! + * Bootstrap v3.2.0 (http://getbootstrap.com) + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.1 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:0 0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}@media print{*{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.table td,.table th{background-color:#fff!important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:transparent}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#428bca;text-decoration:none}a:focus,a:hover{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}cite{font-style:normal}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#428bca}a.text-primary:hover{color:#3071a9}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#428bca}a.bg-primary:hover{background-color:#3071a9}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}blockquote:after,blockquote:before{content:""}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#777;opacity:1}.form-control:-ms-input-placeholder{color:#777}.form-control::-webkit-input-placeholder{color:#777}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{line-height:34px}input[type=date].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm,input[type=time].input-sm{line-height:30px}input[type=date].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg,input[type=time].input-lg{line-height:46px}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;min-height:20px;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.form-horizontal .form-group-sm .form-control,.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-horizontal .form-group-lg .form-control,.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:25px;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{top:0;right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.3px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active:focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.active,.btn-default:active,.btn-default:focus,.btn-default:hover,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary.active,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#3071a9;border-color:#285e8e}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#428bca;border-color:#357ebd}.btn-primary .badge{color:#428bca;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.active,.btn-success:active,.btn-success:focus,.btn-success:hover,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.active,.btn-info:active,.btn-info:focus,.btn-info:hover,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.active,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.active,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#428bca;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#428bca;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group-vertical>.btn:focus,.btn-group>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn>input[type=checkbox],[data-toggle=buttons]>.btn>input[type=radio]{position:absolute;z-index:-1;opacity:0}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#428bca}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#428bca}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030;-webkit-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}.navbar-nav.navbar-right:last-child{margin-right:-15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-form.navbar-right:last-child{margin-right:-15px}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}.navbar-text.navbar-right:last-child{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#777}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#777}.navbar-inverse .navbar-nav>li>a{color:#777}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#777}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#777}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#428bca;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{color:#2a6496;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#428bca;border-color:#428bca}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#428bca}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.nav-pills>.active>a>.badge,a.list-group-item.active>.badge{color:#428bca;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#428bca}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#428bca;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar[aria-valuenow="1"],.progress-bar[aria-valuenow="2"]{min-width:30px}.progress-bar[aria-valuenow="0"]{min-width:30px;color:#777;background-color:transparent;background-image:none;-webkit-box-shadow:none;box-shadow:none}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media,.media-body{overflow:hidden;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#e1edf7}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#428bca}.panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#428bca}.panel-primary>.panel-heading .badge{color:#428bca;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#428bca}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate3d(0,-25%,0);-o-transform:translate3d(0,-25%,0);transform:translate3d(0,-25%,0)}.modal.in .modal-dialog{-webkit-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.in{opacity:.5}.modal-header{min-height:16.42857143px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-size:12px;line-height:1.4;visibility:visible;opacity:0}.tooltip.in{opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{right:5px;bottom:0;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:400;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;margin-top:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed;-webkit-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}.ng-table th{text-align:center;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ng-table th.sortable{cursor:pointer}.ng-table th.sortable .sort-indicator{padding-right:18px;position:relative}.ng-table th.sortable .sort-indicator:after,.ng-table th.sortable .sort-indicator:before{content:"";border-width:0 4px 4px;border-style:solid;border-color:#000 transparent;visibility:visible;right:5px;top:50%;position:absolute;opacity:.3;margin-top:-4px}.ng-table th.sortable .sort-indicator:before{margin-top:2px;border-bottom:none;border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid #000}.ng-table th.sortable .sort-indicator:hover:after,.ng-table th.sortable .sort-indicator:hover:before{opacity:1;visibility:visible}.ng-table th.sortable.sort-asc,.ng-table th.sortable.sort-desc{background-color:rgba(141,192,219,.25);text-shadow:0 1px 1px rgba(255,255,255,.75)}.ng-table th.sortable.sort-asc .sort-indicator:after,.ng-table th.sortable.sort-desc .sort-indicator:after{margin-top:-2px}.ng-table th.sortable.sort-asc .sort-indicator:before,.ng-table th.sortable.sort-desc .sort-indicator:before{visibility:hidden}.ng-table th.sortable.sort-asc .sort-indicator:after,.ng-table th.sortable.sort-asc .sort-indicator:hover:after{visibility:visible;-khtml-opacity:.6;-moz-opacity:.6;opacity:.6}.ng-table th.sortable.sort-desc .sort-indicator:after{border-bottom:none;border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid #000;visibility:visible;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;-khtml-opacity:.6;-moz-opacity:.6;opacity:.6}.ng-table th.filter .input-filter{margin:0;display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.ng-table+.pagination{margin-top:0}@media only screen and (max-width:800px){.ng-table-responsive{border-bottom:1px solid #999}.ng-table-responsive tr{border-top:1px solid #999;border-left:1px solid #999;border-right:1px solid #999}.ng-table-responsive td:before{position:absolute;padding:8px;left:0;top:0;width:50%;white-space:nowrap;text-align:left;font-weight:700}.ng-table-responsive thead tr th{text-align:left}.ng-table-responsive thead tr.ng-table-filters th{padding:0}.ng-table-responsive thead tr.ng-table-filters th form>div{padding:8px}.ng-table-responsive td{border:none;border-bottom:1px solid #eee;position:relative;padding-left:50%;white-space:normal;text-align:left}.ng-table-responsive td:before{content:attr(data-title-text)}.ng-table-responsive,.ng-table-responsive tbody,.ng-table-responsive td,.ng-table-responsive th,.ng-table-responsive thead,.ng-table-responsive tr{display:block}}.select2-container{margin:0;position:relative;display:inline-block;zoom:1;vertical-align:middle}.select2-container,.select2-drop,.select2-search,.select2-search input{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.select2-container .select2-choice{display:block;height:26px;padding:0 0 0 8px;overflow:hidden;position:relative;border:1px solid #aaa;white-space:nowrap;line-height:26px;color:#444;text-decoration:none;border-radius:4px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;background-image:-webkit-gradient(linear,left bottom,left top,color-stop(0,#eee),color-stop(.5,#fff));background-image:-webkit-linear-gradient(center bottom,#eee 0,#fff 50%);background-image:-moz-linear-gradient(center bottom,#eee 0,#fff 50%);background-image:linear-gradient(to top,#eee 0,#fff 50%)}html[dir=rtl] .select2-container .select2-choice{padding:0 8px 0 0}.select2-container.select2-drop-above .select2-choice{border-bottom-color:#aaa;border-radius:0 0 4px 4px;background-image:-webkit-gradient(linear,left bottom,left top,color-stop(0,#eee),color-stop(.9,#fff));background-image:-webkit-linear-gradient(center bottom,#eee 0,#fff 90%);background-image:-moz-linear-gradient(center bottom,#eee 0,#fff 90%);background-image:linear-gradient(to bottom,#eee 0,#fff 90%)}.select2-container.select2-allowclear .select2-choice .select2-chosen{margin-right:42px}.select2-container .select2-choice>.select2-chosen{margin-right:26px;display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;float:none;width:auto}html[dir=rtl] .select2-container .select2-choice>.select2-chosen{margin-left:26px;margin-right:0}.select2-container .select2-choice abbr{display:none;width:12px;height:12px;position:absolute;right:24px;top:8px;font-size:1px;text-decoration:none;border:0;background:url(select2.png) right top no-repeat;cursor:pointer;outline:0}.select2-container.select2-allowclear .select2-choice abbr{display:inline-block}.select2-container .select2-choice abbr:hover{background-position:right -11px;cursor:pointer}.select2-drop-mask{border:0;margin:0;padding:0;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:9998;background-color:#fff}.select2-drop{width:100%;margin-top:-1px;position:absolute;z-index:9999;top:100%;background:#fff;color:#000;border:1px solid #aaa;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 4px 5px rgba(0,0,0,.15);box-shadow:0 4px 5px rgba(0,0,0,.15)}.select2-drop.select2-drop-above{margin-top:1px;border-top:1px solid #aaa;border-bottom:0;border-radius:4px 4px 0 0;-webkit-box-shadow:0 -4px 5px rgba(0,0,0,.15);box-shadow:0 -4px 5px rgba(0,0,0,.15)}.select2-drop-active{border:1px solid #5897fb;border-top:none}.select2-drop.select2-drop-above.select2-drop-active{border-top:1px solid #5897fb}.select2-drop-auto-width{border-top:1px solid #aaa;width:auto}.select2-drop-auto-width .select2-search{padding-top:4px}.select2-container .select2-choice .select2-arrow{display:inline-block;width:18px;height:100%;position:absolute;right:0;top:0;border-left:1px solid #aaa;border-radius:0 4px 4px 0;background-clip:padding-box;background:#ccc;background-image:-webkit-gradient(linear,left bottom,left top,color-stop(0,#ccc),color-stop(.6,#eee));background-image:-webkit-linear-gradient(center bottom,#ccc 0,#eee 60%);background-image:-moz-linear-gradient(center bottom,#ccc 0,#eee 60%);background-image:linear-gradient(to top,#ccc 0,#eee 60%)}html[dir=rtl] .select2-container .select2-choice .select2-arrow{left:0;right:auto;border-left:none;border-right:1px solid #aaa;border-radius:4px 0 0 4px}.select2-container .select2-choice .select2-arrow b{display:block;width:100%;height:100%;background:url(select2.png) no-repeat 0 1px}html[dir=rtl] .select2-container .select2-choice .select2-arrow b{background-position:2px 1px}.select2-search{display:inline-block;width:100%;min-height:26px;margin:0;padding-left:4px;padding-right:4px;position:relative;z-index:10000;white-space:nowrap}.select2-search input{width:100%;height:auto!important;min-height:26px;padding:4px 20px 4px 5px;margin:0;outline:0;font-family:sans-serif;font-size:1em;border:1px solid #aaa;border-radius:0;-webkit-box-shadow:none;box-shadow:none;background:#fff url(select2.png) no-repeat 100% -22px;background:url(select2.png) no-repeat 100% -22px,-webkit-gradient(linear,left bottom,left top,color-stop(.85,#fff),color-stop(.99,#eee));background:url(select2.png) no-repeat 100% -22px,-webkit-linear-gradient(center bottom,#fff 85%,#eee 99%);background:url(select2.png) no-repeat 100% -22px,-moz-linear-gradient(center bottom,#fff 85%,#eee 99%);background:url(select2.png) no-repeat 100% -22px,linear-gradient(to bottom,#fff 85%,#eee 99%) 0 0}html[dir=rtl] .select2-search input{padding:4px 5px 4px 20px;background:#fff url(select2.png) no-repeat -37px -22px;background:url(select2.png) no-repeat -37px -22px,-webkit-gradient(linear,left bottom,left top,color-stop(.85,#fff),color-stop(.99,#eee));background:url(select2.png) no-repeat -37px -22px,-webkit-linear-gradient(center bottom,#fff 85%,#eee 99%);background:url(select2.png) no-repeat -37px -22px,-moz-linear-gradient(center bottom,#fff 85%,#eee 99%);background:url(select2.png) no-repeat -37px -22px,linear-gradient(to bottom,#fff 85%,#eee 99%) 0 0}.select2-drop.select2-drop-above .select2-search input{margin-top:4px}.select2-search input.select2-active{background:#fff url(select2-spinner.gif) no-repeat 100%;background:url(select2-spinner.gif) no-repeat 100%,-webkit-gradient(linear,left bottom,left top,color-stop(.85,#fff),color-stop(.99,#eee));background:url(select2-spinner.gif) no-repeat 100%,-webkit-linear-gradient(center bottom,#fff 85%,#eee 99%);background:url(select2-spinner.gif) no-repeat 100%,-moz-linear-gradient(center bottom,#fff 85%,#eee 99%);background:url(select2-spinner.gif) no-repeat 100%,linear-gradient(to bottom,#fff 85%,#eee 99%) 0 0}.select2-container-active .select2-choice,.select2-container-active .select2-choices{border:1px solid #5897fb;outline:0;-webkit-box-shadow:0 0 5px rgba(0,0,0,.3);box-shadow:0 0 5px rgba(0,0,0,.3)}.select2-dropdown-open .select2-choice{border-bottom-color:transparent;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;border-bottom-left-radius:0;border-bottom-right-radius:0;background-color:#eee;background-image:-webkit-gradient(linear,left bottom,left top,color-stop(0,#fff),color-stop(.5,#eee));background-image:-webkit-linear-gradient(center bottom,#fff 0,#eee 50%);background-image:-moz-linear-gradient(center bottom,#fff 0,#eee 50%);background-image:linear-gradient(to top,#fff 0,#eee 50%)}.select2-dropdown-open.select2-drop-above .select2-choice,.select2-dropdown-open.select2-drop-above .select2-choices{border:1px solid #5897fb;border-top-color:transparent;background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fff),color-stop(.5,#eee));background-image:-webkit-linear-gradient(center top,#fff 0,#eee 50%);background-image:-moz-linear-gradient(center top,#fff 0,#eee 50%);background-image:linear-gradient(to bottom,#fff 0,#eee 50%)}.select2-dropdown-open .select2-choice .select2-arrow{background:0 0;border-left:none;filter:none}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow{border-right:none}.select2-dropdown-open .select2-choice .select2-arrow b{background-position:-18px 1px}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow b{background-position:-16px 1px}.select2-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.select2-results{max-height:200px;padding:0 0 0 4px;margin:4px 4px 4px 0;position:relative;overflow-x:hidden;overflow-y:auto;-webkit-tap-highlight-color:transparent}html[dir=rtl] .select2-results{padding:0 4px 0 0;margin:4px 0 4px 4px}.select2-results ul.select2-result-sub{margin:0;padding-left:0}.select2-results li{list-style:none;display:list-item;background-image:none}.select2-results li.select2-result-with-children>.select2-result-label{font-weight:700}.select2-results .select2-result-label{padding:3px 7px 4px;margin:0;cursor:pointer;min-height:1em;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.select2-results-dept-1 .select2-result-label{padding-left:20px}.select2-results-dept-2 .select2-result-label{padding-left:40px}.select2-results-dept-3 .select2-result-label{padding-left:60px}.select2-results-dept-4 .select2-result-label{padding-left:80px}.select2-results-dept-5 .select2-result-label{padding-left:100px}.select2-results-dept-6 .select2-result-label{padding-left:110px}.select2-results-dept-7 .select2-result-label{padding-left:120px}.select2-results .select2-highlighted{background:#3875d7;color:#fff}.select2-results li em{background:#feffde;font-style:normal}.select2-results .select2-highlighted em{background:0 0}.select2-results .select2-highlighted ul{background:#fff;color:#000}.select2-results .select2-ajax-error,.select2-results .select2-no-results,.select2-results .select2-searching,.select2-results .select2-selection-limit{background:#f4f4f4;display:list-item;padding-left:5px}.select2-results .select2-disabled.select2-highlighted{color:#666;background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-disabled{background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-selected{display:none}.select2-more-results.select2-active{background:#f4f4f4 url(select2-spinner.gif) no-repeat 100%}.select2-results .select2-ajax-error{background:rgba(255,50,50,.2)}.select2-more-results{background:#f4f4f4;display:list-item}.select2-container.select2-container-disabled .select2-choice{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container.select2-container-disabled .select2-choice .select2-arrow{background-color:#f4f4f4;background-image:none;border-left:0}.select2-container.select2-container-disabled .select2-choice abbr{display:none}.select2-container-multi .select2-choices{height:auto!important;height:1%;margin:0;padding:0 5px 0 0;position:relative;border:1px solid #aaa;cursor:text;overflow:hidden;background-color:#fff;background-image:-webkit-gradient(linear,0 0,0 100%,color-stop(1%,#eee),color-stop(15%,#fff));background-image:-webkit-linear-gradient(top,#eee 1%,#fff 15%);background-image:-moz-linear-gradient(top,#eee 1%,#fff 15%);background-image:linear-gradient(to bottom,#eee 1%,#fff 15%)}html[dir=rtl] .select2-container-multi .select2-choices{padding:0 0 0 5px}.select2-locked{padding:3px 5px 3px 5px!important}.select2-container-multi .select2-choices{min-height:26px}.select2-container-multi.select2-container-active .select2-choices{border:1px solid #5897fb;outline:0;-webkit-box-shadow:0 0 5px rgba(0,0,0,.3);box-shadow:0 0 5px rgba(0,0,0,.3)}.select2-container-multi .select2-choices li{float:left;list-style:none}html[dir=rtl] .select2-container-multi .select2-choices li{float:right}.select2-container-multi .select2-choices .select2-search-field{margin:0;padding:0;white-space:nowrap}.select2-container-multi .select2-choices .select2-search-field input{padding:5px;margin:1px 0;font-family:sans-serif;font-size:100%;color:#666;outline:0;border:0;-webkit-box-shadow:none;box-shadow:none;background:0 0!important}.select2-container-multi .select2-choices .select2-search-field input.select2-active{background:#fff url(select2-spinner.gif) no-repeat 100%!important}.select2-default{color:#999!important}.select2-container-multi .select2-choices .select2-search-choice{padding:3px 5px 3px 18px;margin:3px 0 3px 5px;position:relative;line-height:13px;color:#333;cursor:default;border:1px solid #aaa;border-radius:3px;-webkit-box-shadow:0 0 2px #fff inset,0 1px 0 rgba(0,0,0,.05);box-shadow:0 0 2px #fff inset,0 1px 0 rgba(0,0,0,.05);background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#e4e4e4;background-image:-webkit-gradient(linear,0 0,0 100%,color-stop(20%,#f4f4f4),color-stop(50%,#f0f0f0),color-stop(52%,#e8e8e8),color-stop(100%,#eee));background-image:-webkit-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-moz-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:linear-gradient(to bottom,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%)}html[dir=rtl] .select2-container-multi .select2-choices .select2-search-choice{margin:3px 5px 3px 0;padding:3px 18px 3px 5px}.select2-container-multi .select2-choices .select2-search-choice .select2-chosen{cursor:default}.select2-container-multi .select2-choices .select2-search-choice-focus{background:#d4d4d4}.select2-search-choice-close{display:block;width:12px;height:13px;position:absolute;right:3px;top:4px;font-size:1px;outline:0;background:url(select2.png) right top no-repeat}html[dir=rtl] .select2-search-choice-close{right:auto;left:3px}.select2-container-multi .select2-search-choice-close{left:3px}html[dir=rtl] .select2-container-multi .select2-search-choice-close{left:auto;right:2px}.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover{background-position:right -11px}.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close{background-position:right -11px}.select2-container-multi.select2-container-disabled .select2-choices{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice{padding:3px 5px 3px 5px;border:1px solid #ddd;background-image:none;background-color:#f4f4f4}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close{display:none;background:0 0}.select2-result-selectable .select2-match,.select2-result-unselectable .select2-match{text-decoration:underline}.select2-offscreen,.select2-offscreen:focus{clip:rect(0 0 0 0)!important;width:1px!important;height:1px!important;border:0!important;margin:0!important;padding:0!important;overflow:hidden!important;position:absolute!important;outline:0!important;left:0!important;top:0!important}.select2-display-none{display:none}.select2-measure-scrollbar{position:absolute;top:-10000px;left:-10000px;width:100px;height:100px;overflow:scroll}@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:2dppx){.select2-container .select2-choice .select2-arrow b,.select2-container .select2-choice abbr,.select2-search input,.select2-search-choice-close{background-image:url(select2x2.png)!important;background-repeat:no-repeat!important;background-size:60px 40px!important}.select2-search input{background-position:100% -21px!important}}/*! + * ui-select + * http://github.com/angular-ui/ui-select + * Version: 0.12.1 - 2015-07-28T03:50:59.080Z + * License: MIT + */.ui-select-highlight{font-weight:700}.ui-select-offscreen{clip:rect(0 0 0 0)!important;width:1px!important;height:1px!important;border:0!important;margin:0!important;padding:0!important;overflow:hidden!important;position:absolute!important;outline:0!important;left:0!important;top:0!important}.ng-dirty.ng-invalid>a.select2-choice{border-color:#d44950}.select2-result-single{padding-left:0}.select2-locked>.select2-search-choice-close{display:none}.select-locked>.ui-select-match-close{display:none}body>.select2-container.open{z-index:9999}.ui-select-container[theme=select2].direction-up .ui-select-match{border-radius:4px;border-top-left-radius:0;border-top-right-radius:0}.ui-select-container[theme=select2].direction-up .ui-select-dropdown{border-radius:4px;border-bottom-left-radius:0;border-bottom-right-radius:0;border-top-width:1px;border-top-style:solid;box-shadow:0 -4px 8px rgba(0,0,0,.25);margin-top:-4px}.ui-select-container[theme=select2].direction-up .ui-select-dropdown .select2-search{margin-top:4px}.ui-select-container[theme=select2].direction-up.select2-dropdown-open .ui-select-match{border-bottom-color:#5897fb}.selectize-input.selectize-focus{border-color:#007fbb!important}.selectize-control>.selectize-input>input{width:100%}.selectize-control>.selectize-dropdown{width:100%}.ng-dirty.ng-invalid>div.selectize-input{border-color:#d44950}.ui-select-container[theme=selectize].direction-up .ui-select-dropdown{box-shadow:0 -4px 8px rgba(0,0,0,.25);margin-top:-2px}.btn-default-focus{color:#333;background-color:#ebebeb;border-color:#adadad;text-decoration:none;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.ui-select-bootstrap .ui-select-toggle{position:relative}.ui-select-bootstrap .ui-select-toggle>.caret{position:absolute;height:10px;top:50%;right:10px;margin-top:-2px}.input-group>.ui-select-bootstrap.dropdown{position:static}.input-group>.ui-select-bootstrap>input.ui-select-search.form-control{border-radius:4px;border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.ui-select-bootstrap>input.ui-select-search.form-control.direction-up{border-radius:4px!important;border-top-right-radius:0!important;border-bottom-right-radius:0!important}.ui-select-bootstrap>.ui-select-match>.btn{text-align:left!important}.ui-select-bootstrap>.ui-select-match>.caret{position:absolute;top:45%;right:15px}.ui-select-bootstrap>.ui-select-choices{width:100%;height:auto;max-height:200px;overflow-x:hidden;margin-top:-1px}body>.ui-select-bootstrap.open{z-index:1000}.ui-select-multiple.ui-select-bootstrap{height:auto;padding:3px 3px 0 3px}.ui-select-multiple.ui-select-bootstrap input.ui-select-search{background-color:transparent!important;border:none;outline:0;height:1.666666em;margin-bottom:3px}.ui-select-multiple.ui-select-bootstrap .ui-select-match .close{font-size:1.6em;line-height:.75}.ui-select-multiple.ui-select-bootstrap .ui-select-match-item{outline:0;margin:0 3px 3px 0}.ui-select-multiple .ui-select-match-item{position:relative}.ui-select-multiple .ui-select-match-item.dropping-before:before{content:"";position:absolute;top:0;right:100%;height:100%;margin-right:2px;border-left:1px solid #428bca}.ui-select-multiple .ui-select-match-item.dropping-after:after{content:"";position:absolute;top:0;left:100%;height:100%;margin-left:2px;border-right:1px solid #428bca}.ui-select-bootstrap .ui-select-choices-row>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.ui-select-bootstrap .ui-select-choices-row>a:focus,.ui-select-bootstrap .ui-select-choices-row>a:hover{text-decoration:none;color:#262626;background-color:#f5f5f5}.ui-select-bootstrap .ui-select-choices-row.active>a{color:#fff;text-decoration:none;outline:0;background-color:#428bca}.ui-select-bootstrap .ui-select-choices-row.active.disabled>a,.ui-select-bootstrap .ui-select-choices-row.disabled>a{color:#777;cursor:not-allowed;background-color:#fff}.ui-select-match.ng-hide-add,.ui-select-search.ng-hide-add{display:none!important}.ui-select-bootstrap.ng-dirty.ng-invalid>button.btn.ui-select-match{border-color:#d44950}.ui-select-container[theme=bootstrap].direction-up .ui-select-dropdown{box-shadow:0 -4px 8px rgba(0,0,0,.25)}.selectize-control.plugin-drag_drop.multi>.selectize-input>div.ui-sortable-placeholder{visibility:visible!important;background:#f2f2f2!important;background:rgba(0,0,0,.06)!important;border:0 none!important;-webkit-box-shadow:inset 0 0 12px 4px #fff;box-shadow:inset 0 0 12px 4px #fff}.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after{content:'!';visibility:hidden}.selectize-control.plugin-drag_drop .ui-sortable-helper{-webkit-box-shadow:0 2px 5px rgba(0,0,0,.2);box-shadow:0 2px 5px rgba(0,0,0,.2)}.selectize-dropdown-header{position:relative;padding:5px 8px;border-bottom:1px solid #d0d0d0;background:#f8f8f8;-webkit-border-radius:3px 3px 0 0;-moz-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0}.selectize-dropdown-header-close{position:absolute;right:8px;top:50%;color:#303030;opacity:.4;margin-top:-12px;line-height:20px;font-size:20px!important}.selectize-dropdown-header-close:hover{color:#000}.selectize-dropdown.plugin-optgroup_columns .optgroup{border-right:1px solid #f2f2f2;border-top:0 none;float:left;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child{border-right:0 none}.selectize-dropdown.plugin-optgroup_columns .optgroup:before{display:none}.selectize-dropdown.plugin-optgroup_columns .optgroup-header{border-top:0 none}.selectize-control.plugin-remove_button [data-value]{position:relative;padding-right:24px!important}.selectize-control.plugin-remove_button [data-value] .remove{z-index:1;position:absolute;top:0;right:0;bottom:0;width:17px;text-align:center;font-weight:700;font-size:12px;color:inherit;text-decoration:none;vertical-align:middle;display:inline-block;padding:2px 0 0 0;border-left:1px solid #0073bb;-webkit-border-radius:0 2px 2px 0;-moz-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.selectize-control.plugin-remove_button [data-value] .remove:hover{background:rgba(0,0,0,.05)}.selectize-control.plugin-remove_button [data-value].active .remove{border-left-color:#00578d}.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover{background:0 0}.selectize-control.plugin-remove_button .disabled [data-value] .remove{border-left-color:#aaa}.selectize-control{position:relative}.selectize-dropdown,.selectize-input,.selectize-input input{color:#303030;font-family:inherit;font-size:13px;line-height:18px;-webkit-font-smoothing:inherit}.selectize-control.single .selectize-input.input-active,.selectize-input{background:#fff;cursor:text;display:inline-block}.selectize-input{border:1px solid #d0d0d0;padding:8px 8px;display:inline-block;width:100%;overflow:hidden;position:relative;z-index:1;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.1);box-shadow:inset 0 1px 1px rgba(0,0,0,.1);-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.selectize-control.multi .selectize-input.has-items{padding:5px 8px 2px}.selectize-input.full{background-color:#fff}.selectize-input.disabled,.selectize-input.disabled *{cursor:default!important}.selectize-input.focus{-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.15);box-shadow:inset 0 1px 2px rgba(0,0,0,.15)}.selectize-input.dropdown-active{-webkit-border-radius:3px 3px 0 0;-moz-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0}.selectize-input>*{vertical-align:baseline;display:-moz-inline-stack;display:inline-block;zoom:1}.selectize-control.multi .selectize-input>div{cursor:pointer;margin:0 3px 3px 0;padding:2px 6px;background:#1da7ee;color:#fff;border:1px solid #0073bb}.selectize-control.multi .selectize-input>div.active{background:#92c836;color:#fff;border:1px solid #00578d}.selectize-control.multi .selectize-input.disabled>div,.selectize-control.multi .selectize-input.disabled>div.active{color:#fff;background:#d2d2d2;border:1px solid #aaa}.selectize-input>input{display:inline-block!important;padding:0!important;min-height:0!important;max-height:none!important;max-width:100%!important;margin:0 1px!important;text-indent:0!important;border:0 none!important;background:0 0!important;line-height:inherit!important;-webkit-user-select:auto!important;-webkit-box-shadow:none!important;box-shadow:none!important}.selectize-input>input::-ms-clear{display:none}.selectize-input>input:focus{outline:0!important}.selectize-input::after{content:' ';display:block;clear:left}.selectize-input.dropdown-active::before{content:' ';display:block;position:absolute;background:#f0f0f0;height:1px;bottom:0;left:0;right:0}.selectize-dropdown{position:absolute;z-index:10;border:1px solid #d0d0d0;background:#fff;margin:-1px 0 0 0;border-top:0 none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:0 1px 3px rgba(0,0,0,.1);box-shadow:0 1px 3px rgba(0,0,0,.1);-webkit-border-radius:0 0 3px 3px;-moz-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px}.selectize-dropdown [data-selectable]{cursor:pointer;overflow:hidden}.selectize-dropdown [data-selectable] .highlight{background:rgba(125,168,208,.2);-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px}.selectize-dropdown .optgroup-header,.selectize-dropdown [data-selectable]{padding:5px 8px}.selectize-dropdown .optgroup:first-child .optgroup-header{border-top:0 none}.selectize-dropdown .optgroup-header{color:#303030;background:#fff;cursor:default}.selectize-dropdown .active{background-color:#f5fafd;color:#495c68}.selectize-dropdown .active.create{color:#495c68}.selectize-dropdown .create{color:rgba(48,48,48,.5)}.selectize-dropdown-content{overflow-y:auto;overflow-x:hidden;max-height:200px}.selectize-control.single .selectize-input,.selectize-control.single .selectize-input input{cursor:pointer}.selectize-control.single .selectize-input.input-active,.selectize-control.single .selectize-input.input-active input{cursor:text}.selectize-control.single .selectize-input:after{content:' ';display:block;position:absolute;top:50%;right:15px;margin-top:-3px;width:0;height:0;border-style:solid;border-width:5px 5px 0 5px;border-color:grey transparent transparent transparent}.selectize-control.single .selectize-input.dropdown-active:after{margin-top:-4px;border-width:0 5px 5px 5px;border-color:transparent transparent grey transparent}.selectize-control.rtl.single .selectize-input:after{left:15px;right:auto}.selectize-control.rtl .selectize-input>input{margin:0 4px 0 -2px!important}.selectize-control .selectize-input.disabled{opacity:.5;background-color:#fafafa}.selectize-control.multi .selectize-input.has-items{padding-left:5px;padding-right:5px}.selectize-control.multi .selectize-input.disabled [data-value]{color:#999;text-shadow:none;background:0 0;-webkit-box-shadow:none;box-shadow:none}.selectize-control.multi .selectize-input.disabled [data-value],.selectize-control.multi .selectize-input.disabled [data-value] .remove{border-color:#e6e6e6}.selectize-control.multi .selectize-input.disabled [data-value] .remove{background:0 0}.selectize-control.multi .selectize-input [data-value]{text-shadow:0 1px 0 rgba(0,51,83,.3);-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;background-color:#1b9dec;background-image:-moz-linear-gradient(top,#1da7ee,#178ee9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#1da7ee),to(#178ee9));background-image:-webkit-linear-gradient(top,#1da7ee,#178ee9);background-image:-o-linear-gradient(top,#1da7ee,#178ee9);background-image:linear-gradient(to bottom,#1da7ee,#178ee9);background-repeat:repeat-x;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),inset 0 1px rgba(255,255,255,.03);box-shadow:0 1px 0 rgba(0,0,0,.2),inset 0 1px rgba(255,255,255,.03)}.selectize-control.multi .selectize-input [data-value].active{background-color:#0085d4;background-image:-moz-linear-gradient(top,#008fd8,#0075cf);background-image:-webkit-gradient(linear,0 0,0 100%,from(#008fd8),to(#0075cf));background-image:-webkit-linear-gradient(top,#008fd8,#0075cf);background-image:-o-linear-gradient(top,#008fd8,#0075cf);background-image:linear-gradient(to bottom,#008fd8,#0075cf);background-repeat:repeat-x}.selectize-control.single .selectize-input{-webkit-box-shadow:0 1px 0 rgba(0,0,0,.05),inset 0 1px 0 rgba(255,255,255,.8);box-shadow:0 1px 0 rgba(0,0,0,.05),inset 0 1px 0 rgba(255,255,255,.8);background-color:#f9f9f9;background-image:-moz-linear-gradient(top,#fefefe,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fefefe),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fefefe,#f2f2f2);background-image:-o-linear-gradient(top,#fefefe,#f2f2f2);background-image:linear-gradient(to bottom,#fefefe,#f2f2f2);background-repeat:repeat-x}.selectize-control.single .selectize-input,.selectize-dropdown.single{border-color:#b8b8b8}.selectize-dropdown .optgroup-header{padding-top:7px;font-weight:700;font-size:.85em}.selectize-dropdown .optgroup{border-top:1px solid #f0f0f0}.selectize-dropdown .optgroup:first-child{border-top:0 none}.am-fade-and-scale{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards}.am-fade-and-scale.am-fade-and-scale-add,.am-fade-and-scale.ng-enter,.am-fade-and-scale.ng-hide-remove,.am-fade-and-scale.ng-move{-webkit-animation-name:fadeAndScaleIn;animation-name:fadeAndScaleIn}.am-fade-and-scale.am-fade-and-scale-remove,.am-fade-and-scale.ng-hide,.am-fade-and-scale.ng-leave{-webkit-animation-name:fadeAndScaleOut;animation-name:fadeAndScaleOut}.am-fade-and-scale.ng-enter{visibility:hidden;-webkit-animation-name:fadeAndScaleIn;animation-name:fadeAndScaleIn;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade-and-scale.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-fade-and-scale.ng-leave{-webkit-animation-name:fadeAndScaleOut;animation-name:fadeAndScaleOut;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade-and-scale.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}@-webkit-keyframes fadeAndScaleIn{from{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}to{opacity:1}}@keyframes fadeAndScaleIn{from{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}to{opacity:1}}@-webkit-keyframes fadeAndScaleOut{from{opacity:1}to{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}}@keyframes fadeAndScaleOut{from{opacity:1}to{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}}.am-fade-and-slide-top{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards}.am-fade-and-slide-top.am-fade-and-slide-top-add,.am-fade-and-slide-top.ng-hide-remove,.am-fade-and-slide-top.ng-move{-webkit-animation-name:fadeAndSlideFromTop;animation-name:fadeAndSlideFromTop}.am-fade-and-slide-top.am-fade-and-slide-top-remove,.am-fade-and-slide-top.ng-hide{-webkit-animation-name:fadeAndSlideToTop;animation-name:fadeAndSlideToTop}.am-fade-and-slide-top.ng-enter{visibility:hidden;-webkit-animation-name:fadeAndSlideFromTop;animation-name:fadeAndSlideFromTop;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade-and-slide-top.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-fade-and-slide-top.ng-leave{-webkit-animation-name:fadeAndSlideToTop;animation-name:fadeAndSlideToTop;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade-and-slide-top.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}.am-fade-and-slide-right{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards}.am-fade-and-slide-right.am-fade-and-slide-right-add,.am-fade-and-slide-right.ng-hide-remove,.am-fade-and-slide-right.ng-move{-webkit-animation-name:fadeAndSlideFromRight;animation-name:fadeAndSlideFromRight}.am-fade-and-slide-right.am-fade-and-slide-right-remove,.am-fade-and-slide-right.ng-hide{-webkit-animation-name:fadeAndSlideToRight;animation-name:fadeAndSlideToRight}.am-fade-and-slide-right.ng-enter{visibility:hidden;-webkit-animation-name:fadeAndSlideFromRight;animation-name:fadeAndSlideFromRight;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade-and-slide-right.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-fade-and-slide-right.ng-leave{-webkit-animation-name:fadeAndSlideToRight;animation-name:fadeAndSlideToRight;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade-and-slide-right.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}.am-fade-and-slide-bottom{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards}.am-fade-and-slide-bottom.am-fade-and-slide-bottom-add,.am-fade-and-slide-bottom.ng-hide-remove,.am-fade-and-slide-bottom.ng-move{-webkit-animation-name:fadeAndSlideFromBottom;animation-name:fadeAndSlideFromBottom}.am-fade-and-slide-bottom.am-fade-and-slide-bottom-remove,.am-fade-and-slide-bottom.ng-hide{-webkit-animation-name:fadeAndSlideToBottom;animation-name:fadeAndSlideToBottom}.am-fade-and-slide-bottom.ng-enter{visibility:hidden;-webkit-animation-name:fadeAndSlideFromBottom;animation-name:fadeAndSlideFromBottom;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade-and-slide-bottom.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-fade-and-slide-bottom.ng-leave{-webkit-animation-name:fadeAndSlideToBottom;animation-name:fadeAndSlideToBottom;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade-and-slide-bottom.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}.am-fade-and-slide-left{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards}.am-fade-and-slide-left.am-fade-and-slide-left-add,.am-fade-and-slide-left.ng-hide-remove,.am-fade-and-slide-left.ng-move{-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards;-webkit-animation-name:fadeAndSlideFromLeft;animation-name:fadeAndSlideFromLeft}.am-fade-and-slide-left.am-fade-and-slide-left-remove,.am-fade-and-slide-left.ng-hide{-webkit-animation-name:fadeAndSlideToLeft;animation-name:fadeAndSlideToLeft}.am-fade-and-slide-left.ng-enter{visibility:hidden;-webkit-animation-name:fadeAndSlideFromLeft;animation-name:fadeAndSlideFromLeft;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade-and-slide-left.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-fade-and-slide-left.ng-leave{-webkit-animation-name:fadeAndSlideToLeft;animation-name:fadeAndSlideToLeft;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade-and-slide-left.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}@-webkit-keyframes fadeAndSlideFromTop{from{opacity:0;-webkit-transform:translateY(-20%);transform:translateY(-20%)}to{opacity:1}}@keyframes fadeAndSlideFromTop{from{opacity:0;-webkit-transform:translateY(-20%);transform:translateY(-20%)}to{opacity:1}}@-webkit-keyframes fadeAndSlideToTop{from{opacity:1}to{opacity:0;-webkit-transform:translateY(-20%);transform:translateY(-20%)}}@keyframes fadeAndSlideToTop{from{opacity:1}to{opacity:0;-webkit-transform:translateY(-20%);transform:translateY(-20%)}}@-webkit-keyframes fadeAndSlideFromRight{from{opacity:0;-webkit-transform:translateX(20%);transform:translateX(20%)}to{opacity:1}}@keyframes fadeAndSlideFromRight{from{opacity:0;-webkit-transform:translateX(20%);transform:translateX(20%)}to{opacity:1}}@-webkit-keyframes fadeAndSlideToRight{from{opacity:1}to{opacity:0;-webkit-transform:translateX(20%);transform:translateX(20%)}}@keyframes fadeAndSlideToRight{from{opacity:1}to{opacity:0;-webkit-transform:translateX(20%);transform:translateX(20%)}}@-webkit-keyframes fadeAndSlideFromBottom{from{opacity:0;-webkit-transform:translateY(20%);transform:translateY(20%)}to{opacity:1}}@keyframes fadeAndSlideFromBottom{from{opacity:0;-webkit-transform:translateY(20%);transform:translateY(20%)}to{opacity:1}}@-webkit-keyframes fadeAndSlideToBottom{from{opacity:1}to{opacity:0;-webkit-transform:translateY(20%);transform:translateY(20%)}}@keyframes fadeAndSlideToBottom{from{opacity:1}to{opacity:0;-webkit-transform:translateY(20%);transform:translateY(20%)}}@-webkit-keyframes fadeAndSlideFromLeft{from{opacity:0;-webkit-transform:translateX(-20%);transform:translateX(-20%)}to{opacity:1}}@keyframes fadeAndSlideFromLeft{from{opacity:0;-webkit-transform:translateX(-20%);transform:translateX(-20%)}to{opacity:1}}@-webkit-keyframes fadeAndSlideToLeft{from{opacity:1}to{opacity:0;-webkit-transform:translateX(-20%);transform:translateX(-20%)}}@keyframes fadeAndSlideToLeft{from{opacity:1}to{opacity:0;-webkit-transform:translateX(-20%);transform:translateX(-20%)}}.am-fade{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-timing-function:linear;animation-timing-function:linear;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards;opacity:1}.am-fade.am-fade-add,.am-fade.ng-hide-remove,.am-fade.ng-move{-webkit-animation-name:fadeIn;animation-name:fadeIn}.am-fade.am-fade-remove,.am-fade.ng-hide{-webkit-animation-name:fadeOut;animation-name:fadeOut}.am-fade.ng-enter{visibility:hidden;-webkit-animation-name:fadeIn;animation-name:fadeIn;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-fade.ng-leave{-webkit-animation-name:fadeOut;animation-name:fadeOut;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}@-webkit-keyframes fadeIn{from{opacity:0}to{opacity:1}}@keyframes fadeIn{from{opacity:0}to{opacity:1}}@-webkit-keyframes fadeOut{from{opacity:1}to{opacity:0}}@keyframes fadeOut{from{opacity:1}to{opacity:0}}.aside-backdrop.am-fade,.modal-backdrop.am-fade{background:rgba(0,0,0,.5);-webkit-animation-duration:.15s;animation-duration:.15s}.aside-backdrop.am-fade.ng-leave,.modal-backdrop.am-fade.ng-leave{-webkit-animation-delay:.3s;animation-delay:.3s}.am-flip-x{-webkit-animation-duration:.4s;animation-duration:.4s;-webkit-animation-timing-function:ease;animation-timing-function:ease;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards}.am-flip-x.am-flip-x-add,.am-flip-x.ng-hide-remove,.am-flip-x.ng-move{-webkit-animation-name:flipInXBounce;animation-name:flipInXBounce}.am-flip-x.am-flip-x-remove,.am-flip-x.ng-hide{-webkit-animation-name:flipOutX;animation-name:flipOutX}.am-flip-x.ng-enter{visibility:hidden;-webkit-animation-name:flipInXBounce;animation-name:flipInXBounce;-webkit-animation-play-state:paused;animation-play-state:paused}.am-flip-x.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-flip-x.ng-leave{-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-animation-play-state:paused;animation-play-state:paused}.am-flip-x.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}.am-flip-x-linear{-webkit-animation-duration:.4s;animation-duration:.4s;-webkit-animation-timing-function:ease;animation-timing-function:ease;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards}.am-flip-x-linear.am-flip-x-add,.am-flip-x-linear.ng-hide-remove,.am-flip-x-linear.ng-move{-webkit-animation-name:flipInX;animation-name:flipInX}.am-flip-x-linear.am-flip-x-remove,.am-flip-x-linear.ng-hide{-webkit-animation-name:flipOutX;animation-name:flipOutX}.am-flip-x-linear.ng-enter{visibility:hidden;-webkit-animation-name:flipInX;animation-name:flipInX;-webkit-animation-play-state:paused;animation-play-state:paused}.am-flip-x-linear.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-flip-x-linear.ng-leave{-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-animation-play-state:paused;animation-play-state:paused}.am-flip-x-linear.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}@-webkit-keyframes flipInX{from{opacity:0;-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg)}to{opacity:1;-webkit-transform:perspective(400px) rotateX(0);transform:perspective(400px) rotateX(0)}}@keyframes flipInX{from{opacity:0;-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg)}to{opacity:1;-webkit-transform:perspective(400px) rotateX(0);transform:perspective(400px) rotateX(0)}}@-webkit-keyframes flipInXBounce{from{opacity:0;-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg)}40%{-webkit-transform:perspective(400px) rotateX(-10deg);transform:perspective(400px) rotateX(-10deg)}70%{-webkit-transform:perspective(400px) rotateX(10deg);transform:perspective(400px) rotateX(10deg)}to{opacity:1;-webkit-transform:perspective(400px) rotateX(0);transform:perspective(400px) rotateX(0)}}@keyframes flipInXBounce{from{opacity:0;-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg)}40%{-webkit-transform:perspective(400px) rotateX(-10deg);transform:perspective(400px) rotateX(-10deg)}70%{-webkit-transform:perspective(400px) rotateX(10deg);transform:perspective(400px) rotateX(10deg)}to{opacity:1;-webkit-transform:perspective(400px) rotateX(0);transform:perspective(400px) rotateX(0)}}@-webkit-keyframes flipOutX{from{opacity:1;-webkit-transform:perspective(400px) rotateX(0);transform:perspective(400px) rotateX(0)}to{opacity:0;-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg)}}@keyframes flipOutX{from{opacity:1;-webkit-transform:perspective(400px) rotateX(0);transform:perspective(400px) rotateX(0)}to{opacity:0;-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg)}}.am-slide-top{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards}.am-slide-top.am-slide-top-add,.am-slide-top.ng-hide-remove,.am-slide-top.ng-move{-webkit-animation-name:slideFromTop;animation-name:slideFromTop}.am-slide-top.am-slide-top-remove,.am-slide-top.ng-hide{-webkit-animation-name:slideToTop;animation-name:slideToTop}.am-slide-top.ng-enter{visibility:hidden;-webkit-animation-name:slideFromTop;animation-name:slideFromTop;-webkit-animation-play-state:paused;animation-play-state:paused}.am-slide-top.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-slide-top.ng-leave{-webkit-animation-name:slideToTop;animation-name:slideToTop;-webkit-animation-play-state:paused;animation-play-state:paused}.am-slide-top.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}.am-slide-right{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards}.am-slide-right.am-slide-right-add,.am-slide-right.ng-hide-remove,.am-slide-right.ng-move{-webkit-animation-name:slideFromRight;animation-name:slideFromRight}.am-slide-right.am-slide-right-remove,.am-slide-right.ng-hide{-webkit-animation-name:slideToRight;animation-name:slideToRight}.am-slide-right.ng-enter{visibility:hidden;-webkit-animation-name:slideFromRight;animation-name:slideFromRight;-webkit-animation-play-state:paused;animation-play-state:paused}.am-slide-right.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-slide-right.ng-leave{-webkit-animation-name:slideToRight;animation-name:slideToRight;-webkit-animation-play-state:paused;animation-play-state:paused}.am-slide-right.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}.am-slide-bottom{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards}.am-slide-bottom.am-slide-bottom-add,.am-slide-bottom.ng-hide-remove,.am-slide-bottom.ng-move{-webkit-animation-name:slideFromBottom;animation-name:slideFromBottom}.am-slide-bottom.am-slide-bottom-remove,.am-slide-bottom.ng-hide{-webkit-animation-name:slideToBottom;animation-name:slideToBottom}.am-slide-bottom.ng-enter{visibility:hidden;-webkit-animation-name:slideFromBottom;animation-name:slideFromBottom;-webkit-animation-play-state:paused;animation-play-state:paused}.am-slide-bottom.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-slide-bottom.ng-leave{-webkit-animation-name:slideToBottom;animation-name:slideToBottom;-webkit-animation-play-state:paused;animation-play-state:paused}.am-slide-bottom.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}.am-slide-left{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards}.am-slide-left.am-slide-left-add,.am-slide-left.ng-hide-remove,.am-slide-left.ng-move{-webkit-animation-name:slideFromLeft;animation-name:slideFromLeft}.am-slide-left.am-slide-left-remove,.am-slide-left.ng-hide{-webkit-animation-name:slideToLeft;animation-name:slideToLeft}.am-slide-left.ng-enter{visibility:hidden;-webkit-animation-name:slideFromLeft;animation-name:slideFromLeft;-webkit-animation-play-state:paused;animation-play-state:paused}.am-slide-left.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-slide-left.ng-leave{-webkit-animation-name:slideToLeft;animation-name:slideToLeft;-webkit-animation-play-state:paused;animation-play-state:paused}.am-slide-left.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}@-webkit-keyframes slideFromTop{from{-webkit-transform:translateY(-100%);transform:translateY(-100%)}}@keyframes slideFromTop{from{-webkit-transform:translateY(-100%);transform:translateY(-100%)}}@-webkit-keyframes slideToTop{to{-webkit-transform:translateY(-100%);transform:translateY(-100%)}}@keyframes slideToTop{to{-webkit-transform:translateY(-100%);transform:translateY(-100%)}}@-webkit-keyframes slideFromRight{from{-webkit-transform:translateX(100%);transform:translateX(100%)}}@keyframes slideFromRight{from{-webkit-transform:translateX(100%);transform:translateX(100%)}}@-webkit-keyframes slideToRight{to{-webkit-transform:translateX(100%);transform:translateX(100%)}}@keyframes slideToRight{to{-webkit-transform:translateX(100%);transform:translateX(100%)}}@-webkit-keyframes slideFromBottom{from{-webkit-transform:translateY(100%);transform:translateY(100%)}}@keyframes slideFromBottom{from{-webkit-transform:translateY(100%);transform:translateY(100%)}}@-webkit-keyframes slideToBottom{to{-webkit-transform:translateY(100%);transform:translateY(100%)}}@keyframes slideToBottom{to{-webkit-transform:translateY(100%);transform:translateY(100%)}}@-webkit-keyframes slideFromLeft{from{-webkit-transform:translateX(-100%);transform:translateX(-100%)}}@keyframes slideFromLeft{from{-webkit-transform:translateX(-100%);transform:translateX(-100%)}}@-webkit-keyframes slideToLeft{to{-webkit-transform:translateX(-100%);transform:translateX(-100%)}}@keyframes slideToLeft{to{-webkit-transform:translateX(-100%);transform:translateX(-100%)}}.switchery{background-color:#fff;border:1px solid #dfdfdf;border-radius:20px;cursor:pointer;display:inline-block;height:30px;position:relative;vertical-align:middle;width:50px}.switchery>small{background:#fff;border-radius:100%;box-shadow:0 1px 3px rgba(0,0,0,.4);height:30px;position:absolute;top:0;width:30px}.toast-title{font-weight:700}.toast-message{-ms-word-wrap:break-word;word-wrap:break-word}.toast-message a,.toast-message label{color:#fff}.toast-message a:hover{color:#ccc;text-decoration:none}.toast-close-button{position:relative;right:-.3em;top:-.3em;float:right;font-size:20px;font-weight:700;color:#fff;-webkit-text-shadow:0 1px 0 #fff;text-shadow:0 1px 0 #fff;opacity:.8}.toast-close-button:focus,.toast-close-button:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4}button.toast-close-button{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.toast-top-full-width{top:0;right:0;width:100%}.toast-bottom-full-width{bottom:0;right:0;width:100%}.toast-top-left{top:12px;left:12px}.toast-top-center{top:12px}.toast-top-right{top:12px;right:12px}.toast-bottom-right{right:12px;bottom:12px}.toast-bottom-center{bottom:12px}.toast-bottom-left{bottom:12px;left:12px}.toast-center{top:45%}#toast-container{position:fixed;z-index:999999}#toast-container.toast-bottom-center,#toast-container.toast-center,#toast-container.toast-top-center{width:100%;pointer-events:none}#toast-container.toast-bottom-center>div,#toast-container.toast-center>div,#toast-container.toast-top-center>div{margin:auto;pointer-events:auto}#toast-container.toast-bottom-center>button,#toast-container.toast-center>button,#toast-container.toast-top-center>button{pointer-events:auto}#toast-container *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}#toast-container>div{margin:0 0 6px;padding:15px 15px 15px 50px;width:300px;-moz-border-radius:3px 3px 3px 3px;-webkit-border-radius:3px 3px 3px 3px;border-radius:3px 3px 3px 3px;background-position:15px center;background-repeat:no-repeat;-moz-box-shadow:0 0 12px #999;-webkit-box-shadow:0 0 12px #999;box-shadow:0 0 12px #999;color:#fff;opacity:.8}#toast-container>:hover{-moz-box-shadow:0 0 12px #000;-webkit-box-shadow:0 0 12px #000;box-shadow:0 0 12px #000;opacity:1;cursor:pointer}#toast-container>.toast-info{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=)!important}#toast-container>.toast-wait{background-image:url(data:image/gif;base64,R0lGODlhIAAgAIQAAAQCBISGhMzKzERCROTm5CQiJKyurHx+fPz+/ExOTOzu7Dw+PIyOjCwqLFRWVAwKDIyKjMzOzOzq7CQmJLy6vFRSVPTy9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCQAXACwAAAAAIAAgAAAF3eAljmRpnmh6VRSVqLDpIDTixOdUlFSNUDhSQUAT7ES9GnD0SFQAKWItMqr4bqKHVPDI+WiTkaOFFVlrFe83rDrT0qeIjwrT0iLdU0GOiBxhAA4VeSk6QYeIOAsQEAuJKgw+EI8nA18IA48JBAQvFxCXDI8SNAQikV+iiaQIpheWX5mJmxKeF6g0qpQmA4yOu8C7EwYWCgZswRcTFj4KyMAGlwYxDwcHhCXMXxYxBzQHKNo+3DDeCOAn0V/TddbYJA0K48gAEAFQicMWFsfwNA3JSgAIAAFfwIMIL4QAACH5BAkJABoALAAAAAAgACAAhAQCBIyKjERCRMzOzCQiJPTy9DQyNGRmZMTCxOTm5CwqLHx+fBQWFJyenNTW1Pz6/Dw6PGxubAwKDIyOjNTS1CQmJCwuLPz+/Dw+PHRydAAAAAAAAAAAAAAAAAAAAAAAAAXboCaOZGmeaKoxWcSosMkk15W8cZ7VdZaXkcEgQtrxfD9RhHchima1GwlCGUBSFCaFxMrgRtnLFhWujWHhs2nJc8KoVlWGQnEn7/i8XgOwWAB7JwoONQ4KgSQAZRcOgHgSCwsSIhZMNRZ5CzULIgaWF5h4mhecfIQ8jXmQkiODhYeIiRYGjrG2PxgBARi3IhNMAbcCnwI5BAQpAZ8TIwK6vCQVDwUVKL+WzAANTA210g/VJ8OWxQefByQE4dZMzBoInwh4zrtgn2p725YNthUFTNRuGYB3AYGBHCEAACH5BAkJAB0ALAAAAAAgACAAhAQCBISChFRWVMzKzCQiJOTm5GxqbCwuLJSWlPz6/NTW1AwODJSSlGRmZCwqLOzu7HR2dDQ2NAQGBISGhFxaXNTS1CQmJOzq7GxubDQyNKSmpPz+/Nza3AAAAAAAAAAAAAXfYCeOZGmeaKqurHBdAiuP17Zdc0lMAVHWt9yI8LA9fCPB4xEjARoNSWpis01kBpshFahurqzsZosiGpErScMAUO0maKF8Tq/bTQCIQgFp30cQXhB1BHEcXhx0FgkJFiOHVYlzi42AgoRxeRx8fn+en3UABwedKgsBAwMBCygOCjYKDisLFV4VrCUAtVUKpSZdXl8mB8EbByQWcQPFAyYZxccdB7sV0cvBzbmvvG0LBV4FrFTBYCWuNhyyHRTFFB20trh4BxmdYl4YIqepq0IRxRE+IfDCAFQHARo0NGERAgAh+QQJCQAgACwAAAAAIAAgAIUEAgSEgoRMTkzMyswcHhzk5uR0cnQUFhRcXlwsKiz09vQMCgyMiozU1tQkJiR8fnxkZmT8/vwEBgSEhoRcWlzU0tQkIiT08vR0dnQcGhxkYmQ0MjT8+vwMDgyMjozc2twAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG+UCQcEgsGo/IpHLJXDweC6Z0+IhEHlOjRGIMWLHZoUZx0RQlAajxkFFKFFYFl5m5KNpIySU+X2bIBEoQZBBZGQdMElFhjI2Oj5AgHQEDAw8dQxYeDBaNHRVWVhWYCXsRFwmMXqFWEyAerB6MA6xWA6+xs7URt6VWqIwTu64gDh4eDp6goaORQ5OVAZjO1EgEGhB4RwAYDQ0YAEwIcBEKFEgYrBhLBORxgUYfrB9LELuF8fNDAAaVBuEg7NXCVyRdqHVCGLBiIIQAB1Yc4BXh9uEbwAXuyi2iQI7DuSwHdiFqCEGDtizLRFUDsaGAlQIbVoJYIEDAIiZBAAAh+QQJCQAbACwAAAAAIAAgAIQEAgSMioxcWlz08vQcHhysqqwMDgx8enwsKiykoqRkZmT8+vzEwsQMCgyUlpQkJiS0srQEBgSMjoxcXlz09vQkIiSsrqwUEhQ0MjRsamz8/vwAAAAAAAAAAAAAAAAAAAAF7+AmjmRpnmiqruz2PG0sIssCj4CQJAIgj4/abRNJaI6agu9kCAQaphdJgEQKUIFjgGWsahJYLdf7RTWfLKr3+jsBClVlG5Xb9eb4fImgUBBKDVB4ExRHFGwbGRQLGXMEhUgUfw2QC4IyCmSNDQtHlm2ZXgoiGQsUjW0EnUgLfyKBeYSeiHojfH61uS0GBisVEgEVLRcWRxAXKAgDRwMILMVIECgSVRIrBmS9JtRI1iMVBweuGxerSNolyszOIhjLGs0jEFXSKA8SEkMbcEgWIxfzNBxrw6AKgxIGkM05UOWALhERHJhysOThBgAVWYQAACH5BAkJABkALAAAAAAgACAAhAQGBIyKjERCRMzOzCwuLGRiZPz6/OTm5AwODLSytFRSVNTW1Dw6PHx6fAwKDJSSlERGRNTS1DQyNGxqbPz+/BQSFLy6vFRWVNza3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAXqYCaO5FgFwxBUZeu61ULNFMa+eBvQdJD/owFvFhkBBAwHsBQZUooZyWF2YOQkBNJu6ANMaQeli0AxSEwymi0DcUJeEgPlbEJFAghRe/h+Eeg/Dl9UYks5DF9VhksOAgKFi5GSSwh5kzgVCXIJNxknD5aSCTwJIw8zD5MITpanFKmSCHI8NxUPoJejNKWXLZkznL0vCJ3CxsckDpA/ChYJFzkTBgYTSxc80C4OswbLLhY8Fi/bMwYAJVgl4DTiL9LUJADrFuci1zTZLwD1IwU8BSQuWLCQb1EDHg2QiSDALYvCDAISJLDy8FIIACH5BAkJAB4ALAAAAAAgACAAhAQGBISGhFRSVNTW1CQiJKyqrGRmZOzu7CwuLIyOjGxubPz6/BQSFGRiZOTi5CwqLLy6vDQ2NIyKjFRWVCQmJKyurGxqbPT29DQyNJSSlHRydPz+/BQWFOzq7AAAAAAAAAXhoCeOJElYClGubOs117YtjWuvxCLLi3qbhc6h4FPsdorfiNI5dige43GT9AAkHUcCwCpMNxVP7tgTJY4J1uF7EBl0M8Ooueuo2SOCIkVa11kVX2E2EmgsFH4yBz4uAAkdHVstBAUHQ4xKmZqbnJ2bAhAQAiURGJ4eE0cTIxgzpp0QRxCsrp6xO7MjpaepO6unKxOhv8DFxsfIJBwaChw2DAkZDEocDjIOzi0ZMhlKUjIaLtsb3T8aR+EtDBkJ0yQUBQVQI9XX2ZsDMgMlyxr3mzE2XEgmotCGAARFIHiQ0FMIACH5BAkJABgALAAAAAAgACAAhAQCBISGhDw+POTi5CwuLLS2tPTy9BQSFJyenGRiZDQ2NIyOjLy+vPz6/BweHIyKjFRSVOzq7DQyNLy6vBQWFHRydDw6PPz+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXXICaOZHkcZaquIjVd10SxtFrAcFGrVhBYIwoON9uNAsOA6DCEFTEKBEKxEjQvAtELNxkpGrAGNfW4Plpb2QgxRKjKzfPoVGLj3CnLNUv7hscpSDhKOxJSgDwPP0ZGAACMjAQFDQYFBJA0BAZDBpeYGBQVFUU3TV2YFAMwAzNgTQ2PkBVDFRiuQ7CYszi1pUOnkKmrM5qcnqiiTwQTDQ2Wn9DR0tPUfRKQEBEREDQSFw3XRhEwEd3f4TvjF+XWKgJ8JNnb0QkwCdUlCzAL+CQODAwc9BtIMAQAOw==)!important}#toast-container>.toast-error{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=)!important}#toast-container>.toast-success{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==)!important}#toast-container>.toast-warning{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=)!important}#toast-container.toast-bottom-full-width>div,#toast-container.toast-top-full-width>div{width:96%;margin:auto}.toast{background-color:#030303}.toast-success{background-color:#51a351}.toast-error{background-color:#bd362f}.toast-info{background-color:#2f96b4}.toast-wait{background-color:#2f96b4}.toast-warning{background-color:#f89406}@media all and (max-width:240px){#toast-container>div{padding:8px 8px 8px 50px;width:11em}#toast-container .toast-close-button{right:-.2em;top:-.2em}}@media all and (min-width:241px) and (max-width:480px){#toast-container>div{padding:8px 8px 8px 50px;width:18em}#toast-container .toast-close-button{right:-.2em;top:-.2em}}@media all and (min-width:481px) and (max-width:768px){#toast-container>div{padding:15px 15px 15px 50px;width:25em}}:not(.no-enter)#toast-container>div.ng-enter,:not(.no-leave)#toast-container>div.ng-leave{-webkit-transition:1s cubic-bezier(.25,.25,.75,.75) all;-moz-transition:1s cubic-bezier(.25,.25,.75,.75) all;-ms-transition:1s cubic-bezier(.25,.25,.75,.75) all;-o-transition:1s cubic-bezier(.25,.25,.75,.75) all;transition:1s cubic-bezier(.25,.25,.75,.75) all}:not(.no-enter)#toast-container>div.ng-enter.ng-enter-active,:not(.no-leave)#toast-container>div.ng-leave{opacity:.8}:not(.no-enter)#toast-container>div.ng-enter,:not(.no-leave)#toast-container>div.ng-leave.ng-leave-active{opacity:0}html{overflow:auto;height:100%;margin:0;padding:0}body{height:100%;margin:0;padding:0;color:#323232;font-family:Arial,Helvetica,sans-serif;font-size:1em}div,input,li,span,td,textarea{font-size:1em}.container{font-size:1.2em}.footer{margin:1em 0 1em 0}input[disabled],textarea[disabled]{background-color:#f6f6f6}.strong,strong{font-weight:700}.likeH2,h1,h2,h3{color:#f60;text-align:center}h1{font-size:2em;margin:0}.likeH2,h2{font-size:1.8em;font-weight:lighter;line-height:1em;margin:0 0 1em}h3{font-size:1.6em;font-weight:lighter;line-height:1em;margin:0 0 1em;text-align:left}img{border:none;vertical-align:middle}.banner{margin:1.5em 0 1.5em 0}.sub-banner{margin:0 0 1.5em 0}.underlined{text-decoration:underline}.header img{float:left}.header h1{position:relative}hr{margin-top:10px;margin-bottom:10px}.table{text-align:left!important}.centered{text-align:center;color:#cbcbcb}.customTables,.dropdown-menu{text-align:left!important}.resourceCombo{width:100%}.top05{margin-top:.5em}.top10{margin-top:1em}.top15{margin-top:1.5em}.top20{margin-top:2em}.top25{margin-top:2.5em}.top30{margin-top:3em}.left05{margin-left:.5em}.left10{margin-left:1em}.left15{margin-left:1.5em}.left20{margin-left:2em}.left25{margin-left:2.5em}.left30{margin-left:3em}.black{color:#333}.divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.img-dashboard{padding-top:30px;margin:auto} \ No newline at end of file diff --git a/old/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.eot b/old/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 00000000..4a4ca865 Binary files /dev/null and b/old/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.eot differ diff --git a/old/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.svg b/old/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.svg new file mode 100644 index 00000000..e3e2dc73 --- /dev/null +++ b/old/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.svg @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/old/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.ttf b/old/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 00000000..67fa00bf Binary files /dev/null and b/old/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.ttf differ diff --git a/old/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.woff b/old/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.woff new file mode 100644 index 00000000..8c54182a Binary files /dev/null and b/old/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.woff differ diff --git a/old/moon_gui/delivery/assets/i18n/en.json b/old/moon_gui/delivery/assets/i18n/en.json new file mode 100755 index 00000000..4dc7cea5 --- /dev/null +++ b/old/moon_gui/delivery/assets/i18n/en.json @@ -0,0 +1,1357 @@ +{ + "moon": { + "global": { + "applicationName": "Moon", + "404": "Page not found", + "error": "A global error occurs: {{stacktrace}}" + }, + "compatibility": { + "label": "Browsers compatibility", + "title": "Existing browsers compatibility", + "content": "Moon is compliant with : ", + "close": "Close" + }, + "menu": { + "project": "Project", + "pdp": "PDP", + "logs": "Log", + "policy": "Policy", + "model":"Model" + }, + "login":{ + "title" : "Login", + "titlePage" : "Login page", + "username" : "Username", + "password" : "Password", + "login": "Login", + "check": { + "username": { + "required": "Username is required" + }, + "password": { + "required": "Password is required" + } + }, + "error" :"Unable to login into Keystone, error code : {{errorCode}}", + "success" : "Connection established. Welcome to Moon GUI, \"Moon is uppon cloud\"" + }, + "logout": { + "title": "Logout", + "success" : "Successfully logout" + }, + "dashboard":{ + "content" : "Moon:Software-Defined Security Framework" + }, + "policy":{ + "title": "Policies", + "list" : { + "search": { + "placeholder": "Search Policies", + "reset": "Reset" + }, + "table" : { + "name":"Name", + "genre" : "Genre", + "description": "Description", + "loading": { + "category" : "Loading Category" + }, + "notFound": "There is no Policy" + }, + "action": { + "title": "Actions", + "add": "Add Policy", + "detail": "Consut", + "edit": "Edit", + "map" : "Map Policy to PDP", + "unmap" : "Unmap", + "delete": "Delete" + } + }, + "unmap": { + "title": "Unmap Policy to PDP", + "content": "Are you sure you want to unmap PDP `{{pdpName}}` / Policy `{{policyName}}` ?", + "action": { + "unmap": "Unmap", + "cancel": "Cancel" + }, + "error": "Unable to unmap PDP `{{pdpName}}` /Policy `{{policyName}}`", + "success": "PDP `{{pdpName}}` / Policy `{{policyName}}` successfully unmapped" + }, + "map":{ + "title": "Map a Policy to PDP `{{pdpName}}`", + "form" :{ + "list": "List of Policies" + }, + "action": { + "create": "Map Policy", + "cancel": "Cancel", + "new": "Create a Policy", + "list": "Map an existing Policy", + "map": "Map the selected Policy", + "delete" : "Delete the selected Policy" + }, + "check": { + "policy":{ + "required" : "Policy is required" + } + }, + "error": "Unable to map Policy `{{policyName}}` to the PDP `{{pdpName}}`", + "success": "Policy `{{policyName}}` successfully mapped to the PDP `{{pdpName}}`" + }, + "remove": { + "title": "Delete Policy", + "content": { + "query": "Are you sure you want to delete `{{policyName}}` Policy ?" + }, + "action": { + "cancel": "Cancel", + "delete": "Delete" + }, + "error": "Unable to delete Policy `{{policyName}}`, error code : {{errorCode}}, message : \"{{message}}\"", + "success": "Model `{{policyName}}` successfully deleted" + }, + "edit" : { + "title": "Policy `{{policyName}}` configuration", + "update" : "- update", + "show": { + "open": "( show )", + "close": "( close )" + }, + "basic" : { + "title" : "Basic Information", + "form": { + "id": "Id", + "name": "Name", + "genre": "Genre", + "model": "Model", + "description": "Description" + }, + "action": { + "init": "Init", + "update": "Update" + }, + "check": { + "name": { + "required": "Name is required" + }, + "genre": { + "required": "Genre is required" + } + }, + "error": "Unable to update Policy `{{policyName}}`", + "success": "Policy `{{policyName}}` successfully updated" + }, + "perimeter": { + "title" : "Perimeters" + }, + "data": { + "title" : "Data" + }, + "rules" : { + "title" : "Rules" + }, + "assignments": { + "title" : "Assignments" + } + }, + "add":{ + "title": "Add new Policy", + "form": { + "name": "Name", + "genre": "Genre", + "model": "Models", + "description": "Description" + }, + "action": { + "create": "Create Policy", + "cancel": "Cancel" + }, + "check": { + "name": { + "required": "Name is required" + }, + "genre": { + "required": "Genre is required" + }, + "model": { + "required": "Model is required" + } + }, + "error": "Unable to create Policy `{{policyName}}`", + "success": "Policy `{{policyName}}` successfully created" + }, + "perimeter": { + "subject" : { + "title" : "List of associated Subjects", + "delete": { + "error" : "Unable to delete {{subjectName}} Subject, reason : {{reason}}", + "success": "Subject `{{subjectName}}` successfully deleted" + }, + "add": { + "title": "Add a Subject" + }, + "notFound": "There is no Subject" + }, + "object" : { + "title" : "List of associated Objects", + "delete": { + "error" : "Unable to delete {{objectName}} Object, reason : {{reason}}", + "success": "Object `{{objectName}}` successfully deleted" + }, + "add": { + "title": "Add an Object" + }, + "notFound": "There is no Object" + }, + "action" : { + "title" : "List of associated Actions", + "delete": { + "error" : "Unable to delete {{actionName}} Action, reason : {{reason}}", + "success": "Action `{{actionName}}` successfully deleted" + }, + "add": { + "title": "Add an Action" + }, + "notFound": "There is no Action" + }, + "update":{ + "error": "Unable to update Perimeter `{{perimeterName}}`", + "success": "Perimeter `{{perimeterName}}` successfully updated" + }, + "table": { + "id" : "Id", + "name" : "Name", + "description" : "Description", + "email" : "Email", + "partner":{ + "id" : "Partner Id" + }, + "action": { + "title": "Actions", + "delete": "Delete", + "update": "Update", + "unmap": "Unmap" + } + }, + "edit": { + "name" : "Name", + "description" : "Description", + "partnerId": "Partner Id", + "policies": "Policy list", + "email": "E-mail", + "selectedPolicies": "Selected Policies", + "check": { + "name": { + "required": "Name is required" + } + }, + "action": { + "list": "Add an existing Perimeter", + "new": "Add a new Perimeter", + "create": "Add Perimeter", + "add": "Add the selected Perimeter", + "delete" : "Delete the selected Perimeter" + }, + "create":{ + "error": "Unable to create `{{name}}`", + "success": "`{{name}}` successfully created" + }, + "delete":{ + "error": "Unable to delete `{{name}}`", + "success": "`{{name}}` successfully deleted" + } + } + }, + "data": { + "subject" : { + "title" : "List of associated Data Subjects", + "delete": { + "error" : "Unable to delete {{subjectName}} Subject, reason : {{reason}}", + "success": "Subject `{{subjectName}}` successfully deleted" + }, + "add": { + "title": "Add a Data Subject" + }, + "notFound": "There is no Data Subject" + }, + "object" : { + "title" : "List of associated Data Objects", + "delete": { + "error" : "Unable to delete {{objectName}} Object, reason : {{reason}}", + "success": "Object `{{objectName}}` successfully deleted" + }, + "add": { + "title": "Add a Data Object" + }, + "notFound": "There is no Data Object" + }, + "action" : { + "title" : "List of associated Actions", + "delete": { + "error" : "Unable to delete {{actionName}} Action, reason : {{reason}}", + "success": "Action `{{actionName}}` successfully deleted" + }, + "add": { + "title": "Add a Data Action" + }, + "notFound": "There is no Data Action" + }, + "table": { + "category" : { + "id" : "Category Id", + "name" : "Category Name" + }, + "name" : "Name", + "description" : "Description", + "action": { + "title": "Actions", + "delete": "Delete", + "update": "Update" + }, + "loading": { + "category" : "Loading Category" + } + }, + "edit": { + "name" : "Name", + "description" : "Description", + "categories" : "Category List", + "policies": "Policy List", + "check": { + "name": { + "required": "Name is required" + }, + "category":{ + "required": "A Category is required" + }, + "policy":{ + "required": "A Policy is required" + } + }, + "action": { + "list": "Add an existing Data", + "new": "Create a new Data", + "create": "Create Data", + "add": "Add the selected Data", + "delete": "Delete Data" + }, + "create":{ + "error": "Unable to create `{{name}}`", + "success": "`{{name}}` successfully created" + }, + "delete":{ + "error": "Unable to delete `{{name}}`", + "success": "`{{name}}` successfully deleted" + } + } + }, + "rules": { + "title": "Rules", + "list": { + "search": { + "placeholder": "Search Rule", + "reset": "Reset" + }, + "table": { + "id" : "Id", + "metaRule": "Meta Rule", + "description": "Description", + "enabled": "Enabled", + "rule": "Rule", + "instructions": "Instruction", + "notFound": "There is no Rule", + "loading": { + "metaRule" : "Loading Meta Rule" + }, + "action":{ + "title": "Actions", + "delete": "Delete" + } + }, + "action": { + "title": "Actions", + "add": "Add Rule", + "detail": "Consult", + "edit": "Edit", + "delete": "Delete" + }, + "error": "Unable to retrieve Rule" + }, + "edit": { + "title" : "List of associated Rules", + "action" : { + "create": "Create Rules", + "delete": { + "error" : "Unable to delete {{rulesName}} Action, reason : {{reason}}", + "success": "Rules `{{rulesName}}` successfully deleted" + }, + "add": { + "title": "Add a Rule", + "policies": "Select a policy", + "instructions": "Instruction", + "metarules" : "Select one of the associated MetaRules", + "categories":{ + "subject": "Select {{number}} Subject(s)", + "object": "Select {{number}} Object(s)", + "action": "Select {{number}} Action(s)" + }, + "selectedSubjects": "Selected Subject(s)", + "selectedObjects": "Selected Object(s)", + "selectedActions": "Selected Action(s)", + "details":{ + "show": "Details", + "close": "Close" + }, + "check":{ + "policy":{ + "required": "A Policy is required" + }, + "instructions":{ + "required": "An Instruction in JSON format is required" + }, + "metarules":{ + "required": "A MetaRule is required" + }, + "subject":{ + "required": "{{number}} Subject(s) are required" + }, + "object":{ + "required": "{{number}} Object(s) are required" + }, + "action":{ + "required": "{{number}} Action(s) are required" + } + }, + "create":{ + "error": "Unable to create Rules", + "success": "Rules successfully created" + }, + "delete":{ + "error": "Unable to delete Rules, reason : `{{reason}}`", + "success": "Rules successfully deleted" + } + }, + "notFound": "There is no Rules" + } + } + }, + "assignments": { + "subject" : { + "title" : "List of associated Assignments Subjects", + "delete": { + "error" : "Unable to delete Assignments, reason : {{reason}}", + "success": "Assignments successfully deleted" + }, + "add": { + "title": "Add a Assignments Subject" + }, + "notFound": "There is no Assignments Subject" + }, + "object" : { + "title" : "List of associated Assignments Objects", + "delete": { + "error" : "Unable to delete Assignments, reason : {{reason}}", + "success": "Assignments successfully deleted" + }, + "add": { + "title": "Add a Assignments Object" + }, + "notFound": "There is no Assignments Object" + }, + "action" : { + "title" : "List of associated Assignments Actions", + "delete": { + "error" : "Unable to delete Assignments, reason : {{reason}}", + "success": "Assignments successfully deleted" + }, + "add": { + "title": "Add a Assignments Action" + }, + "notFound": "There is no Assignments Action" + }, + "table": { + "action": { + "title": "Actions", + "delete": "Delete", + "update": "Update" + }, + "perimeter": { + "name" : "Perimeter name" + }, + "data": { + "name": "Data name" + }, + "category": { + "name" : "Category name" + }, + "loading": { + "category" : "Loading Category", + "perimeter": "Loading Perimeter", + "data": "Loading Data" + } + }, + "edit": { + "policies": "Select a Policy", + "categories": "Select a Category", + "perimeters": "Select a Perimeter", + "data": "Select a Data", + "selectedData" : "Selected Data", + "check": { + "policy":{ + "required": "A Policy is required" + }, + "category":{ + "required": "A Category is required" + }, + "perimeter":{ + "required": "A Perimeter is required" + }, + "data":{ + "required": "A Data is required" + } + }, + "action": { + "list": "Add an existing Assignments", + "new": "Add a new Assignments", + "create": "Create Assignments", + "map": "Add the selected Assignments", + "delete": "Delete Assignments" + }, + "create":{ + "error": "Unable to create Assignments", + "success": "Assignments successfully created" + }, + "delete":{ + "error": "Unable to delete Assignments, reason : `{{reason}}`", + "success": "Assignments successfully deleted" + } + } + } + }, + "model":{ + "title": "Models", + "list": { + "search": { + "placeholder": "Search Model", + "reset": "Reset" + }, + "table":{ + "name":"Name", + "description": "Description", + "metaRules":{ + "number" : "Number of Meta Rules" + }, + "notFound": "There is no Models" + }, + "action": { + "title": "Actions", + "add": "Add Model", + "detail": "Consult", + "edit": "Edit", + "delete": "Delete" + }, + "error": "Unable to retrieve Models" + }, + "edit" : { + "title": "Model `{{modelName}}` configuration", + "update" : "- update", + "basic" : { + "title" : "Basic Information", + "form": { + "id": "Id", + "name": "Name", + "description": "Description" + }, + "action": { + "init": "Init", + "update": "Update" + }, + "check": { + "name": { + "required": "Name is required" + } + }, + "error": "Unable to update Model `{{modelName}}`", + "success": "Model `{{modelName}}` successfully updated" + }, + "metarules": { + "title" : "Meta Rules" + } + }, + "view": { + "title": "Model `{{modelName}}` details", + "name": "Name", + "id": "Id", + "description": "Description", + "action": { + "close": "Close" + } + }, + "remove": { + "title": "Delete Model", + "content": { + "query": "Are you sure you want to delete `{{modelName}}` Model ?" + }, + "action": { + "cancel": "Cancel", + "delete": "Delete" + }, + "error": "Unable to delete Model `{{modelName}}`, error code : {{errorCode}}, message : \"{{message}}\"", + "success": "Model `{{modelName}}` successfully deleted" + }, + "metarules": { + "title": "List of Meta Rules", + "table": { + "name":"Name", + "description": "Description", + "metadata": { + "subject": { + "number": "Number of Subject Categories" + }, + "object" : { + "number": "Number of Object Categories" + }, + "action": { + "number": "Number of Action Categories" + } + }, + "notFound": "There is no Meta Rules" + }, + "edit" : { + "title" : "Meta Rule `{{metaRuleName}}` configuration", + "update": "- update", + "basic": { + "title": "Basic Information", + "form": { + "id": "Id", + "name": "Name", + "description": "Description" + }, + "action": { + "init": "Init", + "update": "Update" + }, + "check": { + "name": { + "required": "Name is required" + } + }, + "error": "Unable to update Meta Rule `{{metaRuleName}}`", + "success": "Meta Rule `{{metaRuleName}}` successfully updated" + } + }, + "update":{ + "error": "Unable to update Meta Rule `{{metaRuleName}}`", + "success": "Meta Rule `{{metaRuleName}}` successfully updated" + }, + "action": { + "title": "Actions", + "edit": "Edit", + "remove": "Remove", + "settings" : "Settings", + "add": "Add", + "detail": { + "open": "Consult", + "close": "Close" + } + }, + "add": { + "title": "Add new Meta Rule", + "form": { + "name": "Nom", + "description": "Description" + }, + "action": { + "create": "Add Meta Rule", + "cancel": "Cancel" + }, + "check": { + "name": { + "required": "Name is required" + } + }, + "error": "Unable to create Meta Rule `{{metaRuleName}}`", + "success": "Meta Rule `{{metaRuleName}}` successfully created" + }, + "map":{ + "title": "Add a Meta Rule", + "form" :{ + "list": "List of Meta Rules" + }, + "action": { + "create": "Add a new Meta Rule", + "cancel": "Cancel", + "new": "Add a Meta Rule", + "list": "Add an existing Meta Rule", + "add": "Add the selected Meta Rule", + "delete" : "Delete the selected Meta Rule" + }, + "error": "Unable to map Model `{{modelName}}` to the Meta Rule `{{metaRuleName}}`", + "success": "Model `{{modelName}}` successfully mapped to the Meta Rule `{{metaRuleName}}`" + }, + "unmap": { + "title": "Remove Meta Rule to Model", + "content": "Are you sure you want to remove Model `{{modelName}}` / Meta Rule `{{metaRuleName}}` ?", + "action": { + "unmap": "Remove", + "cancel": "Cancel" + }, + "error": "Unable to remove Model `{{modelName}}` / Meta Rule `{{metaRuleName}}`", + "success": "Model `{{modelName}}` / Meta Rule `{{metaRuleName}}` successfully removed" + }, + "delete":{ + "error": "Unable to delete Meta Rule `{{metaRuleName}}`", + "success": "Meta Rule `{{metaRuleName}}` successfully deleted" + } + }, + "metadata": { + "subject" : { + "title" : "List of associated Subject Categories", + "delete": { + "error" : "Unable to delete {{subjectName}} Subject, reason : {{reason}}", + "success": "Subject `{{subjectName}}` successfully deleted" + }, + "add": { + "title": "Add a Subject Category" + }, + "notFound": "There is no Subject" + }, + "object" : { + "title" : "List of associated Object Categories", + "delete": { + "error" : "Unable to delete {{objectName}} Object, reason : {{reason}}", + "success": "Object `{{objectName}}` successfully deleted" + }, + "add": { + "title": "Add an Object Category" + }, + "notFound": "There is no Object" + }, + "action" : { + "title" : "List of associated Action Categories", + "remove": "Remove", + "delete": { + "error" : "Unable to delete {{actionName}} Action, reason : {{reason}}", + "success": "Action `{{actionName}}` successfully deleted" + }, + "add": { + "title": "Add an Action Category" + }, + "notFound": "There is no Action" + }, + "table": { + "id" : "Id", + "name" : "Name", + "description" : "Description", + "action": { + "title": "Actions", + "delete": "Delete", + "update": "Update" + } + }, + "edit": { + "name" : "Name", + "description" : "Description", + "check": { + "name": { + "required": "Name is required" + } + }, + "action": { + "list": "Add an existing Category", + "new": "Add a new Category", + "create": "Add Category", + "add": "Add the selected Category", + "delete": "Delete" + }, + "create":{ + "error": "Unable to create Category `{{name}}`", + "success": "Category `{{name}}` successfully created" + }, + "delete":{ + "error": "Unable to delete Category `{{name}}`", + "success": "Category `{{name}}` successfully deleted" + } + } + }, + "add":{ + "title": "Add new Model", + "form": { + "name": "Name", + "description": "Description" + }, + "action": { + "create": "Create Model", + "cancel": "Cancel" + }, + "check": { + "name": { + "required": "Name is required" + } + }, + "error": "Unable to create Model `{{modelName}}`", + "success": "Model `{{modelName}}` successfully created" + } + }, + "project": { + "title": "Projects", + "list": { + "search": { + "placeholder": "Search Projects", + "reset": "Reset" + }, + "table": { + "name": "Name", + "domain": "Domain", + "managed": "Managed", + "enabled": "Enabled", + "description": "Description", + "mapping": "PDP", + "loading": { + "project": "Loading Projects", + "pdp": "Loading PDP" + }, + "notFound": "There is no Projects" + }, + "action": { + "title": "Actions", + "detail": "Consult", + "delete": "Delete", + "add": "Add Project", + "map": "Map to a PDP", + "unmap": "Unmap" + }, + "error": "Unable to retrieve Projects" + }, + "view": { + "title": "Project `{{projectName}}` details", + "action": { + "close": "Close" + }, + "subject": { + "title": "Subjects", + "name": "Name", + "mail": "Email", + "domain": "Domain", + "enabled": "Enabled", + "error": "Unable to retrieve Subjects" + }, + "object": { + "title": "Objects", + "category": "Category", + "description": "Description", + "enabled": "Enabled", + "name": "Name", + "error": "Unable to retrieve Objects", + "loading": "Loading Objects", + "notFound": "There is no Objects" + }, + "role": { + "title": "Roles", + "category": "Category", + "value": "Value", + "description": "Description", + "assigned": "Assigned", + "enabled": "Enabled", + "error": "Unable to retrieve Roles", + "loading": "Loading Roles", + "notFound": "There is no Roles" + }, + "roleAssignment": { + "title": "Role Assignments", + "category": "Category", + "attributes": "Attributes", + "description": "Description", + "error": "Unable to retrieve Role Assignments", + "loading": "Loading Role Assignments", + "notFound": "There is no Role Assignments" + }, + "group": { + "title": "Groups", + "category": "Category", + "value": "Value", + "description": "Description", + "assigned": "Assigned", + "enabled": "Enabled", + "error": "Unable to retrieve Groups", + "loading": "Loading Groups", + "notFound": "There is no Groups" + }, + "groupAssignment": { + "title": "Group Assignments", + "category": "Category", + "attributes": "Attributes", + "description": "Description", + "error": "Unable to retrieve Group Assignments", + "loading": "Loading Group Assignments", + "notFound": "There is no Group Assignments" + } + }, + "add": { + "title": "Add new Project", + "form": { + "name": "Name", + "description": "Description", + "enabled": "Enabled", + "domain": "Domain" + }, + "action": { + "create": "Create Project", + "cancel": "Cancel" + }, + "check": { + "name": { + "required": "Name is required" + }, + "domain": { + "required": "Domain is required" + } + }, + "error": "Unable to create Project `{{projectName}}`", + "success": "Project `{{projectName}}` successfully created" + }, + "remove": { + "title": "Delete Project", + "content": { + "query": "Are you sure you want to delete `{{projectName}}` Project ?", + "isNotMapped": "This Project is not mapped to any PDP", + "isMapped": "This project is mapped to `{{pdpName}}` PDP, delete this Project, will remove the mapping." + }, + "mapping":{ + "remove":{ + "error": "Unable to remove mapping with Pdp : `{{pdpName}}`" + } + }, + "action": { + "cancel": "Cancel", + "delete": "Delete" + }, + "error": "Unable to delete Project `{{projectName}}`, error code : {{errorCode}}, message : \"{{message}}\"", + "success": "Project `{{projectName}}` successfully deleted" + }, + "map": { + "title": "Map Project `{{projectName}}` to a PDP", + "form": { + "pdp": "PDP" + }, + "action": { + "map": "Map", + "cancel": "Cancel" + }, + "check": { + "pdp": { + "required": "PDP is required" + } + }, + "error": "Unable to map Project `{{projectName}}` to a PDP `{{pdpName}}`", + "success": "Project `{{projectName}}` successfully mapped to a PDP `{{pdpName}}`" + }, + "unmap": { + "title": "Unmap Project and PDP", + "content": "Are you sure you want to unmap Project `{{projectName}}` / PDP `{{pdpName}}` ?", + "action": { + "unmap": "Unmap", + "cancel": "Cancel" + }, + "error": "Unable to unmap Project `{{projectName}}` / PDP `{{pdpName}}`", + "success": "Project `{{projectName}}` / PDP `{{pdpName}}` successfully unmapped" + } + }, + "pdp": { + "title": "PDPs", + "edit" : { + "title": "Pdp `{{pdpName}}` configuration", + "update" : "- update", + "basic" : { + "title" : "Basic Information", + "form": { + "id": "Id", + "name": "Name", + "description": "Description" + }, + "action": { + "init": "Init", + "update": "Update" + }, + "check": { + "name": { + "required": "Name is required" + } + }, + "error": "Unable to update PDP `{{pdpName}}`", + "success": "PDP `{{pdpName}}` successfully updated" + }, + "policy": { + "title" : "Policies" + } + }, + "list": { + "search": { + "placeholder": "Search PDPs", + "reset": "Reset" + }, + "table": { + "name": "Name", + "security_pipeline":{ + "number" : "Number of Securities" + }, + "project": "Project", + "loading": { + "pdp": "Loading PDPs", + "project": "Loading Project" + }, + "mapping" :{ + "map": "Is not mapped" + }, + "notFound": "There is no PDPs" + }, + "action": { + "title": "Actions", + "detail": "Consult", + "configure": "Configure", + "rule": "Rules", + "delete": "Delete", + "add": "Add PDP", + "edit":"Editer" + }, + "error": "Unable to retrieve PDPs" + }, + "add": { + "title": "Add new PDP", + "form": { + "name": "Name", + "policy": "Policy", + "description": "Description" + }, + "action": { + "create": "Create PDP", + "cancel": "Cancel" + }, + "check": { + "name": { + "required": "Name is required" + }, + "policy": { + "required": "Policy is required" + } + }, + "error": "Unable to create PDP `{{pdpName}}`", + "success": "PDP `{{pdpName}}` successfully created" + }, + "remove": { + "title": "Delete PDP", + "content": "Are you sure you want to delete `{{pdpName}}` PDP ?", + "action": { + "cancel": "Cancel", + "delete": "Delete" + }, + "error": "Unable to delete PDP `{{pdpName}}`", + "success": "PDP `{{pdpName}}` successfully deleted" + }, + "configure": { + "title": "PDP `{{pdpName}}` configuration", + "action": { + "back": "Back to PDPs" + }, + "subject": { + "panelTitle": "Subjects configuration", + "title": "Subjects", + "add": { + "title": "Add new Subject", + "form": { + "name": "Name", + "domain": "Domain", + "enabled": "Enabled", + "project": "Project", + "password": "Password", + "description": "Description" + }, + "action": { + "cancel": "Cancel", + "add": "Add Subject" + }, + "check": { + "name": { + "required": "Name is required" + }, + "domain": { + "required": "Domain is required" + }, + "project": { + "required": "Project is required" + }, + "password": { + "required": "Password is required" + } + }, + "error": "Unable to add Subject `{{subjectName}}`", + "success": "Subject `{{subjectName}}` successfully added" + }, + "remove": { + "title": "Delete Subject", + "content": "Are you sure you want to delete `{{subjectName}}` subject of `{{pdpName}}` PDP ?", + "action": { + "cancel": "Cancel", + "delete": "Delete" + }, + "error": "Unable to delete Subject `{{subjectName}}`", + "success": "Subject `{{subjectName}}` successfully deleted" + }, + "category": { + "title": "Categories", + "add": { + "title": "Add new Category", + "form": { + "name": "Name" + }, + "action": { + "cancel": "Cancel", + "add": "Add Category" + }, + "check": { + "name": { + "required": "Name is required" + } + }, + "error": "Unable to add Subject Category `{{categoryName}}`", + "success": "Subject Category `{{categoryName}}` successfully added" + }, + "remove": { + "title": "Delete Category", + "content": "Are you sure you want to delete `{{categoryName}}` subject category of `{{pdpName}}` PDP ?", + "action": { + "cancel": "Cancel", + "delete": "Delete" + }, + "error": "Unable to delete Subject Category `{{categoryName}}`", + "success": "Subject Category `{{categoryName}}` successfully deleted" + } + }, + "categoryValue": { + "title": "Values", + "add": { + "title": "Add new Value", + "form": { + "value": "Value" + }, + "action": { + "cancel": "Cancel", + "add": "Add Value" + }, + "check": { + "value": { + "required": "Value is required" + } + }, + "error": "Unable to add Subject Category Value`{{valueName}}`", + "success": "Subject Category Value `{{valueName}}` successfully added" + }, + "remove": { + "title": "Delete Value", + "content": "Are you sure you want to delete `{{valueName}}` subject category value of `{{pdpName}}` PDP ?", + "action": { + "cancel": "Cancel", + "delete": "Delete" + }, + "error": "Unable to delete Subject Category Value `{{valueName}}`", + "success": "Subject Category Value `{{valueName}}` successfully deleted" + } + }, + "assignment": { + "title": "Subject Assignments", + "action": { + "assign": "Assign", + "unassign": "Unassign" + }, + "list": { + "notFound": "There is no assignments" + }, + "add": { + "error": "Unable to assign Subject `{{subjectName}}` / Category `{{categoryName}}` / Value `{{valueName}}`", + "success": "Subject `{{subjectName}}` / Category `{{categoryName}}` / Value `{{valueName}}` assignment successfully done" + }, + "remove": { + "error": "Unable to unassign Subject `{{subjectName}}` / Category `{{categoryName}}` / Value `{{valueName}}`", + "success": "Subject `{{subjectName}}` / Category `{{categoryName}}` / Value `{{valueName}}` unassignment successfully done" + } + } + }, + "object": { + "panelTitle": "Objects configuration", + "title": "Objects", + "add": { + "title": "Add new Object", + "form": { + "name": "Name", + "image": "Image", + "flavor": "Flavor" + }, + "action": { + "cancel": "Cancel", + "add": "Add Object" + }, + "check": { + "name": { + "required": "Name is required" + }, + "image": { + "required": "Image is required" + }, + "flavor": { + "required": "Flavor is required" + } + }, + "error": "Unable to add Object `{{objectName}}`", + "success": "Object `{{objectName}}` successfully added" + }, + "remove": { + "title": "Delete Object", + "content": "Are you sure you want to delete `{{objectName}}` object of `{{pdpName}}` PDP ?", + "action": { + "cancel": "Cancel", + "delete": "Delete" + }, + "error": "Unable to delete Object `{{objectName}}`", + "success": "Object `{{objectName}}` successfully deleted" + }, + "category": { + "title": "Categories", + "add": { + "title": "Add new Category", + "form": { + "name": "Name" + }, + "action": { + "cancel": "Cancel", + "add": "Add Category" + }, + "check": { + "name": { + "required": "Name is required" + } + }, + "error": "Unable to add Object Category `{{categoryName}}`", + "success": "Object Category `{{categoryName}}` successfully added" + }, + "remove": { + "title": "Delete Category", + "content": "Are you sure you want to delete `{{categoryName}}` object category of `{{pdpName}}` PDP ?", + "action": { + "cancel": "Cancel", + "delete": "Delete" + }, + "error": "Unable to delete Object Category `{{categoryName}}`", + "success": "Object Category `{{categoryName}}` successfully deleted" + } + }, + "categoryValue": { + "title": "Values", + "add": { + "title": "Add new Value", + "form": { + "value": "Value" + }, + "action": { + "cancel": "Cancel", + "add": "Add Value" + }, + "check": { + "value": { + "required": "Value is required" + } + }, + "error": "Unable to add Object Category Value`{{valueName}}`", + "success": "Object Category Value `{{valueName}}` successfully added" + }, + "remove": { + "title": "Delete Value", + "content": "Are you sure you want to delete `{{valueName}}` object category value of `{{pdpName}}` PDP ?", + "action": { + "cancel": "Cancel", + "delete": "Delete" + }, + "error": "Unable to delete Object Category Value `{{valueName}}`", + "success": "Object Category Value `{{valueName}}` successfully deleted" + } + }, + "assignment": { + "title": "Object Assignments", + "action": { + "assign": "Assign", + "unassign": "Unassign" + }, + "list": { + "notFound": "There is no assignments" + }, + "add": { + "error": "Unable to assign Object `{{objectName}}` / Category `{{categoryName}}` / Value `{{valueName}}`", + "success": "Object `{{objectName}}` / Category `{{categoryName}}` / Value `{{valueName}}` assignment successfully done" + }, + "remove": { + "error": "Unable to unassign Object `{{ObjectName}}` / Category `{{categoryName}}` / Value `{{valueName}}`", + "success": "Object `{{objectName}}` / Category `{{categoryName}}` / Value `{{valueName}}` unassignment successfully done" + } + } + } + }, + "rule": { + "title": "PDP `{{pdpName}}` rules", + "list": { + "table": { + "subject": "Subjects", + "object": "Objects", + "notFound": "There is no Rules" + }, + "action": { + "title": "Actions", + "add": "Add Rule", + "delete": "Delete Rule" + } + }, + "add": { + "title": "Add new Rule", + "action": { + "create": "Create Rule", + "cancel": "Cancel" + }, + "form": { + "subject": { + "subject": "Subjects", + "category": "Categories", + "categoryValue": "Values", + "action": { + "add": "Add", + "delete": "Delete" + } + }, + "object": { + "object": "Objects", + "category": "Categories", + "categoryValue": "Values", + "action": { + "add": "Add", + "delete": "Delete" + } + } + }, + "success": "Rule successfully created", + "error": "Unable to create Rule" + }, + "delete": { + "title": "Delete Rule", + "content": "Are you sure you want to delete rule `{{ruleJson}}` of `{{pdpName}}` PDP ?", + "action": { + "delete": "Delete Rule", + "cancel": "Cancel" + }, + "error": "Unable to delete Rule `{{ruleJson}}`", + "success": "Rule `{{ruleJson}}` successfully deleted" + }, + "action": { + "back": "Back to PDPs" + } + } + } + } +} diff --git a/old/moon_gui/delivery/assets/i18n/fr.json b/old/moon_gui/delivery/assets/i18n/fr.json new file mode 100755 index 00000000..85c513b3 --- /dev/null +++ b/old/moon_gui/delivery/assets/i18n/fr.json @@ -0,0 +1,1357 @@ +{ + "moon": { + "global": { + "applicationName": "Moon", + "404": "Page non trouvée", + "error": "Une erreur globale est survenue: {{stacktrace}}" + }, + "compatibility": { + "label": "Compatibilité navigateurs Web", + "title": "Compatibilité avec les navigateurs existants", + "content": "Moon est compatible avec : ", + "close": "Fermer" + }, + "menu": { + "project": "Project", + "pdp": "PDP", + "logs": "Log", + "policy": "Politique", + "model": "Modèle" + }, + "login":{ + "title":"Connexion", + "titlePage" : "Page d'idenditifcation", + "username" : "Nom d'utilisateur", + "password" : "Mot de passe", + "login" : "Connexion", + "check": { + "username": { + "required": "Le nom d'utilisateur est requis" + }, + "password": { + "required": "Le mot de passe est requis" + } + }, + "error" : "Impossible de se connecter à Keystone, code d'erreur {{errorCode}}", + "success" : "Connexion établie, Bienvenue sur la GUI de Moon, \"La lune est au dessus des nuages\"" + }, + "logout": { + "title": "Déconnexion", + "success" : "Déconnxion réussie" + }, + "dashboard":{ + "content" : "Moon:Software-Defined Security Framework" + }, + "policy": { + "title": "Politiques", + "list" : { + "search": { + "placeholder": "Rechercher des Politiques", + "reset": "Effacer" + }, + "table" : { + "name":"Nom", + "genre" : "Genre", + "description": "Description", + "loading": { + "category" : "Chargement de la Catégorie" + }, + "notFound": "Il n'existe aucune Politique" + }, + "action": { + "title": "Actions", + "add": "Ajouter une Politique", + "detail": "Consulter", + "edit": "Editer", + "map" : "Associer une Politique à la PDP", + "unmap" : "Dissocier", + "delete": "Supprimer" + } + }, + "unmap": { + "title": "Dissociation de la Policy et de la PDP", + "content": "Voulez-vous dissocier la PDP `{{pdpName}}` et la Policy `{{policyName}}` ?", + "action": { + "unmap": "Dissocier", + "cancel": "Annuler" + }, + "error": "Impossible de dissocier la PDP `{{pdpName}}` et la Policy`{{policyName}}`", + "success": "La dissociation de la PDP `{{pdpName}}` et de la Policy `{{policyName}}` a été effectuée avec succès" + }, + "map":{ + "title": "Associer une Politique à la PDP `{{pdpName}}`", + "form" :{ + "list": "Liste des Politiques" + }, + "action": { + "create": "Associer une Politique", + "cancel": "Fermer", + "new": "Créer une Politique", + "list": "Associer une Politique existante", + "map": "Associer la Politique sélectionnée", + "delete" : "Supprimer la Politique sélectionnée" + }, + "check": { + "policy":{ + "required" : "La politique est requise" + } + }, + "error": "Impossible d'associer la Politique `{{policyName}}` à la PDP `{{pdpName}}`", + "success": "L'association dde la Politique `{{policyName}}` avec la PDP `{{pdpName}}` a été effectuée avec succès" + }, + "remove": { + "title": "Supprimer une Politique", + "content": { + "query": "Voulez-vous supprimer la Politique `{{policyName}}` ?" + }, + "action": { + "cancel": "Annuler", + "delete": "Supprimer" + }, + "error": "Impossible de supprimer la Politique `{{policyName}}`", + "success": "La Politique `{{policyName}}` a été supprimée avec succès" + }, + "edit" : { + "title": "Configuration de la Politique `{{policyName}}`", + "update": "- mettre à jour", + "show": { + "open": "( voir )", + "close": "( fermer )" + }, + "basic" : { + "title" : "Informations de base", + "form": { + "id": "Id", + "name": "Nom", + "genre": "Genre", + "model": "Modèle", + "description": "Description" + }, + "action": { + "init": "Init", + "update": "Mettre à Jour" + }, + "check": { + "name": { + "required": "Le Nom est requis" + }, + "Genre": { + "required": "Le Genre est requis" + } + }, + "error": "Impossible de mettre à jour la Politique `{{policyName}}`", + "success": "Le Politique `{{policyName}}` a été mise à jour avec succès" + }, + "perimeter": { + "title" : "Périmètres" + }, + "data": { + "title" : "Données" + }, + "rules" : { + "title" : "Règles" + }, + "assignments": { + "title" : "Affectations" + } + }, + "add": { + "title": "Ajouter une nouvelle Politique", + "form": { + "name": "Nom", + "genre" : "Genre", + "model": "Modèles", + "description": "Description" + }, + "action": { + "create": "Créer la Politique", + "cancel": "Annuler" + }, + "check": { + "name": { + "required": "Le nom est requis" + }, + "genre" : { + "required" :"Le Genre est requis" + }, + "model" : { + "required" :"Un Modèle est requis" + } + }, + "error": "Impossible de créer la Politique `{{policyName}}`", + "success": "La Politique `{{policyName}}` a été créée avec succès" + }, + "perimeter" :{ + "subject" : { + "title" : "Liste des Sujets associées", + "delete": { + "error" : "Impossible de supprimer le Sujet : {{subjectName}}, la raison : {{reason}}", + "success": "Sujet `{{subjectName}}` a été supprimé avec succès" + }, + "add": { + "title": "Ajouter une Element Sujet" + }, + "notFound": "Il n'existe aucun Sujet" + }, + "object" : { + "title" : "Liste des Objets associées", + "delete": { + "error" : "Impossible de supprimer l'Objet : {{objectName}}, la raison : {{reason}}", + "success": "Objet `{{objectName}}` a été supprimé avec succès" + }, + "add": { + "title": "Ajouter une Element Objet" + }, + "notFound": "Il n'existe aucun Objet" + }, + "action" : { + "title" : "Liste des Actions associées", + "delete": { + "error" : "Impossible de supprimer l'Action : {{actionName}}, la raison : {{reason}}", + "success": "Action `{{actionName}}` a été supprimé avec succès" + }, + "add": { + "title": "Ajouter une Element Action" + }, + "notFound": "Il n'existe aucune Action" + }, + "update":{ + "error": "Impossible de mettre à jour le Périmètre `{{perimeterName}}`", + "success": "Le Périèmtre `{{perimeterName}}` a été mis à jour" + }, + "table": { + "id" : "Id", + "name" : "Nom", + "description" : "Description", + "email" : "Email", + "partner":{ + "id" : "Id du Partenaire" + }, + "action": { + "title": "Actions", + "delete": "Supprimer", + "update": "Mettre à jour", + "unmap": "Dissocier" + } + }, + "edit": { + "name" : "Nom", + "description" : "Description", + "partnerId": "Partner Id", + "policies":"Liste des Politiques", + "email": "E-mail", + "selectedPolicies": "Politiques selectionnées", + "check": { + "name": { + "required": "Le nom est requis" + } + }, + "action": { + "list": "Associer un Périmètre existant", + "new": "Ajouter un nouveau Périmètre", + "create":"Ajouter le Périmètre ", + "map":"Asscoier le Périmètre selectionné", + "delete": "Supprimer" + }, + "create": { + "error": "Impossible de créer l'Element `{{name}}`", + "success": "L'Element `{{name}}` a été créé avec succès" + }, + "delete": { + "error": "Impossible de supprimer la Element `{{name}}`", + "success": "L'Element `{{name}}` a été supprimée avec succès" + } + } + }, + "data" :{ + "subject" : { + "title" : "Liste des Data Sujets associées", + "delete": { + "error" : "Impossible de supprimer la Data Sujet : {{subjectName}}, la raison : {{reason}}", + "success": "Data Sujet `{{subjectName}}` a été supprimée avec succès" + }, + "add": { + "title": "Ajouter une Data Sujet" + }, + "notFound": "Il n'existe aucune Data Sujet" + }, + "object" : { + "title" : "Liste des Data Objets associées", + "delete": { + "error" : "Impossible de supprimer la Data Objet : {{objectName}}, la raison : {{reason}}", + "success": "Data Objet `{{objectName}}` a été supprimée avec succès" + }, + "add": { + "title": "Ajouter un Data Objet" + }, + "notFound": "Il n'existe aucun Data Objet" + }, + "action" : { + "title" : "Liste des Data Actions associées", + "delete": { + "error" : "Impossible de supprimer la Data Action : {{actionName}}, la raison : {{reason}}", + "success": "Data Action `{{actionName}}` a été supprimée avec succès" + }, + "add": { + "title": "Ajouter une Data Action" + }, + "notFound": "Il n'existe aucune Data Action" + }, + "table": { + "category" : { + "id" : "Id de la Catégorie", + "name" : "Nom de la Catégorie" + }, + "name" : "Nom", + "description" : "Description", + "action": { + "title": "Actions", + "delete": "Supprimer", + "update": "Mettre à jour" + }, + "loading": { + "category" : "Loading Catégorie" + } + }, + "edit": { + "name" : "Nom", + "description" : "Description", + "categories": "Liste des Catégories", + "policies": "Liste des Politiques", + "check": { + "name": { + "required": "Le nom est requis" + }, + "category":{ + "required": "Une Catégorie est requise" + }, + "policy":{ + "required": "Une Politique est requise" + } + }, + "action": { + "list": "Associer une Data existante", + "new": "Créer une nouvelle Data", + "create":"Créer la Data", + "add":"Ajouter la Data selectionnée", + "delete": "Supprimer la Data" + }, + "create": { + "error": "Impossible de créer l'Element `{{name}}`", + "success": "L'Element `{{name}}` a été créé avec succès" + }, + "delete": { + "error": "Impossible de supprimer la Element `{{name}}`", + "success": "L'Element `{{name}}` a été supprimée avec succès" + } + } + }, + "rules": { + "title": "Règles", + "list": { + "search": { + "placeholder": "Rechercher des Règles", + "reset": "Effacer" + }, + "table": { + "id" : "Id", + "metaRule": "Meta Règle", + "description": "Description", + "enabled": "Enabled", + "rule": "Règle", + "instructions": "Instruction", + "notFound": "Il n'existe aucune Règle", + "loading": { + "metaRule" : "Chargement de la Meta Règle" + }, + "action":{ + "title": "Actions", + "delete": "Supprimer" + } + }, + "action": { + "title": "Actions", + "add": "Ajouter une Règle", + "detail": "Consulter", + "edit": "Editer", + "delete": "Supprimer" + }, + "error": "Impossible de récupérer la liste des Règles" + }, + "edit": { + "title" : "Liste des Règles associées", + "action" : { + "create": "Créer une Règles", + "delete": { + "error" : "Impossible de supprimer la Règles{{rulesName}}, raison : {{reason}}", + "success": "Règles`{{rulesName}}` supprimée avec succès" + }, + "add": { + "title": "Ajouter une Règles", + "policies": "Sélectionnez une Politique", + "instructions": "Instruction", + "metarules" : "Sélectionnez une des MetaRules associée(s)", + "categories":{ + "subject": "Sélectionnez {{number}} Sujet(s)", + "object": "Sélectionnez {{number}} Object(s)", + "action": "Sélectionnez {{number}} Action(s)" + }, + "selectedSubjects": "Sujets(s) sélectionnés", + "selectedObjects": "Objet(s) sélectionnés", + "selectedActions": "Action(s) sélectionnées", + "details":{ + "show": "Détails", + "close": "Fermer" + }, + "check":{ + "policy":{ + "required": "Une Politique est requise" + }, + "instructions":{ + "required": "Une Instruction au format JSON est requise" + }, + "metarules":{ + "required": "une MetaRules est requise" + }, + "subject":{ + "required": "{{number}} Sujets(s) sont requis" + }, + "object":{ + "required": "{{number}} Obje(s) sont requis" + }, + "action":{ + "required": "{{number}} Sujets(s) sont requises" + } + }, + "create": { + "error": "Impossible de créer la Règles `{{name}}`", + "success": "La règles `{{name}}` a été créé avec succès" + }, + "delete": { + "error": "Impossible de supprimer la Règle, raison: `{{reason}}`", + "success": "La Règle a été supprimée avec succès" + } + }, + "notFound": "Il n'y a pas de Règles" + } + } + }, + "assignments" :{ + "subject" : { + "title" : "Liste des Affectations Sujets associées", + "delete": { + "error" : "Impossible de supprimer l'Affectations, la raison : {{reason}}", + "success": "Affectations a été supprimé avec succès" + }, + "add": { + "title": "Ajouter une Affectations Sujet" + }, + "notFound": "Il n'existe aucune Affectations Sujet" + }, + "object" : { + "title" : "Liste des Affectations Objets associées", + "delete": { + "error" : "Impossible de supprimer l'Affectations, la raison : {{reason}}", + "success": "Affectations a été supprimée avec succès" + }, + "add": { + "title": "Ajouter une Affectations Objet" + }, + "notFound": "Il n'existe aucune Affectations Objet" + }, + "action" : { + "title" : "Liste des Affectations Actions associées", + "delete": { + "error" : "Impossible de supprimer l'Affectations, la raison : {{reason}}", + "success": "Affectations Action a été supprimée avec succès" + }, + "add": { + "title": "Ajouter une Affectations Action" + }, + "notFound": "Il n'existe aucune Affectations Action" + }, + "table": { + "action": { + "title": "Actions", + "delete": "Supprimer", + "update": "Mettre à jour" + }, + "perimeter": { + "name": "Nom du Périmètre" + }, + "data":{ + "name" : "Nom des Data" + }, + "category": { + "name" : "Nom de la Catégorie" + }, + "loading": { + "category" : "Chargement de la Catégorie", + "perimeter": "Chargement du Périmètre", + "data": "Chargement des Données" + } + }, + "edit": { + "policies": "Sélectionnez une Politique", + "categories": "Sélectionnez une Catégorie", + "perimeters": "Sélectionnez un Perimètre", + "data": "Sélectionnez une Donnée", + "selectedData" : "Données Séléctionnées", + "check": { + "policy":{ + "required": "Une Politique est requise" + }, + "category":{ + "required": "Une Catégorie est requise" + }, + "perimeter":{ + "required": "Un Perimètre est requis" + }, + "data":{ + "required": "Une Donnée est requise" + } + }, + "action": { + "list": "Ajouter une Affectations existante", + "new": "Ajouter une nouvelle Affectations", + "create":"Créer l'Affectations", + "map":"Ajouter l'Affectations selectionnée", + "delete": "Supprimer l'Affectations" + }, + "create": { + "error": "Impossible de créer l'Affectations`", + "success": "L'Affectations a été créé avec succès" + }, + "delete": { + "error": "Impossible de supprimer l'Affectations, raison : `{{reason}}`", + "success": "L'Affectations a été supprimée avec succès" + } + } + } + }, + "model":{ + "title": "Modèles", + "list": { + "search": { + "placeholder": "Rechercher des Modèles", + "reset": "Effacer" + }, + "table":{ + "name":"Nom", + "description": "Description", + "metaRules":{ + "number" : "Nombre de Meta Règles" + }, + "notFound": "Il n'existe aucun Modèle" + }, + "action": { + "title": "Actions", + "add": "Ajouter un modèle", + "detail": "Consulter", + "edit": "Editer", + "delete": "Supprimer" + }, + "error": "Impossible de récupérer la liste des Modèles" + }, + "edit" : { + "title": "Configuration du Modèle `{{modelName}}`", + "update": "- mettre à jour", + "basic" : { + "title" : "Informations de base", + "form": { + "id": "Id", + "name": "Nom", + "description": "Description" + }, + "action": { + "init": "Init", + "update": "Mettre à Jour" + }, + "check": { + "name": { + "required": "Le Nom est requis" + } + }, + "error": "Impossible de mettre à jour le Modèle `{{modelName}}`", + "success": "Le Modèle `{{modelName}}` a été mis à jour avec succès" + }, + "metarules": { + "title" : "Meta Règles" + } + }, + "view": { + "title": "Détail du Modèle `{{modelName}}`", + "name": "Name", + "id": "Id", + "description": "Description", + "action": { + "close": "Fermer" + } + }, + "remove": { + "title": "Supprimer un Modèle", + "content": { + "query": "Voulez-vous supprimer le Modèle `{{modelName}}` ?" + }, + "action": { + "cancel": "Annuler", + "delete": "Supprimer" + }, + "error": "Impossible de supprimer le Modèle `{{modelName}}`", + "success": "Le Modèle `{{modelName}}` a été supprimé avec succès" + }, + "metarules" :{ + "title" : "List des Meta Règles", + "table":{ + "name":"Nom", + "description": "Description", + "metadata": { + "subject" : { + "number" : "Nombre de Catégories Sujet" + }, + "object" : { + "number" : "Nombre de Catégories Objet" + }, + "action" : { + "number" : "Nombre de Catégories Action" + } + }, + "notFound": "Il n'existe aucune Meta Règles" + }, + "edit" : { + "title" : "Configuration de la Meta Règle `{{metaRuleName}}`", + "update": "- mettre à jour", + "basic" : { + "title" : "Informations de base", + "form": { + "id": "Id", + "name": "Nom", + "description": "Description" + }, + "action": { + "init": "Init", + "update": "Mettre à Jour" + }, + "check": { + "name": { + "required": "Le Nom est requis" + } + }, + "error": "Impossible de mettre à jour la Meta Règle `{{metaRuleName}}`", + "success": "La Meta Règle `{{metaRuleName}}` a été mis à jour avec succès" + } + }, + "update":{ + "error": "Impossible de mettre à jour la Meta Règle `{{metaRuleName}}`", + "success": "La Meta Règle `{{metaRuleName}}` a été mis à jour avec succès" + }, + "action": { + "title": "Actions", + "edit": "Editer", + "remove": "Enlever", + "settings" : "Paramètres", + "add": "Ajouter", + "detail": { + "open": "Consulter", + "close": "Fermer" + } + }, + "add":{ + "title": "Ajouter une nouvelle Meta Règle", + "form": { + "name": "Nom", + "description": "Description" + }, + "action": { + "create": "Ajouter la Meta Règle", + "cancel": "Annuler" + }, + "check": { + "name": { + "required": "Le nom est requis" + } + }, + "error": "Impossible de créer la Meta Règle `{{metaRuleName}}`", + "success": "La Meta Règle `{{metaRuleName}}` a été créée avec succès" + }, + "map":{ + "title": "Ajouter une Meta Règle", + "form" :{ + "list": "Liste des Meta Règles" + }, + "action": { + "create": "Ajouter une nouvelle Meta Règle", + "cancel": "Fermer", + "new": "Ajouter une Meta Règle", + "list": "Ajouter une Meta Règle existante", + "add": "Ajouter la Meta Règle sélectionnée", + "delete" : "Supprimer la Meta Règle sélectionnée" + }, + "error": "Impossible d'associer le Modèle `{{modelName}}` à la Meta Règle `{{metaRuleName}}`", + "success": "L'association du Modèle `{{modelName}}` avec la Meta Règle `{{metaRuleName}}` a été effectuée avec succès" + }, + "unmap": { + "title": "Enlever de la Meta Règle du Modèle", + "content": "Voulez-vous enlever le Modèle `{{modelName}}` de la Meta Règle `{{metaRuleName}}` ?", + "action": { + "unmap": "Enlever", + "cancel": "Annuler" + }, + "error": "Impossible d'enlever le Modèle `{{modelName}}` de la Meta Règle `{{metaRuleName}}`", + "success": "La dissociation du Modèle `{{modelName}}` de la Meta Règle `{{metaRuleName}}` a été effectuée avec succès" + }, + "delete": { + "error": "Impossible de supprimer la Meta Rule `{{metaRuleName}}`", + "success": "La Meta Rule `{{metaRuleName}}` a été supprimée avec succès" + } + }, + "metadata" :{ + "subject" : { + "title" : "Liste des Catégories Sujet associées", + "delete": { + "error" : "Impossible de supprimer le Sujet : {{subjectName}}, la raison : {{reason}}", + "success": "Sujet `{{subjectName}}` a été supprimé avec succès" + }, + "add": { + "title": "Ajouter une Catégorie Sujet" + }, + "notFound": "Il n'existe aucun Sujet" + }, + "object" : { + "title" : "Liste des Catégories Objet associées", + "delete": { + "error" : "Impossible de supprimer l'Objet : {{objectName}}, la raison : {{reason}}", + "success": "Objet `{{objectName}}` a été supprimé avec succès" + }, + "add": { + "title": "Ajouter une Catégorie Objet" + }, + "notFound": "Il n'existe aucun Objet" + }, + "action" : { + "title" : "Liste des Catégories Action associées", + "remove": "Enlever", + "delete": { + "error" : "Impossible de supprimer l'Action : {{actionName}}, la raison : {{reason}}", + "success": "Action `{{actionName}}` a été supprimé avec succès" + }, + "add": { + "title": "Ajouter une Catégorie Action" + }, + "notFound": "Il n'existe aucune Action" + }, + "table": { + "id" : "Id", + "name" : "Nom", + "description" : "Description", + "action": { + "title": "Actions", + "delete": "Supprimer", + "update": "Mettre à jour" + } + }, + "edit": { + "name" : "Nom", + "description" : "Description", + "check": { + "name": { + "required": "Le nom est requis" + } + }, + "action": { + "list": "Ajouter une Catégorie existante", + "new": "Ajouter une nouvelle Catégorie", + "create":"Ajouter la Catégorie", + "add":"Ajouter la Catégorie selectionnée", + "delete": "Supprimer" + }, + "create": { + "error": "Impossible de créer la Catégorie `{{name}}`", + "success": "La Catégorie `{{name}}` a été créé avec succès" + }, + "delete": { + "error": "Impossible de supprimer la Catégorie `{{name}}`", + "success": "La Catégorie `{{name}}` a été supprimée avec succès" + } + } + }, + "add":{ + "title": "Ajouter un nouveau Model", + "form": { + "name": "Nom", + "description": "Description" + }, + "action": { + "create": "Créer le Modèle", + "cancel": "Annuler" + }, + "check": { + "name": { + "required": "Le nom est requis" + } + }, + "error": "Impossible de créer le Modèle `{{modelName}}`", + "success": "Le Modèle `{{modelName}}` a été créé avec succès" + } + }, + "project": { + "title": "Projects", + "list": { + "search": { + "placeholder": "Rechercher des Projects", + "reset": "Effacer" + }, + "table": { + "name": "Nom", + "domain": "Domaine", + "managed": "Supervisé", + "enabled": "Activé", + "description": "Description", + "mapping": "PDP", + "loading": { + "project": "Chargement des Projects", + "pdp": "Chargement du PDP" + }, + "notFound": "Il n'existe aucun Project" + }, + "action": { + "title": "Actions", + "detail": "Consulter", + "delete": "Supprimer", + "add": "Ajouter un Project", + "map": "Associer à un PDP", + "unmap": "Dissocier" + }, + "error": "Impossible de récupérer la liste des Projects" + }, + "view": { + "title": "Détail du Project `{{projectName}}`", + "action": { + "close": "Fermer" + }, + "subject": { + "title": "Sujets", + "name": "Nom", + "mail": "Email", + "domain": "Domaine", + "enabled": "Activé", + "error": "Impossible de récupérer la liste des Sujets" + }, + "object": { + "title": "Objets", + "category": "Catégorie", + "description": "Description", + "enabled": "Activé", + "name": "Nom", + "error": "Impossible de récupérer la liste des Objets", + "loading": "Chargement des Objets", + "notFound": "Il n'existe aucun Objet" + }, + "role": { + "title": "Roles", + "category": "Catégorie", + "value": "Valeur", + "description": "Description", + "assigned": "Affecté", + "enabled": "Activé", + "error": "Impossible de récupérer la liste des Roles", + "loading": "Chargement des Roles", + "notFound": "Il n'existe aucun Role" + }, + "roleAssignment": { + "title": "Affectation des roles", + "category": "Catégorie", + "attributes": "Attributs", + "description": "Description", + "error": "impossible de récupérer la liste des affectations", + "loading": "Chargement des Affectations", + "notFound": "Il n'existe aucune Affectation" + }, + "group": { + "title": "Groupes", + "category": "Catégorie", + "value": "Valeur", + "description": "Description", + "assigned": "Affecté", + "enabled": "Activé", + "error": "Impossible de récupérer la liste des Groupes", + "loading": "Chargement des Groupes", + "notFound": "Il n'existe aucun Groupe" + }, + "groupAssignment": { + "title": "Affectation des groupes", + "category": "Catégorie", + "attributes": "Attributs", + "description": "Description", + "error": "impossible de récupérer la liste des affectations", + "loading": "Chargement des Affectations", + "notFound": "Il n'existe aucune Affectation" + } + }, + "add": { + "title": "Ajouter un nouveau Project", + "form": { + "name": "Nom", + "description": "Description", + "enabled": "Activé", + "domain": "Domaine" + }, + "action": { + "create": "Créer le Project", + "cancel": "Annuler" + }, + "check": { + "name": { + "required": "Le nom est requis" + }, + "domain": { + "required": "Le domaine est requis" + } + }, + "error": "Impossible de créer le Project `{{projectName}}`", + "success": "Le Project `{{projectName}}` a été créé avec succès" + }, + "remove": { + "title": "Supprimer un Project", + "content": { + "query": "Voulez-vous supprimer le Project `{{projectName}}` ?", + "isNotMapped": "Ce Project est associé avec aucune PDP.", + "isMapped": "Ce project est associé avec le PDP `{{pdpName}}`, le supprimer va supprimer le mapping associé" + }, + "mapping":{ + "remove":{ + "error": "Impossible de supprimer la relation avec `{{pdpName}}`" + } + }, + "action": { + "cancel": "Annuler", + "delete": "Supprimer" + }, + "error": "Impossible de supprimer le Project `{{projectName}}`", + "success": "Le Project `{{projectName}}` a été supprimé avec succès" + }, + "map": { + "title": "Associé le Project `{{projectName}}` avec une PDP", + "form": { + "pdp": "PDP" + }, + "action": { + "map": "Associer", + "cancel": "Annuler" + }, + "check": { + "pdp": { + "required": "L'PDP est requise" + } + }, + "error": "Impossible d'associer le Project `{{projectName}}` avec la PDP `{{pdpName}}`", + "success": "L'association du Project `{{projectName}}` avec la PDP `{{pdpName}}` a été effectué avec succès" + }, + "unmap": { + "title": "Dissociation Project et PDP", + "content": "Voulez-vous dissocier le Project `{{projectName}}` et la PDP `{{pdpName}}` ?", + "action": { + "unmap": "Dissocier", + "cancel": "Annuler" + }, + "error": "Impossible de dissocier le Project `{{projectName}}` et la PDP `{{pdpName}}`", + "success": "La dissociation du Project `{{projectName}}` et de la PDP `{{pdpName}}` a été effectuée avec succès" + } + }, + "pdp": { + "title": "PDPs", + "edit" : { + "title": "configuration du PDP `{{pdpName}}` ", + "update" : "- Mettre à jour", + "basic" : { + "title" : "Information de base", + "form": { + "id": "Id", + "name": "Nom", + "description": "Description" + }, + "action": { + "init": "Init", + "update": "Mettre à jour" + }, + "check": { + "name": { + "required": "Le Nom est requis" + } + }, + "error": "Impossible de mettre à jour la PDP `{{pdpName}}`", + "success": "La PDP `{{pdpName}}` a été mis à jour avec succès" + }, + "policy": { + "title" : "Politiques" + } + }, + "list": { + "search": { + "placeholder": "Rechercher des PDPs", + "reset": "Effacer" + }, + "table": { + "name": "Nom", + "security_pipeline":{ + "number" : "Nombre de Règles" + }, + "project": "Project", + "loading": { + "pdp": "Chargement des PDPs", + "project": "Chargement du Project" + }, + "mapping" :{ + "map": "n'est pas associé à un projet" + }, + "notFound": "Il n'existe aucune PDP" + }, + "action": { + "title": "Actions", + "detail": "Consulter", + "configure": "Configurer", + "rule": "Règles", + "delete": "Supprimer", + "add": "Ajouter une PDP", + "edit": "Editer" + }, + "error": "Impossible de récupérer la liste des PDPs" + }, + "add": { + "title": "Ajouter une nouvelle PDP", + "form": { + "name": "Nom", + "policy": "Règle", + "description": "Description" + }, + "action": { + "create": "Créer la PDP", + "cancel": "Annuler" + }, + "check": { + "name": { + "required": "Le nom est requis" + }, + "policy": { + "required": "Une règle est requise" + } + }, + "error": "Impossible de créer la PDP `{{pdpName}}`", + "success": "La PDP `{{pdpName}}` a été créée avec succès" + }, + "remove": { + "title": "Supprimer une PDP", + "content": "Voulez-vous supprimer la PDP `{{pdpName}}` ?", + "action": { + "cancel": "Annuler", + "delete": "Supprimer" + }, + "error": "Impossible de supprimer la PDP `{{pdpName}}`", + "success": "la PDP `{{pdpName}}` a été supprimé avec succès" + }, + "configure": { + "title": "Configuration de la PDP `{{pdpName}}`", + "action": { + "back": "Liste des PDPs" + }, + "subject": { + "panelTitle": "Configuration des Sujets", + "title": "Sujets", + "add": { + "title": "Ajouter un nouveau Sujet", + "form": { + "name": "Nom", + "domain": "Domaine", + "enabled": "Activé", + "project": "Projet", + "password": "Mot de passe", + "description": "Description" + }, + "action": { + "cancel": "Annuler", + "add": "Ajouter Sujet" + }, + "check": { + "name": { + "required": "Le nom est requis" + }, + "domain": { + "required": "Le domaine est requis" + }, + "project": { + "required": "Le projet est requis" + }, + "password": { + "required": "Le mot de passe est requis" + } + }, + "error": "Impossible d'ajouter le Sujet `{{subjectName}}`", + "success": "Le Sujet `{{subjectName}}` a été ajouté avec succès" + }, + "remove": { + "title": "Supprimer un Sujet", + "content": "Voulez-vous supprimer le Sujet `{{subjectName}}` de la PDP `{{pdpName}}` ?", + "action": { + "cancel": "Annuler", + "delete": "Supprimer" + }, + "error": "Impossible de supprimer le Sujet `{{subjectName}}`", + "success": "Le Sujet `{{subjectName}}` a été supprimé avec succès" + }, + "category": { + "title": "Catégories", + "add": { + "title": "Ajouter une nouvelle Catégorie", + "form": { + "name": "Nom" + }, + "action": { + "cancel": "Annuler", + "add": "Ajouter Catégorie" + }, + "check": { + "name": { + "required": "Le nom est requis" + } + }, + "error": "Impossible d'ajouter la Catégorie `{{categoryName}}`", + "success": "Catégorie `{{categoryName}}` ajoutée avec succès" + }, + "remove": { + "title": "Supprimer une Catégorie", + "content": "Voulez-vous supprimer la Catégorie `{{categoryName}}` de la PDP `{{pdpName}}` ?", + "action": { + "cancel": "Annuler", + "delete": "Supprimer" + }, + "error": "Impossible de supprimer la Catégorie `{{categoryName}}`", + "success": "La Catégorie `{{categoryName}}` a été supprimée avec succès" + } + }, + "categoryValue": { + "title": "Valeurs", + "add": { + "title": "Ajouter une nouvelle Valeur", + "form": { + "value": "Valeur" + }, + "action": { + "cancel": "Annuler", + "add": "Ajouter Valeur" + }, + "check": { + "value": { + "required": "La valeur est requise" + } + }, + "error": "Impossible d'ajouter la Valeur `{{valueName}}`", + "success": "Valeur `{{valueName}}` ajoutée avec succès" + }, + "remove": { + "title": "Supprimer une Valeur", + "content": "Voulez-vous supprimer la Valeur `{{valueName}}` de la PDP `{{pdpName}}` ?", + "action": { + "cancel": "Annuler", + "delete": "Supprimer" + }, + "error": "Impossible de supprimer la Valeur `{{valueName}}`", + "success": "La Valeur `{{valueName}}` a été supprimée avec succès" + } + }, + "assignment": { + "title": "Affectation des Sujets", + "action": { + "assign": "Affecter", + "unassign": "Désaffecter" + }, + "list": { + "notFound": "Il n'existe aucune affectation" + }, + "add": { + "error": "Impossible de réaliser l'affectation Sujet `{{subjectName}}` / Catégorie `{{categoryName}}` / Valeur `{{valueName}}`", + "success": "Affectation de Sujet `{{subjectName}}` / Catégorie `{{categoryName}}` / Valeur `{{valueName}}` réalisée avec succès" + }, + "remove": { + "error": "Impossible de réaliser la désaffectation Sujet `{{subjectName}}` / Catégorie `{{categoryName}}` / Valeur `{{valueName}}`", + "success": "Désaffectation de Sujet `{{subjectName}}` / Catégorie `{{categoryName}}` / Valeur `{{valueName}}` réalisée avec succès" + } + } + }, + "object": { + "panelTitle": "Configuration des Objets", + "title": "Objets", + "add": { + "title": "Ajouter un nouvel Objet", + "form": { + "name": "Nom", + "image": "Image", + "flavor": "Type" + }, + "action": { + "cancel": "Annuler", + "add": "Ajouter Objet" + }, + "check": { + "name": { + "required": "Le nom est requis" + }, + "image": { + "required": "L'image est requise" + }, + "flavor": { + "required": "Le type est requis" + } + }, + "error": "Impossible d'ajouter l'Objet `{{objectName}}`", + "success": "L'Objet `{{objectName}}` a été ajouté avec succès" + }, + "remove": { + "title": "Supprimer un Objet", + "content": "Voulez-vous supprimer l'Objet `{{objectName}}` de la PDP `{{pdpName}}` ?", + "action": { + "cancel": "Annuler", + "delete": "Supprimer" + }, + "error": "Impossible de supprimer l'Objet `{{objectName}}`", + "success": "L'Objet `{{objectName}}` a été supprimé avec succès" + }, + "category": { + "title": "Catégories", + "add": { + "title": "Ajouter une nouvelle Catégorie", + "form": { + "name": "Nom" + }, + "action": { + "cancel": "Annuler", + "add": "Ajouter Catégorie" + }, + "check": { + "name": { + "required": "Le nom est requis" + } + }, + "error": "Impossible d'ajouter la Catégorie `{{categoryName}}`", + "success": "Catégorie `{{categoryName}}` ajoutée avec succès" + }, + "remove": { + "title": "Supprimer une Catégorie", + "content": "Voulez-vous supprimer la Catégorie `{{categoryName}}` de la PDP `{{pdpName}}` ?", + "action": { + "cancel": "Annuler", + "delete": "Supprimer" + }, + "error": "Impossible de supprimer la Catégorie `{{categoryName}}`", + "success": "La Catégorie `{{categoryName}}` a été supprimée avec succès" + } + }, + "categoryValue": { + "title": "Valeurs", + "add": { + "title": "Ajouter une nouvelle Valeur", + "form": { + "value": "Valeur" + }, + "action": { + "cancel": "Annuler", + "add": "Ajouter Valeur" + }, + "check": { + "value": { + "required": "La valeur est requise" + } + }, + "error": "Impossible d'ajouter la Valeur `{{valueName}}`", + "success": "Valeur `{{valueName}}` ajoutée avec succès" + }, + "remove": { + "title": "Supprimer une Valeur", + "content": "Voulez-vous supprimer la Valeur `{{valueName}}` de la PDP `{{pdpName}}` ?", + "action": { + "cancel": "Annuler", + "delete": "Supprimer" + }, + "error": "Impossible de supprimer la Valeur `{{valueName}}`", + "success": "La Valeur `{{valueName}}` a été supprimée avec succès" + } + }, + "assignment": { + "title": "Affectation des Objets", + "action": { + "assign": "Affecter", + "unassign": "Désaffecter" + }, + "list": { + "notFound": "Il n'existe aucune affectation" + }, + "add": { + "error": "Impossible de réaliser l'affectation Objet `{{objectName}}` / Catégorie `{{categoryName}}` / Valeur `{{valueName}}`", + "success": "Affectation de Objet `{{objectName}}` / Catégorie `{{categoryName}}` / Valeur `{{valueName}}` réalisée avec succès" + }, + "remove": { + "error": "Impossible de réaliser la désaffectation Objet `{{objectName}}` / Catégorie `{{categoryName}}` / Valeur `{{valueName}}`", + "success": "Désaffectation de Objet `{{objectName}}` / Catégorie `{{categoryName}}` / Valeur `{{valueName}}` réalisée avec succès" + } + } + } + }, + "rule": { + "title": "Règles de la PDP `{{pdpName}}`", + "list": { + "table": { + "subject": "Sujets", + "object": "Objects", + "notFound": "Il n'existe aucune règle" + }, + "action": { + "title": "Actions", + "add": "Ajouter une règle", + "delete": "Supprimer une règle" + } + }, + "add": { + "title": "Ajouter une nouvelle Règle", + "action": { + "create": "Créer la Règle", + "cancel": "Annuler" + }, + "form": { + "subject": { + "subject": "Sujets", + "category": "Catégories", + "categoryValue": "Valeur", + "action": { + "add": "Ajouter", + "delete": "Supprimer" + } + }, + "object": { + "object": "Objets", + "category": "Catégories", + "categoryValue": "Valeurs", + "action": { + "add": "Ajouter", + "delete": "Supprimer" + } + } + }, + "success": "La règle a été créée avec succès", + "error": "Impossible de créer la règle" + }, + "delete": { + "title": "Supprime une Règle", + "content": "Voulez-vous supprimer la Valeur règle `{{ruleJson}}` de la PDP `{{pdpName}}` ?", + "action": { + "delete": "Supprimer la Règle", + "cancel": "Annuler" + }, + "error": "Impossible de supprimer la règle `{{ruleJson}}`", + "success": "La règle `{{ruleJson}}` a été supprimée avec succès" + }, + "action": { + "back": "Liste des PDPs" + } + } + } + } +} diff --git a/old/moon_gui/delivery/assets/img/ajax-loader.gif b/old/moon_gui/delivery/assets/img/ajax-loader.gif new file mode 100755 index 00000000..d0bce154 Binary files /dev/null and b/old/moon_gui/delivery/assets/img/ajax-loader.gif differ diff --git a/old/moon_gui/delivery/assets/img/ajax-waiting.gif b/old/moon_gui/delivery/assets/img/ajax-waiting.gif new file mode 100755 index 00000000..d84f6537 Binary files /dev/null and b/old/moon_gui/delivery/assets/img/ajax-waiting.gif differ diff --git a/old/moon_gui/delivery/assets/img/arrow-link.gif b/old/moon_gui/delivery/assets/img/arrow-link.gif new file mode 100755 index 00000000..ca17f44b Binary files /dev/null and b/old/moon_gui/delivery/assets/img/arrow-link.gif differ diff --git a/old/moon_gui/delivery/assets/img/et.jpg b/old/moon_gui/delivery/assets/img/et.jpg new file mode 100644 index 00000000..67cc0a9d Binary files /dev/null and b/old/moon_gui/delivery/assets/img/et.jpg differ diff --git a/old/moon_gui/delivery/assets/img/favicon.ico b/old/moon_gui/delivery/assets/img/favicon.ico new file mode 100755 index 00000000..a7910bf5 Binary files /dev/null and b/old/moon_gui/delivery/assets/img/favicon.ico differ diff --git a/old/moon_gui/delivery/assets/img/logo-openstack.png b/old/moon_gui/delivery/assets/img/logo-openstack.png new file mode 100755 index 00000000..60ab0e1e Binary files /dev/null and b/old/moon_gui/delivery/assets/img/logo-openstack.png differ diff --git a/old/moon_gui/delivery/assets/img/logo-orange.gif b/old/moon_gui/delivery/assets/img/logo-orange.gif new file mode 100755 index 00000000..9c612291 Binary files /dev/null and b/old/moon_gui/delivery/assets/img/logo-orange.gif differ diff --git a/old/moon_gui/delivery/html/authentication/authentication.tpl.html b/old/moon_gui/delivery/html/authentication/authentication.tpl.html new file mode 100644 index 00000000..d942d8e8 --- /dev/null +++ b/old/moon_gui/delivery/html/authentication/authentication.tpl.html @@ -0,0 +1 @@ +

Login

Username is required
Password is required
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/common/404/404.tpl.html b/old/moon_gui/delivery/html/common/404/404.tpl.html new file mode 100644 index 00000000..f03a2e98 --- /dev/null +++ b/old/moon_gui/delivery/html/common/404/404.tpl.html @@ -0,0 +1 @@ +
Not found!
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/common/compatibility/compatibility.tpl.html b/old/moon_gui/delivery/html/common/compatibility/compatibility.tpl.html new file mode 100644 index 00000000..26c0f09e --- /dev/null +++ b/old/moon_gui/delivery/html/common/compatibility/compatibility.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/common/footer/footer.tpl.html b/old/moon_gui/delivery/html/common/footer/footer.tpl.html new file mode 100644 index 00000000..6c01bd92 --- /dev/null +++ b/old/moon_gui/delivery/html/common/footer/footer.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/common/header/header.tpl.html b/old/moon_gui/delivery/html/common/header/header.tpl.html new file mode 100644 index 00000000..92224309 --- /dev/null +++ b/old/moon_gui/delivery/html/common/header/header.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/common/loader/loader.tpl.html b/old/moon_gui/delivery/html/common/loader/loader.tpl.html new file mode 100644 index 00000000..dc52e911 --- /dev/null +++ b/old/moon_gui/delivery/html/common/loader/loader.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/common/waiting/waiting.tpl.html b/old/moon_gui/delivery/html/common/waiting/waiting.tpl.html new file mode 100644 index 00000000..eca2ae9e --- /dev/null +++ b/old/moon_gui/delivery/html/common/waiting/waiting.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/dashboard/dashboard.tpl.html b/old/moon_gui/delivery/html/dashboard/dashboard.tpl.html new file mode 100644 index 00000000..caee0db0 --- /dev/null +++ b/old/moon_gui/delivery/html/dashboard/dashboard.tpl.html @@ -0,0 +1 @@ +

Moon:Software-Defined Security Framework

ET
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/logs/logs.tpl.html b/old/moon_gui/delivery/html/logs/logs.tpl.html new file mode 100644 index 00000000..bb6dd686 --- /dev/null +++ b/old/moon_gui/delivery/html/logs/logs.tpl.html @@ -0,0 +1 @@ +
Logs
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/model/action/model-add.tpl.html b/old/moon_gui/delivery/html/model/action/model-add.tpl.html new file mode 100644 index 00000000..ed370f05 --- /dev/null +++ b/old/moon_gui/delivery/html/model/action/model-add.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/model/action/model-delete.tpl.html b/old/moon_gui/delivery/html/model/action/model-delete.tpl.html new file mode 100644 index 00000000..a3e51261 --- /dev/null +++ b/old/moon_gui/delivery/html/model/action/model-delete.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/model/action/model-view.tpl.html b/old/moon_gui/delivery/html/model/action/model-view.tpl.html new file mode 100644 index 00000000..4e016c12 --- /dev/null +++ b/old/moon_gui/delivery/html/model/action/model-view.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/model/edit/metadata/metadata-edit.tpl.html b/old/moon_gui/delivery/html/model/edit/metadata/metadata-edit.tpl.html new file mode 100644 index 00000000..188c3678 --- /dev/null +++ b/old/moon_gui/delivery/html/model/edit/metadata/metadata-edit.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/model/edit/metadata/metadata-list.tpl.html b/old/moon_gui/delivery/html/model/edit/metadata/metadata-list.tpl.html new file mode 100644 index 00000000..050bfbce --- /dev/null +++ b/old/moon_gui/delivery/html/model/edit/metadata/metadata-list.tpl.html @@ -0,0 +1,88 @@ +

List of associated Subject Categories

IdNameDescription
Remove
There is no Subjects

Add a Subject Category

List associated of Object Categories

IdNameDescription
Remove
There is no Objects

Add an Object Category

List associated of Action Categories

IdNameDescription
Remove
There is no Actions

Add an Action Category

.

List of associated Subject Categories

Name
There is no Subjects

List associated of Object Categories

Name
There is no Objects

List associated of Action Categories

Name
There is no Actions
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-add.tpl.html b/old/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-add.tpl.html new file mode 100644 index 00000000..8593236d --- /dev/null +++ b/old/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-add.tpl.html @@ -0,0 +1 @@ +
Name is required
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-map.tpl.html b/old/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-map.tpl.html new file mode 100644 index 00000000..9041f072 --- /dev/null +++ b/old/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-map.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-unmap.tpl.html b/old/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-unmap.tpl.html new file mode 100644 index 00000000..37e21f11 --- /dev/null +++ b/old/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-unmap.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit-basic.tpl.html b/old/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit-basic.tpl.html new file mode 100644 index 00000000..3a171600 --- /dev/null +++ b/old/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit-basic.tpl.html @@ -0,0 +1 @@ +
Name is required
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit.tpl.html b/old/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit.tpl.html new file mode 100644 index 00000000..5c454d3f --- /dev/null +++ b/old/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/model/edit/metarules/metarules-list.tpl.html b/old/moon_gui/delivery/html/model/edit/metarules/metarules-list.tpl.html new file mode 100644 index 00000000..c6d6c92e --- /dev/null +++ b/old/moon_gui/delivery/html/model/edit/metarules/metarules-list.tpl.html @@ -0,0 +1 @@ +

List of Meta Rules

Name
Description
Number of Subjects
Number of Subjects
Number of Actions
Actions
There is no Meta Rules
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/model/edit/model-edit-basic.tpl.html b/old/moon_gui/delivery/html/model/edit/model-edit-basic.tpl.html new file mode 100644 index 00000000..a645b1ee --- /dev/null +++ b/old/moon_gui/delivery/html/model/edit/model-edit-basic.tpl.html @@ -0,0 +1 @@ +
Name is required
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/model/edit/model-edit.tpl.html b/old/moon_gui/delivery/html/model/edit/model-edit.tpl.html new file mode 100644 index 00000000..10f4545b --- /dev/null +++ b/old/moon_gui/delivery/html/model/edit/model-edit.tpl.html @@ -0,0 +1,4 @@ +

Edit

Basic Information Update
Id
Name
Description
Meta Rule
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/model/model-list.tpl.html b/old/moon_gui/delivery/html/model/model-list.tpl.html new file mode 100644 index 00000000..138a66b7 --- /dev/null +++ b/old/moon_gui/delivery/html/model/model-list.tpl.html @@ -0,0 +1,6 @@ +
 
 
 
Name
Description
Number of Meta Rules
Actions
There is no Models
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/pdp/action/pdp-add.tpl.html b/old/moon_gui/delivery/html/pdp/action/pdp-add.tpl.html new file mode 100644 index 00000000..5d8b2b65 --- /dev/null +++ b/old/moon_gui/delivery/html/pdp/action/pdp-add.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/pdp/action/pdp-delete.tpl.html b/old/moon_gui/delivery/html/pdp/action/pdp-delete.tpl.html new file mode 100644 index 00000000..f5f1d322 --- /dev/null +++ b/old/moon_gui/delivery/html/pdp/action/pdp-delete.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/pdp/edit/pdp-edit-basic.tpl.html b/old/moon_gui/delivery/html/pdp/edit/pdp-edit-basic.tpl.html new file mode 100644 index 00000000..e15e27e0 --- /dev/null +++ b/old/moon_gui/delivery/html/pdp/edit/pdp-edit-basic.tpl.html @@ -0,0 +1 @@ +
Name is required
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/pdp/edit/pdp-edit.tpl.html b/old/moon_gui/delivery/html/pdp/edit/pdp-edit.tpl.html new file mode 100644 index 00000000..96b3dd78 --- /dev/null +++ b/old/moon_gui/delivery/html/pdp/edit/pdp-edit.tpl.html @@ -0,0 +1 @@ +

Edit

Basic Information Update

Id
Name
Description

Policies

\ No newline at end of file diff --git a/old/moon_gui/delivery/html/pdp/pdp-list.tpl.html b/old/moon_gui/delivery/html/pdp/pdp-list.tpl.html new file mode 100644 index 00000000..31d1aae0 --- /dev/null +++ b/old/moon_gui/delivery/html/pdp/pdp-list.tpl.html @@ -0,0 +1 @@ +
 
 
 
Name
Number of Securities
Project
Actions
There is no PDP
Loading Project
Is not mapped
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/policy/action/mapping/policy-map.tpl.html b/old/moon_gui/delivery/html/policy/action/mapping/policy-map.tpl.html new file mode 100644 index 00000000..0d185618 --- /dev/null +++ b/old/moon_gui/delivery/html/policy/action/mapping/policy-map.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/policy/action/mapping/policy-unmap.tpl.html b/old/moon_gui/delivery/html/policy/action/mapping/policy-unmap.tpl.html new file mode 100644 index 00000000..844510e9 --- /dev/null +++ b/old/moon_gui/delivery/html/policy/action/mapping/policy-unmap.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/policy/action/policy-add.tpl.html b/old/moon_gui/delivery/html/policy/action/policy-add.tpl.html new file mode 100644 index 00000000..17f714c8 --- /dev/null +++ b/old/moon_gui/delivery/html/policy/action/policy-add.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/policy/action/policy-delete.tpl.html b/old/moon_gui/delivery/html/policy/action/policy-delete.tpl.html new file mode 100644 index 00000000..2e042fc0 --- /dev/null +++ b/old/moon_gui/delivery/html/policy/action/policy-delete.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/policy/edit/parameter/assignments/assignments-edit.tpl.html b/old/moon_gui/delivery/html/policy/edit/parameter/assignments/assignments-edit.tpl.html new file mode 100644 index 00000000..4d9e8a85 --- /dev/null +++ b/old/moon_gui/delivery/html/policy/edit/parameter/assignments/assignments-edit.tpl.html @@ -0,0 +1 @@ +
Policy is required
Perimeter is required
Category is required
Data is required
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/policy/edit/parameter/assignments/assignments-list.tpl.html b/old/moon_gui/delivery/html/policy/edit/parameter/assignments/assignments-list.tpl.html new file mode 100644 index 00000000..6cae38d8 --- /dev/null +++ b/old/moon_gui/delivery/html/policy/edit/parameter/assignments/assignments-list.tpl.html @@ -0,0 +1 @@ +

List of associated Subjects

Perimeter nameCategory nameData name
Loading
Loading
()
There is no Subjects

Add a Subject Category

List associated of Objects

Perimeter nameCategory nameData name
Loading
Loading
()
There is no Objects

Add an Object Category

List associated of Actions

Perimeter nameCategory nameData name
Loading
Loading
()
There is no Actions

Add an Action Category

.
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/policy/edit/parameter/data/data-edit.tpl.html b/old/moon_gui/delivery/html/policy/edit/parameter/data/data-edit.tpl.html new file mode 100644 index 00000000..d63f6683 --- /dev/null +++ b/old/moon_gui/delivery/html/policy/edit/parameter/data/data-edit.tpl.html @@ -0,0 +1 @@ +
Name is required
Category is required
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/policy/edit/parameter/data/data-list.tpl.html b/old/moon_gui/delivery/html/policy/edit/parameter/data/data-list.tpl.html new file mode 100644 index 00000000..ef9b2ba7 --- /dev/null +++ b/old/moon_gui/delivery/html/policy/edit/parameter/data/data-list.tpl.html @@ -0,0 +1,113 @@ +

List of associated Subjects

NameDescriptionCategory
Loading
Delete
There is no Subjects

Add a Subject Category

List associated of Objects

NameDescriptionCategoryActions
Loading
Delete
There is no Objects

Add an Object Category

List associated of Actions

NameDescriptionCategoryActions
Loading
Delete
There is no Actions

Add an Action Category

.
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/policy/edit/parameter/perimeter/perimeter-edit.tpl.html b/old/moon_gui/delivery/html/policy/edit/parameter/perimeter/perimeter-edit.tpl.html new file mode 100644 index 00000000..23b29cb5 --- /dev/null +++ b/old/moon_gui/delivery/html/policy/edit/parameter/perimeter/perimeter-edit.tpl.html @@ -0,0 +1,11 @@ +
Name is required
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/policy/edit/parameter/perimeter/perimeter-list.tpl.html b/old/moon_gui/delivery/html/policy/edit/parameter/perimeter/perimeter-list.tpl.html new file mode 100644 index 00000000..5331e640 --- /dev/null +++ b/old/moon_gui/delivery/html/policy/edit/parameter/perimeter/perimeter-list.tpl.html @@ -0,0 +1 @@ +

List of associated Subjects

NameDescriptionEmail
Unmap
There is no Subjects

Add a Subject Category

List associated of Objects

NameDescription
Unmap
There is no Objects

Add an Object Category

List associated of Actions

NameDescription
Unmap
There is no Actions

Add an Action Category

.
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/policy/edit/parameter/rules/rules-edit.tpl.html b/old/moon_gui/delivery/html/policy/edit/parameter/rules/rules-edit.tpl.html new file mode 100644 index 00000000..46716d0d --- /dev/null +++ b/old/moon_gui/delivery/html/policy/edit/parameter/rules/rules-edit.tpl.html @@ -0,0 +1 @@ +
Policy is required
A MetaRules is required
Some subject are required
Some objects are required
Some action are required
An instructions is required
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/policy/edit/parameter/rules/rules-list.tpl.html b/old/moon_gui/delivery/html/policy/edit/parameter/rules/rules-list.tpl.html new file mode 100644 index 00000000..25cfe6f1 --- /dev/null +++ b/old/moon_gui/delivery/html/policy/edit/parameter/rules/rules-list.tpl.html @@ -0,0 +1 @@ +

List of associated Subjects

Meta Rule
Rule
Instruction
Actions
There is no Rules
Loading Loading ,
Delete

Add a Rule

.
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/policy/edit/policy-edit-basic.tpl.html b/old/moon_gui/delivery/html/policy/edit/policy-edit-basic.tpl.html new file mode 100644 index 00000000..23f760d4 --- /dev/null +++ b/old/moon_gui/delivery/html/policy/edit/policy-edit-basic.tpl.html @@ -0,0 +1 @@ +
Name is required
{{$select.selected.name}}
{{model.name}}
Model is required
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/policy/edit/policy-edit.tpl.html b/old/moon_gui/delivery/html/policy/edit/policy-edit.tpl.html new file mode 100644 index 00000000..f32497a2 --- /dev/null +++ b/old/moon_gui/delivery/html/policy/edit/policy-edit.tpl.html @@ -0,0 +1,13 @@ +

Edit

Basic Information Update
Id
Name
Genre
Model
Description
Perimeters Show Show
Assignments Show Close
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/policy/policy-list.tpl.html b/old/moon_gui/delivery/html/policy/policy-list.tpl.html new file mode 100644 index 00000000..2e8a981c --- /dev/null +++ b/old/moon_gui/delivery/html/policy/policy-list.tpl.html @@ -0,0 +1 @@ +
 
 
 
Name
Genre
Description
Actions
There is no policy
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/policy/policy-mapped-list.tpl.html b/old/moon_gui/delivery/html/policy/policy-mapped-list.tpl.html new file mode 100644 index 00000000..2e18a1b5 --- /dev/null +++ b/old/moon_gui/delivery/html/policy/policy-mapped-list.tpl.html @@ -0,0 +1 @@ +
Name
Genre
Description
Actions
There is no policy
Unmap
\ No newline at end of file diff --git a/old/moon_gui/delivery/html/project/action/mapping/project-map.tpl.html b/old/moon_gui/delivery/html/project/action/mapping/project-map.tpl.html new file mode 100644 index 00000000..13cef98b --- /dev/null +++ b/old/moon_gui/delivery/html/project/action/mapping/project-map.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/project/action/mapping/project-unmap.tpl.html b/old/moon_gui/delivery/html/project/action/mapping/project-unmap.tpl.html new file mode 100644 index 00000000..735011a9 --- /dev/null +++ b/old/moon_gui/delivery/html/project/action/mapping/project-unmap.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/project/action/project-add.tpl.html b/old/moon_gui/delivery/html/project/action/project-add.tpl.html new file mode 100644 index 00000000..4db03982 --- /dev/null +++ b/old/moon_gui/delivery/html/project/action/project-add.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/project/action/project-delete.tpl.html b/old/moon_gui/delivery/html/project/action/project-delete.tpl.html new file mode 100644 index 00000000..867a6674 --- /dev/null +++ b/old/moon_gui/delivery/html/project/action/project-delete.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/project/action/project-view.tpl.html b/old/moon_gui/delivery/html/project/action/project-view.tpl.html new file mode 100644 index 00000000..157eec80 --- /dev/null +++ b/old/moon_gui/delivery/html/project/action/project-view.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/old/moon_gui/delivery/html/project/project-list.tpl.html b/old/moon_gui/delivery/html/project/project-list.tpl.html new file mode 100644 index 00000000..d0ab8886 --- /dev/null +++ b/old/moon_gui/delivery/html/project/project-list.tpl.html @@ -0,0 +1 @@ +
 
 
 
Name
Domain
Enabled
Description
Mapping
Actions
There is no Projects
Loading PDP
\ No newline at end of file diff --git a/old/moon_gui/delivery/index.html b/old/moon_gui/delivery/index.html new file mode 100644 index 00000000..0631ab7a --- /dev/null +++ b/old/moon_gui/delivery/index.html @@ -0,0 +1,34 @@ + + + + + + + Moon + + + + + + + + +
+
+
+ +
+
+
+ +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/old/moon_gui/delivery/js/app.js b/old/moon_gui/delivery/js/app.js new file mode 100644 index 00000000..96bb1f6a --- /dev/null +++ b/old/moon_gui/delivery/js/app.js @@ -0,0 +1,4 @@ +!function(){"use strict";function e(e,s,d,u){s.useStaticFilesLoader({prefix:"assets/i18n/",suffix:".json"}).preferredLanguage("en").useCookieStorage(),u.theme="selectize",e.when("","/model"),e.when("/","/model"),e.otherwise("/404"),t(d),o(d),n(d),c(d),i(d),r(d),a(d),l(d)}function t(e){return e.state("moon",{abstract:!0,template:"
"}).state("moon.404",{url:"/404",templateUrl:"html/common/404/404.tpl.html"}),e}function o(e){return e.state("moon.dashboard",{url:"/dashboard",templateUrl:"html/dashboard/dashboard.tpl.html"}),e}function n(e){return e.state("moon.auth",{abstract:!0,template:"
"}).state("moon.auth.login",{url:"/login",templateUrl:"html/authentication/authentication.tpl.html",controller:"AuthenticationController",controllerAs:"auth"}),e}function i(e){return e.state("moon.model",{abstract:!0,template:"
"}).state("moon.model.list",{url:"/model",templateUrl:"html/model/model-list.tpl.html",controller:"ModelListController",controllerAs:"list",resolve:{models:["modelService",function(e){return e.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(e,t){return t.findOneWithMetaRules(e.id)}]}}),e}function c(e){return e.state("moon.project",{abstract:!0,template:"
"}).state("moon.project.list",{url:"/project",templateUrl:"html/project/project-list.tpl.html",controller:"ProjectListController",controllerAs:"list",resolve:{projects:["projectService",function(e){return e.findAll()}]}}),e}function r(e){return e.state("moon.pdp",{abstract:!0,template:"
"}).state("moon.pdp.list",{url:"/pdp",templateUrl:"html/pdp/pdp-list.tpl.html",controller:"PDPListController",controllerAs:"list",resolve:{pdps:["pdpService",function(e){return e.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(e,t){return t.findOne(e.id)}]}}),e}function a(e){return e.state("moon.policy",{abstract:!0,template:"
"}).state("moon.policy.list",{url:"/policy",templateUrl:"html/policy/policy-list.tpl.html",controller:"PolicyListController",controllerAs:"list",resolve:{policies:["policyService",function(e){return e.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(e,t){return t.findOne(e.id)}]}}),e}function l(e){return e.state("moon.logs",{url:"/logs",templateUrl:"html/logs/logs.tpl.html",controller:"LogsController",controllerAs:"logs"}),e}function s(e,t,o,n,i,c,r){function a(e,t,o){-1===["/login"].indexOf(r.path())&&!c.currentUser&&r.path("/login")}function l(){e.connected=i.IsConnected(),e.transitionModal.$promise.then(e.transitionModal.show)}function s(){e.transitionModal.hide()}function d(t,i,c,r,a,l){var s=u(t,i,c,r,a,l);o("moon.global.error",{stacktrace:s}).then(function(e){n.alertError(e)}),e.transitionModal.hide()}function u(e,t,o,n,i,c){var r={};return r.status=c.status,r.message=c.statusText,r.state=t,r.params=o,r}e.connected=i.IsConnected(),e.transitionModal=t({scope:e,template:"html/common/waiting/waiting.tpl.html",backdrop:"static",show:!1}),e.$on("$stateChangeStart",l),e.$on("$stateChangeSuccess",s),e.$on("$stateChangeError",d),e.$on("$locationChangeStart",a),i.IsConnected()&&i.SetTokenHeader(i.GetTokenHeader())}angular.module("moon",["ngResource","ngRoute","ui.router","ngMessages","ui.bootstrap","ngTable","ngCookies","ngStorage","pascalprecht.translate","ngAnimate","mgcrea.ngStrap","NgSwitchery","ui.select","toaster"]).config(e).run(s);e.$inject=["$urlRouterProvider","$translateProvider","$stateProvider","uiSelectConfig"],s.$inject=["$rootScope","$modal","$translate","alertService","authenticationService","$sessionStorage","$location"]}(),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/"})}(),function(){"use strict";function e(e,t,o,n,i){function c(){l.loading=!0,e.Login(l.credentials,r,a)}function r(){t("moon.login.success").then(function(e){o.alertSuccess(e),n.go("moon.dashboard"),l.loading=!1})}function a(e){t("moon.login.error",{errorCode:e.status}).then(function(e){o.alertError(e),l.loading=!1})}var l=this;l.login=c,l.loading=!1,l.credentials={username:"",password:""},function(){i.connected&&n.go("moon.dashboard")}()}angular.module("moon").controller("AuthenticationController",e),e.$inject=["authenticationService","$translate","alertService","$state","$rootScope"]}(),function(){"use strict";function e(){}angular.module("moon").controller("LogsController",e)}(),function(){"use strict";function e(e,t,o,n,i,c){function r(){return S.table=new n({page:1,count:10,sorting:{name:"asc"}},{total:function(){return S.getModels().length},getData:function(e,t){var o=t.sorting()?i("orderBy")(S.getModels(),t.orderBy()):S.getModels();e.resolve(o.slice((t.page()-1)*t.count(),t.page()*t.count()))},$scope:{$data:{}}}),S.table}function a(){return S.models?S.models:[]}function l(){return S.getModels().length>0}function s(){S.search.query=""}function d(e){return-1!==e.name.indexOf(S.search.query)||-1!==e.description.indexOf(S.search.query)}function u(){S.add.modal.$promise.then(S.add.modal.show)}function m(e){S.models.push(e)}function p(){S.table.total(S.models.length),S.table.reload()}function f(e,t){m(t),p(),S.add.modal.hide()}function h(e){S.add.modal.hide()}function g(e){S.view.modal.$scope.model=e,S.view.modal.$promise.then(S.view.modal.show)}function y(e){S.del.modal.$scope.model=e,S.del.modal.$promise.then(S.del.modal.show)}function v(e){S.models=_.chain(S.models).reject({id:e.id}).value()}function b(e,t){S.deleteModel(t),S.refreshModels(),S.del.modal.hide()}function j(e,t){S.del.modal.hide()}var S=this;S.models=o,S.table={},S.search={query:"",find:d,reset:s},S.getModels=a,S.hasModels=l,S.deleteModel=v,S.refreshModels=p,S.add={modal:c({template:"html/model/action/model-add.tpl.html",show:!1}),showModal:u},S.view={modal:c({template:"html/model/action/model-view.tpl.html",show:!1}),showModal:g},S.del={modal:c({template:"html/model/action/model-delete.tpl.html",show:!1}),showModal:y},function(){r()}();var T={"event:modelCreatedSuccess":t.$on("event:modelCreatedSuccess",f),"event:modelCreatedError":t.$on("event:modelCreatedError",h),"event:modelDeletedSuccess":t.$on("event:modelDeletedSuccess",b),"event:modelDeletedError":t.$on("event:modelDeletedError",j)};for(var E in T)e.$on("$destroy",T[E])}angular.module("moon").controller("ModelListController",e),e.$inject=["$scope","$rootScope","models","NgTableParams","$filter","$modal"]}(),function(){"use strict";function e(e,t,o,n,i,c,r){function a(){return A.pdps?A.pdps:[]}function l(){return A.getPDPs().length>0}function s(e){A.pdps.push(e)}function d(e){A.pdps=_.chain(A.pdps).reject({id:e.id}).value()}function u(){A.table.total(A.pdps.length),A.table.reload()}function m(e){return _(_.values(A.getPDPs())).each(function(t){t.id===e.id&&(t=_.clone(e))}),A.pdps}function p(e){return e.id}function f(e){return e.tenant.name}function h(e){return e?e.name:""}function g(e){return!_.isNull(e.keystone_project_id)}function y(e){return _.has(e,"project")?e.project:(_.has(e,"callPdpInProgress")||(e.callPdpInProgress=!0,r.findOne(e.keystone_project_id,function(t){return e.callPdpInProgress=!1,e.project=t,e.project})),!1)}function v(){return A.table=new i({page:1,count:10},{total:function(){return A.getPDPs().length},getData:function(e,t){var n=t.sorting()?o("orderBy")(A.getPDPs(),t.orderBy()):A.getPDPs();e.resolve(n.slice((t.page()-1)*t.count(),t.page()*t.count()))},$scope:{$data:{}}}),A.table}function b(e){return-1!==A.getPDPName(e).indexOf(A.search.query)||-1!==A.getSecPipelineFromPdp(e).indexOf(A.search.query)}function j(e){return e.security_pipeline?e.security_pipeline:[]}function S(){A.search.query=""}function T(){A.add.modal.$promise.then(A.add.modal.show)}function E(e,t){A.addPDP(t),A.refreshPDPs(),A.add.modal.hide()}function P(e,t){A.add.modal.hide()}function $(e){A.del.modal.$scope.pdp=e,A.del.modal.$promise.then(A.del.modal.show)}function C(e,t){A.deletePDP(t),A.refreshPDPs(),A.del.modal.hide()}function O(){A.del.modal.hide()}var A=this;A.pdps=c,A.mappings=[],A.getPDPs=a,A.hasPDPs=l,A.getPDPName=h,A.isMapped=g,A.getProjectFromPDP=y,A.getidFromPDP=p,A.table={},A.addPDP=s,A.deletePDP=d,A.refreshPDPs=u,A.updatePDPs=m,A.getMappedProjectName=f,A.getSecPipelineFromPdp=j,A.search={query:"",find:b,reset:S},A.add={modal:n({template:"html/pdp/action/pdp-add.tpl.html",show:!1}),showModal:T},A.del={modal:n({template:"html/pdp/action/pdp-delete.tpl.html",show:!1}),showModal:$},function(){v()}();var R={"event:pdpCreatedSuccess":e.$on("event:pdpCreatedSuccess",E),"event:pdpCreatedError":e.$on("event:pdpCreatedError",P),"event:pdpDeletedSuccess":e.$on("event:pdpDeletedSuccess",C),"event:pdpDeletedError":e.$on("event:pdpDeletedError",O)};_.each(R,function(e){t.$on("$destroy",R[e])})}angular.module("moon").controller("PDPListController",e),e.$inject=["$rootScope","$scope","$filter","$modal","NgTableParams","pdps","projectService"]}(),function(){"use strict";function e(e,t,o,n,i,c){function r(){return j.policies?j.policies:[]}function a(){return j.getPolicies().length>0}function l(){return j.table=new o({page:1,count:10,sorting:{name:"asc",genre:"asc"}},{total:function(){return j.getPolicies().length},getData:function(e,t){var o=t.sorting()?n("orderBy")(j.getPolicies(),t.orderBy()):j.getPolicies();e.resolve(o.slice((t.page()-1)*t.count(),t.page()*t.count()))},$scope:{$data:{}}}),j.table}function s(e){return-1!==e.name.indexOf(j.search.query)||-1!==e.genre.indexOf(j.search.query)||-1!==e.description.indexOf(j.search.query)}function d(){j.search.query=""}function u(){j.add.modal.$promise.then(j.add.modal.show)}function m(e,t){j.addPolicy(t),j.refreshPolicies(),j.add.modal.hide()}function p(e,t){j.add.modal.hide()}function f(e){j.policies.push(e)}function h(){j.table.total(j.policies.length),j.table.reload()}function g(e){j.del.modal.$scope.policy=e,j.del.modal.$promise.then(j.del.modal.show)}function y(e){j.policies=_.chain(j.policies).reject({id:e.id}).value()}function v(e,t){j.deletePolicy(t),j.refreshPolicies(),j.del.modal.hide()}function b(e,t){j.del.modal.hide()}var j=this;j.policies=t,j.getPolicies=r,j.hasPolicies=a,j.addPolicy=f,j.refreshPolicies=h,j.deletePolicy=y,j.table={},j.search={query:"",find:s,reset:d},j.add={modal:i({template:"html/policy/action/policy-add.tpl.html",show:!1}),showModal:u},j.del={modal:i({template:"html/policy/action/policy-delete.tpl.html",show:!1}),showModal:g},function(){l()}();var S={"event:policyCreatedSuccess":c.$on("event:policyCreatedSuccess",m),"event:policyCreatedError":c.$on("event:policyCreatedError",p),"event:policyDeletedSuccess":c.$on("event:policyDeletedSuccess",v),"event:policyDeletedError":c.$on("event:policyDeletedError",b)};for(var T in S)e.$on("$destroy",S[T])}angular.module("moon").controller("PolicyListController",e),e.$inject=["$scope","policies","NgTableParams","$filter","$modal","$rootScope"]}(),function(){"use strict";function e(){return{templateUrl:"html/policy/policy-mapped-list.tpl.html",bindToController:!0,controller:t,controllerAs:"list",scope:{pdp:"="},restrict:"E",replace:!0}}function t(e,t,o,n,i,c){function r(e){_.isUndefined(y.pdp.security_pipeline)||(y.policiesId=y.pdp.security_pipeline,c.findSomeWithCallback(y.policiesId,function(t){y.policies=t,y.loadingPolicies=!1,e?d():a()}))}function a(){return y.table=new o({page:1,count:10},{total:function(){return y.getPolicies().length},getData:function(e,t){var o=t.sorting()?i("orderBy")(y.getPolicies(),t.orderBy()):y.getPolicies();e.resolve(o.slice((t.page()-1)*t.count(),t.page()*t.count()))},$scope:{$data:{}}}),y.table}function l(){return y.policies?y.policies:[]}function s(){return y.getPolicies().length>0}function d(){y.table.total(y.getPolicies().length),y.table.reload()}function u(){y.map.modal.$scope.pdp=y.pdp,y.map.modal.$promise.then(y.map.modal.show)}function m(e){y.unmap.modal.$scope.pdp=y.pdp,y.unmap.modal.$scope.policy=e,y.unmap.modal.$promise.then(y.unmap.modal.show)}function p(e,t){y.pdp=t,r(!0),y.map.modal.hide()}function f(e){y.map.modal.hide()}function h(e,t){y.pdp=t,r(!0),y.unmap.modal.hide()}function g(e){y.unmap.modal.hide()}var y=this;y.table={},y.pdp=e.list.pdp,y.getPolicies=l,y.hasPolicies=s,y.refreshPolicies=d,y.loadingPolicies=!0,y.policies=[],function(){r(!1)}(),y.map={modal:n({template:"html/policy/action/mapping/policy-map.tpl.html",show:!1}),showModal:u},y.unmap={modal:n({template:"html/policy/action/mapping/policy-unmap.tpl.html",show:!1}),showModal:m};var v={"event:policyMapToPdpSuccess":t.$on("event:policyMapToPdpSuccess",p),"event:policyMapToPdpError":t.$on("event:policyMapToPdpError",f),"event:policyUnMappedToPdpSuccess":t.$on("event:policyUnMappedToPdpSuccess",h),"event:policyUnMappedToPdpError":t.$on("event:policyUnMappedToPdpError",g)};for(var b in v)e.$on("$destroy",v[b])}angular.module("moon").directive("moonPolicyMappedList",e),e.$inject=[],angular.module("moon").controller("moonPolicyMappedListController",t),t.$inject=["$scope","$rootScope","NgTableParams","$modal","$filter","policyService"]}(),function(){"use strict";function e(e,t,o,n,i,c,r){function a(){k.loadingPDPs=!0,h(),c.findAllWithCallBack(function(e){k.pdps=e,c.mapPdpsToProjects(k.projects,k.pdps),k.loadingPDPs=!1})}function l(){return k.projects?k.projects:[]}function s(){return k.getProjects().length>0}function d(e){return _.has(e,"pdp")}function u(e){return e.pdp}function m(e){k.projects.push(e)}function p(e){k.projects=_.chain(k.projects).reject({id:e.id}).value()}function f(){k.table.total(k.projects.length),k.table.reload()}function h(){return k.table=new i({page:1,count:10,sorting:{name:"asc"}},{total:function(){return k.getProjects().length},getData:function(e,t){var n=t.sorting()?o("orderBy")(k.getProjects(),t.orderBy()):k.getProjects();e.resolve(n.slice((t.page()-1)*t.count(),t.page()*t.count()))},$scope:{$data:{}}}),k.table}function g(e){return _.has(e,"pdp")?e.pdp.name:"error"}function y(e){return-1!==e.name.indexOf(k.search.query)||-1!==e.description.indexOf(k.search.query)}function v(){k.search.query=""}function b(){k.add.modal.$promise.then(k.add.modal.show)}function j(e,t){k.addProject(t),k.refreshProjects(),k.add.modal.hide()}function S(e,t){k.add.modal.hide()}function T(e){k.del.modal.$scope.project=e,k.del.modal.$promise.then(k.del.modal.show)}function E(e,t){k.deleteProject(t),k.refreshProjects(),k.del.modal.hide()}function P(e,t){k.del.modal.hide()}function $(e){k.map.modal.$scope.project=e,k.map.modal.$promise.then(k.map.modal.show)}function C(e,t){a(),k.map.modal.hide()}function O(e,t){k.map.modal.hide()}function A(e){k.unmap.modal.$scope.project=e,k.unmap.modal.$promise.then(k.unmap.modal.show)}function R(e,t){var o=_.findIndex(k.projects,function(e){return t.id===e.id});if(-1===o)return k.unmap.modal.hide(),!1;k.projects[o]=t,k.refreshProjects(),k.unmap.modal.hide()}function M(e,t){k.unmap.modal.hide()}function D(e){k.view.modal.$scope.project=e,k.view.modal.$promise.then(k.view.modal.show)}var k=this;k.projects=r,k.pdps=[],k.getProjects=l,k.hasProjects=s,k.isProjectMapped=d,k.table={},k.addProject=m,k.deleteProject=p,k.refreshProjects=f,k.getMappedPDPName=g,k.getPdpFromProject=u,k.search={query:"",find:y,reset:v},k.add={modal:n({template:"html/project/action/project-add.tpl.html",show:!1}),showModal:b},k.del={modal:n({template:"html/project/action/project-delete.tpl.html",show:!1}),showModal:T},k.map={modal:n({template:"html/project/action/mapping/project-map.tpl.html",show:!1}),showModal:$},k.unmap={modal:n({template:"html/project/action/mapping/project-unmap.tpl.html",show:!1}),showModal:A},k.view={modal:n({template:"html/project/action/project-view.tpl.html",show:!1}),showModal:D},a();var L={"event:projectCreatedSuccess":e.$on("event:projectCreatedSuccess",j),"event:projectCreatedError":e.$on("event:projectCreatedError",S),"event:projectDeletedSuccess":e.$on("event:projectDeletedSuccess",E),"event:projectDeletedError":e.$on("event:projectDeletedError",P),"event:projectMappedSuccess":e.$on("event:projectMappedSuccess",C),"event:projectMappedError":e.$on("event:projectMappedError",O),"event:projectUnmappedSuccess":e.$on("event:projectUnmappedSuccess",R),"event:projectUnmappedError":e.$on("event:projectUnmappedError",M)};for(var N in L)t.$on("$destroy",L[N])}angular.module("moon").controller("ProjectListController",e),e.$inject=["$rootScope","$scope","$filter","$modal","ngTableParams","pdpService","projects"]}(),function(){"use strict";function e(e,t){function o(){n.browsersModal.$promise.then(n.browsersModal.show)}var n=this;n.version=null,n.browsersModal=null,n.showBrowsersCompliance=o,function(){n.browsersModal=e({template:"html/common/compatibility/compatibility.tpl.html",show:!1}),n.browsersModal}(),function(){var e=n;t.version.get().$promise.then(function(t){return e.version=t.version?t.version:"SNAPSHOT",e.version})}()}angular.module("moon").controller("FooterController",e),e.$inject=["$modal","versionService"]}(),function(){"use strict";function e(e,t,o,n){function i(t,o){o.preventDefault(),e.use(t),e.preferredLanguage(t),r.currentLanguage=t}function c(){o.Logout(),e("moon.logout.success").then(function(e){n.alertSuccess(e)})}var r=this;r.isProjectTabActive=t.isProjectTabActive,r.isPDPTabActive=t.isPDPTabActive,r.isLogsTabActive=t.isLogsTabActive,r.isPolicyTabActive=t.isPolicyTabActive,r.isModelTabActive=t.isModelTabActive,r.changeLocale=i,r.logout=c,r.currentLanguage=e.use(),r.getUser=o.GetUser}angular.module("moon").controller("HeaderController",e),e.$inject=["$translate","menuService","authenticationService","alertService"]}(),function(){"use strict";function e(){return{templateUrl:"html/common/loader/loader.tpl.html",restrict:"E"}}angular.module("moon").directive("moonLoader",e),e.$inject=[]}(),function(){"use strict";function e(e,t,o,n,i,c){function r(){function r(t){var i=c.transformOne(t,"models");n("moon.model.add.success",{modelName:i.name}).then(function(e){o.alertSuccess(e)}),a.loading=!1,e.$emit("event:modelCreatedSuccess",i)}function l(t){n("moon.model.add.error",{modelName:a.model.name}).then(function(e){o.alertError(e)}),a.loading=!1,e.$emit("event:modelCreatedError",a.project)}i.isInvalid(a.form)?i.checkFieldsValidity(a.form):(a.loading=!0,t.data.create({},a.model,r,l))}var a=this;a.form={},a.loading=!1,a.model={name:null,description:null,meta_rules:[]},a.create=r}angular.module("moon").controller("ModelAddController",e),e.$inject=["$scope","modelService","alertService","$translate","formService","utilService"]}(),function(){"use strict";function e(e,t,o,n){function i(){function i(n){t("moon.model.remove.success",{modelName:c.model.name}).then(function(e){o.alertSuccess(e)}),c.loading=!1,e.$emit("event:modelDeletedSuccess",c.model)}function r(n){t("moon.model.remove.error",{modelName:c.model.name,errorCode:n.data.error.code,message:n.data.error.message}).then(function(e){o.alertError(e)}),c.loading=!1,e.$emit("event:modelDeletedError",c.model)}c.loading=!0,n.delete(c.model,i,r)}var c=this;c.model=e.model,c.loading=!1,c.remove=i}angular.module("moon").controller("ModelDeleteController",e),e.$inject=["$scope","$translate","alertService","modelService"]}(),function(){"use strict";function e(e,t){function o(){t.findSomeWithMetaData(n.model.meta_rules).then(function(e){n.meta_rules_values=e,n.model.meta_rules_values=e})}var n=this;n.model=e.model,n.meta_rules_values=!1,function(){n.model.meta_rules.length>0?o():n.meta_rules_values=[]}()}angular.module("moon").controller("ModelViewController",e),e.$inject=["$scope","metaRuleService"]}(),function(){"use strict";function e(e,t,o,n){function i(e,t){c.model=t,n.findSomeWithCallback(t.meta_rules,function(e){c.model.meta_rules_values=e})}var c=this;c.model=o,c.editBasic=!1,c.editMetaRules=!0;var r={"event:modelUpdatedSuccess":t.$on("event:modelUpdatedSuccess",i),"event:updateModelFromMetaRuleAddSuccess":t.$on("event:updateModelFromMetaRuleAddSuccess",i)};for(var a in r)e.$on("$destroy",r[a])}angular.module("moon").controller("ModelEditController",e),e.$inject=["$scope","$rootScope","model","metaRuleService"]}(),function(){"use strict";function e(){return{templateUrl:"html/model/edit/model-edit-basic.tpl.html",bindToController:!0,controller:t,controllerAs:"edit",scope:{model:"="},restrict:"E",replace:!0}}function t(e,t,o,n,i,c){function r(){function r(t){var o=c.transformOne(t,"models");i("moon.model.edit.basic.success",{modelName:o.name}).then(function(e){n.alertSuccess(e)}),l.loading=!1,e.$emit("event:modelUpdatedSuccess",o)}function a(e){i("moon.model.edit.basic.error",{modelName:l.model.name}).then(function(e){n.alertError(e)}),l.loading=!1}o.isInvalid(l.form)?o.checkFieldsValidity(l.form):(l.loading=!0,t.update(l.modelToEdit,r,a))}function a(){l.modelToEdit=angular.copy(l.model)}var l=this;l.editModel=r,l.init=a,l.form={},function(){l.model=e.edit.model,l.modelToEdit=angular.copy(l.model)}()}angular.module("moon").directive("moonModelEditBasic",e),e.$inject=[],angular.module("moon").controller("moonModelEditBasicController",t),t.$inject=["$scope","modelService","formService","alertService","$translate","utilService"]}(),function(){"use strict";function e(e,t,o,n,i,c,r){function a(c){function a(n){t("moon.pdp.add.success",{pdpName:c.name}).then(function(e){o.alertSuccess(e)});var i=r.transformOne(n,"pdps");l.loading=!1,e.$emit("event:pdpCreatedSuccess",i)}function s(n){t("moon.pdp.add.error",{pdpName:c.name}).then(function(e){o.alertError(e)}),l.loading=!1,e.$emit("event:pdpCreatedError")}n.isInvalid(l.form)?n.checkFieldsValidity(l.form):(l.loading=!0,i.data.pdp.create({},{name:l.pdp.name,description:l.pdp.description,security_pipeline:[l.selectedPolicy.id],keystone_project_id:null},a,s))}var l=this;l.form={},l.pdp={},l.policies=[],l.selectedPolicy=null,l.loading=!1,l.loadingPolicies=!0,l.create=a,function(){c.findAllWithCallback(function(e){l.policies=e,l.loadingPolicies=!1})}()}angular.module("moon").controller("PDPAddController",e),e.$inject=["$scope","$translate","alertService","formService","pdpService","policyService","utilService"]}(),function(){"use strict";function e(e,t,o,n){function i(){function i(n){t("moon.pdp.remove.success",{pdpName:c.pdp.name}).then(function(e){o.alertSuccess(e)}),c.loading=!1,e.$emit("event:pdpDeletedSuccess",c.pdp)}function r(n){t("moon.pdp.remove.error",{pdpName:c.pdp.name}).then(function(e){o.alertError(e)}),c.loading=!1,e.$emit("event:pdpDeletedError",c.pdp)}c.loading=!0,n.data.pdp.remove({pdp_id:c.pdp.id},i,r)}var c=this;c.pdp=e.pdp,c.loading=!1,c.remove=i}angular.module("moon").controller("PDPDeleteController",e),e.$inject=["$scope","$translate","alertService","pdpService"]}(),function(){"use strict";function e(e,t,o,n){function i(e,t){c.pdp=t}var c=this;c.pdp=o,c.editBasic=!1;var r={"event:pdpUpdatedSuccess":t.$on("event:pdpUpdatedSuccess",i)};for(var a in r)e.$on("$destroy",r[a])}angular.module("moon").controller("PDPEditController",e),e.$inject=["$scope","$rootScope","pdp","$stateParams"]}(),function(){"use strict";function e(){return{templateUrl:"html/pdp/edit/pdp-edit-basic.tpl.html",bindToController:!0,controller:t,controllerAs:"edit",scope:{pdp:"="},restrict:"E",replace:!0}}function t(e,t,o,n,i,c){function r(){function r(t){var o=c.transformOne(t,"pdps");i("moon.pdp.edit.basic.success",{pdpName:o.name}).then(function(e){n.alertSuccess(e)}),l.loading=!1,e.$emit("event:pdpUpdatedSuccess",o)}function a(e){i("moon.pdp.edit.basic.error",{pdpName:l.pdp.name}).then(function(e){n.alertError(e)}),l.loading=!1}o.isInvalid(l.form)?o.checkFieldsValidity(l.form):(l.loading=!0,t.update(l.pdpToEdit,r,a))}function a(){l.pdpToEdit=angular.copy(l.pdp)}var l=this;l.editPdp=r,l.init=a,l.form={},function(){l.pdp=e.edit.pdp,l.pdpToEdit=angular.copy(l.pdp)}()}angular.module("moon").directive("moonPDPEditBasic",e),e.$inject=[],angular.module("moon").controller("moonPDPEditBasicController",t),t.$inject=["$scope","pdpService","formService","alertService","$translate","utilService"]}(),function(){"use strict";function e(e,t,o,n,i,c,r){function a(){r.findAllWithCallBack(l)}function l(e){d.models=e,d.modelsLoading=!1}function s(){function r(n){var i=c.transformOne(n,"policies");t("moon.policy.add.success",{policyName:i.name}).then(function(e){o.alertSuccess(e)}),d.loading=!1,e.$emit("event:policyCreatedSuccess",i)}function a(n){t("moon.policy.add.error",{policyName:d.model.name}).then(function(e){o.alertError(e)}),d.loading=!1,e.$emit("event:policyCreatedError",d.project)}n.isInvalid(d.form)?n.checkFieldsValidity(d.form):(d.loading=!0,i.data.policy.create({},{name:d.policy.name,description:d.policy.description,genre:[d.selectedGenre],model_id:d.selectedModel.id},r,a))}var d=this;d.loading=!1,d.form={},d.policy={name:null,genre:null,description:null,model_id:null},d.genres=["admin","authz"],d.models=[],d.modelsLoading=!0,d.create=s,function(){a()}()}angular.module("moon").controller("PolicyAddController",e),e.$inject=["$scope","$translate","alertService","formService","policyService","utilService","modelService"]}(),function(){"use strict";function e(e,t,o,n){function i(){function i(n){t("moon.policy.remove.success",{policyName:c.policy.name}).then(function(e){o.alertSuccess(e)}),c.loading=!1,e.$emit("event:policyDeletedSuccess",c.policy)}function r(n){t("moon.policy.remove.error",{policyName:c.policy.name,errorCode:n.data.error.code,message:n.data.error.message}).then(function(e){o.alertError(e)}),c.loading=!1,e.$emit("event:policyDeletedError",c.policy)}c.loading=!0,n.delete(c.policy,i,r)}var c=this;c.policy=e.policy,c.loading=!1,c.remove=i}angular.module("moon").controller("PolicyDeleteController",e),e.$inject=["$scope","$translate","alertService","policyService"]}(),function(){"use strict";function e(e,t,o,n){function i(e){var t=a[e];a.showPerimeters=!1,a.showData=!1,a.showRules=!1,a.showAssignments=!1,a[e]=!t}function c(){a.loadingModel=!0,n.findOneWithCallback(a.policy.model_id,function(e){a.loadingModel=!1,a.policy.model=e})}function r(e,t){a.policy=t,c()}var a=this;a.policy=o,a.editBasic=!1,a.showPerimeters=!1,a.showData=!1,a.showRules=!1,a.showAssignments=!1,a.showPart=i,function(){c()}();var l={"event:policyUpdatedSuccess":t.$on("event:policyUpdatedSuccess",r)};for(var s in l)e.$on("$destroy",l[s])}angular.module("moon").controller("PolicyEditController",e),e.$inject=["$scope","$rootScope","policy","modelService"]}(),function(){"use strict";function e(){return{templateUrl:"html/policy/edit/policy-edit-basic.tpl.html",bindToController:!0,controller:t,controllerAs:"edit",scope:{policy:"="},restrict:"E",replace:!0}}function t(e,t,o,n,i,c,r){function a(){r.findAllWithCallBack(l)}function l(e){u.models=e,_.each(e,function(e){e.id===u.policy.model_id&&(u.selectedModel=e)}),u.modelsLoading=!1}function s(){function r(t){var o=c.transformOne(t,"policies");i("moon.policy.edit.basic.success",{policyName:o.name}).then(function(e){n.alertSuccess(e)}),u.loading=!1,e.$emit("event:policyUpdatedSuccess",o)}function a(e){i("moon.policy.edit.basic.error",{policyName:u.policy.name}).then(function(e){n.alertError(e)}),u.loading=!1}o.isInvalid(u.form)?o.checkFieldsValidity(u.form):(u.loading=!0,delete u.policyToEdit.model,u.policyToEdit.model_id=u.selectedModel.id,t.update(u.policyToEdit,r,a))}function d(){u.policyToEdit=angular.copy(u.policy)}var u=this;u.editPolicy=s,u.init=d,u.form={},u.modelsLoading=!0,function(){u.policy=e.edit.policy,u.policyToEdit=angular.copy(u.policy),console.log(u.policyToEdit),a()}()}angular.module("moon").directive("moonPolicyEditBasic",e),e.$inject=[],angular.module("moon").controller("moonPolicyEditBasicController",t),t.$inject=["$scope","policyService","formService","alertService","$translate","utilService","modelService"]}(),function(){"use strict";function e(e,t,o,n,i,c){function r(){function c(n){var i=n.project;t("moon.project.add.success",{projectName:i.name}).then(function(e){o.alertSuccess(e)}),a.loading=!1,e.$emit("event:projectCreatedSuccess",i)}function r(n){t("moon.project.add.error",{projectName:a.project.project.name}).then(function(e){o.alertError(e)}),a.loading=!1,e.$emit("event:projectCreatedError",a.project)}n.isInvalid(a.form)?n.checkFieldsValidity(a.form):(a.loading=!0,i.data.projects.create({},a.project,c,r))}var a=this;a.form={},a.loading=!1,a.project={project:{name:null,description:null,enabled:!0,domain:c.DOMAIN.DEFAULT}},a.create=r}angular.module("moon").controller("ProjectAddController",e),e.$inject=["$scope","$translate","alertService","formService","projectService","DEFAULT_CST"]}(),function(){"use strict";function e(e,t,o,n,i){function c(){i.findAllWithCallBack(function(e){d.pdps=e,i.mapPdpsToProject(d.project,d.pdps),d.loadingPDP=!1})}function r(){return _.has(d.project,"pdp")}function a(){d.loading=!0,r()?l(s):s()}function l(n){function c(n){t("moon.project.remove.mapping.remove.error",{pdpName:r}).then(function(e){o.alertError(e)}),d.loading=!1,e.$emit("event:projectDeletedError",d.project)}var r=unmap.project.pdp.name;i.unMap(unmap.project,n,c)}function s(){function i(n){t("moon.project.remove.success",{projectName:d.project.name}).then(function(e){o.alertSuccess(e)}),d.loading=!1,e.$emit("event:projectDeletedSuccess",d.project)}function c(n){t("moon.project.remove.error",{projectName:d.project.name,errorCode:n.data.error.code,message:n.data.error.message}).then(function(e){o.alertError(e)}),d.loading=!1,e.$emit("event:projectDeletedError",d.project)}n.data.projects.remove({project_id:d.project.id},i,c)}var d=this;d.project=e.project,d.loading=!1,d.loadingPDP=!0,d.remove=a,d.isProjectMapped=r,d.pdps=[],function(){c()}()}angular.module("moon").controller("ProjectDeleteController",e),e.$inject=["$scope","$translate","alertService","projectService","pdpService"]}(),function(){"use strict";function e(e,t,o,n,i){this.project=t.project}angular.module("moon").controller("ProjectViewController",e),e.$inject=["$q","$scope","$translate","alertService","projectService"]}(),function(){"use strict";function e(e){function t(t){e.pop("error",null,t,5e3)}function o(t){e.pop("success",null,t,5e3)}function n(t){e.pop("note",null,t,5e3)}var i={};return i.alertError=t,i.alertSuccess=o,i.alertInfo=n,i}angular.module("moon").factory("alertService",e),e.$inject=["toaster"]}(),function(){"use strict";function e(){function e(){var e,t=navigator.userAgent,o=t.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i)||[];return/trident/i.test(o[1])?(e=/\brv[ :]+(\d+)/g.exec(t)||[], +"IE "+(e[1]||"")):"Chrome"===o[1]&&null!=(e=t.match(/\bOPR\/(\d+)/))?"Opera "+e[1]:(o=o[2]?[o[1],o[2]]:[navigator.appName,navigator.appVersion,"-?"],null!=(e=t.match(/version\/(\d+)/i))&&o.splice(1,1,e[1]),o.join(" "))}var t={};return t.sayWho=e,t}angular.module("moon").factory("browserService",e)}(),function(){"use strict";function e(){function e(e){return e.$invalid}function t(e){var t=_.keys(e.$error);_(t).each(function(t){var o=_.values(e.$error[t]);_(o).each(function(e){e.$dirty=!0,e.$setValidity(t,!1)})})}var o={};return o.isInvalid=e,o.checkFieldsValidity=t,o}angular.module("moon").factory("formService",e)}(),function(){"use strict";function e(e){function t(){return e.includes("moon.project")}function o(){return e.includes("moon.pdp")}function n(){return e.includes("moon.policy")}function i(){return e.includes("moon.logs")}function c(){return e.includes("moon.model")}var r={};return r.isProjectTabActive=t,r.isPDPTabActive=o,r.isPolicyTabActive=n,r.isLogsTabActive=i,r.isModelTabActive=c,r}angular.module("moon").factory("menuService",e),e.$inject=["$state"]}(),function(){"use strict";function e(e,t){function o(o){switch(o){case e.TYPE.POLICY:default:return t.findAll()}}var n={};return n.findAll=o,n}angular.module("moon").factory("securityPipelineService",e),e.$inject=["SECURITY_PIPELINE_CST","policyService"]}(),function(){"use strict";function e(){return{transform:function(e,t){var o=[];return _.each(e[t],function(e,t){e.id=t,o.push(e)}),o},transformOne:function(e,t){var o=[];return _.each(e[t],function(e,t){e.id=t,o.push(e)}),o[0]}}}angular.module("moon").factory("utilService",e),e.$inject=[]}(),function(){"use strict";function e(e){return{version:e("version.json",{},{get:{method:"GET",isArray:!1}})}}angular.module("moon").factory("versionService",e),e.$inject=["$resource"]}(),function(){"use strict";function e(e,t,o,n){function i(e,t){_.each(e,function(e){return c(e,t)})}function c(e,t){if(_.isNull(e.keystone_project_id))return!1;var o=_.findIndex(t,function(t){return e.id===t.keystone_project_id});return-1!==o&&(e.pdp=t[o],!0)}return{data:{pdp:t(o.PDP+":pdp_id",{},{query:{method:"GET",isArray:!1},get:{method:"GET",isArray:!1},create:{method:"POST"},update:{method:"PATCH"},remove:{method:"DELETE"}})},findAll:function(){return this.data.pdp.query().$promise.then(function(e){return n.transform(e,"pdps")})},findAllWithCallBack:function(e){return this.data.pdp.query().$promise.then(function(t){e(n.transform(t,"pdps"))})},findOne:function(e){return this.data.pdp.get({pdp_id:e}).$promise.then(function(e){return n.transformOne(e,"pdps")})},unMap:function(e,t,o){e.keystone_project_id=null,_.has(e,"project")&&delete e.project,this.data.pdp.update({pdp_id:e.id},e,t,o)},map:function(e,t,o,n){e.keystone_project_id=t,this.data.pdp.update({pdp_id:e.id},e,o,n)},update:function(e,t,o){this.data.pdp.update({pdp_id:e.id},e,t,o)},mapPdpsToProjects:i,mapPdpsToProject:c}}angular.module("moon").factory("pdpService",e),e.$inject=["$q","$resource","REST_URI","utilService"]}(),function(){"use strict";function e(e,t,o,n,i){function c(){return _.has(o,"currentUser")}function r(){delete o.currentUser,n.defaults.headers.common["X-Auth-Token"]="",i.path("/")}function a(){return o.currentUser}function l(){return o.currentUser.connectionToken}function s(e){n.defaults.headers.common["X-Auth-Token"]=e}return{data:e(t.KEYSTONE+"auth/tokens",{},{login:{method:"POST",transformResponse:function(e,t){var o={};return o.data=angular.fromJson(e),o.headers=t(),o}},logout:{method:"DELETE"}}),Login:function(e,t,n){var i={auth:{identity:{methods:["password"],password:{user:{name:e.username,domain:{name:"Default"},password:e.password}}},scope:{project:{name:"admin",domain:{name:"Default"}}}}};this.data.login({},i,function(e){o.currentUser=e.data,o.currentUser.connectionToken=e.headers["x-subject-token"],s(e.headers["x-subject-token"]),t()},n)},IsConnected:c,SetTokenHeader:s,GetTokenHeader:l,GetUser:a,Logout:r}}angular.module("moon").factory("authenticationService",e),e.$inject=["$resource","REST_URI","$sessionStorage","$http","$location"]}(),function(){"use strict";function e(e){return{data:{image:e("./pip/nova/images",{},{query:{method:"GET",isArray:!1}}),flavor:e("./pip/nova/flavors",{},{query:{method:"GET",isArray:!1}})}}}angular.module("moon").factory("novaService",e),e.$inject=["$resource"]}(),function(){"use strict";function e(e,t){return{data:{projects:e(t.KEYSTONE+"projects/:project_id",{},{query:{method:"GET",isArray:!1},get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"}})},findOne:function(e,t){return this.data.projects.get({project_id:e}).$promise.then(function(e){t(e.project)})},findAll:function(){return this.data.projects.query().$promise.then(function(e){var t=[];return _.each(e.projects,function(e){t.push(e)}),t})}}}angular.module("moon").factory("projectService",e),e.$inject=["$resource","REST_URI"]}(),function(){"use strict";function e(){return{templateUrl:"html/model/edit/metadata/metadata-edit.tpl.html",bindToController:!0,controller:t,controllerAs:"edit",scope:{metaDataType:"=",metaRule:"="},restrict:"E",replace:!0}}function t(e,t,o,n,i,c,r,a){function l(){function e(e){g.list=e}switch(g.metaDataType){case o.TYPE.SUBJECT:t.subject.findAllWithCallback(e);break;case o.TYPE.OBJECT:t.object.findAllWithCallback(e);break;case o.TYPE.ACTION:t.action.findAllWithCallback(e);break;default:g.list=[]}}function s(){function t(t){i("moon.model.metarules.update.success",{metaRuleName:l.name}).then(function(e){n.alertSuccess(e)}),l=a.transformOne(t,"meta_rules"),angular.copy(l,g.metaRule),e.$emit("event:updateMetaRuleFromMetaDataAddSuccess",g.metaRule),f()}function c(e){i("moon.model.metarules.update.error",{metaRuleName:l.name,reason:e.message}).then(function(e){n.alertError(e)}),f()}if(g.selectedMetaData){var l=angular.copy(g.metaRule);switch(g.metaDataType){case o.TYPE.SUBJECT:l.subject_categories.push(g.selectedMetaData.id);break;case o.TYPE.OBJECT:l.object_categories.push(g.selectedMetaData.id);break;case o.TYPE.ACTION:l.action_categories.push(g.selectedMetaData.id)}r.update(l,t,c)}}function d(){function e(e){var t={};switch(g.metaDataType){case o.TYPE.SUBJECT:t=a.transformOne(e,"subject_categories");break;case o.TYPE.OBJECT:t=a.transformOne(e,"object_categories");break;case o.TYPE.ACTION:t=a.transformOne(e,"action_categories")}i("moon.model.metadata.edit.create.success",{name:t.name}).then(function(e){n.alertSuccess(e)}),f(),g.list.push(t),h()}function r(e){i("moon.model.metadata.edit.create.error",{name:l.name}).then(function(e){n.alertError(e)}),f()}if(c.isInvalid(g.form))c.checkFieldsValidity(g.form);else{p();var l=angular.copy(g.metaData);switch(g.metaDataType){case o.TYPE.SUBJECT:t.subject.add(l,e,r);break;case o.TYPE.OBJECT:t.object.add(l,e,r);break;case o.TYPE.ACTION:t.action.add(l,e,r)}}}function u(){function c(t){i("moon.model.metadata.edit.delete.success",{name:s.name}).then(function(e){n.alertSuccess(e)}),r.findOneWithMetaData(g.metaRule.id).then(function(t){angular.copy(t,g.metaRule),m(),l(),f(),e.$emit("event:deleteMetaDataFromMetaDataAddSuccess",g.metaRule)})}function a(e){i("moon.model.metadata.edit.delete.error",{name:s.name}).then(function(e){n.alertError(e)}),f()}if(g.selectedMetaData){p();var s=angular.copy(g.selectedMetaData);switch(g.metaDataType){case o.TYPE.SUBJECT:t.subject.delete(s,c,a);break;case o.TYPE.OBJECT:t.object.delete(s,c,a);break;case o.TYPE.ACTION:t.action.delete(s,c,a)}}}function m(){delete g.selectedMetaData}function p(){g.loading=!0}function f(){g.loading=!1}function h(){g.fromList=!0}var g=this;g.metaDataType=e.edit.metaDataType,g.metaRule=e.edit.metaRule,g.fromList=!0,g.form={},g.metaData={name:null,description:null},g.list=[],g.create=d,g.addToMetaRule=s,g.deleteMetaData=u,l()}angular.module("moon").directive("moonMetaDataEdit",e),e.$inject=[],angular.module("moon").controller("moonMetaDataEditController",t),t.$inject=["$scope","metaDataService","META_DATA_CST","alertService","$translate","formService","metaRuleService","utilService"]}(),function(){"use strict";function e(){return{templateUrl:"html/model/edit/metadata/metadata-list.tpl.html",bindToController:!0,controller:t,controllerAs:"list",scope:{metaRule:"=",editMode:"="},restrict:"E",replace:!0}}function t(e,t,o,n,i,c,r,a){function l(){s(),d(),u()}function s(){j.loadingCatSub=!0,o.subject.findSomeWithCallback(j.metaRule.subject_categories,function(e){j.catSub=e,j.loadingCatSub=!1})}function d(){j.loadingCatObj=!0,o.object.findSomeWithCallback(j.metaRule.object_categories,function(e){j.catObj=e,j.loadingCatObj=!1})}function u(){j.loadingCatAct=!0,o.action.findSomeWithCallback(j.metaRule.action_categories,function(e){j.catAct=e,j.loadingCatAct=!1})}function m(e){function t(t){n("moon.model.metarules.update.success",{metaRuleName:j.metaRule.name}).then(function(e){i.alertSuccess(e)}),r=c.findMetaDataFromMetaRule(a.transformOne(t,"meta_rules")),angular.copy(r,j.metaRule),l(),e.loader=!1}function o(t){n("moon.model.metarules.update.error",{metaRuleName:j.metaRule.name,reason:t.message}).then(function(e){i.alertError(e)}),e.loader=!1}e.loader=!0;var r=angular.copy(j.metaRule);r.subject_categories=_.without(r.subject_categories,e.id),c.update(r,t,o)}function p(e){function t(t){n("moon.model.metarules.update.success",{metaRuleName:j.metaRule.name}).then(function(e){i.alertSuccess(e)}),r=c.findMetaDataFromMetaRule(a.transformOne(t,"meta_rules")),angular.copy(r,j.metaRule),l(),e.loader=!1}function o(t){n("moon.model.metarules.update.error",{metaRuleName:j.metaRule.name,reason:t.message}).then(function(e){i.alertError(e)}),e.loader=!1}e.loader=!0;var r=angular.copy(j.metaRule);r.object_categories=_.without(r.object_categories,e.id),c.update(r,t,o)}function f(e){function t(t){n("moon.model.metarules.update.success",{metaRuleName:j.metaRule.name}).then(function(e){i.alertSuccess(e)}),r=c.findMetaDataFromMetaRule(a.transformOne(t,"meta_rules")),angular.copy(r,j.metaRule),l(),e.loader=!1}function o(t){n("moon.model.metarules.update.error",{metaRuleName:j.metaRule.name,reason:t.message}).then(function(e){i.alertError(e)}),e.loader=!1}e.loader=!0;var r=angular.copy(j.metaRule);r.action_categories=_.without(r.action_categories,e.id),c.update(r,t,o)}function h(){return j.catSub?j.catSub:[]}function g(){return j.catObj?j.catObj:[]}function y(){return j.catAct?j.catAct:[]}function v(e,t){j.metaRule=t,l()}function b(e,t){j.metaRule=t,l()}var j=this;j.metaRule=e.list.metaRule,j.editMode=e.list.editMode,j.shortDisplay=e.list.shortDisplay,j.typeOfSubject=r.TYPE.SUBJECT,j.typeOfObject=r.TYPE.OBJECT,j.typeOfAction=r.TYPE.ACTION,j.unMapSub=m,j.unMapObj=p,j.unMapAct=f,j.getSubjectCategories=h,j.getObjectCategories=g,j.getActionCategories=y,l();var S={"event:updateMetaRuleFromMetaDataAddSuccess":t.$on("event:updateMetaRuleFromMetaDataAddSuccess",v),"event:deleteMetaDataFromMetaDataAddSuccess":t.$on("event:deleteMetaDataFromMetaDataAddSuccess",b)};for(var T in S)e.$on("$destroy",S[T])}angular.module("moon").directive("moonMetaDataList",e),e.$inject=[],angular.module("moon").controller("moonMetaDataListController",t),t.$inject=["$scope","$rootScope","metaDataService","$translate","alertService","metaRuleService","META_DATA_CST","utilService"]}(),function(){"use strict";function e(){return{templateUrl:"html/model/edit/metarules/metarules-list.tpl.html",bindToController:!0,controller:t,controllerAs:"list",scope:{editMode:"=",mappedModel:"="},restrict:"E",replace:!0}}function t(e,t,o,n,i,c){function r(){return _.table=new o({page:1,count:10,sorting:{name:"asc"}},{total:function(){return _.getMetaRules().length},getData:function(e,t){var o=t.sorting()?n("orderBy")(_.getMetaRules(),t.orderBy()):_.getMetaRules();e.resolve(o.slice((t.page()-1)*t.count(),t.page()*t.count()))},$scope:{$data:{}}}),_.table}function a(){return _.metaRules?_.metaRules:[]}function l(){return _.getMetaRules().length>0}function s(e){e.id===u().id?(_.showDetailValue=!1,_.subject_list=[],_.object_list=[],_.action_list=[]):(_.subject_list=e.subject_categories_values,_.object_list=e.object_categories_values,_.action_list=e.action_categories_values,_.showDetailValue=e)}function d(e){_.edit.modal.$scope.metaRule=e,_.edit.modal.$promise.then(_.edit.modal.show)}function u(){return _.showDetailValue}function m(){return _.subject_list}function p(){return _.object_list}function f(){return _.action_list}function h(){_.map.modal.$scope.model=_.model,_.map.modal.$promise.then(_.map.modal.show)}function g(){_.metaRules=_.model.meta_rules_values,_.table.total(_.getMetaRules().length),_.table.reload()}function y(e,t){_.model=t,g(),_.map.modal.hide()}function v(e){_.unmap.modal.$scope.model=_.model,_.unmap.modal.$scope.metaRule=e,_.unmap.modal.$promise.then(_.unmap.modal.show)}function b(e,t){_.model=t,c.findSomeWithCallback(_.model.meta_rules,function(e){_.model.meta_rules_values=e,g(),_.unmap.modal.hide()})}function j(e){_.unmap.modal.hide()}var _=this;_.table={},_.editMode=e.list.editMode,_.model=e.list.mappedModel,_.metaRules=_.model.meta_rules_values,_.getMetaRules=a,_.hasMetaRules=l,_.showDetail=s,_.getSubjectList=m,_.getObjectList=p,_.getActionlist=f,_.getShowDetailValue=u,_.showDetailValue=!1,_.subject_list=[],_.object_list=[],_.action_list=[],_.edit={modal:i({template:"html/model/edit/metarules/action/metarules-edit.tpl.html",show:!1}),showModal:d},_.map={modal:i({template:"html/model/edit/metarules/action/mapping/metarules-map.tpl.html",show:!1}),showModal:h},_.unmap={modal:i({template:"html/model/edit/metarules/action/mapping/metarules-unmap.tpl.html",show:!1}),showModal:v},function(){r()}();var S={"event:metaRuleMapToModelSuccess":t.$on("event:metaRuleMapToModelSuccess",y),"event:metaRuleUnMappedToModelSuccess":t.$on("event:metaRuleUnMappedToModelSuccess",b),"event:metaRuleUnMappedToModelError":t.$on("event:metaRuleUnMappedToModelError",j)};for(var T in S)e.$on("$destroy",S[T]);e.$watch("list.editMode",function(e,t){_.showDetailValue=!1})}angular.module("moon").directive("moonMetaRulesList",e),e.$inject=[],angular.module("moon").controller("moonMetaRulesListController",t),t.$inject=["$scope","$rootScope","NgTableParams","$filter","$modal","metaRuleService"]}(),function(){"use strict";function e(e,t,o,n,i,c,r){function a(){s.policiesLoading=!0,i.findAllWithCallback(function(e){s.policies=e,s.policiesLoading=!1})}function l(){function i(n){var i=r.transformOne(n,"pdps");o("moon.policy.map.success",{pdpName:i.name,policyName:s.selectedPolicy.name}).then(function(e){t.alertSuccess(e)}),s.mappingLoading=!1,e.$emit("event:policyMapToPdpSuccess",i)}function a(n){o("moon.policy.map.error",{pdpName:s.pdp.name,policyName:s.selectedPolicy.name}).then(function(e){t.alertError(e)}),s.mappingLoading=!1,e.$emit("event:policyMapToPdpError")}if(n.isInvalid(s.form))n.checkFieldsValidity(s.form);else{s.mappingLoading=!0;var l=angular.copy(s.pdp);l.security_pipeline.push(s.selectedPolicy.id),c.update(l,i,a)}}var s=this;s.pdps=[],s.pdp=e.pdp,s.addPolicyToList=!1,s.map=l,function(){a()}()}angular.module("moon").controller("PolicyMapController",e),e.$inject=["$scope","alertService","$translate","formService","policyService","pdpService","utilService"]}(),function(){"use strict";function e(e,t,o,n,i){function c(){function c(n){t("moon.policy.unmap.success",{pdpName:r.pdp.name,policyName:r.policy.name}).then(function(e){o.alertSuccess(e)}),r.unMappingLoading=!1,e.$emit("event:policyUnMappedToPdpSuccess",i.transformOne(n,"pdps"))}function a(n){t("moon.policy.unmap.error",{pdpName:r.pdp.name,policyName:r.policy.name}).then(function(e){o.alertError(e)}),r.unMappingLoading=!1,e.$emit("event:policyUnMappedToPdpError")}r.unMappingLoading=!0;var l=angular.copy(r.pdp);l.security_pipeline=_.without(l.security_pipeline,r.policy.id),n.update(l,c,a)}var r=this;r.pdp=e.pdp,r.policy=e.policy,r.unMappingLoading=!1,r.unmap=c}angular.module("moon").controller("PolicyUnMapController",e),e.$inject=["$scope","$translate","alertService","pdpService","utilService"]}(),function(){"use strict";function e(e,t,o,n,i){function c(){i.findAllWithCallBack(r)}function r(e){l.pdps=_.filter(e,function(e){return _.isNull(e.keystone_project_id)}),l.pdpsLoading=!1}function a(){function c(n){l.project.pdp=l.selectedPDP,t("moon.project.map.success",{projectName:l.project.name,pdpName:l.selectedPDP.name}).then(function(e){o.alertSuccess(e)}),l.mappingLoading=!1,e.$emit("event:projectMappedSuccess",l.project)}function r(n){t("moon.project.map.error",{projectName:l.project.name,pdpName:l.selectedPDP.name}).then(function(e){o.alertError(e)}),l.mappingLoading=!1,e.$emit("event:projectMappedError",l.project)}n.isInvalid(l.form)?n.checkFieldsValidity(l.form):(l.mappingLoading=!0,i.map(l.selectedPDP,l.project.id,c,r))}var l=this;l.form={},l.project=e.project,l.pdps=[],l.pdpsLoading=!0,l.selectedPDP=null,l.map=a,function(){c()}()}angular.module("moon").controller("ProjectMapController",e),e.$inject=["$scope","$translate","alertService","formService","pdpService"]}(),function(){"use strict";function e(e,t,o,n){function i(){function i(n){t("moon.project.unmap.success",{projectName:c.project.name,pdpName:a}).then(function(e){o.alertSuccess(e)}),c.unMappingLoading=!1,delete c.project.mapping,delete c.project.pdp,e.$emit("event:projectUnmappedSuccess",c.project)}function r(n){t("moon.project.unmap.error",{projectName:c.project.name,pdpName:a}).then(function(e){o.alertError(e)}),c.unMappingLoading=!1,e.$emit("event:projectUnmappedError",c.project)}c.unMappingLoading=!0;var a=c.project.pdp.name;n.unMap(c.project.pdp,i,r)}var c=this;c.project=e.project,c.unMappingLoading=!1,c.unmap=i}angular.module("moon").controller("ProjectUnMapController",e),e.$inject=["$scope","$translate","alertService","pdpService"]}(),function(){"use strict";function e(e,t,o,n){return{data:e(t.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(e){return n.transform(e,"models")})},findAllWithCallBack:function(e){return this.data.query().$promise.then(function(t){e(n.transform(t,"models"))})},findOneWithCallback:function(e,t){return this.data.get({model_id:e}).$promise.then(function(e){t(n.transformOne(e,"models"))})},findOneWithMetaRules:function(e){return this.data.get({model_id:e}).$promise.then(function(t){var i=n.transformOne(t,"models");return i.meta_rules.length>0?o.findSomeWithMetaData(i.meta_rules).then(function(t){return i.meta_rules_values=t,i.id=e,i}):(i.meta_rules_values=[],i.id=e),i})},delete:function(e,t,o){delete e.meta_rules_values,this.data.remove({model_id:e.id},e,t,o)},update:function(e,t,o){delete e.meta_rules_values,this.data.update({model_id:e.id},e,t,o)}}}angular.module("moon").factory("modelService",e),e.$inject=["$resource","REST_URI","metaRuleService","utilService"]}(),function(){"use strict";function e(e,t,o,n){var i={subject:e(t.METADATA.subject+":subject_id",{},{get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"}}),object:e(t.METADATA.object+":object_id",{},{get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"}}),action:e(t.METADATA.action+":action_id",{},{get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"}})};return{subject:{findOne:function(e,t){i.subject.get({subject_id:e}).$promise.then(function(e){t(n.transformOne(e,"subject_categories"))})},findOneReturningPromise:function(e){return i.subject.get({subject_id:e}).$promise},findSome:function(e){var t=this;if(0===e.length)return[];var i=_(e).map(function(e){return t.findOneReturningPromise(e)});return o.all(i).then(function(e){return _(e).map(function(e){return n.transformOne(e,"subject_categories")})})},findSomeWithCallback:function(e,t){var i=this;0===e.length&&t([]);var c=_(e).map(function(e){return i.findOneReturningPromise(e)});o.all(c).then(function(e){t(_(e).map(function(e){return n.transformOne(e,"subject_categories")}))})},findAll:function(){return i.subject.get().$promise.then(function(e){return n.transform(e,"subject_categories")})},findAllWithCallback:function(e){return i.subject.get().$promise.then(function(t){e(n.transform(t,"subject_categories"))})},delete:function(e,t,o){i.subject.remove({subject_id:e.id},e,t,o)},add:function(e,t,o){i.subject.create({},e,t,o)}},object:{findOne:function(e,t){i.object.get({object_id:e}).$promise.then(function(e){t(n.transformOne(e,"object_categories"))})},findOneReturningPromise:function(e){return i.object.get({object_id:e}).$promise},findSome:function(e){var t=this;if(0===e.length)return[];var i=_(e).map(function(e){return t.findOneReturningPromise(e)});return o.all(i).then(function(e){return _(e).map(function(e){return n.transformOne(e,"object_categories")})})},findSomeWithCallback:function(e,t){var i=this;0===e.length&&t([]);var c=_(e).map(function(e){return i.findOneReturningPromise(e)});o.all(c).then(function(e){t(_(e).map(function(e){return n.transformOne(e,"object_categories")}))})},findAll:function(){return i.object.get().$promise.then(function(e){return n.transform(e,"object_categories")})},findAllWithCallback:function(e){return i.object.get().$promise.then(function(t){e(n.transform(t,"object_categories"))})},delete:function(e,t,o){i.object.remove({object_id:e.id},e,t,o)},add:function(e,t,o){i.object.create({},e,t,o)}},action:{findOne:function(e,t){i.action.get({action_id:e}).$promise.then(function(e){t(n.transformOne(e,"action_categories"))})},findOneReturningPromise:function(e){return i.action.get({action_id:e}).$promise},findSome:function(e){var t=this;if(0===e.length)return[];var i=_(e).map(function(e){return t.findOneReturningPromise(e)});return o.all(i).then(function(e){return _(e).map(function(e){return n.transformOne(e,"action_categories")})})},findSomeWithCallback:function(e,t){var i=this;0===e.length&&t([]);var c=_(e).map(function(e){return i.findOneReturningPromise(e)});o.all(c).then(function(e){t(_(e).map(function(e){return n.transformOne(e,"action_categories")}))})},findAll:function(){return i.action.get().$promise.then(function(e){return n.transform(e,"action_categories")})},findAllWithCallback:function(e){return i.action.get().$promise.then(function(t){e(n.transform(t,"action_categories"))})},delete:function(e,t,o){i.action.remove({action_id:e.id},e,t,o)},add:function(e,t,o){i.action.create({},e,t,o)}}}}angular.module("moon").factory("metaDataService",e),e.$inject=["$resource","REST_URI","$q","utilService"]}(),function(){"use strict";function e(e,t,o,n,i){return{data:e(t.METARULES+":metarule_id",{},{query:{method:"GET"},get:{method:"GET",isArray:!1},update:{method:"PATCH"},create:{method:"POST"},remove:{method:"DELETE"}}),findAll:function(){return this.data.query().$promise.then(function(e){return i.transform(e,"meta_rules")})},findAllWithCallback:function(e){this.data.query().$promise.then(function(t){e(i.transform(t,"meta_rules"))})},findSomeWithMetaData:function(e){var t=this;if(0===e.length)return[];var o=_(e).map(function(e){return t.findOneReturningPromise(e)});return n.all(o).then(function(e){return _(e).map(function(e){var o=i.transformOne(e,"meta_rules");return o=t.findMetaDataFromMetaRule(o)})})},findSomeWithCallback:function(e,t){var o=this;if(0===e.length)return t([]);var c=_(e).map(function(e){return o.findOneReturningPromise(e)});return n.all(c).then(function(e){t(_(e).map(function(e){return i.transformOne(e,"meta_rules")}))})},findOneReturningPromise:function(e){return this.data.get({metarule_id:e}).$promise},findOne:function(e){return this.data.get({metarule_id:e}).$promise.then(function(e){return i.transformOne(e,"meta_rules")})},findOneWithCallback:function(e,t){this.data.get({metarule_id:e}).$promise.then(function(e){t(i.transformOne(e,"meta_rules"))})},findOneWithMetaData:function(e){var t=this;return this.data.get({metarule_id:e}).$promise.then(function(e){var o=i.transformOne(e,"meta_rules");return o=t.findMetaDataFromMetaRule(o)})},findMetaDataFromMetaRule:function(e){return e.subject_categories.length>0?o.subject.findSome(e.subject_categories).then(function(t){e.subject_categories_values=t}):e.subject_categories_values=[],e.object_categories.length>0?o.object.findSome(e.object_categories).then(function(t){e.object_categories_values=t}):e.object_categories_values=[],e.action_categories.length>0?o.action.findSome(e.action_categories).then(function(t){e.action_categories_values=t}):e.action_categories_values=[],e},delete:function(e,t,o){this.data.remove({metarule_id:e.id},e,t,o)},update:function(e,t,o){delete e.subject_categories_values,delete e.object_categories_values,delete e.action_categories_values,this.data.update({metarule_id:e.id},e,t,o)}}}angular.module("moon").factory("metaRuleService",e),e.$inject=["$resource","REST_URI","metaDataService","$q","utilService"]}(),function(){"use strict";function e(e,t,o,n){return{data:{policy:e(t.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(e){return o.transform(e,"policies")})},findAllWithCallback:function(e){return this.data.policy.query().$promise.then(function(t){e(o.transform(t,"policies"))})},findOneReturningPromise:function(e){return this.data.policy.get({policy_id:e}).$promise},findSomeWithCallback:function(e,t){var i=this;0===e.length&&t([]);var c=_(e).map(function(e){return i.findOneReturningPromise(e)});n.all(c).then(function(e){t(_(e).map(function(e){return o.transformOne(e,"policies")}))})},findOne:function(e){return this.data.policy.get({policy_id:e}).$promise.then(function(e){return o.transformOne(e,"policies")})},update:function(e,t,o){this.data.policy.update({policy_id:e.id},e,t,o)},delete:function(e,t,o){this.data.policy.remove({policy_id:e.id},e,t,o)}}}angular.module("moon").factory("policyService",e),e.$inject=["$resource","REST_URI","utilService","$q"]}(),function(){"use strict";function e(e,t){function o(e,t){angular.copy(t,n.metaRule)}var n=this;n.metaRule=e.metaRule;var i={"event:metaRuleBasicUpdatedSuccess":t.$on("event:metaRuleBasicUpdatedSuccess",o)};for(var c in i)e.$on("$destroy",i[c])}angular.module("moon").controller("MetaRulesEditController",e),e.$inject=["$scope","$rootScope"]}(),function(){"use strict";function e(){return{templateUrl:"html/model/edit/metarules/action/metarules-edit-basic.tpl.html",bindToController:!0,controller:t,controllerAs:"edit",scope:{metaRule:"="},restrict:"E",replace:!0}}function t(e,t,o,n,i,c){function r(){function r(t){var o=c.transformOne(t,"meta_rules");angular.copy(o,l.metaRule),i("moon.model.metarules.edit.basic.success",{metaRuleName:o.name}).then(function(e){n.alertSuccess(e)}),l.loading=!1,e.$emit("event:metaRuleBasicUpdatedSuccess",l.metaRule)}function a(e){i("moon.model.edit.basic.error",{metaRuleName:l.metaRule.name}).then(function(e){n.alertError(e)}),l.loading=!1}o.isInvalid(l.form)?o.checkFieldsValidity(l.form):(l.loading=!0,t.update(l.metaRuleToEdit,r,a))}function a(){l.metaRuleToEdit=angular.copy(l.metaRule)}var l=this;l.editMetaRule=r,l.init=a,l.form={},function(){l.metaRule=e.edit.metaRule,l.metaRuleToEdit=angular.copy(l.metaRule)}()}angular.module("moon").directive("moonMetaRulesEditBasic",e),e.$inject=[],angular.module("moon").controller("moonMetaRulesEditBasicController",t),t.$inject=["$scope","metaRuleService","formService","alertService","$translate","utilService"]}(),function(){"use strict";function e(){return{templateUrl:"html/policy/edit/parameter/assignments/assignments-edit.tpl.html",bindToController:!0,controller:t,controllerAs:"edit",scope:{assignmentsType:"=",policy:"="},restrict:"E",replace:!0}}function t(e,t,o,n,i,c,r,a,l,s,d){function u(){P.assignments={id:null,category_id:null,data_id:null,policy_id:null},p(),h()}function m(){function c(t){var i={};switch(P.assignmentsType){case l.TYPE.SUBJECT:i=r.transformOne(t,"subject_assignments");break;case l.TYPE.OBJECT:i=r.transformOne(t,"object_assignments");break;case l.TYPE.ACTION:i=r.transformOne(t,"action_assignments")}n("moon.policy.assignments.edit.create.success").then(function(e){o.alertSuccess(e)}),s&&i.policy_id===P.policy.id?(e.$emit("event:createAssignmentsFromAssignmentsEditSuccess",P.assignmentsType),u(),E()):s&&(u(),E())}function a(e){n("moon.policy.rules.edit.action.add.create.error").then(function(e){o.alertError(e)}),E()}if(P.assignementsAttributeValid=!0,S(),i.isInvalid(P.form))i.checkFieldsValidity(P.form);else if(P.assignementsAttributeValid){T();var s=!1;P.assignments.id=P.selectedPerimeter.id,P.assignments.category_id=P.selectedCategory.id,P.assignments.policy_id=P.selectedPolicy.id;var d=angular.copy(P.selectedDataList);_.each(d,function(e){P.assignments.data_id=e.id;var o=angular.copy(P.assignments);switch(P.assignmentsType){case l.TYPE.SUBJECT:t.subject.add(o,P.policy.id,c,a);break;case l.TYPE.OBJECT:t.object.add(o,P.policy.id,c,a);break;case l.TYPE.ACTION:t.action.add(o,P.policy.id,c,a)}}),s=!0}}function p(){P.policyList=[],P.loadingPolicies=!0,c.findAllWithCallback(function(e){_.each(e,function(e){e.id===P.policy.id&&(P.selectedPolicy=e)}),P.policyList=e,P.loadingPolicies=!1})}function f(){function e(e){P.perimeterList=e,P.loadingPerimeters=!1}switch(P.perimeterList=[],P.loadingPerimeters=!0,P.assignmentsType){case l.TYPE.SUBJECT:a.subject.findAllFromPolicyWithCallback(P.selectedPolicy.id,e);break;case l.TYPE.OBJECT:a.object.findAllFromPolicyWithCallback(P.selectedPolicy.id,e);break;case l.TYPE.ACTION:a.action.findAllFromPolicyWithCallback(P.selectedPolicy.id,e);break;default:P.perimeterList=[],P.loadingPerimeters=!1}}function h(){function e(e){P.categoryList=e,P.loadingCategories=!1}switch(P.categoryList=[],P.loadingCategories=!0,P.assignmentsType){case l.TYPE.SUBJECT:s.subject.findAllWithCallback(e);break;case l.TYPE.OBJECT:s.object.findAllWithCallback(e);break;case l.TYPE.ACTION:s.action.findAllWithCallback(e);break;default:P.categoryList=[],P.loadingCategories=!1}}function g(e){function t(e){P.dataList=e,P.dataToBeSelected=angular.copy(P.dataList),P.selectedDataList=[],P.loadingData=!1}switch(P.dataList=[],P.dataToBeSelected=[],P.selectedDataList=[],P.loadingData=!0,P.assignmentsType){case l.TYPE.SUBJECT:d.subject.findAllFromCategoriesWithCallback(P.selectedPolicy.id,e,t);break;case l.TYPE.OBJECT:d.object.findAllFromCategoriesWithCallback(P.selectedPolicy.id,e,t);break;case l.TYPE.ACTION:d.action.findAllFromCategoriesWithCallback(P.selectedPolicy.id,e,t);break;default:P.loadingData=!1}}function y(){P.dataToBeSelected=_.without(P.dataToBeSelected,P.selectedData),P.selectedDataList.push(P.selectedData),b()}function v(e){P.dataToBeSelected.push(e),P.selectedDataList=_.without(P.selectedDataList,e)}function b(){P.selectedData=void 0}function j(e){if(_.isUndefined(e))return"(None)";switch(P.assignmentsType){case l.TYPE.SUBJECT:return e.name;case l.TYPE.OBJECT:case l.TYPE.ACTION:return e.value.name;default:return e.name}}function S(){P.selectedDataList.length>=1?P.assignementsAttributeValid=!0:P.assignementsAttributeValid=!1}function T(){P.loading=!0}function E(){P.loading=!1}var P=this;P.assignmentsType=e.edit.assignmentsType,P.policy=e.edit.policy,P.laoading=!1,P.form={},P.policyList=[],P.loadingPolicies=!0,P.categoryList=[],P.loadingCategories=!0,P.perimeterList=[],P.loadingPerimeters=!0,P.dataList=[],P.dataToBeSelected=[],P.selectedDataList=[],P.loadingData=!0,P.assignementsAttributeValid=!0,P.addSelectedData=y,P.removeSelectedData=v,P.getName=j,P.create=m,u(),e.$watch("edit.selectedPolicy",function(e){_.isUndefined(e)||f()}),e.$watch("edit.selectedCategory",function(e){b(),_.isUndefined(e)||g(e.id)})}angular.module("moon").directive("moonAssignmentsEdit",e),e.$inject=[],angular.module("moon").controller("moonAssignmentsEditController",t),t.$inject=["$scope","assignmentsService","alertService","$translate","formService","policyService","utilService","perimeterService","ASSIGNMENTS_CST","metaDataService","dataService"]}(),function(){"use strict";function e(){return{ +templateUrl:"html/policy/edit/parameter/assignments/assignments-list.tpl.html",bindToController:!0,controller:t,controllerAs:"list",scope:{policy:"=",editMode:"="},restrict:"E",replace:!0}}function t(e,t,o,n,i,c,r,a,l,s,d){function u(){m(),p(),f()}function m(){$.loadingSub=!0,o.subject.findAllFromPolicyWithCallback($.policy.id,function(e){$.subjects=e,$.loadingSub=!1})}function p(){$.loadingObj=!0,o.object.findAllFromPolicyWithCallback($.policy.id,function(e){$.objects=e,$.loadingObj=!1})}function f(){$.loadingAct=!0,o.action.findAllFromPolicyWithCallback($.policy.id,function(e){$.actions=e,$.loadingAct=!1})}function h(e,t){function o(t){e.callPerimeterInProgress=!1,e.perimeter=t}if(_.has(e,"perimeter"))return e.perimeter;if(!_.has(e,"callPerimeterInProgress"))switch(e.callPerimeterInProgress=!0,t){case r.TYPE.SUBJECT:s.subject.findOneFromPolicyWithCallback($.policy.id,e.subject_id,o);break;case r.TYPE.OBJECT:s.object.findOneFromPolicyWithCallback($.policy.id,e.object_id,o);break;case r.TYPE.ACTION:s.action.findOneFromPolicyWithCallback($.policy.id,e.action_id,o)}return!1}function g(e,t){function o(t){e.callCategoryInProgress=!1,e.category=t}if(_.has(e,"category"))return e.category;if(!_.has(e,"callCategoryInProgress"))switch(e.callCategoryInProgress=!0,t){case r.TYPE.SUBJECT:l.subject.findOne(e.subject_cat_id,o);break;case r.TYPE.OBJECT:l.object.findOne(e.object_cat_id,o);break;case r.TYPE.ACTION:l.action.findOne(e.action_cat_id,o)}return!1}function y(e,t,o){function n(o){t.assignments_value[e].callDataInProgress=!1,t.assignments_value[e].data=o}if(_.has(t,"assignments_value")||(t.assignments_value=Array.apply(null,new Array(t.assignments.length)).map(function(){return{data:{}}})),_.has(t.assignments_value[e],"callDataInProgress")&&!t.assignments_value[e].callDataInProgress)return t.assignments_value[e].data;if(!_.has(t.assignments_value[e],"callDataInProgress"))switch(t.assignments_value[e].callDataInProgress=!0,o){case r.TYPE.SUBJECT:d.subject.data.findOne($.policy.id,t.category_id,t.assignments[e],n);break;case r.TYPE.OBJECT:d.object.data.findOne($.policy.id,t.category_id,t.assignments[e],n);break;case r.TYPE.ACTION:d.action.data.findOne($.policy.id,t.category_id,t.assignments[e],n)}return!1}function v(e,t){function c(t){n("moon.policy.assignments.subject.delete.success").then(function(e){i.alertSuccess(e)}),m(),e.loader=!1}function r(t){n("moon.policy.assignments.subject.delete.error",{subjectName:e.name,reason:t.message}).then(function(e){i.alertError(e)}),e.loader=!1}e.loader=!0,o.subject.delete($.policy.id,e.subject_id,e.subject_cat_id,t,c,r)}function b(e,t){function c(t){n("moon.policy.assignments.object.delete.success").then(function(e){i.alertSuccess(e)}),p(),e.loader=!1}function r(t){n("moon.policy.assignments.object.delete.error",{objectName:e.name,reason:t.message}).then(function(e){i.alertError(e)}),e.loader=!1}e.loader=!0,o.object.delete($.policy.id,e.object_id,e.object_cat_id,t,c,r)}function j(e,t){function c(t){n("moon.policy.assignments.action.delete.success").then(function(e){i.alertSuccess(e)}),f(),e.loader=!1}function r(t){n("moon.policy.assignments.action.delete.error",{actionName:e.name,reason:t.message}).then(function(e){i.alertError(e)}),e.loader=!1}e.loader=!0,o.action.delete($.policy.id,e.action_id,e.action_cat_id,t,c,r)}function S(){return $.subjects?$.subjects:[]}function T(){return $.objects?$.objects:[]}function E(){return $.actions?$.actions:[]}function P(e,t){switch(t){case r.TYPE.SUBJECT:m();break;case r.TYPE.OBJECT:p();break;case r.TYPE.ACTION:f();break;default:u()}}var $=this;$.policy=e.list.policy,$.editMode=e.list.editMode,$.typeOfSubject=r.TYPE.SUBJECT,$.typeOfObject=r.TYPE.OBJECT,$.typeOfAction=r.TYPE.ACTION,$.deleteSub=v,$.deleteObj=b,$.deleteAct=j,$.getSubjects=S,$.getObjects=T,$.getActions=E,$.getCategoryFromAssignment=g,$.getPerimeterFromAssignment=h,$.getDataFromAssignmentsIndex=y,u();var C={"event:createAssignmentsFromAssignmentsEditSuccess":t.$on("event:createAssignmentsFromAssignmentsEditSuccess",P)};_.each(C,function(t){e.$on("$destroy",C[t])})}angular.module("moon").directive("moonAssignmentsList",e),e.$inject=[],angular.module("moon").controller("moonAssignmentsListController",t),t.$inject=["$scope","$rootScope","assignmentsService","$translate","alertService","policyService","ASSIGNMENTS_CST","utilService","metaDataService","perimeterService","dataService"]}(),function(){"use strict";function e(){return{templateUrl:"html/policy/edit/parameter/data/data-edit.tpl.html",bindToController:!0,controller:t,controllerAs:"edit",scope:{mnDataType:"=",policy:"="},restrict:"E",replace:!0}}function t(e,t,o,n,i,c,r,a,l,s,d){function u(){s.findOneWithCallback(h.policy.model_id,function(e){d.findSomeWithCallback(e.meta_rules,function(e){function t(e){h.categoriesToBeSelected=e}switch(h.dataType){case o.TYPE.SUBJECT:var n=_.reduce(e,function(e,t){return e.concat(t.subject_categories)},[]);l.subject.findSomeWithCallback(n,t);break;case o.TYPE.OBJECT:var i=_.reduce(e,function(e,t){return e.concat(t.object_categories)},[]);l.object.findSomeWithCallback(i,t);break;case o.TYPE.ACTION:var c=_.reduce(e,function(e,t){return e.concat(t.action_categories)},[]);l.action.findSomeWithCallback(c,t);break;default:h.categoriesToBeSelected=[]}})})}function m(){function r(t){var c={},r="";switch(h.dataType){case o.TYPE.SUBJECT:c=a.transformOne(t.subject_data,"data"),r=c.name;break;case o.TYPE.OBJECT:c=a.transformOne(t.object_data,"data"),r=c.value.name;break;case o.TYPE.ACTION:c=a.transformOne(t.action_data,"data"),r=c.value.name}i("moon.policy.data.edit.create.success",{name:r}).then(function(e){n.alertSuccess(e)}),e.$emit("event:createDataFromDataEditSuccess",c,h.dataType),f(),h.list.push(c)}function l(e){i("moon.policy.data.edit.create.error",{name:s.name}).then(function(e){n.alertError(e)}),f()}if(c.isInvalid(h.form))c.checkFieldsValidity(h.form);else{p();var s=angular.copy(h.data);switch(h.dataType){case o.TYPE.SUBJECT:t.subject.add(s,h.policy.id,h.selectedCategory.id,r,l);break;case o.TYPE.OBJECT:t.object.add(s,h.policy.id,h.selectedCategory.id,r,l);break;case o.TYPE.ACTION:t.action.add(s,h.policy.id,h.selectedCategory.id,r,l)}}}function p(){h.loading=!0}function f(){h.loading=!1}var h=this;h.dataType=e.edit.mnDataType,h.policy=e.edit.policy,h.fromList=!1,h.loading=!1,h.form={},h.data={name:null,description:null},h.list=[],h.categoriesToBeSelected=[],h.create=m,function(){function e(e){_.each(e,function(e){e.policy_id!==h.policy.id&&h.list.push(e)})}switch(u(),h.dataType){case o.TYPE.SUBJECT:t.subject.findAllFromPolicyWithCallback(h.policy.id,e);break;case o.TYPE.OBJECT:t.object.findAllFromPolicyWithCallback(h.policy.id,e);break;case o.TYPE.ACTION:t.action.findAllFromPolicyWithCallback(h.policy.id,e);break;default:h.list=[]}}()}angular.module("moon").directive("moonDataEdit",e),e.$inject=[],angular.module("moon").controller("moonDataEditController",t),t.$inject=["$scope","dataService","DATA_CST","alertService","$translate","formService","policyService","utilService","metaDataService","modelService","metaRuleService"]}(),function(){"use strict";function e(){return{templateUrl:"html/policy/edit/parameter/data/data-list.tpl.html",bindToController:!0,controller:t,controllerAs:"list",scope:{policy:"=",editMode:"="},restrict:"E",replace:!0}}function t(e,t,o,n,i,c,r){function a(){S.loadingSub=!0,o.subject.findAllFromPolicyWithCallback(S.policy.id,function(e){S.subjects=e,S.loadingSub=!1})}function l(){S.loadingObj=!0,o.object.findAllFromPolicyWithCallback(S.policy.id,function(e){S.objects=e,S.loadingObj=!1})}function s(){S.loadingAct=!0,o.action.findAllFromPolicyWithCallback(S.policy.id,function(e){S.actions=e,S.loadingAct=!1})}function d(e,t){function o(t){e.callCategoryInProgress=!1,e.category=t}if(_.has(e,"category"))return e.category;if(!_.has(e,"callCategoryInProgress"))switch(e.callCategoryInProgress=!0,t){case c.TYPE.SUBJECT:r.subject.findOne(e.category_id,o);break;case c.TYPE.OBJECT:r.object.findOne(e.category_id,o);break;case c.TYPE.ACTION:r.action.findOne(e.category_id,o)}return!1}function u(e){function t(t){n("moon.policy.data.subject.delete.success",{subjectName:e.name}).then(function(e){i.alertSuccess(e)}),y(e),e.loader=!1}function c(t){n("moon.policy.data.subject.delete.error",{subjectName:e.name,reason:t.message}).then(function(e){i.alertError(e)}),e.loader=!1}e.loader=!0,o.subject.delete(e,S.policy.id,e.category_id,t,c)}function m(e){function t(t){n("moon.policy.data.object.delete.success",{objectName:e.name}).then(function(e){i.alertSuccess(e)}),v(e),e.loader=!1}function c(t){n("moon.policy.data.object.delete.error",{objectName:e.name,reason:t.message}).then(function(e){i.alertError(e)}),e.loader=!1}e.loader=!0,o.object.delete(e,S.policy.id,e.category_id,t,c)}function p(e){function t(t){n("moon.policy.data.action.delete.success",{actionName:e.name}).then(function(e){i.alertSuccess(e)}),b(e),e.loader=!1}function c(t){n("moon.policy.data.action.delete.error",{actionName:e.name,reason:t.message}).then(function(e){i.alertError(e)}),e.loader=!1}e.loader=!0,o.action.delete(e,S.policy.id,e.category_id,t,c)}function f(){return S.subjects?S.subjects:[]}function h(){return S.objects?S.objects:[]}function g(){return S.actions?S.actions:[]}function y(e){S.subjects=_.without(S.subjects,e)}function v(e){S.objects=_.without(S.objects,e)}function b(e){S.actions=_.without(S.actions,e)}function j(e,t,o){switch(o){case c.TYPE.SUBJECT:S.subjects.push(t);break;case c.TYPE.OBJECT:S.objects.push(t);break;case c.TYPE.ACTION:S.actions.push(t)}}var S=this;S.policy=e.list.policy,S.editMode=e.list.editMode,S.typeOfSubject=c.TYPE.SUBJECT,S.typeOfObject=c.TYPE.OBJECT,S.typeOfAction=c.TYPE.ACTION,S.deleteSub=u,S.deleteObj=m,S.deleteAct=p,S.getSubjects=f,S.getObjects=h,S.getActions=g,S.getCategoryFromData=d,function(){a(),l(),s()}();var T={"event:createDataFromDataEditSuccess":t.$on("event:createDataFromDataEditSuccess",j)};_.each(T,function(t){e.$on("$destroy",T[t])})}angular.module("moon").directive("moonDataList",e),e.$inject=[],angular.module("moon").controller("moonDataListController",t),t.$inject=["$scope","$rootScope","dataService","$translate","alertService","DATA_CST","metaDataService"]}(),function(){"use strict";function e(){return{templateUrl:"html/policy/edit/parameter/perimeter/perimeter-edit.tpl.html",bindToController:!0,controller:t,controllerAs:"edit",scope:{perimeterType:"=",policy:"="},restrict:"E",replace:!0}}function t(e,t,o,n,i,c,r,a,l){function s(){function e(e){_.each(e,function(e){-1===_.indexOf(e.policy_list,T.policy.id)&&T.list.push(e)})}switch(d(),T.perimeterType){case n.TYPE.SUBJECT:o.subject.findAllWithCallback(e);break;case n.TYPE.OBJECT:o.object.findAllWithCallback(e);break;case n.TYPE.ACTION:o.action.findAllWithCallback(e);break;default:T.list=[]}}function d(){T.policyList=[],a.findAllWithCallback(function(e){T.policyList=e,T.policiesToBeSelected=angular.copy(T.policyList)})}function u(){T.selectedPolicy&&!_.contains(T.perimeter.policy_list,T.selectedPolicy.id)&&(T.perimeter.policy_list.push(T.selectedPolicy.id),T.selectedPolicyList.push(T.selectedPolicy),T.policiesToBeSelected=_.without(T.policiesToBeSelected,T.selectedPolicy))}function m(){T.perimeter.policy_list=[],T.selectedPolicyList=[],T.policiesToBeSelected=angular.copy(T.policyList)}function p(e){T.policiesToBeSelected.push(e),T.perimeter.policy_list=_.without(T.perimeter.policy_list,e.id),T.selectedPolicyList=_.without(T.selectedPolicyList,e)}function f(){function e(e){c("moon.perimeter.update.success",{policyName:r.name}).then(function(e){i.alertSuccess(e)}),b()}function t(e){c("moon.policy.update.error",{policyName:r.name,reason:e.message}).then(function(e){i.alertError(e)}),b()}if(T.selectedPerimeter){v();var r=T.selectedPerimeter;switch(r.policy_list.push(T.policy.id),T.perimeterType){case n.TYPE.SUBJECT:o.subject.update(r,e,t);break;case n.TYPE.OBJECT:o.object.update(r,e,t);break;case n.TYPE.ACTION:o.action.update(r,e,t)}}}function h(){function t(t){var o={};switch(T.perimeterType){case n.TYPE.SUBJECT:o=l.transformOne(t,"subjects");break;case n.TYPE.OBJECT:o=l.transformOne(t,"objects");break;case n.TYPE.ACTION:o=l.transformOne(t,"actions")}c("moon.policy.perimeter.edit.create.success",{name:o.name}).then(function(e){i.alertSuccess(e)}),b(),-1===_.indexOf(o.policy_list,T.policy.id)?T.list.push(o):e.$emit("event:createAssignmentsFromAssignmentsEditSuccess",o,T.perimeterType),j(),m()}function a(e){c("moon.policy.perimeter.edit.create.error",{name:s.name}).then(function(e){i.alertError(e)}),b()}if(r.isInvalid(T.form))r.checkFieldsValidity(T.form);else{v();var s=angular.copy(T.perimeter);switch(T.perimeterType){case n.TYPE.SUBJECT:o.subject.add(s,t,a);break;case n.TYPE.OBJECT:o.object.add(s,t,a);break;case n.TYPE.ACTION:o.action.add(s,t,a)}}}function g(){function t(t){c("moon.policy.perimeter.edit.delete.success",{name:d.name}).then(function(e){i.alertSuccess(e)}),a.findOneReturningPromise(T.policy.id).then(function(t){T.policy=l.transformOne(t,"policies"),y(),s(),b(),e.$emit("event:deletePerimeterFromPerimeterAddSuccess",T.policy)})}function r(e){c("moon.policy.perimeter.edit.delete.error",{name:d.name}).then(function(e){i.alertError(e)}),b()}if(T.selectedPerimeter){v();var d=angular.copy(T.selectedPerimeter);switch(T.perimeterType){case n.TYPE.SUBJECT:o.subject.delete(d,t,r);break;case n.TYPE.OBJECT:o.object.delete(d,t,r);break;case n.TYPE.ACTION:o.action.delete(d,t,r)}}}function y(){T.list=_.without(T.list,T.selectedPerimeter),delete T.selectedPerimeter}function v(){T.loading=!0}function b(){T.loading=!1}function j(){T.fromList=!0}function S(e,t,o){o===T.perimeterType&&-1===_.indexOf(t.policy_list,T.policy.id)&&T.list.push(t)}var T=this;T.perimeterType=e.edit.perimeterType,T.subjectType=n.TYPE.SUBJECT,T.policy=e.edit.policy,T.fromList=!0,T.loading=!1,T.form={},T.perimeter={name:null,description:null,partner_id:null,policy_list:[],email:null},T.list=[],T.policyList=[],T.policiesToBeSelected=[],T.selectedPolicyList=[],T.create=h,T.addToPolicy=f,T.addPolicyToPerimeter=u,T.clearSelectedPolicies=m,T.removeSelectedPolicy=p,T.deletePerimeter=g,s();var E={"event:unMapPerimeterFromPerimeterList":t.$on("event:unMapPerimeterFromPerimeterList",S)};_.each(E,function(t){e.$on("$destroy",E[t])})}angular.module("moon").directive("moonPerimeterEdit",e),e.$inject=[],angular.module("moon").controller("moonPerimeterEditController",t),t.$inject=["$scope","$rootScope","perimeterService","PERIMETER_CST","alertService","$translate","formService","policyService","utilService"]}(),function(){"use strict";function e(){return{templateUrl:"html/policy/edit/parameter/perimeter/perimeter-list.tpl.html",bindToController:!0,controller:t,controllerAs:"list",scope:{policy:"=",editMode:"="},restrict:"E",replace:!0}}function t(e,t,o,n,i,c){function r(){a(),l(),s()}function a(){v.loadingSub=!0,o.subject.findAllFromPolicyWithCallback(v.policy.id,function(e){v.subjects=e,v.loadingSub=!1})}function l(){v.loadingObj=!0,o.object.findAllFromPolicyWithCallback(v.policy.id,function(e){v.objects=e,v.loadingObj=!1})}function s(){v.loadingAct=!0,o.action.findAllFromPolicyWithCallback(v.policy.id,function(e){v.actions=e,v.loadingAct=!1})}function d(t){function a(o){n("moon.policy.perimeter.update.success",{perimeterName:s.name}).then(function(e){i.alertSuccess(e)}),e.$emit("event:unMapPerimeterFromPerimeterList",t,c.TYPE.SUBJECT),r(),t.loader=!1}function l(e){n("moon.policy.perimeter.update.error",{perimeterName:t.name,reason:e.message}).then(function(e){i.alertError(e)}),t.loader=!1}t.policy_list=_.without(t.policy_list,v.policy.id),t.loader=!0;var s=angular.copy(t);o.subject.unMapPerimeterFromPolicy(v.policy.id,t.id,a,l)}function u(t){function a(o){n("moon.policy.perimeter.update.success",{perimeterName:s.name}).then(function(e){i.alertSuccess(e)}),e.$emit("event:unMapPerimeterFromPerimeterList",t,c.TYPE.OBJECT),r(),t.loader=!1}function l(e){n("moon.policy.perimeter.update.error",{perimeterName:t.name,reason:e.message}).then(function(e){i.alertError(e)}),t.loader=!1}t.policy_list=_.without(t.policy_list,v.policy.id),t.loader=!0;var s=angular.copy(t);o.object.unMapPerimeterFromPolicy(v.policy.id,t.id,a,l)}function m(t){function a(o){n("moon.policy.perimeter.update.success",{perimeterName:s.name}).then(function(e){i.alertSuccess(e)}),e.$emit("event:unMapPerimeterFromPerimeterList",t,c.TYPE.ACTION),r(),t.loader=!1}function l(e){n("moon.policy.perimeter.update.error",{perimeterName:t.name,reason:e.message}).then(function(e){i.alertError(e)}),t.loader=!1}t.policy_list=_.without(t.policy_list,v.policy.id),t.loader=!0;var s=angular.copy(t);o.action.unMapPerimeterFromPolicy(v.policy.id,t.id,a,l)}function p(){return v.subjects?v.subjects:[]}function f(){return v.objects?v.objects:[]}function h(){return v.actions?v.actions:[]}function g(e,t){v.policy=t,r()}function y(e,t,o){switch(o){case c.TYPE.SUBJECT:v.subjects.push(t);break;case c.TYPE.OBJECT:v.objects.push(t);break;case c.TYPE.ACTION:v.actions.push(t)}}var v=this;v.policy=e.list.policy,v.editMode=e.list.editMode,v.typeOfSubject=c.TYPE.SUBJECT,v.typeOfObject=c.TYPE.OBJECT,v.typeOfAction=c.TYPE.ACTION,v.unMapSub=d,v.unMapObj=u,v.unMapAct=m,v.getSubjects=p,v.getObjects=f,v.getActions=h,r();var b={"event:deletePerimeterFromPerimeterAddSuccess":t.$on("event:deletePerimeterFromPerimeterAddSuccess",g),"event:createAssignmentsFromAssignmentsEditSuccess":t.$on("event:createAssignmentsFromAssignmentsEditSuccess",y)};_.each(b,function(t){e.$on("$destroy",b[t])})}angular.module("moon").directive("moonPerimeterList",e),e.$inject=[],angular.module("moon").controller("moonPerimeterListController",t),t.$inject=["$scope","$rootScope","perimeterService","$translate","alertService","PERIMETER_CST"]}(),function(){"use strict";function e(){return{templateUrl:"html/policy/edit/parameter/rules/rules-edit.tpl.html",bindToController:!0,controller:t,controllerAs:"edit",scope:{policy:"="},restrict:"E",replace:!0}}function t(e,t,o,n,i,c,r,a,l,s,d,u){function m(){M.rules={meta_rule_id:null,rule:[],policy_id:null,instructions:'[{"decision": "grant"}]',enabled:!0},R(),p(),E()}function p(){M.policyList=[],c.findAllWithCallback(function(e){_.each(e,function(e){e.id===M.policy.id&&(M.selectedPolicy=e)}),M.policyList=e})}function f(){M.selectedPolicy.meta_rules_values=void 0,s.findOneWithCallback(M.selectedPolicy.model_id,function(e){a.findSomeWithCallback(e.meta_rules,function(e){M.selectedPolicy.meta_rules_values=e})})}function h(e,t,o){l.subject.findSomeWithCallback(e,function(e){M.categories.subject=e,M.categories.loadingSubjects=!1,_.each(M.categories.subject,function(e){d.subject.findAllFromCategoriesWithCallback(M.selectedPolicy.id,e.id,function(e){M.data.subject=e,M.data.loadingSubjects=!1,M.data.subjectsToBeSelected=angular.copy(M.data.subject)})})}),l.object.findSomeWithCallback(t,function(e){M.categories.object=e,M.categories.loadingObjects=!1,_.each(M.categories.object,function(e){d.object.findAllFromCategoriesWithCallback(M.selectedPolicy.id,e.id,function(e){M.data.object=e,M.data.loadingObjects=!1,M.data.objectsToBeSelected=angular.copy(M.data.object)})})}),l.action.findSomeWithCallback(o,function(e){M.categories.action=e,M.categories.loadingActions=!1,_.each(M.categories.action,function(e){d.action.findAllFromCategoriesWithCallback(M.selectedPolicy.id,e.id,function(e){M.data.action=e,M.data.loadingActions=!1,M.data.actionsToBeSelected=angular.copy(M.data.action)})})})}function g(){function c(t){var i=r.transformOne(t,"rules");n("moon.policy.rules.edit.action.add.create.success").then(function(e){o.alertSuccess(e)}),e.$emit("event:createRulesFromDataRulesSuccess",i),m(),T()}function a(e){n("moon.policy.rules.edit.action.add.create.error").then(function(e){o.alertError(e)}),T()}if(M.instructionsValid=!0,M.numberOfSelectedSubjectValid=!0,M.numberOfSelectedObjecttValid=!0,M.numberOfSelectedActionsValid=!0,y(),v(),i.isInvalid(M.form))i.checkFieldsValidity(M.form);else if(M.instructionsValid&&v()){S(),A(),M.rules.meta_rule_id=M.selectedMetaRules.id,M.rules.policy_id=M.selectedPolicy.id;var l=angular.copy(M.rules);l.instructions=JSON.parse(M.rules.instructions),t.add(l,M.policy.id,c,a)}}function y(){b(M.rules.instructions)?M.instructionsValid=!0:M.instructionsValid=!1}function v(){return $(u.TYPE.SUBJECT)?M.numberOfSelectedSubjectValid=!0:M.numberOfSelectedSubjectValid=!1,$(u.TYPE.OBJECT)?M.numberOfSelectedObjecttValid=!0:M.numberOfSelectedObjecttValid=!1,$(u.TYPE.ACTION)?M.numberOfSelectedActionsValid=!0:M.numberOfSelectedActionsValid=!1,M.numberOfSelectedSubjectValid&&M.numberOfSelectedObjecttValid&&M.numberOfSelectedActionsValid}function b(e){return!_.isUndefined(e)&&j(e)}function j(e){var t=null;try{t=JSON.parse(e)}catch(e){return!1}return"object"==typeof t&&null!==t}function S(){M.loading=!0}function T(){M.loading=!1}function E(){M.selectedMetaRules=void 0,P()}function P(){M.selectedSubject=void 0,M.selectedObject=void 0,M.selectedAction=void 0}function $(e){if(!M.selectedMetaRules)return!1;switch(e){case u.TYPE.SUBJECT:return M.data.selectedSubjectsList.length===M.selectedMetaRules.subject_categories.length;case u.TYPE.OBJECT:return M.data.selectedObjectsList.length===M.selectedMetaRules.object_categories.length;case u.TYPE.ACTION:return M.data.selectedActionsList.length===M.selectedMetaRules.action_categories.length}}function C(e){switch(e){case u.TYPE.SUBJECT:if(!M.selectedSubject||$(e)||_.contains(M.data.selectedSubjectsList,M.selectedSubject))return;M.data.selectedSubjectsList.push(M.selectedSubject),M.data.subjectsToBeSelected=_.without(M.data.subjectsToBeSelected,M.selectedSubject);break;case u.TYPE.OBJECT:if(!M.selectedObject||$(e)||_.contains(M.data.selectedObjectsList,M.selectedObject))return;M.data.selectedObjectsList.push(M.selectedObject),M.data.objectsToBeSelected=_.without(M.data.objectsToBeSelected,M.selectedObject);break;case u.TYPE.ACTION:if(!M.selectedAction||$(e)||_.contains(M.data.selectedActionsList,M.selectedAction))return;M.data.selectedActionsList.push(M.selectedAction),M.data.actionsToBeSelected=_.without(M.data.actionsToBeSelected,M.selectedAction)}}function O(e,t){switch(t){case u.TYPE.SUBJECT:M.data.subjectsToBeSelected.push(e),M.data.selectedSubjectsList=_.without(M.data.selectedSubjectsList,e);break;case u.TYPE.OBJECT:M.data.objectsToBeSelected.push(e),M.data.selectedObjectsList=_.without(M.data.selectedObjectsList,e);break;case u.TYPE.ACTION:M.data.actionsToBeSelected.push(e),M.data.selectedActionsList=_.without(M.data.selectedActionsList,e)}}function A(){function e(e){M.rules.rule.push(e.id)}_.each(M.data.selectedSubjectsList,e),_.each(M.data.selectedObjectsList,e),_.each(M.data.selectedActionsList,e)}function R(){M.data={subject:[],loadingSubjects:!0,subjectsToBeSelected:[],selectedSubjectsList:[],subjectCST:u.TYPE.SUBJECT,object:[],loadingObjects:!0,objectsToBeSelected:[],selectedObjectsList:[],objectCST:u.TYPE.OBJECT,action:[],loadingActions:!0,actionsToBeSelected:[],selectedActionsList:[],actionCST:u.TYPE.ACTION}}var M=this;M.policy=e.edit.policy,M.editMode=!0,M.fromList=!1,M.loading=!1,M.form={},M.showDetailselectedMetaRules=!1,M.list=[],M.policyList=[],M.categories={subject:[],loadingSubjects:!0,object:[],loadingObjects:!0,action:[],loadingActions:!0},M.data={},M.create=g,M.addDataToRules=C,M.removeSelectedDataFromRules=O,M.isNumberSelectedDataAtMaximum=$,M.instructionsValid=!0,M.numberOfSelectedSubjectValid=!0,M.numberOfSelectedObjecttValid=!0,M.numberOfSelectedActionsValid=!0,m(),e.$watch("edit.selectedPolicy",function(e){E(),_.isUndefined(e)||f()}),e.$watch("edit.selectedMetaRules",function(e){P(),M.categories={subject:[],loadingSubjects:!0,object:[],loadingObjects:!0,action:[],loadingActions:!0},R(),_.isUndefined(e)||h(e.subject_categories,e.object_categories,e.action_categories)})}angular.module("moon").directive("moonRulesEdit",e),e.$inject=[],angular.module("moon").controller("moonRulesEditController",t),t.$inject=["$scope","rulesService","alertService","$translate","formService","policyService","utilService","metaRuleService","metaDataService","modelService","dataService","DATA_CST"]}(),function(){"use strict";function e(){return{templateUrl:"html/policy/edit/parameter/rules/rules-list.tpl.html",bindToController:!0,controller:t,controllerAs:"list",scope:{policy:"=",editMode:"="},restrict:"E",replace:!0}}function t(e,t,o,n,i,c,r,a,l){function s(){c.findAllFromPolicyWithCallback(T.policy.id,function(e){T.rules=e,T.loadingRules=!1,v()})}function d(){return T.table=new o({page:1,count:10},{total:function(){return T.getRules().length},getData:function(e,t){var o=t.sorting()?n("orderBy")(T.getRules(),t.orderBy()):T.getRules();e.resolve(o.slice((t.page()-1)*t.count(),t.page()*t.count()))},$scope:{$data:{}}}),T.table}function u(e){return _.has(e,"meta_rule")?e.meta_rule:(_.has(e,"callMetaRuleInProgress")||(e.callMetaRuleInProgress=!0,i.findOneWithCallback(e.meta_rule_id,function(t){e.callMetaRuleInProgress=!1,e.meta_rule=t})),!1)}function m(e,t){if(_.has(t,"rule_value")||(t.rule_value=Array.apply(null,new Array(t.rule.length)).map(function(){return{category:{}}})),_.has(t.rule_value[e],"callCategoryInProgress")&&!t.rule_value[e].callCategoryInProgress)return t.rule_value[e].category;if(!_.has(t.rule_value[e],"callCategoryInProgress")){t.rule_value[e].callCategoryInProgress=!0;var o=0;T.isRuleIndexSubjectCategory(e,t)?(o=t.meta_rule.subject_categories[e],r.subject.data.findOne(T.policy.id,o,t.rule[e],function(o){t.rule_value[e].callCategoryInProgress=!1,t.rule_value[e].category=o})):T.isRuleIndexObjectCategory(e,t)?(o=t.meta_rule.object_categories[e-t.meta_rule.subject_categories.length],r.object.data.findOne(T.policy.id,o,t.rule[e],function(o){t.rule_value[e].callCategoryInProgress=!1,t.rule_value[e].category=o})):T.isRuleIndexActionCategory(e,t)?(o=t.meta_rule.action_categories[e-t.meta_rule.subject_categories.length-t.meta_rule.object_categories.length],r.action.data.findOne(T.policy.id,o,t.rule[e],function(o){t.rule_value[e].callCategoryInProgress=!1,t.rule_value[e].category=o})):(t.rule_value[e].callCategoryInProgress=!1,t.rule_value[e].category={name:"ERROR"})}return!1}function p(e,t){return e+1<=t.meta_rule.subject_categories.length}function f(e,t){var o=e+1;return t.meta_rule.subject_categories.length0}function v(){T.table.total(T.rules.length),T.table.reload()}function b(e,t){T.rules.push(t),v()}function j(e){function t(){a("moon.policy.rules.edit.action.add.delete.success").then(function(e){l.alertSuccess(e)}),S(e),v(),e.loader=!1}function o(t){a("moon.policy.rules.edit.action.add.delete.success",{reason:t.message}).then(function(e){l.alertError(e)}),e.loader=!1}e.loader=!0,c.delete(e.id,T.policy.id,t,o)}function S(e){T.rules=_.without(T.rules,e)}var T=this;T.rules=[],T.editMode=e.list.editMode,T.loadingRules=!0,T.table={},T.getRules=g,T.hasRules=y,T.refreshRules=v,T.deleteRules=j,T.getMetaRuleFromRule=u,T.getCategoryFromRuleIndex=m,T.isRuleIndexSubjectCategory=p,T.isRuleIndexObjectCategory=f,T.isRuleIndexActionCategory=h,function(){d(),s()}();var E={"event:createRulesFromDataRulesSuccess":t.$on("event:createRulesFromDataRulesSuccess",b)};_.each(E,function(t){e.$on("$destroy",E[t])})}angular.module("moon").directive("moonRulesList",e),e.$inject=[],angular.module("moon").controller("moonRulesListController",t),t.$inject=["$scope","$rootScope","NgTableParams","$filter","metaRuleService","rulesService","dataService","$translate","alertService"]}(),function(){"use strict";function e(e,t,o){var n={subject:{policy:e(t.POLICIES+":policy_id/subject_assignments/:perimeter_id/:category_id/:data_id",{},{get:{method:"GET"},create:{method:"POST"},remove:{method:"DELETE"}})},object:{policy:e(t.POLICIES+":policy_id/object_assignments/:perimeter_id/:category_id/:data_id",{},{get:{method:"GET"},create:{method:"POST"},remove:{method:"DELETE"}})},action:{policy:e(t.POLICIES+":policy_id/action_assignments/:perimeter_id/:category_id/:data_id",{},{get:{method:"GET"},create:{method:"POST"},remove:{method:"DELETE"}})}};return{subject:{delete:function(e,t,o,i,c,r){n.subject.policy.remove({policy_id:e,perimeter_id:t,category_id:o,data_id:i},{},c,r)},add:function(e,t,o,i){n.subject.policy.create({policy_id:t},e,o,i)},findAllFromPolicyWithCallback:function(e,t){n.subject.policy.get({policy_id:e}).$promise.then(function(e){t(o.transform(e,"subject_assignments"))})}},object:{delete:function(e,t,o,i,c,r){n.object.policy.remove({policy_id:e,perimeter_id:t,category_id:o,data_id:i},{},c,r)},add:function(e,t,o,i){n.object.policy.create({policy_id:t},e,o,i)},findAllFromPolicyWithCallback:function(e,t){n.object.policy.get({policy_id:e}).$promise.then(function(e){t(o.transform(e,"object_assignments"))})}},action:{delete:function(e,t,o,i,c,r){n.action.policy.remove({policy_id:e,perimeter_id:t,category_id:o,data_id:i},{},c,r)},add:function(e,t,o,i){n.action.policy.create({policy_id:t},e,o,i)},findAllFromPolicyWithCallback:function(e,t){n.action.policy.get({policy_id:e}).$promise.then(function(e){t(o.transform(e,"action_assignments"))})}}}}angular.module("moon").factory("assignmentsService",e),e.$inject=["$resource","REST_URI","utilService"]}(),function(){"use strict";function e(e,t,o){var n={subject:{policy:e(t.POLICIES+":policy_id/subject_data/:subject_id/:category_id/:data_id",{},{get:{method:"GET"},create:{method:"POST"},remove:{method:"DELETE"}})},object:{policy:e(t.POLICIES+":policy_id/object_data/:object_id/:category_id/:data_id",{},{get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"}})},action:{policy:e(t.POLICIES+":policy_id/action_data/:action_id/:category_id/:data_id",{},{get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"}})}};return{subject:{findAllFromPolicyWithCallback:function(e,t){n.subject.policy.get({policy_id:e}).$promise.then(function(e){t(o.transform(e.subject_data[0],"data"))})},findAllFromCategoriesWithCallback:function(e,t,i){n.subject.policy.get({policy_id:e,category_id:t}).$promise.then(function(e){i(e.subject_data[0]?o.transform(e.subject_data[0],"data"):[])})},delete:function(e,t,o,i,c){n.subject.policy.remove({policy_id:t,category_id:o,data_id:e.id},e,i,c)},add:function(e,t,o,i,c){n.subject.policy.create({policy_id:t,category_id:o},e,i,c)},data:{findOne:function(e,t,i,c){n.subject.policy.get({policy_id:e,subject_id:t,data_id:i}).$promise.then(function(e){c(e.subject_data[0]?o.transformOne(e.subject_data[0],"data"):{})})}}},object:{findAllFromPolicyWithCallback:function(e,t){n.object.policy.get({policy_id:e}).$promise.then(function(e){t(o.transform(e.object_data[0],"data"))})},findAllFromCategoriesWithCallback:function(e,t,i){n.object.policy.get({policy_id:e,category_id:t}).$promise.then(function(e){i(e.object_data[0]?o.transform(e.object_data[0],"data"):[])})},delete:function(e,t,o,i,c){n.object.policy.remove({policy_id:t,category_id:o,data_id:e.id},e,i,c)},add:function(e,t,o,i,c){n.object.policy.create({policy_id:t,category_id:o},e,i,c)},data:{findOne:function(e,t,i,c){n.object.policy.get({policy_id:e,object_id:t,data_id:i}).$promise.then(function(e){c(e.object_data[0]?o.transformOne(e.object_data[0],"data"):{})})}}},action:{findAllFromPolicyWithCallback:function(e,t){n.action.policy.get({policy_id:e}).$promise.then(function(e){t(o.transform(e.action_data[0],"data"))})},findAllFromCategoriesWithCallback:function(e,t,i){n.action.policy.get({policy_id:e,category_id:t}).$promise.then(function(e){i(e.action_data[0]?o.transform(e.action_data[0],"data"):[])})},delete:function(e,t,o,i,c){n.action.policy.remove({policy_id:t,category_id:o,data_id:e.id},e,i,c)},add:function(e,t,o,i,c){n.action.policy.create({policy_id:t,category_id:o},e,i,c)},data:{ +findOne:function(e,t,i,c){n.action.policy.get({policy_id:e,action_id:t,data_id:i}).$promise.then(function(e){c(e.action_data[0]?o.transformOne(e.action_data[0],"data"):{})})}}}}}angular.module("moon").factory("dataService",e),e.$inject=["$resource","REST_URI","utilService"]}(),function(){"use strict";function e(e,t,o,n){var i={subject:{perimeter:e(t.PERIMETERS.subject+":subject_id",{},{get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"},update:{method:"PATCH"}}),policy:e(t.POLICIES+":policy_id/subjects/:subject_id",{},{get:{method:"GET"},create:{method:"POST"},remove:{method:"DELETE"},update:{method:"PATCH"}})},object:{perimeter:e(t.PERIMETERS.object+":object_id",{},{get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"},update:{method:"PATCH"}}),policy:e(t.POLICIES+":policy_id/objects/:object_id",{},{get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"},update:{method:"PATCH"}})},action:{perimeter:e(t.PERIMETERS.action+":action_id",{},{get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"},update:{method:"PATCH"}}),policy:e(t.POLICIES+":policy_id/actions/:action_id",{},{get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"},update:{method:"PATCH"}})}};return{subject:{findOne:function(e,t){i.subject.perimeter.get({subject_id:e}).$promise.then(function(e){t(n.transformOne(e,"subjects"))})},findOneReturningPromise:function(e){return i.subject.perimeter.get({subject_id:e}).$promise},findSome:function(e){var t=this;if(0===e.length)return[];var i=_(e).map(function(e){return t.findOneReturningPromise(e)});return o.all(i).then(function(e){return _(e).map(function(e){return n.transformOne(e,"subjects")})})},unMapPerimeterFromPolicy:function(e,t,o,n){i.subject.policy.remove({policy_id:e,subject_id:t},{},o,n)},findAllFromPolicyWithCallback:function(e,t){i.subject.policy.get({policy_id:e}).$promise.then(function(e){t(n.transform(e,"subjects"))})},findOneFromPolicyWithCallback:function(e,t,o){i.subject.policy.get({policy_id:e,subject_id:t}).$promise.then(function(e){o(n.transformOne(e,"subjects"))})},findAll:function(){return i.subject.perimeter.get().$promise.then(function(e){return n.transform(e,"subjects")})},findAllWithCallback:function(e){return i.subject.perimeter.get().$promise.then(function(t){e(n.transform(t,"subjects"))})},delete:function(e,t,o){i.subject.perimeter.remove({subject_id:e.id},e,t,o)},add:function(e,t,o){i.subject.perimeter.create({},e,t,o)},update:function(e,t,o){i.subject.perimeter.update({subject_id:e.id},e,t,o)}},object:{findOne:function(e,t){i.object.perimeter.get({object_id:e}).$promise.then(function(e){t(n.transformOne(e,"objects"))})},findOneReturningPromise:function(e){return i.object.perimeter.get({object_id:e}).$promise},findSome:function(e){var t=this;if(0===e.length)return[];var i=_(e).map(function(e){return t.findOneReturningPromise(e)});return o.all(i).then(function(e){return _(e).map(function(e){return n.transformOne(e,"objects")})})},unMapPerimeterFromPolicy:function(e,t,o,n){i.object.policy.remove({policy_id:e,object_id:t},{},o,n)},findSomeWithCallback:function(e,t){var i=this;0===e.length&&t([]);var c=_(e).map(function(e){return i.findOneReturningPromise(e)});o.all(c).then(function(e){t(_(e).map(function(e){return n.transformOne(e,"objects")}))})},findAll:function(){return i.object.perimeter.get().$promise.then(function(e){return n.transform(e,"objects")})},findAllFromPolicyWithCallback:function(e,t){i.object.policy.get({policy_id:e}).$promise.then(function(e){t(n.transform(e,"objects"))})},findOneFromPolicyWithCallback:function(e,t,o){i.object.policy.get({policy_id:e,object_id:t}).$promise.then(function(e){o(n.transformOne(e,"objects"))})},findAllWithCallback:function(e){return i.object.perimeter.get().$promise.then(function(t){e(n.transform(t,"objects"))})},delete:function(e,t,o){i.object.perimeter.remove({object_id:e.id},e,t,o)},add:function(e,t,o){i.object.perimeter.create({},e,t,o)},update:function(e,t,o){i.object.perimeter.update({object_id:e.id},e,t,o)}},action:{findOne:function(e,t){i.action.perimeter.get({actionId:e}).$promise.then(function(e){t(n.transformOne(e,"actions"))})},findOneReturningPromise:function(e){return i.action.perimeter.get({actionId:e}).$promise},findSome:function(e){var t=this;if(0===e.length)return[];var i=_(e).map(function(e){return t.findOneReturningPromise(e)});return o.all(i).then(function(e){return _(e).map(function(e){return n.transformOne(e,"actions")})})},unMapPerimeterFromPolicy:function(e,t,o,n){i.action.policy.remove({policy_id:e,action_id:t},{},o,n)},findSomeWithCallback:function(e,t){var i=this;0===e.length&&t([]);var c=_(e).map(function(e){return i.findOneReturningPromise(e)});o.all(c).then(function(e){t(_(e).map(function(e){return n.transformOne(e,"actions")}))})},findAll:function(){return i.action.perimeter.get().$promise.then(function(e){return n.transform(e,"actions")})},findAllFromPolicyWithCallback:function(e,t){i.action.policy.get({policy_id:e}).$promise.then(function(e){t(n.transform(e,"actions"))})},findOneFromPolicyWithCallback:function(e,t,o){i.action.policy.get({policy_id:e,action_id:t}).$promise.then(function(e){o(n.transformOne(e,"actions"))})},findAllWithCallback:function(e){return i.action.perimeter.get().$promise.then(function(t){e(n.transform(t,"actions"))})},delete:function(e,t,o){i.action.perimeter.remove({action_id:e.id},e,t,o)},add:function(e,t,o){i.action.perimeter.create({},e,t,o)},update:function(e,t,o){i.action.perimeter.update({action_id:e.id},e,t,o)}}}}angular.module("moon").factory("perimeterService",e),e.$inject=["$resource","REST_URI","$q","utilService"]}(),function(){"use strict";function e(e,t,o){return{data:{policy:e(t.POLICIES+":policy_id/rules/:rule_id",{},{get:{method:"GET"},create:{method:"POST"},remove:{method:"DELETE"}})},findAllFromPolicyWithCallback:function(e,t){this.data.policy.get({policy_id:e}).$promise.then(function(e){console.log("ruleService - findAllFromPolicyWithCallback()"),console.log(e);var n=e.rules;console.log(JSON.stringify(n)),t(o.transform(n,"rules"))})}}}angular.module("moon").factory("ruleService",e),e.$inject=["$resource","REST_URI","utilService"]}(),function(){"use strict";function e(e,t,o){return{data:{policy:e(t.POLICIES+":policy_id/rules/:rule_id",{},{get:{method:"GET"},create:{method:"POST"},remove:{method:"DELETE"}})},add:function(e,t,o,n){this.data.policy.create({policy_id:t},e,o,n)},delete:function(e,t,o,n){this.data.policy.remove({policy_id:t,rule_id:e},{},o,n)},findAllFromPolicyWithCallback:function(e,t){this.data.policy.get({policy_id:e}).$promise.then(function(e){t(e.rules.rules)})}}}angular.module("moon").factory("rulesService",e),e.$inject=["$resource","REST_URI","utilService"]}(),function(){"use strict";function e(){return{templateUrl:"html/model/edit/metarules/action/mapping/metarules-add.tpl.html",bindToController:!0,controller:t,controllerAs:"add",scope:{metaRules:"="},restrict:"E",replace:!0}}function t(e,t,o,n,i,c){function r(){function r(t){var i=c.transformOne(t,"meta_rules");n("moon.model.metarules.add.success",{metaRuleName:i.name}).then(function(e){o.alertSuccess(e)}),a.loading=!1,e.$emit("event:metaRuleCreatedSuccess",i)}function l(t){n("moon.model.metarules.add.error",{metaRuleName:a.metaRule.name}).then(function(e){o.alertError(e)}),a.loading=!1,e.$emit("event:metaRuleCreatedError",a.project)}i.isInvalid(a.form)?i.checkFieldsValidity(a.form):(a.loading=!0,t.data.create({},a.metaRule,r,l))}var a=this;a.laoading=!1,a.form={},a.metaRule={name:null,description:null,subject_categories:[],object_categories:[],action_categories:[]},a.create=r}angular.module("moon").directive("moonMetaRulesAdd",e),e.$inject=[],angular.module("moon").controller("moonMetaRulesAddController",t),t.$inject=["$scope","metaRuleService","alertService","$translate","formService","utilService"]}(),function(){"use strict";function e(e,t,o,n,i,c,r,a){function l(){h.metaRulesLoading=!0,c.findAllWithCallback(function(e){h.metaRules=e,h.metaRulesLoading=!1})}function s(){function t(t){var i=a.transformOne(t,"models");c.findSomeWithMetaData(i.meta_rules).then(function(t){i.meta_rules_values=t,n("moon.model.metarules.map.success",{modelName:i.name,metaRuleName:h.selectedMetaRule.name}).then(function(e){o.alertSuccess(e)}),h.mappingLoading=!1,e.$emit("event:metaRuleMapToModelSuccess",i)})}function l(e){n("moon.model.metarules.map.error",{modelName:h.model.name,metaRuleName:h.selectedMetaRule.name}).then(function(e){o.alertError(e)}),h.mappingLoading=!1}if(i.isInvalid(h.form))i.checkFieldsValidity(h.form);else{h.mappingLoading=!0;var s=angular.copy(h.model);s.meta_rules.push(h.selectedMetaRule.id),r.update(s,t,l)}}function d(){delete h.selectedMetaRule}function u(){function t(t){n("moon.model.metarules.delete.success",{metaRuleName:r.name}).then(function(e){o.alertSuccess(e)}),d(),h.mappingLoading=!1,l(),e.$emit("event:deleteMetaRule",r)}function i(e){n("moon.model.metarules.delete.error",{metaRuleName:r.name}).then(function(e){o.alertError(e)}),h.mappingLoading=!1}if(h.selectedMetaRule){h.mappingLoading=!0;var r=angular.copy(h.selectedMetaRule);c.delete(r,t,i)}}function m(e,t){h.metaRules.push(t),f()}function p(e){}function f(){h.addMetaRuleToList=!1}var h=this;h.metaRules=[],h.model=e.model,h.addMetaRuleToList=!1,h.mapToModel=s,h.deleteMetaRule=u,function(){l()}();var g={"event:metaRuleCreatedSuccess":t.$on("event:metaRuleCreatedSuccess",m),"event:metaRuleCreatedError":t.$on("event:metaRuleCreatedError",p)};for(var y in g)e.$on("$destroy",g[y])}angular.module("moon").controller("moonMetaRulesMapController",e),e.$inject=["$scope","$rootScope","alertService","$translate","formService","metaRuleService","modelService","utilService"]}(),function(){"use strict";function e(e,t,o,n){function i(){function i(n){t("moon.model.metarules.unmap.success",{modelName:c.model.name,metaRuleName:c.metaRule.name}).then(function(e){o.alertSuccess(e)}),c.unMappingLoading=!1,e.$emit("event:metaRuleUnMappedToModelSuccess",a)}function r(n){t("moon.model.metarules.unmap.error",{modelName:c.model.name,metaRuleName:c.metaRule.name}).then(function(e){o.alertError(e)}),c.unMappingLoading=!1,e.$emit("event:metaRuleUnMappedToModelError")}c.unMappingLoading=!0;var a=angular.copy(c.model);a.meta_rules=_.without(a.meta_rules,c.metaRule.id),n.update(a,i,r)}var c=this;c.model=e.model,c.metaRule=e.metaRule,c.unMappingLoading=!1,c.unmap=i}angular.module("moon").controller("MetaRulesUnMapController",e),e.$inject=["$scope","$translate","alertService","modelService"]}(); \ No newline at end of file diff --git a/old/moon_gui/delivery/js/modules.js b/old/moon_gui/delivery/js/modules.js new file mode 100644 index 00000000..ec3b37a3 --- /dev/null +++ b/old/moon_gui/delivery/js/modules.js @@ -0,0 +1,20 @@ +function require(e,t,n){var i=require.resolve(e);if(null==i){n=n||e,t=t||"root";var r=new Error('Failed to require "'+n+'" from "'+t+'"');throw r.path=n,r.parent=t,r.require=!0,r}var o=require.modules[i];if(!o._resolving&&!o.exports){var a={};a.exports={},a.client=a.component=!0,o._resolving=!0,o.call(this,a.exports,require.relative(i),a),delete o._resolving,o.exports=a.exports}return o.exports}if(function(e,t){"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){function n(e){var t=e.length,n=J.type(e);return"function"!==n&&!J.isWindow(e)&&(!(1!==e.nodeType||!t)||("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e))}function i(e,t,n){if(J.isFunction(t))return J.grep(e,function(e,i){return!!t.call(e,i,e)!==n});if(t.nodeType)return J.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(ae.test(t))return J.filter(t,e,n);t=J.filter(t,e)}return J.grep(e,function(e){return z.call(t,e)>=0!==n})}function r(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}function o(e){var t=fe[e]={};return J.each(e.match(de)||[],function(e,n){t[n]=!0}),t}function a(){Z.removeEventListener("DOMContentLoaded",a,!1),e.removeEventListener("load",a,!1),J.ready()}function s(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=J.expando+Math.random()}function l(e,t,n){var i;if(void 0===n&&1===e.nodeType)if(i="data-"+t.replace($e,"-$1").toLowerCase(),"string"==typeof(n=e.getAttribute(i))){try{n="true"===n||"false"!==n&&("null"===n?null:+n+""===n?+n:ve.test(n)?J.parseJSON(n):n)}catch(e){}me.set(e,t,n)}else n=void 0;return n}function c(){return!0}function u(){return!1}function d(){try{return Z.activeElement}catch(e){}}function f(e,t){return J.nodeName(e,"table")&&J.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function p(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function h(e){var t=Pe.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function g(e,t){for(var n=0,i=e.length;n")).appendTo(t.documentElement),t=Fe[0].contentDocument,t.write(),t.close(),n=y(e,t),Fe.detach()),Le[e]=n),n}function w(e,t,n){var i,r,o,a,s=e.style;return n=n||He(e),n&&(a=n.getPropertyValue(t)||n[t]),n&&(""!==a||J.contains(e.ownerDocument,e)||(a=J.style(e,t)),Ve.test(a)&&Re.test(t)&&(i=s.width,r=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=i,s.minWidth=r,s.maxWidth=o)),void 0!==a?a+"":a}function x(e,t){return{get:function(){return e()?void delete this.get:(this.get=t).apply(this,arguments)}}}function C(e,t){if(t in e)return t;for(var n=t[0].toUpperCase()+t.slice(1),i=t,r=ze.length;r--;)if((t=ze[r]+n)in e)return t;return i}function k(e,t,n){var i=Ue.exec(t);return i?Math.max(0,i[1]-(n||0))+(i[2]||"px"):t}function S(e,t,n,i,r){for(var o=n===(i?"border":"content")?4:"width"===t?1:0,a=0;o<4;o+=2)"margin"===n&&(a+=J.css(e,n+be[o],!0,r)),i?("content"===n&&(a-=J.css(e,"padding"+be[o],!0,r)),"margin"!==n&&(a-=J.css(e,"border"+be[o]+"Width",!0,r))):(a+=J.css(e,"padding"+be[o],!0,r),"padding"!==n&&(a+=J.css(e,"border"+be[o]+"Width",!0,r)));return a}function E(e,t,n){var i=!0,r="width"===t?e.offsetWidth:e.offsetHeight,o=He(e),a="border-box"===J.css(e,"boxSizing",!1,o);if(r<=0||null==r){if(r=w(e,t,o),(r<0||null==r)&&(r=e.style[t]),Ve.test(r))return r;i=a&&(X.boxSizingReliable()||r===e.style[t]),r=parseFloat(r)||0}return r+S(e,t,n||(a?"border":"content"),i,o)+"px"}function T(e,t){for(var n,i,r,o=[],a=0,s=e.length;a=0&&n=0},isPlainObject:function(e){return"object"===J.type(e)&&!e.nodeType&&!J.isWindow(e)&&!(e.constructor&&!G.call(e.constructor.prototype,"isPrototypeOf"))},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?Y[K.call(e)]||"object":typeof e},globalEval:function(e){var t,n=eval;(e=J.trim(e))&&(1===e.indexOf("use strict")?(t=Z.createElement("script"),t.text=e,Z.head.appendChild(t).parentNode.removeChild(t)):n(e))},camelCase:function(e){return e.replace(ee,"ms-").replace(te,ne)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,i){var r=0,o=e.length,a=n(e);if(i){if(a)for(;rb.cacheLength&&delete e[t.shift()],e[n+" "]=i}var t=[];return e}function i(e){return e[L]=!0,e}function r(e){var t=M.createElement("div");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function o(e,t){for(var n=e.split("|"),i=e.length;i--;)b.attrHandle[n[i]]=t}function a(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||z)-(~e.sourceIndex||z);if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function s(e){return i(function(t){return t=+t,i(function(n,i){for(var r,o=e([],n.length,t),a=o.length;a--;)n[r=o[a]]&&(n[r]=!(i[r]=n[r]))})})}function l(e){return e&&typeof e.getElementsByTagName!==W&&e}function c(){}function u(e){for(var t=0,n=e.length,i="";t1?function(t,n,i){for(var r=e.length;r--;)if(!e[r](t,n,i))return!1;return!0}:e[0]}function p(e,n,i){for(var r=0,o=n.length;r-1&&(i[c]=!(a[c]=d))}}else y=h(y===a?y.splice(m,y.length):y),o?o(null,a,y,l):Z.apply(a,y)})}function m(e){for(var t,n,i,r=e.length,o=b.relative[e[0].type],a=o||b.relative[" "],s=o?1:0,l=d(function(e){return e===t},a,!0),c=d(function(e){return Q.call(t,e)>-1},a,!0),p=[function(e,n,i){return!o&&(i||n!==E)||((t=n).nodeType?l(e,n,i):c(e,n,i))}];s1&&f(p),s>1&&u(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace(ae,"$1"),n,s0,o=e.length>0,a=function(i,a,s,l,c){var u,d,f,p=0,g="0",m=i&&[],v=[],$=E,y=i||o&&b.find.TAG("*",c),w=V+=null==$?1:Math.random()||.1,x=y.length;for(c&&(E=a!==M&&a);g!==x&&null!=(u=y[g]);g++){if(o&&u){for(d=0;f=e[d++];)if(f(u,a,s)){l.push(u);break}c&&(V=w)}r&&((u=!f&&u)&&p--,i&&m.push(u))}if(p+=g,r&&g!==p){for(d=0;f=n[d++];)f(m,v,a,s);if(i){if(p>0)for(;g--;)m[g]||v[g]||(v[g]=G.call(l));v=h(v)}Z.apply(l,v),c&&!i&&v.length>0&&p+n.length>1&&t.uniqueSort(l)}return c&&(V=w,E=$),m};return r?i(a):a}var $,y,b,w,x,C,k,S,E,T,D,A,M,O,I,P,N,j,F,L="sizzle"+-new Date,R=e.document,V=0,H=0,q=n(),U=n(),_=n(),B=function(e,t){return e===t&&(D=!0),0},W="undefined",z=1<<31,Y={}.hasOwnProperty,K=[],G=K.pop,X=K.push,Z=K.push,J=K.slice,Q=K.indexOf||function(e){for(var t=0,n=this.length;t+~]|"+te+")"+te+"*"),ce=new RegExp("="+te+"*([^\\]'\"]*?)"+te+"*\\]","g"),ue=new RegExp(oe),de=new RegExp("^"+ie+"$"),fe={ID:new RegExp("^#("+ne+")"),CLASS:new RegExp("^\\.("+ne+")"),TAG:new RegExp("^("+ne.replace("w","w*")+")"),ATTR:new RegExp("^"+re),PSEUDO:new RegExp("^"+oe),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+te+"*(even|odd|(([+-]|)(\\d*)n|)"+te+"*(?:([+-]|)"+te+"*(\\d+)|))"+te+"*\\)|)","i"),bool:new RegExp("^(?:"+ee+")$","i"),needsContext:new RegExp("^"+te+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+te+"*((?:-\\d)?\\d*)"+te+"*\\)|)(?=[^-]|$)","i")},pe=/^(?:input|select|textarea|button)$/i,he=/^h\d$/i,ge=/^[^{]+\{\s*\[native \w/,me=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ve=/[+~]/,$e=/'|\\/g,ye=new RegExp("\\\\([\\da-f]{1,6}"+te+"?|("+te+")|.)","ig"),be=function(e,t,n){var i="0x"+t-65536;return i!==i||n?t:i<0?String.fromCharCode(i+65536):String.fromCharCode(i>>10|55296,1023&i|56320)};try{Z.apply(K=J.call(R.childNodes),R.childNodes),K[R.childNodes.length].nodeType}catch(e){Z={apply:K.length?function(e,t){X.apply(e,J.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}y=t.support={},x=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},A=t.setDocument=function(e){var t,n=e?e.ownerDocument||e:R,i=n.defaultView;return n!==M&&9===n.nodeType&&n.documentElement?(M=n,O=n.documentElement,I=!x(n),i&&i!==i.top&&(i.addEventListener?i.addEventListener("unload",function(){A()},!1):i.attachEvent&&i.attachEvent("onunload",function(){A()})),y.attributes=r(function(e){return e.className="i",!e.getAttribute("className")}),y.getElementsByTagName=r(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),y.getElementsByClassName=ge.test(n.getElementsByClassName)&&r(function(e){return e.innerHTML="
",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),y.getById=r(function(e){return O.appendChild(e).id=L,!n.getElementsByName||!n.getElementsByName(L).length}),y.getById?(b.find.ID=function(e,t){if(typeof t.getElementById!==W&&I){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},b.filter.ID=function(e){var t=e.replace(ye,be);return function(e){return e.getAttribute("id")===t}}):(delete b.find.ID,b.filter.ID=function(e){var t=e.replace(ye,be);return function(e){var n=typeof e.getAttributeNode!==W&&e.getAttributeNode("id");return n&&n.value===t}}),b.find.TAG=y.getElementsByTagName?function(e,t){if(typeof t.getElementsByTagName!==W)return t.getElementsByTagName(e)}:function(e,t){var n,i=[],r=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[r++];)1===n.nodeType&&i.push(n);return i}return o},b.find.CLASS=y.getElementsByClassName&&function(e,t){if(typeof t.getElementsByClassName!==W&&I)return t.getElementsByClassName(e)},N=[],P=[],(y.qsa=ge.test(n.querySelectorAll))&&(r(function(e){e.innerHTML="",e.querySelectorAll("[msallowclip^='']").length&&P.push("[*^$]="+te+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||P.push("\\["+te+"*(?:value|"+ee+")"),e.querySelectorAll(":checked").length||P.push(":checked")}),r(function(e){var t=n.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&P.push("name"+te+"*[*^$|!~]?="),e.querySelectorAll(":enabled").length||P.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),P.push(",.*:")})),(y.matchesSelector=ge.test(j=O.matches||O.webkitMatchesSelector||O.mozMatchesSelector||O.oMatchesSelector||O.msMatchesSelector))&&r(function(e){y.disconnectedMatch=j.call(e,"div"),j.call(e,"[s!='']:x"),N.push("!=",oe)}),P=P.length&&new RegExp(P.join("|")),N=N.length&&new RegExp(N.join("|")),t=ge.test(O.compareDocumentPosition),F=t||ge.test(O.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},B=t?function(e,t){if(e===t)return D=!0,0;var i=!e.compareDocumentPosition-!t.compareDocumentPosition;return i||(i=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&i||!y.sortDetached&&t.compareDocumentPosition(e)===i?e===n||e.ownerDocument===R&&F(R,e)?-1:t===n||t.ownerDocument===R&&F(R,t)?1:T?Q.call(T,e)-Q.call(T,t):0:4&i?-1:1)}:function(e,t){if(e===t)return D=!0,0;var i,r=0,o=e.parentNode,s=t.parentNode,l=[e],c=[t];if(!o||!s)return e===n?-1:t===n?1:o?-1:s?1:T?Q.call(T,e)-Q.call(T,t):0;if(o===s)return a(e,t);for(i=e;i=i.parentNode;)l.unshift(i);for(i=t;i=i.parentNode;)c.unshift(i);for(;l[r]===c[r];)r++;return r?a(l[r],c[r]):l[r]===R?-1:c[r]===R?1:0},n):M},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==M&&A(e),n=n.replace(ce,"='$1']"),y.matchesSelector&&I&&(!N||!N.test(n))&&(!P||!P.test(n)))try{var i=j.call(e,n);if(i||y.disconnectedMatch||e.document&&11!==e.document.nodeType)return i}catch(e){}return t(n,M,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==M&&A(e),F(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==M&&A(e);var n=b.attrHandle[t.toLowerCase()],i=n&&Y.call(b.attrHandle,t.toLowerCase())?n(e,t,!I):void 0;return void 0!==i?i:y.attributes||!I?e.getAttribute(t):(i=e.getAttributeNode(t))&&i.specified?i.value:null},t.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},t.uniqueSort=function(e){var t,n=[],i=0,r=0;if(D=!y.detectDuplicates,T=!y.sortStable&&e.slice(0),e.sort(B),D){for(;t=e[r++];)t===e[r]&&(i=n.push(r));for(;i--;)e.splice(n[i],1)}return T=null,e},w=t.getText=function(e){var t,n="",i=0,r=e.nodeType;if(r){if(1===r||9===r||11===r){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=w(e)}else if(3===r||4===r)return e.nodeValue}else for(;t=e[i++];)n+=w(t);return n},b=t.selectors={cacheLength:50,createPseudo:i,match:fe,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ye,be),e[3]=(e[3]||e[4]||e[5]||"").replace(ye,be),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return fe.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&ue.test(n)&&(t=C(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ye,be).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=q[e+" "];return t||(t=new RegExp("(^|"+te+")"+e+"("+te+"|$)"))&&q(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==W&&e.getAttribute("class")||"")})},ATTR:function(e,n,i){return function(r){var o=t.attr(r,e);return null==o?"!="===n:!n||(o+="","="===n?o===i:"!="===n?o!==i:"^="===n?i&&0===o.indexOf(i):"*="===n?i&&o.indexOf(i)>-1:"$="===n?i&&o.slice(-i.length)===i:"~="===n?(" "+o+" ").indexOf(i)>-1:"|="===n&&(o===i||o.slice(0,i.length+1)===i+"-"))}},CHILD:function(e,t,n,i,r){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===i&&0===r?function(e){return!!e.parentNode}:function(t,n,l){var c,u,d,f,p,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,v=s&&t.nodeName.toLowerCase(),$=!l&&!s;if(m){if(o){for(;g;){for(d=t;d=d[g];)if(s?d.nodeName.toLowerCase()===v:1===d.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&$){for(u=m[L]||(m[L]={}),c=u[e]||[],p=c[0]===V&&c[1],f=c[0]===V&&c[2],d=p&&m.childNodes[p];d=++p&&d&&d[g]||(f=p=0)||h.pop();)if(1===d.nodeType&&++f&&d===t){u[e]=[V,p,f];break}}else if($&&(c=(t[L]||(t[L]={}))[e])&&c[0]===V)f=c[1];else for(;(d=++p&&d&&d[g]||(f=p=0)||h.pop())&&((s?d.nodeName.toLowerCase()!==v:1!==d.nodeType)||!++f||($&&((d[L]||(d[L]={}))[e]=[V,f]),d!==t)););return(f-=r)===i||f%i==0&&f/i>=0}}},PSEUDO:function(e,n){var r,o=b.pseudos[e]||b.setFilters[e.toLowerCase()]||t.error("unsupported pseudo: "+e);return o[L]?o(n):o.length>1?(r=[e,e,"",n],b.setFilters.hasOwnProperty(e.toLowerCase())?i(function(e,t){for(var i,r=o(e,n),a=r.length;a--;)i=Q.call(e,r[a]),e[i]=!(t[i]=r[a])}):function(e){return o(e,0,r)}):o}},pseudos:{not:i(function(e){var t=[],n=[],r=k(e.replace(ae,"$1"));return r[L]?i(function(e,t,n,i){for(var o,a=r(e,null,i,[]),s=e.length;s--;)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:i(function(e){return function(n){return t(e,n).length>0}}),contains:i(function(e){return function(t){return(t.textContent||t.innerText||w(t)).indexOf(e)>-1}}),lang:i(function(e){return de.test(e||"")||t.error("unsupported lang: "+e),e=e.replace(ye,be).toLowerCase(),function(t){var n;do{if(n=I?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===O},focus:function(e){return e===M.activeElement&&(!M.hasFocus||M.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return!1===e.disabled},disabled:function(e){return!0===e.disabled},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return he.test(e.nodeName)},input:function(e){return pe.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:s(function(){return[0]}),last:s(function(e,t){return[t-1]}),eq:s(function(e,t,n){return[n<0?n+t:n]}),even:s(function(e,t){for(var n=0;n=0;)e.push(i);return e}),gt:s(function(e,t,n){for(var i=n<0?n+t:n;++i2&&"ID"===(a=o[0]).type&&y.getById&&9===t.nodeType&&I&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(ye,be),t)||[])[0]))return n;d&&(t=t.parentNode),e=e.slice(o.shift().value.length)}for(r=fe.needsContext.test(e)?0:o.length;r--&&(a=o[r],!b.relative[s=a.type]);)if((c=b.find[s])&&(i=c(a.matches[0].replace(ye,be),ve.test(o[0].type)&&l(t.parentNode)||t))){if(o.splice(r,1),!(e=i.length&&u(o)))return Z.apply(n,i),n;break}}return(d||k(e,f))(i,t,!I,n,ve.test(e)&&l(t.parentNode)||t),n},y.sortStable=L.split("").sort(B).join("")===L,y.detectDuplicates=!!D,A(),y.sortDetached=r(function(e){return 1&e.compareDocumentPosition(M.createElement("div"))}),r(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||o("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),y.attributes&&r(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||o("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),r(function(e){return null==e.getAttribute("disabled")})||o(ee,function(e,t,n){var i;if(!n)return!0===e[t]?t.toLowerCase():(i=e.getAttributeNode(t))&&i.specified?i.value:null}),t}(e);J.find=ie,J.expr=ie.selectors,J.expr[":"]=J.expr.pseudos,J.unique=ie.uniqueSort,J.text=ie.getText,J.isXMLDoc=ie.isXML,J.contains=ie.contains;var re=J.expr.match.needsContext,oe=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,ae=/^.[^:#\[\.,]*$/ +;J.filter=function(e,t,n){var i=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===i.nodeType?J.find.matchesSelector(i,e)?[i]:[]:J.find.matches(e,J.grep(t,function(e){return 1===e.nodeType}))},J.fn.extend({find:function(e){var t,n=this.length,i=[],r=this;if("string"!=typeof e)return this.pushStack(J(e).filter(function(){for(t=0;t1?J.unique(i):i),i.selector=this.selector?this.selector+" "+e:e,i},filter:function(e){return this.pushStack(i(this,e||[],!1))},not:function(e){return this.pushStack(i(this,e||[],!0))},is:function(e){return!!i(this,"string"==typeof e&&re.test(e)?J(e):e||[],!1).length}});var se,le=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/;(J.fn.init=function(e,t){var n,i;if(!e)return this;if("string"==typeof e){if(!(n="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:le.exec(e))||!n[1]&&t)return!t||t.jquery?(t||se).find(e):this.constructor(t).find(e);if(n[1]){if(t=t instanceof J?t[0]:t,J.merge(this,J.parseHTML(n[1],t&&t.nodeType?t.ownerDocument||t:Z,!0)),oe.test(n[1])&&J.isPlainObject(t))for(n in t)J.isFunction(this[n])?this[n](t[n]):this.attr(n,t[n]);return this}return i=Z.getElementById(n[2]),i&&i.parentNode&&(this.length=1,this[0]=i),this.context=Z,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):J.isFunction(e)?void 0!==se.ready?se.ready(e):e(J):(void 0!==e.selector&&(this.selector=e.selector,this.context=e.context),J.makeArray(e,this))}).prototype=J.fn,se=J(Z);var ce=/^(?:parents|prev(?:Until|All))/,ue={children:!0,contents:!0,next:!0,prev:!0};J.extend({dir:function(e,t,n){for(var i=[],r=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(r&&J(e).is(n))break;i.push(e)}return i},sibling:function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}}),J.fn.extend({has:function(e){var t=J(e,this),n=t.length;return this.filter(function(){for(var e=0;e-1:1===n.nodeType&&J.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?J.unique(o):o)},index:function(e){return e?"string"==typeof e?z.call(J(e),this[0]):z.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(J.unique(J.merge(this.get(),J(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),J.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return J.dir(e,"parentNode")},parentsUntil:function(e,t,n){return J.dir(e,"parentNode",n)},next:function(e){return r(e,"nextSibling")},prev:function(e){return r(e,"previousSibling")},nextAll:function(e){return J.dir(e,"nextSibling")},prevAll:function(e){return J.dir(e,"previousSibling")},nextUntil:function(e,t,n){return J.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return J.dir(e,"previousSibling",n)},siblings:function(e){return J.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return J.sibling(e.firstChild)},contents:function(e){return e.contentDocument||J.merge([],e.childNodes)}},function(e,t){J.fn[e]=function(n,i){var r=J.map(this,t,n);return"Until"!==e.slice(-5)&&(i=n),i&&"string"==typeof i&&(r=J.filter(i,r)),this.length>1&&(ue[e]||J.unique(r),ce.test(e)&&r.reverse()),this.pushStack(r)}});var de=/\S+/g,fe={};J.Callbacks=function(e){e="string"==typeof e?fe[e]||o(e):J.extend({},e);var t,n,i,r,a,s,l=[],c=!e.once&&[],u=function(o){for(t=e.memory&&o,n=!0,s=r||0,r=0,a=l.length,i=!0;l&&s-1;)l.splice(n,1),i&&(n<=a&&a--,n<=s&&s--)}),this},has:function(e){return e?J.inArray(e,l)>-1:!(!l||!l.length)},empty:function(){return l=[],a=0,this},disable:function(){return l=c=t=void 0,this},disabled:function(){return!l},lock:function(){return c=void 0,t||d.disable(),this},locked:function(){return!c},fireWith:function(e,t){return!l||n&&!c||(t=t||[],t=[e,t.slice?t.slice():t],i?c.push(t):u(t)),this},fire:function(){return d.fireWith(this,arguments),this},fired:function(){return!!n}};return d},J.extend({Deferred:function(e){var t=[["resolve","done",J.Callbacks("once memory"),"resolved"],["reject","fail",J.Callbacks("once memory"),"rejected"],["notify","progress",J.Callbacks("memory")]],n="pending",i={state:function(){return n},always:function(){return r.done(arguments).fail(arguments),this},then:function(){var e=arguments;return J.Deferred(function(n){J.each(t,function(t,o){var a=J.isFunction(e[t])&&e[t];r[o[1]](function(){var e=a&&a.apply(this,arguments);e&&J.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[o[0]+"With"](this===i?n.promise():this,a?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?J.extend(e,i):i}},r={};return i.pipe=i.then,J.each(t,function(e,o){var a=o[2],s=o[3];i[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),r[o[0]]=function(){return r[o[0]+"With"](this===r?i:this,arguments),this},r[o[0]+"With"]=a.fireWith}),i.promise(r),e&&e.call(r,r),r},when:function(e){var t,n,i,r=0,o=_.call(arguments),a=o.length,s=1!==a||e&&J.isFunction(e.promise)?a:0,l=1===s?e:J.Deferred(),c=function(e,n,i){return function(r){n[e]=this,i[e]=arguments.length>1?_.call(arguments):r,i===t?l.notifyWith(n,i):--s||l.resolveWith(n,i)}};if(a>1)for(t=new Array(a),n=new Array(a),i=new Array(a);r0||(pe.resolveWith(Z,[J]),J.fn.triggerHandler&&(J(Z).triggerHandler("ready"),J(Z).off("ready"))))}}),J.ready.promise=function(t){return pe||(pe=J.Deferred(),"complete"===Z.readyState?setTimeout(J.ready):(Z.addEventListener("DOMContentLoaded",a,!1),e.addEventListener("load",a,!1))),pe.promise(t)},J.ready.promise();var he=J.access=function(e,t,n,i,r,o,a){var s=0,l=e.length,c=null==n;if("object"===J.type(n)){r=!0;for(s in n)J.access(e,t,s,n[s],!0,o,a)}else if(void 0!==i&&(r=!0,J.isFunction(i)||(a=!0),c&&(a?(t.call(e,i),t=null):(c=t,t=function(e,t,n){return c.call(J(e),n)})),t))for(;s1,null,!0)},removeData:function(e){return this.each(function(){me.remove(this,e)})}}),J.extend({queue:function(e,t,n){var i;if(e)return t=(t||"fx")+"queue",i=ge.get(e,t),n&&(!i||J.isArray(n)?i=ge.access(e,t,J.makeArray(n)):i.push(n)),i||[]},dequeue:function(e,t){t=t||"fx";var n=J.queue(e,t),i=n.length,r=n.shift(),o=J._queueHooks(e,t),a=function(){J.dequeue(e,t)};"inprogress"===r&&(r=n.shift(),i--),r&&("fx"===t&&n.unshift("inprogress"),delete o.stop,r.call(e,a,o)),!i&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return ge.get(e,n)||ge.access(e,n,{empty:J.Callbacks("once memory").add(function(){ge.remove(e,[t+"queue",n])})})}}),J.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.lengthx",X.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue}();X.focusinBubbles="onfocusin"in e;var Ce=/^key/,ke=/^(?:mouse|pointer|contextmenu)|click/,Se=/^(?:focusinfocus|focusoutblur)$/,Ee=/^([^.]*)(?:\.(.+)|)$/;J.event={global:{},add:function(e,t,n,i,r){var o,a,s,l,c,u,d,f,p,h,g,m=ge.get(e);if(m)for(n.handler&&(o=n,n=o.handler,r=o.selector),n.guid||(n.guid=J.guid++),(l=m.events)||(l=m.events={}),(a=m.handle)||(a=m.handle=function(t){return void 0!==J&&J.event.triggered!==t.type?J.event.dispatch.apply(e,arguments):void 0}),t=(t||"").match(de)||[""],c=t.length;c--;)s=Ee.exec(t[c])||[],p=g=s[1],h=(s[2]||"").split(".").sort(),p&&(d=J.event.special[p]||{},p=(r?d.delegateType:d.bindType)||p,d=J.event.special[p]||{},u=J.extend({type:p,origType:g,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&J.expr.match.needsContext.test(r),namespace:h.join(".")},o),(f=l[p])||(f=l[p]=[],f.delegateCount=0,d.setup&&!1!==d.setup.call(e,i,h,a)||e.addEventListener&&e.addEventListener(p,a,!1)),d.add&&(d.add.call(e,u),u.handler.guid||(u.handler.guid=n.guid)),r?f.splice(f.delegateCount++,0,u):f.push(u),J.event.global[p]=!0)},remove:function(e,t,n,i,r){var o,a,s,l,c,u,d,f,p,h,g,m=ge.hasData(e)&&ge.get(e);if(m&&(l=m.events)){for(t=(t||"").match(de)||[""],c=t.length;c--;)if(s=Ee.exec(t[c])||[],p=g=s[1],h=(s[2]||"").split(".").sort(),p){for(d=J.event.special[p]||{},p=(i?d.delegateType:d.bindType)||p,f=l[p]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=f.length;o--;)u=f[o],!r&&g!==u.origType||n&&n.guid!==u.guid||s&&!s.test(u.namespace)||i&&i!==u.selector&&("**"!==i||!u.selector)||(f.splice(o,1),u.selector&&f.delegateCount--,d.remove&&d.remove.call(e,u));a&&!f.length&&(d.teardown&&!1!==d.teardown.call(e,h,m.handle)||J.removeEvent(e,p,m.handle),delete l[p])}else for(p in l)J.event.remove(e,p+t[c],n,i,!0);J.isEmptyObject(l)&&(delete m.handle,ge.remove(e,"events"))}},trigger:function(t,n,i,r){var o,a,s,l,c,u,d,f=[i||Z],p=G.call(t,"type")?t.type:t,h=G.call(t,"namespace")?t.namespace.split("."):[];if(a=s=i=i||Z,3!==i.nodeType&&8!==i.nodeType&&!Se.test(p+J.event.triggered)&&(p.indexOf(".")>=0&&(h=p.split("."),p=h.shift(),h.sort()),c=p.indexOf(":")<0&&"on"+p,t=t[J.expando]?t:new J.Event(p,"object"==typeof t&&t),t.isTrigger=r?2:3,t.namespace=h.join("."),t.namespace_re=t.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=i),n=null==n?[t]:J.makeArray(n,[t]),d=J.event.special[p]||{},r||!d.trigger||!1!==d.trigger.apply(i,n))){if(!r&&!d.noBubble&&!J.isWindow(i)){for(l=d.delegateType||p,Se.test(l+p)||(a=a.parentNode);a;a=a.parentNode)f.push(a),s=a;s===(i.ownerDocument||Z)&&f.push(s.defaultView||s.parentWindow||e)}for(o=0;(a=f[o++])&&!t.isPropagationStopped();)t.type=o>1?l:d.bindType||p,u=(ge.get(a,"events")||{})[t.type]&&ge.get(a,"handle"),u&&u.apply(a,n),(u=c&&a[c])&&u.apply&&J.acceptData(a)&&(t.result=u.apply(a,n),!1===t.result&&t.preventDefault());return t.type=p,r||t.isDefaultPrevented()||d._default&&!1!==d._default.apply(f.pop(),n)||!J.acceptData(i)||c&&J.isFunction(i[p])&&!J.isWindow(i)&&(s=i[c],s&&(i[c]=null),J.event.triggered=p,i[p](),J.event.triggered=void 0,s&&(i[c]=s)),t.result}},dispatch:function(e){e=J.event.fix(e);var t,n,i,r,o,a=[],s=_.call(arguments),l=(ge.get(this,"events")||{})[e.type]||[],c=J.event.special[e.type]||{};if(s[0]=e,e.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,e)){for(a=J.event.handlers.call(this,e,l),t=0;(r=a[t++])&&!e.isPropagationStopped();)for(e.currentTarget=r.elem,n=0;(o=r.handlers[n++])&&!e.isImmediatePropagationStopped();)e.namespace_re&&!e.namespace_re.test(o.namespace)||(e.handleObj=o,e.data=o.data,void 0!==(i=((J.event.special[o.origType]||{}).handle||o.handler).apply(r.elem,s))&&!1===(e.result=i)&&(e.preventDefault(),e.stopPropagation()));return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,i,r,o,a=[],s=t.delegateCount,l=e.target;if(s&&l.nodeType&&(!e.button||"click"!==e.type))for(;l!==this;l=l.parentNode||this)if(!0!==l.disabled||"click"!==e.type){for(i=[],n=0;n=0:J.find(r,this,null,[l]).length),i[r]&&i.push(o);i.length&&a.push({elem:l,handlers:i})}return s]*)\/>/gi,De=/<([\w:]+)/,Ae=/<|&#?\w+;/,Me=/<(?:script|style|link)/i,Oe=/checked\s*(?:[^=]|=\s*.checked.)/i,Ie=/^$|\/(?:java|ecma)script/i,Pe=/^true\/(.*)/,Ne=/^\s*\s*$/g,je={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};je.optgroup=je.option,je.tbody=je.tfoot=je.colgroup=je.caption=je.thead,je.th=je.td,J.extend({clone:function(e,t,n){var i,r,o,a,s=e.cloneNode(!0),l=J.contains(e.ownerDocument,e);if(!(X.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||J.isXMLDoc(e)))for(a=v(s),o=v(e),i=0,r=o.length;i0&&g(a,!l&&v(e,"script")),s},buildFragment:function(e,t,n,i){for(var r,o,a,s,l,c,u=t.createDocumentFragment(),d=[],f=0,p=e.length;f")+s[2],c=s[0];c--;)o=o.lastChild;J.merge(d,o.childNodes),o=u.firstChild,o.textContent=""}else d.push(t.createTextNode(r));for(u.textContent="",f=0;r=d[f++];)if((!i||-1===J.inArray(r,i))&&(l=J.contains(r.ownerDocument,r),o=v(u.appendChild(r),"script"),l&&g(o),n))for(c=0;r=o[c++];)Ie.test(r.type||"")&&n.push(r);return u},cleanData:function(e){for(var t,n,i,r,o=J.event.special,a=0;void 0!==(n=e[a]);a++){if(J.acceptData(n)&&(r=n[ge.expando])&&(t=ge.cache[r])){if(t.events)for(i in t.events)o[i]?J.event.remove(n,i):J.removeEvent(n,i,t.handle);ge.cache[r]&&delete ge.cache[r]}delete me.cache[n[me.expando]]}}}),J.fn.extend({text:function(e){return he(this,function(e){return void 0===e?J.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){f(this,e).appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=f(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){for(var n,i=e?J.filter(e,this):this,r=0;null!=(n=i[r]);r++)t||1!==n.nodeType||J.cleanData(v(n)),n.parentNode&&(t&&J.contains(n.ownerDocument,n)&&g(v(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(J.cleanData(v(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return J.clone(this,e,t)})},html:function(e){return he(this,function(e){var t=this[0]||{},n=0,i=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Me.test(e)&&!je[(De.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(Te,"<$1>");try{for(;n1&&"string"==typeof f&&!X.checkClone&&Oe.test(f))return this.each(function(n){var i=u.eq(n);g&&(e[0]=f.call(this,n,i.html())),i.domManip(e,t)});if(c&&(n=J.buildFragment(e,this[0].ownerDocument,!1,this),i=n.firstChild,1===n.childNodes.length&&(n=i),i)){for(r=J.map(v(n,"script"),p),o=r.length;l1)},show:function(){return T(this,!0)},hide:function(){return T(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){we(this)?J(this).show():J(this).hide()})}}),J.Tween=D,D.prototype={constructor:D,init:function(e,t,n,i,r,o){this.elem=e,this.prop=n,this.easing=r||"swing",this.options=t,this.start=this.now=this.cur(),this.end=i,this.unit=o||(J.cssNumber[n]?"":"px")},cur:function(){var e=D.propHooks[this.prop];return e&&e.get?e.get(this):D.propHooks._default.get(this)},run:function(e){var t,n=D.propHooks[this.prop];return this.options.duration?this.pos=t=J.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):D.propHooks._default.set(this),this}},D.prototype.init.prototype=D.prototype,D.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=J.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){J.fx.step[e.prop]?J.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[J.cssProps[e.prop]]||J.cssHooks[e.prop])?J.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},D.propHooks.scrollTop=D.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},J.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},J.fx=D.prototype.init,J.fx.step={};var Ye,Ke,Ge=/^(?:toggle|show|hide)$/,Xe=new RegExp("^(?:([+-])=|)("+ye+")([a-z%]*)$","i"),Ze=/queueHooks$/,Je=[I],Qe={"*":[function(e,t){var n=this.createTween(e,t),i=n.cur(),r=Xe.exec(t),o=r&&r[3]||(J.cssNumber[e]?"":"px"),a=(J.cssNumber[e]||"px"!==o&&+i)&&Xe.exec(J.css(n.elem,e)),s=1,l=20;if(a&&a[3]!==o){o=o||a[3],r=r||[],a=+i||1;do{s=s||".5",a/=s,J.style(n.elem,e,a+o)}while(s!==(s=n.cur()/i)&&1!==s&&--l)}return r&&(a=n.start=+a||+i||0,n.unit=o,n.end=r[1]?a+(r[1]+1)*r[2]:+r[2]),n}]};J.Animation=J.extend(N,{tweener:function(e,t){J.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");for(var n,i=0,r=e.length;i1)},removeAttr:function(e){return this.each(function(){J.removeAttr(this,e)})}}),J.extend({attr:function(e,t,n){var i,r,o=e.nodeType;if(e&&3!==o&&8!==o&&2!==o)return void 0===e.getAttribute?J.prop(e,t,n):(1===o&&J.isXMLDoc(e)||(t=t.toLowerCase(),i=J.attrHooks[t]||(J.expr.match.bool.test(t)?et:void 0)),void 0===n?i&&"get"in i&&null!==(r=i.get(e,t))?r:(r=J.find.attr(e,t),null==r?void 0:r):null!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):void J.removeAttr(e,t))},removeAttr:function(e,t){var n,i,r=0,o=t&&t.match(de);if(o&&1===e.nodeType)for(;n=o[r++];)i=J.propFix[n]||n,J.expr.match.bool.test(n)&&(e[i]=!1),e.removeAttribute(n)},attrHooks:{type:{set:function(e,t){if(!X.radioValue&&"radio"===t&&J.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}}}),et={set:function(e,t,n){return!1===t?J.removeAttr(e,n):e.setAttribute(n,n),n}},J.each(J.expr.match.bool.source.match(/\w+/g),function(e,t){var n=tt[t]||J.find.attr;tt[t]=function(e,t,i){var r,o;return i||(o=tt[t],tt[t]=r,r=null!=n(e,t,i)?t.toLowerCase():null,tt[t]=o),r}});var nt=/^(?:input|select|textarea|button)$/i;J.fn.extend({prop:function(e,t){return he(this,J.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[J.propFix[e]||e]})}}),J.extend({propFix:{for:"htmlFor",class:"className"},prop:function(e,t,n){var i,r,o,a=e.nodeType;if(e&&3!==a&&8!==a&&2!==a)return o=1!==a||!J.isXMLDoc(e),o&&(t=J.propFix[t]||t,r=J.propHooks[t]),void 0!==n?r&&"set"in r&&void 0!==(i=r.set(e,n,t))?i:e[t]=n:r&&"get"in r&&null!==(i=r.get(e,t))?i:e[t]},propHooks:{tabIndex:{get:function(e){return e.hasAttribute("tabindex")||nt.test(e.nodeName)||e.href?e.tabIndex:-1}}}}),X.optSelected||(J.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null}}),J.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){J.propFix[this.toLowerCase()]=this});var it=/[\t\r\n\f]/g;J.fn.extend({addClass:function(e){var t,n,i,r,o,a,s="string"==typeof e&&e,l=0,c=this.length;if(J.isFunction(e))return this.each(function(t){J(this).addClass(e.call(this,t,this.className))});if(s)for(t=(e||"").match(de)||[];l=0;)i=i.replace(" "+r+" "," ");a=e?J.trim(i):"",n.className!==a&&(n.className=a)}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):J.isFunction(e)?this.each(function(n){J(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n)for(var t,i=0,r=J(this),o=e.match(de)||[];t=o[i++];)r.hasClass(t)?r.removeClass(t):r.addClass(t);else"undefined"!==n&&"boolean"!==n||(this.className&&ge.set(this,"__className__",this.className),this.className=this.className||!1===e?"":ge.get(this,"__className__")||"")})},hasClass:function(e){for(var t=" "+e+" ",n=0,i=this.length;n=0)return!0;return!1}});var rt=/\r/g;J.fn.extend({val:function(e){var t,n,i,r=this[0];{if(arguments.length)return i=J.isFunction(e),this.each(function(n){var r;1===this.nodeType&&(r=i?e.call(this,n,J(this).val()):e,null==r?r="":"number"==typeof r?r+="":J.isArray(r)&&(r=J.map(r,function(e){return null==e?"":e+""})),(t=J.valHooks[this.type]||J.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,r,"value")||(this.value=r))});if(r)return(t=J.valHooks[r.type]||J.valHooks[r.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(r,"value"))?n:(n=r.value,"string"==typeof n?n.replace(rt,""):null==n?"":n)}}}),J.extend({valHooks:{option:{get:function(e){var t=J.find.attr(e,"value");return null!=t?t:J.trim(J.text(e))}},select:{get:function(e){for(var t,n,i=e.options,r=e.selectedIndex,o="select-one"===e.type||r<0,a=o?null:[],s=o?r+1:i.length,l=r<0?s:o?r:0;l=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),J.each(["radio","checkbox"],function(){J.valHooks[this]={set:function(e,t){if(J.isArray(t))return e.checked=J.inArray(J(e).val(),t)>=0}},X.checkOn||(J.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),J.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){J.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),J.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,i){return this.on(t,e,n,i)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}});var ot=J.now(),at=/\?/;J.parseJSON=function(e){return JSON.parse(e+"")},J.parseXML=function(e){var t,n;if(!e||"string"!=typeof e)return null;try{n=new DOMParser,t=n.parseFromString(e,"text/xml")}catch(e){t=void 0}return t&&!t.getElementsByTagName("parsererror").length||J.error("Invalid XML: "+e),t};var st,lt,ct=/#.*$/,ut=/([?&])_=[^&]*/,dt=/^(.*?):[ \t]*([^\r\n]*)$/gm,ft=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,pt=/^(?:GET|HEAD)$/,ht=/^\/\//,gt=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,mt={},vt={},$t="*/".concat("*");try{lt=location.href}catch(e){lt=Z.createElement("a"),lt.href="",lt=lt.href}st=gt.exec(lt.toLowerCase())||[],J.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:lt,type:"GET",isLocal:ft.test(st[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":$t,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":J.parseJSON,"text xml":J.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?L(L(e,J.ajaxSettings),t):L(J.ajaxSettings,e)},ajaxPrefilter:j(mt),ajaxTransport:j(vt),ajax:function(e,t){function n(e,t,n,a){var l,u,v,$,b,x=t;2!==y&&(y=2,s&&clearTimeout(s),i=void 0,o=a||"",w.readyState=e>0?4:0,l=e>=200&&e<300||304===e,n&&($=R(d,w,n)),$=V(d,$,w,l),l?(d.ifModified&&(b=w.getResponseHeader("Last-Modified"),b&&(J.lastModified[r]=b),(b=w.getResponseHeader("etag"))&&(J.etag[r]=b)),204===e||"HEAD"===d.type?x="nocontent":304===e?x="notmodified":(x=$.state,u=$.data,v=$.error,l=!v)):(v=x,!e&&x||(x="error",e<0&&(e=0))),w.status=e,w.statusText=(t||x)+"",l?h.resolveWith(f,[u,x,w]):h.rejectWith(f,[w,x,v]),w.statusCode(m),m=void 0,c&&p.trigger(l?"ajaxSuccess":"ajaxError",[w,d,l?u:v]),g.fireWith(f,[w,x]),c&&(p.trigger("ajaxComplete",[w,d]),--J.active||J.event.trigger("ajaxStop")))}"object"==typeof e&&(t=e,e=void 0),t=t||{};var i,r,o,a,s,l,c,u,d=J.ajaxSetup({},t),f=d.context||d,p=d.context&&(f.nodeType||f.jquery)?J(f):J.event,h=J.Deferred(),g=J.Callbacks("once memory"),m=d.statusCode||{},v={},$={},y=0,b="canceled",w={readyState:0,getResponseHeader:function(e){var t;if(2===y){if(!a)for(a={};t=dt.exec(o);)a[t[1].toLowerCase()]=t[2];t=a[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===y?o:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return y||(e=$[n]=$[n]||e,v[e]=t),this},overrideMimeType:function(e){return y||(d.mimeType=e),this},statusCode:function(e){var t;if(e)if(y<2)for(t in e)m[t]=[m[t],e[t]];else w.always(e[w.status]);return this},abort:function(e){var t=e||b;return i&&i.abort(t),n(0,t),this}};if(h.promise(w).complete=g.add,w.success=w.done,w.error=w.fail,d.url=((e||d.url||lt)+"").replace(ct,"").replace(ht,st[1]+"//"),d.type=t.method||t.type||d.method||d.type,d.dataTypes=J.trim(d.dataType||"*").toLowerCase().match(de)||[""],null==d.crossDomain&&(l=gt.exec(d.url.toLowerCase()),d.crossDomain=!(!l||l[1]===st[1]&&l[2]===st[2]&&(l[3]||("http:"===l[1]?"80":"443"))===(st[3]||("http:"===st[1]?"80":"443")))),d.data&&d.processData&&"string"!=typeof d.data&&(d.data=J.param(d.data,d.traditional)),F(mt,d,t,w),2===y)return w;c=d.global,c&&0==J.active++&&J.event.trigger("ajaxStart"),d.type=d.type.toUpperCase(),d.hasContent=!pt.test(d.type),r=d.url,d.hasContent||(d.data&&(r=d.url+=(at.test(r)?"&":"?")+d.data,delete d.data),!1===d.cache&&(d.url=ut.test(r)?r.replace(ut,"$1_="+ot++):r+(at.test(r)?"&":"?")+"_="+ot++)),d.ifModified&&(J.lastModified[r]&&w.setRequestHeader("If-Modified-Since",J.lastModified[r]),J.etag[r]&&w.setRequestHeader("If-None-Match",J.etag[r])),(d.data&&d.hasContent&&!1!==d.contentType||t.contentType)&&w.setRequestHeader("Content-Type",d.contentType),w.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+("*"!==d.dataTypes[0]?", "+$t+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)w.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(!1===d.beforeSend.call(f,w,d)||2===y))return w.abort();b="abort";for(u in{success:1,error:1,complete:1})w[u](d[u]);if(i=F(vt,d,t,w)){w.readyState=1,c&&p.trigger("ajaxSend",[w,d]),d.async&&d.timeout>0&&(s=setTimeout(function(){w.abort("timeout")},d.timeout));try{y=1,i.send(v,n)}catch(e){if(!(y<2))throw e;n(-1,e)}}else n(-1,"No Transport");return w},getJSON:function(e,t,n){return J.get(e,t,n,"json")},getScript:function(e,t){return J.get(e,void 0,t,"script")}}),J.each(["get","post"],function(e,t){J[t]=function(e,n,i,r){return J.isFunction(n)&&(r=r||i,i=n,n=void 0),J.ajax({url:e,type:t,dataType:r,data:n,success:i})}}),J.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){J.fn[t]=function(e){return this.on(t,e)}}),J._evalUrl=function(e){return J.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,throws:!0})},J.fn.extend({wrapAll:function(e){var t;return J.isFunction(e)?this.each(function(t){J(this).wrapAll(e.call(this,t))}):(this[0]&&(t=J(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e}).append(this)),this)},wrapInner:function(e){return J.isFunction(e)?this.each(function(t){J(this).wrapInner(e.call(this,t))}):this.each(function(){var t=J(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=J.isFunction(e);return this.each(function(n){J(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){J.nodeName(this,"body")||J(this).replaceWith(this.childNodes)}).end()}}),J.expr.filters.hidden=function(e){return e.offsetWidth<=0&&e.offsetHeight<=0},J.expr.filters.visible=function(e){return!J.expr.filters.hidden(e)};var yt=/%20/g,bt=/\[\]$/,wt=/\r?\n/g,xt=/^(?:submit|button|image|reset|file)$/i,Ct=/^(?:input|select|textarea|keygen)/i;J.param=function(e,t){var n,i=[],r=function(e,t){t=J.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(void 0===t&&(t=J.ajaxSettings&&J.ajaxSettings.traditional),J.isArray(e)||e.jquery&&!J.isPlainObject(e))J.each(e,function(){r(this.name,this.value)});else for(n in e)H(n,e[n],t,r);return i.join("&").replace(yt,"+")},J.fn.extend({serialize:function(){return J.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=J.prop(this,"elements");return e?J.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!J(this).is(":disabled")&&Ct.test(this.nodeName)&&!xt.test(e)&&(this.checked||!xe.test(e))}).map(function(e,t){var n=J(this).val();return null==n?null:J.isArray(n)?J.map(n,function(e){return{name:t.name,value:e.replace(wt,"\r\n")}}):{name:t.name,value:n.replace(wt,"\r\n")}}).get()}}),J.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(e){}};var kt=0,St={},Et={0:200,1223:204},Tt=J.ajaxSettings.xhr();e.ActiveXObject&&J(e).on("unload",function(){for(var e in St)St[e]()}),X.cors=!!Tt&&"withCredentials"in Tt,X.ajax=Tt=!!Tt,J.ajaxTransport(function(e){var t;if(X.cors||Tt&&!e.crossDomain)return{send:function(n,i){var r,o=e.xhr(),a=++kt;if(o.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(r in e.xhrFields)o[r]=e.xhrFields[r];e.mimeType&&o.overrideMimeType&&o.overrideMimeType(e.mimeType),e.crossDomain||n["X-Requested-With"]||(n["X-Requested-With"]="XMLHttpRequest");for(r in n)o.setRequestHeader(r,n[r]);t=function(e){return function(){t&&(delete St[a],t=o.onload=o.onerror=null,"abort"===e?o.abort():"error"===e?i(o.status,o.statusText):i(Et[o.status]||o.status,o.statusText,"string"==typeof o.responseText?{text:o.responseText}:void 0,o.getAllResponseHeaders()))}},o.onload=t(),o.onerror=t("error"),t=St[a]=t("abort");try{o.send(e.hasContent&&e.data||null)}catch(e){if(t)throw e}},abort:function(){t&&t()}}}),J.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return J.globalEval(e),e}}}),J.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),J.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(i,r){t=J("