From 1100c66ce03a059ebe7ece9734e799b49b3a5a9e Mon Sep 17 00:00:00 2001 From: WuKong Date: Sat, 23 Dec 2017 21:49:35 +0100 Subject: moonv4 cleanup Change-Id: Icef927f3236d985ac13ff7376f6ce6314b2b39b0 Signed-off-by: WuKong --- DEV.md | 206 ++ README.md | 381 +++ README.rst | 35 - TODO | 33 + bin/README.md | 5 + bin/bootstrap.py | 235 ++ bin/build_all.sh | 36 + bin/build_all_pip.sh | 16 + bin/delete_orchestrator.sh | 63 + bin/moon_lib_update.sh | 43 + bin/set_auth.src | 7 + bin/start.sh | 39 + conf/moon.conf | 87 + keystonemiddleware-moon/.coveragerc | 7 - keystonemiddleware-moon/.gitignore | 55 - keystonemiddleware-moon/.gitreview | 4 - keystonemiddleware-moon/.testr.conf | 8 - keystonemiddleware-moon/CONTRIBUTING.rst | 16 - keystonemiddleware-moon/HACKING.rst | 24 - keystonemiddleware-moon/LICENSE | 210 -- keystonemiddleware-moon/MANIFEST.in | 7 - keystonemiddleware-moon/README.rst | 19 - keystonemiddleware-moon/babel.cfg | 3 - keystonemiddleware-moon/bandit.yaml | 134 - keystonemiddleware-moon/debian/changelog | 121 - keystonemiddleware-moon/debian/compat | 1 - keystonemiddleware-moon/debian/control | 136 - keystonemiddleware-moon/debian/copyright | 27 - keystonemiddleware-moon/debian/create_deb.py | 196 -- keystonemiddleware-moon/debian/gbp.conf | 9 - .../debian/patches/no-intersphinx.patch | 17 - .../patches/re-add-missing-auth-options.patch | 18 - keystonemiddleware-moon/debian/patches/series | 2 - .../debian/python-keystonemiddleware-doc.doc-base | 9 - keystonemiddleware-moon/debian/rules | 54 - keystonemiddleware-moon/debian/source/format | 1 - keystonemiddleware-moon/debian/source/options | 1 - keystonemiddleware-moon/debian/watch | 3 - keystonemiddleware-moon/doc/.gitignore | 2 - keystonemiddleware-moon/doc/Makefile | 90 - keystonemiddleware-moon/doc/ext/__init__.py | 0 keystonemiddleware-moon/doc/ext/apidoc.py | 46 - keystonemiddleware-moon/doc/source/audit.rst | 81 - keystonemiddleware-moon/doc/source/conf.py | 237 -- .../doc/source/images/audit.png | Bin 48742 -> 0 bytes .../doc/source/images/graphs_authComp.svg | 48 - .../doc/source/images/graphs_authCompDelegate.svg | 53 - keystonemiddleware-moon/doc/source/index.rst | 46 - .../doc/source/middlewarearchitecture.rst | 472 ---- .../examples/pki/certs/cacert.pem | 23 - .../examples/pki/certs/middleware.pem | 50 - .../examples/pki/certs/signing_cert.pem | 22 - .../examples/pki/certs/ssl_cert.pem | 22 - .../examples/pki/cms/auth_token_revoked.json | 85 - .../examples/pki/cms/auth_token_revoked.pem | 75 - .../examples/pki/cms/auth_token_revoked.pkiz | 1 - .../examples/pki/cms/auth_token_scoped.json | 88 - .../examples/pki/cms/auth_token_scoped.pem | 77 - .../examples/pki/cms/auth_token_scoped.pkiz | 1 - .../pki/cms/auth_token_scoped_expired.json | 85 - .../examples/pki/cms/auth_token_scoped_expired.pem | 75 - .../pki/cms/auth_token_scoped_expired.pkiz | 1 - .../examples/pki/cms/auth_token_unscoped.json | 23 - .../examples/pki/cms/auth_token_unscoped.pem | 25 - .../examples/pki/cms/auth_token_unscoped.pkiz | 1 - .../examples/pki/cms/auth_v3_token_revoked.json | 88 - .../examples/pki/cms/auth_v3_token_revoked.pem | 76 - .../examples/pki/cms/auth_v3_token_revoked.pkiz | 1 - .../examples/pki/cms/auth_v3_token_scoped.json | 123 - .../examples/pki/cms/auth_v3_token_scoped.pem | 100 - .../examples/pki/cms/auth_v3_token_scoped.pkiz | 1 - .../examples/pki/cms/revocation_list.der | 0 .../examples/pki/cms/revocation_list.json | 20 - .../examples/pki/cms/revocation_list.pem | 24 - .../examples/pki/cms/revocation_list.pkiz | 1 - keystonemiddleware-moon/examples/pki/gen_cmsz.py | 117 - keystonemiddleware-moon/examples/pki/gen_pki.sh | 213 -- .../examples/pki/private/cakey.pem | 28 - .../examples/pki/private/signing_key.pem | 28 - .../examples/pki/private/ssl_key.pem | 28 - keystonemiddleware-moon/examples/pki/run_all.sh | 31 - .../dependency_links.txt | 1 - .../keystonemiddleware.egg-info/entry_points.txt | 3 - .../keystonemiddleware.egg-info/not-zip-safe | 1 - .../keystonemiddleware.egg-info/top_level.txt | 1 - .../keystonemiddleware/__init__.py | 0 .../keystonemiddleware/audit.py | 449 ---- .../keystonemiddleware/auth_token/__init__.py | 1129 --------- .../keystonemiddleware/auth_token/_auth.py | 194 -- .../keystonemiddleware/auth_token/_base.py | 13 - .../keystonemiddleware/auth_token/_cache.py | 338 --- .../keystonemiddleware/auth_token/_exceptions.py | 27 - .../keystonemiddleware/auth_token/_identity.py | 252 -- .../auth_token/_memcache_crypt.py | 210 -- .../auth_token/_memcache_pool.py | 184 -- .../keystonemiddleware/auth_token/_request.py | 224 -- .../keystonemiddleware/auth_token/_revocations.py | 128 - .../keystonemiddleware/auth_token/_signing_dir.py | 83 - .../keystonemiddleware/auth_token/_user_plugin.py | 193 -- .../keystonemiddleware/auth_token/_utils.py | 32 - .../keystonemiddleware/authz.py | 292 --- .../keystonemiddleware/ec2_token.py | 130 - .../keystonemiddleware/echo/__init__.py | 0 .../keystonemiddleware/echo/__main__.py | 7 - .../keystonemiddleware/echo/service.py | 48 - keystonemiddleware-moon/keystonemiddleware/i18n.py | 37 - .../keystonemiddleware/moon_agent.py | 310 --- .../keystonemiddleware/moon_mgrs/__init__.py | 1 - .../moon_mgrs/abe_mgr/__init__.py | 0 .../moon_mgrs/authz_mgr/__init__.py | 0 .../moon_mgrs/authz_mgr/authz_mgr.py | 106 - .../keystonemiddleware/openstack/__init__.py | 0 .../openstack/common/__init__.py | 0 .../openstack/common/memorycache.py | 97 - keystonemiddleware-moon/keystonemiddleware/opts.py | 52 - .../keystonemiddleware/s3_token.py | 270 -- .../keystonemiddleware/tests/__init__.py | 0 .../keystonemiddleware/tests/unit/__init__.py | 0 .../tests/unit/auth_token/__init__.py | 0 .../tests/unit/auth_token/base.py | 73 - .../tests/unit/auth_token/test_auth.py | 102 - .../unit/auth_token/test_auth_token_middleware.py | 2634 -------------------- .../tests/unit/auth_token/test_base_middleware.py | 202 -- .../tests/unit/auth_token/test_connection_pool.py | 118 - .../tests/unit/auth_token/test_memcache_crypt.py | 97 - .../tests/unit/auth_token/test_request.py | 253 -- .../tests/unit/auth_token/test_revocations.py | 104 - .../tests/unit/auth_token/test_signing_dir.py | 137 - .../tests/unit/auth_token/test_user_auth_plugin.py | 201 -- .../tests/unit/auth_token/test_utils.py | 37 - .../tests/unit/client_fixtures.py | 452 ---- .../tests/unit/test_audit_middleware.py | 560 ----- .../keystonemiddleware/tests/unit/test_opts.py | 86 - .../tests/unit/test_s3_token_middleware.py | 268 -- .../keystonemiddleware/tests/unit/utils.py | 150 -- keystonemiddleware-moon/openstack-common.conf | 7 - keystonemiddleware-moon/requirements.txt | 16 - keystonemiddleware-moon/setup.cfg | 57 - keystonemiddleware-moon/setup.py | 29 - keystonemiddleware-moon/test-requirements-py3.txt | 18 - keystonemiddleware-moon/test-requirements.txt | 24 - .../tools/install_venv_common.py | 172 -- keystonemiddleware-moon/tox.ini | 50 - kubernetes/README.md | 50 + kubernetes/conf/password_moon.txt | 1 + kubernetes/conf/password_root.txt | 1 + kubernetes/conf/ports.conf | 24 + kubernetes/init_k8s.sh | 33 + kubernetes/start_moon.sh | 37 + kubernetes/templates/consul.yaml | 33 + kubernetes/templates/db.yaml | 84 + kubernetes/templates/keystone.yaml | 39 + kubernetes/templates/kube-dns.yaml | 183 ++ kubernetes/templates/moon_configuration.yaml | 25 + kubernetes/templates/moon_gui.yaml | 42 + kubernetes/templates/moon_manager.yaml | 33 + kubernetes/templates/moon_orchestrator.yaml | 40 + moon_authz/Dockerfile | 12 + moon_authz/LICENSE | 202 ++ moon_authz/MANIFEST.in | 9 + moon_authz/README.rst | 9 + moon_authz/moon_authz/__init__.py | 6 + moon_authz/moon_authz/__main__.py | 4 + moon_authz/moon_authz/api/__init__.py | 0 moon_authz/moon_authz/api/authorization.py | 376 +++ moon_authz/moon_authz/api/generic.py | 131 + moon_authz/moon_authz/http_server.py | 140 ++ moon_authz/moon_authz/server.py | 48 + moon_authz/requirements.txt | 5 + moon_authz/setup.py | 47 + moon_authz/tests/unit_python/conftest.py | 29 + moon_authz/tests/unit_python/mock_pods.py | 545 ++++ moon_authz/tests/unit_python/requirements.txt | 5 + moon_authz/tests/unit_python/test_authz.py | 50 + moon_authz/tests/unit_python/utilities.py | 173 ++ moon_bouchon/Dockerfile | 8 + moon_bouchon/README.md | 42 + moon_bouchon/moon_bouchon/__init__.py | 7 + moon_bouchon/moon_bouchon/__main__.py | 9 + moon_bouchon/moon_bouchon/server.py | 138 + moon_bouchon/requirements.txt | 1 + moon_bouchon/setup.cfg | 2 + moon_bouchon/setup.py | 47 + moon_bouchon/tests/test_interface.py | 61 + moon_bouchon/tests/test_wrapper.py | 38 + moon_gui/.gitignore | 4 + moon_gui/.jshintrc | 59 + moon_gui/DEV.md | 49 + moon_gui/Dockerfile | 18 + moon_gui/README.md | 63 + 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 moon_gui/delivery/assets/i18n/en.json | 1357 ++++++++++ moon_gui/delivery/assets/i18n/fr.json | 1357 ++++++++++ moon_gui/delivery/assets/img/ajax-loader.gif | Bin 0 -> 673 bytes moon_gui/delivery/assets/img/ajax-waiting.gif | Bin 0 -> 10819 bytes moon_gui/delivery/assets/img/arrow-link.gif | Bin 0 -> 87 bytes moon_gui/delivery/assets/img/favicon.ico | Bin 0 -> 318 bytes moon_gui/delivery/assets/img/logo-openstack.png | Bin 0 -> 3180 bytes moon_gui/delivery/assets/img/logo-orange.gif | Bin 0 -> 981 bytes .../html/authentication/authentication.tpl.html | 1 + 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 + 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 + moon_gui/delivery/html/model/model-list.tpl.html | 6 + moon_gui/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 + moon_gui/delivery/html/pdp/edit/pdp-edit.tpl.html | 1 + 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-list.tpl.html | 1 + .../policy/edit/parameter/data/data-list.tpl.html | 113 + .../parameter/perimeter/perimeter-list.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 + moon_gui/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 + moon_gui/delivery/index.html | 34 + moon_gui/delivery/js/app.js | 4 + moon_gui/delivery/js/modules.js | 19 + moon_gui/delivery/version.json | 1 + moon_gui/gulpfile.js | 213 ++ moon_gui/package.json | 54 + moon_gui/run.sh | 17 + .../authentication/authentication.controller.js | 58 + .../app/authentication/authentication.tpl.html | 28 + moon_gui/static/app/common/404/404.tpl.html | 3 + .../common/compatibility/compatibility.tpl.html | 26 + .../static/app/common/footer/footer.controller.js | 54 + moon_gui/static/app/common/footer/footer.tpl.html | 7 + .../static/app/common/header/header.controller.js | 56 + moon_gui/static/app/common/header/header.tpl.html | 52 + moon_gui/static/app/common/loader/loader.dir.js | 19 + moon_gui/static/app/common/loader/loader.tpl.html | 1 + .../static/app/common/waiting/waiting.tpl.html | 15 + moon_gui/static/app/dashboard/dashboard.tpl.html | 14 + moon_gui/static/app/logs/logs.controller.js | 16 + 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 | 372 +++ .../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 | 98 + .../model/edit/metarules/metarules-list.tpl.html | 138 + .../app/model/edit/metarules/metarules.list.dir.js | 240 ++ .../app/model/edit/model-edit-basic.tpl.html | 65 + moon_gui/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 + moon_gui/static/app/model/model-list.tpl.html | 123 + moon_gui/static/app/model/model.controller.list.js | 195 ++ moon_gui/static/app/moon.constants.js | 79 + moon_gui/static/app/moon.module.js | 362 +++ moon_gui/static/app/pdp/action/pdp-add.tpl.html | 88 + moon_gui/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 + moon_gui/static/app/pdp/edit/pdp-edit.tpl.html | 64 + .../static/app/pdp/edit/pdp.controller.edit.js | 50 + moon_gui/static/app/pdp/edit/pdp.edit.basic.dir.js | 97 + moon_gui/static/app/pdp/pdp-list.tpl.html | 133 + 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 | 110 + .../policy/edit/parameter/data/data-list.tpl.html | 390 +++ .../policy/edit/parameter/data/data.edit.dir.js | 260 ++ .../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 | 74 + .../app/policy/edit/policy.edit.basic.dir.js | 134 + moon_gui/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 ++ moon_gui/static/app/project/project-list.tpl.html | 157 ++ .../static/app/project/project.controller.list.js | 310 +++ moon_gui/static/app/services/gui/alert.service.js | 39 + .../static/app/services/gui/browser.service.js | 47 + moon_gui/static/app/services/gui/form.service.js | 47 + moon_gui/static/app/services/gui/menu.service.js | 49 + .../app/services/gui/security.pipeline.service.js | 29 + moon_gui/static/app/services/gui/util.service.js | 66 + .../static/app/services/gui/version.service.js | 27 + .../app/services/moon/model/model.service.js | 105 + moon_gui/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 + moon_gui/static/favicon.ico | Bin 0 -> 318 bytes moon_gui/static/i18n/en.json | 1357 ++++++++++ moon_gui/static/i18n/fr.json | 1357 ++++++++++ moon_gui/static/img/ajax-loader.gif | Bin 0 -> 673 bytes moon_gui/static/img/ajax-waiting.gif | Bin 0 -> 10819 bytes moon_gui/static/img/arrow-link.gif | Bin 0 -> 87 bytes moon_gui/static/img/et.jpg | Bin 0 -> 31641 bytes moon_gui/static/img/logo-openstack.png | Bin 0 -> 3180 bytes moon_gui/static/img/logo-orange.gif | Bin 0 -> 981 bytes moon_gui/static/styles/main.css | 173 ++ moon_gui/static/version.json | 3 + moon_gui/templates/index.html | 31 + moon_interface/Dockerfile | 12 + moon_interface/LICENSE | 202 ++ moon_interface/MANIFEST.in | 9 + moon_interface/Makefile | 12 + moon_interface/README.rst | 9 + moon_interface/moon_interface/__init__.py | 6 + moon_interface/moon_interface/__main__.py | 4 + moon_interface/moon_interface/api/__init__.py | 0 moon_interface/moon_interface/api/authz.py | 193 ++ moon_interface/moon_interface/api/generic.py | 131 + moon_interface/moon_interface/authz_requests.py | 159 ++ moon_interface/moon_interface/containers.py | 102 + moon_interface/moon_interface/http_server.py | 136 + moon_interface/moon_interface/server.py | 34 + moon_interface/requirements.txt | 4 + moon_interface/setup.py | 47 + moon_interface/tests/unit_python/api/__init__.py | 0 moon_interface/tests/unit_python/api/test_authz.py | 23 + moon_interface/tests/unit_python/conftest.py | 678 +++++ moon_interface/tests/unit_python/requirements.txt | 5 + moon_interface/tools/api2rst.py | 145 ++ moon_interface/tools/get_keystone_token.py | 71 + moon_interface/tools/run.sh | 5 + moon_manager/Dockerfile | 12 + moon_manager/LICENSE | 202 ++ moon_manager/MANIFEST.in | 9 + moon_manager/README.rst | 9 + moon_manager/moon_manager/__init__.py | 6 + moon_manager/moon_manager/__main__.py | 4 + moon_manager/moon_manager/api/__init__.py | 0 moon_manager/moon_manager/api/assignments.py | 334 +++ moon_manager/moon_manager/api/containers.py | 178 ++ moon_manager/moon_manager/api/data.py | 335 +++ moon_manager/moon_manager/api/generic.py | 131 + moon_manager/moon_manager/api/meta_data.py | 267 ++ moon_manager/moon_manager/api/meta_rules.py | 164 ++ moon_manager/moon_manager/api/models.py | 127 + moon_manager/moon_manager/api/pdp.py | 181 ++ moon_manager/moon_manager/api/perimeter.py | 447 ++++ moon_manager/moon_manager/api/policies.py | 132 + moon_manager/moon_manager/api/rules.py | 140 ++ moon_manager/moon_manager/http_server.py | 157 ++ moon_manager/moon_manager/server.py | 38 + moon_manager/requirements.txt | 6 + moon_manager/setup.py | 47 + moon_manager/tests/unit_python/__init__.py | 0 moon_manager/tests/unit_python/api/__init__.py | 0 .../tests/unit_python/api/test_perimeter.py | 59 + moon_manager/tests/unit_python/conftest.py | 195 ++ moon_manager/tests/unit_python/requirements.txt | 5 + moon_orchestrator/Changelog | 25 + moon_orchestrator/Dockerfile | 15 + moon_orchestrator/LICENSE | 202 ++ moon_orchestrator/MANIFEST.in | 10 + moon_orchestrator/README.md | 3 + moon_orchestrator/conf/dockers/template.dockerfile | 25 + moon_orchestrator/conf/moon.conf | 84 + moon_orchestrator/conf/plugins/authz.py | 67 + moon_orchestrator/conf/plugins/session.py | 67 + .../conf/policies/policy_authz/assignment.json | 55 + .../conf/policies/policy_authz/metadata.json | 23 + .../conf/policies/policy_authz/metarule.json | 24 + .../conf/policies/policy_authz/perimeter.json | 21 + .../conf/policies/policy_authz/rule.json | 25 + .../conf/policies/policy_authz/scope.json | 49 + .../policies/policy_empty_admin/assignment.json | 7 + .../conf/policies/policy_empty_admin/metadata.json | 12 + .../conf/policies/policy_empty_admin/metarule.json | 12 + .../policies/policy_empty_admin/perimeter.json | 39 + .../conf/policies/policy_empty_admin/rule.json | 3 + .../conf/policies/policy_empty_admin/scope.json | 7 + .../policies/policy_empty_authz/assignment.json | 7 + .../conf/policies/policy_empty_authz/metadata.json | 12 + .../conf/policies/policy_empty_authz/metarule.json | 12 + .../policies/policy_empty_authz/perimeter.json | 5 + .../conf/policies/policy_empty_authz/rule.json | 3 + .../conf/policies/policy_empty_authz/scope.json | 7 + .../conf/policies/policy_mls_authz/assignment.json | 29 + .../conf/policies/policy_mls_authz/metadata.json | 18 + .../conf/policies/policy_mls_authz/metarule.json | 12 + .../conf/policies/policy_mls_authz/perimeter.json | 21 + .../conf/policies/policy_mls_authz/rule.json | 16 + .../conf/policies/policy_mls_authz/scope.json | 26 + .../policies/policy_rbac_admin/assignment.json | 48 + .../conf/policies/policy_rbac_admin/metadata.json | 18 + .../conf/policies/policy_rbac_admin/metarule.json | 12 + .../conf/policies/policy_rbac_admin/perimeter.json | 42 + .../conf/policies/policy_rbac_admin/rule.json | 94 + .../conf/policies/policy_rbac_admin/scope.json | 48 + .../conf/policies/policy_root/assignment.json | 39 + .../conf/policies/policy_root/metadata.json | 19 + .../conf/policies/policy_root/metarule.json | 12 + .../conf/policies/policy_root/perimeter.json | 31 + .../conf/policies/policy_root/rule.json | 44 + .../conf/policies/policy_root/scope.json | 39 + moon_orchestrator/moon_orchestrator/__init__.py | 6 + moon_orchestrator/moon_orchestrator/__main__.py | 4 + .../moon_orchestrator/api/__init__.py | 0 moon_orchestrator/moon_orchestrator/api/generic.py | 131 + moon_orchestrator/moon_orchestrator/api/pods.py | 127 + moon_orchestrator/moon_orchestrator/drivers.py | 175 ++ moon_orchestrator/moon_orchestrator/http_server.py | 292 +++ moon_orchestrator/moon_orchestrator/server.py | 36 + moon_orchestrator/requirements.txt | 8 + moon_orchestrator/setup.py | 50 + moon_orchestrator/tests/unit_python/conftest.py | 18 + moon_orchestrator/tests/unit_python/mock_pods.py | 404 +++ .../tests/unit_python/requirements.txt | 5 + moon_orchestrator/tests/unit_python/test_pods.py | 43 + moon_orchestrator/tests/unit_python/utilities.py | 173 ++ moon_wrapper/Dockerfile | 12 + moon_wrapper/LICENSE | 202 ++ moon_wrapper/MANIFEST.in | 9 + moon_wrapper/README.md | 9 + moon_wrapper/moon_wrapper/__init__.py | 6 + moon_wrapper/moon_wrapper/__main__.py | 4 + moon_wrapper/moon_wrapper/api/__init__.py | 0 moon_wrapper/moon_wrapper/api/generic.py | 131 + moon_wrapper/moon_wrapper/api/wrapper.py | 120 + moon_wrapper/moon_wrapper/http_server.py | 140 ++ moon_wrapper/moon_wrapper/server.py | 33 + moon_wrapper/requirements.txt | 5 + moon_wrapper/setup.py | 47 + moon_wrapper/tests/README.md | 35 + moon_wrapper/tests/unit_python/api/__init__.py | 0 moon_wrapper/tests/unit_python/api/test_wrapper.py | 28 + moon_wrapper/tests/unit_python/conftest.py | 687 +++++ moon_wrapper/tests/unit_python/requirements.txt | 5 + moonv4/DEV.md | 206 -- moonv4/README.md | 381 --- moonv4/TODO | 33 - moonv4/bin/README.md | 5 - moonv4/bin/bootstrap.py | 235 -- moonv4/bin/build_all.sh | 36 - moonv4/bin/build_all_pip.sh | 16 - moonv4/bin/delete_orchestrator.sh | 63 - moonv4/bin/moon_lib_update.sh | 43 - moonv4/bin/set_auth.src | 7 - moonv4/bin/start.sh | 39 - moonv4/conf/moon.conf | 87 - moonv4/kubernetes/README.md | 50 - moonv4/kubernetes/conf/password_moon.txt | 1 - moonv4/kubernetes/conf/password_root.txt | 1 - moonv4/kubernetes/conf/ports.conf | 24 - moonv4/kubernetes/init_k8s.sh | 33 - moonv4/kubernetes/start_moon.sh | 37 - moonv4/kubernetes/templates/consul.yaml | 33 - moonv4/kubernetes/templates/db.yaml | 84 - moonv4/kubernetes/templates/keystone.yaml | 39 - moonv4/kubernetes/templates/kube-dns.yaml | 183 -- .../kubernetes/templates/moon_configuration.yaml | 25 - moonv4/kubernetes/templates/moon_gui.yaml | 42 - moonv4/kubernetes/templates/moon_manager.yaml | 33 - moonv4/kubernetes/templates/moon_orchestrator.yaml | 40 - moonv4/moon_authz/Dockerfile | 12 - moonv4/moon_authz/LICENSE | 202 -- moonv4/moon_authz/MANIFEST.in | 9 - moonv4/moon_authz/README.rst | 9 - moonv4/moon_authz/moon_authz/__init__.py | 6 - moonv4/moon_authz/moon_authz/__main__.py | 4 - moonv4/moon_authz/moon_authz/api/__init__.py | 0 moonv4/moon_authz/moon_authz/api/authorization.py | 376 --- moonv4/moon_authz/moon_authz/api/generic.py | 131 - moonv4/moon_authz/moon_authz/http_server.py | 140 -- moonv4/moon_authz/moon_authz/server.py | 48 - moonv4/moon_authz/requirements.txt | 5 - moonv4/moon_authz/setup.py | 47 - moonv4/moon_authz/tests/unit_python/conftest.py | 29 - moonv4/moon_authz/tests/unit_python/mock_pods.py | 545 ---- .../moon_authz/tests/unit_python/requirements.txt | 5 - moonv4/moon_authz/tests/unit_python/test_authz.py | 50 - moonv4/moon_authz/tests/unit_python/utilities.py | 173 -- moonv4/moon_bouchon/Dockerfile | 8 - moonv4/moon_bouchon/README.md | 42 - moonv4/moon_bouchon/moon_bouchon/__init__.py | 7 - moonv4/moon_bouchon/moon_bouchon/__main__.py | 9 - moonv4/moon_bouchon/moon_bouchon/server.py | 138 - moonv4/moon_bouchon/requirements.txt | 1 - moonv4/moon_bouchon/setup.cfg | 2 - moonv4/moon_bouchon/setup.py | 47 - moonv4/moon_bouchon/tests/test_interface.py | 61 - moonv4/moon_bouchon/tests/test_wrapper.py | 38 - moonv4/moon_gui/.gitignore | 4 - moonv4/moon_gui/.jshintrc | 59 - moonv4/moon_gui/DEV.md | 49 - moonv4/moon_gui/Dockerfile | 18 - moonv4/moon_gui/README.md | 63 - moonv4/moon_gui/delivery/assets/css/main.css | 10 - .../assets/fonts/glyphicons-halflings-regular.eot | Bin 20335 -> 0 bytes .../assets/fonts/glyphicons-halflings-regular.svg | 229 -- .../assets/fonts/glyphicons-halflings-regular.ttf | Bin 41280 -> 0 bytes .../assets/fonts/glyphicons-halflings-regular.woff | Bin 23320 -> 0 bytes moonv4/moon_gui/delivery/assets/i18n/en.json | 1357 ---------- moonv4/moon_gui/delivery/assets/i18n/fr.json | 1357 ---------- .../moon_gui/delivery/assets/img/ajax-loader.gif | Bin 673 -> 0 bytes .../moon_gui/delivery/assets/img/ajax-waiting.gif | Bin 10819 -> 0 bytes moonv4/moon_gui/delivery/assets/img/arrow-link.gif | Bin 87 -> 0 bytes moonv4/moon_gui/delivery/assets/img/favicon.ico | Bin 318 -> 0 bytes .../delivery/assets/img/logo-openstack.png | Bin 3180 -> 0 bytes .../moon_gui/delivery/assets/img/logo-orange.gif | Bin 981 -> 0 bytes .../html/authentication/authentication.tpl.html | 1 - .../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 - moonv4/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 - .../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-list.tpl.html | 1 - .../policy/edit/parameter/data/data-list.tpl.html | 113 - .../parameter/perimeter/perimeter-list.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 - moonv4/moon_gui/delivery/index.html | 34 - moonv4/moon_gui/delivery/js/app.js | 4 - moonv4/moon_gui/delivery/js/modules.js | 19 - moonv4/moon_gui/delivery/version.json | 1 - moonv4/moon_gui/gulpfile.js | 213 -- moonv4/moon_gui/package.json | 54 - moonv4/moon_gui/run.sh | 17 - .../authentication/authentication.controller.js | 58 - .../app/authentication/authentication.tpl.html | 28 - moonv4/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 - moonv4/moon_gui/static/app/logs/logs.controller.js | 16 - moonv4/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 | 372 --- .../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 | 98 - .../model/edit/metarules/metarules-list.tpl.html | 138 - .../app/model/edit/metarules/metarules.list.dir.js | 240 -- .../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 - .../moon_gui/static/app/model/model-list.tpl.html | 123 - .../static/app/model/model.controller.list.js | 195 -- moonv4/moon_gui/static/app/moon.constants.js | 79 - moonv4/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 - .../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 - moonv4/moon_gui/static/app/pdp/pdp-list.tpl.html | 133 - .../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 | 110 - .../policy/edit/parameter/data/data-list.tpl.html | 390 --- .../policy/edit/parameter/data/data.edit.dir.js | 260 -- .../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 | 74 - .../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 - moonv4/moon_gui/static/favicon.ico | Bin 318 -> 0 bytes moonv4/moon_gui/static/i18n/en.json | 1357 ---------- moonv4/moon_gui/static/i18n/fr.json | 1357 ---------- moonv4/moon_gui/static/img/ajax-loader.gif | Bin 673 -> 0 bytes moonv4/moon_gui/static/img/ajax-waiting.gif | Bin 10819 -> 0 bytes moonv4/moon_gui/static/img/arrow-link.gif | Bin 87 -> 0 bytes moonv4/moon_gui/static/img/et.jpg | Bin 31641 -> 0 bytes moonv4/moon_gui/static/img/logo-openstack.png | Bin 3180 -> 0 bytes moonv4/moon_gui/static/img/logo-orange.gif | Bin 981 -> 0 bytes moonv4/moon_gui/static/styles/main.css | 173 -- moonv4/moon_gui/static/version.json | 3 - moonv4/moon_gui/templates/index.html | 31 - moonv4/moon_interface/.cache/v/cache/lastfailed | 1 - moonv4/moon_interface/Dockerfile | 12 - moonv4/moon_interface/LICENSE | 202 -- moonv4/moon_interface/MANIFEST.in | 9 - moonv4/moon_interface/Makefile | 12 - moonv4/moon_interface/README.rst | 9 - moonv4/moon_interface/moon_interface/__init__.py | 6 - moonv4/moon_interface/moon_interface/__main__.py | 4 - .../moon_interface/moon_interface/api/__init__.py | 0 moonv4/moon_interface/moon_interface/api/authz.py | 193 -- .../moon_interface/moon_interface/api/generic.py | 131 - .../moon_interface/authz_requests.py | 159 -- moonv4/moon_interface/moon_interface/containers.py | 102 - .../moon_interface/moon_interface/http_server.py | 136 - moonv4/moon_interface/moon_interface/server.py | 34 - moonv4/moon_interface/requirements.txt | 4 - moonv4/moon_interface/setup.py | 47 - .../tests/unit_python/api/__init__.py | 0 .../tests/unit_python/api/test_authz.py | 23 - .../moon_interface/tests/unit_python/conftest.py | 678 ----- .../tests/unit_python/requirements.txt | 5 - moonv4/moon_interface/tools/api2rst.py | 145 -- moonv4/moon_interface/tools/get_keystone_token.py | 71 - moonv4/moon_interface/tools/run.sh | 5 - moonv4/moon_manager/Dockerfile | 12 - moonv4/moon_manager/LICENSE | 202 -- moonv4/moon_manager/MANIFEST.in | 9 - moonv4/moon_manager/README.rst | 9 - moonv4/moon_manager/moon_manager/__init__.py | 6 - moonv4/moon_manager/moon_manager/__main__.py | 4 - moonv4/moon_manager/moon_manager/api/__init__.py | 0 .../moon_manager/moon_manager/api/assignments.py | 334 --- moonv4/moon_manager/moon_manager/api/containers.py | 178 -- moonv4/moon_manager/moon_manager/api/data.py | 335 --- moonv4/moon_manager/moon_manager/api/generic.py | 131 - moonv4/moon_manager/moon_manager/api/meta_data.py | 267 -- moonv4/moon_manager/moon_manager/api/meta_rules.py | 164 -- moonv4/moon_manager/moon_manager/api/models.py | 127 - moonv4/moon_manager/moon_manager/api/pdp.py | 181 -- moonv4/moon_manager/moon_manager/api/perimeter.py | 447 ---- moonv4/moon_manager/moon_manager/api/policies.py | 132 - moonv4/moon_manager/moon_manager/api/rules.py | 140 -- moonv4/moon_manager/moon_manager/http_server.py | 157 -- moonv4/moon_manager/moon_manager/server.py | 38 - moonv4/moon_manager/requirements.txt | 6 - moonv4/moon_manager/setup.py | 47 - moonv4/moon_manager/tests/unit_python/__init__.py | 0 .../moon_manager/tests/unit_python/api/__init__.py | 0 .../tests/unit_python/api/test_perimeter.py | 59 - moonv4/moon_manager/tests/unit_python/conftest.py | 195 -- .../tests/unit_python/requirements.txt | 5 - moonv4/moon_orchestrator/Changelog | 25 - moonv4/moon_orchestrator/Dockerfile | 15 - moonv4/moon_orchestrator/LICENSE | 202 -- moonv4/moon_orchestrator/MANIFEST.in | 10 - moonv4/moon_orchestrator/README.md | 3 - .../conf/dockers/template.dockerfile | 25 - moonv4/moon_orchestrator/conf/moon.conf | 84 - moonv4/moon_orchestrator/conf/plugins/authz.py | 67 - moonv4/moon_orchestrator/conf/plugins/session.py | 67 - .../conf/policies/policy_authz/assignment.json | 55 - .../conf/policies/policy_authz/metadata.json | 23 - .../conf/policies/policy_authz/metarule.json | 24 - .../conf/policies/policy_authz/perimeter.json | 21 - .../conf/policies/policy_authz/rule.json | 25 - .../conf/policies/policy_authz/scope.json | 49 - .../policies/policy_empty_admin/assignment.json | 7 - .../conf/policies/policy_empty_admin/metadata.json | 12 - .../conf/policies/policy_empty_admin/metarule.json | 12 - .../policies/policy_empty_admin/perimeter.json | 39 - .../conf/policies/policy_empty_admin/rule.json | 3 - .../conf/policies/policy_empty_admin/scope.json | 7 - .../policies/policy_empty_authz/assignment.json | 7 - .../conf/policies/policy_empty_authz/metadata.json | 12 - .../conf/policies/policy_empty_authz/metarule.json | 12 - .../policies/policy_empty_authz/perimeter.json | 5 - .../conf/policies/policy_empty_authz/rule.json | 3 - .../conf/policies/policy_empty_authz/scope.json | 7 - .../conf/policies/policy_mls_authz/assignment.json | 29 - .../conf/policies/policy_mls_authz/metadata.json | 18 - .../conf/policies/policy_mls_authz/metarule.json | 12 - .../conf/policies/policy_mls_authz/perimeter.json | 21 - .../conf/policies/policy_mls_authz/rule.json | 16 - .../conf/policies/policy_mls_authz/scope.json | 26 - .../policies/policy_rbac_admin/assignment.json | 48 - .../conf/policies/policy_rbac_admin/metadata.json | 18 - .../conf/policies/policy_rbac_admin/metarule.json | 12 - .../conf/policies/policy_rbac_admin/perimeter.json | 42 - .../conf/policies/policy_rbac_admin/rule.json | 94 - .../conf/policies/policy_rbac_admin/scope.json | 48 - .../conf/policies/policy_root/assignment.json | 39 - .../conf/policies/policy_root/metadata.json | 19 - .../conf/policies/policy_root/metarule.json | 12 - .../conf/policies/policy_root/perimeter.json | 31 - .../conf/policies/policy_root/rule.json | 44 - .../conf/policies/policy_root/scope.json | 39 - .../moon_orchestrator/__init__.py | 6 - .../moon_orchestrator/__main__.py | 4 - .../moon_orchestrator/api/__init__.py | 0 .../moon_orchestrator/api/generic.py | 131 - .../moon_orchestrator/api/pods.py | 127 - .../moon_orchestrator/moon_orchestrator/drivers.py | 175 -- .../moon_orchestrator/http_server.py | 292 --- .../moon_orchestrator/moon_orchestrator/server.py | 36 - moonv4/moon_orchestrator/requirements.txt | 8 - moonv4/moon_orchestrator/setup.py | 50 - .../tests/unit_python/conftest.py | 18 - .../tests/unit_python/mock_pods.py | 404 --- .../tests/unit_python/requirements.txt | 5 - .../tests/unit_python/test_pods.py | 43 - .../tests/unit_python/utilities.py | 173 -- moonv4/moon_wrapper/Dockerfile | 12 - moonv4/moon_wrapper/LICENSE | 202 -- moonv4/moon_wrapper/MANIFEST.in | 9 - moonv4/moon_wrapper/README.md | 9 - moonv4/moon_wrapper/moon_wrapper/__init__.py | 6 - moonv4/moon_wrapper/moon_wrapper/__main__.py | 4 - moonv4/moon_wrapper/moon_wrapper/api/__init__.py | 0 moonv4/moon_wrapper/moon_wrapper/api/generic.py | 131 - moonv4/moon_wrapper/moon_wrapper/api/wrapper.py | 120 - moonv4/moon_wrapper/moon_wrapper/http_server.py | 140 -- moonv4/moon_wrapper/moon_wrapper/server.py | 33 - moonv4/moon_wrapper/requirements.txt | 5 - moonv4/moon_wrapper/setup.py | 47 - moonv4/moon_wrapper/tests/README.md | 35 - .../moon_wrapper/tests/unit_python/api/__init__.py | 0 .../tests/unit_python/api/test_wrapper.py | 28 - moonv4/moon_wrapper/tests/unit_python/conftest.py | 687 ----- .../tests/unit_python/requirements.txt | 5 - moonv4/python_moonclient/Changelog | 12 - moonv4/python_moonclient/LICENSE | 202 -- moonv4/python_moonclient/MANIFEST.in | 10 - moonv4/python_moonclient/README.md | 33 - .../python_moonclient/__init__.py | 6 - .../python_moonclient/python_moonclient/authz.py | 178 -- .../python_moonclient/python_moonclient/config.py | 44 - .../python_moonclient/python_moonclient/models.py | 319 --- .../python_moonclient/python_moonclient/parse.py | 83 - moonv4/python_moonclient/python_moonclient/pdp.py | 211 -- .../python_moonclient/policies.py | 763 ------ moonv4/python_moonclient/requirements.txt | 3 - moonv4/python_moonclient/setup.py | 42 - .../tests/unit_python/conftest.py | 12 - .../tests/unit_python/mock_config.py | 35 - .../tests/unit_python/requirements.txt | 2 - .../tests/unit_python/test_config.py | 8 - .../tests/unit_python/test_models.py | 37 - .../tests/unit_python/test_pdp.py | 16 - .../tests/unit_python/test_policies.py | 157 -- .../tests/unit_python/utilities.py | 153 -- moonv4/python_moondb/Changelog | 55 - moonv4/python_moondb/LICENSE | 202 -- moonv4/python_moondb/MANIFEST.in | 10 - moonv4/python_moondb/README.md | 32 - moonv4/python_moondb/bin/drop_tables.sql | 18 - moonv4/python_moondb/build.sh | 38 - moonv4/python_moondb/python_moondb/__init__.py | 7 - moonv4/python_moondb/python_moondb/api/__init__.py | 0 moonv4/python_moondb/python_moondb/api/keystone.py | 106 - moonv4/python_moondb/python_moondb/api/managers.py | 15 - moonv4/python_moondb/python_moondb/api/model.py | 132 - moonv4/python_moondb/python_moondb/api/pdp.py | 38 - moonv4/python_moondb/python_moondb/api/policy.py | 248 -- .../python_moondb/backends/__init__.py | 97 - .../python_moondb/python_moondb/backends/flat.py | 89 - moonv4/python_moondb/python_moondb/backends/sql.py | 1875 -------------- moonv4/python_moondb/python_moondb/core.py | 297 --- moonv4/python_moondb/python_moondb/db_manager.py | 82 - .../python_moondb/migrate_repo/__init__.py | 0 .../migrate_repo/versions/001_moon.py | 216 -- .../migrate_repo/versions/__init__.py | 0 moonv4/python_moondb/requirements.txt | 6 - moonv4/python_moondb/setup.py | 55 - moonv4/python_moondb/tests/unit_python/conftest.py | 145 -- .../tests/unit_python/mock_components.py | 27 - .../tests/unit_python/mock_keystone.py | 23 - .../tests/unit_python/requirements.txt | 5 - .../tests/unit_python/test_policies.py | 77 - .../python_moondb/tests/unit_python/utilities.py | 136 - moonv4/python_moonutilities/Changelog | 72 - moonv4/python_moonutilities/LICENSE | 202 -- moonv4/python_moonutilities/MANIFEST.in | 10 - moonv4/python_moonutilities/README.md | 33 - .../python_moonutilities/__init__.py | 6 - .../python_moonutilities/api.py | 28 - .../python_moonutilities/auth.py | 76 - .../python_moonutilities/cache.py | 543 ---- .../python_moonutilities/configuration.py | 114 - .../python_moonutilities/exceptions.py | 522 ---- .../python_moonutilities/misc.py | 142 -- .../python_moonutilities/security_functions.py | 531 ---- moonv4/python_moonutilities/requirements.txt | 3 - moonv4/python_moonutilities/setup.py | 42 - .../tests/unit_python/conftest.py | 17 - .../tests/unit_python/mock_cache.py | 321 --- .../tests/unit_python/mock_components.py | 27 - .../tests/unit_python/mock_keystone.py | 23 - .../tests/unit_python/requirements.txt | 2 - .../tests/unit_python/test_cache.py | 75 - .../tests/unit_python/test_configuration.py | 5 - .../tests/unit_python/utilities.py | 136 - moonv4/templates/glance/policy.json | 62 - moonv4/templates/moon_keystone/Dockerfile | 25 - moonv4/templates/moon_keystone/README.md | 26 - moonv4/templates/moon_keystone/run.sh | 81 - moonv4/templates/moonforming/Dockerfile | 10 - moonv4/templates/moonforming/README.md | 12 - moonv4/templates/moonforming/conf/mls.py | 59 - moonv4/templates/moonforming/conf/rbac.py | 61 - moonv4/templates/moonforming/conf2consul.py | 103 - moonv4/templates/moonforming/moon.conf | 79 - .../moonforming/populate_default_values.py | 235 -- moonv4/templates/moonforming/run.sh | 44 - moonv4/templates/moonforming/utils/__init__.py | 0 moonv4/templates/moonforming/utils/config.py | 22 - moonv4/templates/moonforming/utils/models.py | 270 -- moonv4/templates/moonforming/utils/pdp.py | 163 -- moonv4/templates/moonforming/utils/policies.py | 635 ----- moonv4/templates/nova/policy.json | 488 ---- moonv4/templates/python_unit_test/Dockerfile | 8 - moonv4/templates/python_unit_test/README.md | 8 - moonv4/templates/python_unit_test/requirements.txt | 10 - moonv4/templates/python_unit_test/run_tests.sh | 13 - moonv4/tests/get_keystone_projects.py | 16 - moonv4/tests/performance/README.md | 69 - moonv4/tests/populate_default_values.py | 37 - moonv4/tests/scenario/delegation.py | 40 - moonv4/tests/scenario/mls.py | 54 - moonv4/tests/scenario/rbac.py | 44 - moonv4/tests/scenario/rbac_custom_100.py | 89 - moonv4/tests/scenario/rbac_custom_1000.py | 89 - moonv4/tests/scenario/rbac_custom_50.py | 89 - moonv4/tests/scenario/rbac_large.py | 233 -- moonv4/tests/scenario/rbac_mls.py | 50 - moonv4/tests/scenario/session.py | 60 - moonv4/tests/scenario/session_large.py | 389 --- moonv4/tests/send_authz.py | 32 - python_moonclient/Changelog | 12 + python_moonclient/LICENSE | 202 ++ python_moonclient/MANIFEST.in | 10 + python_moonclient/README.md | 33 + python_moonclient/python_moonclient/__init__.py | 6 + python_moonclient/python_moonclient/authz.py | 178 ++ python_moonclient/python_moonclient/config.py | 44 + python_moonclient/python_moonclient/models.py | 319 +++ python_moonclient/python_moonclient/parse.py | 83 + python_moonclient/python_moonclient/pdp.py | 211 ++ python_moonclient/python_moonclient/policies.py | 763 ++++++ python_moonclient/requirements.txt | 3 + python_moonclient/setup.py | 42 + python_moonclient/tests/unit_python/conftest.py | 12 + python_moonclient/tests/unit_python/mock_config.py | 35 + .../tests/unit_python/requirements.txt | 2 + python_moonclient/tests/unit_python/test_config.py | 8 + python_moonclient/tests/unit_python/test_models.py | 37 + python_moonclient/tests/unit_python/test_pdp.py | 16 + .../tests/unit_python/test_policies.py | 157 ++ python_moonclient/tests/unit_python/utilities.py | 153 ++ python_moondb/Changelog | 55 + python_moondb/LICENSE | 202 ++ python_moondb/MANIFEST.in | 10 + python_moondb/README.md | 32 + python_moondb/bin/drop_tables.sql | 18 + python_moondb/build.sh | 38 + python_moondb/python_moondb/__init__.py | 7 + python_moondb/python_moondb/api/__init__.py | 0 python_moondb/python_moondb/api/keystone.py | 106 + python_moondb/python_moondb/api/managers.py | 15 + python_moondb/python_moondb/api/model.py | 132 + python_moondb/python_moondb/api/pdp.py | 38 + python_moondb/python_moondb/api/policy.py | 248 ++ python_moondb/python_moondb/backends/__init__.py | 97 + python_moondb/python_moondb/backends/flat.py | 89 + python_moondb/python_moondb/backends/sql.py | 1875 ++++++++++++++ python_moondb/python_moondb/core.py | 297 +++ python_moondb/python_moondb/db_manager.py | 82 + .../python_moondb/migrate_repo/__init__.py | 0 .../migrate_repo/versions/001_moon.py | 216 ++ .../migrate_repo/versions/__init__.py | 0 python_moondb/requirements.txt | 6 + python_moondb/setup.py | 55 + python_moondb/tests/unit_python/conftest.py | 145 ++ python_moondb/tests/unit_python/mock_components.py | 27 + python_moondb/tests/unit_python/mock_keystone.py | 23 + python_moondb/tests/unit_python/requirements.txt | 5 + python_moondb/tests/unit_python/test_policies.py | 77 + python_moondb/tests/unit_python/utilities.py | 136 + python_moonutilities/Changelog | 72 + python_moonutilities/LICENSE | 202 ++ python_moonutilities/MANIFEST.in | 10 + python_moonutilities/README.md | 33 + .../python_moonutilities/__init__.py | 6 + python_moonutilities/python_moonutilities/api.py | 28 + python_moonutilities/python_moonutilities/auth.py | 76 + python_moonutilities/python_moonutilities/cache.py | 543 ++++ .../python_moonutilities/configuration.py | 114 + .../python_moonutilities/exceptions.py | 522 ++++ python_moonutilities/python_moonutilities/misc.py | 142 ++ .../python_moonutilities/security_functions.py | 531 ++++ python_moonutilities/requirements.txt | 3 + python_moonutilities/setup.py | 42 + python_moonutilities/tests/unit_python/conftest.py | 17 + .../tests/unit_python/mock_cache.py | 321 +++ .../tests/unit_python/mock_components.py | 27 + .../tests/unit_python/mock_keystone.py | 23 + .../tests/unit_python/requirements.txt | 2 + .../tests/unit_python/test_cache.py | 75 + .../tests/unit_python/test_configuration.py | 5 + .../tests/unit_python/utilities.py | 136 + templates/glance/policy.json | 62 + templates/moon_keystone/Dockerfile | 25 + templates/moon_keystone/README.md | 26 + templates/moon_keystone/run.sh | 81 + templates/moonforming/Dockerfile | 10 + templates/moonforming/README.md | 12 + templates/moonforming/conf/mls.py | 59 + templates/moonforming/conf/rbac.py | 61 + templates/moonforming/conf2consul.py | 103 + templates/moonforming/moon.conf | 79 + templates/moonforming/populate_default_values.py | 235 ++ templates/moonforming/run.sh | 44 + templates/moonforming/utils/__init__.py | 0 templates/moonforming/utils/config.py | 22 + templates/moonforming/utils/models.py | 270 ++ templates/moonforming/utils/pdp.py | 163 ++ templates/moonforming/utils/policies.py | 635 +++++ templates/nova/policy.json | 488 ++++ templates/python_unit_test/Dockerfile | 8 + templates/python_unit_test/README.md | 8 + templates/python_unit_test/requirements.txt | 10 + templates/python_unit_test/run_tests.sh | 13 + tests/get_keystone_projects.py | 16 + tests/performance/README.md | 69 + tests/populate_default_values.py | 37 + tests/run_tests.py | 186 -- tests/run_tests.sh | 14 - tests/scenario/delegation.py | 40 + tests/scenario/mls.py | 54 + tests/scenario/rbac.py | 44 + tests/scenario/rbac_custom_100.py | 89 + tests/scenario/rbac_custom_1000.py | 89 + tests/scenario/rbac_custom_50.py | 89 + tests/scenario/rbac_large.py | 233 ++ tests/scenario/rbac_mls.py | 50 + tests/scenario/session.py | 60 + tests/scenario/session_large.py | 389 +++ tests/send_authz.py | 32 + upstream/odl-aaa-moon/aaa/.gitignore | 26 - upstream/odl-aaa-moon/aaa/README.md | 62 - upstream/odl-aaa-moon/aaa/aaa-authn-api/pom.xml | 38 - .../aaa/aaa-authn-api/src/main/docs/Makefile | 29 - .../aaa-authn-api/src/main/docs/class_diagram.png | Bin 30016 -> 0 bytes .../aaa-authn-api/src/main/docs/class_diagram.ucls | 127 - .../src/main/docs/credential_auth_sequence.png | Bin 29197 -> 0 bytes .../src/main/docs/credential_auth_sequence.wsd | 18 - .../src/main/docs/federated_auth_sequence.png | Bin 40566 -> 0 bytes .../src/main/docs/federated_auth_sequence.wsd | 24 - .../aaa/aaa-authn-api/src/main/docs/mapping.rst | 1609 ------------ .../src/main/docs/resource_access_sequence.png | Bin 38693 -> 0 bytes .../src/main/docs/resource_access_sequence.wsd | 25 - .../aaa/aaa-authn-api/src/main/docs/sssd_01.diag | 6 - .../aaa/aaa-authn-api/src/main/docs/sssd_01.svg | 32 - .../aaa/aaa-authn-api/src/main/docs/sssd_02.diag | 18 - .../aaa/aaa-authn-api/src/main/docs/sssd_02.svg | 79 - .../aaa/aaa-authn-api/src/main/docs/sssd_03.diag | 31 - .../aaa/aaa-authn-api/src/main/docs/sssd_03.svg | 143 -- .../aaa/aaa-authn-api/src/main/docs/sssd_04.diag | 25 - .../aaa/aaa-authn-api/src/main/docs/sssd_04.svg | 100 - .../aaa/aaa-authn-api/src/main/docs/sssd_05.svg | 613 ----- .../src/main/docs/sssd_auth_sequence.png | Bin 39322 -> 0 bytes .../src/main/docs/sssd_auth_sequence.wsd | 23 - .../src/main/docs/sssd_configuration.rst | 1687 ------------- .../org/opendaylight/aaa/api/Authentication.java | 26 - .../aaa/api/AuthenticationException.java | 31 - .../aaa/api/AuthenticationService.java | 42 - .../main/java/org/opendaylight/aaa/api/Claim.java | 56 - .../java/org/opendaylight/aaa/api/ClaimAuth.java | 37 - .../org/opendaylight/aaa/api/ClientService.java | 20 - .../org/opendaylight/aaa/api/CredentialAuth.java | 28 - .../java/org/opendaylight/aaa/api/Credentials.java | 15 - .../opendaylight/aaa/api/IDMStoreException.java | 24 - .../org/opendaylight/aaa/api/IDMStoreUtil.java | 40 - .../java/org/opendaylight/aaa/api/IIDMStore.java | 72 - .../java/org/opendaylight/aaa/api/IdMService.java | 39 - .../opendaylight/aaa/api/PasswordCredentials.java | 20 - .../org/opendaylight/aaa/api/SHA256Calculator.java | 74 - .../java/org/opendaylight/aaa/api/TokenAuth.java | 37 - .../java/org/opendaylight/aaa/api/TokenStore.java | 25 - .../java/org/opendaylight/aaa/api/model/Claim.java | 60 - .../org/opendaylight/aaa/api/model/Domain.java | 86 - .../org/opendaylight/aaa/api/model/Domains.java | 34 - .../java/org/opendaylight/aaa/api/model/Grant.java | 86 - .../org/opendaylight/aaa/api/model/Grants.java | 35 - .../org/opendaylight/aaa/api/model/IDMError.java | 61 - .../java/org/opendaylight/aaa/api/model/Role.java | 86 - .../java/org/opendaylight/aaa/api/model/Roles.java | 34 - .../java/org/opendaylight/aaa/api/model/User.java | 126 - .../org/opendaylight/aaa/api/model/UserPwd.java | 40 - .../java/org/opendaylight/aaa/api/model/Users.java | 34 - .../org/opendaylight/aaa/api/model/Version.java | 49 - upstream/odl-aaa-moon/aaa/aaa-authn-basic/pom.xml | 76 - .../java/org/opendaylight/aaa/basic/Activator.java | 31 - .../org/opendaylight/aaa/basic/HttpBasicAuth.java | 129 - .../opendaylight/aaa/basic/HttpBasicAuthTest.java | 102 - .../odl-aaa-moon/aaa/aaa-authn-federation/pom.xml | 132 - .../org/opendaylight/aaa/federation/Activator.java | 51 - .../aaa/federation/ClaimAuthFilter.java | 249 -- .../aaa/federation/FederationConfiguration.java | 95 - .../aaa/federation/FederationEndpoint.java | 149 -- .../aaa/federation/ServiceLocator.java | 83 - .../opendaylight/aaa/federation/SssdFilter.java | 151 -- .../OSGI-INF/metatype/metatype.properties | 11 - .../main/resources/OSGI-INF/metatype/metatype.xml | 19 - .../src/main/resources/WEB-INF/web.xml | 34 - .../src/main/resources/federation.cfg | 3 - .../aaa/federation/FederationEndpointTest.java | 121 - .../odl-aaa-moon/aaa/aaa-authn-keystone/pom.xml | 106 - .../org/opendaylight/aaa/keystone/Activator.java | 34 - .../aaa/keystone/KeystoneTokenAuth.java | 39 - .../aaa-authn-mdsal-api/pom.xml | 99 - .../src/main/yang/aaa-authn-model.yang | 154 -- .../aaa-authn-mdsal-config/pom.xml | 40 - .../src/main/resources/initial/08-authn-config.xml | 43 - .../aaa-authn-mdsal-store-impl/pom.xml | 169 -- .../aaa/authn/mdsal/store/AuthNStore.java | 263 -- .../aaa/authn/mdsal/store/DataEncrypter.java | 101 - .../aaa/authn/mdsal/store/IDMMDSALStore.java | 483 ---- .../aaa/authn/mdsal/store/IDMObject2MDSAL.java | 224 -- .../aaa/authn/mdsal/store/IDMStore.java | 182 -- .../aaa/authn/mdsal/store/util/AuthNStoreUtil.java | 140 -- .../mdsal/store/rev141031/AuthNStoreModule.java | 90 - .../store/rev141031/AuthNStoreModuleFactory.java | 46 - .../src/main/yang/aaa-authn-mdsal-store-cfg.yang | 77 - .../authn/mdsal/store/DataBrokerReadMocker.java | 112 - .../aaa/authn/mdsal/store/DataEncrypterTest.java | 38 - .../aaa/authn/mdsal/store/IDMStoreTest.java | 175 -- .../aaa/authn/mdsal/store/IDMStoreTestUtil.java | 181 -- .../aaa/authn/mdsal/store/MDSALConvertTest.java | 78 - .../authn/mdsal/store/util/AuthNStoreUtilTest.java | 88 - .../odl-aaa-moon/aaa/aaa-authn-mdsal-store/pom.xml | 22 - upstream/odl-aaa-moon/aaa/aaa-authn-sssd/pom.xml | 88 - .../java/org/opendaylight/aaa/sssd/Activator.java | 28 - .../org/opendaylight/aaa/sssd/SssdClaimAuth.java | 220 -- upstream/odl-aaa-moon/aaa/aaa-authn-store/pom.xml | 100 - .../java/org/opendaylight/aaa/store/Activator.java | 45 - .../opendaylight/aaa/store/DefaultTokenStore.java | 154 -- .../OSGI-INF/metatype/metatype.properties | 14 - .../main/resources/OSGI-INF/metatype/metatype.xml | 22 - .../aaa-authn-store/src/main/resources/tokens.cfg | 4 - .../aaa/store/DefaultTokenStoreTest.java | 66 - upstream/odl-aaa-moon/aaa/aaa-authn-sts/pom.xml | 112 - .../java/org/opendaylight/aaa/sts/Activator.java | 207 -- .../aaa/sts/AnonymousPasswordValidator.java | 30 - .../aaa/sts/AnonymousRefreshTokenValidator.java | 29 - .../org/opendaylight/aaa/sts/OAuthRequest.java | 42 - .../org/opendaylight/aaa/sts/ServiceLocator.java | 141 -- .../org/opendaylight/aaa/sts/TokenAuthFilter.java | 148 -- .../org/opendaylight/aaa/sts/TokenEndpoint.java | 242 -- .../src/main/resources/WEB-INF/web.xml | 23 - .../java/org/opendaylight/aaa/sts/RestFixture.java | 34 - .../org/opendaylight/aaa/sts/TokenAuthTest.java | 94 - .../opendaylight/aaa/sts/TokenEndpointTest.java | 164 -- upstream/odl-aaa-moon/aaa/aaa-authn/pom.xml | 103 - .../main/java/org/opendaylight/aaa/Activator.java | 51 - .../opendaylight/aaa/AuthenticationBuilder.java | 122 - .../opendaylight/aaa/AuthenticationManager.java | 77 - .../java/org/opendaylight/aaa/ClaimBuilder.java | 160 -- .../java/org/opendaylight/aaa/ClientManager.java | 88 - .../main/java/org/opendaylight/aaa/EqualUtil.java | 42 - .../java/org/opendaylight/aaa/HashCodeUtil.java | 104 - .../aaa/PasswordCredentialBuilder.java | 87 - .../org/opendaylight/aaa/SecureBlockingQueue.java | 258 -- .../OSGI-INF/metatype/metatype.properties | 12 - .../main/resources/OSGI-INF/metatype/metatype.xml | 16 - .../aaa/aaa-authn/src/main/resources/authn.cfg | 2 - .../aaa/AuthenticationBuilderTest.java | 129 - .../aaa/AuthenticationManagerTest.java | 133 - .../org/opendaylight/aaa/ClaimBuilderTest.java | 208 -- .../org/opendaylight/aaa/ClientManagerTest.java | 70 - .../opendaylight/aaa/PasswordCredentialTest.java | 39 - .../opendaylight/aaa/SecureBlockingQueueTest.java | 191 -- .../aaa/aaa-authz/aaa-authz-config/pom.xml | 43 - .../src/main/resources/initial/08-authz-config.xml | 60 - .../aaa/aaa-authz/aaa-authz-model/pom.xml | 95 - .../src/main/yang/authorization-schema.yang | 190 -- .../aaa-authz/aaa-authz-restconf-config/pom.xml | 43 - .../main/resources/initial/09-rest-connector.xml | 42 - .../aaa/aaa-authz/aaa-authz-service/pom.xml | 152 -- .../aaa/authz/srv/AuthzBrokerImpl.java | 150 -- .../aaa/authz/srv/AuthzConsumerContextImpl.java | 46 - .../authz/srv/AuthzDataReadWriteTransaction.java | 129 - .../aaa/authz/srv/AuthzDomDataBroker.java | 100 - .../aaa/authz/srv/AuthzProviderContextImpl.java | 47 - .../aaa/authz/srv/AuthzReadOnlyTransaction.java | 69 - .../aaa/authz/srv/AuthzServiceImpl.java | 121 - .../aaa/authz/srv/AuthzWriteOnlyTransaction.java | 103 - .../yang/config/aaa_authz/srv/AuthzSrvModule.java | 76 - .../aaa_authz/srv/AuthzSrvModuleFactory.java | 53 - .../src/main/yang/aaa-authz-service-impl.yang | 115 - .../authz/srv/AuthzConsumerContextImplTest.java | 46 - upstream/odl-aaa-moon/aaa/aaa-authz/pom.xml | 23 - .../aaa/aaa-credential-store-api/pom.xml | 22 - .../src/main/yang/credential-model.yang | 47 - upstream/odl-aaa-moon/aaa/aaa-h2-store/.gitignore | 2 - upstream/odl-aaa-moon/aaa/aaa-h2-store/pom.xml | 160 -- .../opendaylight/aaa/h2/config/IdmLightConfig.java | 133 - .../aaa/h2/persistence/AbstractStore.java | 187 -- .../aaa/h2/persistence/DomainStore.java | 166 -- .../aaa/h2/persistence/GrantStore.java | 158 -- .../opendaylight/aaa/h2/persistence/H2Store.java | 316 --- .../opendaylight/aaa/h2/persistence/RoleStore.java | 151 -- .../aaa/h2/persistence/StoreException.java | 29 - .../opendaylight/aaa/h2/persistence/UserStore.java | 202 -- .../authn/h2/store/rev151128/AAAH2StoreModule.java | 49 - .../store/rev151128/AAAH2StoreModuleFactory.java | 29 - .../resources/initial/08-aaa-h2-store-config.xml | 26 - .../aaa-h2-store/src/main/yang/aaa-h2-store.yang | 28 - .../aaa/h2/persistence/DomainStoreTest.java | 76 - .../aaa/h2/persistence/GrantStoreTest.java | 76 - .../aaa/h2/persistence/H2StoreTest.java | 187 -- .../aaa/h2/persistence/RoleStoreTest.java | 76 - .../aaa/h2/persistence/UserStoreTest.java | 79 - upstream/odl-aaa-moon/aaa/aaa-idmlight/pom.xml | 229 -- .../opendaylight/aaa/idm/IdmLightApplication.java | 57 - .../org/opendaylight/aaa/idm/IdmLightProxy.java | 208 -- .../org/opendaylight/aaa/idm/StoreBuilder.java | 118 - .../opendaylight/aaa/idm/rest/DomainHandler.java | 591 ----- .../org/opendaylight/aaa/idm/rest/RoleHandler.java | 228 -- .../org/opendaylight/aaa/idm/rest/UserHandler.java | 420 ---- .../opendaylight/aaa/idm/rest/VersionHandler.java | 46 - .../idmlight/rev151204/AAAIDMLightModule.java | 90 - .../rev151204/AAAIDMLightModuleFactory.java | 29 - .../src/main/resources/WEB-INF/web.xml | 77 - .../aaa/aaa-idmlight/src/main/resources/idmtool.py | 255 -- .../resources/initial/08-aaa-idmlight-config.xml | 26 - .../aaa-idmlight/src/main/yang/aaa-idmlight.yang | 28 - .../aaa/idm/persistence/PasswordHashTest.java | 93 - .../aaa/idm/rest/test/DomainHandlerTest.java | 130 - .../aaa/idm/rest/test/HandlerTest.java | 38 - .../aaa/idm/rest/test/IDMTestStore.java | 271 -- .../aaa/idm/rest/test/RoleHandlerTest.java | 95 - .../aaa/idm/rest/test/UserHandlerTest.java | 96 - .../odl-aaa-moon/aaa/aaa-idmlight/tests/cleardb.sh | 5 - .../aaa/aaa-idmlight/tests/domain.json | 5 - .../aaa/aaa-idmlight/tests/domain2.json | 5 - .../odl-aaa-moon/aaa/aaa-idmlight/tests/grant.json | 4 - .../aaa/aaa-idmlight/tests/grant2.json | 4 - .../aaa/aaa-idmlight/tests/result.json | 1 - .../aaa/aaa-idmlight/tests/role-admin.json | 4 - .../aaa/aaa-idmlight/tests/role-user.json | 4 - .../odl-aaa-moon/aaa/aaa-idmlight/tests/test.sh | 308 --- .../odl-aaa-moon/aaa/aaa-idmlight/tests/user.json | 7 - .../odl-aaa-moon/aaa/aaa-idmlight/tests/user2.json | 7 - .../aaa/aaa-idmlight/tests/userpwd.json | 4 - upstream/odl-aaa-moon/aaa/aaa-idp-mapping/pom.xml | 84 - .../org/opendaylight/aaa/idpmapping/Activator.java | 25 - .../org/opendaylight/aaa/idpmapping/IdpJson.java | 248 -- .../aaa/idpmapping/InvalidRuleException.java | 35 - .../aaa/idpmapping/InvalidTypeException.java | 35 - .../aaa/idpmapping/InvalidValueException.java | 35 - .../opendaylight/aaa/idpmapping/RuleProcessor.java | 1368 ---------- .../aaa/idpmapping/StatementErrorException.java | 35 - .../org/opendaylight/aaa/idpmapping/Token.java | 401 --- .../aaa/idpmapping/UndefinedValueException.java | 34 - .../aaa/idpmapping/RuleProcessorTest.java | 130 - .../org/opendaylight/aaa/idpmapping/TokenTest.java | 66 - upstream/odl-aaa-moon/aaa/aaa-shiro-act/pom.xml | 84 - .../org/opendaylight/aaa/shiroact/Activator.java | 51 - .../opendaylight/aaa/shiroact/ActivatorTest.java | 25 - upstream/odl-aaa-moon/aaa/aaa-shiro/pom.xml | 169 -- .../java/org/opendaylight/aaa/shiro/Activator.java | 45 - .../org/opendaylight/aaa/shiro/ServiceProxy.java | 94 - .../aaa/shiro/accounting/Accounter.java | 38 - .../aaa/shiro/authorization/DefaultRBACRules.java | 78 - .../aaa/shiro/authorization/RBACRule.java | 170 -- .../opendaylight/aaa/shiro/filters/AAAFilter.java | 72 - .../aaa/shiro/filters/AAAShiroFilter.java | 51 - .../aaa/shiro/filters/AuthenticationListener.java | 52 - .../shiro/filters/AuthenticationTokenUtils.java | 129 - .../aaa/shiro/filters/MoonOAuthFilter.java | 186 -- .../shiro/filters/ODLHttpAuthenticationFilter.java | 78 - .../opendaylight/aaa/shiro/moon/MoonPrincipal.java | 160 -- .../aaa/shiro/moon/MoonTokenEndpoint.java | 30 - .../opendaylight/aaa/shiro/realm/MoonRealm.java | 99 - .../aaa/shiro/realm/ODLJndiLdapRealm.java | 315 --- .../aaa/shiro/realm/ODLJndiLdapRealmAuthNOnly.java | 102 - .../opendaylight/aaa/shiro/realm/RadiusRealm.java | 37 - .../opendaylight/aaa/shiro/realm/TACACSRealm.java | 38 - .../aaa/shiro/realm/TokenAuthRealm.java | 369 --- .../aaa/shiro/web/env/KarafIniWebEnvironment.java | 125 - .../aaa-shiro/src/main/resources/WEB-INF/web.xml | 48 - .../aaa/aaa-shiro/src/main/resources/shiro.ini | 106 - .../opendaylight/aaa/shiro/ServiceProxyTest.java | 45 - .../org/opendaylight/aaa/shiro/TestAppender.java | 67 - .../shiro/authorization/DefaultRBACRulesTest.java | 43 - .../aaa/shiro/authorization/RBACRuleTest.java | 106 - .../shiro/filters/AuthenticationListenerTest.java | 72 - .../filters/AuthenticationTokenUtilsTest.java | 124 - .../aaa/shiro/realm/ODLJndiLdapRealmTest.java | 246 -- .../aaa/shiro/realm/TokenAuthRealmTest.java | 139 -- .../shiro/web/env/KarafIniWebEnvironmentTest.java | 76 - .../aaa-shiro/src/test/resources/logback-test.xml | 21 - upstream/odl-aaa-moon/aaa/artifacts/pom.xml | 231 -- .../aaa/commons/docs/AuthNusecases.vsd | Bin 206336 -> 0 bytes .../odl-aaa-moon/aaa/commons/docs/direct_authn.png | Bin 22058 -> 0 bytes .../aaa/commons/docs/federated_authn1.png | Bin 36542 -> 0 bytes .../aaa/commons/docs/federated_authn2.png | Bin 35203 -> 0 bytes .../odl-aaa-moon/aaa/commons/federation/README | 271 -- .../federation/idp_mapping_rules.json.example | 30 - .../aaa/commons/federation/jetty.xml.example | 85 - .../aaa/commons/federation/my_app.conf.example | 31 - .../AAA_AuthZ_MDSAL.json.postman_collection | 77 - .../odl-aaa-moon/aaa/distribution-karaf/pom.xml | 291 --- upstream/odl-aaa-moon/aaa/features/api/pom.xml | 91 - .../features/api/src/main/features/features.xml | 21 - upstream/odl-aaa-moon/aaa/features/authn/pom.xml | 300 --- .../features/authn/src/main/features/features.xml | 249 -- upstream/odl-aaa-moon/aaa/features/authz/pom.xml | 101 - .../features/authz/src/main/features/features.xml | 31 - upstream/odl-aaa-moon/aaa/features/pom.xml | 19 - upstream/odl-aaa-moon/aaa/features/shiro/pom.xml | 179 -- .../features/shiro/src/main/features/features.xml | 41 - upstream/odl-aaa-moon/aaa/parent/pom.xml | 278 --- upstream/odl-aaa-moon/aaa/pom.xml | 50 - 1393 files changed, 48736 insertions(+), 93619 deletions(-) create mode 100644 DEV.md create mode 100644 README.md delete mode 100644 README.rst create mode 100644 TODO create mode 100644 bin/README.md create mode 100644 bin/bootstrap.py create mode 100644 bin/build_all.sh create mode 100644 bin/build_all_pip.sh create mode 100644 bin/delete_orchestrator.sh create mode 100644 bin/moon_lib_update.sh create mode 100644 bin/set_auth.src create mode 100755 bin/start.sh create mode 100644 conf/moon.conf delete mode 100644 keystonemiddleware-moon/.coveragerc delete mode 100644 keystonemiddleware-moon/.gitignore delete mode 100644 keystonemiddleware-moon/.gitreview delete mode 100644 keystonemiddleware-moon/.testr.conf delete mode 100644 keystonemiddleware-moon/CONTRIBUTING.rst delete mode 100644 keystonemiddleware-moon/HACKING.rst delete mode 100644 keystonemiddleware-moon/LICENSE delete mode 100644 keystonemiddleware-moon/MANIFEST.in delete mode 100644 keystonemiddleware-moon/README.rst delete mode 100644 keystonemiddleware-moon/babel.cfg delete mode 100644 keystonemiddleware-moon/bandit.yaml delete mode 100644 keystonemiddleware-moon/debian/changelog delete mode 100644 keystonemiddleware-moon/debian/compat delete mode 100644 keystonemiddleware-moon/debian/control delete mode 100644 keystonemiddleware-moon/debian/copyright delete mode 100644 keystonemiddleware-moon/debian/create_deb.py delete mode 100644 keystonemiddleware-moon/debian/gbp.conf delete mode 100644 keystonemiddleware-moon/debian/patches/no-intersphinx.patch delete mode 100644 keystonemiddleware-moon/debian/patches/re-add-missing-auth-options.patch delete mode 100644 keystonemiddleware-moon/debian/patches/series delete mode 100644 keystonemiddleware-moon/debian/python-keystonemiddleware-doc.doc-base delete mode 100755 keystonemiddleware-moon/debian/rules delete mode 100644 keystonemiddleware-moon/debian/source/format delete mode 100644 keystonemiddleware-moon/debian/source/options delete mode 100644 keystonemiddleware-moon/debian/watch delete mode 100644 keystonemiddleware-moon/doc/.gitignore delete mode 100644 keystonemiddleware-moon/doc/Makefile delete mode 100644 keystonemiddleware-moon/doc/ext/__init__.py delete mode 100644 keystonemiddleware-moon/doc/ext/apidoc.py delete mode 100644 keystonemiddleware-moon/doc/source/audit.rst delete mode 100644 keystonemiddleware-moon/doc/source/conf.py delete mode 100644 keystonemiddleware-moon/doc/source/images/audit.png delete mode 100644 keystonemiddleware-moon/doc/source/images/graphs_authComp.svg delete mode 100644 keystonemiddleware-moon/doc/source/images/graphs_authCompDelegate.svg delete mode 100644 keystonemiddleware-moon/doc/source/index.rst delete mode 100644 keystonemiddleware-moon/doc/source/middlewarearchitecture.rst delete mode 100644 keystonemiddleware-moon/examples/pki/certs/cacert.pem delete mode 100644 keystonemiddleware-moon/examples/pki/certs/middleware.pem delete mode 100644 keystonemiddleware-moon/examples/pki/certs/signing_cert.pem delete mode 100644 keystonemiddleware-moon/examples/pki/certs/ssl_cert.pem delete mode 100644 keystonemiddleware-moon/examples/pki/cms/auth_token_revoked.json delete mode 100644 keystonemiddleware-moon/examples/pki/cms/auth_token_revoked.pem delete mode 100644 keystonemiddleware-moon/examples/pki/cms/auth_token_revoked.pkiz delete mode 100644 keystonemiddleware-moon/examples/pki/cms/auth_token_scoped.json delete mode 100644 keystonemiddleware-moon/examples/pki/cms/auth_token_scoped.pem delete mode 100644 keystonemiddleware-moon/examples/pki/cms/auth_token_scoped.pkiz delete mode 100644 keystonemiddleware-moon/examples/pki/cms/auth_token_scoped_expired.json delete mode 100644 keystonemiddleware-moon/examples/pki/cms/auth_token_scoped_expired.pem delete mode 100644 keystonemiddleware-moon/examples/pki/cms/auth_token_scoped_expired.pkiz delete mode 100644 keystonemiddleware-moon/examples/pki/cms/auth_token_unscoped.json delete mode 100644 keystonemiddleware-moon/examples/pki/cms/auth_token_unscoped.pem delete mode 100644 keystonemiddleware-moon/examples/pki/cms/auth_token_unscoped.pkiz delete mode 100644 keystonemiddleware-moon/examples/pki/cms/auth_v3_token_revoked.json delete mode 100644 keystonemiddleware-moon/examples/pki/cms/auth_v3_token_revoked.pem delete mode 100644 keystonemiddleware-moon/examples/pki/cms/auth_v3_token_revoked.pkiz delete mode 100644 keystonemiddleware-moon/examples/pki/cms/auth_v3_token_scoped.json delete mode 100644 keystonemiddleware-moon/examples/pki/cms/auth_v3_token_scoped.pem delete mode 100644 keystonemiddleware-moon/examples/pki/cms/auth_v3_token_scoped.pkiz delete mode 100644 keystonemiddleware-moon/examples/pki/cms/revocation_list.der delete mode 100644 keystonemiddleware-moon/examples/pki/cms/revocation_list.json delete mode 100644 keystonemiddleware-moon/examples/pki/cms/revocation_list.pem delete mode 100644 keystonemiddleware-moon/examples/pki/cms/revocation_list.pkiz delete mode 100644 keystonemiddleware-moon/examples/pki/gen_cmsz.py delete mode 100755 keystonemiddleware-moon/examples/pki/gen_pki.sh delete mode 100644 keystonemiddleware-moon/examples/pki/private/cakey.pem delete mode 100644 keystonemiddleware-moon/examples/pki/private/signing_key.pem delete mode 100644 keystonemiddleware-moon/examples/pki/private/ssl_key.pem delete mode 100755 keystonemiddleware-moon/examples/pki/run_all.sh delete mode 100644 keystonemiddleware-moon/keystonemiddleware.egg-info/dependency_links.txt delete mode 100644 keystonemiddleware-moon/keystonemiddleware.egg-info/entry_points.txt delete mode 100644 keystonemiddleware-moon/keystonemiddleware.egg-info/not-zip-safe delete mode 100644 keystonemiddleware-moon/keystonemiddleware.egg-info/top_level.txt delete mode 100644 keystonemiddleware-moon/keystonemiddleware/__init__.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/audit.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/auth_token/__init__.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/auth_token/_auth.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/auth_token/_base.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/auth_token/_cache.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/auth_token/_exceptions.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/auth_token/_identity.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/auth_token/_memcache_crypt.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/auth_token/_memcache_pool.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/auth_token/_request.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/auth_token/_revocations.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/auth_token/_signing_dir.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/auth_token/_user_plugin.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/auth_token/_utils.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/authz.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/ec2_token.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/echo/__init__.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/echo/__main__.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/echo/service.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/i18n.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/moon_agent.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/moon_mgrs/__init__.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/moon_mgrs/abe_mgr/__init__.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/moon_mgrs/authz_mgr/__init__.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/moon_mgrs/authz_mgr/authz_mgr.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/openstack/__init__.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/openstack/common/__init__.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/openstack/common/memorycache.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/opts.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/s3_token.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/tests/__init__.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/tests/unit/__init__.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/__init__.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/base.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_auth.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_base_middleware.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_connection_pool.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_memcache_crypt.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_request.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_revocations.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_signing_dir.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_user_auth_plugin.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_utils.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/tests/unit/client_fixtures.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/tests/unit/test_audit_middleware.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/tests/unit/test_opts.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/tests/unit/test_s3_token_middleware.py delete mode 100644 keystonemiddleware-moon/keystonemiddleware/tests/unit/utils.py delete mode 100644 keystonemiddleware-moon/openstack-common.conf delete mode 100644 keystonemiddleware-moon/requirements.txt delete mode 100644 keystonemiddleware-moon/setup.cfg delete mode 100644 keystonemiddleware-moon/setup.py delete mode 100644 keystonemiddleware-moon/test-requirements-py3.txt delete mode 100644 keystonemiddleware-moon/test-requirements.txt delete mode 100644 keystonemiddleware-moon/tools/install_venv_common.py delete mode 100644 keystonemiddleware-moon/tox.ini create mode 100644 kubernetes/README.md create mode 100644 kubernetes/conf/password_moon.txt create mode 100644 kubernetes/conf/password_root.txt create mode 100644 kubernetes/conf/ports.conf create mode 100644 kubernetes/init_k8s.sh create mode 100644 kubernetes/start_moon.sh create mode 100644 kubernetes/templates/consul.yaml create mode 100644 kubernetes/templates/db.yaml create mode 100644 kubernetes/templates/keystone.yaml create mode 100644 kubernetes/templates/kube-dns.yaml create mode 100644 kubernetes/templates/moon_configuration.yaml create mode 100644 kubernetes/templates/moon_gui.yaml create mode 100644 kubernetes/templates/moon_manager.yaml create mode 100644 kubernetes/templates/moon_orchestrator.yaml create mode 100644 moon_authz/Dockerfile create mode 100644 moon_authz/LICENSE create mode 100644 moon_authz/MANIFEST.in create mode 100644 moon_authz/README.rst create mode 100644 moon_authz/moon_authz/__init__.py create mode 100644 moon_authz/moon_authz/__main__.py create mode 100644 moon_authz/moon_authz/api/__init__.py create mode 100644 moon_authz/moon_authz/api/authorization.py create mode 100644 moon_authz/moon_authz/api/generic.py create mode 100644 moon_authz/moon_authz/http_server.py create mode 100644 moon_authz/moon_authz/server.py create mode 100644 moon_authz/requirements.txt create mode 100644 moon_authz/setup.py create mode 100644 moon_authz/tests/unit_python/conftest.py create mode 100644 moon_authz/tests/unit_python/mock_pods.py create mode 100644 moon_authz/tests/unit_python/requirements.txt create mode 100644 moon_authz/tests/unit_python/test_authz.py create mode 100644 moon_authz/tests/unit_python/utilities.py create mode 100644 moon_bouchon/Dockerfile create mode 100644 moon_bouchon/README.md create mode 100644 moon_bouchon/moon_bouchon/__init__.py create mode 100644 moon_bouchon/moon_bouchon/__main__.py create mode 100644 moon_bouchon/moon_bouchon/server.py create mode 100644 moon_bouchon/requirements.txt create mode 100644 moon_bouchon/setup.cfg create mode 100644 moon_bouchon/setup.py create mode 100644 moon_bouchon/tests/test_interface.py create mode 100644 moon_bouchon/tests/test_wrapper.py create mode 100644 moon_gui/.gitignore create mode 100644 moon_gui/.jshintrc create mode 100644 moon_gui/DEV.md create mode 100644 moon_gui/Dockerfile create mode 100644 moon_gui/README.md create mode 100644 moon_gui/delivery/assets/css/main.css create mode 100644 moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.eot create mode 100644 moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.svg create mode 100644 moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.ttf create mode 100644 moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.woff create mode 100755 moon_gui/delivery/assets/i18n/en.json create mode 100755 moon_gui/delivery/assets/i18n/fr.json create mode 100755 moon_gui/delivery/assets/img/ajax-loader.gif create mode 100755 moon_gui/delivery/assets/img/ajax-waiting.gif create mode 100755 moon_gui/delivery/assets/img/arrow-link.gif create mode 100755 moon_gui/delivery/assets/img/favicon.ico create mode 100755 moon_gui/delivery/assets/img/logo-openstack.png create mode 100755 moon_gui/delivery/assets/img/logo-orange.gif create mode 100644 moon_gui/delivery/html/authentication/authentication.tpl.html create mode 100644 moon_gui/delivery/html/common/404/404.tpl.html create mode 100644 moon_gui/delivery/html/common/compatibility/compatibility.tpl.html create mode 100644 moon_gui/delivery/html/common/footer/footer.tpl.html create mode 100644 moon_gui/delivery/html/common/header/header.tpl.html create mode 100644 moon_gui/delivery/html/common/loader/loader.tpl.html create mode 100644 moon_gui/delivery/html/common/waiting/waiting.tpl.html create mode 100644 moon_gui/delivery/html/dashboard/dashboard.tpl.html create mode 100644 moon_gui/delivery/html/logs/logs.tpl.html create mode 100644 moon_gui/delivery/html/model/action/model-add.tpl.html create mode 100644 moon_gui/delivery/html/model/action/model-delete.tpl.html create mode 100644 moon_gui/delivery/html/model/action/model-view.tpl.html create mode 100644 moon_gui/delivery/html/model/edit/metadata/metadata-edit.tpl.html create mode 100644 moon_gui/delivery/html/model/edit/metadata/metadata-list.tpl.html create mode 100644 moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-add.tpl.html create mode 100644 moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-map.tpl.html create mode 100644 moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-unmap.tpl.html create mode 100644 moon_gui/delivery/html/model/edit/metarules/action/metarules-edit-basic.tpl.html create mode 100644 moon_gui/delivery/html/model/edit/metarules/action/metarules-edit.tpl.html create mode 100644 moon_gui/delivery/html/model/edit/metarules/metarules-list.tpl.html create mode 100644 moon_gui/delivery/html/model/edit/model-edit-basic.tpl.html create mode 100644 moon_gui/delivery/html/model/edit/model-edit.tpl.html create mode 100644 moon_gui/delivery/html/model/model-list.tpl.html create mode 100644 moon_gui/delivery/html/pdp/action/pdp-add.tpl.html create mode 100644 moon_gui/delivery/html/pdp/action/pdp-delete.tpl.html create mode 100644 moon_gui/delivery/html/pdp/edit/pdp-edit-basic.tpl.html create mode 100644 moon_gui/delivery/html/pdp/edit/pdp-edit.tpl.html create mode 100644 moon_gui/delivery/html/pdp/pdp-list.tpl.html create mode 100644 moon_gui/delivery/html/policy/action/mapping/policy-map.tpl.html create mode 100644 moon_gui/delivery/html/policy/action/mapping/policy-unmap.tpl.html create mode 100644 moon_gui/delivery/html/policy/action/policy-add.tpl.html create mode 100644 moon_gui/delivery/html/policy/action/policy-delete.tpl.html create mode 100644 moon_gui/delivery/html/policy/edit/parameter/assignments/assignments-list.tpl.html create mode 100644 moon_gui/delivery/html/policy/edit/parameter/data/data-list.tpl.html create mode 100644 moon_gui/delivery/html/policy/edit/parameter/perimeter/perimeter-list.tpl.html create mode 100644 moon_gui/delivery/html/policy/edit/parameter/rules/rules-list.tpl.html create mode 100644 moon_gui/delivery/html/policy/edit/policy-edit-basic.tpl.html create mode 100644 moon_gui/delivery/html/policy/edit/policy-edit.tpl.html create mode 100644 moon_gui/delivery/html/policy/policy-list.tpl.html create mode 100644 moon_gui/delivery/html/policy/policy-mapped-list.tpl.html create mode 100644 moon_gui/delivery/html/project/action/mapping/project-map.tpl.html create mode 100644 moon_gui/delivery/html/project/action/mapping/project-unmap.tpl.html create mode 100644 moon_gui/delivery/html/project/action/project-add.tpl.html create mode 100644 moon_gui/delivery/html/project/action/project-delete.tpl.html create mode 100644 moon_gui/delivery/html/project/action/project-view.tpl.html create mode 100644 moon_gui/delivery/html/project/project-list.tpl.html create mode 100644 moon_gui/delivery/index.html create mode 100644 moon_gui/delivery/js/app.js create mode 100644 moon_gui/delivery/js/modules.js create mode 100755 moon_gui/delivery/version.json create mode 100644 moon_gui/gulpfile.js create mode 100644 moon_gui/package.json create mode 100644 moon_gui/run.sh create mode 100755 moon_gui/static/app/authentication/authentication.controller.js create mode 100755 moon_gui/static/app/authentication/authentication.tpl.html create mode 100755 moon_gui/static/app/common/404/404.tpl.html create mode 100755 moon_gui/static/app/common/compatibility/compatibility.tpl.html create mode 100755 moon_gui/static/app/common/footer/footer.controller.js create mode 100755 moon_gui/static/app/common/footer/footer.tpl.html create mode 100755 moon_gui/static/app/common/header/header.controller.js create mode 100755 moon_gui/static/app/common/header/header.tpl.html create mode 100755 moon_gui/static/app/common/loader/loader.dir.js create mode 100755 moon_gui/static/app/common/loader/loader.tpl.html create mode 100755 moon_gui/static/app/common/waiting/waiting.tpl.html create mode 100755 moon_gui/static/app/dashboard/dashboard.tpl.html create mode 100755 moon_gui/static/app/logs/logs.controller.js create mode 100755 moon_gui/static/app/logs/logs.tpl.html create mode 100755 moon_gui/static/app/model/action/model-add.tpl.html create mode 100755 moon_gui/static/app/model/action/model-delete.tpl.html create mode 100755 moon_gui/static/app/model/action/model-view.tpl.html create mode 100755 moon_gui/static/app/model/action/model.controller.add.js create mode 100755 moon_gui/static/app/model/action/model.controller.delete.js create mode 100755 moon_gui/static/app/model/action/model.controller.view.js create mode 100755 moon_gui/static/app/model/edit/metadata/metadata-edit.tpl.html create mode 100755 moon_gui/static/app/model/edit/metadata/metadata-list.tpl.html create mode 100755 moon_gui/static/app/model/edit/metadata/metadata.edit.dir.js create mode 100755 moon_gui/static/app/model/edit/metadata/metadata.list.dir.js create mode 100755 moon_gui/static/app/model/edit/metarules/action/mapping/metarules-add.tpl.html create mode 100755 moon_gui/static/app/model/edit/metarules/action/mapping/metarules-map.tpl.html create mode 100755 moon_gui/static/app/model/edit/metarules/action/mapping/metarules-unmap.tpl.html create mode 100755 moon_gui/static/app/model/edit/metarules/action/mapping/metarules.controller.add.js create mode 100755 moon_gui/static/app/model/edit/metarules/action/mapping/metarules.map.controller.js create mode 100755 moon_gui/static/app/model/edit/metarules/action/mapping/metarules.unmap.controller.js create mode 100755 moon_gui/static/app/model/edit/metarules/action/metarules-edit-basic.tpl.html create mode 100755 moon_gui/static/app/model/edit/metarules/action/metarules-edit.tpl.html create mode 100755 moon_gui/static/app/model/edit/metarules/action/metarules.controller.edit.js create mode 100755 moon_gui/static/app/model/edit/metarules/action/metarules.edit.basic.dir.js create mode 100755 moon_gui/static/app/model/edit/metarules/metarules-list.tpl.html create mode 100755 moon_gui/static/app/model/edit/metarules/metarules.list.dir.js create mode 100755 moon_gui/static/app/model/edit/model-edit-basic.tpl.html create mode 100755 moon_gui/static/app/model/edit/model-edit.tpl.html create mode 100755 moon_gui/static/app/model/edit/model.controller.edit.js create mode 100755 moon_gui/static/app/model/edit/model.edit.basic.dir.js create mode 100755 moon_gui/static/app/model/model-list.tpl.html create mode 100755 moon_gui/static/app/model/model.controller.list.js create mode 100644 moon_gui/static/app/moon.constants.js create mode 100755 moon_gui/static/app/moon.module.js create mode 100755 moon_gui/static/app/pdp/action/pdp-add.tpl.html create mode 100755 moon_gui/static/app/pdp/action/pdp-delete.tpl.html create mode 100755 moon_gui/static/app/pdp/action/pdp.controller.add.js create mode 100755 moon_gui/static/app/pdp/action/pdp.controller.delete.js create mode 100755 moon_gui/static/app/pdp/edit/pdp-edit-basic.tpl.html create mode 100755 moon_gui/static/app/pdp/edit/pdp-edit.tpl.html create mode 100755 moon_gui/static/app/pdp/edit/pdp.controller.edit.js create mode 100755 moon_gui/static/app/pdp/edit/pdp.edit.basic.dir.js create mode 100755 moon_gui/static/app/pdp/pdp-list.tpl.html create mode 100755 moon_gui/static/app/pdp/pdp.controller.list.js create mode 100755 moon_gui/static/app/policy/action/mapping/policy-map.tpl.html create mode 100755 moon_gui/static/app/policy/action/mapping/policy-unmap.tpl.html create mode 100755 moon_gui/static/app/policy/action/mapping/policy.controller.map.js create mode 100755 moon_gui/static/app/policy/action/mapping/policy.controller.unmap.js create mode 100755 moon_gui/static/app/policy/action/policy-add.tpl.html create mode 100755 moon_gui/static/app/policy/action/policy-delete.tpl.html create mode 100755 moon_gui/static/app/policy/action/policy.controller.add.js create mode 100755 moon_gui/static/app/policy/action/policy.controller.delete.js create mode 100755 moon_gui/static/app/policy/edit/parameter/assignments/assignments-edit.tpl.html create mode 100755 moon_gui/static/app/policy/edit/parameter/assignments/assignments-list.tpl.html create mode 100755 moon_gui/static/app/policy/edit/parameter/assignments/assignments.edit.dir.js create mode 100755 moon_gui/static/app/policy/edit/parameter/assignments/assignments.list.dir.js create mode 100755 moon_gui/static/app/policy/edit/parameter/data/data-edit.tpl.html create mode 100755 moon_gui/static/app/policy/edit/parameter/data/data-list.tpl.html create mode 100755 moon_gui/static/app/policy/edit/parameter/data/data.edit.dir.js create mode 100755 moon_gui/static/app/policy/edit/parameter/data/data.list.dir.js create mode 100755 moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-edit.tpl.html create mode 100755 moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-list.tpl.html create mode 100755 moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.edit.dir.js create mode 100755 moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.list.dir.js create mode 100755 moon_gui/static/app/policy/edit/parameter/rules/rules-edit.tpl.html create mode 100755 moon_gui/static/app/policy/edit/parameter/rules/rules-list.tpl.html create mode 100755 moon_gui/static/app/policy/edit/parameter/rules/rules.edit.dir.js create mode 100755 moon_gui/static/app/policy/edit/parameter/rules/rules.list.dir.js create mode 100755 moon_gui/static/app/policy/edit/policy-edit-basic.tpl.html create mode 100755 moon_gui/static/app/policy/edit/policy-edit.tpl.html create mode 100755 moon_gui/static/app/policy/edit/policy.controller.edit.js create mode 100755 moon_gui/static/app/policy/edit/policy.edit.basic.dir.js create mode 100755 moon_gui/static/app/policy/policy-list.tpl.html create mode 100755 moon_gui/static/app/policy/policy-mapped-list.tpl.html create mode 100755 moon_gui/static/app/policy/policy.controller.list.js create mode 100755 moon_gui/static/app/policy/policy.mapped.list.dir.js create mode 100755 moon_gui/static/app/project/action/mapping/project-map.tpl.html create mode 100755 moon_gui/static/app/project/action/mapping/project-unmap.tpl.html create mode 100755 moon_gui/static/app/project/action/mapping/project.controller.map.js create mode 100755 moon_gui/static/app/project/action/mapping/project.controller.unmap.js create mode 100755 moon_gui/static/app/project/action/project-add.tpl.html create mode 100755 moon_gui/static/app/project/action/project-delete.tpl.html create mode 100755 moon_gui/static/app/project/action/project-view.tpl.html create mode 100755 moon_gui/static/app/project/action/project.controller.add.js create mode 100755 moon_gui/static/app/project/action/project.controller.delete.js create mode 100755 moon_gui/static/app/project/action/project.controller.view.js create mode 100755 moon_gui/static/app/project/project-list.tpl.html create mode 100755 moon_gui/static/app/project/project.controller.list.js create mode 100755 moon_gui/static/app/services/gui/alert.service.js create mode 100755 moon_gui/static/app/services/gui/browser.service.js create mode 100755 moon_gui/static/app/services/gui/form.service.js create mode 100755 moon_gui/static/app/services/gui/menu.service.js create mode 100755 moon_gui/static/app/services/gui/security.pipeline.service.js create mode 100755 moon_gui/static/app/services/gui/util.service.js create mode 100755 moon_gui/static/app/services/gui/version.service.js create mode 100755 moon_gui/static/app/services/moon/model/model.service.js create mode 100755 moon_gui/static/app/services/moon/pdp.service.js create mode 100755 moon_gui/static/app/services/moon/policy/parameters/assignements.service.js create mode 100755 moon_gui/static/app/services/moon/policy/parameters/data.service.js create mode 100755 moon_gui/static/app/services/moon/policy/parameters/perimeter.service.js create mode 100644 moon_gui/static/app/services/moon/policy/parameters/rule.service.js create mode 100755 moon_gui/static/app/services/moon/policy/parameters/rules.service.js create mode 100755 moon_gui/static/app/services/moon/policy/policy.service.js create mode 100755 moon_gui/static/app/services/moon/rule/metadata.service.js create mode 100755 moon_gui/static/app/services/moon/rule/metarule.service.js create mode 100755 moon_gui/static/app/services/partner/authentication.service.js create mode 100755 moon_gui/static/app/services/partner/nova.service.js create mode 100755 moon_gui/static/app/services/partner/project.service.js create mode 100755 moon_gui/static/favicon.ico create mode 100755 moon_gui/static/i18n/en.json create mode 100755 moon_gui/static/i18n/fr.json create mode 100755 moon_gui/static/img/ajax-loader.gif create mode 100755 moon_gui/static/img/ajax-waiting.gif create mode 100755 moon_gui/static/img/arrow-link.gif create mode 100644 moon_gui/static/img/et.jpg create mode 100755 moon_gui/static/img/logo-openstack.png create mode 100755 moon_gui/static/img/logo-orange.gif create mode 100644 moon_gui/static/styles/main.css create mode 100755 moon_gui/static/version.json create mode 100644 moon_gui/templates/index.html create mode 100644 moon_interface/Dockerfile create mode 100644 moon_interface/LICENSE create mode 100644 moon_interface/MANIFEST.in create mode 100644 moon_interface/Makefile create mode 100644 moon_interface/README.rst create mode 100644 moon_interface/moon_interface/__init__.py create mode 100644 moon_interface/moon_interface/__main__.py create mode 100644 moon_interface/moon_interface/api/__init__.py create mode 100644 moon_interface/moon_interface/api/authz.py create mode 100644 moon_interface/moon_interface/api/generic.py create mode 100644 moon_interface/moon_interface/authz_requests.py create mode 100644 moon_interface/moon_interface/containers.py create mode 100644 moon_interface/moon_interface/http_server.py create mode 100644 moon_interface/moon_interface/server.py create mode 100644 moon_interface/requirements.txt create mode 100644 moon_interface/setup.py create mode 100644 moon_interface/tests/unit_python/api/__init__.py create mode 100644 moon_interface/tests/unit_python/api/test_authz.py create mode 100644 moon_interface/tests/unit_python/conftest.py create mode 100644 moon_interface/tests/unit_python/requirements.txt create mode 100644 moon_interface/tools/api2rst.py create mode 100644 moon_interface/tools/get_keystone_token.py create mode 100644 moon_interface/tools/run.sh create mode 100644 moon_manager/Dockerfile create mode 100644 moon_manager/LICENSE create mode 100644 moon_manager/MANIFEST.in create mode 100644 moon_manager/README.rst create mode 100644 moon_manager/moon_manager/__init__.py create mode 100644 moon_manager/moon_manager/__main__.py create mode 100644 moon_manager/moon_manager/api/__init__.py create mode 100644 moon_manager/moon_manager/api/assignments.py create mode 100644 moon_manager/moon_manager/api/containers.py create mode 100644 moon_manager/moon_manager/api/data.py create mode 100644 moon_manager/moon_manager/api/generic.py create mode 100644 moon_manager/moon_manager/api/meta_data.py create mode 100644 moon_manager/moon_manager/api/meta_rules.py create mode 100644 moon_manager/moon_manager/api/models.py create mode 100644 moon_manager/moon_manager/api/pdp.py create mode 100644 moon_manager/moon_manager/api/perimeter.py create mode 100644 moon_manager/moon_manager/api/policies.py create mode 100644 moon_manager/moon_manager/api/rules.py create mode 100644 moon_manager/moon_manager/http_server.py create mode 100644 moon_manager/moon_manager/server.py create mode 100644 moon_manager/requirements.txt create mode 100644 moon_manager/setup.py create mode 100644 moon_manager/tests/unit_python/__init__.py create mode 100644 moon_manager/tests/unit_python/api/__init__.py create mode 100644 moon_manager/tests/unit_python/api/test_perimeter.py create mode 100644 moon_manager/tests/unit_python/conftest.py create mode 100644 moon_manager/tests/unit_python/requirements.txt create mode 100644 moon_orchestrator/Changelog create mode 100644 moon_orchestrator/Dockerfile create mode 100644 moon_orchestrator/LICENSE create mode 100644 moon_orchestrator/MANIFEST.in create mode 100644 moon_orchestrator/README.md create mode 100644 moon_orchestrator/conf/dockers/template.dockerfile create mode 100644 moon_orchestrator/conf/moon.conf create mode 100644 moon_orchestrator/conf/plugins/authz.py create mode 100644 moon_orchestrator/conf/plugins/session.py create mode 100644 moon_orchestrator/conf/policies/policy_authz/assignment.json create mode 100644 moon_orchestrator/conf/policies/policy_authz/metadata.json create mode 100644 moon_orchestrator/conf/policies/policy_authz/metarule.json create mode 100644 moon_orchestrator/conf/policies/policy_authz/perimeter.json create mode 100644 moon_orchestrator/conf/policies/policy_authz/rule.json create mode 100644 moon_orchestrator/conf/policies/policy_authz/scope.json create mode 100644 moon_orchestrator/conf/policies/policy_empty_admin/assignment.json create mode 100644 moon_orchestrator/conf/policies/policy_empty_admin/metadata.json create mode 100644 moon_orchestrator/conf/policies/policy_empty_admin/metarule.json create mode 100644 moon_orchestrator/conf/policies/policy_empty_admin/perimeter.json create mode 100644 moon_orchestrator/conf/policies/policy_empty_admin/rule.json create mode 100644 moon_orchestrator/conf/policies/policy_empty_admin/scope.json create mode 100644 moon_orchestrator/conf/policies/policy_empty_authz/assignment.json create mode 100644 moon_orchestrator/conf/policies/policy_empty_authz/metadata.json create mode 100644 moon_orchestrator/conf/policies/policy_empty_authz/metarule.json create mode 100644 moon_orchestrator/conf/policies/policy_empty_authz/perimeter.json create mode 100644 moon_orchestrator/conf/policies/policy_empty_authz/rule.json create mode 100644 moon_orchestrator/conf/policies/policy_empty_authz/scope.json create mode 100644 moon_orchestrator/conf/policies/policy_mls_authz/assignment.json create mode 100644 moon_orchestrator/conf/policies/policy_mls_authz/metadata.json create mode 100644 moon_orchestrator/conf/policies/policy_mls_authz/metarule.json create mode 100644 moon_orchestrator/conf/policies/policy_mls_authz/perimeter.json create mode 100644 moon_orchestrator/conf/policies/policy_mls_authz/rule.json create mode 100644 moon_orchestrator/conf/policies/policy_mls_authz/scope.json create mode 100644 moon_orchestrator/conf/policies/policy_rbac_admin/assignment.json create mode 100644 moon_orchestrator/conf/policies/policy_rbac_admin/metadata.json create mode 100644 moon_orchestrator/conf/policies/policy_rbac_admin/metarule.json create mode 100644 moon_orchestrator/conf/policies/policy_rbac_admin/perimeter.json create mode 100644 moon_orchestrator/conf/policies/policy_rbac_admin/rule.json create mode 100644 moon_orchestrator/conf/policies/policy_rbac_admin/scope.json create mode 100644 moon_orchestrator/conf/policies/policy_root/assignment.json create mode 100644 moon_orchestrator/conf/policies/policy_root/metadata.json create mode 100644 moon_orchestrator/conf/policies/policy_root/metarule.json create mode 100644 moon_orchestrator/conf/policies/policy_root/perimeter.json create mode 100644 moon_orchestrator/conf/policies/policy_root/rule.json create mode 100644 moon_orchestrator/conf/policies/policy_root/scope.json create mode 100644 moon_orchestrator/moon_orchestrator/__init__.py create mode 100644 moon_orchestrator/moon_orchestrator/__main__.py create mode 100644 moon_orchestrator/moon_orchestrator/api/__init__.py create mode 100644 moon_orchestrator/moon_orchestrator/api/generic.py create mode 100644 moon_orchestrator/moon_orchestrator/api/pods.py create mode 100644 moon_orchestrator/moon_orchestrator/drivers.py create mode 100644 moon_orchestrator/moon_orchestrator/http_server.py create mode 100644 moon_orchestrator/moon_orchestrator/server.py create mode 100644 moon_orchestrator/requirements.txt create mode 100644 moon_orchestrator/setup.py create mode 100644 moon_orchestrator/tests/unit_python/conftest.py create mode 100644 moon_orchestrator/tests/unit_python/mock_pods.py create mode 100644 moon_orchestrator/tests/unit_python/requirements.txt create mode 100644 moon_orchestrator/tests/unit_python/test_pods.py create mode 100644 moon_orchestrator/tests/unit_python/utilities.py create mode 100644 moon_wrapper/Dockerfile create mode 100644 moon_wrapper/LICENSE create mode 100644 moon_wrapper/MANIFEST.in create mode 100644 moon_wrapper/README.md create mode 100644 moon_wrapper/moon_wrapper/__init__.py create mode 100644 moon_wrapper/moon_wrapper/__main__.py create mode 100644 moon_wrapper/moon_wrapper/api/__init__.py create mode 100644 moon_wrapper/moon_wrapper/api/generic.py create mode 100644 moon_wrapper/moon_wrapper/api/wrapper.py create mode 100644 moon_wrapper/moon_wrapper/http_server.py create mode 100644 moon_wrapper/moon_wrapper/server.py create mode 100644 moon_wrapper/requirements.txt create mode 100644 moon_wrapper/setup.py create mode 100644 moon_wrapper/tests/README.md create mode 100644 moon_wrapper/tests/unit_python/api/__init__.py create mode 100644 moon_wrapper/tests/unit_python/api/test_wrapper.py create mode 100644 moon_wrapper/tests/unit_python/conftest.py create mode 100644 moon_wrapper/tests/unit_python/requirements.txt delete mode 100644 moonv4/DEV.md delete mode 100644 moonv4/README.md delete mode 100644 moonv4/TODO delete mode 100644 moonv4/bin/README.md delete mode 100644 moonv4/bin/bootstrap.py delete mode 100644 moonv4/bin/build_all.sh delete mode 100644 moonv4/bin/build_all_pip.sh delete mode 100644 moonv4/bin/delete_orchestrator.sh delete mode 100644 moonv4/bin/moon_lib_update.sh delete mode 100644 moonv4/bin/set_auth.src delete mode 100755 moonv4/bin/start.sh delete mode 100644 moonv4/conf/moon.conf delete mode 100644 moonv4/kubernetes/README.md delete mode 100644 moonv4/kubernetes/conf/password_moon.txt delete mode 100644 moonv4/kubernetes/conf/password_root.txt delete mode 100644 moonv4/kubernetes/conf/ports.conf delete mode 100644 moonv4/kubernetes/init_k8s.sh delete mode 100644 moonv4/kubernetes/start_moon.sh delete mode 100644 moonv4/kubernetes/templates/consul.yaml delete mode 100644 moonv4/kubernetes/templates/db.yaml delete mode 100644 moonv4/kubernetes/templates/keystone.yaml delete mode 100644 moonv4/kubernetes/templates/kube-dns.yaml delete mode 100644 moonv4/kubernetes/templates/moon_configuration.yaml delete mode 100644 moonv4/kubernetes/templates/moon_gui.yaml delete mode 100644 moonv4/kubernetes/templates/moon_manager.yaml delete mode 100644 moonv4/kubernetes/templates/moon_orchestrator.yaml delete mode 100644 moonv4/moon_authz/Dockerfile delete mode 100644 moonv4/moon_authz/LICENSE delete mode 100644 moonv4/moon_authz/MANIFEST.in delete mode 100644 moonv4/moon_authz/README.rst delete mode 100644 moonv4/moon_authz/moon_authz/__init__.py delete mode 100644 moonv4/moon_authz/moon_authz/__main__.py delete mode 100644 moonv4/moon_authz/moon_authz/api/__init__.py delete mode 100644 moonv4/moon_authz/moon_authz/api/authorization.py delete mode 100644 moonv4/moon_authz/moon_authz/api/generic.py delete mode 100644 moonv4/moon_authz/moon_authz/http_server.py delete mode 100644 moonv4/moon_authz/moon_authz/server.py delete mode 100644 moonv4/moon_authz/requirements.txt delete mode 100644 moonv4/moon_authz/setup.py delete mode 100644 moonv4/moon_authz/tests/unit_python/conftest.py delete mode 100644 moonv4/moon_authz/tests/unit_python/mock_pods.py delete mode 100644 moonv4/moon_authz/tests/unit_python/requirements.txt delete mode 100644 moonv4/moon_authz/tests/unit_python/test_authz.py delete mode 100644 moonv4/moon_authz/tests/unit_python/utilities.py delete mode 100644 moonv4/moon_bouchon/Dockerfile delete mode 100644 moonv4/moon_bouchon/README.md delete mode 100644 moonv4/moon_bouchon/moon_bouchon/__init__.py delete mode 100644 moonv4/moon_bouchon/moon_bouchon/__main__.py delete mode 100644 moonv4/moon_bouchon/moon_bouchon/server.py delete mode 100644 moonv4/moon_bouchon/requirements.txt delete mode 100644 moonv4/moon_bouchon/setup.cfg delete mode 100644 moonv4/moon_bouchon/setup.py delete mode 100644 moonv4/moon_bouchon/tests/test_interface.py delete mode 100644 moonv4/moon_bouchon/tests/test_wrapper.py delete mode 100644 moonv4/moon_gui/.gitignore delete mode 100644 moonv4/moon_gui/.jshintrc delete mode 100644 moonv4/moon_gui/DEV.md delete mode 100644 moonv4/moon_gui/Dockerfile delete mode 100644 moonv4/moon_gui/README.md delete mode 100644 moonv4/moon_gui/delivery/assets/css/main.css delete mode 100644 moonv4/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.eot delete mode 100644 moonv4/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.svg delete mode 100644 moonv4/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.ttf delete mode 100644 moonv4/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.woff delete mode 100755 moonv4/moon_gui/delivery/assets/i18n/en.json delete mode 100755 moonv4/moon_gui/delivery/assets/i18n/fr.json delete mode 100755 moonv4/moon_gui/delivery/assets/img/ajax-loader.gif delete mode 100755 moonv4/moon_gui/delivery/assets/img/ajax-waiting.gif delete mode 100755 moonv4/moon_gui/delivery/assets/img/arrow-link.gif delete mode 100755 moonv4/moon_gui/delivery/assets/img/favicon.ico delete mode 100755 moonv4/moon_gui/delivery/assets/img/logo-openstack.png delete mode 100755 moonv4/moon_gui/delivery/assets/img/logo-orange.gif delete mode 100644 moonv4/moon_gui/delivery/html/authentication/authentication.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/common/404/404.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/common/compatibility/compatibility.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/common/footer/footer.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/common/header/header.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/common/loader/loader.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/common/waiting/waiting.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/dashboard/dashboard.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/logs/logs.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/model/action/model-add.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/model/action/model-delete.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/model/action/model-view.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/model/edit/metadata/metadata-edit.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/model/edit/metadata/metadata-list.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-add.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-map.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-unmap.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit-basic.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/model/edit/metarules/metarules-list.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/model/edit/model-edit-basic.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/model/edit/model-edit.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/model/model-list.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/pdp/action/pdp-add.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/pdp/action/pdp-delete.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/pdp/edit/pdp-edit-basic.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/pdp/edit/pdp-edit.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/pdp/pdp-list.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/policy/action/mapping/policy-map.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/policy/action/mapping/policy-unmap.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/policy/action/policy-add.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/policy/action/policy-delete.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/policy/edit/parameter/assignments/assignments-list.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/policy/edit/parameter/data/data-list.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/policy/edit/parameter/perimeter/perimeter-list.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/policy/edit/parameter/rules/rules-list.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/policy/edit/policy-edit-basic.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/policy/edit/policy-edit.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/policy/policy-list.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/policy/policy-mapped-list.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/project/action/mapping/project-map.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/project/action/mapping/project-unmap.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/project/action/project-add.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/project/action/project-delete.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/project/action/project-view.tpl.html delete mode 100644 moonv4/moon_gui/delivery/html/project/project-list.tpl.html delete mode 100644 moonv4/moon_gui/delivery/index.html delete mode 100644 moonv4/moon_gui/delivery/js/app.js delete mode 100644 moonv4/moon_gui/delivery/js/modules.js delete mode 100755 moonv4/moon_gui/delivery/version.json delete mode 100644 moonv4/moon_gui/gulpfile.js delete mode 100644 moonv4/moon_gui/package.json delete mode 100644 moonv4/moon_gui/run.sh delete mode 100755 moonv4/moon_gui/static/app/authentication/authentication.controller.js delete mode 100755 moonv4/moon_gui/static/app/authentication/authentication.tpl.html delete mode 100755 moonv4/moon_gui/static/app/common/404/404.tpl.html delete mode 100755 moonv4/moon_gui/static/app/common/compatibility/compatibility.tpl.html delete mode 100755 moonv4/moon_gui/static/app/common/footer/footer.controller.js delete mode 100755 moonv4/moon_gui/static/app/common/footer/footer.tpl.html delete mode 100755 moonv4/moon_gui/static/app/common/header/header.controller.js delete mode 100755 moonv4/moon_gui/static/app/common/header/header.tpl.html delete mode 100755 moonv4/moon_gui/static/app/common/loader/loader.dir.js delete mode 100755 moonv4/moon_gui/static/app/common/loader/loader.tpl.html delete mode 100755 moonv4/moon_gui/static/app/common/waiting/waiting.tpl.html delete mode 100755 moonv4/moon_gui/static/app/dashboard/dashboard.tpl.html delete mode 100755 moonv4/moon_gui/static/app/logs/logs.controller.js delete mode 100755 moonv4/moon_gui/static/app/logs/logs.tpl.html delete mode 100755 moonv4/moon_gui/static/app/model/action/model-add.tpl.html delete mode 100755 moonv4/moon_gui/static/app/model/action/model-delete.tpl.html delete mode 100755 moonv4/moon_gui/static/app/model/action/model-view.tpl.html delete mode 100755 moonv4/moon_gui/static/app/model/action/model.controller.add.js delete mode 100755 moonv4/moon_gui/static/app/model/action/model.controller.delete.js delete mode 100755 moonv4/moon_gui/static/app/model/action/model.controller.view.js delete mode 100755 moonv4/moon_gui/static/app/model/edit/metadata/metadata-edit.tpl.html delete mode 100755 moonv4/moon_gui/static/app/model/edit/metadata/metadata-list.tpl.html delete mode 100755 moonv4/moon_gui/static/app/model/edit/metadata/metadata.edit.dir.js delete mode 100755 moonv4/moon_gui/static/app/model/edit/metadata/metadata.list.dir.js delete mode 100755 moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-add.tpl.html delete mode 100755 moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-map.tpl.html delete mode 100755 moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-unmap.tpl.html delete mode 100755 moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.controller.add.js delete mode 100755 moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.map.controller.js delete mode 100755 moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.unmap.controller.js delete mode 100755 moonv4/moon_gui/static/app/model/edit/metarules/action/metarules-edit-basic.tpl.html delete mode 100755 moonv4/moon_gui/static/app/model/edit/metarules/action/metarules-edit.tpl.html delete mode 100755 moonv4/moon_gui/static/app/model/edit/metarules/action/metarules.controller.edit.js delete mode 100755 moonv4/moon_gui/static/app/model/edit/metarules/action/metarules.edit.basic.dir.js delete mode 100755 moonv4/moon_gui/static/app/model/edit/metarules/metarules-list.tpl.html delete mode 100755 moonv4/moon_gui/static/app/model/edit/metarules/metarules.list.dir.js delete mode 100755 moonv4/moon_gui/static/app/model/edit/model-edit-basic.tpl.html delete mode 100755 moonv4/moon_gui/static/app/model/edit/model-edit.tpl.html delete mode 100755 moonv4/moon_gui/static/app/model/edit/model.controller.edit.js delete mode 100755 moonv4/moon_gui/static/app/model/edit/model.edit.basic.dir.js delete mode 100755 moonv4/moon_gui/static/app/model/model-list.tpl.html delete mode 100755 moonv4/moon_gui/static/app/model/model.controller.list.js delete mode 100644 moonv4/moon_gui/static/app/moon.constants.js delete mode 100755 moonv4/moon_gui/static/app/moon.module.js delete mode 100755 moonv4/moon_gui/static/app/pdp/action/pdp-add.tpl.html delete mode 100755 moonv4/moon_gui/static/app/pdp/action/pdp-delete.tpl.html delete mode 100755 moonv4/moon_gui/static/app/pdp/action/pdp.controller.add.js delete mode 100755 moonv4/moon_gui/static/app/pdp/action/pdp.controller.delete.js delete mode 100755 moonv4/moon_gui/static/app/pdp/edit/pdp-edit-basic.tpl.html delete mode 100755 moonv4/moon_gui/static/app/pdp/edit/pdp-edit.tpl.html delete mode 100755 moonv4/moon_gui/static/app/pdp/edit/pdp.controller.edit.js delete mode 100755 moonv4/moon_gui/static/app/pdp/edit/pdp.edit.basic.dir.js delete mode 100755 moonv4/moon_gui/static/app/pdp/pdp-list.tpl.html delete mode 100755 moonv4/moon_gui/static/app/pdp/pdp.controller.list.js delete mode 100755 moonv4/moon_gui/static/app/policy/action/mapping/policy-map.tpl.html delete mode 100755 moonv4/moon_gui/static/app/policy/action/mapping/policy-unmap.tpl.html delete mode 100755 moonv4/moon_gui/static/app/policy/action/mapping/policy.controller.map.js delete mode 100755 moonv4/moon_gui/static/app/policy/action/mapping/policy.controller.unmap.js delete mode 100755 moonv4/moon_gui/static/app/policy/action/policy-add.tpl.html delete mode 100755 moonv4/moon_gui/static/app/policy/action/policy-delete.tpl.html delete mode 100755 moonv4/moon_gui/static/app/policy/action/policy.controller.add.js delete mode 100755 moonv4/moon_gui/static/app/policy/action/policy.controller.delete.js delete mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments-edit.tpl.html delete mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments-list.tpl.html delete mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments.edit.dir.js delete mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments.list.dir.js delete mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/data/data-edit.tpl.html delete mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/data/data-list.tpl.html delete mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/data/data.edit.dir.js delete mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/data/data.list.dir.js delete mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-edit.tpl.html delete mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-list.tpl.html delete mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.edit.dir.js delete mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.list.dir.js delete mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules-edit.tpl.html delete mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules-list.tpl.html delete mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules.edit.dir.js delete mode 100755 moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules.list.dir.js delete mode 100755 moonv4/moon_gui/static/app/policy/edit/policy-edit-basic.tpl.html delete mode 100755 moonv4/moon_gui/static/app/policy/edit/policy-edit.tpl.html delete mode 100755 moonv4/moon_gui/static/app/policy/edit/policy.controller.edit.js delete mode 100755 moonv4/moon_gui/static/app/policy/edit/policy.edit.basic.dir.js delete mode 100755 moonv4/moon_gui/static/app/policy/policy-list.tpl.html delete mode 100755 moonv4/moon_gui/static/app/policy/policy-mapped-list.tpl.html delete mode 100755 moonv4/moon_gui/static/app/policy/policy.controller.list.js delete mode 100755 moonv4/moon_gui/static/app/policy/policy.mapped.list.dir.js delete mode 100755 moonv4/moon_gui/static/app/project/action/mapping/project-map.tpl.html delete mode 100755 moonv4/moon_gui/static/app/project/action/mapping/project-unmap.tpl.html delete mode 100755 moonv4/moon_gui/static/app/project/action/mapping/project.controller.map.js delete mode 100755 moonv4/moon_gui/static/app/project/action/mapping/project.controller.unmap.js delete mode 100755 moonv4/moon_gui/static/app/project/action/project-add.tpl.html delete mode 100755 moonv4/moon_gui/static/app/project/action/project-delete.tpl.html delete mode 100755 moonv4/moon_gui/static/app/project/action/project-view.tpl.html delete mode 100755 moonv4/moon_gui/static/app/project/action/project.controller.add.js delete mode 100755 moonv4/moon_gui/static/app/project/action/project.controller.delete.js delete mode 100755 moonv4/moon_gui/static/app/project/action/project.controller.view.js delete mode 100755 moonv4/moon_gui/static/app/project/project-list.tpl.html delete mode 100755 moonv4/moon_gui/static/app/project/project.controller.list.js delete mode 100755 moonv4/moon_gui/static/app/services/gui/alert.service.js delete mode 100755 moonv4/moon_gui/static/app/services/gui/browser.service.js delete mode 100755 moonv4/moon_gui/static/app/services/gui/form.service.js delete mode 100755 moonv4/moon_gui/static/app/services/gui/menu.service.js delete mode 100755 moonv4/moon_gui/static/app/services/gui/security.pipeline.service.js delete mode 100755 moonv4/moon_gui/static/app/services/gui/util.service.js delete mode 100755 moonv4/moon_gui/static/app/services/gui/version.service.js delete mode 100755 moonv4/moon_gui/static/app/services/moon/model/model.service.js delete mode 100755 moonv4/moon_gui/static/app/services/moon/pdp.service.js delete mode 100755 moonv4/moon_gui/static/app/services/moon/policy/parameters/assignements.service.js delete mode 100755 moonv4/moon_gui/static/app/services/moon/policy/parameters/data.service.js delete mode 100755 moonv4/moon_gui/static/app/services/moon/policy/parameters/perimeter.service.js delete mode 100644 moonv4/moon_gui/static/app/services/moon/policy/parameters/rule.service.js delete mode 100755 moonv4/moon_gui/static/app/services/moon/policy/parameters/rules.service.js delete mode 100755 moonv4/moon_gui/static/app/services/moon/policy/policy.service.js delete mode 100755 moonv4/moon_gui/static/app/services/moon/rule/metadata.service.js delete mode 100755 moonv4/moon_gui/static/app/services/moon/rule/metarule.service.js delete mode 100755 moonv4/moon_gui/static/app/services/partner/authentication.service.js delete mode 100755 moonv4/moon_gui/static/app/services/partner/nova.service.js delete mode 100755 moonv4/moon_gui/static/app/services/partner/project.service.js delete mode 100755 moonv4/moon_gui/static/favicon.ico delete mode 100755 moonv4/moon_gui/static/i18n/en.json delete mode 100755 moonv4/moon_gui/static/i18n/fr.json delete mode 100755 moonv4/moon_gui/static/img/ajax-loader.gif delete mode 100755 moonv4/moon_gui/static/img/ajax-waiting.gif delete mode 100755 moonv4/moon_gui/static/img/arrow-link.gif delete mode 100644 moonv4/moon_gui/static/img/et.jpg delete mode 100755 moonv4/moon_gui/static/img/logo-openstack.png delete mode 100755 moonv4/moon_gui/static/img/logo-orange.gif delete mode 100644 moonv4/moon_gui/static/styles/main.css delete mode 100755 moonv4/moon_gui/static/version.json delete mode 100644 moonv4/moon_gui/templates/index.html delete mode 100644 moonv4/moon_interface/.cache/v/cache/lastfailed delete mode 100644 moonv4/moon_interface/Dockerfile delete mode 100644 moonv4/moon_interface/LICENSE delete mode 100644 moonv4/moon_interface/MANIFEST.in delete mode 100644 moonv4/moon_interface/Makefile delete mode 100644 moonv4/moon_interface/README.rst delete mode 100644 moonv4/moon_interface/moon_interface/__init__.py delete mode 100644 moonv4/moon_interface/moon_interface/__main__.py delete mode 100644 moonv4/moon_interface/moon_interface/api/__init__.py delete mode 100644 moonv4/moon_interface/moon_interface/api/authz.py delete mode 100644 moonv4/moon_interface/moon_interface/api/generic.py delete mode 100644 moonv4/moon_interface/moon_interface/authz_requests.py delete mode 100644 moonv4/moon_interface/moon_interface/containers.py delete mode 100644 moonv4/moon_interface/moon_interface/http_server.py delete mode 100644 moonv4/moon_interface/moon_interface/server.py delete mode 100644 moonv4/moon_interface/requirements.txt delete mode 100644 moonv4/moon_interface/setup.py delete mode 100644 moonv4/moon_interface/tests/unit_python/api/__init__.py delete mode 100644 moonv4/moon_interface/tests/unit_python/api/test_authz.py delete mode 100644 moonv4/moon_interface/tests/unit_python/conftest.py delete mode 100644 moonv4/moon_interface/tests/unit_python/requirements.txt delete mode 100644 moonv4/moon_interface/tools/api2rst.py delete mode 100644 moonv4/moon_interface/tools/get_keystone_token.py delete mode 100644 moonv4/moon_interface/tools/run.sh delete mode 100644 moonv4/moon_manager/Dockerfile delete mode 100644 moonv4/moon_manager/LICENSE delete mode 100644 moonv4/moon_manager/MANIFEST.in delete mode 100644 moonv4/moon_manager/README.rst delete mode 100644 moonv4/moon_manager/moon_manager/__init__.py delete mode 100644 moonv4/moon_manager/moon_manager/__main__.py delete mode 100644 moonv4/moon_manager/moon_manager/api/__init__.py delete mode 100644 moonv4/moon_manager/moon_manager/api/assignments.py delete mode 100644 moonv4/moon_manager/moon_manager/api/containers.py delete mode 100644 moonv4/moon_manager/moon_manager/api/data.py delete mode 100644 moonv4/moon_manager/moon_manager/api/generic.py delete mode 100644 moonv4/moon_manager/moon_manager/api/meta_data.py delete mode 100644 moonv4/moon_manager/moon_manager/api/meta_rules.py delete mode 100644 moonv4/moon_manager/moon_manager/api/models.py delete mode 100644 moonv4/moon_manager/moon_manager/api/pdp.py delete mode 100644 moonv4/moon_manager/moon_manager/api/perimeter.py delete mode 100644 moonv4/moon_manager/moon_manager/api/policies.py delete mode 100644 moonv4/moon_manager/moon_manager/api/rules.py delete mode 100644 moonv4/moon_manager/moon_manager/http_server.py delete mode 100644 moonv4/moon_manager/moon_manager/server.py delete mode 100644 moonv4/moon_manager/requirements.txt delete mode 100644 moonv4/moon_manager/setup.py delete mode 100644 moonv4/moon_manager/tests/unit_python/__init__.py delete mode 100644 moonv4/moon_manager/tests/unit_python/api/__init__.py delete mode 100644 moonv4/moon_manager/tests/unit_python/api/test_perimeter.py delete mode 100644 moonv4/moon_manager/tests/unit_python/conftest.py delete mode 100644 moonv4/moon_manager/tests/unit_python/requirements.txt delete mode 100644 moonv4/moon_orchestrator/Changelog delete mode 100644 moonv4/moon_orchestrator/Dockerfile delete mode 100644 moonv4/moon_orchestrator/LICENSE delete mode 100644 moonv4/moon_orchestrator/MANIFEST.in delete mode 100644 moonv4/moon_orchestrator/README.md delete mode 100644 moonv4/moon_orchestrator/conf/dockers/template.dockerfile delete mode 100644 moonv4/moon_orchestrator/conf/moon.conf delete mode 100644 moonv4/moon_orchestrator/conf/plugins/authz.py delete mode 100644 moonv4/moon_orchestrator/conf/plugins/session.py delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_authz/assignment.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_authz/metadata.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_authz/metarule.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_authz/perimeter.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_authz/rule.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_authz/scope.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_empty_admin/assignment.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_empty_admin/metadata.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_empty_admin/metarule.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_empty_admin/perimeter.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_empty_admin/rule.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_empty_admin/scope.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_empty_authz/assignment.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_empty_authz/metadata.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_empty_authz/metarule.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_empty_authz/perimeter.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_empty_authz/rule.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_empty_authz/scope.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_mls_authz/assignment.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_mls_authz/metadata.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_mls_authz/metarule.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_mls_authz/perimeter.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_mls_authz/rule.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_mls_authz/scope.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_rbac_admin/assignment.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_rbac_admin/metadata.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_rbac_admin/metarule.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_rbac_admin/perimeter.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_rbac_admin/rule.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_rbac_admin/scope.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_root/assignment.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_root/metadata.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_root/metarule.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_root/perimeter.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_root/rule.json delete mode 100644 moonv4/moon_orchestrator/conf/policies/policy_root/scope.json delete mode 100644 moonv4/moon_orchestrator/moon_orchestrator/__init__.py delete mode 100644 moonv4/moon_orchestrator/moon_orchestrator/__main__.py delete mode 100644 moonv4/moon_orchestrator/moon_orchestrator/api/__init__.py delete mode 100644 moonv4/moon_orchestrator/moon_orchestrator/api/generic.py delete mode 100644 moonv4/moon_orchestrator/moon_orchestrator/api/pods.py delete mode 100644 moonv4/moon_orchestrator/moon_orchestrator/drivers.py delete mode 100644 moonv4/moon_orchestrator/moon_orchestrator/http_server.py delete mode 100644 moonv4/moon_orchestrator/moon_orchestrator/server.py delete mode 100644 moonv4/moon_orchestrator/requirements.txt delete mode 100644 moonv4/moon_orchestrator/setup.py delete mode 100644 moonv4/moon_orchestrator/tests/unit_python/conftest.py delete mode 100644 moonv4/moon_orchestrator/tests/unit_python/mock_pods.py delete mode 100644 moonv4/moon_orchestrator/tests/unit_python/requirements.txt delete mode 100644 moonv4/moon_orchestrator/tests/unit_python/test_pods.py delete mode 100644 moonv4/moon_orchestrator/tests/unit_python/utilities.py delete mode 100644 moonv4/moon_wrapper/Dockerfile delete mode 100644 moonv4/moon_wrapper/LICENSE delete mode 100644 moonv4/moon_wrapper/MANIFEST.in delete mode 100644 moonv4/moon_wrapper/README.md delete mode 100644 moonv4/moon_wrapper/moon_wrapper/__init__.py delete mode 100644 moonv4/moon_wrapper/moon_wrapper/__main__.py delete mode 100644 moonv4/moon_wrapper/moon_wrapper/api/__init__.py delete mode 100644 moonv4/moon_wrapper/moon_wrapper/api/generic.py delete mode 100644 moonv4/moon_wrapper/moon_wrapper/api/wrapper.py delete mode 100644 moonv4/moon_wrapper/moon_wrapper/http_server.py delete mode 100644 moonv4/moon_wrapper/moon_wrapper/server.py delete mode 100644 moonv4/moon_wrapper/requirements.txt delete mode 100644 moonv4/moon_wrapper/setup.py delete mode 100644 moonv4/moon_wrapper/tests/README.md delete mode 100644 moonv4/moon_wrapper/tests/unit_python/api/__init__.py delete mode 100644 moonv4/moon_wrapper/tests/unit_python/api/test_wrapper.py delete mode 100644 moonv4/moon_wrapper/tests/unit_python/conftest.py delete mode 100644 moonv4/moon_wrapper/tests/unit_python/requirements.txt delete mode 100644 moonv4/python_moonclient/Changelog delete mode 100644 moonv4/python_moonclient/LICENSE delete mode 100644 moonv4/python_moonclient/MANIFEST.in delete mode 100644 moonv4/python_moonclient/README.md delete mode 100644 moonv4/python_moonclient/python_moonclient/__init__.py delete mode 100644 moonv4/python_moonclient/python_moonclient/authz.py delete mode 100644 moonv4/python_moonclient/python_moonclient/config.py delete mode 100644 moonv4/python_moonclient/python_moonclient/models.py delete mode 100644 moonv4/python_moonclient/python_moonclient/parse.py delete mode 100644 moonv4/python_moonclient/python_moonclient/pdp.py delete mode 100644 moonv4/python_moonclient/python_moonclient/policies.py delete mode 100644 moonv4/python_moonclient/requirements.txt delete mode 100644 moonv4/python_moonclient/setup.py delete mode 100644 moonv4/python_moonclient/tests/unit_python/conftest.py delete mode 100644 moonv4/python_moonclient/tests/unit_python/mock_config.py delete mode 100644 moonv4/python_moonclient/tests/unit_python/requirements.txt delete mode 100644 moonv4/python_moonclient/tests/unit_python/test_config.py delete mode 100644 moonv4/python_moonclient/tests/unit_python/test_models.py delete mode 100644 moonv4/python_moonclient/tests/unit_python/test_pdp.py delete mode 100644 moonv4/python_moonclient/tests/unit_python/test_policies.py delete mode 100644 moonv4/python_moonclient/tests/unit_python/utilities.py delete mode 100644 moonv4/python_moondb/Changelog delete mode 100644 moonv4/python_moondb/LICENSE delete mode 100644 moonv4/python_moondb/MANIFEST.in delete mode 100644 moonv4/python_moondb/README.md delete mode 100644 moonv4/python_moondb/bin/drop_tables.sql delete mode 100644 moonv4/python_moondb/build.sh delete mode 100644 moonv4/python_moondb/python_moondb/__init__.py delete mode 100644 moonv4/python_moondb/python_moondb/api/__init__.py delete mode 100644 moonv4/python_moondb/python_moondb/api/keystone.py delete mode 100644 moonv4/python_moondb/python_moondb/api/managers.py delete mode 100644 moonv4/python_moondb/python_moondb/api/model.py delete mode 100644 moonv4/python_moondb/python_moondb/api/pdp.py delete mode 100644 moonv4/python_moondb/python_moondb/api/policy.py delete mode 100644 moonv4/python_moondb/python_moondb/backends/__init__.py delete mode 100644 moonv4/python_moondb/python_moondb/backends/flat.py delete mode 100644 moonv4/python_moondb/python_moondb/backends/sql.py delete mode 100644 moonv4/python_moondb/python_moondb/core.py delete mode 100644 moonv4/python_moondb/python_moondb/db_manager.py delete mode 100644 moonv4/python_moondb/python_moondb/migrate_repo/__init__.py delete mode 100644 moonv4/python_moondb/python_moondb/migrate_repo/versions/001_moon.py delete mode 100644 moonv4/python_moondb/python_moondb/migrate_repo/versions/__init__.py delete mode 100644 moonv4/python_moondb/requirements.txt delete mode 100644 moonv4/python_moondb/setup.py delete mode 100644 moonv4/python_moondb/tests/unit_python/conftest.py delete mode 100644 moonv4/python_moondb/tests/unit_python/mock_components.py delete mode 100644 moonv4/python_moondb/tests/unit_python/mock_keystone.py delete mode 100644 moonv4/python_moondb/tests/unit_python/requirements.txt delete mode 100644 moonv4/python_moondb/tests/unit_python/test_policies.py delete mode 100644 moonv4/python_moondb/tests/unit_python/utilities.py delete mode 100644 moonv4/python_moonutilities/Changelog delete mode 100644 moonv4/python_moonutilities/LICENSE delete mode 100644 moonv4/python_moonutilities/MANIFEST.in delete mode 100644 moonv4/python_moonutilities/README.md delete mode 100644 moonv4/python_moonutilities/python_moonutilities/__init__.py delete mode 100644 moonv4/python_moonutilities/python_moonutilities/api.py delete mode 100644 moonv4/python_moonutilities/python_moonutilities/auth.py delete mode 100644 moonv4/python_moonutilities/python_moonutilities/cache.py delete mode 100644 moonv4/python_moonutilities/python_moonutilities/configuration.py delete mode 100644 moonv4/python_moonutilities/python_moonutilities/exceptions.py delete mode 100644 moonv4/python_moonutilities/python_moonutilities/misc.py delete mode 100644 moonv4/python_moonutilities/python_moonutilities/security_functions.py delete mode 100644 moonv4/python_moonutilities/requirements.txt delete mode 100644 moonv4/python_moonutilities/setup.py delete mode 100644 moonv4/python_moonutilities/tests/unit_python/conftest.py delete mode 100644 moonv4/python_moonutilities/tests/unit_python/mock_cache.py delete mode 100644 moonv4/python_moonutilities/tests/unit_python/mock_components.py delete mode 100644 moonv4/python_moonutilities/tests/unit_python/mock_keystone.py delete mode 100644 moonv4/python_moonutilities/tests/unit_python/requirements.txt delete mode 100644 moonv4/python_moonutilities/tests/unit_python/test_cache.py delete mode 100644 moonv4/python_moonutilities/tests/unit_python/test_configuration.py delete mode 100644 moonv4/python_moonutilities/tests/unit_python/utilities.py delete mode 100644 moonv4/templates/glance/policy.json delete mode 100644 moonv4/templates/moon_keystone/Dockerfile delete mode 100644 moonv4/templates/moon_keystone/README.md delete mode 100644 moonv4/templates/moon_keystone/run.sh delete mode 100644 moonv4/templates/moonforming/Dockerfile delete mode 100644 moonv4/templates/moonforming/README.md delete mode 100644 moonv4/templates/moonforming/conf/mls.py delete mode 100644 moonv4/templates/moonforming/conf/rbac.py delete mode 100644 moonv4/templates/moonforming/conf2consul.py delete mode 100644 moonv4/templates/moonforming/moon.conf delete mode 100644 moonv4/templates/moonforming/populate_default_values.py delete mode 100644 moonv4/templates/moonforming/run.sh delete mode 100644 moonv4/templates/moonforming/utils/__init__.py delete mode 100644 moonv4/templates/moonforming/utils/config.py delete mode 100644 moonv4/templates/moonforming/utils/models.py delete mode 100644 moonv4/templates/moonforming/utils/pdp.py delete mode 100644 moonv4/templates/moonforming/utils/policies.py delete mode 100644 moonv4/templates/nova/policy.json delete mode 100644 moonv4/templates/python_unit_test/Dockerfile delete mode 100644 moonv4/templates/python_unit_test/README.md delete mode 100644 moonv4/templates/python_unit_test/requirements.txt delete mode 100644 moonv4/templates/python_unit_test/run_tests.sh delete mode 100644 moonv4/tests/get_keystone_projects.py delete mode 100644 moonv4/tests/performance/README.md delete mode 100644 moonv4/tests/populate_default_values.py delete mode 100644 moonv4/tests/scenario/delegation.py delete mode 100644 moonv4/tests/scenario/mls.py delete mode 100644 moonv4/tests/scenario/rbac.py delete mode 100644 moonv4/tests/scenario/rbac_custom_100.py delete mode 100644 moonv4/tests/scenario/rbac_custom_1000.py delete mode 100644 moonv4/tests/scenario/rbac_custom_50.py delete mode 100644 moonv4/tests/scenario/rbac_large.py delete mode 100644 moonv4/tests/scenario/rbac_mls.py delete mode 100644 moonv4/tests/scenario/session.py delete mode 100644 moonv4/tests/scenario/session_large.py delete mode 100644 moonv4/tests/send_authz.py create mode 100644 python_moonclient/Changelog create mode 100644 python_moonclient/LICENSE create mode 100644 python_moonclient/MANIFEST.in create mode 100644 python_moonclient/README.md create mode 100644 python_moonclient/python_moonclient/__init__.py create mode 100644 python_moonclient/python_moonclient/authz.py create mode 100644 python_moonclient/python_moonclient/config.py create mode 100644 python_moonclient/python_moonclient/models.py create mode 100644 python_moonclient/python_moonclient/parse.py create mode 100644 python_moonclient/python_moonclient/pdp.py create mode 100644 python_moonclient/python_moonclient/policies.py create mode 100644 python_moonclient/requirements.txt create mode 100644 python_moonclient/setup.py create mode 100644 python_moonclient/tests/unit_python/conftest.py create mode 100644 python_moonclient/tests/unit_python/mock_config.py create mode 100644 python_moonclient/tests/unit_python/requirements.txt create mode 100644 python_moonclient/tests/unit_python/test_config.py create mode 100644 python_moonclient/tests/unit_python/test_models.py create mode 100644 python_moonclient/tests/unit_python/test_pdp.py create mode 100644 python_moonclient/tests/unit_python/test_policies.py create mode 100644 python_moonclient/tests/unit_python/utilities.py create mode 100644 python_moondb/Changelog create mode 100644 python_moondb/LICENSE create mode 100644 python_moondb/MANIFEST.in create mode 100644 python_moondb/README.md create mode 100644 python_moondb/bin/drop_tables.sql create mode 100644 python_moondb/build.sh create mode 100644 python_moondb/python_moondb/__init__.py create mode 100644 python_moondb/python_moondb/api/__init__.py create mode 100644 python_moondb/python_moondb/api/keystone.py create mode 100644 python_moondb/python_moondb/api/managers.py create mode 100644 python_moondb/python_moondb/api/model.py create mode 100644 python_moondb/python_moondb/api/pdp.py create mode 100644 python_moondb/python_moondb/api/policy.py create mode 100644 python_moondb/python_moondb/backends/__init__.py create mode 100644 python_moondb/python_moondb/backends/flat.py create mode 100644 python_moondb/python_moondb/backends/sql.py create mode 100644 python_moondb/python_moondb/core.py create mode 100644 python_moondb/python_moondb/db_manager.py create mode 100644 python_moondb/python_moondb/migrate_repo/__init__.py create mode 100644 python_moondb/python_moondb/migrate_repo/versions/001_moon.py create mode 100644 python_moondb/python_moondb/migrate_repo/versions/__init__.py create mode 100644 python_moondb/requirements.txt create mode 100644 python_moondb/setup.py create mode 100644 python_moondb/tests/unit_python/conftest.py create mode 100644 python_moondb/tests/unit_python/mock_components.py create mode 100644 python_moondb/tests/unit_python/mock_keystone.py create mode 100644 python_moondb/tests/unit_python/requirements.txt create mode 100644 python_moondb/tests/unit_python/test_policies.py create mode 100644 python_moondb/tests/unit_python/utilities.py create mode 100644 python_moonutilities/Changelog create mode 100644 python_moonutilities/LICENSE create mode 100644 python_moonutilities/MANIFEST.in create mode 100644 python_moonutilities/README.md create mode 100644 python_moonutilities/python_moonutilities/__init__.py create mode 100644 python_moonutilities/python_moonutilities/api.py create mode 100644 python_moonutilities/python_moonutilities/auth.py create mode 100644 python_moonutilities/python_moonutilities/cache.py create mode 100644 python_moonutilities/python_moonutilities/configuration.py create mode 100644 python_moonutilities/python_moonutilities/exceptions.py create mode 100644 python_moonutilities/python_moonutilities/misc.py create mode 100644 python_moonutilities/python_moonutilities/security_functions.py create mode 100644 python_moonutilities/requirements.txt create mode 100644 python_moonutilities/setup.py create mode 100644 python_moonutilities/tests/unit_python/conftest.py create mode 100644 python_moonutilities/tests/unit_python/mock_cache.py create mode 100644 python_moonutilities/tests/unit_python/mock_components.py create mode 100644 python_moonutilities/tests/unit_python/mock_keystone.py create mode 100644 python_moonutilities/tests/unit_python/requirements.txt create mode 100644 python_moonutilities/tests/unit_python/test_cache.py create mode 100644 python_moonutilities/tests/unit_python/test_configuration.py create mode 100644 python_moonutilities/tests/unit_python/utilities.py create mode 100644 templates/glance/policy.json create mode 100644 templates/moon_keystone/Dockerfile create mode 100644 templates/moon_keystone/README.md create mode 100644 templates/moon_keystone/run.sh create mode 100644 templates/moonforming/Dockerfile create mode 100644 templates/moonforming/README.md create mode 100644 templates/moonforming/conf/mls.py create mode 100644 templates/moonforming/conf/rbac.py create mode 100644 templates/moonforming/conf2consul.py create mode 100644 templates/moonforming/moon.conf create mode 100644 templates/moonforming/populate_default_values.py create mode 100644 templates/moonforming/run.sh create mode 100644 templates/moonforming/utils/__init__.py create mode 100644 templates/moonforming/utils/config.py create mode 100644 templates/moonforming/utils/models.py create mode 100644 templates/moonforming/utils/pdp.py create mode 100644 templates/moonforming/utils/policies.py create mode 100644 templates/nova/policy.json create mode 100644 templates/python_unit_test/Dockerfile create mode 100644 templates/python_unit_test/README.md create mode 100644 templates/python_unit_test/requirements.txt create mode 100644 templates/python_unit_test/run_tests.sh create mode 100644 tests/get_keystone_projects.py create mode 100644 tests/performance/README.md create mode 100644 tests/populate_default_values.py delete mode 100755 tests/run_tests.py delete mode 100755 tests/run_tests.sh create mode 100644 tests/scenario/delegation.py create mode 100644 tests/scenario/mls.py create mode 100644 tests/scenario/rbac.py create mode 100644 tests/scenario/rbac_custom_100.py create mode 100644 tests/scenario/rbac_custom_1000.py create mode 100644 tests/scenario/rbac_custom_50.py create mode 100644 tests/scenario/rbac_large.py create mode 100644 tests/scenario/rbac_mls.py create mode 100644 tests/scenario/session.py create mode 100644 tests/scenario/session_large.py create mode 100644 tests/send_authz.py delete mode 100644 upstream/odl-aaa-moon/aaa/.gitignore delete mode 100644 upstream/odl-aaa-moon/aaa/README.md delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/docs/Makefile delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/docs/class_diagram.png delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/docs/class_diagram.ucls delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/docs/credential_auth_sequence.png delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/docs/credential_auth_sequence.wsd delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/docs/federated_auth_sequence.png delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/docs/federated_auth_sequence.wsd delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/docs/mapping.rst delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/docs/resource_access_sequence.png delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/docs/resource_access_sequence.wsd delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/docs/sssd_01.diag delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/docs/sssd_01.svg delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/docs/sssd_02.diag delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/docs/sssd_02.svg delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/docs/sssd_03.diag delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/docs/sssd_03.svg delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/docs/sssd_04.diag delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/docs/sssd_04.svg delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/docs/sssd_05.svg delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/docs/sssd_auth_sequence.png delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/docs/sssd_auth_sequence.wsd delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/docs/sssd_configuration.rst delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/Authentication.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/AuthenticationException.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/AuthenticationService.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/Claim.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/ClaimAuth.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/ClientService.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/CredentialAuth.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/Credentials.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/IDMStoreException.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/IDMStoreUtil.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/IIDMStore.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/IdMService.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/PasswordCredentials.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/SHA256Calculator.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/TokenAuth.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/TokenStore.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/model/Claim.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/model/Domain.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/model/Domains.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/model/Grant.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/model/Grants.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/model/IDMError.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/model/Role.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/model/Roles.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/model/User.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/model/UserPwd.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/model/Users.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/model/Version.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-basic/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-basic/src/main/java/org/opendaylight/aaa/basic/Activator.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-basic/src/main/java/org/opendaylight/aaa/basic/HttpBasicAuth.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-basic/src/test/java/org/opendaylight/aaa/basic/HttpBasicAuthTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-federation/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-federation/src/main/java/org/opendaylight/aaa/federation/Activator.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-federation/src/main/java/org/opendaylight/aaa/federation/ClaimAuthFilter.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-federation/src/main/java/org/opendaylight/aaa/federation/FederationConfiguration.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-federation/src/main/java/org/opendaylight/aaa/federation/FederationEndpoint.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-federation/src/main/java/org/opendaylight/aaa/federation/ServiceLocator.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-federation/src/main/java/org/opendaylight/aaa/federation/SssdFilter.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-federation/src/main/resources/OSGI-INF/metatype/metatype.properties delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-federation/src/main/resources/OSGI-INF/metatype/metatype.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-federation/src/main/resources/WEB-INF/web.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-federation/src/main/resources/federation.cfg delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-federation/src/test/java/org/opendaylight/aaa/federation/FederationEndpointTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-keystone/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-keystone/src/main/java/org/opendaylight/aaa/keystone/Activator.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-keystone/src/main/java/org/opendaylight/aaa/keystone/KeystoneTokenAuth.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-mdsal-store/aaa-authn-mdsal-api/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-mdsal-store/aaa-authn-mdsal-api/src/main/yang/aaa-authn-model.yang delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-mdsal-store/aaa-authn-mdsal-config/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-mdsal-store/aaa-authn-mdsal-config/src/main/resources/initial/08-authn-config.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/AuthNStore.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/DataEncrypter.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/IDMMDSALStore.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/IDMObject2MDSAL.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/IDMStore.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/util/AuthNStoreUtil.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/mdsal/store/rev141031/AuthNStoreModule.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/mdsal/store/rev141031/AuthNStoreModuleFactory.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/yang/aaa-authn-mdsal-store-cfg.yang delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/test/java/org/opendaylight/aaa/authn/mdsal/store/DataBrokerReadMocker.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/test/java/org/opendaylight/aaa/authn/mdsal/store/DataEncrypterTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/test/java/org/opendaylight/aaa/authn/mdsal/store/IDMStoreTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/test/java/org/opendaylight/aaa/authn/mdsal/store/IDMStoreTestUtil.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/test/java/org/opendaylight/aaa/authn/mdsal/store/MDSALConvertTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/test/java/org/opendaylight/aaa/authn/mdsal/store/util/AuthNStoreUtilTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-mdsal-store/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-sssd/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-sssd/src/main/java/org/opendaylight/aaa/sssd/Activator.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-sssd/src/main/java/org/opendaylight/aaa/sssd/SssdClaimAuth.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-store/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-store/src/main/java/org/opendaylight/aaa/store/Activator.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-store/src/main/java/org/opendaylight/aaa/store/DefaultTokenStore.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-store/src/main/resources/OSGI-INF/metatype/metatype.properties delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-store/src/main/resources/OSGI-INF/metatype/metatype.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-store/src/main/resources/tokens.cfg delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-store/src/test/java/org/opendaylight/aaa/store/DefaultTokenStoreTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-sts/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-sts/src/main/java/org/opendaylight/aaa/sts/Activator.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-sts/src/main/java/org/opendaylight/aaa/sts/AnonymousPasswordValidator.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-sts/src/main/java/org/opendaylight/aaa/sts/AnonymousRefreshTokenValidator.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-sts/src/main/java/org/opendaylight/aaa/sts/OAuthRequest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-sts/src/main/java/org/opendaylight/aaa/sts/ServiceLocator.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-sts/src/main/java/org/opendaylight/aaa/sts/TokenAuthFilter.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-sts/src/main/java/org/opendaylight/aaa/sts/TokenEndpoint.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-sts/src/main/resources/WEB-INF/web.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-sts/src/test/java/org/opendaylight/aaa/sts/RestFixture.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-sts/src/test/java/org/opendaylight/aaa/sts/TokenAuthTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn-sts/src/test/java/org/opendaylight/aaa/sts/TokenEndpointTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn/src/main/java/org/opendaylight/aaa/Activator.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn/src/main/java/org/opendaylight/aaa/AuthenticationBuilder.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn/src/main/java/org/opendaylight/aaa/AuthenticationManager.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn/src/main/java/org/opendaylight/aaa/ClaimBuilder.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn/src/main/java/org/opendaylight/aaa/ClientManager.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn/src/main/java/org/opendaylight/aaa/EqualUtil.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn/src/main/java/org/opendaylight/aaa/HashCodeUtil.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn/src/main/java/org/opendaylight/aaa/PasswordCredentialBuilder.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn/src/main/java/org/opendaylight/aaa/SecureBlockingQueue.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn/src/main/resources/OSGI-INF/metatype/metatype.properties delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn/src/main/resources/OSGI-INF/metatype/metatype.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn/src/main/resources/authn.cfg delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn/src/test/java/org/opendaylight/aaa/AuthenticationBuilderTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn/src/test/java/org/opendaylight/aaa/AuthenticationManagerTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn/src/test/java/org/opendaylight/aaa/ClaimBuilderTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn/src/test/java/org/opendaylight/aaa/ClientManagerTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn/src/test/java/org/opendaylight/aaa/PasswordCredentialTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authn/src/test/java/org/opendaylight/aaa/SecureBlockingQueueTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authz/aaa-authz-config/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authz/aaa-authz-config/src/main/resources/initial/08-authz-config.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authz/aaa-authz-model/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authz/aaa-authz-model/src/main/yang/authorization-schema.yang delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authz/aaa-authz-restconf-config/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authz/aaa-authz-restconf-config/src/main/resources/initial/09-rest-connector.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authz/aaa-authz-service/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authz/aaa-authz-service/src/main/java/org/opendaylight/aaa/authz/srv/AuthzBrokerImpl.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authz/aaa-authz-service/src/main/java/org/opendaylight/aaa/authz/srv/AuthzConsumerContextImpl.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authz/aaa-authz-service/src/main/java/org/opendaylight/aaa/authz/srv/AuthzDataReadWriteTransaction.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authz/aaa-authz-service/src/main/java/org/opendaylight/aaa/authz/srv/AuthzDomDataBroker.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authz/aaa-authz-service/src/main/java/org/opendaylight/aaa/authz/srv/AuthzProviderContextImpl.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authz/aaa-authz-service/src/main/java/org/opendaylight/aaa/authz/srv/AuthzReadOnlyTransaction.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authz/aaa-authz-service/src/main/java/org/opendaylight/aaa/authz/srv/AuthzServiceImpl.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authz/aaa-authz-service/src/main/java/org/opendaylight/aaa/authz/srv/AuthzWriteOnlyTransaction.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authz/aaa-authz-service/src/main/java/org/opendaylight/controller/config/yang/config/aaa_authz/srv/AuthzSrvModule.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authz/aaa-authz-service/src/main/java/org/opendaylight/controller/config/yang/config/aaa_authz/srv/AuthzSrvModuleFactory.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authz/aaa-authz-service/src/main/yang/aaa-authz-service-impl.yang delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authz/aaa-authz-service/src/test/java/org/opendaylight/aaa/authz/srv/AuthzConsumerContextImplTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-authz/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-credential-store-api/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-credential-store-api/src/main/yang/credential-model.yang delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-h2-store/.gitignore delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-h2-store/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/config/IdmLightConfig.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/AbstractStore.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/DomainStore.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/GrantStore.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/H2Store.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/RoleStore.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/StoreException.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/UserStore.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/h2/store/rev151128/AAAH2StoreModule.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/h2/store/rev151128/AAAH2StoreModuleFactory.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-h2-store/src/main/resources/initial/08-aaa-h2-store-config.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-h2-store/src/main/yang/aaa-h2-store.yang delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/DomainStoreTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/GrantStoreTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/H2StoreTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/RoleStoreTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/UserStoreTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/src/main/java/org/opendaylight/aaa/idm/IdmLightApplication.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/src/main/java/org/opendaylight/aaa/idm/IdmLightProxy.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/src/main/java/org/opendaylight/aaa/idm/StoreBuilder.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/src/main/java/org/opendaylight/aaa/idm/rest/DomainHandler.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/src/main/java/org/opendaylight/aaa/idm/rest/RoleHandler.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/src/main/java/org/opendaylight/aaa/idm/rest/UserHandler.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/src/main/java/org/opendaylight/aaa/idm/rest/VersionHandler.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/idmlight/rev151204/AAAIDMLightModule.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/idmlight/rev151204/AAAIDMLightModuleFactory.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/src/main/resources/WEB-INF/web.xml delete mode 100755 upstream/odl-aaa-moon/aaa/aaa-idmlight/src/main/resources/idmtool.py delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/src/main/resources/initial/08-aaa-idmlight-config.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/src/main/yang/aaa-idmlight.yang delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/src/test/java/org/opendaylight/aaa/idm/persistence/PasswordHashTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/src/test/java/org/opendaylight/aaa/idm/rest/test/DomainHandlerTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/src/test/java/org/opendaylight/aaa/idm/rest/test/HandlerTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/src/test/java/org/opendaylight/aaa/idm/rest/test/IDMTestStore.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/src/test/java/org/opendaylight/aaa/idm/rest/test/RoleHandlerTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/src/test/java/org/opendaylight/aaa/idm/rest/test/UserHandlerTest.java delete mode 100755 upstream/odl-aaa-moon/aaa/aaa-idmlight/tests/cleardb.sh delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/tests/domain.json delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/tests/domain2.json delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/tests/grant.json delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/tests/grant2.json delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/tests/result.json delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/tests/role-admin.json delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/tests/role-user.json delete mode 100755 upstream/odl-aaa-moon/aaa/aaa-idmlight/tests/test.sh delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/tests/user.json delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/tests/user2.json delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idmlight/tests/userpwd.json delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idp-mapping/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idp-mapping/src/main/java/org/opendaylight/aaa/idpmapping/Activator.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idp-mapping/src/main/java/org/opendaylight/aaa/idpmapping/IdpJson.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idp-mapping/src/main/java/org/opendaylight/aaa/idpmapping/InvalidRuleException.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idp-mapping/src/main/java/org/opendaylight/aaa/idpmapping/InvalidTypeException.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idp-mapping/src/main/java/org/opendaylight/aaa/idpmapping/InvalidValueException.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idp-mapping/src/main/java/org/opendaylight/aaa/idpmapping/RuleProcessor.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idp-mapping/src/main/java/org/opendaylight/aaa/idpmapping/StatementErrorException.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idp-mapping/src/main/java/org/opendaylight/aaa/idpmapping/Token.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idp-mapping/src/main/java/org/opendaylight/aaa/idpmapping/UndefinedValueException.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idp-mapping/src/test/java/org/opendaylight/aaa/idpmapping/RuleProcessorTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-idp-mapping/src/test/java/org/opendaylight/aaa/idpmapping/TokenTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro-act/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro-act/src/main/java/org/opendaylight/aaa/shiroact/Activator.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro-act/src/test/java/org/opendaylight/aaa/shiroact/ActivatorTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/main/java/org/opendaylight/aaa/shiro/Activator.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/main/java/org/opendaylight/aaa/shiro/ServiceProxy.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/main/java/org/opendaylight/aaa/shiro/accounting/Accounter.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/main/java/org/opendaylight/aaa/shiro/authorization/DefaultRBACRules.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/main/java/org/opendaylight/aaa/shiro/authorization/RBACRule.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/main/java/org/opendaylight/aaa/shiro/filters/AAAFilter.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/main/java/org/opendaylight/aaa/shiro/filters/AAAShiroFilter.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/main/java/org/opendaylight/aaa/shiro/filters/AuthenticationListener.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/main/java/org/opendaylight/aaa/shiro/filters/AuthenticationTokenUtils.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/main/java/org/opendaylight/aaa/shiro/filters/MoonOAuthFilter.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/main/java/org/opendaylight/aaa/shiro/filters/ODLHttpAuthenticationFilter.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/main/java/org/opendaylight/aaa/shiro/moon/MoonPrincipal.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/main/java/org/opendaylight/aaa/shiro/moon/MoonTokenEndpoint.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/main/java/org/opendaylight/aaa/shiro/realm/MoonRealm.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/main/java/org/opendaylight/aaa/shiro/realm/ODLJndiLdapRealm.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/main/java/org/opendaylight/aaa/shiro/realm/ODLJndiLdapRealmAuthNOnly.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/main/java/org/opendaylight/aaa/shiro/realm/RadiusRealm.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/main/java/org/opendaylight/aaa/shiro/realm/TACACSRealm.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/main/java/org/opendaylight/aaa/shiro/realm/TokenAuthRealm.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/main/java/org/opendaylight/aaa/shiro/web/env/KarafIniWebEnvironment.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/main/resources/WEB-INF/web.xml delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/main/resources/shiro.ini delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/ServiceProxyTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/TestAppender.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/authorization/DefaultRBACRulesTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/authorization/RBACRuleTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/filters/AuthenticationListenerTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/filters/AuthenticationTokenUtilsTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/realm/ODLJndiLdapRealmTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/realm/TokenAuthRealmTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/web/env/KarafIniWebEnvironmentTest.java delete mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/resources/logback-test.xml delete mode 100644 upstream/odl-aaa-moon/aaa/artifacts/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/commons/docs/AuthNusecases.vsd delete mode 100644 upstream/odl-aaa-moon/aaa/commons/docs/direct_authn.png delete mode 100644 upstream/odl-aaa-moon/aaa/commons/docs/federated_authn1.png delete mode 100644 upstream/odl-aaa-moon/aaa/commons/docs/federated_authn2.png delete mode 100644 upstream/odl-aaa-moon/aaa/commons/federation/README delete mode 100644 upstream/odl-aaa-moon/aaa/commons/federation/idp_mapping_rules.json.example delete mode 100644 upstream/odl-aaa-moon/aaa/commons/federation/jetty.xml.example delete mode 100644 upstream/odl-aaa-moon/aaa/commons/federation/my_app.conf.example delete mode 100644 upstream/odl-aaa-moon/aaa/commons/postman_examples/AAA_AuthZ_MDSAL.json.postman_collection delete mode 100644 upstream/odl-aaa-moon/aaa/distribution-karaf/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/features/api/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/features/api/src/main/features/features.xml delete mode 100644 upstream/odl-aaa-moon/aaa/features/authn/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/features/authn/src/main/features/features.xml delete mode 100644 upstream/odl-aaa-moon/aaa/features/authz/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/features/authz/src/main/features/features.xml delete mode 100644 upstream/odl-aaa-moon/aaa/features/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/features/shiro/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/features/shiro/src/main/features/features.xml delete mode 100644 upstream/odl-aaa-moon/aaa/parent/pom.xml delete mode 100644 upstream/odl-aaa-moon/aaa/pom.xml diff --git a/DEV.md b/DEV.md new file mode 100644 index 00000000..0dff2f17 --- /dev/null +++ b/DEV.md @@ -0,0 +1,206 @@ +# Developer Tutorial + +## Gerrit Setup +### Git Install +- `sudo apt-get install git` +- `git config --global user.email "example@wikimedia.org"` +- `git config --global user.name "example"` + +### ssh key +- `cd ~/.ssh` +- `ssh-keygen -t rsa -C your_email@youremail.com` +- `~/.ssh/id_rsa`: identification (private) key` +- `~/.ssh/id_rsa.pub`: public key +- copy the public key to Gerrit web +- add Gerrit web上 entry to `~/.ssh/known_hosts` +- eval `ssh-agent`: start ssh-agent +- `ssh-add ~/.ssh/id_rsa`: add private key to ssh +- `ssh -p 29418 @gerrit.opnfv.org`: test + +### Gerrit clone +- `git clone https://WuKong@gerrit.opnfv.org:29418/moon` +- the password is dynamically generated on the Gerrit web + +### Gerrit Setting +- `sudo apt-get install python-pip` +- `sudo pip install git-review` +- `git remote add gerrit ssh://@gerrit.opnfv.org:29418/moon.git` +- add the ssh public key to the Gerrit web +- `git review –s`: test the Gerrit review connection +- add Contributor Agreement, from settings/Agreement + +### Gerrit-Review +- git add XXX +- git commit --signoff --all +- git review + +### Review Correction +- `git clone https://git.opnfv.org/moon` +- `cd moon` +- get the commit id from Gerrit dashboard +- `git checkout commit_id` +- `git checkout -b 48957-1` (where '48957' is the change number and '1' is the patch_number) +- do your changes ex:`vi specs/policy/external-pdp.rst` +- `git add specs/policy/external-pdp.rst` +- `git commit –amend` +- `git review` + + +## Build Python Package +### pre-requist +Get the code +```bash +git clone https://git.opnfv.org/moon +cd moon/moonv4 +export MOON_HOME=$(pwd) +sudo ln -s $(pwd)/conf /etc/moon +``` + +Install python wheel +```bash +sudo apt install python3-wheel +``` + +Install pip twine +```bash +sudo pip install twine +``` + +Package code, wheel is a new format instead of `tar.gz` +```bash +python setup.py sdist bdist_wheel +``` + +Upload to PyPi +```bash +twine upload dist/moon_xxx-y.y.y.whl +twine upload dist/moon_xxx-y.y.y.tar.gz +``` + +Install a package from PyPi +```bash +sudo pypi install moon_xxx --upgrade +``` + +### moon_db +- change version in `moon_db/__init__.py` +- add `Changelog` + +### moon_utilities +- change version in `moon_utilities/__init__.py` +- add `Changelog` + +### moon_orchestrator +- change version in `moon_orchestrator/__init__.py` +- add `Changelog` + + +### Build All Pip +```bash +sudo pip3 install pip --upgrade +cd ${MOON_HOME}/bin +source build_all_pip.sh +``` + + +## Container +## keystone_mitaka +see `templates/docker/keystone/README.md` to build the `keystone_mitaka` container + + +### moon_router + + +### moon_interface + + +### moon_manager + + +### moon_authz + + +### moon_gui + + +## How to hack the Moon platform +### Force the build of components + +If you want to rebuild one or more component, you have to modify the configuration file `moon.conf`. + +For example, if you want to rebuild the moon_interface, got to the `[interface]` section and delete the +value of the container key like this: + +``` +[interface] +host=172.18.0.11 +port=38001 +# Name of the container to download (if empty build from scratch) +# example: container=moon/moon_interface:latest +container= +``` + +You can configure the interface, the router and both the security_function and security_policy. +You can also force the version of the component like this: `container=moon/moon_interface:4.0.0` + +### Update the moon_interface + +Go to the directory `${MOON_HOME}/moon_interface` and update the code accordingly to your needs, +then update the python package. + +```bash +cd ${MOON_HOME}/moon_interface +python setup.py sdist +cp dist/moon_interface_* ../moon_orchestrator/dist +# kill moon_orchestrator if needed and restart it +``` + +### Update the moon_secrouter + +Go to the directory `${MOON_HOME}/moon_secrouter` and update the code accordingly to your needs, +then update the python package. + +```bash +cd ${MOON_HOME}/moon_secrouter +python setup.py sdist +cp dist/moon_secrouter* ../moon_orchestrator/dist +# kill moon_orchestrator if needed and restart it +``` + +## Problems that may arise + +If the moon_orchestrator doesn't want to start +(with, for example, the following error: `docker.errors.APIError: 409 Client Error: Conflict`), +check if the router and interface containers still exist and kill and delete them: + +```bash +docker kill moon_interface +docker kill moon_router +docker rm moon_interface +docker rm moon_router +``` + +If the moon_orchestrator complains that it cannot request the RabbitMQ server, +check if the messenger server is up and running: + +```bash +docker ps +# you must see the messenger running here +# if not, restart it +docker run -dti --net=moon --hostname messenger --name messenger --link messenger:messenger -e RABBITMQ_DEFAULT_USER=moon -e RABBITMQ_DEFAULT_PASS=password -e RABBITMQ_NODENAME=rabbit@messenger -e RABBITMQ_DEFAULT_VHOST=moon -p 5671:5671 -p 5672:5672 rabbitmq:3-management +``` + +## Configure DB +### Relaunch Keystone docker +If error of `get_keystone_projects()`, then relaunch the Keystone docker, and wait 40 seconds!!! +```bash +docker rm -f keystone +docker run -dti --net moon --name keystone --hostname=keystone -e DB_HOST=db -e DB_PASSWORD_ROOT=p4sswOrd1 -p 35357:35357 -p 5000:5000 keystone:mitaka +``` + +### Add default data in DB +Pre-fill the DB with a RBAC policy +```bash +cd ${MOON_HOME}/moon_interface/tests/apitests +python3 populate_default_values.py scenario/ rbac.py +``` diff --git a/README.md b/README.md new file mode 100644 index 00000000..ba3604d6 --- /dev/null +++ b/README.md @@ -0,0 +1,381 @@ +# Moon +__Version 4.3__ + +This directory contains all the modules for running the Moon platform. + +## Installation +### kubeadm +You must follow those explanations to install `kubeadm`: +> https://kubernetes.io/docs/setup/independent/install-kubeadm/ + +To summarize, you must install `docker`: +```bash +apt update +apt install -y docker.io +``` + +And then, install `kubeadm`: +```bash +apt update && apt install -y apt-transport-https +curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - +cat </etc/apt/sources.list.d/kubernetes.list +deb http://apt.kubernetes.io/ kubernetes-xenial main +EOF +apt update +apt install -y kubelet kubeadm kubectl +``` + +### Moon +The Moon code is not necessary to start the platform but you need +Kubernetes configuration files from the GIT repository. + +The easy way is to clone the Moon code: +```bash +git clone https://git.opnfv.org/moon +cd moon/moonv4 +export MOON=$(pwd) +``` + +### OpenStack +You must have the following OpenStack components installed somewhere: +- nova, see [Nova install](https://docs.openstack.org/mitaka/install-guide-ubuntu/nova-controller-install.html) +- glance, see [Glance install](https://docs.openstack.org/glance/pike/install/) + +A Keystone component is automatically installed and configured in the Moon platform. +After the Moon platform installation, the Keystone server will be available +at: `http://localhost:30005 or http://\:30005` + +You can also use your own Keystone server if you want. + +## Initialisation +### kubeadm +The `kubeadm` platform can be initialized with the following shell script: +```bash +sh kubernetes/init_k8s.sh +``` + +Wait until all the kubeadm containers are in the `running` state: +```bash +watch kubectl get po --namespace=kube-system +``` + +You must see something like this: + + $ kubectl get po --namespace=kube-system + NAME READY STATUS RESTARTS AGE + calico-etcd-7qgjb 1/1 Running 0 1h + calico-node-f8zvm 2/2 Running 1 1h + calico-policy-controller-59fc4f7888-ns9kv 1/1 Running 0 1h + etcd-varuna 1/1 Running 0 1h + kube-apiserver-varuna 1/1 Running 0 1h + kube-controller-manager-varuna 1/1 Running 0 1h + kube-dns-bfbb49cd7-rgqxn 3/3 Running 0 1h + kube-proxy-x88wg 1/1 Running 0 1h + kube-scheduler-varuna 1/1 Running 0 1h + +### Moon +The Moon platform is composed on the following components: +* `consul`: a Consul configuration server +* `db`: a MySQL database server +* `keystone`: a Keystone authentication server +* `gui`: a Moon web interface +* `manager`: the Moon manager for the database +* `orchestrator`: the Moon component that manage pods in te K8S platform +* `wrapper`: the Moon endpoint where OpenStack component connect to. + +At this point, you must choose one of the following options: +* Specific configuration +* Generic configuration + +#### Specific Configuration +Why using a specific configuration: +1. The `db` and `keystone` can be installed by yourself but you must configure the +Moon platform to use them. +2. You want to change the default passwords in the Moon platform + +Use the following commands: `TODO` + +#### Generic Configuration +Why using a specific configuration: +1. You just want to test the platform +2. You want to develop on the Moon platform + +The `Moon` platform can be initialized with the following shell script: +```bash +sh kubernetes/start_moon.sh +``` + +Wait until all the Moon containers are in the `running` state: +```bash +watch kubectl get po --namespace=moon +``` + +You must see something like this: + + $ kubectl get po --namespace=moon + NAME READY STATUS RESTARTS AGE + consul-57b6d66975-9qnfx 1/1 Running 0 52m + db-867f9c6666-bq8cf 1/1 Running 0 52m + gui-bc9878b58-q288x 1/1 Running 0 51m + keystone-7d9cdbb69f-bl6ln 1/1 Running 0 52m + manager-5bfbb96988-2nvhd 1/1 Running 0 51m + manager-5bfbb96988-fg8vj 1/1 Running 0 51m + manager-5bfbb96988-w9wnk 1/1 Running 0 51m + orchestrator-65d8fb4574-tnfx2 1/1 Running 0 51m + wrapper-astonishing-748b7dcc4f-ngsvp 1/1 Running 0 51m + +## Configuration +### Moon +#### Introduction +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 + +This is a 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 server in the +`openstack/keystone` element or through the link: +> 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 here: +> http://varuna: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: + + cd $MOON + kubectl delete -f kubernetes/templates/moon_configuration.yaml + kubectl create -f kubernetes/templates/moon_configuration.yaml + + +### OpenStack +Before updating the configuration of the OpenStack platform, check that the platform +is working without Moon, use the following commands: +```bash +# set authentication +openstack endpoint list +openstack user list +openstack server list +``` + +In order to connect the OpenStack platform with the Moon platform, you must update some +configuration files in Nova and Glance: +* `/etc/nova/policy.json` +* `/etc/glance/policy.json` + +In some installed platform, the `/etc/nova/policy.json` can be absent so you have +to create one. You can find example files in those directory: +> ${MOON}/moonv4/templates/nova/policy.json +> ${MOON}/moonv4/templates/glance/policy.json + +Each line is mapped to an OpenStack API interface, for example, the following line +allows the user to get details for every virtual machines in the cloud +(the corresponding shell command is `openstack server list`): + + "os_compute_api:servers:detail": "", + +This lines indicates that there is no special authorisation to use this API, +every users can use it. If you want that the Moon platform handles that authorisation, +update this line with: + + "os_compute_api:servers:detail": "http://my_hostname:31001/authz" + +1) by replacing `my_hostname` with the hostname (od the IP address) of the Moon platform. +2) by updating the TCP port (default: 31001) with the good one. + +To find this TCP port, use the following command: + + $ kubectl get services -n moon | grep wrapper | cut -d ":" -f 2 | cut -d " " -f 1 + 31002/TCP + +### Moon +The Moon platform comes with a graphical user interface which can be used with +a web browser at this URL: +> http://$MOON_HOST:30002 + +You will be asked to put a login and password. Those elements are the login and password +of the Keystone server, if you didn't modify the Keystone server, you will find the +login and password here: +> http://$MOON_HOST:30005/ui/#/dc1/kv/openstack/keystone/edit + +**WARNING: the password is in clear text, this is a known security issue.** + +The Moon platform can also be requested through its API: +> http://$MOON_HOST:30001 + +**WARNING: By default, no login/password will be needed because of +the configuration which is in DEV mode.** + +If you want more security, you have to update the configuration of the Keystone server here: +> http://$MOON_HOST:30005/ui/#/dc1/kv/openstack/keystone/edit + +by modifying the `check_token` argument to `yes`. +If you write this modification, your requests to Moon API must always include a valid token +taken from the Keystone server. This token must be place in the header of the request +(`X-Auth-Token`). + +## usage +### tests the platform +In order to know if the platform is healthy, here are some commands you can use. +1) Check that all the K8S pods in the Moon namespace are in running state: +`kubectl get pods -n moon` + +2) Check if the Manager API is running: +```bash +curl http://$MOON_HOST:30001 +curl http://$MOON_HOST:30001/pdp +curl http://$MOON_HOST:30001/policies +``` + +If you configured the authentication in the Moon platform: +```bash +curl -i \ + -H "Content-Type: application/json" \ + -d ' +{ "auth": { + "identity": { + "methods": ["password"], + "password": { + "user": { + "name": "admin", + "domain": { "id": "default" }, + "password": "" + } + } + }, + "scope": { + "project": { + "name": "admin", + "domain": { "id": "default" } + } + } + } +}' \ + "http://moon_hostname:30006/v3/auth/tokens" ; echo + +curl --header "X-Auth-Token: " http://moon_hostname:30001 +curl --header "X-Auth-Token: " http://moon_hostname:30001/pdp +curl --header "X-Auth-Token: " http://moon_hostname:30001/policies +``` + +3) Use a web browser to navigate to the GUI and enter the login and password of the keystone service: +`firefox http://$MOON_HOST:30002` + +4) Use tests Python Scripts +check firstly the Consul service for *Components/Manager*, e.g. +```json +{ + "port": 8082, + "bind": "0.0.0.0", + "hostname": "manager", + "container": "wukongsun/moon_manager:v4.3.1", + "external": { + "port": 30001, + "hostname": "$MOON_HOST" + } +} +``` +*OpenStack/Keystone*: e.g. +```json +{ + "url": "http://keystone:5000/v3", + "user": "admin", + "password": "p4ssw0rd", + "domain": "default", + "project": "admin", + "check_token": false, + "certificate": false, + "external": { + "url": "http://$MOON_HOST:30006/v3" + } +} +``` + +```bash +python3 populate_default_values.py --consul-host=$MOON_HOST --consul-port=30005 -v scenario/rbac_large.py +python3 send_authz.py --consul-host=$MOON_HOST --consul-port=30005 --authz-host=$MOON_HOST --authz-port=31002 -v scenario/rbac_large.py +``` + +### GUI 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`) + + +## Annexes + +### connect to the OpenStack platform + +Here is a shell script to authenticate to the OpenStack platform as `admin`: + + export OS_USERNAME=admin + export OS_PASSWORD=p4ssw0rd + export OS_REGION_NAME=Orange + export OS_TENANT_NAME=admin + export OS_AUTH_URL=http://moon_hostname:30006/v3 + export OS_DOMAIN_NAME=Default + export OS_IDENTITY_API_VERSION=3 + +For the `demo_user`, use: + + export OS_USERNAME=demo_user + export OS_PASSWORD=your_secret_password + export OS_REGION_NAME=Orange + export OS_TENANT_NAME=demo + export OS_AUTH_URL=http://moon_hostname:30006/v3 + export OS_DOMAIN_NAME=Default + export OS_IDENTITY_API_VERSION=3 + diff --git a/README.rst b/README.rst deleted file mode 100644 index d91649bf..00000000 --- a/README.rst +++ /dev/null @@ -1,35 +0,0 @@ -MOON OPNFV Repo -=============== - -keystone-moon -------------- - -this is a fork of OpenStack/keystone which adds an extension to Keystone for access control policy - -keystonemiddleware-moon ------------------------ - -this is a fork of OpenStack/keystonemiddleware which enables access control policy enforcement of keystone-moon - - -moonclient ----------- - -this is a command-line interface to manipulate keystone-moon - - -moonv4 ------- - -this is the new moon framework based on micro-service architectures - - -upstream/odl-aaa-moon ---------------------- - -this is a fork of OpenDaylight/aaa which adds a shiro filter/realm to delegate OpenDaylight authenticaiton to keystone-moon - -tests ------ - -this contains tests for OPNFV/CI tests integration diff --git a/TODO b/TODO new file mode 100644 index 00000000..afdadf3c --- /dev/null +++ b/TODO @@ -0,0 +1,33 @@ +Here is a list of what must be done to have complete version of the Moon platform. + +Architecture + +- Add a complete logging system +- Replace moon_orchestrator with Kubernetes + +Actions that must be done before the next version: + +- manage a token/uuid (ie session ID) in the moon_interface component +- add a timestamps in moon_router to know if the database has been modified +- rename moon_db and moon_utilities because they are not container but just libraries +- work on moonclient because it doesn't work with the new data model +- check all input from moon_interface (check that input data are correct and safe) +- Move @enforce from moon_db to API in Moon_Manager +- Need to work on unit tests with the new data model + +Bugs to fix: + +- Connect the authz functionality with the enforce decorator +- When adding user or VM in GUI, there is a bug in the backend (manager ?) +- GUI: in the "Projects" tab, move the "Map" link in the "Action" button +- GUI: move tabs in this order : "Models, Policy, PDP, Projects" + +Other actions: + +- Some cleaning in all classes +- Write Installation procedures +- Write User and administrator documentation +- Run unit tests +- Add and run integration tests +- Need to check if the Moon platform still can retrieve users and roles from Keystone +- Need to retrieve VM from Nova diff --git a/bin/README.md b/bin/README.md new file mode 100644 index 00000000..3125c468 --- /dev/null +++ b/bin/README.md @@ -0,0 +1,5 @@ +# Automated Tools/Scripts + +## moon_utilities_update +- update moon_utilities to PIP: `./moon_utilities_update.sh upload` +- locally update moon_utilities for each moon Python package: `./moon_utilities_update.sh copy` \ No newline at end of file diff --git a/bin/bootstrap.py b/bin/bootstrap.py new file mode 100644 index 00000000..6f2a5e03 --- /dev/null +++ b/bin/bootstrap.py @@ -0,0 +1,235 @@ +import os +import sys +import time +import requests +import yaml +import logging +import json +import base64 +import mysql.connector +import re +import subprocess + +logging.basicConfig(level=logging.INFO) +log = logging.getLogger("moon.bootstrap") +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 start_consul(data_config): + cmd = ["docker", "run", "-d", "--net=moon", "--name=consul", "--hostname=consul", "-p", "8500:8500", "consul"] + output = subprocess.run(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + if output.returncode != 0: + log.info(" ".join(cmd)) + log.info(output.returncode) + log.error(output.stderr) + log.error(output.stdout) + raise Exception("Error starting Consul container!") + while True: + try: + req = requests.get("http://{}:{}/ui".format(CONSUL_HOST, CONSUL_PORT)) + except requests.exceptions.ConnectionError: + log.info("Waiting for Consul ({}:{})".format(CONSUL_HOST, CONSUL_PORT)) + time.sleep(1) + continue + else: + break + # if req.status_code in (302, 200): + # break + # log.info("Waiting for Consul ({}:{})".format(CONSUL_HOST, CONSUL_PORT)) + # time.sleep(1) + log.info("Consul is up") + + req = requests.get("http://{}:{}/v1/kv/database".format(CONSUL_HOST, CONSUL_PORT)) + if req.status_code == 200: + log.info("Consul is already populated") + return + + 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(): + if type(_value) is dict: + 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]) + + +def start_database(): + cmd = ["docker", "run", "-dti", "--net=moon", "--hostname=db", "--name=db", + "-e", "MYSQL_ROOT_PASSWORD=p4sswOrd1", "-e", "MYSQL_DATABASE=moon", "-e", "MYSQL_USER=moon", + "-e", "MYSQL_PASSWORD=p4sswOrd1", "-p", "3306:3306", "mysql:latest"] + output = subprocess.run(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + if output.returncode != 0: + log.info(cmd) + log.error(output.stderr) + log.error(output.stdout) + raise Exception("Error starting DB container!") + for database in get("database"): + database_url = database['url'] + match = re.search("(?P^[\\w+]+):\/\/(?P\\w+):(?P.+)@(?P\\w+):*(?P\\d*)", + database_url) + config = match.groupdict() + while True: + try: + conn = mysql.connector.connect( + host=config["host"], + user=config["user"], + password=config["password"], + database="moon" + ) + conn.close() + except mysql.connector.errors.InterfaceError: + log.info("Waiting for Database ({})".format(config["host"])) + time.sleep(1) + continue + else: + log.info("Database is up, populating it...") + output = subprocess.run(["moon_db_manager", "upgrade"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + if output.returncode != 0: + raise Exception("Error populating the database!") + break + + +def start_keystone(): + output = subprocess.run(["docker", "run", "-dti", "--net=moon", "--hostname=keystone", "--name=keystone", + "-e", "DB_HOST=db", "-e", "DB_PASSWORD_ROOT=p4sswOrd1", "-p", "35357:35357", + "-p", "5000:5000", "keystone:mitaka"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + if output.returncode != 0: + raise Exception("Error starting Keystone container!") + # TODO: Keystone answers request too quickly + # even if it is not fully loaded + # we must test if a token retrieval is possible or not + # to see if Keystone is truly up and running + for config in get("openstack/keystone"): + while True: + try: + time.sleep(1) + req = requests.get(config["url"]) + except requests.exceptions.ConnectionError: + log.info("Waiting for Keystone ({})".format(config["url"])) + time.sleep(1) + continue + else: + log.info("Keystone is up") + break + + +def start_moon(data_config): + cmds = [ + # ["docker", "run", "-dti", "--net=moon", "--name=wrapper", "--hostname=wrapper", "-p", + # "{0}:{0}".format(data_config['components']['wrapper']['port']), + # data_config['components']['wrapper']['container']], + ["docker", "run", "-dti", "--net=moon", "--name=manager", + "--hostname=manager", "-p", + "{0}:{0}".format(data_config['components']['manager']['port']), + data_config['components']['manager']['container']], + ["docker", "run", "-dti", "--net=moon", "--name=interface", + "--hostname=interface", "-p", + "{0}:{0}".format(data_config['components']['interface']['port']), + data_config['components']['interface']['container']], + ] + for cmd in cmds: + log.warning("Start {}".format(cmd[-1])) + # answer = input() + # if answer.lower() in ("y", "yes", "o", "oui"): + output = subprocess.run(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + time.sleep(3) + if output.returncode != 0: + log.info(" ".join(cmd)) + log.info(output.returncode) + log.error(output.stderr) + log.error(output.stdout) + raise Exception("Error starting {} container!".format(cmd[-1])) + subprocess.run(["docker", "ps"]) + + +def main(): + data_config = search_config_file() + subprocess.run(["docker", "rm", "-f", "consul", "db", "manager", "wrapper", "interface", "authz*", "keystone"]) + start_consul(data_config) + start_database() + start_keystone() + start_moon(data_config) + +main() + diff --git a/bin/build_all.sh b/bin/build_all.sh new file mode 100644 index 00000000..5bbf6a19 --- /dev/null +++ b/bin/build_all.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +VERSION=v4.1 +export DOCKER_HOST=tcp://172.88.88.1:2376 + + +mkdir $MOON_HOME/moon_orchestrator/dist 2>/dev/null + +echo Building Moon_Orchestrator +cd $MOON_HOME/moon_orchestrator +docker build -t wukongsun/moon_orchestrator:${VERSION} . + +echo Building Moon_Interface +cd $MOON_HOME/moon_interface +docker build -t wukongsun/moon_interface:${VERSION} . + +echo Building Moon_Security_Router +cd $MOON_HOME/moon_secrouter +docker build -t wukongsun/moon_router:${VERSION} . + +echo Building Moon_Manager +cd $MOON_HOME/moon_manager +docker build -t wukongsun/moon_manager:${VERSION} . + +echo Building Moon_Authz +cd $MOON_HOME/moon_authz +docker build -t wukongsun/moon_authz:${VERSION} . + + +echo Building Moon_DB +cd $MOON_HOME/moon_db +python3 setup.py sdist bdist_wheel > /tmp/moon_db.log + +echo Building Moon_Utilities +cd $MOON_HOME/moon_utilities +python3 setup.py sdist bdist_wheel > /tmp/moon_utilities.log diff --git a/bin/build_all_pip.sh b/bin/build_all_pip.sh new file mode 100644 index 00000000..2b415bf0 --- /dev/null +++ b/bin/build_all_pip.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + + +echo Building Moon_DB +cd $MOON_HOME/moon_db +python3 setup.py sdist bdist_wheel> /tmp/moon_db.log + + +echo Building Moon_Utilities +cd $MOON_HOME/moon_utilities +python3 setup.py sdist bdist_wheel> /tmp/moon_utilities.log + + +echo Building Moon_Orchestrator +cd $MOON_HOME/moon_orchestrator +python3 setup.py sdist bdist_wheel> /tmp/moon_orchestrator.log \ No newline at end of file diff --git a/bin/delete_orchestrator.sh b/bin/delete_orchestrator.sh new file mode 100644 index 00000000..95fcfddd --- /dev/null +++ b/bin/delete_orchestrator.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +set +x + +kubectl delete -n moon -f kubernetes/templates/moon_orchestrator.yaml +for i in $(kubectl get deployments -n moon | grep wrapper | cut -d " " -f 1 | xargs); do + kubectl delete deployments/$i -n moon; +done +for i in $(kubectl get deployments -n moon | grep interface | cut -d " " -f 1 | xargs); do + kubectl delete deployments/$i -n moon; +done +for i in $(kubectl get deployments -n moon | grep authz | cut -d " " -f 1 | xargs); do + kubectl delete deployments/$i -n moon; +done +for i in $(kubectl get services -n moon | grep wrapper | cut -d " " -f 1 | xargs); do + kubectl delete services/$i -n moon; +done +for i in $(kubectl get services -n moon | grep interface | cut -d " " -f 1 | xargs); do + kubectl delete services/$i -n moon; +done +for i in $(kubectl get services -n moon | grep authz | cut -d " " -f 1 | xargs); do + kubectl delete services/$i -n moon; +done + +if [ "$1" = "build" ]; then + + DOCKER_ARGS="" + + cd moon_manager + docker build -t wukongsun/moon_manager:v4.3.1 . ${DOCKER_ARGS} + if [ "$2" = "push" ]; then + docker push wukongsun/moon_manager:v4.3.1 + fi + cd - + + cd moon_orchestrator + docker build -t wukongsun/moon_orchestrator:v4.3 . ${DOCKER_ARGS} + if [ "$2" = "push" ]; then + docker push wukongsun/moon_orchestrator:v4.3 + fi + cd - + + cd moon_interface + docker build -t wukongsun/moon_interface:v4.3 . ${DOCKER_ARGS} + if [ "$2" = "push" ]; then + docker push wukongsun/moon_interface:v4.3 + fi + cd - + + cd moon_authz + docker build -t wukongsun/moon_authz:v4.3 . ${DOCKER_ARGS} + if [ "$2" = "push" ]; then + docker push wukongsun/moon_authz:v4.3 + fi + cd - + + cd moon_wrapper + docker build -t wukongsun/moon_wrapper:v4.3 . ${DOCKER_ARGS} + if [ "$2" = "push" ]; then + docker push wukongsun/moon_wrapper:v4.3 + fi + cd - +fi diff --git a/bin/moon_lib_update.sh b/bin/moon_lib_update.sh new file mode 100644 index 00000000..3925e336 --- /dev/null +++ b/bin/moon_lib_update.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +# usage: moon_update.sh {build,upload,copy} {python_moondb,python_moonutilities} + +CMD=$1 +COMPONENT=$2 +GPG_ID=$3 + +VERSION=${COMPONENT}-$(grep __version__ ${COMPONENT}/${COMPONENT}/__init__.py | cut -d "\"" -f 2) + +cd ${COMPONENT} + +python3 setup.py sdist bdist_wheel + +if [ "$CMD" = "upload" ]; then + # Instead of "A0A96E75", use your own GPG ID + rm dist/*.asc 2>/dev/null + gpg --detach-sign -u "${GPG_ID}" -a dist/${VERSION}-py3-none-any.whl + gpg --detach-sign -u "${GPG_ID}" -a dist/${VERSION/_/-}.tar.gz + twine upload dist/${VERSION}-py3-none-any.whl dist/${VERSION}-py3-none-any.whl.asc + twine upload dist/${VERSION/_/-}.tar.gz dist/${VERSION/_/-}.tar.gz.asc +fi + +rm -f ../moon_manager/dist/${COMPONENT}* +rm -f ../moon_orchestrator/dist/${COMPONENT}* +rm -f ../moon_wrapper/dist/${COMPONENT}* +rm -f ../moon_interface/dist/${COMPONENT}* +rm -f ../moon_authz/dist/${COMPONENT}* + + +if [ "$CMD" = "copy" ]; then + mkdir -p ../moon_manager/dist/ 2>/dev/null + cp -v dist/${VERSION}-py3-none-any.whl ../moon_manager/dist/ + mkdir -p ../moon_orchestrator/dist/ 2>/dev/null + cp -v dist/${VERSION}-py3-none-any.whl ../moon_orchestrator/dist/ + mkdir -p ../moon_wrapper/dist/ 2>/dev/null + cp -v dist/${VERSION}-py3-none-any.whl ../moon_wrapper/dist/ + mkdir -p ../moon_interface/dist/ 2>/dev/null + cp -v dist/${VERSION}-py3-none-any.whl ../moon_interface/dist/ + mkdir -p ../moon_authz/dist/ 2>/dev/null + cp -v dist/${VERSION}-py3-none-any.whl ../moon_authz/dist/ +fi + diff --git a/bin/set_auth.src b/bin/set_auth.src new file mode 100644 index 00000000..d955e30b --- /dev/null +++ b/bin/set_auth.src @@ -0,0 +1,7 @@ +export OS_USERNAME=admin +export OS_PASSWORD=p4ssw0rd +export OS_REGION_NAME=Orange +export OS_TENANT_NAME=admin +export OS_AUTH_URL=http://keystone:5000/v3 +export OS_DOMAIN_NAME=Default +export MOON_URL=http://172.18.0.11:38001 diff --git a/bin/start.sh b/bin/start.sh new file mode 100755 index 00000000..e95ac393 --- /dev/null +++ b/bin/start.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +VERSION=4.1 +export DOCKER_HOST=tcp://172.88.88.1:2376 + +echo -e "\033[31mDeleting previous dockers\033[m" +docker rm -f $(docker ps -a | grep moon | cut -d " " -f 1) 2>/dev/null +docker rm -f messenger db keystone consul 2>/dev/null + +echo -e "\033[32mStarting Messenger\033[m" +docker run -dti --net=moon --hostname messenger --name messenger -e RABBITMQ_DEFAULT_USER=moon -e RABBITMQ_DEFAULT_PASS=p4sswOrd1 -e RABBITMQ_NODENAME=rabbit@messenger -e RABBITMQ_DEFAULT_VHOST=moon -e RABBITMQ_HIPE_COMPILE=1 -p 5671:5671 -p 5672:5672 -p 8080:15672 rabbitmq:3-management + +echo -e "\033[32mStarting DB manager\033[m" +docker run -dti --net=moon --hostname db --name db -e MYSQL_ROOT_PASSWORD=p4sswOrd1 -e MYSQL_DATABASE=moon -e MYSQL_USER=moon -e MYSQL_PASSWORD=p4sswOrd1 -p 3306:3306 mysql:latest + +docker run -d --net=moon --name=consul --hostname=consul -p 8500:8500 consul + +echo "waiting for Database (it may takes time)..." +echo -e "\033[35m" +sed '/ready for connections/q' <(docker logs db -f) +echo -e "\033[m" + +echo "waiting for Messenger (it may takes time)..." +echo -e "\033[35m" +sed '/Server startup complete;/q' <(docker logs messenger -f) +echo -e "\033[m" + +docker run -dti --net moon --hostname keystone --name keystone -e DB_HOST=db -e DB_PASSWORD_ROOT=p4sswOrd1 -p 35357:35357 -p 5000:5000 keystone:mitaka + +echo -e "\033[32mConfiguring Moon platform\033[m" +sudo pip install moon_db +moon_db_manager upgrade + +cd ${MOON_HOME}/moon_orchestrator +python3 populate_consul.py + +echo -e "\033[32mStarting Moon platform\033[m" + +docker container run -dti --net moon --hostname orchestrator --name orchestrator wukongsun/moon_orchestrator:${VERSION} diff --git a/conf/moon.conf b/conf/moon.conf new file mode 100644 index 00000000..a5a40ad2 --- /dev/null +++ b/conf/moon.conf @@ -0,0 +1,87 @@ +database: + url: mysql+pymysql://moon:p4sswOrd1@db/moon + driver: sql + +openstack: + keystone: + url: http://keystone:5000/v3 + user: admin + password: p4ssw0rd + domain: default + project: admin + check_token: false + certificate: false + external: + url: http://keystone:30006/v3 + +plugins: + authz: + container: wukongsun/moon_authz:v4.3 + port: 8081 + session: + container: asteroide/session:latest + port: 8082 + +components: + interface: + port: 8080 + bind: 0.0.0.0 + hostname: interface + container: wukongsun/moon_interface:v4.3 + orchestrator: + port: 8083 + bind: 0.0.0.0 + hostname: orchestrator + container: wukongsun/moon_orchestrator:v4.3 + external: + port: 30003 + hostname: orchestrator + wrapper: + port: 8080 + bind: 0.0.0.0 + hostname: wrapper + container: wukongsun/moon_wrapper:v4.3.1 + timeout: 5 + manager: + port: 8082 + bind: 0.0.0.0 + hostname: manager + container: wukongsun/moon_manager:v4.3.1 + external: + port: 30001 + hostname: manager + port_start: 31001 + +logging: + version: 1 + + formatters: + brief: + format: "%(levelname)s %(name)s %(message)-30s" + custom: + format: "%(asctime)-15s %(levelname)s %(name)s %(message)s" + + handlers: + console: + class : logging.StreamHandler + formatter: brief + level : INFO + stream : ext://sys.stdout + file: + class : logging.handlers.RotatingFileHandler + formatter: custom + level : DEBUG + filename: /tmp/moon.log + maxBytes: 1048576 + backupCount: 3 + + loggers: + moon: + level: DEBUG + handlers: [console, file] + propagate: no + + root: + level: ERROR + handlers: [console] + diff --git a/keystonemiddleware-moon/.coveragerc b/keystonemiddleware-moon/.coveragerc deleted file mode 100644 index 75b0fcb0..00000000 --- a/keystonemiddleware-moon/.coveragerc +++ /dev/null @@ -1,7 +0,0 @@ -[run] -branch = True -source = keystonemiddleware -omit = keystonemiddleware/tests/*,keystonemiddleware/openstack/* - -[report] -ignore-errors = True diff --git a/keystonemiddleware-moon/.gitignore b/keystonemiddleware-moon/.gitignore deleted file mode 100644 index bd6a3658..00000000 --- a/keystonemiddleware-moon/.gitignore +++ /dev/null @@ -1,55 +0,0 @@ -*.py[cod] - -# C extensions -*.so - -# Packages -*.egg -*.egg-info -dist -build -eggs -parts -bin -var -sdist -develop-eggs -.installed.cfg -lib -lib64 - -# Installer logs -pip-log.txt - -# Unit test / coverage reports -.coverage -.tox -nosetests.xml -.testrepository -cover - -# Translations -*.mo - -# Mr Developer -.mr.developer.cfg -.project -.pydevproject - -# Complexity -output/*.html -output/*/index.html - -# Sphinx -doc/build - -# pbr generates these -AUTHORS -ChangeLog - -# Editors -*~ -.*.swp - -# Oslo Sync -.update-venv diff --git a/keystonemiddleware-moon/.gitreview b/keystonemiddleware-moon/.gitreview deleted file mode 100644 index 99b3a27f..00000000 --- a/keystonemiddleware-moon/.gitreview +++ /dev/null @@ -1,4 +0,0 @@ -[gerrit] -host=review.openstack.org -port=29418 -project=openstack/keystonemiddleware.git diff --git a/keystonemiddleware-moon/.testr.conf b/keystonemiddleware-moon/.testr.conf deleted file mode 100644 index 06f67a02..00000000 --- a/keystonemiddleware-moon/.testr.conf +++ /dev/null @@ -1,8 +0,0 @@ -[DEFAULT] -test_command= - OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \ - OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \ - OS_LOG_CAPTURE=${OS_LOG_CAPTURE:-1} \ - ${PYTHON:-python} -m subunit.run discover -t ./ ./keystonemiddleware/tests $LISTOPT $IDOPTION -test_id_option=--load-list $IDFILE -test_list_option=--list diff --git a/keystonemiddleware-moon/CONTRIBUTING.rst b/keystonemiddleware-moon/CONTRIBUTING.rst deleted file mode 100644 index ba308f23..00000000 --- a/keystonemiddleware-moon/CONTRIBUTING.rst +++ /dev/null @@ -1,16 +0,0 @@ -If you would like to contribute to the development of OpenStack, -you must follow the steps in this page: - - http://docs.openstack.org/infra/manual/developers.html - -Once those steps have been completed, changes to OpenStack -should be submitted for review via the Gerrit tool, following -the workflow documented at: - - http://docs.openstack.org/infra/manual/developers.html#development-workflow - -Pull requests submitted through GitHub will be ignored. - -Bugs should be filed on Launchpad, not GitHub: - - https://bugs.launchpad.net/keystonemiddleware diff --git a/keystonemiddleware-moon/HACKING.rst b/keystonemiddleware-moon/HACKING.rst deleted file mode 100644 index 77de6b32..00000000 --- a/keystonemiddleware-moon/HACKING.rst +++ /dev/null @@ -1,24 +0,0 @@ -Keystone Style Commandments -=========================== - -- Step 1: Read the OpenStack Style Commandments - http://docs.openstack.org/developer/hacking/ -- Step 2: Read on - -Exceptions ----------- - -When dealing with exceptions from underlying libraries, translate those -exceptions to an instance or subclass of ClientException. - -======= -Testing -======= - -Keystone Middleware uses testtools and testr for its unittest suite -and its test runner. Basic workflow around our use of tox and testr can -be found at http://wiki.openstack.org/testr. If you'd like to learn more -in depth: - - https://testtools.readthedocs.org/ - https://testrepository.readthedocs.org/ diff --git a/keystonemiddleware-moon/LICENSE b/keystonemiddleware-moon/LICENSE deleted file mode 100644 index 4a5b9421..00000000 --- a/keystonemiddleware-moon/LICENSE +++ /dev/null @@ -1,210 +0,0 @@ -Copyright (c) 2009 Jacob Kaplan-Moss - initial codebase (< v2.1) -Copyright (c) 2011 Rackspace - OpenStack extensions (>= v2.1) -Copyright (c) 2011 Nebula, Inc - Keystone refactor (>= v2.7) -Copyright (c) 2017 Orange - Moon platform (>= v3.0) -All rights reserved. - - - 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. - ---- License for python-keystoneclient versions prior to 2.1 --- - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of this project nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/keystonemiddleware-moon/MANIFEST.in b/keystonemiddleware-moon/MANIFEST.in deleted file mode 100644 index 29c06765..00000000 --- a/keystonemiddleware-moon/MANIFEST.in +++ /dev/null @@ -1,7 +0,0 @@ -include README.rst -include AUTHORS HACKING LICENSE -include ChangeLog -include run_tests.sh tox.ini -recursive-include doc * -recursive-include tests * -recursive-include tools * diff --git a/keystonemiddleware-moon/README.rst b/keystonemiddleware-moon/README.rst deleted file mode 100644 index fcbdbdde..00000000 --- a/keystonemiddleware-moon/README.rst +++ /dev/null @@ -1,19 +0,0 @@ -Middleware for the OpenStack Identity API (Keystone) -==================================================== - -This package contains middleware modules designed to provide authentication and -authorization features to web services other than `Keystone -`. The most prominent module is -``keystonemiddleware.auth_token``. This package does not expose any CLI or -Python API features. - -For information on contributing, see ``CONTRIBUTING.rst``. - -* License: Apache License, Version 2.0 -* Documentation: http://docs.openstack.org/developer/keystonemiddleware -* Source: http://git.openstack.org/cgit/openstack/keystonemiddleware -* Bugs: http://bugs.launchpad.net/keystonemiddleware - -For any other information, refer to the parent project, Keystone: - - https://github.com/openstack/keystone diff --git a/keystonemiddleware-moon/babel.cfg b/keystonemiddleware-moon/babel.cfg deleted file mode 100644 index 79cd39bf..00000000 --- a/keystonemiddleware-moon/babel.cfg +++ /dev/null @@ -1,3 +0,0 @@ -[python: **.py] - - diff --git a/keystonemiddleware-moon/bandit.yaml b/keystonemiddleware-moon/bandit.yaml deleted file mode 100644 index d4e7dbca..00000000 --- a/keystonemiddleware-moon/bandit.yaml +++ /dev/null @@ -1,134 +0,0 @@ -# optional: after how many files to update progress -#show_progress_every: 100 - -# optional: plugins directory name -#plugins_dir: 'plugins' - -# optional: plugins discovery name pattern -plugin_name_pattern: '*.py' - -# optional: terminal escape sequences to display colors -#output_colors: -# DEFAULT: '\033[0m' -# HEADER: '\033[95m' -# INFO: '\033[94m' -# WARN: '\033[93m' -# ERROR: '\033[91m' - -# optional: log format string -#log_format: "[%(module)s]\t%(levelname)s\t%(message)s" - -# globs of files which should be analyzed -include: - - '*.py' - - '*.pyw' - -# a list of strings, which if found in the path will cause files to be excluded -# for example /tests/ - to remove all all files in tests directory -exclude_dirs: - - '/tests/' - -profiles: - keystone_conservative: - include: - - blacklist_functions - - blacklist_imports - - request_with_no_cert_validation - - exec_used - - set_bad_file_permissions - - subprocess_popen_with_shell_equals_true - - linux_commands_wildcard_injection - - ssl_with_bad_version - - - keystone_verbose: - include: - - blacklist_functions - - blacklist_imports - - request_with_no_cert_validation - - exec_used - - set_bad_file_permissions - - hardcoded_tmp_directory - - subprocess_popen_with_shell_equals_true - - any_other_function_with_shell_equals_true - - linux_commands_wildcard_injection - - ssl_with_bad_version - - ssl_with_bad_defaults - -blacklist_functions: - bad_name_sets: - - pickle: - qualnames: [pickle.loads, pickle.load, pickle.Unpickler, - cPickle.loads, cPickle.load, cPickle.Unpickler] - message: "Pickle library appears to be in use, possible security issue." - - marshal: - qualnames: [marshal.load, marshal.loads] - message: "Deserialization with the marshal module is possibly dangerous." - - md5: - qualnames: [hashlib.md5] - message: "Use of insecure MD5 hash function." - - mktemp_q: - qualnames: [tempfile.mktemp] - message: "Use of insecure and deprecated function (mktemp)." - - eval: - qualnames: [eval] - message: "Use of possibly insecure function - consider using safer ast.literal_eval." - - mark_safe: - names: [mark_safe] - message: "Use of mark_safe() may expose cross-site scripting vulnerabilities and should be reviewed." - - httpsconnection: - qualnames: [httplib.HTTPSConnection] - message: "Use of HTTPSConnection does not provide security, see https://wiki.openstack.org/wiki/OSSN/OSSN-0033" - - yaml_load: - qualnames: [yaml.load] - message: "Use of unsafe yaml load. Allows instantiation of arbitrary objects. Consider yaml.safe_load()." - - urllib_urlopen: - qualnames: [urllib.urlopen, urllib.urlretrieve, urllib.URLopener, urllib.FancyURLopener, urllib2.urlopen, urllib2.Request] - message: "Audit url open for permitted schemes. Allowing use of file:/ or custom schemes is often unexpected." - -shell_injection: - # Start a process using the subprocess module, or one of its wrappers. - subprocess: [subprocess.Popen, subprocess.call, subprocess.check_call, - subprocess.check_output, utils.execute, utils.execute_with_timeout] - # Start a process with a function vulnerable to shell injection. - shell: [os.system, os.popen, os.popen2, os.popen3, os.popen4, - popen2.popen2, popen2.popen3, popen2.popen4, popen2.Popen3, - popen2.Popen4, commands.getoutput, commands.getstatusoutput] - # Start a process with a function that is not vulnerable to shell injection. - no_shell: [os.execl, os.execle, os.execlp, os.execlpe, os.execv,os.execve, - os.execvp, os.execvpe, os.spawnl, os.spawnle, os.spawnlp, - os.spawnlpe, os.spawnv, os.spawnve, os.spawnvp, os.spawnvpe, - os.startfile] - -blacklist_imports: - bad_import_sets: - - telnet: - imports: [telnetlib] - level: ERROR - message: "Telnet is considered insecure. Use SSH or some other encrypted protocol." - -hardcoded_password: - word_list: "wordlist/default-passwords" - -ssl_with_bad_version: - bad_protocol_versions: - - 'PROTOCOL_SSLv2' - - 'SSLv2_METHOD' - - 'SSLv23_METHOD' - - 'PROTOCOL_SSLv3' # strict option - - 'PROTOCOL_TLSv1' # strict option - - 'SSLv3_METHOD' # strict option - - 'TLSv1_METHOD' # strict option - -password_config_option_not_marked_secret: - function_names: - - oslo.config.cfg.StrOpt - - oslo_config.cfg.StrOpt - -execute_with_run_as_root_equals_true: - function_names: - - ceilometer.utils.execute - - cinder.utils.execute - - neutron.agent.linux.utils.execute - - nova.utils.execute - - nova.utils.trycmd diff --git a/keystonemiddleware-moon/debian/changelog b/keystonemiddleware-moon/debian/changelog deleted file mode 100644 index ffc44169..00000000 --- a/keystonemiddleware-moon/debian/changelog +++ /dev/null @@ -1,121 +0,0 @@ -python-keystonemiddleware (4.4.0-4) UNRELEASED; urgency=medium - - * Standards-Version is 3.9.8 now (no change) - * d/rules: Changed UPSTREAM_GIT protocol to https - * d/copyright: Changed source URL to https protocol - - -- Ondřej Nový Sat, 09 Apr 2016 19:27:43 +0200 - -python-keystonemiddleware (4.4.0-3) unstable; urgency=medium - - * Re-add missing auth options in oslo-config-generator: - - Add re-add-missing-auth-options.patch - - Disable now failing unit tests. - - -- Thomas Goirand Wed, 06 Apr 2016 22:16:03 +0000 - -python-keystonemiddleware (4.4.0-2) unstable; urgency=medium - - * Added git as build-depends-indep. - - -- Thomas Goirand Mon, 04 Apr 2016 11:22:51 +0000 - -python-keystonemiddleware (4.4.0-1) unstable; urgency=medium - - [ Ondřej Nový ] - * Fixed homepage (https). - * Fixed VCS URLs (https). - - [ Thomas Goirand ] - * New upstream release. - * Uploading to unstable. - * Fixed (build-)depends for this release. - * Standards-Version: 3.9.7 (no change). - - -- Thomas Goirand Mon, 04 Apr 2016 12:21:37 +0200 - -python-keystonemiddleware (4.0.0-1) experimental; urgency=medium - - * New upstream release. - * Fixed (build-)depends for this release. - * Also test with Python 3. - * Fixed debian/copyright ordering. - - -- Thomas Goirand Thu, 10 Dec 2015 16:29:42 +0100 - -python-keystonemiddleware (3.0.0-1) experimental; urgency=medium - - * New upstream release. - * Fixed (build-)depends for this release. - - -- Thomas Goirand Fri, 04 Dec 2015 11:02:00 +0100 - -python-keystonemiddleware (2.3.0-3) unstable; urgency=medium - - * Uploading to unstable. - - -- Thomas Goirand Fri, 16 Oct 2015 10:04:17 +0000 - -python-keystonemiddleware (2.3.0-2) experimental; urgency=medium - - * Added Python 3 support. - - -- Thomas Goirand Sat, 03 Oct 2015 19:48:25 +0200 - -python-keystonemiddleware (2.3.0-1) experimental; urgency=medium - - * New upstream release. - * Align dependencies with upstream. - * d/control: Update uploaders. - - -- Corey Bryant Wed, 30 Sep 2015 14:42:41 -0400 - -python-keystonemiddleware (2.1.0-2) experimental; urgency=medium - - * Removed python-bandit build-depends. - - -- Thomas Goirand Thu, 30 Jul 2015 20:50:50 +0000 - -python-keystonemiddleware (2.1.0-1) experimental; urgency=medium - - * New upstream release. - * Fixed (build-)depends for this release. - * Fixed watch file. - - -- Thomas Goirand Thu, 30 Jul 2015 07:38:14 +0000 - -python-keystonemiddleware (1.5.0-2) unstable; urgency=high - - * CVE-2015-1852: S3Token TLS cert verification option not honored. Applied - upstream patch. - - -- Thomas Goirand Wed, 17 Jun 2015 08:28:00 +0000 - -python-keystonemiddleware (1.5.0-1) unstable; urgency=medium - - * New upstream release. - * Fixed (build-)depends for this release. - * Removed nature.css from debian/copyright (and it's BSD licence). - - -- Thomas Goirand Wed, 08 Apr 2015 10:08:46 +0200 - -python-keystonemiddleware (1.0.0-3) unstable; urgency=medium - - * Added CVE-2014-7144_convert_the_conf_value_into_correct_type.patch. Thanks - to Luciano Bello for the report (Closes: #762748). - - -- Thomas Goirand Thu, 25 Sep 2014 07:16:29 +0000 - -python-keystonemiddleware (1.0.0-2) unstable; urgency=medium - - * Do not attempt to run unit tests in Python 2.6, as it needs the discover - package, which we don't want as build-depends. - * Removes intersphinx plugin from docs build. - - -- Thomas Goirand Mon, 28 Jul 2014 00:29:44 +0800 - -python-keystonemiddleware (1.0.0-1) unstable; urgency=medium - - * Initial release. (Closes: #755135) - - -- Thomas Goirand Tue, 08 Jul 2014 14:25:47 +0800 diff --git a/keystonemiddleware-moon/debian/compat b/keystonemiddleware-moon/debian/compat deleted file mode 100644 index ec635144..00000000 --- a/keystonemiddleware-moon/debian/compat +++ /dev/null @@ -1 +0,0 @@ -9 diff --git a/keystonemiddleware-moon/debian/control b/keystonemiddleware-moon/debian/control deleted file mode 100644 index a6dd5eab..00000000 --- a/keystonemiddleware-moon/debian/control +++ /dev/null @@ -1,136 +0,0 @@ -Source: python-keystonemiddleware -Section: python -Priority: optional -Maintainer: PKG OpenStack -Uploaders: Thomas Goirand , - Corey Bryant , -Build-Depends: debhelper (>= 9), - dh-python, - openstack-pkg-tools, - python-all, - python-pbr (>= 1.8), - python-setuptools, - python-sphinx, - python3-all, - python3-pbr (>= 1.8), - python3-setuptools, -Build-Depends-Indep: git, - python-bandit, - python-coverage, - python-crypto, - python-fixtures (>= 1.3.1), - python-hacking, - python-keystoneauth1 (>= 2.1.0), - python-keystoneclient (>= 1:1.6.0), - python-memcache (>= 1.56), - python-mock (>= 1.2), - python-oslo.config (>= 1:3.7.0), - python-oslo.context (>= 0.2.0), - python-oslo.i18n (>= 2.1.0), - python-oslo.messaging (>= 4.0.0), - python-oslo.serialization (>= 1.10.0), - python-oslo.utils (>= 3.5.0), - python-oslosphinx (>= 2.5.0), - python-oslotest (>= 1.10.0), - python-positional (>= 1.0.1), - python-pycadf (>= 1.1.0), - python-requests (>= 2.8.1), - python-requests-mock (>= 0.7.0), - python-six (>= 1.9.0), - python-stevedore (>= 1.5.0), - python-testresources, - python-testtools (>= 1.4.0), - python-webob, - python3-bandit, - python3-crypto, - python3-fixtures (>= 1.3.1), - python3-keystoneauth1 (>= 2.1.0), - python3-keystoneclient (>= 1:1.6.0), - python3-memcache (>= 1.56), - python3-mock (>= 1.2), - python3-oslo.config (>= 1:3.7.0), - python3-oslo.context (>= 0.2.0), - python3-oslo.i18n (>= 2.1.0), - python3-oslo.messaging (>= 4.0.0), - python3-oslo.serialization (>= 1.10.0), - python3-oslo.utils (>= 3.5.0), - python3-oslotest (>= 1.10.0), - python3-positional (>= 1.0.1), - python3-pycadf (>= 1.1.0), - python3-requests (>= 2.8.1), - python3-requests-mock (>= 0.7.0), - python3-six (>= 1.9.0), - python3-stevedore (>= 1.5.0), - python3-subunit, - python3-testresources, - python3-testtools (>= 1.4.0), - python3-webob, - subunit, - testrepository, -Standards-Version: 3.9.8 -Vcs-Browser: https://anonscm.debian.org/cgit/openstack/python-keystonemiddleware.git/ -Vcs-Git: https://anonscm.debian.org/git/openstack/python-keystonemiddleware.git -Homepage: https://launchpad.net/keystonemiddleware - -Package: python-keystonemiddleware -Architecture: all -Depends: python-keystoneauth1 (>= 2.1.0), - python-keystoneclient (>= 1:1.6.0), - python-oslo.config (>= 1:3.7.0), - python-oslo.context (>= 0.2.0), - python-oslo.i18n (>= 2.1.0), - python-oslo.serialization (>= 1.10.0), - python-oslo.utils (>= 3.5.0), - python-pbr (>= 1.8), - python-positional (>= 1.0.1), - python-pycadf (>= 1.1.0), - python-requests (>= 2.8.1), - python-six (>= 1.9.0), - python-webob, - ${misc:Depends}, - ${python:Depends}, -Description: Middleware for OpenStack Identity (Keystone) - Python 2.x - This package contains middleware modules designed to provide authentication - and authorization features to web services other than Keystone. The most - prominent module is keystonemiddleware.auth_token. This package does not - expose any CLI or Python API features. - . - This package contains the Python 2.x module. - -Package: python3-keystonemiddleware -Architecture: all -Depends: python3-keystoneauth1 (>= 2.1.0), - python3-keystoneclient (>= 1:1.6.0), - python3-oslo.config (>= 1:3.7.0), - python3-oslo.context (>= 0.2.0), - python3-oslo.i18n (>= 2.1.0), - python3-oslo.serialization (>= 1.10.0), - python3-oslo.utils (>= 3.5.0), - python3-pbr (>= 1.8), - python3-positional (>= 1.0.1), - python3-pycadf (>= 1.1.0), - python3-requests (>= 2.8.1), - python3-six (>= 1.9.0), - python3-webob, - ${misc:Depends}, - ${python3:Depends}, -Description: Middleware for OpenStack Identity (Keystone) - Python 3.x - This package contains middleware modules designed to provide authentication - and authorization features to web services other than Keystone. The most - prominent module is keystonemiddleware.auth_token. This package does not - expose any CLI or Python API features. - . - This package contains the Python 3.x module. - -Package: python-keystonemiddleware-doc -Section: doc -Architecture: all -Depends: ${misc:Depends}, - ${sphinxdoc:Depends}, -Description: Middleware for OpenStack Identity (Keystone) - doc - This package contains middleware modules designed to provide authentication - and authorization features to web services other than Keystone. The most - prominent module is keystonemiddleware.auth_token. This package does not - expose any CLI or Python API features. - . - This package contains the documentation. diff --git a/keystonemiddleware-moon/debian/copyright b/keystonemiddleware-moon/debian/copyright deleted file mode 100644 index cae54f2a..00000000 --- a/keystonemiddleware-moon/debian/copyright +++ /dev/null @@ -1,27 +0,0 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: keystonemiddleware -Source: https://launchpad.net/keystonemiddleware - -Files: * -Copyright: (c) 2013-2016, OpenStack Foundation -License: Apache-2 - -Files: debian/* -Copyright: (c) 2014-2016, Thomas Goirand -License: Apache-2 - -License: Apache-2 - 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. - . - On Debian-based systems the full text of the Apache version 2.0 license - can be found in /usr/share/common-licenses/Apache-2.0. diff --git a/keystonemiddleware-moon/debian/create_deb.py b/keystonemiddleware-moon/debian/create_deb.py deleted file mode 100644 index 03d6b790..00000000 --- a/keystonemiddleware-moon/debian/create_deb.py +++ /dev/null @@ -1,196 +0,0 @@ -#!/usr/bin/env python3.5 - -import os -import sys -import subprocess -import glob -import argparse - - -parser = argparse.ArgumentParser() -parser.add_argument('--src', help='Do not clone Moon repository, use SRC as source directory', dest="src") -args = parser.parse_args() - - -TMP_DIR = "/tmp/debian-moon" -MOON_DIR = os.path.join(TMP_DIR, "moon") -INIT_dir = os.path.split(os.path.abspath(sys.argv[0]))[0] - -print("init dir: {}".format(INIT_dir)) - -_run = subprocess.run(["mkdir", "-p", TMP_DIR]) -if _run.returncode != 0: - exit("\033[31mCannot create tmp dir\033[m") - -os.chdir(TMP_DIR) - -_run = subprocess.run(["sudo", "apt-get", "install", "-y", "git"]) -if _run.returncode != 0: - exit("\033[31mCannot install Git\033[m") - -# print("\033[32mCloning Debian version\033[m") -# _run = subprocess.run(["git", "clone", "https://anonscm.debian.org/git/openstack/python-keystonemiddleware.git"]) -# if _run.returncode != 0: -# os.chdir(os.path.join(TMP_DIR, "python-keystonemiddleware")) -# _run = subprocess.run(["git", "pull"]) -# if _run.returncode != 0: -# print("\033[31mCannot clone ou pull debian version\033[m") - -os.chdir(TMP_DIR) - -if args.src: - print("\033[32mUsing {} as source directory\033[m".format(args.src)) - MOON_DIR = args.src -else: - print("\033[32mCloning Moon project\033[m") - _run = subprocess.run(["git", "clone", "https://git.opnfv.org/moon"]) - if _run.returncode != 0: - os.chdir(os.path.join(TMP_DIR, "moon")) - _run = subprocess.run(["git", "pull"]) - if _run.returncode != 0: - print("\033[31mCannot clone Moon project\033[m") - -os.chdir(TMP_DIR) - -# src_path = os.path.join(TMP_DIR, "python-keystonemiddleware", "debian") -# dst_path = os.path.join(TMP_DIR, "moon", "keystonemiddleware-moon") -# print("\033[32mCopying from {} to {}\033[m".format(src_path, dst_path)) -# _run = subprocess.run(["cp", -# "-rv", -# src_path, -# dst_path]) - -print("\033[32mBuilding Moon project\033[m") -os.chdir(os.path.join(MOON_DIR, "keystonemiddleware-moon")) - -mandatory_deb_pkg = """dh-apparmor -dh-systemd -openstack-pkg-tools -python-all python-pbr -python-sphinx -python-bashate -python-keystonemiddleware -python-ldap -python-ldappool -python-memcache -python-migrate -python-mock -python-msgpack -python-oslo.cache -python-oslo.concurrency -python-oslo.config -python-oslo.context -python-oslo.db -python-oslo.i18n -python-oslo.log -python-oslo.messaging -python-oslo.policy -python-oslo.serialization -python-oslo.service -python-oslo.utils -python-oslosphinx -python-oslotest -python-os-testr -python-passlib -python-paste -python-pastedeploy -python-pycadf -python-pymongo -python-pysaml2 -python-pysqlite2 -python-routes -python-sqlalchemy -python-stevedore -python-testscenarios -python-testtools -python-unittest2 -python-webob -python-webtest -subunit -testrepository -python-coverage -python-dogpile.cache -python-eventlet -python-hacking -python-oslo.cache -python-oslo.concurrency -python-oslo.config -python-oslo.db -python-oslo.log -python-oslo.messaging -python-oslo.middleware -python-tempest-lib -python-oauthlib -python-pam -python3-all -python3-setuptools -python-bandit -python-requests-mock -python-testresources -python3-bandit -python3-crypto -python3-keystoneauth1 -python3-keystoneclient -python3-memcache -python3-mock -python3-oslo.config -python3-oslo.context -python3-oslo.i18n -python3-oslo.messaging -python3-oslo.serialization -python3-oslo.utils -python3-oslotest -python3-positional -python3-pycadf -python3-requests-mock -python3-stevedore -python3-testresources -python3-webob -""" - -_command = ["sudo", "apt-get", "install", "-y"] -_command.extend(mandatory_deb_pkg.split()) -_run = subprocess.run(_command) - -print("\033[32mremove a Debian patch as it inserts a bug in Moon\033[m") -series_filename = os.path.join(MOON_DIR, "keystonemiddleware-moon", - "debian", "patches", "series") -series_lines = open(series_filename).readlines() - -output = open(series_filename, "w") -for line in series_lines: - if "re-add-missing-auth-options.patch" not in line: - output.write(line) - output.write("\n") -output.close() -os.remove(os.path.join(MOON_DIR, "keystonemiddleware-moon", - "debian", "patches", "re-add-missing-auth-options.patch")) - -os.putenv("DEB_BUILD_OPTIONS", "nocheck") - -changelog = open(os.path.join(MOON_DIR, "keystonemiddleware-moon", "debian", "changelog"), "rt") -changelog_str = changelog.read() -# print(changelog_str.splitlines()[0]) -current_version = changelog_str.splitlines()[0].split("(")[1].split(")")[0] -changelog.close() -changelog = open(os.path.join(MOON_DIR, "keystonemiddleware-moon", "debian", "changelog"), "wt") -changelog.write("""python-keystonemiddleware ({version}) UNRELEASED; urgency=medium - - * integration of the Moon platform. - - -- Thomas Duval {date} - -""".format( - version=current_version+"-moon", - date=subprocess.Popen(["date"], stdin=None, stdout=subprocess.PIPE).communicate()[0].decode("utf-8").strip())) -changelog.write(changelog_str) -changelog.close() - -_run = subprocess.run(["dpkg-buildpackage", "-b", "-us"]) - -print("\033[32mResults:\033[m") -subprocess.run(["mkdir", "-p", "/tmp/deb"]) - -files = glob.glob(os.path.join(MOON_DIR, "*.deb")) -for _file in files: - subprocess.run(["mv", "-v", _file, "/tmp/deb/"]) diff --git a/keystonemiddleware-moon/debian/gbp.conf b/keystonemiddleware-moon/debian/gbp.conf deleted file mode 100644 index 7436424b..00000000 --- a/keystonemiddleware-moon/debian/gbp.conf +++ /dev/null @@ -1,9 +0,0 @@ -[DEFAULT] -upstream-branch = master -debian-branch = debian/mitaka -upstream-tag = %(version)s -compression = xz - -[buildpackage] -export-dir = ../build-area/ - diff --git a/keystonemiddleware-moon/debian/patches/no-intersphinx.patch b/keystonemiddleware-moon/debian/patches/no-intersphinx.patch deleted file mode 100644 index a5e25751..00000000 --- a/keystonemiddleware-moon/debian/patches/no-intersphinx.patch +++ /dev/null @@ -1,17 +0,0 @@ -Description: Remove the intersphinx plugin. - Do not use the intersphinx plugin which is doing network access during - the build. -Author: Thomas Goirand -Forwarded: no -Last-Update: 2014-07-28 - ---- python-keystonemiddleware-1.0.0.orig/doc/source/conf.py -+++ python-keystonemiddleware-1.0.0/doc/source/conf.py -@@ -42,7 +42,6 @@ sys.path.insert(0, os.path.abspath(os.pa - extensions = ['sphinx.ext.autodoc', - 'sphinx.ext.todo', - 'sphinx.ext.coverage', -- 'sphinx.ext.intersphinx', - # NOTE(blk-u): Uncomment the [pbr] section in setup.cfg and - # remove this Sphinx extension when - # https://launchpad.net/bugs/1260495 is fixed. diff --git a/keystonemiddleware-moon/debian/patches/re-add-missing-auth-options.patch b/keystonemiddleware-moon/debian/patches/re-add-missing-auth-options.patch deleted file mode 100644 index fc981d0c..00000000 --- a/keystonemiddleware-moon/debian/patches/re-add-missing-auth-options.patch +++ /dev/null @@ -1,18 +0,0 @@ -Description: Re-add missing auth options - Upstream went a bit quick to remove Auth options from the default generated - config files. -Author: Thomas Goirand -Forwarded: no -Last-Update: 2016-04-07 - ---- python-keystonemiddleware-4.4.0.orig/keystonemiddleware/auth_token/__init__.py -+++ python-keystonemiddleware-4.4.0/keystonemiddleware/auth_token/__init__.py -@@ -370,7 +370,7 @@ _OPTS = [ - ' only while migrating from a less secure algorithm to a more' - ' secure one. Once all the old tokens are expired this option' - ' should be set to a single value for better performance.'), --] -+] + _auth.OPTS - - CONF = cfg.CONF - CONF.register_opts(_OPTS, group=_base.AUTHTOKEN_GROUP) diff --git a/keystonemiddleware-moon/debian/patches/series b/keystonemiddleware-moon/debian/patches/series deleted file mode 100644 index 3c47073f..00000000 --- a/keystonemiddleware-moon/debian/patches/series +++ /dev/null @@ -1,2 +0,0 @@ -no-intersphinx.patch -re-add-missing-auth-options.patch diff --git a/keystonemiddleware-moon/debian/python-keystonemiddleware-doc.doc-base b/keystonemiddleware-moon/debian/python-keystonemiddleware-doc.doc-base deleted file mode 100644 index bd08be62..00000000 --- a/keystonemiddleware-moon/debian/python-keystonemiddleware-doc.doc-base +++ /dev/null @@ -1,9 +0,0 @@ -Document: keystonemiddleware-doc -Title: keystonemiddleware Documentation -Author: N/A -Abstract: Sphinx documentation for keystonemiddleware -Section: Programming/Python - -Format: HTML -Index: /usr/share/doc/python-keystonemiddleware-doc/html/index.html -Files: /usr/share/doc/python-keystonemiddleware-doc/html/* diff --git a/keystonemiddleware-moon/debian/rules b/keystonemiddleware-moon/debian/rules deleted file mode 100755 index 2229093a..00000000 --- a/keystonemiddleware-moon/debian/rules +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/make -f - -PYTHONS:=$(shell pyversions -vr) -PYTHON3S:=$(shell py3versions -vr) - -UPSTREAM_GIT := https://github.com/openstack/keystonemiddleware.git -include /usr/share/openstack-pkg-tools/pkgos.make - -export OSLO_PACKAGE_VERSION=$(shell dpkg-parsechangelog | grep Version: | cut -d' ' -f2 | sed -e 's/^[[:digit:]]*://' -e 's/[-].*//' -e 's/~/.0/' | head -n 1) - -%: - dh $@ --buildsystem=python_distutils --with python2,python3,sphinxdoc - -override_dh_auto_install: - set -e ; for pyvers in $(PYTHONS); do \ - python$$pyvers setup.py install --install-layout=deb \ - --root $(CURDIR)/debian/python-keystonemiddleware; \ - done - set -e ; for pyvers in $(PYTHON3S); do \ - python$$pyvers setup.py install --install-layout=deb \ - --root $(CURDIR)/debian/python3-keystonemiddleware; \ - done - -override_dh_auto_test: -ifeq (,$(findstring nocheck, $(DEB_BUILD_OPTIONS))) - echo "===> Running tests" - set -e ; for i in 2.7 $(PYTHON3S) ; do \ - PYMAJOR=`echo $$i | cut -d'.' -f1` ; \ - echo "===> Testing with python$$i (python$$PYMAJOR)" ; \ - rm -rf .testrepository ; \ - testr-python$$PYMAJOR init ; \ - TEMP_REZ=`mktemp -t` ; \ - PYTHONPATH=$(CURDIR) PYTHON=python$$i testr-python$$PYMAJOR run --subunit 'keystonemiddleware.tests\.unit\.(?!(.*OptsTestCase.test_entry_point.*|.*test_opts.OptsTestCase.test_list_auth_token_opts.*|.*test_opts.OptsTestCase.test_original_list_all_options.*))' | tee $$TEMP_REZ | subunit2pyunit ; \ - cat $$TEMP_REZ | subunit-filter -s --no-passthrough | subunit-stats ; \ - rm -f $$TEMP_REZ ; \ - testr-python$$PYMAJOR slowest ; \ - done -endif - -override_dh_clean: - dh_clean -O--buildsystem=python_distutils - rm -rf build - -override_dh_sphinxdoc: - sphinx-build -b html doc/source debian/python-keystonemiddleware-doc/usr/share/doc/python-keystonemiddleware-doc/html - dh_sphinxdoc -O--buildsystem=python_distutils - -# Commands not to run -override_dh_installcatalogs: -override_dh_installemacsen override_dh_installifupdown: -override_dh_installinfo override_dh_installmenu override_dh_installmime: -override_dh_installmodules override_dh_installlogcheck: -override_dh_installpam override_dh_installppp override_dh_installudev override_dh_installwm: -override_dh_installxfonts override_dh_gconf override_dh_icons override_dh_perl override_dh_usrlocal: diff --git a/keystonemiddleware-moon/debian/source/format b/keystonemiddleware-moon/debian/source/format deleted file mode 100644 index 163aaf8d..00000000 --- a/keystonemiddleware-moon/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (quilt) diff --git a/keystonemiddleware-moon/debian/source/options b/keystonemiddleware-moon/debian/source/options deleted file mode 100644 index cb61fa52..00000000 --- a/keystonemiddleware-moon/debian/source/options +++ /dev/null @@ -1 +0,0 @@ -extend-diff-ignore = "^[^/]*[.]egg-info/" diff --git a/keystonemiddleware-moon/debian/watch b/keystonemiddleware-moon/debian/watch deleted file mode 100644 index d7d3dbeb..00000000 --- a/keystonemiddleware-moon/debian/watch +++ /dev/null @@ -1,3 +0,0 @@ -version=3 -opts="uversionmangle=s/\.(b|rc)/~$1/" \ -https://github.com/openstack/keystonemiddleware/tags .*/(\d[\d\.]+)\.tar\.gz diff --git a/keystonemiddleware-moon/doc/.gitignore b/keystonemiddleware-moon/doc/.gitignore deleted file mode 100644 index edde2181..00000000 --- a/keystonemiddleware-moon/doc/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build/ -source/api/ diff --git a/keystonemiddleware-moon/doc/Makefile b/keystonemiddleware-moon/doc/Makefile deleted file mode 100644 index 84f00bd5..00000000 --- a/keystonemiddleware-moon/doc/Makefile +++ /dev/null @@ -1,90 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -SPHINXSOURCE = source -PAPER = -BUILDDIR = build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SPHINXSOURCE) - -.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/keystonemiddleware.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/keystonemiddleware.qhc" - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ - "run these through (pdf)latex." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." diff --git a/keystonemiddleware-moon/doc/ext/__init__.py b/keystonemiddleware-moon/doc/ext/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/keystonemiddleware-moon/doc/ext/apidoc.py b/keystonemiddleware-moon/doc/ext/apidoc.py deleted file mode 100644 index 2575f422..00000000 --- a/keystonemiddleware-moon/doc/ext/apidoc.py +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright 2014 OpenStack Foundation -# -# 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. - -# NOTE(blk-u): Uncomment the [pbr] section in setup.cfg and remove this -# Sphinx extension when https://launchpad.net/bugs/1260495 is fixed. - -import os.path as path - -from sphinx import apidoc - - -# NOTE(blk-u): pbr will run Sphinx multiple times when it generates -# documentation. Once for each builder. To run this extension we use the -# 'builder-inited' hook that fires at the beginning of a Sphinx build. -# We use ``run_already`` to make sure apidocs are only generated once -# even if Sphinx is run multiple times. -run_already = False - - -def run_apidoc(app): - global run_already - if run_already: - return - run_already = True - - package_dir = path.abspath(path.join(app.srcdir, '..', '..', - 'keystonemiddleware')) - source_dir = path.join(app.srcdir, 'api') - apidoc.main(['apidoc', package_dir, '-f', - '-H', 'keystonemiddleware Modules', - '-o', source_dir]) - - -def setup(app): - app.connect('builder-inited', run_apidoc) diff --git a/keystonemiddleware-moon/doc/source/audit.rst b/keystonemiddleware-moon/doc/source/audit.rst deleted file mode 100644 index d23f8168..00000000 --- a/keystonemiddleware-moon/doc/source/audit.rst +++ /dev/null @@ -1,81 +0,0 @@ -.. - Copyright 2014 IBM Corp - - 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. - -.. _middleware: - -================= - Audit middleware -================= - -The Keystone middleware library provides an optional WSGI middleware filter -which allows the ability to audit API requests for each component of OpenStack. - -The audit middleware filter utilises environment variables to build the CADF -event. - -.. figure:: ./images/audit.png - :width: 100% - :align: center - :alt: Figure 1: Audit middleware in Nova pipeline - -The figure above shows the middleware in Nova's pipeline. - -Enabling audit middleware -========================= -To enable auditing, oslo.messaging_ should be installed. If not, the middleware -will log the audit event instead. Auditing can be enabled for a specific -project by editing the project's api-paste.ini file to include the following -filter definition: - -:: - - [filter:audit] - paste.filter_factory = keystonemiddleware.audit:filter_factory - audit_map_file = /etc/nova/api_audit_map.conf - -The filter should be included after Keystone middleware's auth_token middleware -so it can utilise environment variables set by auth_token. Below is an example -using Nova's WSGI pipeline:: - - [composite:openstack_compute_api_v2] - use = call:nova.api.auth:pipeline_factory - noauth = faultwrap sizelimit noauth ratelimit osapi_compute_app_v2 - keystone = faultwrap sizelimit authtoken keystonecontext ratelimit audit osapi_compute_app_v2 - keystone_nolimit = faultwrap sizelimit authtoken keystonecontext audit osapi_compute_app_v2 - -.. _oslo.messaging: http://www.github.com/openstack/oslo.messaging - -Configure audit middleware -========================== -To properly audit api requests, the audit middleware requires an -api_audit_map.conf to be defined. The project's corresponding -api_audit_map.conf file is included in the `pyCADF library`_. - -The location of the mapping file should be specified explicitly by adding the -path to the 'audit_map_file' option of the filter definition:: - - [filter:audit] - paste.filter_factory = keystonemiddleware.audit:filter_factory - audit_map_file = /etc/nova/api_audit_map.conf - -Additional options can be set:: - - [filter:audit] - paste.filter_factory = pycadf.middleware.audit:filter_factory - audit_map_file = /etc/nova/api_audit_map.conf - service_name = test # opt to set HTTP_X_SERVICE_NAME environ variable - ignore_req_list = GET,POST # opt to ignore specific requests - -.. _pyCADF library: https://github.com/openstack/pycadf/tree/master/etc/pycadf diff --git a/keystonemiddleware-moon/doc/source/conf.py b/keystonemiddleware-moon/doc/source/conf.py deleted file mode 100644 index ff4b24cc..00000000 --- a/keystonemiddleware-moon/doc/source/conf.py +++ /dev/null @@ -1,237 +0,0 @@ -# -*- coding: utf-8 -*- -# -# keystonemiddleware documentation build configuration file, created by -# sphinx-quickstart on Sun Dec 6 14:19:25 2009. -# -# This file is execfile()d with the current directory set to its containing -# dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -from __future__ import unicode_literals - -import os -import sys - -import pbr.version - - -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), - '..', '..'))) - -# NOTE(blk-u): Path for our Sphinx extension, remove when -# https://launchpad.net/bugs/1260495 is fixed. -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), - '..'))) - - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.append(os.path.abspath('.')) - -# -- General configuration ---------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', - 'sphinx.ext.todo', - 'sphinx.ext.coverage', - 'sphinx.ext.intersphinx', - # NOTE(blk-u): Uncomment the [pbr] section in setup.cfg and - # remove this Sphinx extension when - # https://launchpad.net/bugs/1260495 is fixed. - 'ext.apidoc', - 'oslosphinx' - ] - -todo_include_todos = True - -# Add any paths that contain templates here, relative to this directory. -#templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = 'keystonemiddleware' -copyright = 'OpenStack Contributors' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -version_info = pbr.version.VersionInfo('keystonemiddleware') -# The short X.Y version. -version = version_info.version_string() -# The full version, including alpha/beta/rc tags. -release = version_info.release_string() - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of documents that shouldn't be included in the build. -#unused_docs = [] - -# List of directories, relative to source directory, that shouldn't be searched -# for source files. -exclude_trees = [] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -modindex_common_prefix = ['keystonemiddleware.'] - -# Grouping the document tree for man pages. -# List of tuples 'sourcefile', 'target', 'title', 'Authors name', 'manual' - -man_pages = [] - -# -- Options for HTML output -------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. Major themes that come with -# Sphinx are currently 'default' and 'sphinxdoc'. -#html_theme_path = ["."] -#html_theme = '_theme' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -#html_static_path = ['static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -git_cmd = "git log --pretty=format:'%ad, commit %h' --date=local -n1" -html_last_updated_fmt = os.popen(git_cmd).read() - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_use_modindex = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = '' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'keystonemiddlewaredoc' - - -# -- Options for LaTeX output ------------------------------------------------- - -# The paper size ('letter' or 'a4'). -#latex_paper_size = 'letter' - -# The font size ('10pt', '11pt' or '12pt'). -#latex_font_size = '10pt' - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]) -# . -latex_documents = [ - ('index', 'keystonmiddleware.tex', - 'keystonemiddleware Documentation', - 'Nebula Inc, based on work by Rackspace and Jacob Kaplan-Moss', - 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# Additional stuff for the LaTeX preamble. -#latex_preamble = '' - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_use_modindex = True - -keystoneclient = 'http://docs.openstack.org/developer/python-keystoneclient/' - -intersphinx_mapping = {'keystoneclient': (keystoneclient, None), - } diff --git a/keystonemiddleware-moon/doc/source/images/audit.png b/keystonemiddleware-moon/doc/source/images/audit.png deleted file mode 100644 index 5c2b1305..00000000 Binary files a/keystonemiddleware-moon/doc/source/images/audit.png and /dev/null differ diff --git a/keystonemiddleware-moon/doc/source/images/graphs_authComp.svg b/keystonemiddleware-moon/doc/source/images/graphs_authComp.svg deleted file mode 100644 index 6be629c1..00000000 --- a/keystonemiddleware-moon/doc/source/images/graphs_authComp.svg +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - -AuthComp - - -AuthComp - -Auth -Component - - - -AuthComp->Reject - - -Reject -Unauthenticated -Requests - - -Service - -OpenStack -Service - - -AuthComp->Service - - -Forward -Authenticated -Requests - - - -Start->AuthComp - - - - - diff --git a/keystonemiddleware-moon/doc/source/images/graphs_authCompDelegate.svg b/keystonemiddleware-moon/doc/source/images/graphs_authCompDelegate.svg deleted file mode 100644 index 4788829a..00000000 --- a/keystonemiddleware-moon/doc/source/images/graphs_authCompDelegate.svg +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - -AuthCompDelegate - - -AuthComp - -Auth -Component - - - -AuthComp->Reject - - -Reject Requests -Indicated by the Service - - -Service - -OpenStack -Service - - -AuthComp->Service - - -Forward Requests -with Identiy Status - - -Service->AuthComp - - -Send Response OR -Reject Message - - - -Start->AuthComp - - - - - diff --git a/keystonemiddleware-moon/doc/source/index.rst b/keystonemiddleware-moon/doc/source/index.rst deleted file mode 100644 index 9092ec79..00000000 --- a/keystonemiddleware-moon/doc/source/index.rst +++ /dev/null @@ -1,46 +0,0 @@ -Python Middleware for OpenStack Identity API (Keystone) -======================================================= - -This is the middleware provided for integrating with the OpenStack -Identity API and handling authorization enforcement based upon the -data within the OpenStack Identity tokens. Also included is middleware that -provides the ability to create audit events based on API requests. - -Contents: - -.. toctree:: - :maxdepth: 1 - - middlewarearchitecture - audit - -Related Identity Projects -========================= - -In addition to creating the Python Middleware for OpenStack Identity -API, the Keystone team also provides `Identity Service`_, as well as -`Python Client Library`_. - -.. _`Identity Service`: http://docs.openstack.org/developer/keystone/ -.. _`Python Client Library`: http://docs.openstack.org/developer/python-keystoneclient/ - -Contributing -============ - -Code is hosted `on GitHub`_. Submit bugs to the Keystone project on -`Launchpad`_. Submit code to the ``openstack/keystonemiddleware`` project -using `Gerrit`_. - -.. _on GitHub: https://github.com/openstack/keystonemiddleware -.. _Launchpad: https://launchpad.net/keystonemiddleware -.. _Gerrit: http://docs.openstack.org/infra/manual/developers.html#development-workflow - -Run tests with ``python setup.py test``. - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - diff --git a/keystonemiddleware-moon/doc/source/middlewarearchitecture.rst b/keystonemiddleware-moon/doc/source/middlewarearchitecture.rst deleted file mode 100644 index e543be47..00000000 --- a/keystonemiddleware-moon/doc/source/middlewarearchitecture.rst +++ /dev/null @@ -1,472 +0,0 @@ -.. Copyright 2011-2013 OpenStack Foundation -.. All Rights Reserved. - -.. 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. - -======================= -Middleware Architecture -======================= - -Abstract -======== - -The Keystone middleware architecture supports a common authentication protocol -in use between the OpenStack projects. By using keystone as a common -authentication and authorization mechanism, the OpenStack project can plug in -to existing authentication and authorization systems in use by existing -environments. - -In this document, we describe the architecture and responsibilities of the -authentication middleware which acts as the internal API mechanism for -OpenStack projects based on the WSGI standard. - -This documentation describes the implementation in -:class:`keystonemiddleware.auth_token` - -Specification Overview -====================== - -'Authentication' is the process of determining that users are who they say they -are. Typically, 'authentication protocols' such as HTTP Basic Auth, Digest -Access, public key, token, etc, are used to verify a user's identity. In this -document, we define an ''authentication component'' as a software module that -implements an authentication protocol for an OpenStack service. OpenStack is -using a token based mechanism to represent authentication and authorization. - -At a high level, an authentication middleware component is a proxy that -intercepts HTTP calls from clients and populates HTTP headers in the request -context for other WSGI middleware or applications to use. The general flow -of the middleware processing is: - -* clear any existing authorization headers to prevent forgery -* collect the token from the existing HTTP request headers -* validate the token - - * if valid, populate additional headers representing the identity that has - been authenticated and authorized - * if invalid, or no token present, reject the request (HTTPUnauthorized) - or pass along a header indicating the request is unauthorized (configurable - in the middleware) - * if the keystone service is unavailable to validate the token, reject - the request with HTTPServiceUnavailable. - -.. _authComponent: - -Authentication Component ------------------------- - -Figure 1. Authentication Component - -.. image:: images/graphs_authComp.svg - :width: 100% - :height: 180 - :alt: An Authentication Component - -The middleware may also be configured to operate in a 'delegated mode'. -In this mode, the decision to reject an unauthenticated client is delegated to -the OpenStack service, as illustrated in :ref:`authComponentDelegated`. - -Here, requests are forwarded to the OpenStack service with an identity status -message that indicates whether the client's identity has been confirmed or is -indeterminate. It is the OpenStack service that decides whether or not a reject -message should be sent to the client. - -.. _authComponentDelegated: - -Authentication Component (Delegated Mode) ------------------------------------------ - -Figure 2. Authentication Component (Delegated Mode) - -.. image:: images/graphs_authCompDelegate.svg - :width: 100% - :height: 180 - :alt: An Authentication Component (Delegated Mode) - -.. _deployStrategies: - -Deployment Strategy -=================== - -The middleware is intended to be used inline with OpenStack wsgi components, -based on the Oslo WSGI middleware class. It is typically deployed -as a configuration element in a paste configuration pipeline of other -middleware components, with the pipeline terminating in the service -application. The middleware conforms to the python WSGI standard [PEP-333]_. -In initializing the middleware, a configuration item (which acts like a python -dictionary) is passed to the middleware with relevant configuration options. - -Configuration -------------- - -The middleware is configured within the config file of the main application as -a WSGI component. Example for the auth_token middleware: - -.. code-block:: ini - - [app:myService] - paste.app_factory = myService:app_factory - - [pipeline:main] - pipeline = authtoken myService - - [filter:authtoken] - paste.filter_factory = keystonemiddleware.auth_token:filter_factory - - # Prefix to prepend at the beginning of the path (string - # value) - #auth_admin_prefix= - - # Host providing the admin Identity API endpoint (string - # value) - auth_host=127.0.0.1 - - # Port of the admin Identity API endpoint (integer value) - auth_port=35357 - - # Protocol of the admin Identity API endpoint(http or https) - # (string value) - auth_protocol=https - - # Complete public Identity API endpoint (string value) - #auth_uri= - - # API version of the admin Identity API endpoint (string - # value) - #auth_version= - - # Do not handle authorization requests within the middleware, - # but delegate the authorization decision to downstream WSGI - # components (boolean value) - #delay_auth_decision=false - - # Request timeout value for communicating with Identity API - # server. (boolean value) - #http_connect_timeout= - - # How many times are we trying to reconnect when communicating - # with Identity API Server. (integer value) - #http_request_max_retries=3 - - # Single shared secret with the Keystone configuration used - # for bootstrapping a Keystone installation, or otherwise - # bypassing the normal authentication process. (string value) - #admin_token= - - # Keystone account username (string value) - #admin_user= - - # Keystone account password (string value) - admin_password=SuperSekretPassword - - # Keystone service account tenant name to validate user tokens - # (string value) - #admin_tenant_name=admin - - # Env key for the swift cache (string value) - #cache= - - # Required if Keystone server requires client certificate - # (string value) - #certfile= - - # Required if Keystone server requires client certificate - # (string value) - #keyfile= - - # A PEM encoded Certificate Authority to use when verifying - # HTTPs connections. Defaults to system CAs. (string value) - #cafile= - - # Verify HTTPS connections. (boolean value) - #insecure=false - - # Directory used to cache files related to PKI tokens (string - # value) - #signing_dir= - - # If defined, the memcached server(s) to use for caching (list - # value) - # Deprecated group/name - [DEFAULT]/memcache_servers - #memcached_servers= - - # In order to prevent excessive requests and validations, the - # middleware uses an in-memory cache for the tokens the - # Keystone API returns. This is only valid if memcache_servers - # is defined. Set to -1 to disable caching completely. - # (integer value) - #token_cache_time=300 - - # Value only used for unit testing (integer value) - #revocation_cache_time=1 - - # (optional) if defined, indicate whether token data should be - # authenticated or authenticated and encrypted. Acceptable - # values are MAC or ENCRYPT. If MAC, token data is - # authenticated (with HMAC) in the cache. If ENCRYPT, token - # data is encrypted and authenticated in the cache. If the - # value is not one of these options or empty, auth_token will - # raise an exception on initialization. (string value) - #memcache_security_strategy= - - # (optional, mandatory if memcache_security_strategy is - # defined) this string is used for key derivation. (string - # value) - #memcache_secret_key= - - # (optional) indicate whether to set the X-Service-Catalog - # header. If False, middleware will not ask for service - # catalog on token validation and will not set the X-Service- - # Catalog header. (boolean value) - #include_service_catalog=true - - # Used to control the use and type of token binding. Can be - # set to: "disabled" to not check token binding. "permissive" - # (default) to validate binding information if the bind type - # is of a form known to the server and ignore it if not. - # "strict" like "permissive" but if the bind type is unknown - # the token will be rejected. "required" any form of token - # binding is needed to be allowed. Finally the name of a - # binding method that must be present in tokens. (string - # value) - #enforce_token_bind=permissive - -For services which have a separate paste-deploy ini file, auth_token middleware -can be alternatively configured in [keystone_authtoken] section in the main -config file. For example in Nova, all middleware parameters can be removed -from ``api-paste.ini``: - -.. code-block:: ini - - [filter:authtoken] - paste.filter_factory = keystonemiddleware.auth_token:filter_factory - -and set in ``nova.conf``: - -.. code-block:: ini - - [DEFAULT] - auth_strategy=keystone - - [keystone_authtoken] - auth_host = 127.0.0.1 - auth_port = 35357 - auth_protocol = http - admin_user = admin - admin_password = SuperSekretPassword - admin_tenant_name = service - # Any of the options that could be set in api-paste.ini can be set here. - -Note that middleware parameters in paste config take priority, they must be -removed to use values in [keystone_authtoken] section. - -If the service doesn't use the global oslo.config object (CONF), then the -olso config project name can be set it in paste config and -keystonemiddleware will load the project configuration itself. -Optionally the location of the configuration file can be set if oslo.config -is not able to discover it. - -.. code-block:: ini - - [filter:authtoken] - paste.filter_factory = keystonemiddleware.auth_token:filter_factory - oslo_config_project = nova - # oslo_config_file = /not_discoverable_location/nova.conf - - -Configuration Options ---------------------- - -* ``auth_admin_prefix``: Prefix to prepend at the beginning of the path -* ``auth_host``: (required) the host providing the keystone service API endpoint - for validating and requesting tokens -* ``auth_port``: (optional, default `35357`) the port used to validate tokens -* ``auth_protocol``: (optional, default `https`) -* ``auth_uri``: (optional, defaults to - `auth_protocol`://`auth_host`:`auth_port`) -* ``auth_version``: API version of the admin Identity API endpoint -* ``delay_auth_decision``: (optional, default `0`) (off). If on, the middleware - will not reject invalid auth requests, but will delegate that decision to - downstream WSGI components. -* ``http_connect_timeout``: (optional) Request timeout value for communicating - with Identity API server. -* ``http_request_max_retries``: (default 3) How many times are we trying to - reconnect when communicating with Identity API Server. -* ``http_handler``: (optional) Allows to pass in the name of a fake - http_handler callback function used instead of `httplib.HTTPConnection` or - `httplib.HTTPSConnection`. Useful for unit testing where network is not - available. - -* ``admin_token``: either this or the following three options are required. If - set, this is a single shared secret with the keystone configuration used to - validate tokens. -* ``admin_user``, ``admin_password``, ``admin_tenant_name``: if ``admin_token`` - is not set, or invalid, then admin_user, admin_password, and - admin_tenant_name are defined as a service account which is expected to have - been previously configured in Keystone to validate user tokens. - -* ``cache``: (optional) Env key for the swift cache - -* ``certfile``: (required, if Keystone server requires client cert) -* ``keyfile``: (required, if Keystone server requires client cert) This can be - the same as the certfile if the certfile includes the private key. -* ``cafile``: (optional, defaults to use system CA bundle) the path to a PEM - encoded CA file/bundle that will be used to verify HTTPS connections. -* ``insecure``: (optional, default `False`) Don't verify HTTPS connections - (overrides `cafile`). - -* ``signing_dir``: (optional) Directory used to cache files related to PKI - tokens - -* ``memcached_servers``: (optional) If defined, the memcached server(s) to use - for caching -* ``token_cache_time``: (default 300) In order to prevent excessive requests - and validations, the middleware uses an in-memory cache for the tokens the - Keystone API returns. This is only valid if memcache_servers s defined. Set - to -1 to disable caching completely. -* ``memcache_security_strategy``: (optional) if defined, indicate whether token - data should be authenticated or authenticated and encrypted. Acceptable - values are MAC or ENCRYPT. If MAC, token data is authenticated (with HMAC) - in the cache. If ENCRYPT, token data is encrypted and authenticated in the - cache. If the value is not one of these options or empty, auth_token will - raise an exception on initialization. -* ``memcache_secret_key``: (mandatory if memcache_security_strategy is defined) - this string is used for key derivation. -* ``include_service_catalog``: (optional, default `True`) Indicate whether to - set the X-Service-Catalog header. If False, middleware will not ask for - service catalog on token validation and will not set the X-Service-Catalog - header. -* ``enforce_token_bind``: (default ``permissive``) Used to control the use and - type of token binding. Can be set to: "disabled" to not check token binding. - "permissive" (default) to validate binding information if the bind type is of - a form known to the server and ignore it if not. "strict" like "permissive" - but if the bind type is unknown the token will be rejected. "required" any - form of token binding is needed to be allowed. Finally the name of a binding - method that must be present in tokens. - -Caching for improved response ------------------------------ - -In order to prevent excessive requests and validations, the middleware uses an -in-memory cache for the tokens the keystone API returns. Keep in mind that -invalidated tokens may continue to work if they are still in the token cache, -so token_cache_time is configurable. For larger deployments, the middleware -also supports memcache based caching. - -* ``memcached_servers``: (optonal) if defined, the memcached server(s) to use for - cacheing. It will be ignored if Swift MemcacheRing is used instead. -* ``token_cache_time``: (optional, default 300 seconds) Set to -1 to disable - caching completely. - -When deploying auth_token middleware with Swift, user may elect -to use Swift MemcacheRing instead of the local Keystone memcache. -The Swift MemcacheRing object is passed in from the request environment -and it defaults to 'swift.cache'. However it could be -different, depending on deployment. To use Swift MemcacheRing, you must -provide the ``cache`` option. - -* ``cache``: (optional) if defined, the environment key where the Swift - MemcacheRing object is stored. - -Memcached dependencies -====================== - -In order to use `memcached`_ it is necessary to install the `python-memcached`_ -library. If data stored in `memcached`_ will need to be encrypted it is also -necessary to install the `pycrypto`_ library. These libs are not listed in -the requirements.txt file. - -.. _`memcached`: http://memcached.org/ -.. _`python-memcached`: https://pypi.python.org/pypi/python-memcached -.. _`pycrypto`: https://pypi.python.org/pypi/pycrypto - -Memcached and System Time -========================= - -When using `memcached`_ with ``auth_token`` middleware, ensure that the system -time of memcached hosts is set to UTC. Memcached uses the host's system -time in determining whether a key has expired, whereas Keystone sets -key expiry in UTC. The timezone used by Keystone and memcached must -match if key expiry is to behave as expected. - -Memcache Protection -=================== - -When using memcached, we are storing user tokens and token validation -information into the cache as raw data. Which means that anyone who -has access to the memcached servers can read and modify data stored -there. To mitigate this risk, ``auth_token`` middleware provides an -option to authenticate and optionally encrypt the token data stored in -the cache. - -* ``memcache_security_strategy``: (optional) if defined, indicate - whether token data should be authenticated or authenticated and - encrypted. Acceptable values are ``MAC`` or ``ENCRYPT``. If ``MAC``, - token data is authenticated (with HMAC) in the cache. If - ``ENCRYPT``, token data is encrypted and authenticated in the - cache. If the value is not one of these options or empty, - ``auth_token`` will raise an exception on initialization. -* ``memcache_secret_key``: (optional, mandatory if - ``memcache_security_strategy`` is defined) this string is used for - key derivation. If ``memcache_security_strategy`` is defined and - ``memcache_secret_key`` is absent, ``auth_token`` will raise an - exception on initialization. - -Exchanging User Information -=========================== - -The middleware expects to find a token representing the user with the header -``X-Auth-Token`` or ``X-Storage-Token``. `X-Storage-Token` is supported for -swift/cloud files and for legacy Rackspace use. If the token isn't present and -the middleware is configured to not delegate auth responsibility, it will -respond to the HTTP request with HTTPUnauthorized, returning the header -``WWW-Authenticate`` with the value `Keystone uri='...'` to indicate where to -request a token. The auth_uri returned is configured with the middleware. - -The authentication middleware extends the HTTP request with the header -``X-Identity-Status``. If a request is successfully authenticated, the value -is set to `Confirmed`. If the middleware is delegating the auth decision to the -service, then the status is set to `Invalid` if the auth request was -unsuccessful. - -An ``X-Service-Token`` header may also be included with a request. If present, -and the value of ``X-Auth-Token`` or ``X-Storage-Token`` has not caused the -request to be denied, then the middleware will attempt to validate the value of -``X-Service-Token``. If valid, the authentication middleware extends the HTTP -request with the header ``X-Service-Identity-Status`` having value `Confirmed` -and also extends the request with additional headers representing the identity -authenticated and authorised by the token. - -If ``X-Service-Token`` is present and its value is invalid and the -``delay_auth_decision`` option is True then the value of -``X-Service-Identity-Status`` is set to `Invalid` and no further headers are -added. Otherwise if ``X-Service-Token`` is present and its value is invalid -then the middleware will respond to the HTTP request with HTTPUnauthorized, -regardless of the validity of the ``X-Auth-Token`` or ``X-Storage-Token`` -values. - -Extended the request with additional User Information ------------------------------------------------------ - -:py:class:`keystonemiddleware.auth_token.AuthProtocol` extends the -request with additional information if the user has been authenticated. See the -"What we add to the request for use by the OpenStack service" section in -:py:mod:`keystonemiddleware.auth_token` for the list of fields set by -the auth_token middleware. - - -References -========== - -.. [PEP-333] pep0333 Phillip J Eby. 'Python Web Server Gateway Interface - v1.0.'' http://www.python.org/dev/peps/pep-0333/. diff --git a/keystonemiddleware-moon/examples/pki/certs/cacert.pem b/keystonemiddleware-moon/examples/pki/certs/cacert.pem deleted file mode 100644 index 952bdaea..00000000 --- a/keystonemiddleware-moon/examples/pki/certs/cacert.pem +++ /dev/null @@ -1,23 +0,0 @@ ------BEGIN CERTIFICATE----- -MIID1jCCAr6gAwIBAgIJAJOtRP2+wrM/MA0GCSqGSIb3DQEBBQUAMIGeMQowCAYD -VQQFEwE1MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVN1bm55 -dmFsZTESMBAGA1UEChMJT3BlblN0YWNrMREwDwYDVQQLEwhLZXlzdG9uZTElMCMG -CSqGSIb3DQEJARYWa2V5c3RvbmVAb3BlbnN0YWNrLm9yZzEUMBIGA1UEAxMLU2Vs -ZiBTaWduZWQwIBcNMTMwOTEzMTYyNTQyWhgPMjA3MjAzMDcxNjI1NDJaMIGeMQow -CAYDVQQFEwE1MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVN1 -bm55dmFsZTESMBAGA1UEChMJT3BlblN0YWNrMREwDwYDVQQLEwhLZXlzdG9uZTEl -MCMGCSqGSIb3DQEJARYWa2V5c3RvbmVAb3BlbnN0YWNrLm9yZzEUMBIGA1UEAxML -U2VsZiBTaWduZWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCl8906 -EaRpibQFcCBWfxzLi5x/XpZ9iL6UX92NrSJxcDbaGws7s+GtjgDy8UOEonesRWTe -qQEZtHpC3/UHHOnsA8F6ha/pq9LioqT7RehCnZCLBJwh5Ct+lclpWs15SkjJD2LT -Dkjox0eA9nOBx+XDlWyU/GAyqx5Wsvg/Kxr0iod9/4IcJdnSdUjq4v0Cxg/zNk08 -XPJX+F0bUDhgdUf7JrAmmS5LA8wphRnbIgtVsf6VN9HrbqtHAJDxh8gEfuwdhEW1 -df1fBtZ+6WMIF3IRSbIsZELFB6sqcyRj7HhMoWMkdEyPb2f8mq61MzTgE6lJGIyT -RvEoFie7qtGADIofAgMBAAGjEzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN -AQEFBQADggEBAJRMdEwAdN+crqI9dBLYlbBbnQ8xr9mk+REMdz9+SKhDCNdVisWU -iLEZvK/aozrsRsDi81JjS4Tz0wXo8zsPPoDnXgDYEicNPTKifbPKgHdDIGFOwBKn -y2cF6fHEn8n3KIBrDCNY6rHcYGZ7lbq/8eF0GoYQboPiuYesvVpynPmIK5/Mmire -EuuZALAe1IFqqFt+l6tiJU2JWUFjLkFARMOD14qFZm+SInl64toi08j6gdou+NMW -7GEMbVHwNTafM/TgFN5j0yP9SAnYubckLSyH6hwR+rM8dztP5769joxQfnc9O/Bn -TBD9KFpeQv6VJWLAxiIKcQCRTTDJLZZ0MQI= ------END CERTIFICATE----- diff --git a/keystonemiddleware-moon/examples/pki/certs/middleware.pem b/keystonemiddleware-moon/examples/pki/certs/middleware.pem deleted file mode 100644 index 7d593efd..00000000 --- a/keystonemiddleware-moon/examples/pki/certs/middleware.pem +++ /dev/null @@ -1,50 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDpjCCAo4CARAwDQYJKoZIhvcNAQEFBQAwgZ4xCjAIBgNVBAUTATUxCzAJBgNV -BAYTAlVTMQswCQYDVQQIEwJDQTESMBAGA1UEBxMJU3Vubnl2YWxlMRIwEAYDVQQK -EwlPcGVuU3RhY2sxETAPBgNVBAsTCEtleXN0b25lMSUwIwYJKoZIhvcNAQkBFhZr -ZXlzdG9uZUBvcGVuc3RhY2sub3JnMRQwEgYDVQQDEwtTZWxmIFNpZ25lZDAgFw0x -MzA5MTMxNjI1NDNaGA8yMDcyMDMwNzE2MjU0M1owgZAxCzAJBgNVBAYTAlVTMQsw -CQYDVQQIEwJDQTESMBAGA1UEBxMJU3Vubnl2YWxlMRIwEAYDVQQKEwlPcGVuU3Rh -Y2sxETAPBgNVBAsTCEtleXN0b25lMSUwIwYJKoZIhvcNAQkBFhZrZXlzdG9uZUBv -cGVuc3RhY2sub3JnMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQDL06AaJROwHPgJ9tcySSBepzJ81jYars2sMvLjyuvd -iIBbhWvbS/a9Tw3WgL8H6OALkHiOU/f0A6Rpv8dGDIDsxZQVjT/4SLaQUOeDM+9b -fkKHpSd9G3CsdSSZgOH08n+MyZ7slPHfUHLYWso0SJD0vAi1gmGDlSM/mmhhHTpC -DGo6Wbwqare6JNeTCGJTJYwrxtoMCh/W1ZrslPC5lFvlHD7KBBf6IU2A8Xh/dUa3 -p5pmQeHPW8Em90DzIB1qH0DRXl3KANc24xYRR45pPCVkk6vFsy6P0JwwpnkszB+L -cK6CEsJhLsOYvQFsiQfSZ8m7YGhgrMLxtop4YEPirGGrAgMBAAEwDQYJKoZIhvcN -AQEFBQADggEBAAjU7YomUx/U56p1KWHvr1B7oczHF8fPHYbuk5c/N81WOJeSRy+P -5ZGZ2UPjvqqXByv+78YWMKGY1BZ/2doeWuydr0sdSxEwmIUBYxFpujuYY+0AjS/n -mMr1ZijK7TJssteKM7/MClzghUhPweDZrAg3ff1hbhK5QSy+9UPxUqLH44tfYSVC -/BzM6se0p5ToM0bwdsa8TofaBRE1L1IW/Hg4VIGOoKs0R0uLm7+Oot2me2cEuZ6h -Wls6MED8ND1Nz8EAKwndkeDu2iMM+qx/YFp6K8BQ5E5nXd2rbUZUlQMp1WbUlZ87 -KvC98aT0UYIq6uo1Lx/dQvJs7faAkYd4lmE= ------END CERTIFICATE----- ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDL06AaJROwHPgJ -9tcySSBepzJ81jYars2sMvLjyuvdiIBbhWvbS/a9Tw3WgL8H6OALkHiOU/f0A6Rp -v8dGDIDsxZQVjT/4SLaQUOeDM+9bfkKHpSd9G3CsdSSZgOH08n+MyZ7slPHfUHLY -Wso0SJD0vAi1gmGDlSM/mmhhHTpCDGo6Wbwqare6JNeTCGJTJYwrxtoMCh/W1Zrs -lPC5lFvlHD7KBBf6IU2A8Xh/dUa3p5pmQeHPW8Em90DzIB1qH0DRXl3KANc24xYR -R45pPCVkk6vFsy6P0JwwpnkszB+LcK6CEsJhLsOYvQFsiQfSZ8m7YGhgrMLxtop4 -YEPirGGrAgMBAAECggEATwvbY0hNwlb5uqOIAXBqpUqiQdexU9fG26lGmSDxKBDv -9o5frcRgBDrMWwvDCgY+HT4CAvB9kJx4/qnpVjkzJp/ZNiJ5VIiehIlbv348rXbh -xkk+bz5dDATCFOXuu1fwL2FhyM5anwhMAav0DyK1VLQ3jGzr9GO6L8hqAn+bQFFu -6ngiODwfhBMl5aRoL9UOBEhccK07znrH0JGRz+3+5Cdz59Xw91Bv210LhNNDL58+ -0JD0N+YztVOQd2bgwo0bQbOEijzmYq+0mjoqAnJh1/++y7PlIPs0AnPgqSnFPx9+ -6FsQEVRgk5Uq3kvPLaP4nT2y6MDZSp+ujYldvJhyQQKBgQDuX2pZIJMZ4aFnkG+K -TmJ5wsLa/u9an0TmvAL9RLtBpVpQNKD8cQ+y8PUZavXDbAIt5NWqZVnTbCR79Dnd -mZKblwcHhtsyA5f89el5KcxY2BREWdHdTnJpNd7XRlUECmzvX1zGj77lA982PhII -yflRBRV3vqLkgC8vfoYgRyRElwKBgQDa5jnLdx/RahfYMOgn1HE5o4hMzLR4Y0Dd -+gELshcUbPqouoP5zOb8WOagVJIgZVOSN+/VqbilVYrqRiNTn2rnoxs+HHRdaJNN -3eXllD4J2HfC2BIj1xSpIdyh2XewAJqw9IToHNB29QUhxOtgwseHciPG6JaKH2ik -kqGKH/EKDQKBgFFAftygiOPCkCTgC9UmANUmOQsy6N2H+pF3tsEj43xt44oBVnqW -A1boYXNnjRwuvdNs9BPf9i1l6E3EItFRXrLgWQoMwryakv0ryYh+YeRKyyW9RBbe -fYs1TJ8unx4Ae79gTxxztQsVNcmkgLs0NWKTjAzEE3w14V+cDhYEie1DAoGBAJdI -V5cLrBzBstsB6eBlDR9lqrRRIUS2a8U9m+1mVlcSfiWQSdehSd4K3tDdwePLw3ch -W4qR8n+pYAlLEe0gFvUhn5lMdwt7U5qUCeehjUKmrRYm2FqWsbu2IFJnBjXIJSC4 -zQXRrC0aZ0KQYpAL7XPpaVp1slyhGmPqxuO78Y0dAoGBAMHo3EIMwu9rfuGwFodr -GFsOZhfJqgo5GDNxxf89Q9WWpMDTCdX+wdBTrN/wsMbBuwIDHrUuRnk6D5CWRjSk -/ikCgHN3kOtrbL8zzqRomGAIIWKYGFEIGe1GHVGo5r//HXHdPxFXygvruQ/xbOA4 -RGvmDiji8vVDq7Shho8I6KuT ------END PRIVATE KEY----- diff --git a/keystonemiddleware-moon/examples/pki/certs/signing_cert.pem b/keystonemiddleware-moon/examples/pki/certs/signing_cert.pem deleted file mode 100644 index 63ab2478..00000000 --- a/keystonemiddleware-moon/examples/pki/certs/signing_cert.pem +++ /dev/null @@ -1,22 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDpTCCAo0CAREwDQYJKoZIhvcNAQEFBQAwgZ4xCjAIBgNVBAUTATUxCzAJBgNV -BAYTAlVTMQswCQYDVQQIEwJDQTESMBAGA1UEBxMJU3Vubnl2YWxlMRIwEAYDVQQK -EwlPcGVuU3RhY2sxETAPBgNVBAsTCEtleXN0b25lMSUwIwYJKoZIhvcNAQkBFhZr -ZXlzdG9uZUBvcGVuc3RhY2sub3JnMRQwEgYDVQQDEwtTZWxmIFNpZ25lZDAgFw0x -MzA5MTMxNjI1NDNaGA8yMDcyMDMwNzE2MjU0M1owgY8xCzAJBgNVBAYTAlVTMQsw -CQYDVQQIEwJDQTESMBAGA1UEBxMJU3Vubnl2YWxlMRIwEAYDVQQKEwlPcGVuU3Rh -Y2sxETAPBgNVBAsTCEtleXN0b25lMSUwIwYJKoZIhvcNAQkBFhZrZXlzdG9uZUBv -cGVuc3RhY2sub3JnMREwDwYDVQQDEwhLZXlzdG9uZTCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBAMz5WsgsuX3rZUdLwQpZXN2Ro7LQ6jEZnreBqMztVObw -BuC1WdiJsg6dVlC7PVdt+0gY1c8WFg1TKmsucxesQSyfGAPg+9T/hsRMb6y12uJx -fp3Wgqqw0U1HsXvMiaJH87MaGnt043BxzF+R9fhAcDk6Cyj5cx9J0LvZJEOzN4J4 -ZRyO6j/DZZItb3lK5W9xkuoT+mTdDZOQJnXyG818uiWfjdCkLjr1ruytRcBOo4na -Y828voT/A7I95+YCgKgbjiUWhHeTaNmMEQiGy0nGYfteC+oSsHOlxZ3b12azzHPk -83Bh2ez0Ih9vcZoe9DqvlFOXfv9q8OsYc5Yo6gPTXEsCAwEAATANBgkqhkiG9w0B -AQUFAAOCAQEAmaYE98kOQWu6DV84ZcZP/OdT8eeu3vdB247nRj+6+GYItN/Gzqt4 -HVvz7c+FVTolCcAQQ+z3XGswI9fIJ78Hb0p9CgnLprc3L7Xtk60Im59Xlf3tcurn -r/ZnSDcjRBXKiEDrSM0VrhAnc0GoSeb6aDWopec+1hWOWfBVAg9R8yJgU9sUgO3O -0gimGyrw8eubmNhckSQLJTunUTsrkcBjuSg63wAD9OqCiX6c2eoQr+0YBp2eV2/n -aOiJXWNLbeueMKSYiJNyyvM/dlON7/56cdwDTzKzgD34TImouM5VKipUwCX1ovLu -ITLzALzpqFFzc8ugV9pMgUKtDbZoPp9EEA== ------END CERTIFICATE----- diff --git a/keystonemiddleware-moon/examples/pki/certs/ssl_cert.pem b/keystonemiddleware-moon/examples/pki/certs/ssl_cert.pem deleted file mode 100644 index cdd2e4c0..00000000 --- a/keystonemiddleware-moon/examples/pki/certs/ssl_cert.pem +++ /dev/null @@ -1,22 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDpjCCAo4CARAwDQYJKoZIhvcNAQEFBQAwgZ4xCjAIBgNVBAUTATUxCzAJBgNV -BAYTAlVTMQswCQYDVQQIEwJDQTESMBAGA1UEBxMJU3Vubnl2YWxlMRIwEAYDVQQK -EwlPcGVuU3RhY2sxETAPBgNVBAsTCEtleXN0b25lMSUwIwYJKoZIhvcNAQkBFhZr -ZXlzdG9uZUBvcGVuc3RhY2sub3JnMRQwEgYDVQQDEwtTZWxmIFNpZ25lZDAgFw0x -MzA5MTMxNjI1NDNaGA8yMDcyMDMwNzE2MjU0M1owgZAxCzAJBgNVBAYTAlVTMQsw -CQYDVQQIEwJDQTESMBAGA1UEBxMJU3Vubnl2YWxlMRIwEAYDVQQKEwlPcGVuU3Rh -Y2sxETAPBgNVBAsTCEtleXN0b25lMSUwIwYJKoZIhvcNAQkBFhZrZXlzdG9uZUBv -cGVuc3RhY2sub3JnMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQDL06AaJROwHPgJ9tcySSBepzJ81jYars2sMvLjyuvd -iIBbhWvbS/a9Tw3WgL8H6OALkHiOU/f0A6Rpv8dGDIDsxZQVjT/4SLaQUOeDM+9b -fkKHpSd9G3CsdSSZgOH08n+MyZ7slPHfUHLYWso0SJD0vAi1gmGDlSM/mmhhHTpC -DGo6Wbwqare6JNeTCGJTJYwrxtoMCh/W1ZrslPC5lFvlHD7KBBf6IU2A8Xh/dUa3 -p5pmQeHPW8Em90DzIB1qH0DRXl3KANc24xYRR45pPCVkk6vFsy6P0JwwpnkszB+L -cK6CEsJhLsOYvQFsiQfSZ8m7YGhgrMLxtop4YEPirGGrAgMBAAEwDQYJKoZIhvcN -AQEFBQADggEBAAjU7YomUx/U56p1KWHvr1B7oczHF8fPHYbuk5c/N81WOJeSRy+P -5ZGZ2UPjvqqXByv+78YWMKGY1BZ/2doeWuydr0sdSxEwmIUBYxFpujuYY+0AjS/n -mMr1ZijK7TJssteKM7/MClzghUhPweDZrAg3ff1hbhK5QSy+9UPxUqLH44tfYSVC -/BzM6se0p5ToM0bwdsa8TofaBRE1L1IW/Hg4VIGOoKs0R0uLm7+Oot2me2cEuZ6h -Wls6MED8ND1Nz8EAKwndkeDu2iMM+qx/YFp6K8BQ5E5nXd2rbUZUlQMp1WbUlZ87 -KvC98aT0UYIq6uo1Lx/dQvJs7faAkYd4lmE= ------END CERTIFICATE----- diff --git a/keystonemiddleware-moon/examples/pki/cms/auth_token_revoked.json b/keystonemiddleware-moon/examples/pki/cms/auth_token_revoked.json deleted file mode 100644 index 3da8f8bb..00000000 --- a/keystonemiddleware-moon/examples/pki/cms/auth_token_revoked.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "access": { - "token": { - "expires": "2038-01-18T21:14:07Z", - "id": "placeholder", - "tenant": { - "id": "tenant_id1", - "enabled": true, - "description": null, - "name": "tenant_name1" - } - }, - "serviceCatalog": [ - { - "endpoints_links": [], - "endpoints": [ - { - "adminURL": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a", - "region": "regionOne", - "internalURL": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a", - "publicURL": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a" - } - ], - "type": "volume", - "name": "volume" - }, - { - "endpoints_links": [], - "endpoints": [ - { - "adminURL": "http://127.0.0.1:9292/v1", - "region": "regionOne", - "internalURL": "http://127.0.0.1:9292/v1", - "publicURL": "http://127.0.0.1:9292/v1" - } - ], - "type": "image", - "name": "glance" - }, - { - "endpoints_links": [], - "endpoints": [ - { - "adminURL": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a", - "region": "regionOne", - "internalURL": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a", - "publicURL": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a" - } - ], - "type": "compute", - "name": "nova" - }, - { - "endpoints_links": [], - "endpoints": [ - { - "adminURL": "http://127.0.0.1:35357/v2.0", - "region": "RegionOne", - "internalURL": "http://127.0.0.1:35357/v2.0", - "publicURL": "http://127.0.0.1:5000/v2.0" - } - ], - "type": "identity", - "name": "keystone" - } - ], - "user": { - "username": "revoked_username1", - "roles_links": [ - "role1", - "role2" - ], - "id": "revoked_user_id1", - "roles": [ - { - "name": "role1" - }, - { - "name": "role2" - } - ], - "name": "revoked_username1" - } - } -} diff --git a/keystonemiddleware-moon/examples/pki/cms/auth_token_revoked.pem b/keystonemiddleware-moon/examples/pki/cms/auth_token_revoked.pem deleted file mode 100644 index a685a457..00000000 --- a/keystonemiddleware-moon/examples/pki/cms/auth_token_revoked.pem +++ /dev/null @@ -1,75 +0,0 @@ ------BEGIN CMS----- -MIINnQYJKoZIhvcNAQcCoIINjjCCDYoCAQExCTAHBgUrDgMCGjCCC6oGCSqGSIb3 -DQEHAaCCC5sEgguXew0KICAgICJhY2Nlc3MiOiB7DQogICAgICAgICJ0b2tlbiI6 -IHsNCiAgICAgICAgICAgICJleHBpcmVzIjogIjIwMzgtMDEtMThUMjE6MTQ6MDda -IiwNCiAgICAgICAgICAgICJpZCI6ICJwbGFjZWhvbGRlciIsDQogICAgICAgICAg -ICAidGVuYW50Ijogew0KICAgICAgICAgICAgICAgICJpZCI6ICJ0ZW5hbnRfaWQx -IiwNCiAgICAgICAgICAgICAgICAiZW5hYmxlZCI6IHRydWUsDQogICAgICAgICAg -ICAgICAgImRlc2NyaXB0aW9uIjogbnVsbCwNCiAgICAgICAgICAgICAgICAibmFt -ZSI6ICJ0ZW5hbnRfbmFtZTEiDQogICAgICAgICAgICB9DQogICAgICAgIH0sDQog -ICAgICAgICJzZXJ2aWNlQ2F0YWxvZyI6IFsNCiAgICAgICAgICAgIHsNCiAgICAg -ICAgICAgICAgICAiZW5kcG9pbnRzX2xpbmtzIjogW10sDQogICAgICAgICAgICAg -ICAgImVuZHBvaW50cyI6IFsNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAg -ICAgICAgICAgICAgICAgICAgImFkbWluVVJMIjogImh0dHA6Ly8xMjcuMC4wLjE6 -ODc3Ni92MS82NGI2ZjNmYmNjNTM0MzVlOGE2MGZjZjg5YmI2NjE3YSIsDQogICAg -ICAgICAgICAgICAgICAgICAgICAicmVnaW9uIjogInJlZ2lvbk9uZSIsDQogICAg -ICAgICAgICAgICAgICAgICAgICAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzEyNy4w -LjAuMTo4Nzc2L3YxLzY0YjZmM2ZiY2M1MzQzNWU4YTYwZmNmODliYjY2MTdhIiwN -CiAgICAgICAgICAgICAgICAgICAgICAgICJwdWJsaWNVUkwiOiAiaHR0cDovLzEy -Ny4wLjAuMTo4Nzc2L3YxLzY0YjZmM2ZiY2M1MzQzNWU4YTYwZmNmODliYjY2MTdh -Ig0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgXSwNCiAg -ICAgICAgICAgICAgICAidHlwZSI6ICJ2b2x1bWUiLA0KICAgICAgICAgICAgICAg -ICJuYW1lIjogInZvbHVtZSINCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7 -DQogICAgICAgICAgICAgICAgImVuZHBvaW50c19saW5rcyI6IFtdLA0KICAgICAg -ICAgICAgICAgICJlbmRwb2ludHMiOiBbDQogICAgICAgICAgICAgICAgICAgIHsN -CiAgICAgICAgICAgICAgICAgICAgICAgICJhZG1pblVSTCI6ICJodHRwOi8vMTI3 -LjAuMC4xOjkyOTIvdjEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgInJlZ2lv -biI6ICJyZWdpb25PbmUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgImludGVy -bmFsVVJMIjogImh0dHA6Ly8xMjcuMC4wLjE6OTI5Mi92MSIsDQogICAgICAgICAg -ICAgICAgICAgICAgICAicHVibGljVVJMIjogImh0dHA6Ly8xMjcuMC4wLjE6OTI5 -Mi92MSINCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIF0s -DQogICAgICAgICAgICAgICAgInR5cGUiOiAiaW1hZ2UiLA0KICAgICAgICAgICAg -ICAgICJuYW1lIjogImdsYW5jZSINCiAgICAgICAgICAgIH0sDQogICAgICAgICAg -ICB7DQogICAgICAgICAgICAgICAgImVuZHBvaW50c19saW5rcyI6IFtdLA0KICAg -ICAgICAgICAgICAgICJlbmRwb2ludHMiOiBbDQogICAgICAgICAgICAgICAgICAg -IHsNCiAgICAgICAgICAgICAgICAgICAgICAgICJhZG1pblVSTCI6ICJodHRwOi8v -MTI3LjAuMC4xOjg3NzQvdjEuMS82NGI2ZjNmYmNjNTM0MzVlOGE2MGZjZjg5YmI2 -NjE3YSIsDQogICAgICAgICAgICAgICAgICAgICAgICAicmVnaW9uIjogInJlZ2lv -bk9uZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAiaW50ZXJuYWxVUkwiOiAi -aHR0cDovLzEyNy4wLjAuMTo4Nzc0L3YxLjEvNjRiNmYzZmJjYzUzNDM1ZThhNjBm -Y2Y4OWJiNjYxN2EiLA0KICAgICAgICAgICAgICAgICAgICAgICAgInB1YmxpY1VS -TCI6ICJodHRwOi8vMTI3LjAuMC4xOjg3NzQvdjEuMS82NGI2ZjNmYmNjNTM0MzVl -OGE2MGZjZjg5YmI2NjE3YSINCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAg -ICAgICAgICAgIF0sDQogICAgICAgICAgICAgICAgInR5cGUiOiAiY29tcHV0ZSIs -DQogICAgICAgICAgICAgICAgIm5hbWUiOiAibm92YSINCiAgICAgICAgICAgIH0s -DQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgImVuZHBvaW50c19saW5r -cyI6IFtdLA0KICAgICAgICAgICAgICAgICJlbmRwb2ludHMiOiBbDQogICAgICAg -ICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICJhZG1pblVS -TCI6ICJodHRwOi8vMTI3LjAuMC4xOjM1MzU3L3YyLjAiLA0KICAgICAgICAgICAg -ICAgICAgICAgICAgInJlZ2lvbiI6ICJSZWdpb25PbmUiLA0KICAgICAgICAgICAg -ICAgICAgICAgICAgImludGVybmFsVVJMIjogImh0dHA6Ly8xMjcuMC4wLjE6MzUz -NTcvdjIuMCIsDQogICAgICAgICAgICAgICAgICAgICAgICAicHVibGljVVJMIjog -Imh0dHA6Ly8xMjcuMC4wLjE6NTAwMC92Mi4wIg0KICAgICAgICAgICAgICAgICAg -ICB9DQogICAgICAgICAgICAgICAgXSwNCiAgICAgICAgICAgICAgICAidHlwZSI6 -ICJpZGVudGl0eSIsDQogICAgICAgICAgICAgICAgIm5hbWUiOiAia2V5c3RvbmUi -DQogICAgICAgICAgICB9DQogICAgICAgIF0sDQogICAgICAgICJ1c2VyIjogew0K -ICAgICAgICAgICAgInVzZXJuYW1lIjogInJldm9rZWRfdXNlcm5hbWUxIiwNCiAg -ICAgICAgICAgICJyb2xlc19saW5rcyI6IFsNCiAgICAgICAgICAgICAgICAicm9s -ZTEiLA0KICAgICAgICAgICAgICAgICJyb2xlMiINCiAgICAgICAgICAgIF0sDQog -ICAgICAgICAgICAiaWQiOiAicmV2b2tlZF91c2VyX2lkMSIsDQogICAgICAgICAg -ICAicm9sZXMiOiBbDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAg -ICAgICAibmFtZSI6ICJyb2xlMSINCiAgICAgICAgICAgICAgICB9LA0KICAgICAg -ICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgIm5hbWUiOiAicm9sZTIi -DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgXSwNCiAgICAgICAgICAg -ICJuYW1lIjogInJldm9rZWRfdXNlcm5hbWUxIg0KICAgICAgICB9DQogICAgfQ0K -fQ0KMYIByjCCAcYCAQEwgaQwgZ4xCjAIBgNVBAUTATUxCzAJBgNVBAYTAlVTMQsw -CQYDVQQIEwJDQTESMBAGA1UEBxMJU3Vubnl2YWxlMRIwEAYDVQQKEwlPcGVuU3Rh -Y2sxETAPBgNVBAsTCEtleXN0b25lMSUwIwYJKoZIhvcNAQkBFhZrZXlzdG9uZUBv -cGVuc3RhY2sub3JnMRQwEgYDVQQDEwtTZWxmIFNpZ25lZAIBETAHBgUrDgMCGjAN -BgkqhkiG9w0BAQEFAASCAQAxJMbNZf0/IWg/+/ciWQr9yuW9M48hQdaHcN+t6qvZ -OlPev8N1tP8pNTupW9LXt0N8ZU/8AzPLPeRXHqd4lzuDV6ttesfLL3Ag410o4Elb -Aum11Y1kDGlbwnaYoD9m07FML1ZfOWJ81Z0CITVGGRX90e+jlYjtnmdshmi2saVl -r/Sae6ta52gjptaZE9tOu42uXlfhWNuC0/W7lRuWbWSHZENZWtTHHz2Q+v/HxORf -jY3kwSaVEkx9faQ9Npy6J+rSQg+lIMRAYw/rFWedEsP9MzHKBcKTXid0yIQ2ox1r -1Em3WapL1FDpwJtHaaL92WTEQulpxJUcmzPgEd5H78+Q ------END CMS----- diff --git a/keystonemiddleware-moon/examples/pki/cms/auth_token_revoked.pkiz b/keystonemiddleware-moon/examples/pki/cms/auth_token_revoked.pkiz deleted file mode 100644 index 9fbe8ea2..00000000 --- a/keystonemiddleware-moon/examples/pki/cms/auth_token_revoked.pkiz +++ /dev/null @@ -1 +0,0 @@ -PKIZ_eJylVtly4jgUfddXzHuqK9jGED_Mgze8BInYeEF-8wJeBYTF29ePbEh3p9OZycxQRZUtS_eee87Rlb59oz9J1Qz0hwzXw8s3AA1DZxpsPh8CI6tjJFqxfKBjnSLL0pMli5bayo6oS6l7UlIoawUd31qavH7V1kbEAcVSdTGkg4mrpunG3nZmhllUxRzMV7k0N_b0eR8cMespeGNnkSbsjeKQ-tw5j8jiAoK1MTNkk43Ylol8N1_KYh74fBlrwjHa2_3bZOzbl9DnPbdsaGAxD3V7EiuHGix7tUPdtFkW4hU6hynqY3bJ4XbZ4wkuAgLZIMcsZGBv9ch3p9jBTUAQWSlVjgvMAugkmZE3qbE3q4Ct6igfEXWBnxwjln-JyA0VzT4JNuYV--07FGCA8X9QgAHGDxQSg0l7xIy3duQRySHR7WaVP9XQMbgxgTxtV0XKoR7XSaHWABV2jgjuA2IWuHd7pEAmcLIMFRLBLJ6ufDNHBW4Rq-Y7b3KmQSfbjVQN5Br7oAaR7l2oEsOHKiJ2E7HVNdHRLtKqa3iTMtps6EL9JttdtX2kLa6YdXPwb2X7hS8ewKLsBsL-qxLgs8jvA39OLnjPbtmtHGNg9yNhpLpgP6nGgMS7BrpUD4hAzAhn-nCKOxp5cUl26yal-4HCZO4L-Toh6qcWB18kazDXZDQX1f5n6cE_aT9kjom3D33hetP-TnQpXAf5Aa1zgFTFhM-ixVccaA0cXeH6iUWawYKgoGAIKpADJ7D3qpWmslALiqBIeUwMFhUqh29GaxLfpHyhL22m39b7u3LB33qdoDraSEyifWw0G7Y9RuTSg1EOhhGWMm1fAw-0K43wWI-PObt-c-FndgdfkLCn_DCoE1iYT5tfLT-osP5q9_ldcPAx-lebittARaxBUhh0wBQ262GxzcfanQPfrmi9x0QvPyVw4AIMBN4X15S40W10L1RbXTpSB46TjMJoYJ9eoKJeoJO5sFBn0LFmUElCcINNs5HFNRkg085Ds2W0jCoY3-0u8d1B3h8b7G3-QriCYRDenFYGG1TEpGoS7d5UNJ6JtGb4dgxufEyG4LSMXehbrbGf3PbC_WND-1wR-FkdaXRv5KYw1J5s6NGW35DFRDjTJO_6JaCa0gXuW0sbnjujmvwC2awSIpwC396NAW-GG9fcA3j9zwfmvfN29Lyk5ZkfXDoicYzR-kMJTMx63c8Lg00wKFJuOK-_Geo7T2_lfp8D7pPupDDCztFkMT40aaprYqpK0NBK-t9C69DIIlY8y1qojcpA69zIFlYAHdDUxvTcXl1CsdRExlVlCcrWRG3VQrSkFHmSGDuyh5iI8HxCFhS-uoaSOM4FcgZNh5OqqEIT7KMTtNVGacZMS7XJlsGm6hONti9HraAMv99M6MXEFG3sgx_b1hOjIdD-FmhJhC7oVRdKxphJbOHSZb1zkEtO6CfXwKfXH5oMSA1ePDdTRcwOjWL9fFdSJckS6bVHFfF1IvDP-CWbCmXy9NpVu_BpqcRivc16oLGr4hK_vmoz1BDkvSxetosqVk-l6J5X-elhpsFty70GHNfuNX6VQnbGwedWP0pnp9wFMTBTn1wV_hryDJ7He69j2piEh31eh4yyeDTnVnOUqwekOJskWmXPiGm6R-UlY4xz-ZjMe0C6bus-TBfLy45cLuHM19gyW1Df1s5JbjUu1XU3FphSW7XS6UnvrDYL42XW7YvwyD-fOhBCxpuHZbEsrSeTeY6cR3W5TY66RQ4MmmvZUYXRflFI5uuWEecPjMA9If-BMIFQZVOb04E_O0ai7my7iTy3iyjLPXa6O678kDwyBSTepGIrln2AO_U4mzlzS-TU7WP1_DJr_vwTjHdVFSk_7q1_AfJ_mjc= \ No newline at end of file diff --git a/keystonemiddleware-moon/examples/pki/cms/auth_token_scoped.json b/keystonemiddleware-moon/examples/pki/cms/auth_token_scoped.json deleted file mode 100644 index cf18fa18..00000000 --- a/keystonemiddleware-moon/examples/pki/cms/auth_token_scoped.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "access": { - "token": { - "expires": "2038-01-18T21:14:07Z", - "id": "placeholder", - "tenant": { - "id": "tenant_id1", - "enabled": true, - "description": null, - "name": "tenant_name1" - }, - "audit_ids": [ - "SLIXlXQUQZWUi9VJrqdXqA" - ] - }, - "serviceCatalog": [ - { - "endpoints_links": [], - "endpoints": [ - { - "adminURL": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a", - "region": "regionOne", - "internalURL": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a", - "publicURL": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a" - } - ], - "type": "volume", - "name": "volume" - }, - { - "endpoints_links": [], - "endpoints": [ - { - "adminURL": "http://127.0.0.1:9292/v1", - "region": "regionOne", - "internalURL": "http://127.0.0.1:9292/v1", - "publicURL": "http://127.0.0.1:9292/v1" - } - ], - "type": "image", - "name": "glance" - }, - { - "endpoints_links": [], - "endpoints": [ - { - "adminURL": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a", - "region": "regionOne", - "internalURL": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a", - "publicURL": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a" - } - ], - "type": "compute", - "name": "nova" - }, - { - "endpoints_links": [], - "endpoints": [ - { - "adminURL": "http://127.0.0.1:35357/v2.0", - "region": "RegionOne", - "internalURL": "http://127.0.0.1:35357/v2.0", - "publicURL": "http://127.0.0.1:5000/v2.0" - } - ], - "type": "identity", - "name": "keystone" - } - ], - "user": { - "username": "user_name1", - "roles_links": [ - "role1", - "role2" - ], - "id": "user_id1", - "roles": [ - { - "name": "role1" - }, - { - "name": "role2" - } - ], - "name": "user_name1" - } - } -} diff --git a/keystonemiddleware-moon/examples/pki/cms/auth_token_scoped.pem b/keystonemiddleware-moon/examples/pki/cms/auth_token_scoped.pem deleted file mode 100644 index 68f50493..00000000 --- a/keystonemiddleware-moon/examples/pki/cms/auth_token_scoped.pem +++ /dev/null @@ -1,77 +0,0 @@ ------BEGIN CMS----- -MIIN5QYJKoZIhvcNAQcCoIIN1jCCDdICAQExDTALBglghkgBZQMEAgEwggvqBgkq -hkiG9w0BBwGgggvbBIIL13sNCiAgICAiYWNjZXNzIjogew0KICAgICAgICAidG9r -ZW4iOiB7DQogICAgICAgICAgICAiZXhwaXJlcyI6ICIyMDM4LTAxLTE4VDIxOjE0 -OjA3WiIsDQogICAgICAgICAgICAiaWQiOiAicGxhY2Vob2xkZXIiLA0KICAgICAg -ICAgICAgInRlbmFudCI6IHsNCiAgICAgICAgICAgICAgICAiaWQiOiAidGVuYW50 -X2lkMSIsDQogICAgICAgICAgICAgICAgImVuYWJsZWQiOiB0cnVlLA0KICAgICAg -ICAgICAgICAgICJkZXNjcmlwdGlvbiI6IG51bGwsDQogICAgICAgICAgICAgICAg -Im5hbWUiOiAidGVuYW50X25hbWUxIg0KICAgICAgICAgICAgfSwNCiAgICAgICAg -ICAgICJhdWRpdF9pZHMiOiBbDQogICAgICAgICAgICAgICAgIlNMSVhsWFFVUVpX -VWk5VkpycWRYcUEiDQogICAgICAgICAgICBdDQogICAgICAgIH0sDQogICAgICAg -ICJzZXJ2aWNlQ2F0YWxvZyI6IFsNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAg -ICAgICAiZW5kcG9pbnRzX2xpbmtzIjogW10sDQogICAgICAgICAgICAgICAgImVu -ZHBvaW50cyI6IFsNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAg -ICAgICAgICAgICAgImFkbWluVVJMIjogImh0dHA6Ly8xMjcuMC4wLjE6ODc3Ni92 -MS82NGI2ZjNmYmNjNTM0MzVlOGE2MGZjZjg5YmI2NjE3YSIsDQogICAgICAgICAg -ICAgICAgICAgICAgICAicmVnaW9uIjogInJlZ2lvbk9uZSIsDQogICAgICAgICAg -ICAgICAgICAgICAgICAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzEyNy4wLjAuMTo4 -Nzc2L3YxLzY0YjZmM2ZiY2M1MzQzNWU4YTYwZmNmODliYjY2MTdhIiwNCiAgICAg -ICAgICAgICAgICAgICAgICAgICJwdWJsaWNVUkwiOiAiaHR0cDovLzEyNy4wLjAu -MTo4Nzc2L3YxLzY0YjZmM2ZiY2M1MzQzNWU4YTYwZmNmODliYjY2MTdhIg0KICAg -ICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgXSwNCiAgICAgICAg -ICAgICAgICAidHlwZSI6ICJ2b2x1bWUiLA0KICAgICAgICAgICAgICAgICJuYW1l -IjogInZvbHVtZSINCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAg -ICAgICAgICAgICAgImVuZHBvaW50c19saW5rcyI6IFtdLA0KICAgICAgICAgICAg -ICAgICJlbmRwb2ludHMiOiBbDQogICAgICAgICAgICAgICAgICAgIHsNCiAgICAg -ICAgICAgICAgICAgICAgICAgICJhZG1pblVSTCI6ICJodHRwOi8vMTI3LjAuMC4x -OjkyOTIvdjEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgInJlZ2lvbiI6ICJy -ZWdpb25PbmUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgImludGVybmFsVVJM -IjogImh0dHA6Ly8xMjcuMC4wLjE6OTI5Mi92MSIsDQogICAgICAgICAgICAgICAg -ICAgICAgICAicHVibGljVVJMIjogImh0dHA6Ly8xMjcuMC4wLjE6OTI5Mi92MSIN -CiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIF0sDQogICAg -ICAgICAgICAgICAgInR5cGUiOiAiaW1hZ2UiLA0KICAgICAgICAgICAgICAgICJu -YW1lIjogImdsYW5jZSINCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQog -ICAgICAgICAgICAgICAgImVuZHBvaW50c19saW5rcyI6IFtdLA0KICAgICAgICAg -ICAgICAgICJlbmRwb2ludHMiOiBbDQogICAgICAgICAgICAgICAgICAgIHsNCiAg -ICAgICAgICAgICAgICAgICAgICAgICJhZG1pblVSTCI6ICJodHRwOi8vMTI3LjAu -MC4xOjg3NzQvdjEuMS82NGI2ZjNmYmNjNTM0MzVlOGE2MGZjZjg5YmI2NjE3YSIs -DQogICAgICAgICAgICAgICAgICAgICAgICAicmVnaW9uIjogInJlZ2lvbk9uZSIs -DQogICAgICAgICAgICAgICAgICAgICAgICAiaW50ZXJuYWxVUkwiOiAiaHR0cDov -LzEyNy4wLjAuMTo4Nzc0L3YxLjEvNjRiNmYzZmJjYzUzNDM1ZThhNjBmY2Y4OWJi -NjYxN2EiLA0KICAgICAgICAgICAgICAgICAgICAgICAgInB1YmxpY1VSTCI6ICJo -dHRwOi8vMTI3LjAuMC4xOjg3NzQvdjEuMS82NGI2ZjNmYmNjNTM0MzVlOGE2MGZj -Zjg5YmI2NjE3YSINCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAg -ICAgIF0sDQogICAgICAgICAgICAgICAgInR5cGUiOiAiY29tcHV0ZSIsDQogICAg -ICAgICAgICAgICAgIm5hbWUiOiAibm92YSINCiAgICAgICAgICAgIH0sDQogICAg -ICAgICAgICB7DQogICAgICAgICAgICAgICAgImVuZHBvaW50c19saW5rcyI6IFtd -LA0KICAgICAgICAgICAgICAgICJlbmRwb2ludHMiOiBbDQogICAgICAgICAgICAg -ICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICJhZG1pblVSTCI6ICJo -dHRwOi8vMTI3LjAuMC4xOjM1MzU3L3YyLjAiLA0KICAgICAgICAgICAgICAgICAg -ICAgICAgInJlZ2lvbiI6ICJSZWdpb25PbmUiLA0KICAgICAgICAgICAgICAgICAg -ICAgICAgImludGVybmFsVVJMIjogImh0dHA6Ly8xMjcuMC4wLjE6MzUzNTcvdjIu -MCIsDQogICAgICAgICAgICAgICAgICAgICAgICAicHVibGljVVJMIjogImh0dHA6 -Ly8xMjcuMC4wLjE6NTAwMC92Mi4wIg0KICAgICAgICAgICAgICAgICAgICB9DQog -ICAgICAgICAgICAgICAgXSwNCiAgICAgICAgICAgICAgICAidHlwZSI6ICJpZGVu -dGl0eSIsDQogICAgICAgICAgICAgICAgIm5hbWUiOiAia2V5c3RvbmUiDQogICAg -ICAgICAgICB9DQogICAgICAgIF0sDQogICAgICAgICJ1c2VyIjogew0KICAgICAg -ICAgICAgInVzZXJuYW1lIjogInVzZXJfbmFtZTEiLA0KICAgICAgICAgICAgInJv -bGVzX2xpbmtzIjogWw0KICAgICAgICAgICAgICAgICJyb2xlMSIsDQogICAgICAg -ICAgICAgICAgInJvbGUyIg0KICAgICAgICAgICAgXSwNCiAgICAgICAgICAgICJp -ZCI6ICJ1c2VyX2lkMSIsDQogICAgICAgICAgICAicm9sZXMiOiBbDQogICAgICAg -ICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAibmFtZSI6ICJyb2xlMSIN -CiAgICAgICAgICAgICAgICB9LA0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAg -ICAgICAgICAgICAgIm5hbWUiOiAicm9sZTIiDQogICAgICAgICAgICAgICAgfQ0K -ICAgICAgICAgICAgXSwNCiAgICAgICAgICAgICJuYW1lIjogInVzZXJfbmFtZTEi -DQogICAgICAgIH0NCiAgICB9DQp9DQoxggHOMIIBygIBATCBpDCBnjEKMAgGA1UE -BRMBNTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlTdW5ueXZh -bGUxEjAQBgNVBAoTCU9wZW5TdGFjazERMA8GA1UECxMIS2V5c3RvbmUxJTAjBgkq -hkiG9w0BCQEWFmtleXN0b25lQG9wZW5zdGFjay5vcmcxFDASBgNVBAMTC1NlbGYg -U2lnbmVkAgERMAsGCWCGSAFlAwQCATANBgkqhkiG9w0BAQEFAASCAQCgtkCXRzS8 -s7WjZCsKDhMt6q5JQIm7x6EMKCBaOABQG9EOVIAyqfoJDdjDtz9rZEPO3UVTpPkg -VjtA0QV97qT8bX55AcCkk7kBRDOKTtco5GOGwjMxL+GWbIwWiB7DKIP4RA6NLZtF -WxUbLBY+OgBSiayuHqSx+Rd08QC9oHf25wRkTNp3VFPxtAleDmASzdAoIafoS+FB -Po+9WuTaGdeya7S+ms4SSyXf9cdMKGv010R/aMINWUWaBrkB4wlespYLmKH/XzwS -pENRIdbI9XHEOYTWKqul5tucA3p21IA24ND6acl9CXHr3KeqXpRwclSZ38Kg/23T -92D+SowEjlGf ------END CMS----- diff --git a/keystonemiddleware-moon/examples/pki/cms/auth_token_scoped.pkiz b/keystonemiddleware-moon/examples/pki/cms/auth_token_scoped.pkiz deleted file mode 100644 index cbfc0821..00000000 --- a/keystonemiddleware-moon/examples/pki/cms/auth_token_scoped.pkiz +++ /dev/null @@ -1 +0,0 @@ -PKIZ_eJylVkuXojgY3edXzL5OnwLUKlnMgrdBwAJDgOx4KK-gVimC_PoJWFVdM93z6DNuNEFu7nfv98i3b-wjawZ0flPs7bj4BmwIV8s8MtdHAotr6khuqhzZ3nxQFFlcKpKr9SqSLDmneVHnMnFtTcq1Ls_DmZzXr6CoS0PsOFnujJxtHmUI9cXqXEaBU5HQGWB1zHc3k0uEC01K-ATZMxIWXRyaNL3BJwAVeLNVe24hqbeQNscq7DeVxm0qaRaU8AwV80QU9qJidomhVyQoronh0fT-jAMkWBTJwS03pfwMG9xGgXkmwbTm0gOmliKV8bSWyswYny-4UKC1vZ0AWhAFPB1pwoNHk0ZvM11sx733P9QsjCptaJcZ9DqFYCz4xOjFETgKcQ3i0NvHgTfFGtxMhDQaJXrhYazHmMenDSbr9KDXwUqXIeWnF1MB37KGVsR3CpAZ-jkR0pFywsRiLLwuEWibreyPvYIY_CmheIvuWhyzlddtyuXVRnAGrEpqbWXOhMtnzhBds0q7OpVXOk00kMasosEfHNXmCSoKp5KbSIjmm8AsnSrqHUErwUSpwYc4ENu7FiYlAou3Flty1-GUMH3Shomt_8gCjDT-Dwsw0phYrHCZGLTC2LQnJk3BZSvpybote7tKxwM6q9KeNmo6c0pRsLdLwTGgAEjFzmmcykE2Zw-YbgxNsA1SkSpfRA0UnEqbRVtTDLddPuYJWcnXmOVCyotn9v0GxnSE-iUbWWQr2rG4xxiFROj5JPAndiw_Ln_d3zPA0TXwq7Z916u-bRC8AiZY-X-cAH-H_An8L-KCT3URXNiTun8v2M_0AhO9QD-8U20_i6vJzqzyKsIALeVeqZ-AdyC2p9cgCWj7n7xXRnbz3hoiLqpIYwukjASbB_bgDk7gzyMUdaRxmo1Ky6hij1BWwLL7Lmg5CXcjQXZKhMVL0twtBiMlEo7Ue-zX3dQ44pXHperxag3azbmNLJjA6Dh3hpSzZlFvfUl18F8q7p_cAL8S78_CBZ_xHvjJHtYj69QQx8QZQqE_Jc3l3q14bmqiu1B-d8m5JqHMs470Q763yYwwQPbC2MK_AE5As7Hlexem3aQZ-AfRBlahvHNj4ZTz7ieObEdHwFdLfsGRT3DwHV3mo6Y_Rfy_VaHf2arEagWytSmCX8n7aUqx4cJmBLf7YbA0F7oLHTYDF_TDkSx0xhE2zcPp91jOrJlMU2pcU_EO8D6Fbqzb0D8zOLM-IZ4J-ugZ429Y3lnTejwYwAMemHBsOrn9u9JseOJPy77YOx1gf1bnnc1k4wfyHnN_Lul38AmEsdiHvGhHUB4qRZHS43h36EAeu11O5r1SSVDOHSxLPpKQ3yuDZN7XEZIoRrZ77hQ3UrHrQq0zVRdpW1uWDCDxvib3tunPcJscqMBygNoe7DRp-vNa6-hLypT3Z14RCedeQ9LLHfiMFO1CwYfy9tbvYPf1qlPLekHeSEiHzGDN1ZevI1B6B2Lpbh5sz-2Alk8nqVp3QSToG6g7J8IACYtI-8ndSHW_HqLJQHYlLc81aX3lauEoClh6VuT6CVmW_Xx4cUKMVpistrF-8znERbl2fHvMwv1Zg7ipXuENxJolYFGlM8EwxIGkw0pI51zZPri711NwFfOy9-h2eDMzXGe6HAtPSqjDtyZSZq0lXBUA-dVBNQ9FszxyDqe-1DG0sq2P0nb_-vCoLDptv3s43RpcnC1-vVPWh6J_uR7D1-xVklHsgVJt1t5DSq3mbKql9HradSuMTCoWQ_HywKdLk7-01l5nbWlbqI8WXjxrwgYhdFwe0MF9AUVO9lb9XD9JQ2Ku-TjaCYawm8_np5i1w2pmP9qSdKH5rttzT12SxPlSXOs3xXe0U6N6BnD2jNsSSlK1ffBnwirm-se3_a7NcLsk-e-_g-lCqznq98vtH9MPoOI= \ No newline at end of file diff --git a/keystonemiddleware-moon/examples/pki/cms/auth_token_scoped_expired.json b/keystonemiddleware-moon/examples/pki/cms/auth_token_scoped_expired.json deleted file mode 100644 index 04ec9f30..00000000 --- a/keystonemiddleware-moon/examples/pki/cms/auth_token_scoped_expired.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "access": { - "token": { - "expires": "2010-06-02T14:47:34Z", - "id": "placeholder", - "tenant": { - "id": "tenant_id1", - "enabled": true, - "description": null, - "name": "tenant_name1" - } - }, - "serviceCatalog": [ - { - "endpoints_links": [], - "endpoints": [ - { - "adminURL": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a", - "region": "regionOne", - "internalURL": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a", - "publicURL": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a" - } - ], - "type": "volume", - "name": "volume" - }, - { - "endpoints_links": [], - "endpoints": [ - { - "adminURL": "http://127.0.0.1:9292/v1", - "region": "regionOne", - "internalURL": "http://127.0.0.1:9292/v1", - "publicURL": "http://127.0.0.1:9292/v1" - } - ], - "type": "image", - "name": "glance" - }, - { - "endpoints_links": [], - "endpoints": [ - { - "adminURL": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a", - "region": "regionOne", - "internalURL": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a", - "publicURL": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a" - } - ], - "type": "compute", - "name": "nova" - }, - { - "endpoints_links": [], - "endpoints": [ - { - "adminURL": "http://127.0.0.1:35357/v2.0", - "region": "RegionOne", - "internalURL": "http://127.0.0.1:35357/v2.0", - "publicURL": "http://127.0.0.1:5000/v2.0" - } - ], - "type": "identity", - "name": "keystone" - } - ], - "user": { - "username": "user_name1", - "roles_links": [ - "role1", - "role2" - ], - "id": "user_id1", - "roles": [ - { - "name": "role1" - }, - { - "name": "role2" - } - ], - "name": "user_name1" - } - } -} diff --git a/keystonemiddleware-moon/examples/pki/cms/auth_token_scoped_expired.pem b/keystonemiddleware-moon/examples/pki/cms/auth_token_scoped_expired.pem deleted file mode 100644 index c3de8bbe..00000000 --- a/keystonemiddleware-moon/examples/pki/cms/auth_token_scoped_expired.pem +++ /dev/null @@ -1,75 +0,0 @@ ------BEGIN CMS----- -MIINhwYJKoZIhvcNAQcCoIINeDCCDXQCAQExCTAHBgUrDgMCGjCCC5QGCSqGSIb3 -DQEHAaCCC4UEgguBew0KICAgICJhY2Nlc3MiOiB7DQogICAgICAgICJ0b2tlbiI6 -IHsNCiAgICAgICAgICAgICJleHBpcmVzIjogIjIwMTAtMDYtMDJUMTQ6NDc6MzRa -IiwNCiAgICAgICAgICAgICJpZCI6ICJwbGFjZWhvbGRlciIsDQogICAgICAgICAg -ICAidGVuYW50Ijogew0KICAgICAgICAgICAgICAgICJpZCI6ICJ0ZW5hbnRfaWQx -IiwNCiAgICAgICAgICAgICAgICAiZW5hYmxlZCI6IHRydWUsDQogICAgICAgICAg -ICAgICAgImRlc2NyaXB0aW9uIjogbnVsbCwNCiAgICAgICAgICAgICAgICAibmFt -ZSI6ICJ0ZW5hbnRfbmFtZTEiDQogICAgICAgICAgICB9DQogICAgICAgIH0sDQog -ICAgICAgICJzZXJ2aWNlQ2F0YWxvZyI6IFsNCiAgICAgICAgICAgIHsNCiAgICAg -ICAgICAgICAgICAiZW5kcG9pbnRzX2xpbmtzIjogW10sDQogICAgICAgICAgICAg -ICAgImVuZHBvaW50cyI6IFsNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAg -ICAgICAgICAgICAgICAgICAgImFkbWluVVJMIjogImh0dHA6Ly8xMjcuMC4wLjE6 -ODc3Ni92MS82NGI2ZjNmYmNjNTM0MzVlOGE2MGZjZjg5YmI2NjE3YSIsDQogICAg -ICAgICAgICAgICAgICAgICAgICAicmVnaW9uIjogInJlZ2lvbk9uZSIsDQogICAg -ICAgICAgICAgICAgICAgICAgICAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzEyNy4w -LjAuMTo4Nzc2L3YxLzY0YjZmM2ZiY2M1MzQzNWU4YTYwZmNmODliYjY2MTdhIiwN -CiAgICAgICAgICAgICAgICAgICAgICAgICJwdWJsaWNVUkwiOiAiaHR0cDovLzEy -Ny4wLjAuMTo4Nzc2L3YxLzY0YjZmM2ZiY2M1MzQzNWU4YTYwZmNmODliYjY2MTdh -Ig0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgXSwNCiAg -ICAgICAgICAgICAgICAidHlwZSI6ICJ2b2x1bWUiLA0KICAgICAgICAgICAgICAg -ICJuYW1lIjogInZvbHVtZSINCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7 -DQogICAgICAgICAgICAgICAgImVuZHBvaW50c19saW5rcyI6IFtdLA0KICAgICAg -ICAgICAgICAgICJlbmRwb2ludHMiOiBbDQogICAgICAgICAgICAgICAgICAgIHsN -CiAgICAgICAgICAgICAgICAgICAgICAgICJhZG1pblVSTCI6ICJodHRwOi8vMTI3 -LjAuMC4xOjkyOTIvdjEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgInJlZ2lv -biI6ICJyZWdpb25PbmUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgImludGVy -bmFsVVJMIjogImh0dHA6Ly8xMjcuMC4wLjE6OTI5Mi92MSIsDQogICAgICAgICAg -ICAgICAgICAgICAgICAicHVibGljVVJMIjogImh0dHA6Ly8xMjcuMC4wLjE6OTI5 -Mi92MSINCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIF0s -DQogICAgICAgICAgICAgICAgInR5cGUiOiAiaW1hZ2UiLA0KICAgICAgICAgICAg -ICAgICJuYW1lIjogImdsYW5jZSINCiAgICAgICAgICAgIH0sDQogICAgICAgICAg -ICB7DQogICAgICAgICAgICAgICAgImVuZHBvaW50c19saW5rcyI6IFtdLA0KICAg -ICAgICAgICAgICAgICJlbmRwb2ludHMiOiBbDQogICAgICAgICAgICAgICAgICAg -IHsNCiAgICAgICAgICAgICAgICAgICAgICAgICJhZG1pblVSTCI6ICJodHRwOi8v -MTI3LjAuMC4xOjg3NzQvdjEuMS82NGI2ZjNmYmNjNTM0MzVlOGE2MGZjZjg5YmI2 -NjE3YSIsDQogICAgICAgICAgICAgICAgICAgICAgICAicmVnaW9uIjogInJlZ2lv -bk9uZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAiaW50ZXJuYWxVUkwiOiAi -aHR0cDovLzEyNy4wLjAuMTo4Nzc0L3YxLjEvNjRiNmYzZmJjYzUzNDM1ZThhNjBm -Y2Y4OWJiNjYxN2EiLA0KICAgICAgICAgICAgICAgICAgICAgICAgInB1YmxpY1VS -TCI6ICJodHRwOi8vMTI3LjAuMC4xOjg3NzQvdjEuMS82NGI2ZjNmYmNjNTM0MzVl -OGE2MGZjZjg5YmI2NjE3YSINCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAg -ICAgICAgICAgIF0sDQogICAgICAgICAgICAgICAgInR5cGUiOiAiY29tcHV0ZSIs -DQogICAgICAgICAgICAgICAgIm5hbWUiOiAibm92YSINCiAgICAgICAgICAgIH0s -DQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgImVuZHBvaW50c19saW5r -cyI6IFtdLA0KICAgICAgICAgICAgICAgICJlbmRwb2ludHMiOiBbDQogICAgICAg -ICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICJhZG1pblVS -TCI6ICJodHRwOi8vMTI3LjAuMC4xOjM1MzU3L3YyLjAiLA0KICAgICAgICAgICAg -ICAgICAgICAgICAgInJlZ2lvbiI6ICJSZWdpb25PbmUiLA0KICAgICAgICAgICAg -ICAgICAgICAgICAgImludGVybmFsVVJMIjogImh0dHA6Ly8xMjcuMC4wLjE6MzUz -NTcvdjIuMCIsDQogICAgICAgICAgICAgICAgICAgICAgICAicHVibGljVVJMIjog -Imh0dHA6Ly8xMjcuMC4wLjE6NTAwMC92Mi4wIg0KICAgICAgICAgICAgICAgICAg -ICB9DQogICAgICAgICAgICAgICAgXSwNCiAgICAgICAgICAgICAgICAidHlwZSI6 -ICJpZGVudGl0eSIsDQogICAgICAgICAgICAgICAgIm5hbWUiOiAia2V5c3RvbmUi -DQogICAgICAgICAgICB9DQogICAgICAgIF0sDQogICAgICAgICJ1c2VyIjogew0K -ICAgICAgICAgICAgInVzZXJuYW1lIjogInVzZXJfbmFtZTEiLA0KICAgICAgICAg -ICAgInJvbGVzX2xpbmtzIjogWw0KICAgICAgICAgICAgICAgICJyb2xlMSIsDQog -ICAgICAgICAgICAgICAgInJvbGUyIg0KICAgICAgICAgICAgXSwNCiAgICAgICAg -ICAgICJpZCI6ICJ1c2VyX2lkMSIsDQogICAgICAgICAgICAicm9sZXMiOiBbDQog -ICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAibmFtZSI6ICJy -b2xlMSINCiAgICAgICAgICAgICAgICB9LA0KICAgICAgICAgICAgICAgIHsNCiAg -ICAgICAgICAgICAgICAgICAgIm5hbWUiOiAicm9sZTIiDQogICAgICAgICAgICAg -ICAgfQ0KICAgICAgICAgICAgXSwNCiAgICAgICAgICAgICJuYW1lIjogInVzZXJf -bmFtZTEiDQogICAgICAgIH0NCiAgICB9DQp9DQoxggHKMIIBxgIBATCBpDCBnjEK -MAgGA1UEBRMBNTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlT -dW5ueXZhbGUxEjAQBgNVBAoTCU9wZW5TdGFjazERMA8GA1UECxMIS2V5c3RvbmUx -JTAjBgkqhkiG9w0BCQEWFmtleXN0b25lQG9wZW5zdGFjay5vcmcxFDASBgNVBAMT -C1NlbGYgU2lnbmVkAgERMAcGBSsOAwIaMA0GCSqGSIb3DQEBAQUABIIBALYxBjRE -hecjo98fUdki3cwcpGU8zY8XHQa4x15WGkPxkI1HwSYaId/WjrOWP2CxmT3vVe7Z -lqV2a0YmdPx9zdDm09VmoiZr3HxYaNzXztT817dECYINCgz33EnansIyPHG2hjOR -4Gt7R26MXf+AIRiCNuCFZPnHI1pfCbwuky9/iBokvE9mThA+bVrUPZd/2+jp4s3B -n3+fbC+FCoZ5t522wGgEtVyMNvC90Wvvuf2mx7baXNo4/0ZG8C86lT+qmMe22zlf -+DxmJl149p419zdv6rzTU7p2OeTBnkdw1GsEqKyvtHYxzAjLYjiJo6jyaERXBaLm -/J7ZRSBmhHoLuWk= ------END CMS----- diff --git a/keystonemiddleware-moon/examples/pki/cms/auth_token_scoped_expired.pkiz b/keystonemiddleware-moon/examples/pki/cms/auth_token_scoped_expired.pkiz deleted file mode 100644 index 766b4cdd..00000000 --- a/keystonemiddleware-moon/examples/pki/cms/auth_token_scoped_expired.pkiz +++ /dev/null @@ -1 +0,0 @@ -PKIZ_eJylVtlyozgUfddXzHuqK2xOzCObMdiSzW7pzUCMwchLbNavH4GT6kmnM5OZcZWrQEhH555z75V-_GA_1TAt9IcGveHlB4CWNW8cbC9OxNrXCVKcRDuxsWuhaeqTpCmO0Wq-Mlez4FXPoGYO44lkat7F9KxYBLpjzJUtG4ynRpZFzy-dvccCKhMR5qtcfbaO7PlIzlgIdbxx97EpH63ilEXiNY_p7AaIZz1Zmi3EQsvHUZAvNSUn0eSQmPI5Prr9-2QcubdtNAmDQ8OAlXw7d7lEP9Vg2Rsd6qRmWSgV9E8S6hNhKeJ22WMOF4RCgeRYgDzsnR5FgYR93BCK6Eovc1xgAUA_3Vt5k1lHuyRCWcf5yKgjUXqOhck6pndWbHeObOwKR-0HFmCg8X9YgIHGTxYqj2l7xnzo-drI5JTO3WaVT2voW-K4gSa1qyITUY_rtDBqgAo3RxT3hNoF7oMe6ZAn_n6PCpViAUuryM5RgVskGPku5K4MlHvZqOUgrnUkNYjn4Y05MXwoY-o2sVBW6RztYrOstncr482GLZzfbXtz7RibswoLQQ7-rW2_6DUBsDh0g2D_1QnwFfJH4K_FBR_VPXQr3xrU_SwYLW84SssRkIYVmav1wAgkvHxlD69Jx5Bnt3TnNRmrB0aTf1s4qVNqfJni4JtiDcnFjcnFvP-r9eCfvB92Tmh43EZydff-TeiDXA32AxbnQKlM6GQfz76Tgc6gUQW9qYBMSwCkYGQoKpAPOdiH5co0BGiSghTZBFNLQIUh4nuiNWlkM73Qt4rpt_H-Llzwt7lOUR1vVD41PzeajdCeY3rrwWgHz8tLjbWvQQfWlUZ6QjhJRLd-z8Kv0h18w8Ke6cOjThZgLjW_pvzggvfd7vM7cPAZ_btNJWigrtQgLSw2YMsbb1jsThLzTYPILVm853R--FLAQQswCPi2uGbCjdnGaqF8matnloHjJKuwGugrN6hj9rcD6DtPSE-eYO9uwZ02243OqnSgzDoP223PwijJ-O52aRQM9v4ssPf5M7kCwyC8Z9qBbFCR0LJJzbemYk742GyGb2dy14MbwFkYu23ktNaRu9fC28eG9bmCRPs6Nllt5LY8xJ5u2NGW35klVL6yTT70S8A8ZQuC95Y2PHdWyf1COeyZrbuxqfrvFTqAwRwMKB8ayDvg8VMn7tj5WcL83bER9K7BV7uwOEdLxzBK-Ux0Vi8bXobYUjt2zCsJ1gA7_5ts6zQZkVqtUCw1Q6GqBL7iB63WK_b9HftKGfrQuTaag_XQcSyjsXXHNzwAVcVU-MBQW2gHYljFx1JgKVxC12oMZZy8MJpynZhhFYguuztcW8NX1nfgqw8041a-bBDHaoHZGTRW89fbykGd7ckr2ZR9arIWFqj1AJTcgapYtI8Auk5jZONOutHcfBK11JqhM2GAhEVkfLjeKEjNDpf9ITflhlNZ-DOgKB67B2niTXTXpH1IYeWIT09VZWNhm5pu_7LFotenk40hKN5tMWmeLuGz5F_p9Lw8CZct2Exj5Vhc1ig3oPTgy6G0cGOnnYclRPPLjp6a5elZauAxWJk7U3pep74japd2cbW6ykoJIP5aWuX7hwdztjNlszcnrfuwmnC8LJSzZ11Osktpha621jm0Jdw6epycXy3yWK5odqWiC66rXBCk-CJeBffxOaJazV2mNJhOt4l2eFXI3o0Wt2oBV3SWRiePSlr56B_UY9dRTz2YEvCb9bK-zFdQrRHO5cuZqx5fIiHT1CZ3-SQq7Cpz7MNRvjxORbSpQnmy7B7YRZI_16hsr-B6Pb2IF9vVHjxzkSbJLjhEi9h4DOIVBeNd1ED6z3vpnxbOkgI= \ No newline at end of file diff --git a/keystonemiddleware-moon/examples/pki/cms/auth_token_unscoped.json b/keystonemiddleware-moon/examples/pki/cms/auth_token_unscoped.json deleted file mode 100644 index 41566888..00000000 --- a/keystonemiddleware-moon/examples/pki/cms/auth_token_unscoped.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "access": { - "token": { - "expires": "2112-08-17T15:35:34Z", - "id": "01e032c996ef4406b144335915a41e79" - }, - "serviceCatalog": {}, - "user": { - "username": "user_name1", - "roles_links": [], - "id": "c9c89e3be3ee453fbf00c7966f6d3fbd", - "roles": [ - { - "name": "role1" - }, - { - "name": "role2" - } - ], - "name": "user_name1" - } - } -} diff --git a/keystonemiddleware-moon/examples/pki/cms/auth_token_unscoped.pem b/keystonemiddleware-moon/examples/pki/cms/auth_token_unscoped.pem deleted file mode 100644 index 6855221f..00000000 --- a/keystonemiddleware-moon/examples/pki/cms/auth_token_unscoped.pem +++ /dev/null @@ -1,25 +0,0 @@ ------BEGIN CMS----- -MIIERgYJKoZIhvcNAQcCoIIENzCCBDMCAQExCTAHBgUrDgMCGjCCAlMGCSqGSIb3 -DQEHAaCCAkQEggJAew0KICAgICJhY2Nlc3MiOiB7DQogICAgICAgICJ0b2tlbiI6 -IHsNCiAgICAgICAgICAgICJleHBpcmVzIjogIjIxMTItMDgtMTdUMTU6MzU6MzRa -IiwNCiAgICAgICAgICAgICJpZCI6ICIwMWUwMzJjOTk2ZWY0NDA2YjE0NDMzNTkx -NWE0MWU3OSINCiAgICAgICAgfSwNCiAgICAgICAgInNlcnZpY2VDYXRhbG9nIjog -e30sDQogICAgICAgICJ1c2VyIjogew0KICAgICAgICAgICAgInVzZXJuYW1lIjog -InVzZXJfbmFtZTEiLA0KICAgICAgICAgICAgInJvbGVzX2xpbmtzIjogW10sDQog -ICAgICAgICAgICAiaWQiOiAiYzljODllM2JlM2VlNDUzZmJmMDBjNzk2NmY2ZDNm -YmQiLA0KICAgICAgICAgICAgInJvbGVzIjogWw0KICAgICAgICAgICAgICAgIHsN -CiAgICAgICAgICAgICAgICAgICAgIm5hbWUiOiAicm9sZTEiDQogICAgICAgICAg -ICAgICAgfSwNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAg -ICJuYW1lIjogInJvbGUyIg0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAg -IF0sDQogICAgICAgICAgICAibmFtZSI6ICJ1c2VyX25hbWUxIg0KICAgICAgICB9 -DQogICAgfQ0KfQ0KMYIByjCCAcYCAQEwgaQwgZ4xCjAIBgNVBAUTATUxCzAJBgNV -BAYTAlVTMQswCQYDVQQIEwJDQTESMBAGA1UEBxMJU3Vubnl2YWxlMRIwEAYDVQQK -EwlPcGVuU3RhY2sxETAPBgNVBAsTCEtleXN0b25lMSUwIwYJKoZIhvcNAQkBFhZr -ZXlzdG9uZUBvcGVuc3RhY2sub3JnMRQwEgYDVQQDEwtTZWxmIFNpZ25lZAIBETAH -BgUrDgMCGjANBgkqhkiG9w0BAQEFAASCAQAXNWXYv3q2EcEjigKDJEOvnKBGTHeV -o9iwYmtdJ2kKtbuZiSGOcWymxNtv//IPMmNDWZ/uwDZt37YdPwCMRJa79h6dastD -5slEZGMxgFekm/1yqpV2F7xGqGIED2rNTeBlVnYS6ZOL8hCqekPb1OqXZ3vDaHtQ -rrBzNP8RbWS4MyUoVZtSEYANjJVp/zou/pYASml9iNPPKrl2xRgYuzaAirVIiTZt -QZY4LQYnHdVBLTZ0fQQugohTba789ix0U79ReQrIOqnBD3OnmN0uRovu5s1HYyre -c67FixOpNgA4IBFsqYG2feP6ZF1zCmAaRYX4LpprZLGzg/aPHxqjXGsT ------END CMS----- diff --git a/keystonemiddleware-moon/examples/pki/cms/auth_token_unscoped.pkiz b/keystonemiddleware-moon/examples/pki/cms/auth_token_unscoped.pkiz deleted file mode 100644 index 13c5e40c..00000000 --- a/keystonemiddleware-moon/examples/pki/cms/auth_token_unscoped.pkiz +++ /dev/null @@ -1 +0,0 @@ -PKIZ_eJx9VMmSozgQvfMVfa-oMAbbVRzmIAlZCFvQGLHewAs72MaY5esHuzt65tSKUEiZkS_z5RL5-TkfiAk1fiBmv4RPgVGq7kCg75qQps-jAawjamYd4QiBwUHAwgPiQIOJc1cThkg-67lDkH0jNo1lQbWwBqJZaQc4SXB2HvU0kIzyKLPMzOAXred_HV4DyVUD_5DGRKlp3iRnWWwp0kUhlh5lnNEN1dos9NM-8vXyOM4yoiPjeNxzsNpzLLsqXpo5e13Ry-gLfA0R3QizYc88p2eTnpu8kEIvEA0VSEGO55dNBi8Gw8PibCObtq7sEchO_szqd1DhWClt6BuXmJRd9It27Nt9Qqt1GnvOLP8GlEoXeMuS2e_oYywNb6YC3T6-_m_8dshxdpmdzPV4g14501p_xsQZab08_WEx44S_RHnnOL-56bGV6TlTUDlT6DmiwY0qqIKeESYLJg-kMA8LJoVZiHTl4otDkmi7ub1wSCgEHMGrimCd4x0DCQFLB8MDgwbHewYKIrwVKUOuywY0AR0mhgtBwkFhQHagPQaB6lqWhvuSn7x1d_bDuZXOgHNgvWwFCBqOHKUPvTU_kW0eTfjAwPc7EhoYtSV3fZQPz7hyBp2DHCbFLS0yovQiRBb2hG31KM--IcbSurTI29H0djSun8fqOGxVYP9ixThaGmVMgsSRyjqu3AIk-CAwcCTQbk3Q04gB8c-IzhMKgeUAONcCbO8atS73i3mAGF0iWEaZWKcHN11FAj1_r8a1F5ZGKDWGyD468ZlOstqwRb1jnp5-5fK-M-cJvXSTbE6Vxqs4Sg9dUQdNcSuE_Cfc3JzH-fqxLruP-wpoqpNGV9iP8lMuzsmGtUkY1PCeUyJHQ7Nl2vfJslSkKOoJWpOw21fD1JDztsjbyx27Hw95icVWut-JOC6a_SUK-k1AmpUrNtpjm3T5osNNEn608g1lsSOgZBVvppgUhx2vm-5ate56rZynjSgam_tr6J7awn9y4n5Lth48bJRdy6Wx8m52ju7IE1Z-G92-ldZegIXrbm6gHJuBT63Ss1g3be9i5-ZTVotYxMm5WNrPXaB2_PpzsPt_hPdKwYb633r5FzKfcIU= \ No newline at end of file diff --git a/keystonemiddleware-moon/examples/pki/cms/auth_v3_token_revoked.json b/keystonemiddleware-moon/examples/pki/cms/auth_v3_token_revoked.json deleted file mode 100644 index c5dc01a9..00000000 --- a/keystonemiddleware-moon/examples/pki/cms/auth_v3_token_revoked.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "token": { - "catalog": [ - { - "endpoints": [ - { - "adminURL": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a", - "region": "regionOne", - "internalURL": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a", - "publicURL": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a" - } - ], - "endpoints_links": [], - "type": "volume", - "name": "volume" - }, - { - "endpoints": [ - { - "adminURL": "http://127.0.0.1:9292/v1", - "region": "regionOne", - "internalURL": "http://127.0.0.1:9292/v1", - "publicURL": "http://127.0.0.1:9292/v1" - } - ], - "endpoints_links": [], - "type": "image", - "name": "glance" - }, - { - "endpoints": [ - { - "adminURL": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a", - "region": "regionOne", - "internalURL": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a", - "publicURL": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a" - } - ], - "endpoints_links": [], - "type": "compute", - "name": "nova" - }, - { - "endpoints": [ - { - "adminURL": "http://127.0.0.1:35357/v3", - "region": "RegionOne", - "internalURL": "http://127.0.0.1:35357/v3", - "publicURL": "http://127.0.0.1:5000/v3" - } - ], - "endpoints_links": [], - "type": "identity", - "name": "keystone" - } - ], - "expires_at": "2038-01-18T21:14:07Z", - "project": { - "enabled": true, - "description": null, - "name": "tenant_name1", - "id": "tenant_id1", - "domain": { - "id": "domain_id1", - "name": "domain_name1" - } - }, - "user": { - "name": "revoked_username1", - "id": "revoked_user_id1", - "domain": { - "id": "domain_id1", - "name": "domain_name1" - } - }, - "roles": [ - { - "name": "role1" - }, - { - "name": "role2" - } - ], - "methods": [ - "password" - ] - } -} diff --git a/keystonemiddleware-moon/examples/pki/cms/auth_v3_token_revoked.pem b/keystonemiddleware-moon/examples/pki/cms/auth_v3_token_revoked.pem deleted file mode 100644 index 94a077ba..00000000 --- a/keystonemiddleware-moon/examples/pki/cms/auth_v3_token_revoked.pem +++ /dev/null @@ -1,76 +0,0 @@ ------BEGIN CMS----- -MIINrQYJKoZIhvcNAQcCoIINnjCCDZoCAQExCTAHBgUrDgMCGjCCC7oGCSqGSIb3 -DQEHAaCCC6sEggunew0KICAgICJ0b2tlbiI6IHsNCiAgICAgICAgImNhdGFsb2ci -OiBbDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgImVuZHBvaW50cyI6 -IFsNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAg -ICAgImFkbWluVVJMIjogImh0dHA6Ly8xMjcuMC4wLjE6ODc3Ni92MS82NGI2ZjNm -YmNjNTM0MzVlOGE2MGZjZjg5YmI2NjE3YSIsDQogICAgICAgICAgICAgICAgICAg -ICAgICAicmVnaW9uIjogInJlZ2lvbk9uZSIsDQogICAgICAgICAgICAgICAgICAg -ICAgICAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzEyNy4wLjAuMTo4Nzc2L3YxLzY0 -YjZmM2ZiY2M1MzQzNWU4YTYwZmNmODliYjY2MTdhIiwNCiAgICAgICAgICAgICAg -ICAgICAgICAgICJwdWJsaWNVUkwiOiAiaHR0cDovLzEyNy4wLjAuMTo4Nzc2L3Yx -LzY0YjZmM2ZiY2M1MzQzNWU4YTYwZmNmODliYjY2MTdhIg0KICAgICAgICAgICAg -ICAgICAgICB9DQogICAgICAgICAgICAgICAgXSwNCiAgICAgICAgICAgICAgICAi -ZW5kcG9pbnRzX2xpbmtzIjogW10sDQogICAgICAgICAgICAgICAgInR5cGUiOiAi -dm9sdW1lIiwNCiAgICAgICAgICAgICAgICAibmFtZSI6ICJ2b2x1bWUiDQogICAg -ICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJlbmRw -b2ludHMiOiBbDQogICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAg -ICAgICAgICAgICJhZG1pblVSTCI6ICJodHRwOi8vMTI3LjAuMC4xOjkyOTIvdjEi -LA0KICAgICAgICAgICAgICAgICAgICAgICAgInJlZ2lvbiI6ICJyZWdpb25PbmUi -LA0KICAgICAgICAgICAgICAgICAgICAgICAgImludGVybmFsVVJMIjogImh0dHA6 -Ly8xMjcuMC4wLjE6OTI5Mi92MSIsDQogICAgICAgICAgICAgICAgICAgICAgICAi -cHVibGljVVJMIjogImh0dHA6Ly8xMjcuMC4wLjE6OTI5Mi92MSINCiAgICAgICAg -ICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIF0sDQogICAgICAgICAgICAg -ICAgImVuZHBvaW50c19saW5rcyI6IFtdLA0KICAgICAgICAgICAgICAgICJ0eXBl -IjogImltYWdlIiwNCiAgICAgICAgICAgICAgICAibmFtZSI6ICJnbGFuY2UiDQog -ICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJl -bmRwb2ludHMiOiBbDQogICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAg -ICAgICAgICAgICAgICJhZG1pblVSTCI6ICJodHRwOi8vMTI3LjAuMC4xOjg3NzQv -djEuMS82NGI2ZjNmYmNjNTM0MzVlOGE2MGZjZjg5YmI2NjE3YSIsDQogICAgICAg -ICAgICAgICAgICAgICAgICAicmVnaW9uIjogInJlZ2lvbk9uZSIsDQogICAgICAg -ICAgICAgICAgICAgICAgICAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzEyNy4wLjAu -MTo4Nzc0L3YxLjEvNjRiNmYzZmJjYzUzNDM1ZThhNjBmY2Y4OWJiNjYxN2EiLA0K -ICAgICAgICAgICAgICAgICAgICAgICAgInB1YmxpY1VSTCI6ICJodHRwOi8vMTI3 -LjAuMC4xOjg3NzQvdjEuMS82NGI2ZjNmYmNjNTM0MzVlOGE2MGZjZjg5YmI2NjE3 -YSINCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIF0sDQog -ICAgICAgICAgICAgICAgImVuZHBvaW50c19saW5rcyI6IFtdLA0KICAgICAgICAg -ICAgICAgICJ0eXBlIjogImNvbXB1dGUiLA0KICAgICAgICAgICAgICAgICJuYW1l -IjogIm5vdmEiDQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAg -ICAgICAgICAgICJlbmRwb2ludHMiOiBbDQogICAgICAgICAgICAgICAgICAgIHsN -CiAgICAgICAgICAgICAgICAgICAgICAgICJhZG1pblVSTCI6ICJodHRwOi8vMTI3 -LjAuMC4xOjM1MzU3L3YzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICJyZWdp -b24iOiAiUmVnaW9uT25lIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICJpbnRl -cm5hbFVSTCI6ICJodHRwOi8vMTI3LjAuMC4xOjM1MzU3L3YzIiwNCiAgICAgICAg -ICAgICAgICAgICAgICAgICJwdWJsaWNVUkwiOiAiaHR0cDovLzEyNy4wLjAuMTo1 -MDAwL3YzIg0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAg -XSwNCiAgICAgICAgICAgICAgICAiZW5kcG9pbnRzX2xpbmtzIjogW10sDQogICAg -ICAgICAgICAgICAgInR5cGUiOiAiaWRlbnRpdHkiLA0KICAgICAgICAgICAgICAg -ICJuYW1lIjogImtleXN0b25lIg0KICAgICAgICAgICAgfQ0KICAgICAgICBdLA0K -ICAgICAgICAiZXhwaXJlc19hdCI6ICIyMDM4LTAxLTE4VDIxOjE0OjA3WiIsDQog -ICAgICAgICJwcm9qZWN0Ijogew0KICAgICAgICAgICAgImVuYWJsZWQiOiB0cnVl -LA0KICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogbnVsbCwNCiAgICAgICAgICAg -ICJuYW1lIjogInRlbmFudF9uYW1lMSIsDQogICAgICAgICAgICAiaWQiOiAidGVu -YW50X2lkMSIsDQogICAgICAgICAgICAiZG9tYWluIjogew0KICAgICAgICAgICAg -ICAgICJpZCI6ICJkb21haW5faWQxIiwNCiAgICAgICAgICAgICAgICAibmFtZSI6 -ICJkb21haW5fbmFtZTEiDQogICAgICAgICAgICB9DQogICAgICAgIH0sDQogICAg -ICAgICJ1c2VyIjogew0KICAgICAgICAgICAgIm5hbWUiOiAicmV2b2tlZF91c2Vy -bmFtZTEiLA0KICAgICAgICAgICAgImlkIjogInJldm9rZWRfdXNlcl9pZDEiLA0K -ICAgICAgICAgICAgImRvbWFpbiI6IHsNCiAgICAgICAgICAgICAgICAiaWQiOiAi -ZG9tYWluX2lkMSIsDQogICAgICAgICAgICAgICAgIm5hbWUiOiAiZG9tYWluX25h -bWUxIg0KICAgICAgICAgICAgfQ0KICAgICAgICB9LA0KICAgICAgICAicm9sZXMi -OiBbDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgIm5hbWUiOiAicm9s -ZTEiDQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAg -ICAgICJuYW1lIjogInJvbGUyIg0KICAgICAgICAgICAgfQ0KICAgICAgICBdLA0K -ICAgICAgICAibWV0aG9kcyI6IFsNCiAgICAgICAgICAgICJwYXNzd29yZCINCiAg -ICAgICAgXQ0KICAgIH0NCn0NCjGCAcowggHGAgEBMIGkMIGeMQowCAYDVQQFEwE1 -MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVN1bm55dmFsZTES -MBAGA1UEChMJT3BlblN0YWNrMREwDwYDVQQLEwhLZXlzdG9uZTElMCMGCSqGSIb3 -DQEJARYWa2V5c3RvbmVAb3BlbnN0YWNrLm9yZzEUMBIGA1UEAxMLU2VsZiBTaWdu -ZWQCAREwBwYFKw4DAhowDQYJKoZIhvcNAQEBBQAEggEAwFCjl3GSGrlil3cLwS11 -1gtc6K3gBSMbc7LviIFk4KDRBvHWEHT1fs/Q4T0Y12P97Uaxh47f2sNgdbsDKSE8 -K/KCeMy+0I7Eo3iDoXKcIRPux1sXFhOX36qLPpY4eWd3Q77MiUPng+78qA3AMPPl -wEcfb2OaYsWmVi9jGsDfAvksF/WO5dg+G9m2l+zcboIJswsKbBJnM5bn8EDHk7bg -YuMnOzqZsoymr6sehOPQ8QTV6kIj1w/gmtkaIH2QtBo78hCqjZ+cFeYy4zDk2HJg -Mf7PDm0hx1G0hJMVxdNzkWoFvLreTzRselsrXrx8Gejof92JyKuBjZq0kBpphOHG -6w== ------END CMS----- diff --git a/keystonemiddleware-moon/examples/pki/cms/auth_v3_token_revoked.pkiz b/keystonemiddleware-moon/examples/pki/cms/auth_v3_token_revoked.pkiz deleted file mode 100644 index 67823fd3..00000000 --- a/keystonemiddleware-moon/examples/pki/cms/auth_v3_token_revoked.pkiz +++ /dev/null @@ -1 +0,0 @@ -PKIZ_eJylVsmSozgQvesr5l7R0Symyhz6wG5oS5jFgLixtDEY7PLC-vUjYXd31Sw1PTOOcNgIZerle7no0yfykTXDRL8p0KMPnwA0zdWywNbXU2zuuwxJTqacyNpiUhRZXCqSow2KL63kYntRC6gYFVnfLQ3FOxuemfJAdbSVlNBFSSuK6PpttJiUu9VpaT6bq2uZrawuaYIqV-7PcSjscTPU8fzsjiAPt1dTsQ4px-6TcFHapfxiNsI-Dbfkv1TGhnjDYd1G3Lw2mGVfmE19MKsT-XU7kIb6a1qLr7GqlTuPvvxpnBtBi0OBeW_s1hmHxiSSmSQUW0A9pcfgmipvPB_dOm30NtffOkb73NCvKZdRlCkJlThna3A3iLt0Fdxiz6ThEGO3T7m6zVfw--Z9bLAEaeD5NHbFOuUrt7fLZQegb_LrSmqhshjsquDRhLu80jpUuSVq8BQ3VoWn7YRUyMb-fo8qucEcXtihVaIKDwBxWrlWpDJrgiON6Y7IqmOu7tKD2D5QvaYkrIzyo79HASiM_4MCUBg_UKyCMjXqKggseJdpz-Qr6Xk9LgdYZfSAfl1pz7aa8agUOegtOYAMk4srck6DKuRDBk5BbRsaB424iqtCwI3JoUrjsWeJEVXj6AqZ8ZC5Ea8kkdj6rm_Qxiu5S4juGSteye8lG0ms-i2nMn6X7Y4sv5L8qCg_4N_K9p6vwwhs36SE_WclwN95fuf4A3LBO3Z9U4Azu38mLAnZfcxtZ4ekIg-ZIVJEE4i44TVtbhP1HLKsuFbeV2PaiBz-IMXBr5FFk8uhIbVU-7fSg4-1n08e4zB_TbnFjOg70T4nzPIDUsItqfuRlO_1lzJQoRwthvWEGVzFDYBcXGIOsnByJhRuF9jHfdygxlbrElfkjZ_v50Q7yixpZa-Y_aVi-ut4_ypc8FGuY068kRxg_txo0I7kRZvwsARUjihirrTjEh5oV6LwLnFUT7nxIwv_Nt3BP0tI-dnyax5Pdy4eKV7ONh64SyRs0uaeZbQa44hW3hBsD_09C1cuk6mnbj1pIxqpIsS5f5oIJyxAI5FlnGH2eWiRMkb_ZMhCVepnREc2B_TUfFX3j9hfYzILcqNmvn1A3J03Nqe2ZLAETGKIh3vzIKPM0KeMz7usccpZlSZYZEY9xhHa4ciZkcFKmmyF6aHHDMDWnZHAGpB66hF7evQF8RpH8N0AefSILjXIhDr-VA08oI8pN9Sw_J4LwRRH5mNOut08_h7D9o3U8zwFhPXdvOhrDxWcPwzV-kD7A333xpiEFHcJFxxAxNPT7jDho3XFyvtNjz074pzAZ8WdbyhSduqLYmUAqdBkaBoH8v0GnVOvSFgNHEfXeo2FzrVXnPnZ0Hor2E7aGkoHQ2K3miJDxWG0AWiV5MgFCmQp85UAsWkjCDkpbRKSB2XpvnkPLZ-X67RGDA7RBbpar_az4zXQ-v36R977Wg0V-OP6Qm4vluTikIQhZDwhswmklDo63h2tG3EE8aRtoWzOJ0kDXG-54BqXsp-EeRuHjiKR0-Qe61_7hSrtT73qvL1PaTKQHXo30qTi8A1d3G3mrSX5pubCKREZlaxEeZF0qnqe3Gq0mmcvvB763tW0W69v-s-RDqpRgZnLY1x4BMViY3G8gDiW3cTRsolW2uc0MOVLyz_fal5dtTiSq7TstR2f2eNmoWKwQVmIxW25t-zzywnrqrEbO_VsuJd1bWtQ1vTyKWg3ngtbQfl80c8Xd0wydeAbqJRPVxcMHty3SBcuQd0vfX_h9ofRwuYUcmWwGJJ8SL7mJRwCzcebvLt5SqHwT_LGzgaxZ3aFBBzm5Ww_7faNib7K_nR4sXH7ujkdrPPlZSva8pNYtf1zPY0o6XtJv52T6LwNfIlbdkJvSQxA-XNVOzJ7Vlipvh6Dk_2UC0vmcxS3tiN9-QLmC62G1J-X298BCSOhiw== \ No newline at end of file diff --git a/keystonemiddleware-moon/examples/pki/cms/auth_v3_token_scoped.json b/keystonemiddleware-moon/examples/pki/cms/auth_v3_token_scoped.json deleted file mode 100644 index 90207457..00000000 --- a/keystonemiddleware-moon/examples/pki/cms/auth_v3_token_scoped.json +++ /dev/null @@ -1,123 +0,0 @@ -{ - "token": { - "audit_ids": [ - "SLIXlXQUQZWUi9VJrqdXqA" - ], - "methods": [ - "password" - ], - "roles": [ - { - "name": "role1" - }, - { - "name": "role2" - } - ], - "expires_at": "2038-01-18T21:14:07Z", - "project": { - "id": "tenant_id1", - "domain": { - "id": "domain_id1", - "name": "domain_name1" - }, - "enabled": true, - "description": null, - "name": "tenant_name1" - }, - "catalog": [ - { - "endpoints": [ - { - "interface": "admin", - "url": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a", - "region": "regionOne" - }, - { - "interface": "internal", - "url": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a", - "region": "regionOne" - }, - { - "interface": "public", - "url": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a", - "region": "regionOne" - } - ], - "type": "volume", - "name": "volume" - }, - { - "endpoints": [ - { - "interface": "admin", - "url": "http://127.0.0.1:9292/v1", - "region": "regionOne" - }, - { - "interface": "internal", - "url": "http://127.0.0.1:9292/v1", - "region": "regionOne" - }, - { - "interface": "public", - "url": "http://127.0.0.1:9292/v1", - "region": "regionOne" - } - ], - "type": "image", - "name": "glance" - }, - { - "endpoints": [ - { - "interface": "admin", - "url": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a", - "region": "regionOne" - }, - { - "interface": "internal", - "url": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a", - "region": "regionOne" - }, - { - "interface": "public", - "url": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a", - "region": "regionOne" - } - ], - "type": "compute", - "name": "nova" - }, - { - "endpoints": [ - { - "interface": "admin", - "url": "http://127.0.0.1:35357/v3", - "region": "RegionOne" - }, - { - "interface": "internal", - "url": "http://127.0.0.1:35357/v3", - "region": "RegionOne" - }, - { - "interface": "public", - "url": "http://127.0.0.1:5000/v3", - "region": "RegionOne" - } - ], - "type": "identity", - "name": "keystone" - } - ], - "user": { - "domain": { - "id": "domain_id1", - "name": "domain_name1" - }, - "name": "user_name1", - "id": "user_id1" - } - } -} diff --git a/keystonemiddleware-moon/examples/pki/cms/auth_v3_token_scoped.pem b/keystonemiddleware-moon/examples/pki/cms/auth_v3_token_scoped.pem deleted file mode 100644 index e83e7a09..00000000 --- a/keystonemiddleware-moon/examples/pki/cms/auth_v3_token_scoped.pem +++ /dev/null @@ -1,100 +0,0 @@ ------BEGIN CMS----- -MIISOAYJKoZIhvcNAQcCoIISKTCCEiUCAQExDTALBglghkgBZQMEAgEwghA9Bgkq -hkiG9w0BBwGgghAuBIIQKnsNCiAgICAidG9rZW4iOiB7DQogICAgICAgICJhdWRp -dF9pZHMiOiBbDQogICAgICAgICAgICAiU0xJWGxYUVVRWldVaTlWSnJxZFhxQSIN -CiAgICAgICAgXSwNCiAgICAgICAgIm1ldGhvZHMiOiBbDQogICAgICAgICAgICAi -cGFzc3dvcmQiDQogICAgICAgIF0sDQogICAgICAgICJyb2xlcyI6IFsNCiAgICAg -ICAgICAgIHsNCiAgICAgICAgICAgICAgICAibmFtZSI6ICJyb2xlMSINCiAgICAg -ICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgIm5hbWUi -OiAicm9sZTIiDQogICAgICAgICAgICB9DQogICAgICAgIF0sDQogICAgICAgICJl -eHBpcmVzX2F0IjogIjIwMzgtMDEtMThUMjE6MTQ6MDdaIiwNCiAgICAgICAgInBy -b2plY3QiOiB7DQogICAgICAgICAgICAiaWQiOiAidGVuYW50X2lkMSIsDQogICAg -ICAgICAgICAiZG9tYWluIjogew0KICAgICAgICAgICAgICAgICJpZCI6ICJkb21h -aW5faWQxIiwNCiAgICAgICAgICAgICAgICAibmFtZSI6ICJkb21haW5fbmFtZTEi -DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgImVuYWJsZWQiOiB0cnVlLA0K -ICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogbnVsbCwNCiAgICAgICAgICAgICJu -YW1lIjogInRlbmFudF9uYW1lMSINCiAgICAgICAgfSwNCiAgICAgICAgImNhdGFs -b2ciOiBbDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgImVuZHBvaW50 -cyI6IFsNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAg -ICAgICAgImludGVyZmFjZSI6ICJhZG1pbiIsDQogICAgICAgICAgICAgICAgICAg -ICAgICAidXJsIjogImh0dHA6Ly8xMjcuMC4wLjE6ODc3Ni92MS82NGI2ZjNmYmNj -NTM0MzVlOGE2MGZjZjg5YmI2NjE3YSIsDQogICAgICAgICAgICAgICAgICAgICAg -ICAicmVnaW9uIjogInJlZ2lvbk9uZSINCiAgICAgICAgICAgICAgICAgICAgfSwN -CiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAg -ImludGVyZmFjZSI6ICJpbnRlcm5hbCIsDQogICAgICAgICAgICAgICAgICAgICAg -ICAidXJsIjogImh0dHA6Ly8xMjcuMC4wLjE6ODc3Ni92MS82NGI2ZjNmYmNjNTM0 -MzVlOGE2MGZjZjg5YmI2NjE3YSIsDQogICAgICAgICAgICAgICAgICAgICAgICAi -cmVnaW9uIjogInJlZ2lvbk9uZSINCiAgICAgICAgICAgICAgICAgICAgfSwNCiAg -ICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgImlu -dGVyZmFjZSI6ICJwdWJsaWMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgInVy -bCI6ICJodHRwOi8vMTI3LjAuMC4xOjg3NzYvdjEvNjRiNmYzZmJjYzUzNDM1ZThh -NjBmY2Y4OWJiNjYxN2EiLA0KICAgICAgICAgICAgICAgICAgICAgICAgInJlZ2lv -biI6ICJyZWdpb25PbmUiDQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAg -ICAgICAgICBdLA0KICAgICAgICAgICAgICAgICJ0eXBlIjogInZvbHVtZSIsDQog -ICAgICAgICAgICAgICAgIm5hbWUiOiAidm9sdW1lIg0KICAgICAgICAgICAgfSwN -CiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAiZW5kcG9pbnRzIjogWw0K -ICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICAi -aW50ZXJmYWNlIjogImFkbWluIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICJ1 -cmwiOiAiaHR0cDovLzEyNy4wLjAuMTo5MjkyL3YxIiwNCiAgICAgICAgICAgICAg -ICAgICAgICAgICJyZWdpb24iOiAicmVnaW9uT25lIg0KICAgICAgICAgICAgICAg -ICAgICB9LA0KICAgICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAg -ICAgICAgICAiaW50ZXJmYWNlIjogImludGVybmFsIiwNCiAgICAgICAgICAgICAg -ICAgICAgICAgICJ1cmwiOiAiaHR0cDovLzEyNy4wLjAuMTo5MjkyL3YxIiwNCiAg -ICAgICAgICAgICAgICAgICAgICAgICJyZWdpb24iOiAicmVnaW9uT25lIg0KICAg -ICAgICAgICAgICAgICAgICB9LA0KICAgICAgICAgICAgICAgICAgICB7DQogICAg -ICAgICAgICAgICAgICAgICAgICAiaW50ZXJmYWNlIjogInB1YmxpYyIsDQogICAg -ICAgICAgICAgICAgICAgICAgICAidXJsIjogImh0dHA6Ly8xMjcuMC4wLjE6OTI5 -Mi92MSIsDQogICAgICAgICAgICAgICAgICAgICAgICAicmVnaW9uIjogInJlZ2lv -bk9uZSINCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIF0s -DQogICAgICAgICAgICAgICAgInR5cGUiOiAiaW1hZ2UiLA0KICAgICAgICAgICAg -ICAgICJuYW1lIjogImdsYW5jZSINCiAgICAgICAgICAgIH0sDQogICAgICAgICAg -ICB7DQogICAgICAgICAgICAgICAgImVuZHBvaW50cyI6IFsNCiAgICAgICAgICAg -ICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgImludGVyZmFjZSI6 -ICJhZG1pbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAidXJsIjogImh0dHA6 -Ly8xMjcuMC4wLjE6ODc3NC92MS4xLzY0YjZmM2ZiY2M1MzQzNWU4YTYwZmNmODli -YjY2MTdhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICJyZWdpb24iOiAicmVn -aW9uT25lIg0KICAgICAgICAgICAgICAgICAgICB9LA0KICAgICAgICAgICAgICAg -ICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICAiaW50ZXJmYWNlIjogImlu -dGVybmFsIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICJ1cmwiOiAiaHR0cDov -LzEyNy4wLjAuMTo4Nzc0L3YxLjEvNjRiNmYzZmJjYzUzNDM1ZThhNjBmY2Y4OWJi -NjYxN2EiLA0KICAgICAgICAgICAgICAgICAgICAgICAgInJlZ2lvbiI6ICJyZWdp -b25PbmUiDQogICAgICAgICAgICAgICAgICAgIH0sDQogICAgICAgICAgICAgICAg -ICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICJpbnRlcmZhY2UiOiAicHVi -bGljIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICJ1cmwiOiAiaHR0cDovLzEy -Ny4wLjAuMTo4Nzc0L3YxLjEvNjRiNmYzZmJjYzUzNDM1ZThhNjBmY2Y4OWJiNjYx -N2EiLA0KICAgICAgICAgICAgICAgICAgICAgICAgInJlZ2lvbiI6ICJyZWdpb25P -bmUiDQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBdLA0K -ICAgICAgICAgICAgICAgICJ0eXBlIjogImNvbXB1dGUiLA0KICAgICAgICAgICAg -ICAgICJuYW1lIjogIm5vdmEiDQogICAgICAgICAgICB9LA0KICAgICAgICAgICAg -ew0KICAgICAgICAgICAgICAgICJlbmRwb2ludHMiOiBbDQogICAgICAgICAgICAg -ICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICJpbnRlcmZhY2UiOiAi -YWRtaW4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgInVybCI6ICJodHRwOi8v -MTI3LjAuMC4xOjM1MzU3L3YzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICJy -ZWdpb24iOiAiUmVnaW9uT25lIg0KICAgICAgICAgICAgICAgICAgICB9LA0KICAg -ICAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgICAgICAiaW50 -ZXJmYWNlIjogImludGVybmFsIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICJ1 -cmwiOiAiaHR0cDovLzEyNy4wLjAuMTozNTM1Ny92MyIsDQogICAgICAgICAgICAg -ICAgICAgICAgICAicmVnaW9uIjogIlJlZ2lvbk9uZSINCiAgICAgICAgICAgICAg -ICAgICAgfSwNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAg -ICAgICAgICAgImludGVyZmFjZSI6ICJwdWJsaWMiLA0KICAgICAgICAgICAgICAg -ICAgICAgICAgInVybCI6ICJodHRwOi8vMTI3LjAuMC4xOjUwMDAvdjMiLA0KICAg -ICAgICAgICAgICAgICAgICAgICAgInJlZ2lvbiI6ICJSZWdpb25PbmUiDQogICAg -ICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBdLA0KICAgICAgICAg -ICAgICAgICJ0eXBlIjogImlkZW50aXR5IiwNCiAgICAgICAgICAgICAgICAibmFt -ZSI6ICJrZXlzdG9uZSINCiAgICAgICAgICAgIH0NCiAgICAgICAgXSwNCiAgICAg -ICAgInVzZXIiOiB7DQogICAgICAgICAgICAiZG9tYWluIjogew0KICAgICAgICAg -ICAgICAgICJpZCI6ICJkb21haW5faWQxIiwNCiAgICAgICAgICAgICAgICAibmFt -ZSI6ICJkb21haW5fbmFtZTEiDQogICAgICAgICAgICB9LA0KICAgICAgICAgICAg -Im5hbWUiOiAidXNlcl9uYW1lMSIsDQogICAgICAgICAgICAiaWQiOiAidXNlcl9p -ZDEiDQogICAgICAgIH0NCiAgICB9DQp9DQoxggHOMIIBygIBATCBpDCBnjEKMAgG -A1UEBRMBNTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlTdW5u -eXZhbGUxEjAQBgNVBAoTCU9wZW5TdGFjazERMA8GA1UECxMIS2V5c3RvbmUxJTAj -BgkqhkiG9w0BCQEWFmtleXN0b25lQG9wZW5zdGFjay5vcmcxFDASBgNVBAMTC1Nl -bGYgU2lnbmVkAgERMAsGCWCGSAFlAwQCATANBgkqhkiG9w0BAQEFAASCAQBBvzoh -0iSPMQhuRCAtTG3cPhyewvf554MPjbGQnu8mYmmfyxl7gMmWkTAmyckAsSv4mS6/ -4SQj9WCn4T1lFkhUz7WWjCwt6fWWp3mzF8Nl/kMsJKDwlxDGbPzsyewXIUsw11sz -q/Qxs7qGxQ1vYWnaWQ3hC3oZw7cOswKRJicdP439iVPvfqR9CDbK55sPP+ewZRgQ -YJ3Uc/xDizxepudFJj9+VHKceA37/sVK0ataNe2uHLHwVBYPwOppMckP169QBw8x -QYh9h+kcOAyZ5psiUzCpLKnlMiYDrVcTGxnTeiVHxKXxj/MERNhR1Y4lEr0ZHJ+p -Y6p3FBP2VUCefaRh ------END CMS----- diff --git a/keystonemiddleware-moon/examples/pki/cms/auth_v3_token_scoped.pkiz b/keystonemiddleware-moon/examples/pki/cms/auth_v3_token_scoped.pkiz deleted file mode 100644 index 74f8f632..00000000 --- a/keystonemiddleware-moon/examples/pki/cms/auth_v3_token_scoped.pkiz +++ /dev/null @@ -1 +0,0 @@ -PKIZ_eJy9V0tzozoT3etX3H1qKoBNEhbfgpexMJKNjXloZyDmJWwnNs9f_wnsSWYyuXUzc6uuq7yQQN2n-_RpNd--sZ-iGxD_paLNsPgGEISmIwfm4khgWkdYtiP1yPZWjqqqTqHKtt5qjmwpCU3SIlGIjXQ50ZskiddKUryAtMgMqeEUpTEStqkqEM5Xh3MWG9Ir8abZMlMeYcnT2EhrMkfDOoQHJY0meBJOzAJAyp2hanah0NKogw9wdmEHxDT0tuxlOYtK6UwcPdtvmuS5M6vA4ynMjwk8mHVobDsAD3xsqXJG_LTZ-SaNeCmNVWZIhR3S0NRy5NZy9KmrwXaZ69wylydeBgenDTP-AoiHucEis16EAp_u3mDTYvRUruvQm51CKp2IpmeDs7CcXchmcMJCuB4S9-PmDSosXQbVPBPPHoxx0cGlw8HduJZZfobnIucLtABoM8L5IbY1ZcaqeCaNe7fnBfFxHpW0iQ1ahxnzboh8aLQSGCwHwowLvLYmb0l0KzJXaoaMe08srZjnjpSz_AY_JQZ_AuE1IXxUNiO83XzNRdqxtnq9w920sXK5Qs5xivtIsCZBa_UBF-SkRAJhjhEPUG_32NtOAydoSInLpUazIGePnDiFWTPQRYlwg83oJl58CgVxFZbbMV-AZf8UsrijkqSBcOV-gE78IS_NmPXYN89XRlIunssPVvfUojyqkDptgJXrD0uN1VUmCWjzJGADCiTHZVDiHDuIQ71Ll4YuIIPkJE_EoIQCzvVJcE1uB66Qpreqcw87T6ocQaTwwCp0fv6Opgw8fGNJ4YOyPQXdNXfgT5P3PXfgj5Lnjvrhnn2FgissUodzdyjPD0X1fd-ULFX5tD7A3xXIF-tDBCgvuiHGr3D-GeXgdzgfKXegiEbK_yMaxX8KEXxGzTUEegm8mI4Hf2hxRGjTsMRvCFkIYhEZ0pCcfjjoTT6BXc6K0KPVFYXbhWPLM4_xfN2AZfZUIwdORsjqlPW9ZIJ7u45zvfqKNsBHcfxuUt8KibWx82cQ_wkh-F35fkQIfpf3j7SDT-TLjfLN9Rrn64xh60lp5kG_7bGGeOKkKc6VMhCC6dIzM4DzoMXC9cL4nrTb1XUtmkKqBjX6w31xWIuRca2HQJAu0dzlwC8SLsU6Lt_uQnZHrJtQYIm-XawfBQVGa976MlxpXxETGkJxIsYCGt8HP8GmP8O-NpFf-sUNAStvFZ7BF5oG84h43DEJd79SCbZ_IOEfHYJPPPJIkxtGZf-JhDcfmyv4IOGCqZPb-Wvxo4x3gitGEzYrvEufjwS3A_9muBjOgF-Hi3evsY9pRH-aE07kKrTR-23AGOhiteC7BYO-33m3xtKZjqPTIJyla9ed7VzePS1dsogOs8KbzxRIeWnvGCqQoymb-eYLNvspCBoF-z8j-9iocqC5tj3TG51H9rlR7XFt6I3pbnvdQnJhyPxWB6qCVJvTWz2XbSXBriJHjupiPixFMWY9goW2QYo8vqymyHQmCg0pZhMNfkVrvQFaM1q29Ca1iE97NmBW7BBFKjLUzYuxgeFEs3VTXgfeOxOuHA6GDpgDgyWrlDrS61ukwNGT3CJrK7hnkinOzosrNq2pMvOmNoEZQAJlb6spMlSQzBngBy-KbG9lNuoqsl45jyd9AeeC-HheWe3ZcDV83l82hJcKyxTugoXTmR29W7ggfMi9NIj3U057PbLunu_O-6Pf76PznSIHxJRq4e7OOIWL7KTwPgcP9f2rd7_dRKUwebBCDmgngUi2KFhknc5gFhThttK4Je6NbWFO4GIz0T3rsfJW4mql2yo1yqqtlZnzjLO21O874K2f7p-3F08ISRVMDf_iXbz5PD_K8sTuT0er8oTnKn5NWsdHyHVR99DQbfas-vv01XjSVsATVN47Wg1furyTLmYXI0p8ob7Xl6tjv6sXjplX6K40Nz4WV013XF_UIgmX3fSurGfTwwJ0j4vLEa_um-eE7-4VWqYvq8eX-zbZTFYPl2htaOZRdlYzh4P_A-M3io619--V_wMk2UFA \ No newline at end of file diff --git a/keystonemiddleware-moon/examples/pki/cms/revocation_list.der b/keystonemiddleware-moon/examples/pki/cms/revocation_list.der deleted file mode 100644 index e69de29b..00000000 diff --git a/keystonemiddleware-moon/examples/pki/cms/revocation_list.json b/keystonemiddleware-moon/examples/pki/cms/revocation_list.json deleted file mode 100644 index 2c239e53..00000000 --- a/keystonemiddleware-moon/examples/pki/cms/revocation_list.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "revoked": [ - { - "expires": "2112-08-14T17:58:48Z", - "id": "dc57ea171d2f93e4ff5fa01fe5711f2a" - }, - { - "expires": "2112-08-14T17:58:48Z", - "id": "4948fb46f88c41af90b65213a48baef7" - }, - { - "expires": "2112-08-14T17:58:48Z", - "id": "dc57ea171d2f93e4ff5fa01fe5711f2a" - }, - { - "expires": "2112-08-14T17:58:48Z", - "id": "4948fb46f88c41af90b65213a48baef7" - } - ] -} diff --git a/keystonemiddleware-moon/examples/pki/cms/revocation_list.pem b/keystonemiddleware-moon/examples/pki/cms/revocation_list.pem deleted file mode 100644 index a86d6d34..00000000 --- a/keystonemiddleware-moon/examples/pki/cms/revocation_list.pem +++ /dev/null @@ -1,24 +0,0 @@ ------BEGIN CMS----- -MIIEGAYJKoZIhvcNAQcCoIIECTCCBAUCAQExCTAHBgUrDgMCGjCCAiUGCSqGSIb3 -DQEHAaCCAhYEggISew0KICAgICJyZXZva2VkIjogWw0KICAgICAgICB7DQogICAg -ICAgICAgICAiZXhwaXJlcyI6ICIyMTEyLTA4LTE0VDE3OjU4OjQ4WiIsDQogICAg -ICAgICAgICAiaWQiOiAiZGM1N2VhMTcxZDJmOTNlNGZmNWZhMDFmZTU3MTFmMmEi -DQogICAgICAgIH0sDQogICAgICAgIHsNCiAgICAgICAgICAgICJleHBpcmVzIjog -IjIxMTItMDgtMTRUMTc6NTg6NDhaIiwNCiAgICAgICAgICAgICJpZCI6ICI0OTQ4 -ZmI0NmY4OGM0MWFmOTBiNjUyMTNhNDhiYWVmNyINCiAgICAgICAgfSwNCiAgICAg -ICAgew0KICAgICAgICAgICAgImV4cGlyZXMiOiAiMjExMi0wOC0xNFQxNzo1ODo0 -OFoiLA0KICAgICAgICAgICAgImlkIjogImRjNTdlYTE3MWQyZjkzZTRmZjVmYTAx -ZmU1NzExZjJhIg0KICAgICAgICB9LA0KICAgICAgICB7DQogICAgICAgICAgICAi -ZXhwaXJlcyI6ICIyMTEyLTA4LTE0VDE3OjU4OjQ4WiIsDQogICAgICAgICAgICAi -aWQiOiAiNDk0OGZiNDZmODhjNDFhZjkwYjY1MjEzYTQ4YmFlZjciDQogICAgICAg -IH0NCiAgICBdDQp9DQoxggHKMIIBxgIBATCBpDCBnjEKMAgGA1UEBRMBNTELMAkG -A1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlTdW5ueXZhbGUxEjAQBgNV -BAoTCU9wZW5TdGFjazERMA8GA1UECxMIS2V5c3RvbmUxJTAjBgkqhkiG9w0BCQEW -FmtleXN0b25lQG9wZW5zdGFjay5vcmcxFDASBgNVBAMTC1NlbGYgU2lnbmVkAgER -MAcGBSsOAwIaMA0GCSqGSIb3DQEBAQUABIIBAGMtzsHJdosl27LoRWYHGknORRWE -K0E9a7Bm4ZDt0XiGn0opGWpXF3Kj+7q86Ph1qcG9vZy20e2V+8n5696//OgMGCZe -QNbkOv70c0pkICMqczv4RaNF+UPetwDdv+p0WV8nLH5dDVc8Pp8B4T6fN6vXHXA2 -GMWxxn8SpF9bvP8S5VCAt7wsvmhWJpJVYe6bOdYzlhR0yLJzv4GvHtPVP+cBz6nS -uJguvt77MfQU97pOaDbvfmsJRUf/L3Fd93KbgLTzFPEhddTs1oD9pSDckncnZwua -9nIDn2iFNB/NfZrbqy+owM0Nt5j1m4dcPX/qm0J9DAhKGeDUbIu+81yL308= ------END CMS----- diff --git a/keystonemiddleware-moon/examples/pki/cms/revocation_list.pkiz b/keystonemiddleware-moon/examples/pki/cms/revocation_list.pkiz deleted file mode 100644 index 600fce02..00000000 --- a/keystonemiddleware-moon/examples/pki/cms/revocation_list.pkiz +++ /dev/null @@ -1 +0,0 @@ -PKIZ_eJx9VEuPszgQvPMr9h6NQgIhk8N3MMaACTaBmJdvCZMxGMhjkgmPX79kRtq9rNYXq0ul6u7qVr-9Tc9EDqZ_QbJ_BW8KwdhiXe5tLxyXz4KCsICXCQstCMHYQRCiHjLgmiL-sgSBjpzwpHPg_ubs8VFTrBC54DCBsYqEsL3T4A0848_DMqmxvIhUu1c8K7tD5jXFgA0M8UAYGnwGdJ8hVUkspAUy1gMZ6mmF7xh6Vw5fRK_Ox1jjKerpaNekzVdkGau8zRe8RR1JeUNZ0SskzYd87218aK5xm-iF00wVkCqoQEUk6kmldgFUe2qHk9BlEVgXNbAvlQ9BdUjDSnkRqVWrgcOnn7eBVUpq2SWXdZfLfDGJjDkL9by1Gy6L6nPfianN5uSa16JNRuXVJ5a4Jww_iCUehEUxYYVBmTCoVR5w1QncNj9-4DaSlH00OUMaScNhSjIqnEUtl0mbM9DzNl7QEfVceiU-q3fs_r-BL_-U_zYQq8FUNm-xSttcDxyiktRuA2ZWVMaTCC2n6qo8TVqFDt4my9ReCHc77YTZC2wCBs2rBc2zRFsChAMWMTIjYlKGfALq37gkMElIr8AReKagiQkEAzU1SYQ7BHIrCUMXdQ37SFffp4yXRyfukQThL_fCYLzpeLpiyodjy8OIIgLef5RhT_B-mawKLXoe27j3GJCmqG9lXTmbTjVhiKZmHs0po-pxuWqU0PlRGn-EhtWzaIvetsD-NxNhcEGbo5OLeNmcj21SA_FKVjjm_h6ADh8UAtR_9npaaxOEMTAnLwBePp4BLmXIWNlG3VbvrrPtiQexUW7rJVjJVTHLKFesvvOb53c2y3nfroKr_4HPWybJU5LKEN9F1blaEoPLEt9um4GU7jwrV4_30NvPxp29rpSZE9w6fjULI9zSqsSXWt34unwcYvmpzz_XiIe0nEtSfz6-gVaWj2__0JzrPF0PCCzvtnI-rXdREidG9V7NbmsBV_6mymo9HLTrEoxi53yWtrEjc_U6DtJ71MbzfWfCehrqqf-qb0q011N5z0mktafnQvrah6d2TEBxvsEi0o7hw_LnxL3Gxs2AJyPULAcZZR0GOHJPZzRX6GXHb1Y-J5pO3aO8k1ulj14d6C75KgSo8sN8zOaD2Y1P9P2F_yg_dwhR69-b9Dc2l4GQ \ No newline at end of file diff --git a/keystonemiddleware-moon/examples/pki/gen_cmsz.py b/keystonemiddleware-moon/examples/pki/gen_cmsz.py deleted file mode 100644 index 6840c08e..00000000 --- a/keystonemiddleware-moon/examples/pki/gen_cmsz.py +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/python - -# 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. - -import json -import os - -from keystoneclient.common import cms -from keystoneclient import utils - -CURRENT_DIR = os.path.abspath(os.path.dirname(__file__)) - - -def make_filename(*args): - return os.path.join(CURRENT_DIR, *args) - - -def generate_revocation_list(): - REVOKED_TOKENS = ['auth_token_revoked', 'auth_v3_token_revoked'] - revoked_list = [] - for token in REVOKED_TOKENS: - with open(make_filename('cms', '%s.pkiz' % name), 'r') as f: - token_data = f.read() - id = utils.hash_signed_token(token_data.encode('utf-8')) - revoked_list.append({ - 'id': id, - "expires": "2112-08-14T17:58:48Z" - }) - with open(make_filename('cms', '%s.pem' % name), 'r') as f: - pem_data = f.read() - token_data = cms.cms_to_token(pem_data).encode('utf-8') - id = utils.hash_signed_token(token_data) - revoked_list.append({ - 'id': id, - "expires": "2112-08-14T17:58:48Z" - }) - revoked_json = json.dumps({"revoked": revoked_list}) - with open(make_filename('cms', 'revocation_list.json'), 'w') as f: - f.write(revoked_json) - encoded = cms.pkiz_sign(revoked_json, - SIGNING_CERT_FILE_NAME, - SIGNING_KEY_FILE_NAME) - with open(make_filename('cms', 'revocation_list.pkiz'), 'w') as f: - f.write(encoded) - - encoded = cms.cms_sign_data(revoked_json, - SIGNING_CERT_FILE_NAME, - SIGNING_KEY_FILE_NAME) - with open(make_filename('cms', 'revocation_list.pem'), 'w') as f: - f.write(encoded) - - -CA_CERT_FILE_NAME = make_filename('certs', 'cacert.pem') -SIGNING_CERT_FILE_NAME = make_filename('certs', 'signing_cert.pem') -SIGNING_KEY_FILE_NAME = make_filename('private', 'signing_key.pem') -EXAMPLE_TOKENS = ['auth_token_revoked', - 'auth_token_unscoped', - 'auth_token_scoped', - 'auth_token_scoped_expired', - 'auth_v3_token_scoped', - 'auth_v3_token_revoked'] - - -# Helper script to generate the sample data for testing -# the signed tokens using the existing JSON data for the -# MII-prefixed tokens. Uses the keys and certificates -# generated in gen_pki.sh. -def generate_der_form(name): - derfile = make_filename('cms', '%s.der' % name) - with open(derfile, 'w') as f: - derform = cms.cms_sign_data(text, - SIGNING_CERT_FILE_NAME, - SIGNING_KEY_FILE_NAME, cms.PKIZ_CMS_FORM) - f.write(derform) - -for name in EXAMPLE_TOKENS: - json_file = make_filename('cms', name + '.json') - pkiz_file = make_filename('cms', name + '.pkiz') - with open(json_file, 'r') as f: - string_data = f.read() - - # validate the JSON - try: - token_data = json.loads(string_data) - except ValueError as v: - raise SystemExit('%s while processing token data from %s: %s' % - (v, json_file, string_data)) - - text = json.dumps(token_data).encode('utf-8') - - # Uncomment to record the token uncompressed, - # useful for debugging - # generate_der_form(name) - - encoded = cms.pkiz_sign(text, - SIGNING_CERT_FILE_NAME, - SIGNING_KEY_FILE_NAME) - - # verify before writing - cms.pkiz_verify(encoded, - SIGNING_CERT_FILE_NAME, - CA_CERT_FILE_NAME) - - with open(pkiz_file, 'w') as f: - f.write(encoded) - - generate_revocation_list() diff --git a/keystonemiddleware-moon/examples/pki/gen_pki.sh b/keystonemiddleware-moon/examples/pki/gen_pki.sh deleted file mode 100755 index b8b28f9d..00000000 --- a/keystonemiddleware-moon/examples/pki/gen_pki.sh +++ /dev/null @@ -1,213 +0,0 @@ -#!/bin/bash - -# Copyright 2012 OpenStack Foundation -# -# 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. - -# These functions generate the certificates and signed tokens for the tests. - -DIR=`dirname "$0"` -CURRENT_DIR=`cd "$DIR" && pwd` -CERTS_DIR=$CURRENT_DIR/certs -PRIVATE_DIR=$CURRENT_DIR/private -CMS_DIR=$CURRENT_DIR/cms - - -function rm_old { - rm -rf $CERTS_DIR/*.pem - rm -rf $PRIVATE_DIR/*.pem -} - -function cleanup { - rm -rf *.conf > /dev/null 2>&1 - rm -rf index* > /dev/null 2>&1 - rm -rf *.crt > /dev/null 2>&1 - rm -rf newcerts > /dev/null 2>&1 - rm -rf *.pem > /dev/null 2>&1 - rm -rf serial* > /dev/null 2>&1 -} - -function generate_ca_conf { - echo ' -[ req ] -default_bits = 2048 -default_keyfile = cakey.pem -default_md = default - -prompt = no -distinguished_name = ca_distinguished_name - -x509_extensions = ca_extensions - -[ ca_distinguished_name ] -serialNumber = 5 -countryName = US -stateOrProvinceName = CA -localityName = Sunnyvale -organizationName = OpenStack -organizationalUnitName = Keystone -emailAddress = keystone@openstack.org -commonName = Self Signed - -[ ca_extensions ] -basicConstraints = critical,CA:true -' > ca.conf -} - -function generate_ssl_req_conf { - echo ' -[ req ] -default_bits = 2048 -default_keyfile = keystonekey.pem -default_md = default - -prompt = no -distinguished_name = distinguished_name - -[ distinguished_name ] -countryName = US -stateOrProvinceName = CA -localityName = Sunnyvale -organizationName = OpenStack -organizationalUnitName = Keystone -commonName = localhost -emailAddress = keystone@openstack.org -' > ssl_req.conf -} - -function generate_cms_signing_req_conf { - echo ' -[ req ] -default_bits = 2048 -default_keyfile = keystonekey.pem -default_md = default - -prompt = no -distinguished_name = distinguished_name - -[ distinguished_name ] -countryName = US -stateOrProvinceName = CA -localityName = Sunnyvale -organizationName = OpenStack -organizationalUnitName = Keystone -commonName = Keystone -emailAddress = keystone@openstack.org -' > cms_signing_req.conf -} - -function generate_signing_conf { - echo ' -[ ca ] -default_ca = signing_ca - -[ signing_ca ] -dir = . -database = $dir/index.txt -new_certs_dir = $dir/newcerts - -certificate = $dir/certs/cacert.pem -serial = $dir/serial -private_key = $dir/private/cakey.pem - -default_days = 21360 -default_crl_days = 30 -default_md = default - -policy = policy_any - -[ policy_any ] -countryName = supplied -stateOrProvinceName = supplied -localityName = optional -organizationName = supplied -organizationalUnitName = supplied -emailAddress = supplied -commonName = supplied -' > signing.conf -} - -function setup { - touch index.txt - echo '10' > serial - generate_ca_conf - mkdir newcerts -} - -function check_error { - if [ $1 != 0 ] ; then - echo "Failed! rc=${1}" - echo 'Bailing ...' - cleanup - exit $1 - else - echo 'Done' - fi -} - -function generate_ca { - echo 'Generating New CA Certificate ...' - openssl req -x509 -newkey rsa:2048 -days 21360 -out $CERTS_DIR/cacert.pem -keyout $PRIVATE_DIR/cakey.pem -outform PEM -config ca.conf -nodes - check_error $? -} - -function ssl_cert_req { - echo 'Generating SSL Certificate Request ...' - generate_ssl_req_conf - openssl req -newkey rsa:2048 -keyout $PRIVATE_DIR/ssl_key.pem -keyform PEM -out ssl_req.pem -outform PEM -config ssl_req.conf -nodes - check_error $? - #openssl req -in req.pem -text -noout -} - -function cms_signing_cert_req { - echo 'Generating CMS Signing Certificate Request ...' - generate_cms_signing_req_conf - openssl req -newkey rsa:2048 -keyout $PRIVATE_DIR/signing_key.pem -keyform PEM -out cms_signing_req.pem -outform PEM -config cms_signing_req.conf -nodes - check_error $? - #openssl req -in req.pem -text -noout -} - -function issue_certs { - generate_signing_conf - echo 'Issuing SSL Certificate ...' - openssl ca -in ssl_req.pem -config signing.conf -batch - check_error $? - openssl x509 -in $CURRENT_DIR/newcerts/10.pem -out $CERTS_DIR/ssl_cert.pem - check_error $? - echo 'Issuing CMS Signing Certificate ...' - openssl ca -in cms_signing_req.pem -config signing.conf -batch - check_error $? - openssl x509 -in $CURRENT_DIR/newcerts/11.pem -out $CERTS_DIR/signing_cert.pem - check_error $? -} - -function create_middleware_cert { - cp $CERTS_DIR/ssl_cert.pem $CERTS_DIR/middleware.pem - cat $PRIVATE_DIR/ssl_key.pem >> $CERTS_DIR/middleware.pem -} - -function check_openssl { - echo 'Checking openssl availability ...' - which openssl - check_error $? -} - -JSON_FILES="${CMS_DIR}/auth_token_revoked.json ${CMS_DIR}/auth_token_unscoped.json ${CMS_DIR}/auth_token_scoped.json ${CMS_DIR}/auth_token_scoped_expired.json ${CMS_DIR}/revocation_list.json ${CMS_DIR}/auth_v3_token_scoped.json ${CMS_DIR}/auth_v3_token_revoked.json" - -function gen_sample_cms { - for json_file in $JSON_FILES - do - openssl cms -sign -in $json_file -nosmimecap -signer $CERTS_DIR/signing_cert.pem -inkey $PRIVATE_DIR/signing_key.pem -outform PEM -nodetach -nocerts -noattr -out ${json_file/.json/.pem} - done -} - diff --git a/keystonemiddleware-moon/examples/pki/private/cakey.pem b/keystonemiddleware-moon/examples/pki/private/cakey.pem deleted file mode 100644 index 1c93ee18..00000000 --- a/keystonemiddleware-moon/examples/pki/private/cakey.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCl8906EaRpibQF -cCBWfxzLi5x/XpZ9iL6UX92NrSJxcDbaGws7s+GtjgDy8UOEonesRWTeqQEZtHpC -3/UHHOnsA8F6ha/pq9LioqT7RehCnZCLBJwh5Ct+lclpWs15SkjJD2LTDkjox0eA -9nOBx+XDlWyU/GAyqx5Wsvg/Kxr0iod9/4IcJdnSdUjq4v0Cxg/zNk08XPJX+F0b -UDhgdUf7JrAmmS5LA8wphRnbIgtVsf6VN9HrbqtHAJDxh8gEfuwdhEW1df1fBtZ+ -6WMIF3IRSbIsZELFB6sqcyRj7HhMoWMkdEyPb2f8mq61MzTgE6lJGIyTRvEoFie7 -qtGADIofAgMBAAECggEBAJ47X3y2xaU7f0KQHsVafgI2JAnuDl+zusOOhJlJs8Wl -0Sc1EgjjAxOQiqcaE96rap//qqYDTuFLjCenkuItV32KNzizr3+GLZWaruRHS6X4 -xpFG2/gUrsQL3fdudOxpP+01lmzW+f25xRvZ4VilWRabquSDntWxA0R3cOwKFbGD -uuwbTw3pBrRfCk/2IdpQtRrvvkVIFiYT6b/zeCQzhp4RETbC0oxqcEEOIUGmimAV -9cbwafinxCo54cOfX4JAh3j7Mp3eQUymoFk5gnmIeVe0QmpH2VkN7eItrhEvHKOk -On7a5xvQ8s3wqPV5ZawHQcqar/p3QnGkiT6a+8LkIMECgYEA2iJ2DprTGZFRN0M7 -Yj4WLsSC3/GKK8eYsKG3TvMrmPqUDaiWLIvBoc1Le59x9eoF7Mha+WX+cAFL+GTg -1sB+PUZZStpf1R1tGvMldvpQ+5GplUBpuQe4J0n5rCG6+5jkvSr7xO+G1B+C3GFq -KR3iltiW5WJRVwh2k8yGvx3agyUCgYEAwsKFX82F7O+9IVud1JSQWmZMiyEK+DEX -JRnwx4HBuWr+AZqbb0grRRb6x8JTUOD4T7DZGxTaAdfzzRjKU2sBAO8VCgaj2Auv -5nsbvfXvrmDDCqwoaD2PMy+kgFvE0QTh65tzuGXl1IgpIYSC1JwnP6kOeUDbqE+k -UXzfVZzDdvMCgYByk9dfJIPt0h7O4Em4+NO+DQqRhtYE2PqjDM60cZZc7IIICp2X -GHHFA4i6jq3Vde9WyIbAqYpUWtoExzgylTm6BdGxN7NOxf4hQcZUEHepLIHfG85s -mlloibrTZ4RH06+SjZlhgE9Z7JNYHvMcVc5HXc0k/9ep15AxYiUFDjFQ4QKBgG7i -k089U4/X2wWgBNdgkmN1tQTNllJCmNvdzhG41dQ8j0vYe8C7BS+76qJLCGaW/6lX -lfRuRcUg78UI5UDjPloKxR7FMwmxdb+yvdPEr2bH3qQ36nWW/u30pSMTnJYownwD -MLp/AYCk2U4lBNwJ3+rF1ODCRY2pcnOWtg0nSL5zAoGAWRoOinogEnOodJzO7eB3 -TmL6M9QMyrAPBDsCnduJ8yW5mMUNod139YbSDxZPYwTLhK/GiHP/7OvLV5hg0s4s -QKnNaMeEowX7dyEO4ehnbfzysxXPKLRVhWhN6MCUc71NMxqr7QkuCXAjJS6/G21+ -Im3+Xb3Scq+UZghR+jiEZF0= ------END PRIVATE KEY----- diff --git a/keystonemiddleware-moon/examples/pki/private/signing_key.pem b/keystonemiddleware-moon/examples/pki/private/signing_key.pem deleted file mode 100644 index 758c0ffe..00000000 --- a/keystonemiddleware-moon/examples/pki/private/signing_key.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDM+VrILLl962VH -S8EKWVzdkaOy0OoxGZ63gajM7VTm8AbgtVnYibIOnVZQuz1XbftIGNXPFhYNUypr -LnMXrEEsnxgD4PvU/4bETG+stdricX6d1oKqsNFNR7F7zImiR/OzGhp7dONwccxf -kfX4QHA5Ogso+XMfSdC72SRDszeCeGUcjuo/w2WSLW95SuVvcZLqE/pk3Q2TkCZ1 -8hvNfLoln43QpC469a7srUXATqOJ2mPNvL6E/wOyPefmAoCoG44lFoR3k2jZjBEI -hstJxmH7XgvqErBzpcWd29dms8xz5PNwYdns9CIfb3GaHvQ6r5RTl37/avDrGHOW -KOoD01xLAgMBAAECggEAaIi22qWsh+JYCW9B6NRAPyN6V8Sh2x6UykOO4cwb45b/ -+vOh+YPn0fo9vfhvxTnq0A8SY4WBA5SpanYK7kTEDEyqw7em1y7l/RB6V5t7IMb+ -6uIuS3zXkVEB3AApJSEK0Ql7/gBTydHPh+H5jnzWfujyLhhhtNBBarvH+drZcWio -lWx8RERN4cH+3DZD/xxjH2Ff+X1XMvb8Xcup7MlWi2FtREg7LttLNWNK25iWjciP -QwfWQIrURRJrD2IrOr9V2nuIEvRqRRBoO+pxJT2sC48NJ3hiKV2GtSQe2nRpQJ47 -f9MEsF5KVQOOn+aQ60EKOI0MpNPmpiCZ5hFvBrNuOQKBgQD6vueEdI9eJgz5YN+t -XWdpNippv35RTD8R4bQcE6GqIUXOmtQFS2wPJLn7nisZUsGMNEs36Yl0T9iow63r -5GNAfgzpqN1XZqaSMwAdxKmlBNYpAkVXHhv+1jN+9diDYmoj9T+3Q6Zvk5e/Liyp -6i+TsDppwmmr2utWajhyJ7owFwKBgQDRROncTztGDYLfRcrIoYsPo79KQ8tqwd2a -07Usch2kplTqojCUmmhMMFgV2eZPPiCjnEy2bAYh9I/oj7xG6EwApXTshZdCpivC -rbUV64MakRTUP8IvM6PdI+apkJRsRUi/bSyIbcRlvEoCMNZhfj/5VY6w/jlwrPJj -oBOCXBlB7QKBgQDGEbEeX1i03UfYYh6uep7qbEAaooqsu5cCkBDPMO6+TmQvLPyY -Zhio6bEEQs/2w/lhwBk+xHqw5zXVMiWbtiB03F1k4eBeXxbrW+AWo7gCQ4zMfh+6 -Dm284wVwn9D1D/OaDevT31uEvcjb2ySq3/PPLSEnU8xXVaoa6/NEsX8Q5wKBgQCm -2smULWBXZKJ6n00mVxdnqun0rsVcI6Mrta14+KwGAdEnG5achdivFsTE924YtLKV -gSPxN4RUQokTprc52jHvOf1WMNYAADpYCOSfy55G6nKvIP8VX5lB00Qw4uRUx5FP -gB7H0K2NaGmiAYqNRXqAtOUG3kyyOFMzeAjWIdTJqQKBgQCHzY1c7sS1vv7mPEkr -6CpwoaEbZeFnWoHBA8Rd82psqfYsVJIRwk5Id8zgDSEmoEi8hQ9UrYbrFpLK77xq -EYSxLQHTNlM0G3lyEsv/gJhwYYhdTYiW3Cx3F6Y++jyn9O/+hFMyQvuesAL7DUYE -ptEfvzFprpQUpByXkIpuJub6fg== ------END PRIVATE KEY----- diff --git a/keystonemiddleware-moon/examples/pki/private/ssl_key.pem b/keystonemiddleware-moon/examples/pki/private/ssl_key.pem deleted file mode 100644 index 363ce94b..00000000 --- a/keystonemiddleware-moon/examples/pki/private/ssl_key.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDL06AaJROwHPgJ -9tcySSBepzJ81jYars2sMvLjyuvdiIBbhWvbS/a9Tw3WgL8H6OALkHiOU/f0A6Rp -v8dGDIDsxZQVjT/4SLaQUOeDM+9bfkKHpSd9G3CsdSSZgOH08n+MyZ7slPHfUHLY -Wso0SJD0vAi1gmGDlSM/mmhhHTpCDGo6Wbwqare6JNeTCGJTJYwrxtoMCh/W1Zrs -lPC5lFvlHD7KBBf6IU2A8Xh/dUa3p5pmQeHPW8Em90DzIB1qH0DRXl3KANc24xYR -R45pPCVkk6vFsy6P0JwwpnkszB+LcK6CEsJhLsOYvQFsiQfSZ8m7YGhgrMLxtop4 -YEPirGGrAgMBAAECggEATwvbY0hNwlb5uqOIAXBqpUqiQdexU9fG26lGmSDxKBDv -9o5frcRgBDrMWwvDCgY+HT4CAvB9kJx4/qnpVjkzJp/ZNiJ5VIiehIlbv348rXbh -xkk+bz5dDATCFOXuu1fwL2FhyM5anwhMAav0DyK1VLQ3jGzr9GO6L8hqAn+bQFFu -6ngiODwfhBMl5aRoL9UOBEhccK07znrH0JGRz+3+5Cdz59Xw91Bv210LhNNDL58+ -0JD0N+YztVOQd2bgwo0bQbOEijzmYq+0mjoqAnJh1/++y7PlIPs0AnPgqSnFPx9+ -6FsQEVRgk5Uq3kvPLaP4nT2y6MDZSp+ujYldvJhyQQKBgQDuX2pZIJMZ4aFnkG+K -TmJ5wsLa/u9an0TmvAL9RLtBpVpQNKD8cQ+y8PUZavXDbAIt5NWqZVnTbCR79Dnd -mZKblwcHhtsyA5f89el5KcxY2BREWdHdTnJpNd7XRlUECmzvX1zGj77lA982PhII -yflRBRV3vqLkgC8vfoYgRyRElwKBgQDa5jnLdx/RahfYMOgn1HE5o4hMzLR4Y0Dd -+gELshcUbPqouoP5zOb8WOagVJIgZVOSN+/VqbilVYrqRiNTn2rnoxs+HHRdaJNN -3eXllD4J2HfC2BIj1xSpIdyh2XewAJqw9IToHNB29QUhxOtgwseHciPG6JaKH2ik -kqGKH/EKDQKBgFFAftygiOPCkCTgC9UmANUmOQsy6N2H+pF3tsEj43xt44oBVnqW -A1boYXNnjRwuvdNs9BPf9i1l6E3EItFRXrLgWQoMwryakv0ryYh+YeRKyyW9RBbe -fYs1TJ8unx4Ae79gTxxztQsVNcmkgLs0NWKTjAzEE3w14V+cDhYEie1DAoGBAJdI -V5cLrBzBstsB6eBlDR9lqrRRIUS2a8U9m+1mVlcSfiWQSdehSd4K3tDdwePLw3ch -W4qR8n+pYAlLEe0gFvUhn5lMdwt7U5qUCeehjUKmrRYm2FqWsbu2IFJnBjXIJSC4 -zQXRrC0aZ0KQYpAL7XPpaVp1slyhGmPqxuO78Y0dAoGBAMHo3EIMwu9rfuGwFodr -GFsOZhfJqgo5GDNxxf89Q9WWpMDTCdX+wdBTrN/wsMbBuwIDHrUuRnk6D5CWRjSk -/ikCgHN3kOtrbL8zzqRomGAIIWKYGFEIGe1GHVGo5r//HXHdPxFXygvruQ/xbOA4 -RGvmDiji8vVDq7Shho8I6KuT ------END PRIVATE KEY----- diff --git a/keystonemiddleware-moon/examples/pki/run_all.sh b/keystonemiddleware-moon/examples/pki/run_all.sh deleted file mode 100755 index ba2f0b6e..00000000 --- a/keystonemiddleware-moon/examples/pki/run_all.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash -x - -# Copyright 2012 OpenStack Foundation -# -# 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. - -# This script generates the crypto necessary for the SSL tests. - -. gen_pki.sh - -check_openssl -rm_old -cleanup -setup -generate_ca -ssl_cert_req -cms_signing_cert_req -issue_certs -create_middleware_cert -gen_sample_cms -cleanup diff --git a/keystonemiddleware-moon/keystonemiddleware.egg-info/dependency_links.txt b/keystonemiddleware-moon/keystonemiddleware.egg-info/dependency_links.txt deleted file mode 100644 index 8b137891..00000000 --- a/keystonemiddleware-moon/keystonemiddleware.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/keystonemiddleware-moon/keystonemiddleware.egg-info/entry_points.txt b/keystonemiddleware-moon/keystonemiddleware.egg-info/entry_points.txt deleted file mode 100644 index 8bc83366..00000000 --- a/keystonemiddleware-moon/keystonemiddleware.egg-info/entry_points.txt +++ /dev/null @@ -1,3 +0,0 @@ -[oslo.config.opts] -keystonemiddleware.auth_token = keystonemiddleware.opts:list_auth_token_opts - diff --git a/keystonemiddleware-moon/keystonemiddleware.egg-info/not-zip-safe b/keystonemiddleware-moon/keystonemiddleware.egg-info/not-zip-safe deleted file mode 100644 index 8b137891..00000000 --- a/keystonemiddleware-moon/keystonemiddleware.egg-info/not-zip-safe +++ /dev/null @@ -1 +0,0 @@ - diff --git a/keystonemiddleware-moon/keystonemiddleware.egg-info/top_level.txt b/keystonemiddleware-moon/keystonemiddleware.egg-info/top_level.txt deleted file mode 100644 index 0622f2ef..00000000 --- a/keystonemiddleware-moon/keystonemiddleware.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -keystonemiddleware diff --git a/keystonemiddleware-moon/keystonemiddleware/__init__.py b/keystonemiddleware-moon/keystonemiddleware/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/keystonemiddleware-moon/keystonemiddleware/audit.py b/keystonemiddleware-moon/keystonemiddleware/audit.py deleted file mode 100644 index e3536092..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/audit.py +++ /dev/null @@ -1,449 +0,0 @@ -# -# 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. - -""" -Build open standard audit information based on incoming requests - -AuditMiddleware filter should be placed after keystonemiddleware.auth_token -in the pipeline so that it can utilise the information the Identity server -provides. -""" - -import ast -import collections -import functools -import logging -import os.path -import re -import sys - -from oslo_config import cfg -from oslo_context import context -try: - import oslo_messaging - messaging = True -except ImportError: - messaging = False -from pycadf import cadftaxonomy as taxonomy -from pycadf import cadftype -from pycadf import credential -from pycadf import endpoint -from pycadf import eventfactory as factory -from pycadf import host -from pycadf import identifier -from pycadf import reason -from pycadf import reporterstep -from pycadf import resource -from pycadf import tag -from pycadf import timestamp -import six -from six.moves import configparser -from six.moves.urllib import parse as urlparse -import webob.dec - -from keystonemiddleware.i18n import _LE, _LI - - -_LOG = None - - -def _log_and_ignore_error(fn): - @functools.wraps(fn) - def wrapper(*args, **kwargs): - try: - return fn(*args, **kwargs) - except Exception as e: - _LOG.exception(_LE('An exception occurred processing ' - 'the API call: %s '), e) - return wrapper - - -Service = collections.namedtuple('Service', - ['id', 'name', 'type', 'admin_endp', - 'public_endp', 'private_endp']) - - -AuditMap = collections.namedtuple('AuditMap', - ['path_kw', - 'custom_actions', - 'service_endpoints', - 'default_target_endpoint_type']) - - -# NOTE(blk-u): Compatibility for Python 2. SafeConfigParser and -# SafeConfigParser.readfp are deprecated in Python 3. Remove this when we drop -# support for Python 2. -if six.PY2: - class _ConfigParser(configparser.SafeConfigParser): - read_file = configparser.SafeConfigParser.readfp -else: - _ConfigParser = configparser.ConfigParser - - -class OpenStackAuditApi(object): - - def __init__(self, cfg_file): - """Configure to recognize and map known api paths.""" - path_kw = {} - custom_actions = {} - endpoints = {} - default_target_endpoint_type = None - - if cfg_file: - try: - map_conf = _ConfigParser() - map_conf.read_file(open(cfg_file)) - - try: - default_target_endpoint_type = map_conf.get( - 'DEFAULT', 'target_endpoint_type') - except configparser.NoOptionError: - pass - - try: - custom_actions = dict(map_conf.items('custom_actions')) - except configparser.Error: - pass - - try: - path_kw = dict(map_conf.items('path_keywords')) - except configparser.Error: - pass - - try: - endpoints = dict(map_conf.items('service_endpoints')) - except configparser.Error: - pass - except configparser.ParsingError as err: - raise PycadfAuditApiConfigError( - 'Error parsing audit map file: %s' % err) - self._MAP = AuditMap( - path_kw=path_kw, custom_actions=custom_actions, - service_endpoints=endpoints, - default_target_endpoint_type=default_target_endpoint_type) - - @staticmethod - def _clean_path(value): - """Clean path if path has json suffix.""" - return value[:-5] if value.endswith('.json') else value - - def get_action(self, req): - """Take a given Request, parse url path to calculate action type. - - Depending on req.method: - - if POST: - - - path ends with 'action', read the body and use as action; - - path ends with known custom_action, take action from config; - - request ends with known path, assume is create action; - - request ends with unknown path, assume is update action. - - if GET: - - - request ends with known path, assume is list action; - - request ends with unknown path, assume is read action. - - if PUT, assume update action. - if DELETE, assume delete action. - if HEAD, assume read action. - - """ - path = req.path[:-1] if req.path.endswith('/') else req.path - url_ending = self._clean_path(path[path.rfind('/') + 1:]) - method = req.method - - if url_ending + '/' + method.lower() in self._MAP.custom_actions: - action = self._MAP.custom_actions[url_ending + '/' + - method.lower()] - elif url_ending in self._MAP.custom_actions: - action = self._MAP.custom_actions[url_ending] - elif method == 'POST': - if url_ending == 'action': - try: - if req.json: - body_action = list(req.json.keys())[0] - action = taxonomy.ACTION_UPDATE + '/' + body_action - else: - action = taxonomy.ACTION_CREATE - except ValueError: - action = taxonomy.ACTION_CREATE - elif url_ending not in self._MAP.path_kw: - action = taxonomy.ACTION_UPDATE - else: - action = taxonomy.ACTION_CREATE - elif method == 'GET': - if url_ending in self._MAP.path_kw: - action = taxonomy.ACTION_LIST - else: - action = taxonomy.ACTION_READ - elif method == 'PUT' or method == 'PATCH': - action = taxonomy.ACTION_UPDATE - elif method == 'DELETE': - action = taxonomy.ACTION_DELETE - elif method == 'HEAD': - action = taxonomy.ACTION_READ - else: - action = taxonomy.UNKNOWN - - return action - - def _get_service_info(self, endp): - service = Service( - type=self._MAP.service_endpoints.get( - endp['type'], - taxonomy.UNKNOWN), - name=endp['name'], - id=identifier.norm_ns(endp['endpoints'][0].get('id', - endp['name'])), - admin_endp=endpoint.Endpoint( - name='admin', - url=endp['endpoints'][0].get('adminURL', taxonomy.UNKNOWN)), - private_endp=endpoint.Endpoint( - name='private', - url=endp['endpoints'][0].get('internalURL', taxonomy.UNKNOWN)), - public_endp=endpoint.Endpoint( - name='public', - url=endp['endpoints'][0].get('publicURL', taxonomy.UNKNOWN))) - - return service - - def _build_typeURI(self, req, service_type): - """Build typeURI of target - - Combines service type and corresponding path for greater detail. - """ - type_uri = '' - prev_key = None - for key in re.split('/', req.path): - key = self._clean_path(key) - if key in self._MAP.path_kw: - type_uri += '/' + key - elif prev_key in self._MAP.path_kw: - type_uri += '/' + self._MAP.path_kw[prev_key] - prev_key = key - return service_type + type_uri - - def _build_target(self, req, service): - """Build target resource.""" - target_typeURI = ( - self._build_typeURI(req, service.type) - if service.type != taxonomy.UNKNOWN else service.type) - target = resource.Resource(typeURI=target_typeURI, - id=service.id, name=service.name) - if service.admin_endp: - target.add_address(service.admin_endp) - if service.private_endp: - target.add_address(service.private_endp) - if service.public_endp: - target.add_address(service.public_endp) - return target - - def get_target_resource(self, req): - """Retrieve target information - - If discovery is enabled, target will attempt to retrieve information - from service catalog. If not, the information will be taken from - given config file. - """ - service_info = Service(type=taxonomy.UNKNOWN, name=taxonomy.UNKNOWN, - id=taxonomy.UNKNOWN, admin_endp=None, - private_endp=None, public_endp=None) - try: - catalog = ast.literal_eval( - req.environ['HTTP_X_SERVICE_CATALOG']) - except KeyError: - raise PycadfAuditApiConfigError( - 'Service catalog is missing. ' - 'Cannot discover target information') - - default_endpoint = None - for endp in catalog: - endpoint_urls = endp['endpoints'][0] - admin_urlparse = urlparse.urlparse( - endpoint_urls.get('adminURL', '')) - public_urlparse = urlparse.urlparse( - endpoint_urls.get('publicURL', '')) - req_url = urlparse.urlparse(req.host_url) - if (req_url.netloc == admin_urlparse.netloc - or req_url.netloc == public_urlparse.netloc): - service_info = self._get_service_info(endp) - break - elif (self._MAP.default_target_endpoint_type and - endp['type'] == self._MAP.default_target_endpoint_type): - default_endpoint = endp - else: - if default_endpoint: - service_info = self._get_service_info(default_endpoint) - return self._build_target(req, service_info) - - -class ClientResource(resource.Resource): - def __init__(self, project_id=None, **kwargs): - super(ClientResource, self).__init__(**kwargs) - if project_id is not None: - self.project_id = project_id - - -class KeystoneCredential(credential.Credential): - def __init__(self, identity_status=None, **kwargs): - super(KeystoneCredential, self).__init__(**kwargs) - if identity_status is not None: - self.identity_status = identity_status - - -class PycadfAuditApiConfigError(Exception): - """Error raised when pyCADF fails to configure correctly.""" - - -class AuditMiddleware(object): - """Create an audit event based on request/response. - - The audit middleware takes in various configuration options such as the - ability to skip audit of certain requests. The full list of options can - be discovered here: - http://docs.openstack.org/developer/keystonemiddleware/audit.html - """ - - @staticmethod - def _get_aliases(proj): - aliases = {} - if proj: - # Aliases to support backward compatibility - aliases = { - '%s.openstack.common.rpc.impl_kombu' % proj: 'rabbit', - '%s.openstack.common.rpc.impl_qpid' % proj: 'qpid', - '%s.openstack.common.rpc.impl_zmq' % proj: 'zmq', - '%s.rpc.impl_kombu' % proj: 'rabbit', - '%s.rpc.impl_qpid' % proj: 'qpid', - '%s.rpc.impl_zmq' % proj: 'zmq', - } - return aliases - - def __init__(self, app, **conf): - self._application = app - global _LOG - _LOG = logging.getLogger(conf.get('log_name', __name__)) - self._service_name = conf.get('service_name') - self._ignore_req_list = [x.upper().strip() for x in - conf.get('ignore_req_list', '').split(',')] - self._cadf_audit = OpenStackAuditApi(conf.get('audit_map_file')) - - transport_aliases = self._get_aliases(cfg.CONF.project) - if messaging: - self._notifier = oslo_messaging.Notifier( - oslo_messaging.get_transport(cfg.CONF, - aliases=transport_aliases), - os.path.basename(sys.argv[0])) - - def _emit_audit(self, context, event_type, payload): - """Emit audit notification - - if oslo.messaging enabled, send notification. if not, log event. - """ - - if messaging: - self._notifier.info(context, event_type, payload) - else: - _LOG.info(_LI('Event type: %(event_type)s, Context: %(context)s, ' - 'Payload: %(payload)s'), {'context': context, - 'event_type': event_type, - 'payload': payload}) - - def _create_event(self, req): - correlation_id = identifier.generate_uuid() - action = self._cadf_audit.get_action(req) - - initiator = ClientResource( - typeURI=taxonomy.ACCOUNT_USER, - id=identifier.norm_ns(str(req.environ['HTTP_X_USER_ID'])), - name=req.environ['HTTP_X_USER_NAME'], - host=host.Host(address=req.client_addr, agent=req.user_agent), - credential=KeystoneCredential( - token=req.environ['HTTP_X_AUTH_TOKEN'], - identity_status=req.environ['HTTP_X_IDENTITY_STATUS']), - project_id=identifier.norm_ns(req.environ['HTTP_X_PROJECT_ID'])) - target = self._cadf_audit.get_target_resource(req) - - event = factory.EventFactory().new_event( - eventType=cadftype.EVENTTYPE_ACTIVITY, - outcome=taxonomy.OUTCOME_PENDING, - action=action, - initiator=initiator, - target=target, - observer=resource.Resource(id='target')) - event.requestPath = req.path_qs - event.add_tag(tag.generate_name_value_tag('correlation_id', - correlation_id)) - # cache model in request to allow tracking of transistive steps. - req.environ['cadf_event'] = event - return event - - @_log_and_ignore_error - def _process_request(self, request): - event = self._create_event(request) - - self._emit_audit(context.get_admin_context().to_dict(), - 'audit.http.request', event.as_dict()) - - @_log_and_ignore_error - def _process_response(self, request, response=None): - # NOTE(gordc): handle case where error processing request - if 'cadf_event' not in request.environ: - self._create_event(request) - event = request.environ['cadf_event'] - - if response: - if response.status_int >= 200 and response.status_int < 400: - result = taxonomy.OUTCOME_SUCCESS - else: - result = taxonomy.OUTCOME_FAILURE - event.reason = reason.Reason( - reasonType='HTTP', reasonCode=str(response.status_int)) - else: - result = taxonomy.UNKNOWN - - event.outcome = result - event.add_reporterstep( - reporterstep.Reporterstep( - role=cadftype.REPORTER_ROLE_MODIFIER, - reporter=resource.Resource(id='target'), - reporterTime=timestamp.get_utc_now())) - - self._emit_audit(context.get_admin_context().to_dict(), - 'audit.http.response', event.as_dict()) - - @webob.dec.wsgify - def __call__(self, req): - if req.method in self._ignore_req_list: - return req.get_response(self._application) - - self._process_request(req) - try: - response = req.get_response(self._application) - except Exception: - self._process_response(req) - raise - else: - self._process_response(req, response) - return response - - -def filter_factory(global_conf, **local_conf): - """Returns a WSGI filter app for use with paste.deploy.""" - conf = global_conf.copy() - conf.update(local_conf) - - def audit_filter(app): - return AuditMiddleware(app, **conf) - return audit_filter diff --git a/keystonemiddleware-moon/keystonemiddleware/auth_token/__init__.py b/keystonemiddleware-moon/keystonemiddleware/auth_token/__init__.py deleted file mode 100644 index be268da3..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/auth_token/__init__.py +++ /dev/null @@ -1,1129 +0,0 @@ -# Copyright 2010-2012 OpenStack Foundation -# -# 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. - -""" -Token-based Authentication Middleware - -This WSGI component: - -* Verifies that incoming client requests have valid tokens by validating - tokens with the auth service. -* Rejects unauthenticated requests unless the auth_token middleware is in - ``delay_auth_decision`` mode, which means the final decision is delegated to - the downstream WSGI component (usually the OpenStack service). -* Collects and forwards identity information based on a valid token - such as user name, domain, project, etc. - -Refer to: http://docs.openstack.org/developer/keystonemiddleware/\ -middlewarearchitecture.html - - -Headers -------- - -The auth_token middleware uses headers sent in by the client on the request -and sets headers and environment variables for the downstream WSGI component. - -Coming in from initial call from client or customer -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -HTTP_X_AUTH_TOKEN - The client token being passed in. - -HTTP_X_SERVICE_TOKEN - A service token being passed in. - -Used for communication between components -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -WWW-Authenticate - HTTP header returned to a user indicating which endpoint to use - to retrieve a new token. - -What auth_token adds to the request for use by the OpenStack service -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -When using composite authentication (a user and service token are -present) additional service headers relating to the service user -will be added. They take the same form as the standard headers but add -``_SERVICE_``. These headers will not exist in the environment if no -service token is present. - -HTTP_X_IDENTITY_STATUS, HTTP_X_SERVICE_IDENTITY_STATUS - Will be set to either ``Confirmed`` or ``Invalid``. - - The underlying service will only see a value of 'Invalid' if the middleware - is configured to run in ``delay_auth_decision`` mode. As with all such - headers, ``HTTP_X_SERVICE_IDENTITY_STATUS`` will only exist in the - environment if a service token is presented. This is different than - ``HTTP_X_IDENTITY_STATUS`` which is always set even if no user token is - presented. This allows the underlying service to determine if a - denial should use ``401 Unauthenticated`` or ``403 Forbidden``. - -HTTP_X_DOMAIN_ID, HTTP_X_SERVICE_DOMAIN_ID - Identity service managed unique identifier, string. Only present if - this is a domain-scoped token. - -HTTP_X_DOMAIN_NAME, HTTP_X_SERVICE_DOMAIN_NAME - Unique domain name, string. Only present if this is a domain-scoped - token. - -HTTP_X_PROJECT_ID, HTTP_X_SERVICE_PROJECT_ID - Identity service managed unique identifier, string. Only present if - this is a project-scoped token. - -HTTP_X_PROJECT_NAME, HTTP_X_SERVICE_PROJECT_NAME - Project name, unique within owning domain, string. Only present if - this is a project-scoped token. - -HTTP_X_PROJECT_DOMAIN_ID, HTTP_X_SERVICE_PROJECT_DOMAIN_ID - Identity service managed unique identifier of owning domain of - project, string. Only present if this is a project-scoped v3 token. If - this variable is set, this indicates that the PROJECT_NAME can only - be assumed to be unique within this domain. - -HTTP_X_PROJECT_DOMAIN_NAME, HTTP_X_SERVICE_PROJECT_DOMAIN_NAME - Name of owning domain of project, string. Only present if this is a - project-scoped v3 token. If this variable is set, this indicates that - the PROJECT_NAME can only be assumed to be unique within this domain. - -HTTP_X_USER_ID, HTTP_X_SERVICE_USER_ID - Identity-service managed unique identifier, string. - -HTTP_X_USER_NAME, HTTP_X_SERVICE_USER_NAME - User identifier, unique within owning domain, string. - -HTTP_X_USER_DOMAIN_ID, HTTP_X_SERVICE_USER_DOMAIN_ID - Identity service managed unique identifier of owning domain of - user, string. If this variable is set, this indicates that the USER_NAME - can only be assumed to be unique within this domain. - -HTTP_X_USER_DOMAIN_NAME, HTTP_X_SERVICE_USER_DOMAIN_NAME - Name of owning domain of user, string. If this variable is set, this - indicates that the USER_NAME can only be assumed to be unique within - this domain. - -HTTP_X_ROLES, HTTP_X_SERVICE_ROLES - Comma delimited list of case-sensitive role names. - -HTTP_X_SERVICE_CATALOG - service catalog (optional, JSON string). - - For compatibility reasons this catalog will always be in the V2 catalog - format even if it is a v3 token. - - .. note:: This is an exception in that it contains 'SERVICE' but relates to - a user token, not a service token. The existing user's catalog can be - very large; it was decided not to present a catalog relating to the - service token to avoid using more HTTP header space. - -HTTP_X_TENANT_ID - *Deprecated* in favor of HTTP_X_PROJECT_ID. - - Identity service managed unique identifier, string. For v3 tokens, this - will be set to the same value as HTTP_X_PROJECT_ID. - -HTTP_X_TENANT_NAME - *Deprecated* in favor of HTTP_X_PROJECT_NAME. - - Project identifier, unique within owning domain, string. For v3 tokens, - this will be set to the same value as HTTP_X_PROJECT_NAME. - -HTTP_X_TENANT - *Deprecated* in favor of HTTP_X_TENANT_ID and HTTP_X_TENANT_NAME. - - Identity server-assigned unique identifier, string. For v3 tokens, this - will be set to the same value as HTTP_X_PROJECT_ID. - -HTTP_X_USER - *Deprecated* in favor of HTTP_X_USER_ID and HTTP_X_USER_NAME. - - User name, unique within owning domain, string. - -HTTP_X_ROLE - *Deprecated* in favor of HTTP_X_ROLES. - - Will contain the same values as HTTP_X_ROLES. - -Environment Variables -^^^^^^^^^^^^^^^^^^^^^ - -These variables are set in the request environment for use by the downstream -WSGI component. - -keystone.token_info - Information about the token discovered in the process of validation. This - may include extended information returned by the token validation call, as - well as basic information about the project and user. - -keystone.token_auth - A keystoneclient auth plugin that may be used with a - :py:class:`keystoneclient.session.Session`. This plugin will load the - authentication data provided to auth_token middleware. - - -Configuration -------------- - -auth_token middleware configuration can be in the main application's -configuration file, e.g. in ``nova.conf``: - -.. code-block:: ini - - [keystone_authtoken] - auth_plugin = password - auth_url = http://keystone:35357/ - username = nova - user_domain_id = default - password = whyarewestillusingpasswords - project_name = service - project_domain_id = default - -Configuration can also be in the ``api-paste.ini`` file with the same options, -but this is discouraged. - -Swift ------ - -When deploy auth_token middleware with Swift, user may elect to use Swift -memcache instead of the local auth_token memcache. Swift memcache is passed in -from the request environment and it's identified by the ``swift.cache`` key. -However it could be different, depending on deployment. To use Swift memcache, -you must set the ``cache`` option to the environment key where the Swift cache -object is stored. - -""" - -import binascii -import datetime -import logging - -from keystoneclient import access -from keystoneclient import adapter -from keystoneclient import auth -from keystoneclient.common import cms -from keystoneclient import discover -from keystoneclient import exceptions -from keystoneclient import session -from oslo_config import cfg -from oslo_serialization import jsonutils -import pkg_resources -import six -import webob.dec - -from keystonemiddleware.auth_token import _auth -from keystonemiddleware.auth_token import _base -from keystonemiddleware.auth_token import _cache -from keystonemiddleware.auth_token import _exceptions as exc -from keystonemiddleware.auth_token import _identity -from keystonemiddleware.auth_token import _request -from keystonemiddleware.auth_token import _revocations -from keystonemiddleware.auth_token import _signing_dir -from keystonemiddleware.auth_token import _user_plugin -from keystonemiddleware.i18n import _, _LC, _LE, _LI, _LW - - -# NOTE(jamielennox): A number of options below are deprecated however are left -# in the list and only mentioned as deprecated in the help string. This is -# because we have to provide the same deprecation functionality for arguments -# passed in via the conf in __init__ (from paste) and there is no way to test -# that the default value was set or not in CONF. -# Also if we were to remove the options from the CONF list (as typical CONF -# deprecation works) then other projects will not be able to override the -# options via CONF. - -_OPTS = [ - cfg.StrOpt('auth_uri', - default=None, - # FIXME(dolph): should be default='http://127.0.0.1:5000/v2.0/', - # or (depending on client support) an unversioned, publicly - # accessible identity endpoint (see bug 1207517) - help='Complete public Identity API endpoint.'), - cfg.StrOpt('auth_version', - default=None, - help='API version of the admin Identity API endpoint.'), - cfg.BoolOpt('delay_auth_decision', - default=False, - help='Do not handle authorization requests within the' - ' middleware, but delegate the authorization decision to' - ' downstream WSGI components.'), - cfg.IntOpt('http_connect_timeout', - default=None, - help='Request timeout value for communicating with Identity' - ' API server.'), - cfg.IntOpt('http_request_max_retries', - default=3, - help='How many times are we trying to reconnect when' - ' communicating with Identity API Server.'), - cfg.StrOpt('cache', - default=None, - help='Env key for the swift cache.'), - cfg.StrOpt('certfile', - help='Required if identity server requires client certificate'), - cfg.StrOpt('keyfile', - help='Required if identity server requires client certificate'), - cfg.StrOpt('cafile', default=None, - help='A PEM encoded Certificate Authority to use when ' - 'verifying HTTPs connections. Defaults to system CAs.'), - cfg.BoolOpt('insecure', default=False, help='Verify HTTPS connections.'), - cfg.StrOpt('region_name', default=None, - help='The region in which the identity server can be found.'), - cfg.StrOpt('signing_dir', - help='Directory used to cache files related to PKI tokens.'), - cfg.ListOpt('memcached_servers', - deprecated_name='memcache_servers', - help='Optionally specify a list of memcached server(s) to' - ' use for caching. If left undefined, tokens will instead be' - ' cached in-process.'), - cfg.IntOpt('token_cache_time', - default=300, - help='In order to prevent excessive effort spent validating' - ' tokens, the middleware caches previously-seen tokens for a' - ' configurable duration (in seconds). Set to -1 to disable' - ' caching completely.'), - cfg.IntOpt('revocation_cache_time', - default=10, - help='Determines the frequency at which the list of revoked' - ' tokens is retrieved from the Identity service (in seconds). A' - ' high number of revocation events combined with a low cache' - ' duration may significantly reduce performance.'), - cfg.StrOpt('memcache_security_strategy', - default=None, - help='(Optional) If defined, indicate whether token data' - ' should be authenticated or authenticated and encrypted.' - ' Acceptable values are MAC or ENCRYPT. If MAC, token data is' - ' authenticated (with HMAC) in the cache. If ENCRYPT, token' - ' data is encrypted and authenticated in the cache. If the' - ' value is not one of these options or empty, auth_token will' - ' raise an exception on initialization.'), - cfg.StrOpt('memcache_secret_key', - default=None, - secret=True, - help='(Optional, mandatory if memcache_security_strategy is' - ' defined) This string is used for key derivation.'), - cfg.IntOpt('memcache_pool_dead_retry', - default=5 * 60, - help='(Optional) Number of seconds memcached server is' - ' considered dead before it is tried again.'), - cfg.IntOpt('memcache_pool_maxsize', - default=10, - help='(Optional) Maximum total number of open connections to' - ' every memcached server.'), - cfg.IntOpt('memcache_pool_socket_timeout', - default=3, - help='(Optional) Socket timeout in seconds for communicating ' - 'with a memcached server.'), - cfg.IntOpt('memcache_pool_unused_timeout', - default=60, - help='(Optional) Number of seconds a connection to memcached' - ' is held unused in the pool before it is closed.'), - cfg.IntOpt('memcache_pool_conn_get_timeout', - default=10, - help='(Optional) Number of seconds that an operation will wait ' - 'to get a memcached client connection from the pool.'), - cfg.BoolOpt('memcache_use_advanced_pool', - default=False, - help='(Optional) Use the advanced (eventlet safe) memcached ' - 'client pool. The advanced pool will only work under ' - 'python 2.x.'), - cfg.BoolOpt('include_service_catalog', - default=True, - help='(Optional) Indicate whether to set the X-Service-Catalog' - ' header. If False, middleware will not ask for service' - ' catalog on token validation and will not set the' - ' X-Service-Catalog header.'), - cfg.StrOpt('enforce_token_bind', - default='permissive', - help='Used to control the use and type of token binding. Can' - ' be set to: "disabled" to not check token binding.' - ' "permissive" (default) to validate binding information if the' - ' bind type is of a form known to the server and ignore it if' - ' not. "strict" like "permissive" but if the bind type is' - ' unknown the token will be rejected. "required" any form of' - ' token binding is needed to be allowed. Finally the name of a' - ' binding method that must be present in tokens.'), - cfg.BoolOpt('check_revocations_for_cached', default=False, - help='If true, the revocation list will be checked for cached' - ' tokens. This requires that PKI tokens are configured on the' - ' identity server.'), - cfg.ListOpt('hash_algorithms', default=['md5'], - help='Hash algorithms to use for hashing PKI tokens. This may' - ' be a single algorithm or multiple. The algorithms are those' - ' supported by Python standard hashlib.new(). The hashes will' - ' be tried in the order given, so put the preferred one first' - ' for performance. The result of the first hash will be stored' - ' in the cache. This will typically be set to multiple values' - ' only while migrating from a less secure algorithm to a more' - ' secure one. Once all the old tokens are expired this option' - ' should be set to a single value for better performance.'), -] - -CONF = cfg.CONF -CONF.register_opts(_OPTS, group=_base.AUTHTOKEN_GROUP) - -_LOG = logging.getLogger(__name__) - - -class _BIND_MODE(object): - DISABLED = 'disabled' - PERMISSIVE = 'permissive' - STRICT = 'strict' - REQUIRED = 'required' - KERBEROS = 'kerberos' - - -def _token_is_v2(token_info): - return ('access' in token_info) - - -def _token_is_v3(token_info): - return ('token' in token_info) - - -def _conf_values_type_convert(conf): - """Convert conf values into correct type.""" - if not conf: - return {} - - opt_types = {} - for o in (_OPTS + _auth.AuthTokenPlugin.get_options()): - type_dest = (getattr(o, 'type', str), o.dest) - opt_types[o.dest] = type_dest - # Also add the deprecated name with the same type and dest. - for d_o in o.deprecated_opts: - opt_types[d_o.name] = type_dest - - opts = {} - for k, v in six.iteritems(conf): - dest = k - try: - if v is not None: - type_, dest = opt_types[k] - v = type_(v) - except KeyError: - # This option is not known to auth_token. - pass - except ValueError as e: - raise exc.ConfigurationError( - _('Unable to convert the value of %(key)s option into correct ' - 'type: %(ex)s') % {'key': k, 'ex': e}) - opts[dest] = v - return opts - - -def _get_project_version(project): - return pkg_resources.get_distribution(project).version - - -class _BaseAuthProtocol(object): - """A base class for AuthProtocol token checking implementations. - - :param Callable app: The next application to call after middleware. - :param logging.Logger log: The logging object to use for output. By default - it will use a logger in the - keystonemiddleware.auth_token namespace. - :param str enforce_token_bind: The style of token binding enforcement to - perform. - """ - - def __init__(self, - app, - log=_LOG, - enforce_token_bind=_BIND_MODE.PERMISSIVE): - self.log = log - self._app = app - self._enforce_token_bind = enforce_token_bind - - @webob.dec.wsgify(RequestClass=_request._AuthTokenRequest) - def __call__(self, req): - """Handle incoming request.""" - response = self.process_request(req) - if response: - return response - response = req.get_response(self._app) - return self.process_response(response) - - def process_request(self, request): - """Process request. - - If this method returns a value then that value will be used as the - response. The next application down the stack will not be executed and - process_response will not be called. - - Otherwise, the next application down the stack will be executed and - process_response will be called with the generated response. - - By default this method does not return a value. - - :param request: Incoming request - :type request: _request.AuthTokenRequest - - """ - request.remove_auth_headers() - - user_auth_ref = None - serv_auth_ref = None - - if request.user_token: - self.log.debug('Authenticating user token') - try: - data, user_auth_ref = self._do_fetch_token(request.user_token) - self._validate_token(user_auth_ref) - self._confirm_token_bind(user_auth_ref, request) - except exc.InvalidToken: - self.log.info(_LI('Invalid user token')) - request.user_token_valid = False - else: - request.user_token_valid = True - request.environ['keystone.token_info'] = data - - if request.service_token: - self.log.debug('Authenticating service token') - try: - _, serv_auth_ref = self._do_fetch_token(request.service_token) - self._validate_token(serv_auth_ref) - self._confirm_token_bind(serv_auth_ref, request) - except exc.InvalidToken: - self.log.info(_LI('Invalid service token')) - request.service_token_valid = False - else: - request.service_token_valid = True - - p = _user_plugin.UserAuthPlugin(user_auth_ref, serv_auth_ref) - request.environ['keystone.token_auth'] = p - - def _validate_token(self, auth_ref): - """Perform the validation steps on the token. - - :param auth_ref: The token data - :type auth_ref: keystoneclient.access.AccessInfo - - :raises exc.InvalidToken: if token is rejected - """ - # 0 seconds of validity means is it valid right now. - if auth_ref.will_expire_soon(stale_duration=0): - raise exc.InvalidToken(_('Token authorization failed')) - - def _do_fetch_token(self, token): - """Helper method to fetch a token and convert it into an AccessInfo""" - data = self._fetch_token(token) - - try: - return data, access.AccessInfo.factory(body=data, auth_token=token) - except Exception: - self.log.warning(_LW('Invalid token contents.'), exc_info=True) - raise exc.InvalidToken(_('Token authorization failed')) - - def _fetch_token(self, token): - """Fetch the token data based on the value in the header. - - Retrieve the data associated with the token value that was in the - header. This can be from PKI, contacting the identity server or - whatever is required. - - :param str token: The token present in the request header. - - :raises exc.InvalidToken: if token is invalid. - - :returns: The token data - :rtype: dict - """ - raise NotImplemented() - - def process_response(self, response): - """Do whatever you'd like to the response. - - By default the response is returned unmodified. - - :param response: Response object - :type response: ._request._AuthTokenResponse - """ - return response - - def _invalid_user_token(self, msg=False): - # NOTE(jamielennox): use False as the default so that None is valid - if msg is False: - msg = _('Token authorization failed') - - raise exc.InvalidToken(msg) - - def _confirm_token_bind(self, auth_ref, req): - if self._enforce_token_bind == _BIND_MODE.DISABLED: - return - - try: - if auth_ref.version == 'v2.0': - bind = auth_ref['token']['bind'] - elif auth_ref.version == 'v3': - bind = auth_ref['bind'] - else: - self._invalid_user_token() - except KeyError: - bind = {} - - # permissive and strict modes don't require there to be a bind - permissive = self._enforce_token_bind in (_BIND_MODE.PERMISSIVE, - _BIND_MODE.STRICT) - - if not bind: - if permissive: - # no bind provided and none required - return - else: - self.log.info(_LI('No bind information present in token.')) - self._invalid_user_token() - - # get the named mode if bind_mode is not one of the predefined - if permissive or self._enforce_token_bind == _BIND_MODE.REQUIRED: - name = None - else: - name = self._enforce_token_bind - - if name and name not in bind: - self.log.info(_LI('Named bind mode %s not in bind information'), - name) - self._invalid_user_token() - - for bind_type, identifier in six.iteritems(bind): - if bind_type == _BIND_MODE.KERBEROS: - if req.auth_type != 'negotiate': - self.log.info(_LI('Kerberos credentials required and ' - 'not present.')) - self._invalid_user_token() - - if req.remote_user != identifier: - self.log.info(_LI('Kerberos credentials do not match ' - 'those in bind.')) - self._invalid_user_token() - - self.log.debug('Kerberos bind authentication successful.') - - elif self._enforce_token_bind == _BIND_MODE.PERMISSIVE: - self.log.debug('Ignoring Unknown bind for permissive mode: ' - '%(bind_type)s: %(identifier)s.', - {'bind_type': bind_type, - 'identifier': identifier}) - - else: - self.log.info( - _LI('Couldn`t verify unknown bind: %(bind_type)s: ' - '%(identifier)s.'), - {'bind_type': bind_type, 'identifier': identifier}) - self._invalid_user_token() - - -class AuthProtocol(_BaseAuthProtocol): - """Middleware that handles authenticating client calls.""" - - _SIGNING_CERT_FILE_NAME = 'signing_cert.pem' - _SIGNING_CA_FILE_NAME = 'cacert.pem' - - def __init__(self, app, conf): - log = logging.getLogger(conf.get('log_name', __name__)) - log.info(_LI('Starting Keystone auth_token middleware')) - - # NOTE(wanghong): If options are set in paste file, all the option - # values passed into conf are string type. So, we should convert the - # conf value into correct type. - self._conf = _conf_values_type_convert(conf) - - # NOTE(sileht): If we don't want to use oslo.config global object - # we can set the paste "oslo_config_project" and the middleware - # will load the configuration with a local oslo.config object. - self._local_oslo_config = None - if 'oslo_config_project' in conf: - if 'oslo_config_file' in conf: - default_config_files = [conf['oslo_config_file']] - else: - default_config_files = None - - # For unit tests, support passing in a ConfigOpts in - # oslo_config_config. - self._local_oslo_config = conf.get('oslo_config_config', - cfg.ConfigOpts()) - self._local_oslo_config( - {}, project=conf['oslo_config_project'], - default_config_files=default_config_files, - validate_default_values=True) - - self._local_oslo_config.register_opts( - _OPTS, group=_base.AUTHTOKEN_GROUP) - auth.register_conf_options(self._local_oslo_config, - group=_base.AUTHTOKEN_GROUP) - - super(AuthProtocol, self).__init__( - app, - log=log, - enforce_token_bind=self._conf_get('enforce_token_bind')) - - # delay_auth_decision means we still allow unauthenticated requests - # through and we let the downstream service make the final decision - self._delay_auth_decision = self._conf_get('delay_auth_decision') - self._include_service_catalog = self._conf_get( - 'include_service_catalog') - self._hash_algorithms = self._conf_get('hash_algorithms') - - self._identity_server = self._create_identity_server() - - self._auth_uri = self._conf_get('auth_uri') - if not self._auth_uri: - self.log.warning( - _LW('Configuring auth_uri to point to the public identity ' - 'endpoint is required; clients may not be able to ' - 'authenticate against an admin endpoint')) - - # FIXME(dolph): drop support for this fallback behavior as - # documented in bug 1207517. - - self._auth_uri = self._identity_server.auth_uri - - self._signing_directory = _signing_dir.SigningDirectory( - directory_name=self._conf_get('signing_dir'), log=self.log) - - self._token_cache = self._token_cache_factory() - - revocation_cache_timeout = datetime.timedelta( - seconds=self._conf_get('revocation_cache_time')) - self._revocations = _revocations.Revocations(revocation_cache_timeout, - self._signing_directory, - self._identity_server, - self._cms_verify, - self.log) - - self._check_revocations_for_cached = self._conf_get( - 'check_revocations_for_cached') - - def _conf_get(self, name, group=_base.AUTHTOKEN_GROUP): - # try config from paste-deploy first - if name in self._conf: - return self._conf[name] - elif self._local_oslo_config: - return self._local_oslo_config[group][name] - else: - return CONF[group][name] - - def process_request(self, request): - """Process request. - - Evaluate the headers in a request and attempt to authenticate the - request. If authenticated then additional headers are added to the - request for use by applications. If not authenticated the request will - be rejected or marked unauthenticated depending on configuration. - """ - self._token_cache.initialize(request.environ) - - resp = super(AuthProtocol, self).process_request(request) - if resp: - return resp - - if not request.user_token: - # if no user token is present then that's an invalid request - request.user_token_valid = False - - # NOTE(jamielennox): The service status is allowed to be missing if a - # service token is not passed. If the service status is missing that's - # a valid request. We should find a better way to expose this from the - # request object. - user_status = request.user_token and request.user_token_valid - service_status = request.headers.get('X-Service-Identity-Status', - 'Confirmed') - - if not (user_status and service_status == 'Confirmed'): - if self._delay_auth_decision: - self.log.info(_LI('Deferring reject downstream')) - else: - self.log.info(_LI('Rejecting request')) - self._reject_request() - - if request.user_token_valid: - request.set_user_headers(request.token_auth._user_auth_ref, - self._include_service_catalog) - - if request.service_token and request.service_token_valid: - request.set_service_headers(request.token_auth._serv_auth_ref) - - if self.log.isEnabledFor(logging.DEBUG): - self.log.debug('Received request from %s', - request.token_auth._log_format) - - def process_response(self, response): - """Process Response. - - Add ``WWW-Authenticate`` headers to requests that failed with - ``401 Unauthenticated`` so users know where to authenticate for future - requests. - """ - if response.status_int == 401: - response.headers.extend(self._reject_auth_headers) - - return response - - @property - def _reject_auth_headers(self): - header_val = 'Keystone uri=\'%s\'' % self._auth_uri - return [('WWW-Authenticate', header_val)] - - def _reject_request(self): - """Redirect client to auth server. - - :param env: wsgi request environment - :param start_response: wsgi response callback - :returns: HTTPUnauthorized http response - - """ - raise webob.exc.HTTPUnauthorized(body='Authentication required', - headers=self._reject_auth_headers) - - def _token_hashes(self, token): - """Generate a list of hashes that the current token may be cached as. - - With PKI tokens we have multiple hashing algorithms that we test with - revocations. This generates that whole list. - - The first element of this list is the preferred algorithm and is what - new cache values should be saved as. - - :param str token: The token being presented by a user. - - :returns: list of str token hashes. - """ - if cms.is_asn1_token(token) or cms.is_pkiz(token): - return list(cms.cms_hash_token(token, mode=algo) - for algo in self._hash_algorithms) - else: - return [token] - - def _cache_get_hashes(self, token_hashes): - """Check if the token is cached already. - - Functions takes a list of hashes that might be in the cache and matches - the first one that is present. If nothing is found in the cache it - returns None. - - :returns: token data if found else None. - """ - - for token in token_hashes: - cached = self._token_cache.get(token) - - if cached: - return cached - - def _fetch_token(self, token): - """Retrieve a token from either a PKI bundle or the identity server. - - :param str token: token id - - :raises exc.InvalidToken: if token is rejected - """ - data = None - token_hashes = None - - try: - token_hashes = self._token_hashes(token) - cached = self._cache_get_hashes(token_hashes) - - if cached: - data = cached - - if self._check_revocations_for_cached: - # A token stored in Memcached might have been revoked - # regardless of initial mechanism used to validate it, - # and needs to be checked. - self._revocations.check(token_hashes) - else: - data = self._validate_offline(token, token_hashes) - if not data: - data = self._identity_server.verify_token(token) - - self._token_cache.store(token_hashes[0], data) - - except (exceptions.ConnectionRefused, exceptions.RequestTimeout, - exc.RevocationListError, exc.ServiceError) as e: - self.log.critical(_LC('Unable to validate token: %s'), e) - raise webob.exc.HTTPServiceUnavailable() - except exc.InvalidToken: - self.log.debug('Token validation failure.', exc_info=True) - if token_hashes: - self._token_cache.store_invalid(token_hashes[0]) - self.log.warning(_LW('Authorization failed for token')) - raise - except Exception: - self.log.critical(_LC('Unable to validate token'), exc_info=True) - raise webob.exc.HTTPInternalServerError() - - return data - - def _validate_offline(self, token, token_hashes): - try: - if cms.is_pkiz(token): - verified = self._verify_pkiz_token(token, token_hashes) - elif cms.is_asn1_token(token): - verified = self._verify_signed_token(token, token_hashes) - else: - # Can't do offline validation for this type of token. - return - except exceptions.CertificateConfigError: - self.log.warning(_LW('Fetch certificate config failed, ' - 'fallback to online validation.')) - except exc.RevocationListError: - self.log.warning(_LW('Fetch revocation list failed, ' - 'fallback to online validation.')) - else: - data = jsonutils.loads(verified) - - audit_ids = None - if 'access' in data: - # It's a v2 token. - audit_ids = data['access']['token'].get('audit_ids') - else: - # It's a v3 token - audit_ids = data['token'].get('audit_ids') - - if audit_ids: - self._revocations.check_by_audit_id(audit_ids) - - return data - - def _validate_token(self, auth_ref): - super(AuthProtocol, self)._validate_token(auth_ref) - - if auth_ref.version == 'v2.0' and not auth_ref.project_id: - msg = _('Unable to determine service tenancy.') - raise exc.InvalidToken(msg) - - def _cms_verify(self, data, inform=cms.PKI_ASN1_FORM): - """Verifies the signature of the provided data's IAW CMS syntax. - - If either of the certificate files might be missing, fetch them and - retry. - """ - def verify(): - try: - signing_cert_path = self._signing_directory.calc_path( - self._SIGNING_CERT_FILE_NAME) - signing_ca_path = self._signing_directory.calc_path( - self._SIGNING_CA_FILE_NAME) - return cms.cms_verify(data, signing_cert_path, - signing_ca_path, - inform=inform).decode('utf-8') - except (exceptions.CMSError, - cms.subprocess.CalledProcessError) as err: - self.log.warning(_LW('Verify error: %s'), err) - raise exc.InvalidToken(_('Token authorization failed')) - - try: - return verify() - except exceptions.CertificateConfigError: - # the certs might be missing; unconditionally fetch to avoid racing - self._fetch_signing_cert() - self._fetch_ca_cert() - - try: - # retry with certs in place - return verify() - except exceptions.CertificateConfigError as err: - # if this is still occurring, something else is wrong and we - # need err.output to identify the problem - self.log.error(_LE('CMS Verify output: %s'), err.output) - raise - - def _verify_signed_token(self, signed_text, token_ids): - """Check that the token is unrevoked and has a valid signature.""" - self._revocations.check(token_ids) - formatted = cms.token_to_cms(signed_text) - verified = self._cms_verify(formatted) - return verified - - def _verify_pkiz_token(self, signed_text, token_ids): - self._revocations.check(token_ids) - try: - uncompressed = cms.pkiz_uncompress(signed_text) - verified = self._cms_verify(uncompressed, inform=cms.PKIZ_CMS_FORM) - return verified - # TypeError If the signed_text is not zlib compressed - # binascii.Error if signed_text has incorrect base64 padding (py34) - except (TypeError, binascii.Error): - raise exc.InvalidToken(signed_text) - - def _fetch_signing_cert(self): - self._signing_directory.write_file( - self._SIGNING_CERT_FILE_NAME, - self._identity_server.fetch_signing_cert()) - - def _fetch_ca_cert(self): - self._signing_directory.write_file( - self._SIGNING_CA_FILE_NAME, - self._identity_server.fetch_ca_cert()) - - def _get_auth_plugin(self): - # NOTE(jamielennox): Ideally this would use get_from_conf_options - # however that is not possible because we have to support the override - # pattern we use in _conf_get. There is a somewhat replacement for this - # in keystoneclient in load_from_options_getter which should be used - # when available. Until then this is essentially a copy and paste of - # the ksc load_from_conf_options code because we need to get a fix out - # for this quickly. - - # FIXME(jamielennox): update to use load_from_options_getter when - # https://review.openstack.org/162529 merges. - - # !!! - UNDER NO CIRCUMSTANCES COPY ANY OF THIS CODE - !!! - - group = self._conf_get('auth_section') or _base.AUTHTOKEN_GROUP - plugin_name = self._conf_get('auth_plugin', group=group) - plugin_kwargs = dict() - - if plugin_name: - plugin_class = auth.get_plugin_class(plugin_name) - else: - plugin_class = _auth.AuthTokenPlugin - # logger object is a required parameter of the default plugin - plugin_kwargs['log'] = self.log - - plugin_opts = plugin_class.get_options() - (self._local_oslo_config or CONF).register_opts(plugin_opts, - group=group) - - for opt in plugin_opts: - val = self._conf_get(opt.dest, group=group) - if val is not None: - val = opt.type(val) - plugin_kwargs[opt.dest] = val - - return plugin_class.load_from_options(**plugin_kwargs) - - def _determine_project(self): - """Determine a project name from all available config sources. - - The sources are checked in the following order: - - 1. The paste-deploy config for auth_token middleware - 2. The keystone_authtoken in the project's config - 3. The oslo.config CONF.project property - - """ - try: - return self._conf_get('project') - except cfg.NoSuchOptError: - # Prefer local oslo config object - if self._local_oslo_config: - return self._local_oslo_config.project - try: - # CONF.project will exist only if the service uses - # oslo.config. It will only be set when the project - # calls CONF(...) and when not set oslo.config oddly - # raises a NoSuchOptError exception. - return CONF.project - except cfg.NoSuchOptError: - return '' - - def _build_useragent_string(self): - project = self._determine_project() - if project: - project_version = _get_project_version(project) - project = '{project}/{project_version} '.format( - project=project, - project_version=project_version) - - ua_template = ('{project}' - 'keystonemiddleware.auth_token/{ksm_version}') - return ua_template.format( - project=project, - ksm_version=_get_project_version('keystonemiddleware')) - - def _create_identity_server(self): - # NOTE(jamielennox): Loading Session here should be exactly the - # same as calling Session.load_from_conf_options(CONF, GROUP) - # however we can't do that because we have to use _conf_get to - # support the paste.ini options. - sess = session.Session.construct(dict( - cert=self._conf_get('certfile'), - key=self._conf_get('keyfile'), - cacert=self._conf_get('cafile'), - insecure=self._conf_get('insecure'), - timeout=self._conf_get('http_connect_timeout'), - user_agent=self._build_useragent_string() - )) - - auth_plugin = self._get_auth_plugin() - - adap = adapter.Adapter( - sess, - auth=auth_plugin, - service_type='identity', - interface='admin', - region_name=self._conf_get('region_name'), - connect_retries=self._conf_get('http_request_max_retries')) - - auth_version = self._conf_get('auth_version') - if auth_version is not None: - auth_version = discover.normalize_version_number(auth_version) - return _identity.IdentityServer( - self.log, - adap, - include_service_catalog=self._include_service_catalog, - requested_auth_version=auth_version) - - def _token_cache_factory(self): - security_strategy = self._conf_get('memcache_security_strategy') - - cache_kwargs = dict( - cache_time=int(self._conf_get('token_cache_time')), - env_cache_name=self._conf_get('cache'), - memcached_servers=self._conf_get('memcached_servers'), - use_advanced_pool=self._conf_get('memcache_use_advanced_pool'), - memcache_pool_dead_retry=self._conf_get( - 'memcache_pool_dead_retry'), - memcache_pool_maxsize=self._conf_get('memcache_pool_maxsize'), - memcache_pool_unused_timeout=self._conf_get( - 'memcache_pool_unused_timeout'), - memcache_pool_conn_get_timeout=self._conf_get( - 'memcache_pool_conn_get_timeout'), - memcache_pool_socket_timeout=self._conf_get( - 'memcache_pool_socket_timeout'), - ) - - if security_strategy: - secret_key = self._conf_get('memcache_secret_key') - return _cache.SecureTokenCache(self.log, - security_strategy, - secret_key, - **cache_kwargs) - else: - return _cache.TokenCache(self.log, **cache_kwargs) - - -def filter_factory(global_conf, **local_conf): - """Returns a WSGI filter app for use with paste.deploy.""" - conf = global_conf.copy() - conf.update(local_conf) - - def auth_filter(app): - return AuthProtocol(app, conf) - return auth_filter - - -def app_factory(global_conf, **local_conf): - conf = global_conf.copy() - conf.update(local_conf) - return AuthProtocol(None, conf) - - -# NOTE(jamielennox): Maintained here for public API compatibility. -InvalidToken = exc.InvalidToken -ServiceError = exc.ServiceError -ConfigurationError = exc.ConfigurationError -RevocationListError = exc.RevocationListError diff --git a/keystonemiddleware-moon/keystonemiddleware/auth_token/_auth.py b/keystonemiddleware-moon/keystonemiddleware/auth_token/_auth.py deleted file mode 100644 index cf7ed84d..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/auth_token/_auth.py +++ /dev/null @@ -1,194 +0,0 @@ -# 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. - -import logging - -from keystoneclient import auth -from keystoneclient.auth.identity import v2 -from keystoneclient.auth import token_endpoint -from keystoneclient import discover -from oslo_config import cfg - -from keystonemiddleware.auth_token import _base -from keystonemiddleware.i18n import _, _LW - - -_LOG = logging.getLogger(__name__) - - -class AuthTokenPlugin(auth.BaseAuthPlugin): - - def __init__(self, auth_host, auth_port, auth_protocol, auth_admin_prefix, - admin_user, admin_password, admin_tenant_name, admin_token, - identity_uri, log): - - log.warning(_LW( - "Use of the auth_admin_prefix, auth_host, auth_port, " - "auth_protocol, identity_uri, admin_token, admin_user, " - "admin_password, and admin_tenant_name configuration options is " - "deprecated in favor of auth_plugin and related options and may " - "be removed in a future release.")) - - # NOTE(jamielennox): it does appear here that our default arguments - # are backwards. We need to do it this way so that we can handle the - # same deprecation strategy for CONF and the conf variable. - if not identity_uri: - log.warning(_LW('Configuring admin URI using auth fragments. ' - 'This is deprecated, use \'identity_uri\'' - ' instead.')) - - if ':' in auth_host: - # Note(dzyu) it is an IPv6 address, so it needs to be wrapped - # with '[]' to generate a valid IPv6 URL, based on - # http://www.ietf.org/rfc/rfc2732.txt - auth_host = '[%s]' % auth_host - - identity_uri = '%s://%s:%s' % (auth_protocol, - auth_host, - auth_port) - - if auth_admin_prefix: - identity_uri = '%s/%s' % (identity_uri, - auth_admin_prefix.strip('/')) - - self._identity_uri = identity_uri.rstrip('/') - - # FIXME(jamielennox): Yes. This is wrong. We should be determining the - # plugin to use based on a combination of discovery and inputs. Much - # of this can be changed when we get keystoneclient 0.10. For now this - # hardcoded path is EXACTLY the same as the original auth_token did. - auth_url = '%s/v2.0' % self._identity_uri - - if admin_token: - log.warning(_LW( - "The admin_token option in the auth_token middleware is " - "deprecated and should not be used. The admin_user and " - "admin_password options should be used instead. The " - "admin_token option may be removed in a future release.")) - self._plugin = token_endpoint.Token(auth_url, admin_token) - else: - self._plugin = v2.Password(auth_url, - username=admin_user, - password=admin_password, - tenant_name=admin_tenant_name) - - self._LOG = log - self._discover = None - - def get_token(self, *args, **kwargs): - return self._plugin.get_token(*args, **kwargs) - - def get_endpoint(self, session, interface=None, version=None, **kwargs): - """Return an endpoint for the client. - - There are no required keyword arguments to ``get_endpoint`` as a plugin - implementation should use best effort with the information available to - determine the endpoint. - - :param session: The session object that the auth_plugin belongs to. - :type session: keystoneclient.session.Session - :param version: The version number required for this endpoint. - :type version: tuple or str - :param str interface: what visibility the endpoint should have. - - :returns: The base URL that will be used to talk to the required - service or None if not available. - :rtype: string - """ - if interface == auth.AUTH_INTERFACE: - return self._identity_uri - - if not version: - # NOTE(jamielennox): This plugin can only be used within auth_token - # and auth_token will always provide version= with requests. - return None - - if not self._discover: - self._discover = discover.Discover(session, - auth_url=self._identity_uri, - authenticated=False) - - if not self._discover.url_for(version): - # NOTE(jamielennox): The requested version is not supported by the - # identity server. - return None - - # NOTE(jamielennox): for backwards compatibility here we don't - # actually use the URL from discovery we hack it up instead. :( - # NOTE(blk-u): Normalizing the version is a workaround for bug 1450272. - # This can be removed once that's fixed. Also fix the docstring for the - # version parameter to be just "tuple". - version = discover.normalize_version_number(version) - if discover.version_match((2, 0), version): - return '%s/v2.0' % self._identity_uri - elif discover.version_match((3, 0), version): - return '%s/v3' % self._identity_uri - - # NOTE(jamielennox): This plugin will only get called from auth_token - # middleware. The middleware should never request a version that the - # plugin doesn't know how to handle. - msg = _('Invalid version asked for in auth_token plugin') - raise NotImplementedError(msg) - - def invalidate(self): - return self._plugin.invalidate() - - @classmethod - def get_options(cls): - options = super(AuthTokenPlugin, cls).get_options() - - options.extend([ - cfg.StrOpt('auth_admin_prefix', - default='', - help='Prefix to prepend at the beginning of the path. ' - 'Deprecated, use identity_uri.'), - cfg.StrOpt('auth_host', - default='127.0.0.1', - help='Host providing the admin Identity API endpoint. ' - 'Deprecated, use identity_uri.'), - cfg.IntOpt('auth_port', - default=35357, - help='Port of the admin Identity API endpoint. ' - 'Deprecated, use identity_uri.'), - cfg.StrOpt('auth_protocol', - default='https', - help='Protocol of the admin Identity API endpoint ' - '(http or https). Deprecated, use identity_uri.'), - cfg.StrOpt('identity_uri', - default=None, - help='Complete admin Identity API endpoint. This ' - 'should specify the unversioned root endpoint ' - 'e.g. https://localhost:35357/'), - cfg.StrOpt('admin_token', - secret=True, - help='This option is deprecated and may be removed in ' - 'a future release. Single shared secret with the ' - 'Keystone configuration used for bootstrapping a ' - 'Keystone installation, or otherwise bypassing ' - 'the normal authentication process. This option ' - 'should not be used, use `admin_user` and ' - '`admin_password` instead.'), - cfg.StrOpt('admin_user', - help='Service username.'), - cfg.StrOpt('admin_password', - secret=True, - help='Service user password.'), - cfg.StrOpt('admin_tenant_name', - default='admin', - help='Service tenant name.'), - ]) - - return options - - -auth.register_conf_options(cfg.CONF, _base.AUTHTOKEN_GROUP) -AuthTokenPlugin.register_conf_options(cfg.CONF, _base.AUTHTOKEN_GROUP) diff --git a/keystonemiddleware-moon/keystonemiddleware/auth_token/_base.py b/keystonemiddleware-moon/keystonemiddleware/auth_token/_base.py deleted file mode 100644 index ee4ec13c..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/auth_token/_base.py +++ /dev/null @@ -1,13 +0,0 @@ -# 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. - -AUTHTOKEN_GROUP = 'keystone_authtoken' diff --git a/keystonemiddleware-moon/keystonemiddleware/auth_token/_cache.py b/keystonemiddleware-moon/keystonemiddleware/auth_token/_cache.py deleted file mode 100644 index ce5faf66..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/auth_token/_cache.py +++ /dev/null @@ -1,338 +0,0 @@ -# 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. - -import contextlib -import hashlib - -from oslo_serialization import jsonutils -import six - -from keystonemiddleware.auth_token import _exceptions as exc -from keystonemiddleware.auth_token import _memcache_crypt as memcache_crypt -from keystonemiddleware.i18n import _, _LE -from keystonemiddleware.openstack.common import memorycache - - -def _hash_key(key): - """Turn a set of arguments into a SHA256 hash. - - Using a known-length cache key is important to ensure that memcache - maximum key length is not exceeded causing failures to validate. - """ - if isinstance(key, six.text_type): - # NOTE(morganfainberg): Ensure we are always working with a bytes - # type required for the hasher. In python 2.7 it is possible to - # get a text_type (unicode). In python 3.4 all strings are - # text_type and not bytes by default. This encode coerces the - # text_type to the appropriate bytes values. - key = key.encode('utf-8') - return hashlib.sha256(key).hexdigest() - - -class _CachePool(list): - """A lazy pool of cache references.""" - - def __init__(self, cache, memcached_servers): - self._environment_cache = cache - self._memcached_servers = memcached_servers - - @contextlib.contextmanager - def reserve(self): - """Context manager to manage a pooled cache reference.""" - if self._environment_cache is not None: - # skip pooling and just use the cache from the upstream filter - yield self._environment_cache - return # otherwise the context manager will continue! - - try: - c = self.pop() - except IndexError: - # the pool is empty, so we need to create a new client - c = memorycache.get_client(self._memcached_servers) - - try: - yield c - finally: - self.append(c) - - -class _MemcacheClientPool(object): - """An advanced memcached client pool that is eventlet safe.""" - def __init__(self, memcache_servers, memcache_dead_retry=None, - memcache_pool_maxsize=None, memcache_pool_unused_timeout=None, - memcache_pool_conn_get_timeout=None, - memcache_pool_socket_timeout=None): - # NOTE(morganfainberg): import here to avoid hard dependency on - # python-memcached library. - global _memcache_pool - from keystonemiddleware.auth_token import _memcache_pool - - self._pool = _memcache_pool.MemcacheClientPool( - memcache_servers, - arguments={ - 'dead_retry': memcache_dead_retry, - 'socket_timeout': memcache_pool_socket_timeout, - }, - maxsize=memcache_pool_maxsize, - unused_timeout=memcache_pool_unused_timeout, - conn_get_timeout=memcache_pool_conn_get_timeout, - ) - - @contextlib.contextmanager - def reserve(self): - with self._pool.get() as client: - yield client - - -class TokenCache(object): - """Encapsulates the auth_token token cache functionality. - - auth_token caches tokens that it's seen so that when a token is re-used the - middleware doesn't have to do a more expensive operation (like going to the - identity server) to validate the token. - - initialize() must be called before calling the other methods. - - Store a valid token in the cache using store(); mark a token as invalid in - the cache using store_invalid(). - - Check if a token is in the cache and retrieve it using get(). - - """ - - _CACHE_KEY_TEMPLATE = 'tokens/%s' - _INVALID_INDICATOR = 'invalid' - - def __init__(self, log, cache_time=None, - env_cache_name=None, memcached_servers=None, - use_advanced_pool=False, memcache_pool_dead_retry=None, - memcache_pool_maxsize=None, memcache_pool_unused_timeout=None, - memcache_pool_conn_get_timeout=None, - memcache_pool_socket_timeout=None): - self._LOG = log - self._cache_time = cache_time - self._env_cache_name = env_cache_name - self._memcached_servers = memcached_servers - self._use_advanced_pool = use_advanced_pool - self._memcache_pool_dead_retry = memcache_pool_dead_retry, - self._memcache_pool_maxsize = memcache_pool_maxsize, - self._memcache_pool_unused_timeout = memcache_pool_unused_timeout - self._memcache_pool_conn_get_timeout = memcache_pool_conn_get_timeout - self._memcache_pool_socket_timeout = memcache_pool_socket_timeout - - self._cache_pool = None - self._initialized = False - - def _get_cache_pool(self, cache, memcache_servers, use_advanced_pool=False, - memcache_dead_retry=None, memcache_pool_maxsize=None, - memcache_pool_unused_timeout=None, - memcache_pool_conn_get_timeout=None, - memcache_pool_socket_timeout=None): - if use_advanced_pool is True and memcache_servers and cache is None: - return _MemcacheClientPool( - memcache_servers, - memcache_dead_retry=memcache_dead_retry, - memcache_pool_maxsize=memcache_pool_maxsize, - memcache_pool_unused_timeout=memcache_pool_unused_timeout, - memcache_pool_conn_get_timeout=memcache_pool_conn_get_timeout, - memcache_pool_socket_timeout=memcache_pool_socket_timeout) - else: - return _CachePool(cache, memcache_servers) - - def initialize(self, env): - if self._initialized: - return - - self._cache_pool = self._get_cache_pool( - env.get(self._env_cache_name), - self._memcached_servers, - use_advanced_pool=self._use_advanced_pool, - memcache_dead_retry=self._memcache_pool_dead_retry, - memcache_pool_maxsize=self._memcache_pool_maxsize, - memcache_pool_unused_timeout=self._memcache_pool_unused_timeout, - memcache_pool_conn_get_timeout=self._memcache_pool_conn_get_timeout - ) - - self._initialized = True - - def store(self, token_id, data): - """Put token data into the cache. - """ - self._LOG.debug('Storing token in cache') - self._cache_store(token_id, data) - - def store_invalid(self, token_id): - """Store invalid token in cache.""" - self._LOG.debug('Marking token as unauthorized in cache') - self._cache_store(token_id, self._INVALID_INDICATOR) - - def _get_cache_key(self, token_id): - """Get a unique key for this token id. - - Turn the token_id into something that can uniquely identify that token - in a key value store. - - As this is generally the first function called in a key lookup this - function also returns a context object. This context object is not - modified or used by the Cache object but is passed back on subsequent - functions so that decryption or other data can be shared throughout a - cache lookup. - - :param str token_id: The unique token id. - - :returns: A tuple of a string key and an implementation specific - context object - """ - # NOTE(jamielennox): in the basic implementation there is no need for - # a context so just pass None as it will only get passed back later. - unused_context = None - return self._CACHE_KEY_TEMPLATE % _hash_key(token_id), unused_context - - def _deserialize(self, data, context): - """Deserialize data from the cache back into python objects. - - Take data retrieved from the cache and return an appropriate python - dictionary. - - :param str data: The data retrieved from the cache. - :param object context: The context that was returned from - _get_cache_key. - - :returns: The python object that was saved. - """ - # memory cache will handle deserialization for us - return data - - def _serialize(self, data, context): - """Serialize data so that it can be saved to the cache. - - Take python objects and serialize them so that they can be saved into - the cache. - - :param object data: The data to be cached. - :param object context: The context that was returned from - _get_cache_key. - - :returns: The python object that was saved. - """ - # memory cache will handle serialization for us - return data - - def get(self, token_id): - """Return token information from cache. - - If token is invalid raise exc.InvalidToken - return token only if fresh (not expired). - """ - - if not token_id: - # Nothing to do - return - - key, context = self._get_cache_key(token_id) - - with self._cache_pool.reserve() as cache: - serialized = cache.get(key) - - if serialized is None: - return None - - if isinstance(serialized, six.text_type): - serialized = serialized.encode('utf8') - data = self._deserialize(serialized, context) - - # Note that _INVALID_INDICATOR and (data, expires) are the only - # valid types of serialized cache entries, so there is not - # a collision with jsonutils.loads(serialized) == None. - if not isinstance(data, six.string_types): - data = data.decode('utf-8') - cached = jsonutils.loads(data) - if cached == self._INVALID_INDICATOR: - self._LOG.debug('Cached Token is marked unauthorized') - raise exc.InvalidToken(_('Token authorization failed')) - - # NOTE(jamielennox): Cached values used to be stored as a tuple of data - # and expiry time. They no longer are but we have to allow some time to - # transition the old format so if it's a tuple just return the data. - try: - data, expires = cached - except ValueError: - data = cached - - return data - - def _cache_store(self, token_id, data): - """Store value into memcache. - - data may be _INVALID_INDICATOR or a tuple like (data, expires) - - """ - data = jsonutils.dumps(data) - if isinstance(data, six.text_type): - data = data.encode('utf-8') - - cache_key, context = self._get_cache_key(token_id) - data_to_store = self._serialize(data, context) - - with self._cache_pool.reserve() as cache: - cache.set(cache_key, data_to_store, time=self._cache_time) - - -class SecureTokenCache(TokenCache): - """A token cache that stores tokens encrypted. - - A more secure version of TokenCache that will encrypt tokens before - caching them. - """ - - def __init__(self, log, security_strategy, secret_key, **kwargs): - super(SecureTokenCache, self).__init__(log, **kwargs) - - security_strategy = security_strategy.upper() - - if security_strategy not in ('MAC', 'ENCRYPT'): - msg = _('memcache_security_strategy must be ENCRYPT or MAC') - raise exc.ConfigurationError(msg) - if not secret_key: - msg = _('memcache_secret_key must be defined when a ' - 'memcache_security_strategy is defined') - raise exc.ConfigurationError(msg) - - if isinstance(security_strategy, six.string_types): - security_strategy = security_strategy.encode('utf-8') - if isinstance(secret_key, six.string_types): - secret_key = secret_key.encode('utf-8') - - self._security_strategy = security_strategy - self._secret_key = secret_key - - def _get_cache_key(self, token_id): - context = memcache_crypt.derive_keys(token_id, - self._secret_key, - self._security_strategy) - key = self._CACHE_KEY_TEMPLATE % memcache_crypt.get_cache_key(context) - return key, context - - def _deserialize(self, data, context): - try: - # unprotect_data will return None if raw_cached is None - return memcache_crypt.unprotect_data(context, data) - except Exception: - msg = _LE('Failed to decrypt/verify cache data') - self._LOG.exception(msg) - - # this should have the same effect as data not - # found in cache - return None - - def _serialize(self, data, context): - return memcache_crypt.protect_data(context, data) diff --git a/keystonemiddleware-moon/keystonemiddleware/auth_token/_exceptions.py b/keystonemiddleware-moon/keystonemiddleware/auth_token/_exceptions.py deleted file mode 100644 index be045c96..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/auth_token/_exceptions.py +++ /dev/null @@ -1,27 +0,0 @@ -# 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. - - -class InvalidToken(Exception): - pass - - -class ServiceError(Exception): - pass - - -class ConfigurationError(Exception): - pass - - -class RevocationListError(Exception): - pass diff --git a/keystonemiddleware-moon/keystonemiddleware/auth_token/_identity.py b/keystonemiddleware-moon/keystonemiddleware/auth_token/_identity.py deleted file mode 100644 index 6fbeac27..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/auth_token/_identity.py +++ /dev/null @@ -1,252 +0,0 @@ -# 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. - -import functools - -from keystoneclient import auth -from keystoneclient import discover -from keystoneclient import exceptions -from keystoneclient.v2_0 import client as v2_client -from keystoneclient.v3 import client as v3_client -from six.moves import urllib - -from keystonemiddleware.auth_token import _auth -from keystonemiddleware.auth_token import _exceptions as exc -from keystonemiddleware.i18n import _, _LE, _LI, _LW - - -def _convert_fetch_cert_exception(fetch_cert): - @functools.wraps(fetch_cert) - def wrapper(self): - try: - text = fetch_cert(self) - except exceptions.HTTPError as e: - raise exceptions.CertificateConfigError(e.details) - return text - - return wrapper - - -class _RequestStrategy(object): - - AUTH_VERSION = None - - def __init__(self, adap, include_service_catalog=None): - self._include_service_catalog = include_service_catalog - - def verify_token(self, user_token): - pass - - @_convert_fetch_cert_exception - def fetch_signing_cert(self): - return self._fetch_signing_cert() - - def _fetch_signing_cert(self): - pass - - @_convert_fetch_cert_exception - def fetch_ca_cert(self): - return self._fetch_ca_cert() - - def _fetch_ca_cert(self): - pass - - def fetch_revocation_list(self): - pass - - -class _V2RequestStrategy(_RequestStrategy): - - AUTH_VERSION = (2, 0) - - def __init__(self, adap, **kwargs): - super(_V2RequestStrategy, self).__init__(adap, **kwargs) - self._client = v2_client.Client(session=adap) - - def verify_token(self, token): - auth_ref = self._client.tokens.validate_access_info(token) - - if not auth_ref: - msg = _('Failed to fetch token data from identity server') - raise exc.InvalidToken(msg) - - return {'access': auth_ref} - - def _fetch_signing_cert(self): - return self._client.certificates.get_signing_certificate() - - def _fetch_ca_cert(self): - return self._client.certificates.get_ca_certificate() - - def fetch_revocation_list(self): - return self._client.tokens.get_revoked() - - -class _V3RequestStrategy(_RequestStrategy): - - AUTH_VERSION = (3, 0) - - def __init__(self, adap, **kwargs): - super(_V3RequestStrategy, self).__init__(adap, **kwargs) - self._client = v3_client.Client(session=adap) - - def verify_token(self, token): - auth_ref = self._client.tokens.validate( - token, - include_catalog=self._include_service_catalog) - - if not auth_ref: - msg = _('Failed to fetch token data from identity server') - raise exc.InvalidToken(msg) - - return {'token': auth_ref} - - def _fetch_signing_cert(self): - return self._client.simple_cert.get_certificates() - - def _fetch_ca_cert(self): - return self._client.simple_cert.get_ca_certificates() - - def fetch_revocation_list(self): - return self._client.tokens.get_revoked() - - -_REQUEST_STRATEGIES = [_V3RequestStrategy, _V2RequestStrategy] - - -class IdentityServer(object): - """Base class for operations on the Identity API server. - - The auth_token middleware needs to communicate with the Identity API server - to validate UUID tokens, fetch the revocation list, signing certificates, - etc. This class encapsulates the data and methods to perform these - operations. - - """ - - def __init__(self, log, adap, include_service_catalog=None, - requested_auth_version=None): - self._LOG = log - self._adapter = adap - self._include_service_catalog = include_service_catalog - self._requested_auth_version = requested_auth_version - - # Built on-demand with self._request_strategy. - self._request_strategy_obj = None - - @property - def auth_uri(self): - auth_uri = self._adapter.get_endpoint(interface=auth.AUTH_INTERFACE) - - # NOTE(jamielennox): This weird stripping of the prefix hack is - # only relevant to the legacy case. We urljoin '/' to get just the - # base URI as this is the original behaviour. - if isinstance(self._adapter.auth, _auth.AuthTokenPlugin): - auth_uri = urllib.parse.urljoin(auth_uri, '/').rstrip('/') - - return auth_uri - - @property - def auth_version(self): - return self._request_strategy.AUTH_VERSION - - @property - def _request_strategy(self): - if not self._request_strategy_obj: - strategy_class = self._get_strategy_class() - self._adapter.version = strategy_class.AUTH_VERSION - - self._request_strategy_obj = strategy_class( - self._adapter, - include_service_catalog=self._include_service_catalog) - - return self._request_strategy_obj - - def _get_strategy_class(self): - if self._requested_auth_version: - # A specific version was requested. - if discover.version_match(_V3RequestStrategy.AUTH_VERSION, - self._requested_auth_version): - return _V3RequestStrategy - - # The version isn't v3 so we don't know what to do. Just assume V2. - return _V2RequestStrategy - - # Specific version was not requested then we fall through to - # discovering available versions from the server - for klass in _REQUEST_STRATEGIES: - if self._adapter.get_endpoint(version=klass.AUTH_VERSION): - msg = _LI('Auth Token confirmed use of %s apis') - self._LOG.info(msg, self._requested_auth_version) - return klass - - versions = ['v%d.%d' % s.AUTH_VERSION for s in _REQUEST_STRATEGIES] - self._LOG.error(_LE('No attempted versions [%s] supported by server'), - ', '.join(versions)) - - msg = _('No compatible apis supported by server') - raise exc.ServiceError(msg) - - def verify_token(self, user_token, retry=True): - """Authenticate user token with identity server. - - :param user_token: user's token id - :param retry: flag that forces the middleware to retry - user authentication when an indeterminate - response is received. Optional. - :returns: access info received from identity server on success - :rtype: :py:class:`keystoneclient.access.AccessInfo` - :raises exc.InvalidToken: if token is rejected - :raises exc.ServiceError: if unable to authenticate token - - """ - try: - auth_ref = self._request_strategy.verify_token(user_token) - except exceptions.NotFound as e: - self._LOG.warning(_LW('Authorization failed for token')) - self._LOG.warning(_LW('Identity response: %s'), e.response.text) - raise exc.InvalidToken(_('Token authorization failed')) - except exceptions.Unauthorized as e: - self._LOG.info(_LI('Identity server rejected authorization')) - self._LOG.warning(_LW('Identity response: %s'), e.response.text) - if retry: - self._LOG.info(_LI('Retrying validation')) - return self.verify_token(user_token, False) - msg = _('Identity server rejected authorization necessary to ' - 'fetch token data') - raise exc.ServiceError(msg) - except exceptions.HttpError as e: - self._LOG.error( - _LE('Bad response code while validating token: %s'), - e.http_status) - self._LOG.warning(_LW('Identity response: %s'), e.response.text) - msg = _('Failed to fetch token data from identity server') - raise exc.ServiceError(msg) - else: - return auth_ref - - def fetch_revocation_list(self): - try: - data = self._request_strategy.fetch_revocation_list() - except exceptions.HTTPError as e: - msg = _('Failed to fetch token revocation list: %d') - raise exc.RevocationListError(msg % e.http_status) - if 'signed' not in data: - msg = _('Revocation list improperly formatted.') - raise exc.RevocationListError(msg) - return data['signed'] - - def fetch_signing_cert(self): - return self._request_strategy.fetch_signing_cert() - - def fetch_ca_cert(self): - return self._request_strategy.fetch_ca_cert() diff --git a/keystonemiddleware-moon/keystonemiddleware/auth_token/_memcache_crypt.py b/keystonemiddleware-moon/keystonemiddleware/auth_token/_memcache_crypt.py deleted file mode 100644 index 2e45571f..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/auth_token/_memcache_crypt.py +++ /dev/null @@ -1,210 +0,0 @@ -# Copyright 2010-2013 OpenStack Foundation -# -# 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. - -""" -Utilities for memcache encryption and integrity check. - -Data should be serialized before entering these functions. Encryption -has a dependency on the pycrypto. If pycrypto is not available, -CryptoUnavailableError will be raised. - -This module will not be called unless signing or encryption is enabled -in the config. It will always validate signatures, and will decrypt -data if encryption is enabled. It is not valid to mix protection -modes. - -""" - -import base64 -import functools -import hashlib -import hmac -import math -import os -import six -import sys - -from keystonemiddleware.i18n import _ - -# make sure pycrypto is available -try: - from Crypto.Cipher import AES -except ImportError: - AES = None - -HASH_FUNCTION = hashlib.sha384 -DIGEST_LENGTH = HASH_FUNCTION().digest_size -DIGEST_SPLIT = DIGEST_LENGTH // 3 -DIGEST_LENGTH_B64 = 4 * int(math.ceil(DIGEST_LENGTH / 3.0)) - - -class InvalidMacError(Exception): - """raise when unable to verify MACed data. - - This usually indicates that data had been expectedly modified in memcache. - - """ - pass - - -class DecryptError(Exception): - """raise when unable to decrypt encrypted data. - - """ - pass - - -class CryptoUnavailableError(Exception): - """raise when Python Crypto module is not available. - - """ - pass - - -def assert_crypto_availability(f): - """Ensure Crypto module is available.""" - - @functools.wraps(f) - def wrapper(*args, **kwds): - if AES is None: - raise CryptoUnavailableError() - return f(*args, **kwds) - return wrapper - - -if sys.version_info >= (3, 3): - constant_time_compare = hmac.compare_digest -else: - def constant_time_compare(first, second): - """Returns True if both string inputs are equal, otherwise False. - - This function should take a constant amount of time regardless of - how many characters in the strings match. - - """ - if len(first) != len(second): - return False - result = 0 - if six.PY3 and isinstance(first, bytes) and isinstance(second, bytes): - for x, y in zip(first, second): - result |= x ^ y - else: - for x, y in zip(first, second): - result |= ord(x) ^ ord(y) - return result == 0 - - -def derive_keys(token, secret, strategy): - """Derives keys for MAC and ENCRYPTION from the user-provided - secret. The resulting keys should be passed to the protect and - unprotect functions. - - As suggested by NIST Special Publication 800-108, this uses the - first 128 bits from the sha384 KDF for the obscured cache key - value, the second 128 bits for the message authentication key and - the remaining 128 bits for the encryption key. - - This approach is faster than computing a separate hmac as the KDF - for each desired key. - """ - digest = hmac.new(secret, token + strategy, HASH_FUNCTION).digest() - return {'CACHE_KEY': digest[:DIGEST_SPLIT], - 'MAC': digest[DIGEST_SPLIT: 2 * DIGEST_SPLIT], - 'ENCRYPTION': digest[2 * DIGEST_SPLIT:], - 'strategy': strategy} - - -def sign_data(key, data): - """Sign the data using the defined function and the derived key.""" - mac = hmac.new(key, data, HASH_FUNCTION).digest() - return base64.b64encode(mac) - - -@assert_crypto_availability -def encrypt_data(key, data): - """Encrypt the data with the given secret key. - - Padding is n bytes of the value n, where 1 <= n <= blocksize. - """ - iv = os.urandom(16) - cipher = AES.new(key, AES.MODE_CBC, iv) - padding = 16 - len(data) % 16 - return iv + cipher.encrypt(data + six.int2byte(padding) * padding) - - -@assert_crypto_availability -def decrypt_data(key, data): - """Decrypt the data with the given secret key.""" - iv = data[:16] - cipher = AES.new(key, AES.MODE_CBC, iv) - try: - result = cipher.decrypt(data[16:]) - except Exception: - raise DecryptError(_('Encrypted data appears to be corrupted.')) - - # Strip the last n padding bytes where n is the last value in - # the plaintext - return result[:-1 * six.byte2int([result[-1]])] - - -def protect_data(keys, data): - """Given keys and serialized data, returns an appropriately - protected string suitable for storage in the cache. - - """ - if keys['strategy'] == b'ENCRYPT': - data = encrypt_data(keys['ENCRYPTION'], data) - - encoded_data = base64.b64encode(data) - - signature = sign_data(keys['MAC'], encoded_data) - return signature + encoded_data - - -def unprotect_data(keys, signed_data): - """Given keys and cached string data, verifies the signature, - decrypts if necessary, and returns the original serialized data. - - """ - # cache backends return None when no data is found. We don't mind - # that this particular special value is unsigned. - if signed_data is None: - return None - - # First we calculate the signature - provided_mac = signed_data[:DIGEST_LENGTH_B64] - calculated_mac = sign_data( - keys['MAC'], - signed_data[DIGEST_LENGTH_B64:]) - - # Then verify that it matches the provided value - if not constant_time_compare(provided_mac, calculated_mac): - raise InvalidMacError(_('Invalid MAC; data appears to be corrupted.')) - - data = base64.b64decode(signed_data[DIGEST_LENGTH_B64:]) - - # then if necessary decrypt the data - if keys['strategy'] == b'ENCRYPT': - data = decrypt_data(keys['ENCRYPTION'], data) - - return data - - -def get_cache_key(keys): - """Given keys generated by derive_keys(), returns a base64 - encoded value suitable for use as a cache key in memcached. - - """ - return base64.b64encode(keys['CACHE_KEY']) diff --git a/keystonemiddleware-moon/keystonemiddleware/auth_token/_memcache_pool.py b/keystonemiddleware-moon/keystonemiddleware/auth_token/_memcache_pool.py deleted file mode 100644 index 77652868..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/auth_token/_memcache_pool.py +++ /dev/null @@ -1,184 +0,0 @@ -# Copyright 2014 Mirantis Inc -# All Rights Reserved. -# -# 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. - -"""Thread-safe connection pool for python-memcached.""" - -# NOTE(yorik-sar): this file is copied between keystone and keystonemiddleware -# and should be kept in sync until we can use external library for this. - -import collections -import contextlib -import itertools -import logging -import time - -from six.moves import queue - -from keystonemiddleware.i18n import _LC - - -_PoolItem = collections.namedtuple('_PoolItem', ['ttl', 'connection']) - - -class ConnectionGetTimeoutException(Exception): - pass - - -class ConnectionPool(queue.Queue): - """Base connection pool class - - This class implements the basic connection pool logic as an abstract base - class. - """ - def __init__(self, maxsize, unused_timeout, conn_get_timeout=None): - """Initialize the connection pool. - - :param maxsize: maximum number of client connections for the pool - :type maxsize: int - :param unused_timeout: idle time to live for unused clients (in - seconds). If a client connection object has been - in the pool and idle for longer than the - unused_timeout, it will be reaped. This is to - ensure resources are released as utilization - goes down. - :type unused_timeout: int - :param conn_get_timeout: maximum time in seconds to wait for a - connection. If set to `None` timeout is - indefinite. - :type conn_get_timeout: int - """ - queue.Queue.__init__(self, maxsize) - self._unused_timeout = unused_timeout - self._connection_get_timeout = conn_get_timeout - self._acquired = 0 - self._LOG = logging.getLogger(__name__) - - def _create_connection(self): - raise NotImplementedError - - def _destroy_connection(self, conn): - raise NotImplementedError - - @contextlib.contextmanager - def acquire(self): - try: - conn = self.get(timeout=self._connection_get_timeout) - except queue.Empty: - self._LOG.critical(_LC('Unable to get a connection from pool id ' - '%(id)s after %(seconds)s seconds.'), - {'id': id(self), - 'seconds': self._connection_get_timeout}) - raise ConnectionGetTimeoutException() - try: - yield conn - finally: - self.put(conn) - - def _qsize(self): - return self.maxsize - self._acquired - - if not hasattr(queue.Queue, '_qsize'): - qsize = _qsize - - def _get(self): - if self.queue: - conn = self.queue.pop().connection - else: - conn = self._create_connection() - self._acquired += 1 - return conn - - def _put(self, conn): - self.queue.append(_PoolItem( - ttl=time.time() + self._unused_timeout, - connection=conn, - )) - self._acquired -= 1 - # Drop all expired connections from the right end of the queue - now = time.time() - while self.queue and self.queue[0].ttl < now: - conn = self.queue.popleft().connection - self._destroy_connection(conn) - - -class MemcacheClientPool(ConnectionPool): - def __init__(self, urls, arguments, **kwargs): - ConnectionPool.__init__(self, **kwargs) - self._urls = urls - self._arguments = arguments - # NOTE(morganfainberg): The host objects expect an int for the - # deaduntil value. Initialize this at 0 for each host with 0 indicating - # the host is not dead. - self._hosts_deaduntil = [0] * len(urls) - - # NOTE(morganfainberg): Lazy import to allow middleware to work with - # python 3k even if memcache will not due to python 3k - # incompatibilities within the python-memcache library. - global memcache - import memcache - - # This 'class' is taken from http://stackoverflow.com/a/22520633/238308 - # Don't inherit client from threading.local so that we can reuse - # clients in different threads - MemcacheClient = type('_MemcacheClient', (object,), - dict(memcache.Client.__dict__)) - - self._memcache_client_class = MemcacheClient - - def _create_connection(self): - return self._memcache_client_class(self._urls, **self._arguments) - - def _destroy_connection(self, conn): - conn.disconnect_all() - - def _get(self): - conn = ConnectionPool._get(self) - try: - # Propagate host state known to us to this client's list - now = time.time() - for deaduntil, host in zip(self._hosts_deaduntil, conn.servers): - if deaduntil > now and host.deaduntil <= now: - host.mark_dead('propagating death mark from the pool') - host.deaduntil = deaduntil - except Exception: - # We need to be sure that connection doesn't leak from the pool. - # This code runs before we enter context manager's try-finally - # block, so we need to explicitly release it here - ConnectionPool._put(self, conn) - raise - return conn - - def _put(self, conn): - try: - # If this client found that one of the hosts is dead, mark it as - # such in our internal list - now = time.time() - for i, deaduntil, host in zip(itertools.count(), - self._hosts_deaduntil, - conn.servers): - # Do nothing if we already know this host is dead - if deaduntil <= now: - if host.deaduntil > now: - self._hosts_deaduntil[i] = host.deaduntil - else: - self._hosts_deaduntil[i] = 0 - # If all hosts are dead we should forget that they're dead. This - # way we won't get completely shut off until dead_retry seconds - # pass, but will be checking servers as frequent as we can (over - # way smaller socket_timeout) - if all(deaduntil > now for deaduntil in self._hosts_deaduntil): - self._hosts_deaduntil[:] = [0] * len(self._hosts_deaduntil) - finally: - ConnectionPool._put(self, conn) diff --git a/keystonemiddleware-moon/keystonemiddleware/auth_token/_request.py b/keystonemiddleware-moon/keystonemiddleware/auth_token/_request.py deleted file mode 100644 index 72fd5380..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/auth_token/_request.py +++ /dev/null @@ -1,224 +0,0 @@ -# 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. - -import itertools - -from oslo_serialization import jsonutils -import six -import webob - - -def _v3_to_v2_catalog(catalog): - """Convert a catalog to v2 format. - - X_SERVICE_CATALOG must be specified in v2 format. If you get a token - that is in v3 convert it. - """ - v2_services = [] - for v3_service in catalog: - # first copy over the entries we allow for the service - v2_service = {'type': v3_service['type']} - try: - v2_service['name'] = v3_service['name'] - except KeyError: - pass - - # now convert the endpoints. Because in v3 we specify region per - # URL not per group we have to collect all the entries of the same - # region together before adding it to the new service. - regions = {} - for v3_endpoint in v3_service.get('endpoints', []): - region_name = v3_endpoint.get('region') - try: - region = regions[region_name] - except KeyError: - region = {'region': region_name} if region_name else {} - regions[region_name] = region - - interface_name = v3_endpoint['interface'].lower() + 'URL' - region[interface_name] = v3_endpoint['url'] - - v2_service['endpoints'] = list(regions.values()) - v2_services.append(v2_service) - - return v2_services - - -# NOTE(jamielennox): this should probably be moved into its own file, but at -# the moment there's no real logic here so just keep it locally. -class _AuthTokenResponse(webob.Response): - - default_content_type = None # prevents webob assigning a content type - - -class _AuthTokenRequest(webob.Request): - - ResponseClass = _AuthTokenResponse - - _HEADER_TEMPLATE = { - 'X%s-Domain-Id': 'domain_id', - 'X%s-Domain-Name': 'domain_name', - 'X%s-Project-Id': 'project_id', - 'X%s-Project-Name': 'project_name', - 'X%s-Project-Domain-Id': 'project_domain_id', - 'X%s-Project-Domain-Name': 'project_domain_name', - 'X%s-User-Id': 'user_id', - 'X%s-User-Name': 'username', - 'X%s-User-Domain-Id': 'user_domain_id', - 'X%s-User-Domain-Name': 'user_domain_name', - } - - _ROLES_TEMPLATE = 'X%s-Roles' - - _USER_HEADER_PREFIX = '' - _SERVICE_HEADER_PREFIX = '-Service' - - _USER_STATUS_HEADER = 'X-Identity-Status' - _SERVICE_STATUS_HEADER = 'X-Service-Identity-Status' - - _SERVICE_CATALOG_HEADER = 'X-Service-Catalog' - _TOKEN_AUTH = 'keystone.token_auth' - - _CONFIRMED = 'Confirmed' - _INVALID = 'Invalid' - - # header names that have been deprecated in favour of something else. - _DEPRECATED_HEADER_MAP = { - 'X-Role': 'X-Roles', - 'X-User': 'X-User-Name', - 'X-Tenant-Id': 'X-Project-Id', - 'X-Tenant-Name': 'X-Project-Name', - 'X-Tenant': 'X-Project-Name', - } - - def _confirmed(cls, value): - return cls._CONFIRMED if value else cls._INVALID - - @property - def user_token_valid(self): - """User token is marked as valid. - - :returns: True if the X-Identity-Status header is set to Confirmed. - :rtype: bool - """ - return self.headers[self._USER_STATUS_HEADER] == self._CONFIRMED - - @user_token_valid.setter - def user_token_valid(self, value): - self.headers[self._USER_STATUS_HEADER] = self._confirmed(value) - - @property - def user_token(self): - return self.headers.get('X-Auth-Token', - self.headers.get('X-Storage-Token')) - - @property - def service_token_valid(self): - """Service token is marked as valid. - - :returns: True if the X-Service-Identity-Status header - is set to Confirmed. - :rtype: bool - """ - return self.headers[self._SERVICE_STATUS_HEADER] == self._CONFIRMED - - @service_token_valid.setter - def service_token_valid(self, value): - self.headers[self._SERVICE_STATUS_HEADER] = self._confirmed(value) - - @property - def service_token(self): - return self.headers.get('X-Service-Token') - - def _set_auth_headers(self, auth_ref, prefix): - names = ','.join(auth_ref.role_names) - self.headers[self._ROLES_TEMPLATE % prefix] = names - - for header_tmplt, attr in six.iteritems(self._HEADER_TEMPLATE): - self.headers[header_tmplt % prefix] = getattr(auth_ref, attr) - - def set_user_headers(self, auth_ref, include_service_catalog): - """Convert token object into headers. - - Build headers that represent authenticated user - see main - doc info at start of __init__ file for details of headers to be defined - """ - self._set_auth_headers(auth_ref, self._USER_HEADER_PREFIX) - - for k, v in six.iteritems(self._DEPRECATED_HEADER_MAP): - self.headers[k] = self.headers[v] - - if include_service_catalog and auth_ref.has_service_catalog(): - catalog = auth_ref.service_catalog.get_data() - if auth_ref.version == 'v3': - catalog = _v3_to_v2_catalog(catalog) - - c = jsonutils.dumps(catalog) - self.headers[self._SERVICE_CATALOG_HEADER] = c - - self.user_token_valid = True - - def set_service_headers(self, auth_ref): - """Convert token object into service headers. - - Build headers that represent authenticated user - see main - doc info at start of __init__ file for details of headers to be defined - """ - self._set_auth_headers(auth_ref, self._SERVICE_HEADER_PREFIX) - self.service_token_valid = True - - def _all_auth_headers(self): - """All the authentication headers that can be set on the request""" - yield self._SERVICE_CATALOG_HEADER - yield self._USER_STATUS_HEADER - yield self._SERVICE_STATUS_HEADER - - for header in self._DEPRECATED_HEADER_MAP: - yield header - - prefixes = (self._USER_HEADER_PREFIX, self._SERVICE_HEADER_PREFIX) - - for tmpl, prefix in itertools.product(self._HEADER_TEMPLATE, prefixes): - yield tmpl % prefix - - for prefix in prefixes: - yield self._ROLES_TEMPLATE % prefix - - def remove_auth_headers(self): - """Remove headers so a user can't fake authentication.""" - for header in self._all_auth_headers(): - self.headers.pop(header, None) - - @property - def auth_type(self): - """The authentication type that was performed by the web server. - - The returned string value is always lower case. - - :returns: The AUTH_TYPE environ string or None if not present. - :rtype: str or None - """ - try: - auth_type = self.environ['AUTH_TYPE'] - except KeyError: - return None - else: - return auth_type.lower() - - @property - def token_auth(self): - """The auth plugin that will be associated with this request""" - return self.environ.get(self._TOKEN_AUTH) - - @token_auth.setter - def token_auth(self, v): - self.environ[self._TOKEN_AUTH] = v diff --git a/keystonemiddleware-moon/keystonemiddleware/auth_token/_revocations.py b/keystonemiddleware-moon/keystonemiddleware/auth_token/_revocations.py deleted file mode 100644 index a68356a8..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/auth_token/_revocations.py +++ /dev/null @@ -1,128 +0,0 @@ -# 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. - -import datetime -import logging -import os - -from oslo_serialization import jsonutils -from oslo_utils import timeutils - -from keystonemiddleware.auth_token import _exceptions as exc -from keystonemiddleware.i18n import _ - -_LOG = logging.getLogger(__name__) - - -class Revocations(object): - _FILE_NAME = 'revoked.pem' - - def __init__(self, timeout, signing_directory, identity_server, - cms_verify, log=_LOG): - self._cache_timeout = timeout - self._signing_directory = signing_directory - self._identity_server = identity_server - self._cms_verify = cms_verify - self._log = log - - self._fetched_time_prop = None - self._list_prop = None - - @property - def _fetched_time(self): - if not self._fetched_time_prop: - # If the fetched list has been written to disk, use its - # modification time. - file_path = self._signing_directory.calc_path(self._FILE_NAME) - if os.path.exists(file_path): - mtime = os.path.getmtime(file_path) - fetched_time = datetime.datetime.utcfromtimestamp(mtime) - # Otherwise the list will need to be fetched. - else: - fetched_time = datetime.datetime.min - self._fetched_time_prop = fetched_time - return self._fetched_time_prop - - @_fetched_time.setter - def _fetched_time(self, value): - self._fetched_time_prop = value - - def _fetch(self): - revocation_list_data = self._identity_server.fetch_revocation_list() - return self._cms_verify(revocation_list_data) - - @property - def _list(self): - timeout = self._fetched_time + self._cache_timeout - list_is_current = timeutils.utcnow() < timeout - - if list_is_current: - # Load the list from disk if required - if not self._list_prop: - self._list_prop = jsonutils.loads( - self._signing_directory.read_file(self._FILE_NAME)) - else: - self._list = self._fetch() - return self._list_prop - - @_list.setter - def _list(self, value): - """Save a revocation list to memory and to disk. - - :param value: A json-encoded revocation list - - """ - self._list_prop = jsonutils.loads(value) - self._fetched_time = timeutils.utcnow() - self._signing_directory.write_file(self._FILE_NAME, value) - - def _is_revoked(self, token_id): - """Indicate whether the token_id appears in the revocation list.""" - revoked_tokens = self._list.get('revoked', None) - if not revoked_tokens: - return False - - revoked_ids = (x['id'] for x in revoked_tokens) - return token_id in revoked_ids - - def _any_revoked(self, token_ids): - for token_id in token_ids: - if self._is_revoked(token_id): - return True - return False - - def check(self, token_ids): - if self._any_revoked(token_ids): - self._log.debug('Token is marked as having been revoked') - raise exc.InvalidToken(_('Token has been revoked')) - - def check_by_audit_id(self, audit_ids): - """Check whether the audit_id appears in the revocation list. - - :raises keystonemiddleware.auth_token._exceptions.InvalidToken: - if the audit ID(s) appear in the revocation list. - - """ - revoked_tokens = self._list.get('revoked', None) - if not revoked_tokens: - # There's no revoked tokens, so nothing to do. - return - - # The audit_id may not be present in the revocation events because - # earlier versions of the identity server didn't provide them. - revoked_ids = set( - x['audit_id'] for x in revoked_tokens if 'audit_id' in x) - for audit_id in audit_ids: - if audit_id in revoked_ids: - self._log.debug( - 'Token is marked as having been revoked by audit id') - raise exc.InvalidToken(_('Token has been revoked')) diff --git a/keystonemiddleware-moon/keystonemiddleware/auth_token/_signing_dir.py b/keystonemiddleware-moon/keystonemiddleware/auth_token/_signing_dir.py deleted file mode 100644 index f8b1a410..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/auth_token/_signing_dir.py +++ /dev/null @@ -1,83 +0,0 @@ -# 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. - -import logging -import os -import stat -import tempfile - -import six - -from keystonemiddleware.auth_token import _exceptions as exc -from keystonemiddleware.i18n import _, _LI, _LW - -_LOG = logging.getLogger(__name__) - - -class SigningDirectory(object): - - def __init__(self, directory_name=None, log=None): - self._log = log or _LOG - - if directory_name is None: - directory_name = tempfile.mkdtemp(prefix='keystone-signing-') - self._log.info( - _LI('Using %s as cache directory for signing certificate'), - directory_name) - self._directory_name = directory_name - - self._verify_signing_dir() - - def write_file(self, file_name, new_contents): - - # In Python2, encoding is slow so the following check avoids it if it - # is not absolutely necessary. - if isinstance(new_contents, six.text_type): - new_contents = new_contents.encode('utf-8') - - def _atomic_write(): - with tempfile.NamedTemporaryFile(dir=self._directory_name, - delete=False) as f: - f.write(new_contents) - os.rename(f.name, self.calc_path(file_name)) - - try: - _atomic_write() - except (OSError, IOError): - self._verify_signing_dir() - _atomic_write() - - def read_file(self, file_name): - path = self.calc_path(file_name) - open_kwargs = {'encoding': 'utf-8'} if six.PY3 else {} - with open(path, 'r', **open_kwargs) as f: - return f.read() - - def calc_path(self, file_name): - return os.path.join(self._directory_name, file_name) - - def _verify_signing_dir(self): - if os.path.isdir(self._directory_name): - if not os.access(self._directory_name, os.W_OK): - raise exc.ConfigurationError( - _('unable to access signing_dir %s') % - self._directory_name) - uid = os.getuid() - if os.stat(self._directory_name).st_uid != uid: - self._log.warning(_LW('signing_dir is not owned by %s'), uid) - current_mode = stat.S_IMODE(os.stat(self._directory_name).st_mode) - if current_mode != stat.S_IRWXU: - self._log.warning( - _LW('signing_dir mode is %(mode)s instead of %(need)s'), - {'mode': oct(current_mode), 'need': oct(stat.S_IRWXU)}) - else: - os.makedirs(self._directory_name, stat.S_IRWXU) diff --git a/keystonemiddleware-moon/keystonemiddleware/auth_token/_user_plugin.py b/keystonemiddleware-moon/keystonemiddleware/auth_token/_user_plugin.py deleted file mode 100644 index 93075c5c..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/auth_token/_user_plugin.py +++ /dev/null @@ -1,193 +0,0 @@ -# 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 keystoneclient.auth.identity import base as base_identity - - -class _TokenData(object): - """An abstraction to show auth_token consumers some of the token contents. - - This is a simplified and cleaned up keystoneclient.access.AccessInfo object - with which services relying on auth_token middleware can find details of - the current token. - """ - - def __init__(self, auth_ref): - self._stored_auth_ref = auth_ref - - @property - def _is_v2(self): - return self._stored_auth_ref.version == 'v2.0' - - @property - def auth_token(self): - """The token data used to authenticate requests. - - :returns: token data. - :rtype: str - """ - return self._stored_auth_ref.auth_token - - @property - def user_id(self): - """The user id associated with the authentication request. - - :rtype: str - """ - return self._stored_auth_ref.user_id - - @property - def user_domain_id(self): - """Returns the domain id of the user associated with the authentication - request. - - :returns: str - """ - # NOTE(jamielennox): v2 AccessInfo returns 'default' for domain_id - # because it can't know that value. We want to return None instead. - if self._is_v2: - return None - - return self._stored_auth_ref.user_domain_id - - @property - def project_id(self): - """The project ID associated with the authentication. - - :rtype: str - """ - return self._stored_auth_ref.project_id - - @property - def project_domain_id(self): - """The domain id of the project associated with the authentication - request. - - :rtype: str - """ - # NOTE(jamielennox): v2 AccessInfo returns 'default' for domain_id - # because it can't know that value. We want to return None instead. - if self._is_v2: - return None - - return self._stored_auth_ref.project_domain_id - - @property - def trust_id(self): - """Returns the trust id associated with the authentication request.. - - :rtype: str - """ - return self._stored_auth_ref.trust_id - - @property - def role_ids(self): - """Role ids of the user associated with the authentication request. - - :rtype: set(str) - """ - return frozenset(self._stored_auth_ref.role_ids or []) - - @property - def role_names(self): - """Role names of the user associated with the authentication request. - - :rtype: set(str) - """ - return frozenset(self._stored_auth_ref.role_names or []) - - @property - def _log_format(self): - roles = ','.join(self.role_names) - return 'user_id %s, project_id %s, roles %s' % (self.user_id, - self.project_id, - roles) - - -class UserAuthPlugin(base_identity.BaseIdentityPlugin): - """The incoming authentication credentials. - - A plugin that represents the incoming user credentials. This can be - consumed by applications. - - This object is not expected to be constructed directly by users. It is - created and passed by auth_token middleware and then can be used as the - authentication plugin when communicating via a session. - """ - - def __init__(self, user_auth_ref, serv_auth_ref): - super(UserAuthPlugin, self).__init__(reauthenticate=False) - - # NOTE(jamielennox): _user_auth_ref and _serv_auth_ref are private - # because this object ends up in the environ that is passed to the - # service, however they are used within auth_token middleware. - self._user_auth_ref = user_auth_ref - self._serv_auth_ref = serv_auth_ref - - self._user_data = None - self._serv_data = None - - @property - def has_user_token(self): - """Did this authentication request contained a user auth token.""" - return self._user_auth_ref is not None - - @property - def user(self): - """Authentication information about the user token. - - Will return None if a user token was not passed with this request. - """ - if not self.has_user_token: - return None - - if not self._user_data: - self._user_data = _TokenData(self._user_auth_ref) - - return self._user_data - - @property - def has_service_token(self): - """Did this authentication request contained a service token.""" - return self._serv_auth_ref is not None - - @property - def service(self): - """Authentication information about the service token. - - Will return None if a user token was not passed with this request. - """ - if not self.has_service_token: - return None - - if not self._serv_data: - self._serv_data = _TokenData(self._serv_auth_ref) - - return self._serv_data - - def get_auth_ref(self, session, **kwargs): - # NOTE(jamielennox): We will always use the auth_ref that was - # calculated by the middleware. reauthenticate=False in __init__ should - # ensure that this function is only called on the first access. - return self._user_auth_ref - - @property - def _log_format(self): - msg = [] - - if self.has_user_token: - msg.append('user: %s' % self.user._log_format) - - if self.has_service_token: - msg.append('service: %s' % self.service._log_format) - - return ' '.join(msg) diff --git a/keystonemiddleware-moon/keystonemiddleware/auth_token/_utils.py b/keystonemiddleware-moon/keystonemiddleware/auth_token/_utils.py deleted file mode 100644 index daed02dd..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/auth_token/_utils.py +++ /dev/null @@ -1,32 +0,0 @@ -# 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 six.moves import urllib - - -def safe_quote(s): - """URL-encode strings that are not already URL-encoded.""" - return urllib.parse.quote(s) if s == urllib.parse.unquote(s) else s - - -class MiniResp(object): - - def __init__(self, error_message, env, headers=[]): - # The HEAD method is unique: it must never return a body, even if - # it reports an error (RFC-2616 clause 9.4). We relieve callers - # from varying the error responses depending on the method. - if env['REQUEST_METHOD'] == 'HEAD': - self.body = [''] - else: - self.body = [error_message.encode()] - self.headers = list(headers) - self.headers.append(('Content-type', 'text/plain')) diff --git a/keystonemiddleware-moon/keystonemiddleware/authz.py b/keystonemiddleware-moon/keystonemiddleware/authz.py deleted file mode 100644 index 93c0a7da..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/authz.py +++ /dev/null @@ -1,292 +0,0 @@ -# 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 webob -import logging -import json -import six -import requests -import re -import httplib - -from keystone import exception -from cStringIO import StringIO -from oslo_config import cfg -# from keystoneclient import auth -from keystonemiddleware.i18n import _, _LC, _LE, _LI, _LW - - -_OPTS = [ - cfg.StrOpt('auth_uri', - default="http://127.0.0.1:35357/v3", - help='Complete public Identity API endpoint.'), - cfg.StrOpt('auth_version', - default=None, - help='API version of the admin Identity API endpoint.'), - cfg.StrOpt('authz_login', - default="admin", - help='Name of the administrator who will connect to the Keystone Moon backends.'), - cfg.StrOpt('authz_password', - default="nomoresecrete", - help='Password of the administrator who will connect to the Keystone Moon backends.'), - cfg.StrOpt('logfile', - default="/tmp/authz.log", - help='File where logs goes.'), - ] - -_AUTHZ_GROUP = 'keystone_authz' -CONF = cfg.CONF -CONF.register_opts(_OPTS, group=_AUTHZ_GROUP) -CONF.debug = True -# auth.register_conf_options(CONF, _AUTHZ_GROUP) - -# from http://developer.openstack.org/api-ref-objectstorage-v1.html -SWIFT_API = ( - ("^/v1/(?P[\w_-]+)$", "GET", "get_account_details"), - ("^/v1/(?P[\w_-]+)$", "POST", "modify_account"), - ("^/v1/(?P[\w_-]+)$", "HEAD", "get_account"), - ("^/v1/(?P[\w_-]+)/(?P[\w-]+)$", "GET", "get_container"), - ("^/v1/(?P[\w_-]+)/(?P[\w-]+)$", "PUT", "create_container"), - ("^/v1/(?P[\w_-]+)/(?P[\w-]+)$", "POST", "update_container_metadata"), - ("^/v1/(?P[\w_-]+)/(?P[\w-]+)$", "DELETE", "delete_container"), - ("^/v1/(?P[\w_-]+)/(?P[\w-]+)$", "HEAD", "get_container_metadata"), - ("^/v1/(?P[\w_-]+)/(?P[\w-]+)/(?P.+)$", "GET", "get_object"), - ("^/v1/(?P[\w_-]+)/(?P[\w-]+)/(?P.+)$", "PUT", "create_object"), - ("^/v1/(?P[\w_-]+)/(?P[\w-]+)/(?P.+)$", "COPY", "copy_object"), - ("^/v1/(?P[\w_-]+)/(?P[\w-]+)/(?P.+)$", "POST", "update_object_metadata"), - ("^/v1/(?P[\w_-]+)/(?P[\w-]+)/(?P.+)$", "DELETE", "delete_object"), - ("^/v1/(?P[\w_-]+)/(?P[\w-]+)/(?P.+)$", "HEAD", "get_object_metadata"), -) - - -class ServiceError(Exception): - pass - - -class AuthZProtocol(object): - """Middleware that handles authenticating client calls.""" - - def __init__(self, app, conf): - self._LOG = logging.getLogger(conf.get('log_name', __name__)) - # FIXME: events are duplicated in log file - authz_fh = logging.FileHandler(CONF.keystone_authz["logfile"]) - self._LOG.setLevel(logging.DEBUG) - self._LOG.addHandler(authz_fh) - self._LOG.info(_LI('Starting Keystone authz middleware')) - self._conf = conf - self._app = app - - # MOON - self.auth_host = conf.get('auth_host', "127.0.0.1") - self.auth_port = int(conf.get('auth_port', 35357)) - auth_protocol = conf.get('auth_protocol', 'http') - self._request_uri = '%s://%s:%s' % (auth_protocol, self.auth_host, - self.auth_port) - - # SSL - insecure = conf.get('insecure', False) - cert_file = conf.get('certfile') - key_file = conf.get('keyfile') - - if insecure: - self._verify = False - elif cert_file and key_file: - self._verify = (cert_file, key_file) - elif cert_file: - self._verify = cert_file - else: - self._verify = None - - def get_url(self, url): - conn = httplib.HTTPConnection(self.auth_host, self.auth_port) - headers = { - "Content-type": "application/x-www-form-urlencoded", - "Accept": "text/plain,text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", - } - conn.request('GET', url, headers=headers) - resp = conn.getresponse() - content = resp.read() - conn.close() - try: - return json.loads(content) - except ValueError: - return {"content": content} - - def _deny_request(self, code): - error_table = { - 'AccessDenied': (401, 'Access denied'), - 'InvalidURI': (400, 'Could not parse the specified URI'), - 'NotFound': (404, 'URI not found'), - 'Error': (500, 'Server error'), - } - resp = webob.Response(content_type='text/xml') - resp.status = error_table[code][0] - error_msg = ('\r\n' - '\r\n %s\r\n ' - '%s\r\n\r\n' % - (code, error_table[code][1])) - if six.PY3: - error_msg = error_msg.encode() - resp.body = error_msg - return resp - - def _get_authz_from_moon(self, tenant_id, subject_id, object_id, action_id): - try: - _url ='{}/v3/OS-MOON/authz/{}/{}/{}/{}'.format( - self._request_uri, - tenant_id, - subject_id, - object_id, - action_id) - self._LOG.info(_url) - response = requests.get(_url,verify=self._verify) - except requests.exceptions.RequestException as e: - self._LOG.error(_LI('HTTP connection exception: %s'), e) - resp = self._deny_request('InvalidURI') - raise ServiceError(resp) - - if response.status_code < 200 or response.status_code >= 300: - self._LOG.debug('Keystone reply error: status=%s reason=%s', - response.status_code, response.reason) - if response.status_code == 404: - resp = self._deny_request('NotFound') - elif response.status_code == 401: - resp = self._deny_request('AccessDenied') - else: - resp = self._deny_request('Error') - raise ServiceError(resp) - - return response - - def _find_openstack_component(self, env): - if "nova.context" in env.keys(): - return "nova" - elif "swift.authorize" in env.keys(): - return "swift" - else: - self._LOG.debug(env.keys()) - return "unknown" - - def _get_action(self, env, component): - """ Find and return the action of the request - Actually, find only Nova (start, destroy, pause, unpause, ...) and swift actions - - :param env: the request - :return: the action or "" - """ - action = "" - self.input = "" - if component == "nova": - length = int(env.get('CONTENT_LENGTH', '0')) - # TODO (dthom): compute for Nova, Cinder, Neutron, ... - action = "" - if length > 0: - try: - sub_action_object = env['wsgi.input'].read(length) - self.input = sub_action_object - action = json.loads(sub_action_object).keys()[0] - body = StringIO(sub_action_object) - env['wsgi.input'] = body - except ValueError: - self._LOG.error("Error in decoding sub-action") - except Exception as e: - self._LOG.error(str(e)) - if not action or len(action) == 0 and "servers/detail" in env["PATH_INFO"]: - return "list" - if component == "swift": - path = env["PATH_INFO"] - method = env["REQUEST_METHOD"] - for api in SWIFT_API: - if re.match(api[0], path) and method == api[1]: - action = api[2] - length = int(env.get('CONTENT_LENGTH', '0')) - # TODO (dthom): compute for Nova, Cinder, Neutron, ... - _action = "" - if length > 0: - try: - sub_action_object = env['wsgi.input'].read(length) - self.input = sub_action_object - _action = json.loads(sub_action_object).keys()[0] - body = StringIO(sub_action_object) - env['wsgi.input'] = body - self._LOG.debug("wsgi.input={}".format(_action)) - except ValueError: - self._LOG.error("Error in decoding sub-action") - except Exception as e: - self._LOG.error(str(e)) - return action - - @staticmethod - def _get_object(env, component): - if component == "nova": - # http://developer.openstack.org/api-ref-compute-v2.1.html - # nova URLs: - # //servers/ - # list details for server_id - # //servers//action - # execute action to server_id - # //servers//metadata - # show metadata from server_id - # //servers/details - # list servers - url = env.get("PATH_INFO").split("/") - if url[-1] == "detail": - return "servers" - try: - return url[3] - except IndexError: - return - elif component == "swift": - # remove the "/v1/" part of the URL - return env.get("PATH_INFO").split("/", 2)[-1].replace("/", "-").replace(".", "-") - return "unknown" - - def __call__(self, env, start_response): - req = webob.Request(env) - - subject_id = env.get("HTTP_X_USER_ID") - if not subject_id: - self._LOG.warning("No subject_id found for {}".format(env.get("PATH_INFO"))) - return self._app(env, start_response) - tenant_id = env.get("HTTP_X_TENANT_ID") - if not tenant_id: - self._LOG.warning("No tenant_id found for {}".format(env.get("PATH_INFO"))) - return self._app(env, start_response) - component = self._find_openstack_component(env) - action_id = self._get_action(env, component) - self._LOG.debug("\033[1m\033[31mrequest={}\033[m".format(env["PATH_INFO"])) - if action_id: - object_id = self._get_object(env, component) - if not object_id: - object_id = "servers" - self._LOG.debug("object_id={}".format(object_id)) - resp = self._get_authz_from_moon(tenant_id, subject_id, object_id, action_id) - if resp.status_code == 200: - answer = json.loads(resp.content) - self._LOG.debug("action_id={}/{}".format(component, action_id)) - self._LOG.debug(answer) - if "authz" in answer and answer["authz"]: - return self._app(env, start_response) - self._LOG.error("You are not authorized to do that! ({})".format(unicode(answer["comment"]))) - raise exception.Unauthorized(message="You are not authorized to do that! ({})".format(unicode(answer["comment"]))) - else: - self._LOG.error("Unable to request Moon ({}: {})".format(resp.status_code, resp.reason)) - else: - self._LOG.debug("No action_id found for {}".format(env.get("PATH_INFO"))) - # If action is not found, we can't raise an exception because a lots of action is missing - # in function self._get_action, it is not possible to get them all. - return self._app(env, start_response) - # raise exception.Unauthorized(message="You are not authorized to do that!") - - -def filter_factory(global_conf, **local_conf): - """Returns a WSGI filter app for use with paste.deploy.""" - conf = global_conf.copy() - conf.update(local_conf) - - def auth_filter(app): - return AuthZProtocol(app, conf) - return auth_filter - diff --git a/keystonemiddleware-moon/keystonemiddleware/ec2_token.py b/keystonemiddleware-moon/keystonemiddleware/ec2_token.py deleted file mode 100644 index df3bb6b0..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/ec2_token.py +++ /dev/null @@ -1,130 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. -# -# 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. - -""" -Starting point for routing EC2 requests. - -""" - -from oslo_config import cfg -from oslo_serialization import jsonutils -import requests -import webob.dec -import webob.exc - -keystone_ec2_opts = [ - cfg.StrOpt('url', - default='http://localhost:5000/v2.0/ec2tokens', - help='URL to get token from ec2 request.'), - cfg.StrOpt('keyfile', - help='Required if EC2 server requires client certificate.'), - cfg.StrOpt('certfile', - help='Client certificate key filename. Required if EC2 server ' - 'requires client certificate.'), - cfg.StrOpt('cafile', - help='A PEM encoded certificate authority to use when ' - 'verifying HTTPS connections. Defaults to the system ' - 'CAs.'), - cfg.BoolOpt('insecure', default=False, - help='Disable SSL certificate verification.'), -] - -CONF = cfg.CONF -CONF.register_opts(keystone_ec2_opts, group='keystone_ec2_token') - - -class EC2Token(object): - """Authenticate an EC2 request with keystone and convert to token.""" - - def __init__(self, application): - super(EC2Token, self).__init__() - self._application = application - - @webob.dec.wsgify() - def __call__(self, req): - # Read request signature and access id. - try: - signature = req.params['Signature'] - access = req.params['AWSAccessKeyId'] - except KeyError: - raise webob.exc.HTTPBadRequest() - - # Make a copy of args for authentication and signature verification. - auth_params = dict(req.params) - # Not part of authentication args - auth_params.pop('Signature') - - # Authenticate the request. - creds = { - 'ec2Credentials': { - 'access': access, - 'signature': signature, - 'host': req.host, - 'verb': req.method, - 'path': req.path, - 'params': auth_params, - } - } - creds_json = jsonutils.dumps(creds) - headers = {'Content-Type': 'application/json'} - - verify = True - if CONF.keystone_ec2_token.insecure: - verify = False - elif CONF.keystone_ec2_token.cafile: - verify = CONF.keystone_ec2_token.cafile - - cert = None - if (CONF.keystone_ec2_token.certfile and - CONF.keystone_ec2_token.keyfile): - cert = (CONF.keystone_ec2_certfile, - CONF.keystone_ec2_token.keyfile) - elif CONF.keystone_ec2_token.certfile: - cert = CONF.keystone_ec2_token.certfile - - response = requests.post(CONF.keystone_ec2_token.url, data=creds_json, - headers=headers, verify=verify, cert=cert) - - # NOTE(vish): We could save a call to keystone by - # having keystone return token, tenant, - # user, and roles from this call. - - result = response.json() - try: - token_id = result['access']['token']['id'] - except (AttributeError, KeyError): - raise webob.exc.HTTPBadRequest() - - # Authenticated! - req.headers['X-Auth-Token'] = token_id - return self._application - - -def filter_factory(global_conf, **local_conf): - """Returns a WSGI filter app for use with paste.deploy.""" - conf = global_conf.copy() - conf.update(local_conf) - - def auth_filter(app): - return EC2Token(app, conf) - return auth_filter - - -def app_factory(global_conf, **local_conf): - conf = global_conf.copy() - conf.update(local_conf) - return EC2Token(None, conf) diff --git a/keystonemiddleware-moon/keystonemiddleware/echo/__init__.py b/keystonemiddleware-moon/keystonemiddleware/echo/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/keystonemiddleware-moon/keystonemiddleware/echo/__main__.py b/keystonemiddleware-moon/keystonemiddleware/echo/__main__.py deleted file mode 100644 index 88332f02..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/echo/__main__.py +++ /dev/null @@ -1,7 +0,0 @@ -from keystonemiddleware.echo import service - - -try: - service.EchoService() -except KeyboardInterrupt: - pass diff --git a/keystonemiddleware-moon/keystonemiddleware/echo/service.py b/keystonemiddleware-moon/keystonemiddleware/echo/service.py deleted file mode 100644 index 277cc027..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/echo/service.py +++ /dev/null @@ -1,48 +0,0 @@ -# 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. - -""" -Run the echo service directly on port 8000 by executing the following:: - - $ python -m keystonemiddleware.echo - -When the ``auth_token`` module authenticates a request, the echo service -will respond with all the environment variables presented to it by this -module. -""" - -from wsgiref import simple_server - -from oslo_serialization import jsonutils -import six - -from keystonemiddleware import auth_token - - -def echo_app(environ, start_response): - """A WSGI application that echoes the CGI environment back to the user.""" - start_response('200 OK', [('Content-Type', 'application/json')]) - environment = dict((k, v) for k, v in six.iteritems(environ) - if k.startswith('HTTP_X_')) - yield jsonutils.dumps(environment) - - -class EchoService(object): - """Runs an instance of the echo app on init.""" - def __init__(self): - # hardcode any non-default configuration here - conf = {'auth_protocol': 'http', 'admin_token': 'ADMIN'} - app = auth_token.AuthProtocol(echo_app, conf) - server = simple_server.make_server('', 8000, app) - print('Serving on port 8000 (Ctrl+C to end)...') - server.serve_forever() diff --git a/keystonemiddleware-moon/keystonemiddleware/i18n.py b/keystonemiddleware-moon/keystonemiddleware/i18n.py deleted file mode 100644 index 0591284d..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/i18n.py +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright 2014 IBM Corp. -# -# 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. - -"""oslo.i18n integration module. - -See http://docs.openstack.org/developer/oslo.i18n/usage.html . - -""" - -import oslo_i18n as i18n - - -_translators = i18n.TranslatorFactory(domain='keystonemiddleware') - -# The primary translation function using the well-known name "_" -_ = _translators.primary - -# Translators for log levels. -# -# The abbreviated names are meant to reflect the usual use of a short -# name like '_'. The "L" is for "log" and the other letter comes from -# the level. -_LI = _translators.log_info -_LW = _translators.log_warning -_LE = _translators.log_error -_LC = _translators.log_critical diff --git a/keystonemiddleware-moon/keystonemiddleware/moon_agent.py b/keystonemiddleware-moon/keystonemiddleware/moon_agent.py deleted file mode 100644 index fd878fea..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/moon_agent.py +++ /dev/null @@ -1,310 +0,0 @@ -# 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 webob -import logging -import json -import re -import httplib - -from cStringIO import StringIO -from oslo_config import cfg -from keystonemiddleware.i18n import _, _LC, _LE, _LI, _LW - - -_OPTS = [ - cfg.StrOpt('auth_uri', - default="http://127.0.0.1:35357/v3", - help='Complete public Identity API endpoint.'), - cfg.StrOpt('auth_version', - default=None, - help='API version of the admin Identity API endpoint.'), - cfg.StrOpt('authz_login', - default="admin", - help='Name of the administrator who will connect to the Keystone Moon backends.'), - cfg.StrOpt('authz_password', - default="nomoresecrete", - help='Password of the administrator who will connect to the Keystone Moon backends.'), - cfg.StrOpt('logfile', - default="/tmp/authz.log", - help='File where logs goes.'), - ] - -_MOON_KEYSTONEMIDDLEWARE_AGENT_GROUP = 'moon_keystonemiddleware_agent' -CONF = cfg.CONF -CONF.register_opts(_OPTS, group=_MOON_KEYSTONEMIDDLEWARE_AGENT_GROUP) -CONF.debug = True - -# from http://developer.openstack.org/api-ref-objectstorage-v1.html -SWIFT_API = ( - ("^/v1/(?P[\w_-]+)$", "GET", "get_account_details"), - ("^/v1/(?P[\w_-]+)$", "POST", "modify_account"), - ("^/v1/(?P[\w_-]+)$", "HEAD", "get_account"), - ("^/v1/(?P[\w_-]+)/(?P[\w-]+)$", "GET", "get_container"), - ("^/v1/(?P[\w_-]+)/(?P[\w-]+)$", "PUT", "create_container"), - ("^/v1/(?P[\w_-]+)/(?P[\w-]+)$", "POST", "update_container_metadata"), - ("^/v1/(?P[\w_-]+)/(?P[\w-]+)$", "DELETE", "delete_container"), - ("^/v1/(?P[\w_-]+)/(?P[\w-]+)$", "HEAD", "get_container_metadata"), - ("^/v1/(?P[\w_-]+)/(?P[\w-]+)/(?P.+)$", "GET", "get_object"), - ("^/v1/(?P[\w_-]+)/(?P[\w-]+)/(?P.+)$", "PUT", "create_object"), - ("^/v1/(?P[\w_-]+)/(?P[\w-]+)/(?P.+)$", "COPY", "copy_object"), - ("^/v1/(?P[\w_-]+)/(?P[\w-]+)/(?P.+)$", "POST", "update_object_metadata"), - ("^/v1/(?P[\w_-]+)/(?P[\w-]+)/(?P.+)$", "DELETE", "delete_object"), - ("^/v1/(?P[\w_-]+)/(?P[\w-]+)/(?P.+)$", "HEAD", "get_object_metadata"), -) - - -class MoonAgentKeystoneMiddleware(object): - """Moon's agent for KeystoneMiddleware to interact calls.""" - - post_data = { - "auth": { - "identity": { - "methods": [ - "password" - ], - "password": { - "user": { - "domain": { - "id": "Default" - }, - "name": "admin", - "password": "nomoresecrete" - } - } - } - } - } - - def __init__(self, app, conf): - self.conf = conf - self._LOG = logging.getLogger(conf.get('log_name', __name__)) - # FIXME: events are duplicated in log file - moon_agent_fh = logging.FileHandler(self.conf.get('logfile', "/tmp/keystonemiddleware.log")) - self._LOG.setLevel(logging.DEBUG) - self._LOG.addHandler(moon_agent_fh) - self._LOG.info(_LI('Starting Moon KeystoneMiddleware Agent')) - self._conf = conf - self._app = app - - # Auth - self.auth_host = conf.get('auth_host', "127.0.0.1") - self.auth_port = int(conf.get('auth_port', 35357)) - auth_protocol = conf.get('auth_protocol', 'http') - self._conf["_request_uri"] = '%s://%s:%s' % (auth_protocol, self.auth_host, # TODO: ??? for auth or authz - self.auth_port) - - # SSL - insecure = conf.get('insecure', False) - cert_file = conf.get('certfile') - key_file = conf.get('keyfile') - - if insecure: - self._conf["_verify"] = False - elif cert_file and key_file: - self._conf["_verify"] = (cert_file, key_file) - elif cert_file: - self._conf["_verify"] = cert_file - else: - self._conf["_verify"] = None - - # Moon registered mgrs - self.local_registered_mgr_dict = dict() # TODO: load from the sql backend - from keystonemiddleware.moon_mgrs.authz_mgr.authz_mgr import AuthzMgr - self.local_registered_mgr_dict["authz_mgr"] = AuthzMgr(self._conf) - - def __set_token(self): - self.post_data["auth"]["identity"]["password"]["user"]["name"] = self.conf.get('authz_login', "admin") - self.post_data["auth"]["identity"]["password"]["user"]["password"] = self.conf.get('authz_password', "nomoresecrete") - data = self.get_url("/v3/auth/tokens", post_data=self.post_data) - if "token" not in data: - raise Exception("Authentication problem ({})".format(data)) - self.token = data["token"] - - def __unset_token(self): - data = self.get_url("/v3/auth/tokens", method="DELETE", authtoken=True) - if "content" in data and len(data["content"]) > 0: - self._LOG.error("Error while unsetting token {}".format(data["content"])) - self.token = None - - def get_url(self, url, post_data=None, delete_data=None, method="GET", authtoken=None): - if post_data: - method = "POST" - if delete_data: - method = "DELETE" - self._LOG.debug("\033[32m{} {}\033[m".format(method, url)) - conn = httplib.HTTPConnection(self.auth_host, self.auth_port) - headers = { - "Content-type": "application/x-www-form-urlencoded", - "Accept": "text/plain,text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", - } - if authtoken: - if self.x_subject_token: - if method == "DELETE": - headers["X-Subject-Token"] = self.x_subject_token - headers["X-Auth-Token"] = self.x_subject_token - else: - headers["X-Auth-Token"] = self.x_subject_token - if post_data: - method = "POST" - headers["Content-type"] = "application/json" - post_data = json.dumps(post_data) - conn.request(method, url, post_data, headers=headers) - elif delete_data: - method = "DELETE" - conn.request(method, url, json.dumps(delete_data), headers=headers) - else: - conn.request(method, url, headers=headers) - resp = conn.getresponse() - headers = resp.getheaders() - try: - self.x_subject_token = dict(headers)["x-subject-token"] - except KeyError: - pass - content = resp.read() - conn.close() - try: - return json.loads(content) - except ValueError: - return {"content": content} - - def _find_openstack_component(self, env): - if "nova.context" in env.keys(): - return "nova" - elif "swift.authorize" in env.keys(): - return "swift" - else: - self._LOG.debug(env.keys()) - return "unknown" - - def _get_action(self, env, component): - """ Find and return the action of the request - Actually, find only Nova action (start, destroy, pause, unpause, ...) - - :param env: the request - :return: the action or "" - """ - action = "" - self.input = "" - if component == "nova": - length = int(env.get('CONTENT_LENGTH', '0')) - # TODO (dthom): compute for Nova, Cinder, Neutron, ... - action = "" - if length > 0: - try: - sub_action_object = env['wsgi.input'].read(length) - self.input = sub_action_object - action = json.loads(sub_action_object).keys()[0] - body = StringIO(sub_action_object) - env['wsgi.input'] = body - except ValueError: - self._LOG.error("Error in decoding sub-action") - except Exception as e: - self._LOG.error(str(e)) - if not action or len(action) == 0 and "servers/detail" in env["PATH_INFO"]: - return "list" - if component == "swift": - path = env["PATH_INFO"] - method = env["REQUEST_METHOD"] - for api in SWIFT_API: - if re.match(api[0], path) and method == api[1]: - action = api[2] - length = int(env.get('CONTENT_LENGTH', '0')) - # TODO (dthom): compute for Nova, Cinder, Neutron, ... - _action = "" - if length > 0: - try: - sub_action_object = env['wsgi.input'].read(length) - self.input = sub_action_object - _action = json.loads(sub_action_object).keys()[0] - body = StringIO(sub_action_object) - env['wsgi.input'] = body - self._LOG.debug("wsgi.input={}".format(_action)) - except ValueError: - self._LOG.error("Error in decoding sub-action") - except Exception as e: - self._LOG.error(str(e)) - return action - - @staticmethod - def _get_resource(env, component): - if component == "nova": - # http://developer.openstack.org/api-ref-compute-v2.1.html - # nova URLs: - # //servers/ - # list details for server_id - # //servers//action - # execute action to server_id - # //servers//metadata - # show metadata from server_id - # //servers/details - # list servers - url = env.get("PATH_INFO").split("/") - if url[-1] == "detail": - return "servers" - try: - return url[3] - except IndexError: - return - elif component == "swift": - # remove the "/v1/" part of the URL - return env.get("PATH_INFO").split("/", 2)[-1].replace("/", "-").replace(".", "-") - return "unknown" - - def __call__(self, env, start_response): - req = webob.Request(env) - agent_data = dict() - - agent_data['user_id'] = env.get("HTTP_X_USER_ID") - if not agent_data['user_id']: - self._LOG.warning("No user_id found for {}".format(env.get("PATH_INFO"))) - return self._app(env, start_response) - - agent_data['tenant_id'] = env.get("HTTP_X_TENANT_ID") - if not agent_data['tenant_id']: - self._LOG.warning("No tenant_id found for {}".format(env.get("PATH_INFO"))) - return self._app(env, start_response) - - agent_data['OS_component'] = self._find_openstack_component(env) - - agent_data['action_id'] = self._get_action(env, agent_data['OS_component']) - if not agent_data['action_id']: - self._LOG.warning("No action_id found for {}".format(env.get("PATH_INFO"))) - # If action is not found, we can't raise an exception because a lots of action is missing - # in function self._get_action, it is not possible to get them all. - return self._app(env, start_response) - - agent_data['resource_id'] = self._get_resource(env, agent_data['OS_component']) - if not agent_data['resource_id'] : - self._LOG.warning("No resource_id found for {}".format(env.get("PATH_INFO"))) - return self._app(env, start_response) - else: - self._LOG.debug("resource_id={}".format(agent_data['resource_id'])) - - self.__set_token() - for _mgr in self.local_registered_mgr_dict: # TODO: update from the sql backend - self.local_registered_mgr_dict[_mgr].response_content = \ - json.loads(self.local_registered_mgr_dict[_mgr].treat_request(self.x_subject_token, agent_data).content) - self.__unset_token() - - aggregate_result = 1 - for _mgr in self.local_registered_mgr_dict: - if not self.local_registered_mgr_dict[_mgr].response_content: - aggregate_result = 0 - - if aggregate_result: - return self._app(env, start_response) - - -def filter_factory(global_conf, **local_conf): - """Returns a WSGI filter app for use with paste.deploy.""" - conf = global_conf.copy() - conf.update(local_conf) - - def moon_agent_filter(app): - return MoonAgentKeystoneMiddleware(app, conf) - return moon_agent_filter - - diff --git a/keystonemiddleware-moon/keystonemiddleware/moon_mgrs/__init__.py b/keystonemiddleware-moon/keystonemiddleware/moon_mgrs/__init__.py deleted file mode 100644 index 10d80bc9..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/moon_mgrs/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__author__ = 'wukong' diff --git a/keystonemiddleware-moon/keystonemiddleware/moon_mgrs/abe_mgr/__init__.py b/keystonemiddleware-moon/keystonemiddleware/moon_mgrs/abe_mgr/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/keystonemiddleware-moon/keystonemiddleware/moon_mgrs/authz_mgr/__init__.py b/keystonemiddleware-moon/keystonemiddleware/moon_mgrs/authz_mgr/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/keystonemiddleware-moon/keystonemiddleware/moon_mgrs/authz_mgr/authz_mgr.py b/keystonemiddleware-moon/keystonemiddleware/moon_mgrs/authz_mgr/authz_mgr.py deleted file mode 100644 index 9a0a4009..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/moon_mgrs/authz_mgr/authz_mgr.py +++ /dev/null @@ -1,106 +0,0 @@ -import logging -import requests -import six -import webob -import json - -from keystone import exception -from keystonemiddleware.i18n import _, _LC, _LE, _LI, _LW -from oslo_config import cfg - - -_OPTS = [ - cfg.StrOpt('authz_login', - default="admin", - help='Name of the administrator who will connect to the Keystone Moon backends.'), - cfg.StrOpt('authz_password', - default="nomoresecrete", - help='Password of the administrator who will connect to the Keystone Moon backends.'), - cfg.StrOpt('logfile', - default="/tmp/moon_authz_mgr.log", # TODO: update in paste.init - help='File where logs goes.'), - ] - -_MOON_AUTHZ_MGR_GROUP = 'moon_authz_mgr' -CONF = cfg.CONF -CONF.register_opts(_OPTS, group=_MOON_AUTHZ_MGR_GROUP) -CONF.debug = True - - -class ServiceError(Exception): - pass - - -class AuthzMgr(object): - - def __init__(self, conf): - self.conf = conf - self._LOG = logging.getLogger(conf.get('log_name', __name__)) - authz_mgr_fh = logging.FileHandler(self.conf.get('logfile', "/tmp/keystonemiddleware.log")) - self._LOG.setLevel(logging.DEBUG) - self._LOG.addHandler(authz_mgr_fh) - self.response_content = "" - - def _deny_request(self, code): - error_table = { - 'AccessDenied': (401, 'Access denied'), - 'InvalidURI': (400, 'Could not parse the specified URI'), - 'NotFound': (404, 'URI not found'), - 'Error': (500, 'Server error'), - } - resp = webob.Response(content_type='text/xml') - resp.status = error_table[code][0] - error_msg = ('\r\n' - '\r\n %s\r\n ' - '%s\r\n\r\n' % - (code, error_table[code][1])) - if six.PY3: - error_msg = error_msg.encode() - resp.body = error_msg - return resp - - def treat_request(self, auth_token, agent_data): - if not agent_data['resource_id']: - agent_data['resource_id'] = "servers" - - headers = {'X-Auth-Token': auth_token} - self._LOG.debug('X-Auth-Token={}'.format(auth_token)) - try: - _url = '{}/moon/authz/{}/{}/{}/{}'.format( - self.conf["_request_uri"], - agent_data['tenant_id'], - agent_data['user_id'], - agent_data['resource_id'], - agent_data['action_id']) - self._LOG.info(_url) - response = requests.get(_url, - headers=headers, - verify=self.conf["_verify"]) - except requests.exceptions.RequestException as e: - self._LOG.error(_LI('HTTP connection exception: %s'), e) - resp = self._deny_request('InvalidURI') - raise ServiceError(resp) - - if response.status_code < 200 or response.status_code >= 300: - self._LOG.debug('Keystone reply error: status=%s reason=%s', - response.status_code, response.reason) - if response.status_code == 404: - resp = self._deny_request('NotFound') - elif response.status_code == 401: - resp = self._deny_request('AccessDenied') - else: - resp = self._deny_request('Error') - raise ServiceError(resp) - - elif response.status_code == 200: - answer = json.loads(response.content) - self._LOG.debug("action_id={}/{}".format(agent_data['OS_component'], agent_data['action_id'])) - self._LOG.debug(answer) - if "authz" in answer and answer["authz"]: - return response - self._LOG.error("You are not authorized to do that! ({})".format(unicode(answer["comment"]))) - raise exception.Unauthorized(message="You are not authorized to do that! ({})".format(unicode(answer["comment"]))) - else: - self._LOG.error("Unable to request Moon ({}: {})".format(response.status_code, response.reason)) - - return response diff --git a/keystonemiddleware-moon/keystonemiddleware/openstack/__init__.py b/keystonemiddleware-moon/keystonemiddleware/openstack/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/keystonemiddleware-moon/keystonemiddleware/openstack/common/__init__.py b/keystonemiddleware-moon/keystonemiddleware/openstack/common/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/keystonemiddleware-moon/keystonemiddleware/openstack/common/memorycache.py b/keystonemiddleware-moon/keystonemiddleware/openstack/common/memorycache.py deleted file mode 100644 index e72c26df..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/openstack/common/memorycache.py +++ /dev/null @@ -1,97 +0,0 @@ -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. -# -# 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. - -"""Super simple fake memcache client.""" - -import copy - -from oslo_config import cfg -from oslo_utils import timeutils - -memcache_opts = [ - cfg.ListOpt('memcached_servers', - help='Memcached servers or None for in process cache.'), -] - -CONF = cfg.CONF -CONF.register_opts(memcache_opts) - - -def list_opts(): - """Entry point for oslo-config-generator.""" - return [(None, copy.deepcopy(memcache_opts))] - - -def get_client(memcached_servers=None): - client_cls = Client - - if not memcached_servers: - memcached_servers = CONF.memcached_servers - if memcached_servers: - import memcache - client_cls = memcache.Client - - return client_cls(memcached_servers, debug=0) - - -class Client(object): - """Replicates a tiny subset of memcached client interface.""" - - def __init__(self, *args, **kwargs): - """Ignores the passed in args.""" - self.cache = {} - - def get(self, key): - """Retrieves the value for a key or None. - - This expunges expired keys during each get. - """ - - now = timeutils.utcnow_ts() - for k in list(self.cache): - (timeout, _value) = self.cache[k] - if timeout and now >= timeout: - del self.cache[k] - - return self.cache.get(key, (0, None))[1] - - def set(self, key, value, time=0, min_compress_len=0): - """Sets the value for a key.""" - timeout = 0 - if time != 0: - timeout = timeutils.utcnow_ts() + time - self.cache[key] = (timeout, value) - return True - - def add(self, key, value, time=0, min_compress_len=0): - """Sets the value for a key if it doesn't exist.""" - if self.get(key) is not None: - return False - return self.set(key, value, time, min_compress_len) - - def incr(self, key, delta=1): - """Increments the value for a key.""" - value = self.get(key) - if value is None: - return None - new_value = int(value) + delta - self.cache[key] = (self.cache[key][0], str(new_value)) - return new_value - - def delete(self, key, time=0): - """Deletes the value associated with a key.""" - if key in self.cache: - del self.cache[key] diff --git a/keystonemiddleware-moon/keystonemiddleware/opts.py b/keystonemiddleware-moon/keystonemiddleware/opts.py deleted file mode 100644 index 62a7dabf..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/opts.py +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright (c) 2014 OpenStack Foundation. -# -# 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. - -__all__ = [ - 'list_auth_token_opts', -] - -import copy - -import keystonemiddleware.auth_token -from keystonemiddleware.auth_token import _auth -from keystonemiddleware.auth_token import _base - -auth_token_opts = [ - (_base.AUTHTOKEN_GROUP, - keystonemiddleware.auth_token._OPTS + - _auth.AuthTokenPlugin.get_options()) -] - - -def list_auth_token_opts(): - """Return a list of oslo_config options available in auth_token middleware. - - The returned list includes all oslo_config options which may be registered - at runtime by the project. - - Each element of the list is a tuple. The first element is the name of the - group under which the list of elements in the second element will be - registered. A group name of None corresponds to the [DEFAULT] group in - config files. - - This function is also discoverable via the entry point - 'keystonemiddleware.auth_token' under the 'oslo.config.opts' - namespace. - - The purpose of this is to allow tools like the Oslo sample config file - generator to discover the options exposed to users by this middleware. - - :returns: a list of (group_name, opts) tuples - """ - return [(g, copy.deepcopy(o)) for g, o in auth_token_opts] diff --git a/keystonemiddleware-moon/keystonemiddleware/s3_token.py b/keystonemiddleware-moon/keystonemiddleware/s3_token.py deleted file mode 100644 index d71ab276..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/s3_token.py +++ /dev/null @@ -1,270 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# Copyright 2011,2012 Akira YOSHIYAMA -# All Rights Reserved. -# -# 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. - -# This source code is based ./auth_token.py and ./ec2_token.py. -# See them for their copyright. - -""" -S3 Token Middleware - -This WSGI component: - -* Gets a request from the swift3 middleware with an S3 Authorization - access key. -* Validates s3 token in Keystone. -* Transforms the account name to AUTH_%(tenant_name). - -""" - -import logging -import webob - -from oslo_serialization import jsonutils -from oslo_utils import strutils -import requests -import six -from six.moves import urllib - -from keystonemiddleware.i18n import _, _LI - - -PROTOCOL_NAME = 'S3 Token Authentication' - - -# TODO(kun): remove it after oslo merge this. -def _split_path(path, minsegs=1, maxsegs=None, rest_with_last=False): - """Validate and split the given HTTP request path. - - **Examples**:: - - ['a'] = _split_path('/a') - ['a', None] = _split_path('/a', 1, 2) - ['a', 'c'] = _split_path('/a/c', 1, 2) - ['a', 'c', 'o/r'] = _split_path('/a/c/o/r', 1, 3, True) - - :param path: HTTP Request path to be split - :param minsegs: Minimum number of segments to be extracted - :param maxsegs: Maximum number of segments to be extracted - :param rest_with_last: If True, trailing data will be returned as part - of last segment. If False, and there is - trailing data, raises ValueError. - :returns: list of segments with a length of maxsegs (non-existent - segments will return as None) - :raises: ValueError if given an invalid path - """ - if not maxsegs: - maxsegs = minsegs - if minsegs > maxsegs: - raise ValueError(_('minsegs > maxsegs: %(min)d > %(max)d)') % - {'min': minsegs, 'max': maxsegs}) - if rest_with_last: - segs = path.split('/', maxsegs) - minsegs += 1 - maxsegs += 1 - count = len(segs) - if (segs[0] or count < minsegs or count > maxsegs or - '' in segs[1:minsegs]): - raise ValueError(_('Invalid path: %s') % urllib.parse.quote(path)) - else: - minsegs += 1 - maxsegs += 1 - segs = path.split('/', maxsegs) - count = len(segs) - if (segs[0] or count < minsegs or count > maxsegs + 1 or - '' in segs[1:minsegs] or - (count == maxsegs + 1 and segs[maxsegs])): - raise ValueError(_('Invalid path: %s') % urllib.parse.quote(path)) - segs = segs[1:maxsegs] - segs.extend([None] * (maxsegs - 1 - len(segs))) - return segs - - -class ServiceError(Exception): - pass - - -class S3Token(object): - """Middleware that handles S3 authentication.""" - - def __init__(self, app, conf): - """Common initialization code.""" - self._app = app - self._logger = logging.getLogger(conf.get('log_name', __name__)) - self._logger.debug('Starting the %s component', PROTOCOL_NAME) - self._reseller_prefix = conf.get('reseller_prefix', 'AUTH_') - # where to find the auth service (we use this to validate tokens) - - auth_host = conf.get('auth_host') - auth_port = int(conf.get('auth_port', 35357)) - auth_protocol = conf.get('auth_protocol', 'https') - - self._request_uri = '%s://%s:%s' % (auth_protocol, auth_host, - auth_port) - - # SSL - insecure = strutils.bool_from_string(conf.get('insecure', False)) - cert_file = conf.get('certfile') - key_file = conf.get('keyfile') - - if insecure: - self._verify = False - elif cert_file and key_file: - self._verify = (cert_file, key_file) - elif cert_file: - self._verify = cert_file - else: - self._verify = None - - def _deny_request(self, code): - error_table = { - 'AccessDenied': (401, 'Access denied'), - 'InvalidURI': (400, 'Could not parse the specified URI'), - } - resp = webob.Response(content_type='text/xml') - resp.status = error_table[code][0] - error_msg = ('\r\n' - '\r\n %s\r\n ' - '%s\r\n\r\n' % - (code, error_table[code][1])) - if six.PY3: - error_msg = error_msg.encode() - resp.body = error_msg - return resp - - def _json_request(self, creds_json): - headers = {'Content-Type': 'application/json'} - try: - response = requests.post('%s/v2.0/s3tokens' % self._request_uri, - headers=headers, data=creds_json, - verify=self._verify) - except requests.exceptions.RequestException as e: - self._logger.info(_LI('HTTP connection exception: %s'), e) - resp = self._deny_request('InvalidURI') - raise ServiceError(resp) - - if response.status_code < 200 or response.status_code >= 300: - self._logger.debug('Keystone reply error: status=%s reason=%s', - response.status_code, response.reason) - resp = self._deny_request('AccessDenied') - raise ServiceError(resp) - - return response - - def __call__(self, environ, start_response): - """Handle incoming request. authenticate and send downstream.""" - req = webob.Request(environ) - self._logger.debug('Calling S3Token middleware.') - - try: - parts = _split_path(req.path, 1, 4, True) - version, account, container, obj = parts - except ValueError: - msg = 'Not a path query, skipping.' - self._logger.debug(msg) - return self._app(environ, start_response) - - # Read request signature and access id. - if 'Authorization' not in req.headers: - msg = 'No Authorization header. skipping.' - self._logger.debug(msg) - return self._app(environ, start_response) - - token = req.headers.get('X-Auth-Token', - req.headers.get('X-Storage-Token')) - if not token: - msg = 'You did not specify an auth or a storage token. skipping.' - self._logger.debug(msg) - return self._app(environ, start_response) - - auth_header = req.headers['Authorization'] - try: - access, signature = auth_header.split(' ')[-1].rsplit(':', 1) - except ValueError: - msg = 'You have an invalid Authorization header: %s' - self._logger.debug(msg, auth_header) - return self._deny_request('InvalidURI')(environ, start_response) - - # NOTE(chmou): This is to handle the special case with nova - # when we have the option s3_affix_tenant. We will force it to - # connect to another account than the one - # authenticated. Before people start getting worried about - # security, I should point that we are connecting with - # username/token specified by the user but instead of - # connecting to its own account we will force it to go to an - # another account. In a normal scenario if that user don't - # have the reseller right it will just fail but since the - # reseller account can connect to every account it is allowed - # by the swift_auth middleware. - force_tenant = None - if ':' in access: - access, force_tenant = access.split(':') - - # Authenticate request. - creds = {'credentials': {'access': access, - 'token': token, - 'signature': signature}} - creds_json = jsonutils.dumps(creds) - self._logger.debug('Connecting to Keystone sending this JSON: %s', - creds_json) - # NOTE(vish): We could save a call to keystone by having - # keystone return token, tenant, user, and roles - # from this call. - # - # NOTE(chmou): We still have the same problem we would need to - # change token_auth to detect if we already - # identified and not doing a second query and just - # pass it through to swiftauth in this case. - try: - resp = self._json_request(creds_json) - except ServiceError as e: - resp = e.args[0] - msg = 'Received error, exiting middleware with error: %s' - self._logger.debug(msg, resp.status_code) - return resp(environ, start_response) - - self._logger.debug('Keystone Reply: Status: %d, Output: %s', - resp.status_code, resp.content) - - try: - identity_info = resp.json() - token_id = str(identity_info['access']['token']['id']) - tenant = identity_info['access']['token']['tenant'] - except (ValueError, KeyError): - error = 'Error on keystone reply: %d %s' - self._logger.debug(error, resp.status_code, resp.content) - return self._deny_request('InvalidURI')(environ, start_response) - - req.headers['X-Auth-Token'] = token_id - tenant_to_connect = force_tenant or tenant['id'] - if six.PY2 and isinstance(tenant_to_connect, six.text_type): - tenant_to_connect = tenant_to_connect.encode('utf-8') - self._logger.debug('Connecting with tenant: %s', tenant_to_connect) - new_tenant_name = '%s%s' % (self._reseller_prefix, tenant_to_connect) - environ['PATH_INFO'] = environ['PATH_INFO'].replace(account, - new_tenant_name) - return self._app(environ, start_response) - - -def filter_factory(global_conf, **local_conf): - """Returns a WSGI filter app for use with paste.deploy.""" - conf = global_conf.copy() - conf.update(local_conf) - - def auth_filter(app): - return S3Token(app, conf) - return auth_filter diff --git a/keystonemiddleware-moon/keystonemiddleware/tests/__init__.py b/keystonemiddleware-moon/keystonemiddleware/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/keystonemiddleware-moon/keystonemiddleware/tests/unit/__init__.py b/keystonemiddleware-moon/keystonemiddleware/tests/unit/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/__init__.py b/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/base.py b/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/base.py deleted file mode 100644 index d76572a8..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/base.py +++ /dev/null @@ -1,73 +0,0 @@ -# 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. - -import logging - -import fixtures -from oslo_config import cfg -from oslo_config import fixture as cfg_fixture -from requests_mock.contrib import fixture as rm_fixture -import six -import webob.dec - -from keystonemiddleware import auth_token -from keystonemiddleware.tests.unit import utils - - -class BaseAuthTokenTestCase(utils.BaseTestCase): - - def setUp(self): - super(BaseAuthTokenTestCase, self).setUp() - self.requests_mock = self.useFixture(rm_fixture.Fixture()) - self.logger = fixtures.FakeLogger(level=logging.DEBUG) - self.cfg = self.useFixture(cfg_fixture.Config(conf=cfg.ConfigOpts())) - - def create_middleware(self, cb, conf=None, use_global_conf=False): - - @webob.dec.wsgify - def _do_cb(req): - return cb(req) - - if use_global_conf: - opts = conf or {} - else: - opts = { - 'oslo_config_project': 'keystonemiddleware', - 'oslo_config_config': self.cfg.conf, - } - opts.update(conf or {}) - - return auth_token.AuthProtocol(_do_cb, opts) - - def create_simple_middleware(self, - status='200 OK', - body='', - headers=None, - **kwargs): - def cb(req): - resp = webob.Response(body, status) - resp.headers.update(headers or {}) - return resp - - return self.create_middleware(cb, **kwargs) - - @classmethod - def call(cls, middleware, method='GET', path='/', headers=None): - req = webob.Request.blank(path) - req.method = method - - for k, v in six.iteritems(headers or {}): - req.headers[k] = v - - resp = req.get_response(middleware) - resp.request = req - return resp diff --git a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_auth.py b/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_auth.py deleted file mode 100644 index d6ebc9a0..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_auth.py +++ /dev/null @@ -1,102 +0,0 @@ -# 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. - -import logging -import uuid - -from keystoneclient import auth -from keystoneclient import fixture -from keystoneclient import session -from requests_mock.contrib import fixture as rm_fixture -import six - -from keystonemiddleware.auth_token import _auth -from keystonemiddleware.tests.unit import utils - - -class DefaultAuthPluginTests(utils.BaseTestCase): - - def new_plugin(self, auth_host=None, auth_port=None, auth_protocol=None, - auth_admin_prefix=None, admin_user=None, - admin_password=None, admin_tenant_name=None, - admin_token=None, identity_uri=None, log=None): - if not log: - log = self.logger - - return _auth.AuthTokenPlugin.load_from_options( - auth_host=auth_host, - auth_port=auth_port, - auth_protocol=auth_protocol, - auth_admin_prefix=auth_admin_prefix, - admin_user=admin_user, - admin_password=admin_password, - admin_tenant_name=admin_tenant_name, - admin_token=admin_token, - identity_uri=identity_uri, - log=log) - - def setUp(self): - super(DefaultAuthPluginTests, self).setUp() - - self.stream = six.StringIO() - self.logger = logging.getLogger(__name__) - self.session = session.Session() - self.requests_mock = self.useFixture(rm_fixture.Fixture()) - - def test_auth_uri_from_fragments(self): - auth_protocol = 'http' - auth_host = 'testhost' - auth_port = 8888 - auth_admin_prefix = 'admin' - - expected = '%s://%s:%d/admin' % (auth_protocol, auth_host, auth_port) - - plugin = self.new_plugin(auth_host=auth_host, - auth_protocol=auth_protocol, - auth_port=auth_port, - auth_admin_prefix=auth_admin_prefix) - - self.assertEqual(expected, - plugin.get_endpoint(self.session, - interface=auth.AUTH_INTERFACE)) - - def test_identity_uri_overrides_fragments(self): - identity_uri = 'http://testhost:8888/admin' - plugin = self.new_plugin(identity_uri=identity_uri, - auth_host='anotherhost', - auth_port=9999, - auth_protocol='ftp') - - self.assertEqual(identity_uri, - plugin.get_endpoint(self.session, - interface=auth.AUTH_INTERFACE)) - - def test_with_admin_token(self): - token = uuid.uuid4().hex - plugin = self.new_plugin(identity_uri='http://testhost:8888/admin', - admin_token=token) - self.assertEqual(token, plugin.get_token(self.session)) - - def test_with_user_pass(self): - base_uri = 'http://testhost:8888/admin' - token = fixture.V2Token() - admin_tenant_name = uuid.uuid4().hex - - self.requests_mock.post(base_uri + '/v2.0/tokens', - json=token) - - plugin = self.new_plugin(identity_uri=base_uri, - admin_user=uuid.uuid4().hex, - admin_password=uuid.uuid4().hex, - admin_tenant_name=admin_tenant_name) - - self.assertEqual(token.token_id, plugin.get_token(self.session)) diff --git a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py b/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py deleted file mode 100644 index e6a495f4..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py +++ /dev/null @@ -1,2634 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# -# 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. - -import datetime -import json -import logging -import os -import shutil -import stat -import tempfile -import time -import uuid -import warnings - -import fixtures -from keystoneclient import auth -from keystoneclient.common import cms -from keystoneclient import exceptions -from keystoneclient import fixture -from keystoneclient import session -import mock -from oslo_config import cfg -from oslo_serialization import jsonutils -from oslo_utils import timeutils -from oslotest import createfile -import six -import testresources -import testtools -from testtools import matchers -import webob -import webob.dec - -from keystonemiddleware import auth_token -from keystonemiddleware.auth_token import _base -from keystonemiddleware.auth_token import _exceptions as exc -from keystonemiddleware.auth_token import _revocations -from keystonemiddleware.openstack.common import memorycache -from keystonemiddleware.tests.unit.auth_token import base -from keystonemiddleware.tests.unit import client_fixtures -from keystonemiddleware.tests.unit import utils - - -EXPECTED_V2_DEFAULT_ENV_RESPONSE = { - 'HTTP_X_IDENTITY_STATUS': 'Confirmed', - 'HTTP_X_TENANT_ID': 'tenant_id1', - 'HTTP_X_TENANT_NAME': 'tenant_name1', - 'HTTP_X_USER_ID': 'user_id1', - 'HTTP_X_USER_NAME': 'user_name1', - 'HTTP_X_ROLES': 'role1,role2', - 'HTTP_X_USER': 'user_name1', # deprecated (diablo-compat) - 'HTTP_X_TENANT': 'tenant_name1', # deprecated (diablo-compat) - 'HTTP_X_ROLE': 'role1,role2', # deprecated (diablo-compat) -} - -EXPECTED_V2_DEFAULT_SERVICE_ENV_RESPONSE = { - 'HTTP_X_SERVICE_IDENTITY_STATUS': 'Confirmed', - 'HTTP_X_SERVICE_PROJECT_ID': 'service_project_id1', - 'HTTP_X_SERVICE_PROJECT_NAME': 'service_project_name1', - 'HTTP_X_SERVICE_USER_ID': 'service_user_id1', - 'HTTP_X_SERVICE_USER_NAME': 'service_user_name1', - 'HTTP_X_SERVICE_ROLES': 'service_role1,service_role2', -} - -EXPECTED_V3_DEFAULT_ENV_ADDITIONS = { - 'HTTP_X_PROJECT_DOMAIN_ID': 'domain_id1', - 'HTTP_X_PROJECT_DOMAIN_NAME': 'domain_name1', - 'HTTP_X_USER_DOMAIN_ID': 'domain_id1', - 'HTTP_X_USER_DOMAIN_NAME': 'domain_name1', -} - -EXPECTED_V3_DEFAULT_SERVICE_ENV_ADDITIONS = { - 'HTTP_X_SERVICE_PROJECT_DOMAIN_ID': 'service_domain_id1', - 'HTTP_X_SERVICE_PROJECT_DOMAIN_NAME': 'service_domain_name1', - 'HTTP_X_SERVICE_USER_DOMAIN_ID': 'service_domain_id1', - 'HTTP_X_SERVICE_USER_DOMAIN_NAME': 'service_domain_name1' -} - - -BASE_HOST = 'https://keystone.example.com:1234' -BASE_URI = '%s/testadmin' % BASE_HOST -FAKE_ADMIN_TOKEN_ID = 'admin_token2' -FAKE_ADMIN_TOKEN = jsonutils.dumps( - {'access': {'token': {'id': FAKE_ADMIN_TOKEN_ID, - 'expires': '2022-10-03T16:58:01Z'}}}) - -VERSION_LIST_v3 = fixture.DiscoveryList(href=BASE_URI) -VERSION_LIST_v2 = fixture.DiscoveryList(v3=False, href=BASE_URI) - -ERROR_TOKEN = '7ae290c2a06244c4b41692eb4e9225f2' -MEMCACHED_SERVERS = ['localhost:11211'] -MEMCACHED_AVAILABLE = None - - -def memcached_available(): - """Do a sanity check against memcached. - - Returns ``True`` if the following conditions are met (otherwise, returns - ``False``): - - - ``python-memcached`` is installed - - a usable ``memcached`` instance is available via ``MEMCACHED_SERVERS`` - - the client is able to set and get a key/value pair - - """ - global MEMCACHED_AVAILABLE - - if MEMCACHED_AVAILABLE is None: - try: - import memcache - c = memcache.Client(MEMCACHED_SERVERS) - c.set('ping', 'pong', time=1) - MEMCACHED_AVAILABLE = c.get('ping') == 'pong' - except ImportError: - MEMCACHED_AVAILABLE = False - - return MEMCACHED_AVAILABLE - - -def cleanup_revoked_file(filename): - try: - os.remove(filename) - except OSError: - pass - - -def strtime(at=None): - at = at or timeutils.utcnow() - return at.strftime(timeutils.PERFECT_TIME_FORMAT) - - -class TimezoneFixture(fixtures.Fixture): - @staticmethod - def supported(): - # tzset is only supported on Unix. - return hasattr(time, 'tzset') - - def __init__(self, new_tz): - super(TimezoneFixture, self).__init__() - self.tz = new_tz - self.old_tz = os.environ.get('TZ') - - def setUp(self): - super(TimezoneFixture, self).setUp() - if not self.supported(): - raise NotImplementedError('timezone override is not supported.') - os.environ['TZ'] = self.tz - time.tzset() - self.addCleanup(self.cleanup) - - def cleanup(self): - if self.old_tz is not None: - os.environ['TZ'] = self.old_tz - elif 'TZ' in os.environ: - del os.environ['TZ'] - time.tzset() - - -class TimeFixture(fixtures.Fixture): - - def __init__(self, new_time, normalize=True): - super(TimeFixture, self).__init__() - if isinstance(new_time, six.string_types): - new_time = timeutils.parse_isotime(new_time) - if normalize: - new_time = timeutils.normalize_time(new_time) - self.new_time = new_time - - def setUp(self): - super(TimeFixture, self).setUp() - timeutils.set_time_override(self.new_time) - self.addCleanup(timeutils.clear_time_override) - - -class FakeApp(object): - """This represents a WSGI app protected by the auth_token middleware.""" - - SUCCESS = b'SUCCESS' - FORBIDDEN = b'FORBIDDEN' - expected_env = {} - - def __init__(self, expected_env=None, need_service_token=False): - self.expected_env = dict(EXPECTED_V2_DEFAULT_ENV_RESPONSE) - - if expected_env: - self.expected_env.update(expected_env) - - self.need_service_token = need_service_token - - @webob.dec.wsgify - def __call__(self, req): - for k, v in self.expected_env.items(): - assert req.environ[k] == v, '%s != %s' % (req.environ[k], v) - - resp = webob.Response() - - if (req.environ.get('HTTP_X_IDENTITY_STATUS') == 'Invalid' and - req.environ['HTTP_X_SERVICE_IDENTITY_STATUS'] == 'Invalid'): - # Simulate delayed auth forbidding access with arbitrary status - # code to differentiate checking this code path - resp.status = 419 - resp.body = FakeApp.FORBIDDEN - elif req.environ.get('HTTP_X_SERVICE_IDENTITY_STATUS') == 'Invalid': - # Simulate delayed auth forbidding access with arbitrary status - # code to differentiate checking this code path - resp.status = 420 - resp.body = FakeApp.FORBIDDEN - elif req.environ['HTTP_X_IDENTITY_STATUS'] == 'Invalid': - # Simulate delayed auth forbidding access - resp.status = 403 - resp.body = FakeApp.FORBIDDEN - elif (self.need_service_token is True and - req.environ.get('HTTP_X_SERVICE_TOKEN') is None): - # Simulate requiring composite auth - # Arbitrary value to allow checking this code path - resp.status = 418 - resp.body = FakeApp.FORBIDDEN - else: - resp.body = FakeApp.SUCCESS - - return resp - - -class v3FakeApp(FakeApp): - """This represents a v3 WSGI app protected by the auth_token middleware.""" - - def __init__(self, expected_env=None, need_service_token=False): - - # with v3 additions, these are for the DEFAULT TOKEN - v3_default_env_additions = dict(EXPECTED_V3_DEFAULT_ENV_ADDITIONS) - if expected_env: - v3_default_env_additions.update(expected_env) - super(v3FakeApp, self).__init__(expected_env=v3_default_env_additions, - need_service_token=need_service_token) - - -class CompositeBase(object): - """Base composite auth object with common service token environment.""" - - def __init__(self, expected_env=None): - comp_expected_env = dict(EXPECTED_V2_DEFAULT_SERVICE_ENV_RESPONSE) - - if expected_env: - comp_expected_env.update(expected_env) - - super(CompositeBase, self).__init__( - expected_env=comp_expected_env, need_service_token=True) - - -class CompositeFakeApp(CompositeBase, FakeApp): - """A fake v2 WSGI app protected by composite auth_token middleware.""" - - def __init__(self, expected_env): - super(CompositeFakeApp, self).__init__(expected_env=expected_env) - - -class v3CompositeFakeApp(CompositeBase, v3FakeApp): - """A fake v3 WSGI app protected by composite auth_token middleware.""" - - def __init__(self, expected_env=None): - - # with v3 additions, these are for the DEFAULT SERVICE TOKEN - v3_default_service_env_additions = dict( - EXPECTED_V3_DEFAULT_SERVICE_ENV_ADDITIONS) - - if expected_env: - v3_default_service_env_additions.update(expected_env) - - super(v3CompositeFakeApp, self).__init__( - v3_default_service_env_additions) - - -class BaseAuthTokenMiddlewareTest(base.BaseAuthTokenTestCase): - """Base test class for auth_token middleware. - - All the tests allow for running with auth_token - configured for receiving v2 or v3 tokens, with the - choice being made by passing configuration data into - setUp(). - - The base class will, by default, run all the tests - expecting v2 token formats. Child classes can override - this to specify, for instance, v3 format. - - """ - def setUp(self, expected_env=None, auth_version=None, fake_app=None): - super(BaseAuthTokenMiddlewareTest, self).setUp() - - self.expected_env = expected_env or dict() - self.fake_app = fake_app or FakeApp - self.middleware = None - - signing_dir = self._setup_signing_directory() - - self.conf = { - 'identity_uri': 'https://keystone.example.com:1234/testadmin/', - 'signing_dir': signing_dir, - 'auth_version': auth_version, - 'auth_uri': 'https://keystone.example.com:1234', - 'admin_user': uuid.uuid4().hex, - } - - self.auth_version = auth_version - self.response_status = None - self.response_headers = None - - # NOTE(gyee): For this test suite and for the stable liberty branch - # only, we will ignore deprecated calls that keystonemiddleware makes. - warnings.filterwarnings('ignore', category=DeprecationWarning, - module='^keystonemiddleware\\.') - - def call_middleware(self, **kwargs): - return self.call(self.middleware, **kwargs) - - def _setup_signing_directory(self): - directory_name = self.useFixture(fixtures.TempDir()).path - - # Copy the sample certificate files into the temporary directory. - for filename in ['cacert.pem', 'signing_cert.pem', ]: - shutil.copy2(os.path.join(client_fixtures.CERTDIR, filename), - os.path.join(directory_name, filename)) - - return directory_name - - def set_middleware(self, expected_env=None, conf=None): - """Configure the class ready to call the auth_token middleware. - - Set up the various fake items needed to run the middleware. - Individual tests that need to further refine these can call this - function to override the class defaults. - - """ - if conf: - self.conf.update(conf) - - if expected_env: - self.expected_env.update(expected_env) - - self.middleware = auth_token.AuthProtocol( - self.fake_app(self.expected_env), self.conf) - - self.middleware._revocations._list = jsonutils.dumps( - {"revoked": [], "extra": "success"}) - - def update_expected_env(self, expected_env={}): - self.middleware._app.expected_env.update(expected_env) - - def purge_token_expected_env(self): - for key in six.iterkeys(self.token_expected_env): - del self.middleware._app.expected_env[key] - - def purge_service_token_expected_env(self): - for key in six.iterkeys(self.service_token_expected_env): - del self.middleware._app.expected_env[key] - - def assertLastPath(self, path): - if path: - self.assertEqual(BASE_URI + path, - self.requests_mock.last_request.url) - else: - self.assertIsNone(self.requests_mock.last_request) - - -class DiabloAuthTokenMiddlewareTest(BaseAuthTokenMiddlewareTest, - testresources.ResourcedTestCase): - - resources = [('examples', client_fixtures.EXAMPLES_RESOURCE)] - - """Auth Token middleware should understand Diablo keystone responses.""" - def setUp(self): - # pre-diablo only had Tenant ID, which was also the Name - expected_env = { - 'HTTP_X_TENANT_ID': 'tenant_id1', - 'HTTP_X_TENANT_NAME': 'tenant_id1', - # now deprecated (diablo-compat) - 'HTTP_X_TENANT': 'tenant_id1', - } - - super(DiabloAuthTokenMiddlewareTest, self).setUp( - expected_env=expected_env) - - self.requests_mock.get(BASE_URI, - json=VERSION_LIST_v2, - status_code=300) - - self.requests_mock.post("%s/v2.0/tokens" % BASE_URI, - text=FAKE_ADMIN_TOKEN) - - self.token_id = self.examples.VALID_DIABLO_TOKEN - token_response = self.examples.JSON_TOKEN_RESPONSES[self.token_id] - - url = "%s/v2.0/tokens/%s" % (BASE_URI, self.token_id) - self.requests_mock.get(url, text=token_response) - - self.set_middleware() - - def test_valid_diablo_response(self): - resp = self.call_middleware(headers={'X-Auth-Token': self.token_id}) - self.assertEqual(200, resp.status_int) - self.assertIn('keystone.token_info', resp.request.environ) - - -class NoMemcacheAuthToken(BaseAuthTokenMiddlewareTest): - """These tests will not have the memcache module available.""" - - def setUp(self): - super(NoMemcacheAuthToken, self).setUp() - self.useFixture(utils.DisableModuleFixture('memcache')) - - def test_nomemcache(self): - conf = { - 'admin_token': 'admin_token1', - 'auth_host': 'keystone.example.com', - 'auth_port': '1234', - 'memcached_servers': ','.join(MEMCACHED_SERVERS), - 'auth_uri': 'https://keystone.example.com:1234', - } - - auth_token.AuthProtocol(FakeApp(), conf) - - -class CachePoolTest(BaseAuthTokenMiddlewareTest): - def test_use_cache_from_env(self): - """If `swift.cache` is set in the environment and `cache` is set in the - config then the env cache is used. - """ - env = {'swift.cache': 'CACHE_TEST'} - conf = { - 'cache': 'swift.cache' - } - self.set_middleware(conf=conf) - self.middleware._token_cache.initialize(env) - with self.middleware._token_cache._cache_pool.reserve() as cache: - self.assertEqual(cache, 'CACHE_TEST') - - def test_not_use_cache_from_env(self): - """If `swift.cache` is set in the environment but `cache` isn't set in - the config then the env cache isn't used. - """ - self.set_middleware() - env = {'swift.cache': 'CACHE_TEST'} - self.middleware._token_cache.initialize(env) - with self.middleware._token_cache._cache_pool.reserve() as cache: - self.assertNotEqual(cache, 'CACHE_TEST') - - def test_multiple_context_managers_share_single_client(self): - self.set_middleware() - token_cache = self.middleware._token_cache - env = {} - token_cache.initialize(env) - - caches = [] - - with token_cache._cache_pool.reserve() as cache: - caches.append(cache) - - with token_cache._cache_pool.reserve() as cache: - caches.append(cache) - - self.assertIs(caches[0], caches[1]) - self.assertEqual(set(caches), set(token_cache._cache_pool)) - - def test_nested_context_managers_create_multiple_clients(self): - self.set_middleware() - env = {} - self.middleware._token_cache.initialize(env) - token_cache = self.middleware._token_cache - - with token_cache._cache_pool.reserve() as outer_cache: - with token_cache._cache_pool.reserve() as inner_cache: - self.assertNotEqual(outer_cache, inner_cache) - - self.assertEqual( - set([inner_cache, outer_cache]), - set(token_cache._cache_pool)) - - -class GeneralAuthTokenMiddlewareTest(BaseAuthTokenMiddlewareTest, - testresources.ResourcedTestCase): - """These tests are not affected by the token format - (see CommonAuthTokenMiddlewareTest). - """ - - resources = [('examples', client_fixtures.EXAMPLES_RESOURCE)] - - def test_token_is_v2_accepts_v2(self): - token = self.examples.UUID_TOKEN_DEFAULT - token_response = self.examples.TOKEN_RESPONSES[token] - self.assertTrue(auth_token._token_is_v2(token_response)) - - def test_token_is_v2_rejects_v3(self): - token = self.examples.v3_UUID_TOKEN_DEFAULT - token_response = self.examples.TOKEN_RESPONSES[token] - self.assertFalse(auth_token._token_is_v2(token_response)) - - def test_token_is_v3_rejects_v2(self): - token = self.examples.UUID_TOKEN_DEFAULT - token_response = self.examples.TOKEN_RESPONSES[token] - self.assertFalse(auth_token._token_is_v3(token_response)) - - def test_token_is_v3_accepts_v3(self): - token = self.examples.v3_UUID_TOKEN_DEFAULT - token_response = self.examples.TOKEN_RESPONSES[token] - self.assertTrue(auth_token._token_is_v3(token_response)) - - def test_fixed_cache_key_length(self): - self.set_middleware() - short_string = uuid.uuid4().hex - long_string = 8 * uuid.uuid4().hex - - token_cache = self.middleware._token_cache - hashed_short_string_key, context_ = token_cache._get_cache_key( - short_string) - hashed_long_string_key, context_ = token_cache._get_cache_key( - long_string) - - # The hash keys should always match in length - self.assertThat(hashed_short_string_key, - matchers.HasLength(len(hashed_long_string_key))) - - @testtools.skipUnless(memcached_available(), 'memcached not available') - def test_encrypt_cache_data(self): - conf = { - 'memcached_servers': ','.join(MEMCACHED_SERVERS), - 'memcache_security_strategy': 'encrypt', - 'memcache_secret_key': 'mysecret' - } - self.set_middleware(conf=conf) - token = b'my_token' - data = 'this_data' - token_cache = self.middleware._token_cache - token_cache.initialize({}) - token_cache._cache_store(token, data) - self.assertEqual(token_cache.get(token), data) - - @testtools.skipUnless(memcached_available(), 'memcached not available') - def test_sign_cache_data(self): - conf = { - 'memcached_servers': ','.join(MEMCACHED_SERVERS), - 'memcache_security_strategy': 'mac', - 'memcache_secret_key': 'mysecret' - } - self.set_middleware(conf=conf) - token = b'my_token' - data = 'this_data' - token_cache = self.middleware._token_cache - token_cache.initialize({}) - token_cache._cache_store(token, data) - self.assertEqual(token_cache.get(token), data) - - @testtools.skipUnless(memcached_available(), 'memcached not available') - def test_no_memcache_protection(self): - conf = { - 'memcached_servers': ','.join(MEMCACHED_SERVERS), - 'memcache_secret_key': 'mysecret' - } - self.set_middleware(conf=conf) - token = 'my_token' - data = 'this_data' - token_cache = self.middleware._token_cache - token_cache.initialize({}) - token_cache._cache_store(token, data) - self.assertEqual(token_cache.get(token), data) - - def test_assert_valid_memcache_protection_config(self): - # test missing memcache_secret_key - conf = { - 'memcached_servers': ','.join(MEMCACHED_SERVERS), - 'memcache_security_strategy': 'Encrypt' - } - self.assertRaises(exc.ConfigurationError, self.set_middleware, - conf=conf) - # test invalue memcache_security_strategy - conf = { - 'memcached_servers': ','.join(MEMCACHED_SERVERS), - 'memcache_security_strategy': 'whatever' - } - self.assertRaises(exc.ConfigurationError, self.set_middleware, - conf=conf) - # test missing memcache_secret_key - conf = { - 'memcached_servers': ','.join(MEMCACHED_SERVERS), - 'memcache_security_strategy': 'mac' - } - self.assertRaises(exc.ConfigurationError, self.set_middleware, - conf=conf) - conf = { - 'memcached_servers': ','.join(MEMCACHED_SERVERS), - 'memcache_security_strategy': 'Encrypt', - 'memcache_secret_key': '' - } - self.assertRaises(exc.ConfigurationError, self.set_middleware, - conf=conf) - conf = { - 'memcached_servers': ','.join(MEMCACHED_SERVERS), - 'memcache_security_strategy': 'mAc', - 'memcache_secret_key': '' - } - self.assertRaises(exc.ConfigurationError, self.set_middleware, - conf=conf) - - def test_config_revocation_cache_timeout(self): - conf = { - 'revocation_cache_time': '24', - 'auth_uri': 'https://keystone.example.com:1234', - 'admin_user': uuid.uuid4().hex - } - middleware = auth_token.AuthProtocol(self.fake_app, conf) - self.assertEqual(middleware._revocations._cache_timeout, - datetime.timedelta(seconds=24)) - - def test_conf_values_type_convert(self): - conf = { - 'revocation_cache_time': '24', - 'identity_uri': 'https://keystone.example.com:1234', - 'include_service_catalog': '0', - 'nonexsit_option': '0', - } - - middleware = auth_token.AuthProtocol(self.fake_app, conf) - self.assertEqual(datetime.timedelta(seconds=24), - middleware._revocations._cache_timeout) - self.assertEqual(False, middleware._include_service_catalog) - self.assertEqual('0', middleware._conf['nonexsit_option']) - - def test_deprecated_conf_values(self): - conf = { - 'memcache_servers': ','.join(MEMCACHED_SERVERS), - } - - middleware = auth_token.AuthProtocol(self.fake_app, conf) - self.assertEqual(MEMCACHED_SERVERS, - middleware._conf_get('memcached_servers')) - - def test_conf_values_type_convert_with_wrong_value(self): - conf = { - 'include_service_catalog': '123', - } - self.assertRaises(exc.ConfigurationError, - auth_token.AuthProtocol, self.fake_app, conf) - - def test_auth_region_name(self): - token = fixture.V3Token() - - auth_url = 'http://keystone-auth.example.com:5000' - east_url = 'http://keystone-east.example.com:5000' - west_url = 'http://keystone-west.example.com:5000' - - auth_versions = fixture.DiscoveryList(href=auth_url) - east_versions = fixture.DiscoveryList(href=east_url) - west_versions = fixture.DiscoveryList(href=west_url) - - s = token.add_service('identity') - s.add_endpoint(interface='admin', url=east_url, region='east') - s.add_endpoint(interface='admin', url=west_url, region='west') - - self.requests_mock.get(auth_url, json=auth_versions) - self.requests_mock.get(east_url, json=east_versions) - self.requests_mock.get(west_url, json=west_versions) - - self.requests_mock.post( - '%s/v3/auth/tokens' % auth_url, - headers={'X-Subject-Token': uuid.uuid4().hex}, - json=token) - - east_mock = self.requests_mock.get( - '%s/v3/auth/tokens' % east_url, - headers={'X-Subject-Token': uuid.uuid4().hex}, - json=fixture.V3Token()) - - west_mock = self.requests_mock.get( - '%s/v3/auth/tokens' % west_url, - headers={'X-Subject-Token': uuid.uuid4().hex}, - json=fixture.V3Token()) - - conf = {'auth_uri': auth_url, - 'auth_url': auth_url + '/v3', - 'auth_plugin': 'v3password', - 'username': 'user', - 'password': 'pass'} - - self.assertEqual(0, east_mock.call_count) - self.assertEqual(0, west_mock.call_count) - - east_app = self.create_simple_middleware(conf=dict(region_name='east', - **conf)) - self.call(east_app, headers={'X-Auth-Token': uuid.uuid4().hex}) - - self.assertEqual(1, east_mock.call_count) - self.assertEqual(0, west_mock.call_count) - - west_app = self.create_simple_middleware(conf=dict(region_name='west', - **conf)) - - self.call(west_app, headers={'X-Auth-Token': uuid.uuid4().hex}) - - self.assertEqual(1, east_mock.call_count) - self.assertEqual(1, west_mock.call_count) - - -class CommonAuthTokenMiddlewareTest(object): - """These tests are run once using v2 tokens and again using v3 tokens.""" - - def test_init_does_not_call_http(self): - conf = { - 'revocation_cache_time': '1' - } - self.create_simple_middleware(conf=conf) - self.assertLastPath(None) - - def test_auth_with_no_token_does_not_call_http(self): - middleware = self.create_simple_middleware() - resp = self.call(middleware) - self.assertLastPath(None) - self.assertEqual(401, resp.status_int) - - def test_init_by_ipv6Addr_auth_host(self): - del self.conf['identity_uri'] - conf = { - 'auth_host': '2001:2013:1:f101::1', - 'auth_port': '1234', - 'auth_protocol': 'http', - 'auth_uri': None, - 'auth_version': 'v3.0', - } - middleware = self.create_simple_middleware(conf=conf) - self.assertEqual('http://[2001:2013:1:f101::1]:1234', - middleware._auth_uri) - - def assert_valid_request_200(self, token, with_catalog=True): - resp = self.call_middleware(headers={'X-Auth-Token': token}) - self.assertEqual(200, resp.status_int) - if with_catalog: - self.assertTrue(resp.request.headers.get('X-Service-Catalog')) - else: - self.assertNotIn('X-Service-Catalog', resp.request.headers) - self.assertEqual(FakeApp.SUCCESS, resp.body) - self.assertIn('keystone.token_info', resp.request.environ) - return resp.request - - def test_valid_uuid_request(self): - for _ in range(2): # Do it twice because first result was cached. - token = self.token_dict['uuid_token_default'] - self.assert_valid_request_200(token) - self.assert_valid_last_url(token) - - def test_valid_uuid_request_with_auth_fragments(self): - del self.conf['identity_uri'] - self.conf['auth_protocol'] = 'https' - self.conf['auth_host'] = 'keystone.example.com' - self.conf['auth_port'] = '1234' - self.conf['auth_admin_prefix'] = '/testadmin' - self.set_middleware() - self.assert_valid_request_200(self.token_dict['uuid_token_default']) - self.assert_valid_last_url(self.token_dict['uuid_token_default']) - - def _test_cache_revoked(self, token, revoked_form=None): - # When the token is cached and revoked, 401 is returned. - self.middleware._check_revocations_for_cached = True - - # Token should be cached as ok after this. - resp = self.call_middleware(headers={'X-Auth-Token': token}) - self.assertEqual(200, resp.status_int) - - # Put it in revocation list. - self.middleware._revocations._list = self.get_revocation_list_json( - token_ids=[revoked_form or token]) - - resp = self.call_middleware(headers={'X-Auth-Token': token}) - self.assertEqual(401, resp.status_int) - - def test_cached_revoked_error(self): - # When the token is cached and revocation list retrieval fails, - # 503 is returned - token = self.token_dict['uuid_token_default'] - self.middleware._check_revocations_for_cached = True - - # Token should be cached as ok after this. - resp = self.call_middleware(headers={'X-Auth-Token': token}) - self.assertEqual(200, resp.status_int) - - # Cause the revocation list to be fetched again next time so we can - # test the case where that retrieval fails - self.middleware._revocations._fetched_time = datetime.datetime.min - with mock.patch.object(self.middleware._revocations, '_fetch', - side_effect=exc.RevocationListError): - resp = self.call_middleware(headers={'X-Auth-Token': token}) - self.assertEqual(503, resp.status_int) - - def test_unexpected_exception_in_validate_offline(self): - # When an unexpected exception is hit during _validate_offline, - # 500 is returned - token = self.token_dict['uuid_token_default'] - with mock.patch.object(self.middleware, '_validate_offline', - side_effect=Exception): - resp = self.call_middleware(headers={'X-Auth-Token': token}) - self.assertEqual(500, resp.status_int) - - def test_cached_revoked_uuid(self): - # When the UUID token is cached and revoked, 401 is returned. - self._test_cache_revoked(self.token_dict['uuid_token_default']) - - def test_valid_signed_request(self): - for _ in range(2): # Do it twice because first result was cached. - self.assert_valid_request_200( - self.token_dict['signed_token_scoped']) - # ensure that signed requests do not generate HTTP traffic - self.assertLastPath(None) - - def test_valid_signed_compressed_request(self): - self.assert_valid_request_200( - self.token_dict['signed_token_scoped_pkiz']) - # ensure that signed requests do not generate HTTP traffic - self.assertLastPath(None) - - def test_revoked_token_receives_401(self): - self.middleware._revocations._list = ( - self.get_revocation_list_json()) - - token = self.token_dict['revoked_token'] - resp = self.call_middleware(headers={'X-Auth-Token': token}) - - self.assertEqual(401, resp.status_int) - - def test_revoked_token_receives_401_sha256(self): - self.conf['hash_algorithms'] = ','.join(['sha256', 'md5']) - self.set_middleware() - self.middleware._revocations._list = ( - self.get_revocation_list_json(mode='sha256')) - - token = self.token_dict['revoked_token'] - resp = self.call_middleware(headers={'X-Auth-Token': token}) - self.assertEqual(401, resp.status_int) - - def test_cached_revoked_pki(self): - # When the PKI token is cached and revoked, 401 is returned. - token = self.token_dict['signed_token_scoped'] - revoked_form = cms.cms_hash_token(token) - self._test_cache_revoked(token, revoked_form) - - def test_cached_revoked_pkiz(self): - # When the PKIZ token is cached and revoked, 401 is returned. - token = self.token_dict['signed_token_scoped_pkiz'] - revoked_form = cms.cms_hash_token(token) - self._test_cache_revoked(token, revoked_form) - - def test_revoked_token_receives_401_md5_secondary(self): - # When hash_algorithms has 'md5' as the secondary hash and the - # revocation list contains the md5 hash for a token, that token is - # considered revoked so returns 401. - self.conf['hash_algorithms'] = ','.join(['sha256', 'md5']) - self.set_middleware() - self.middleware._revocations._list = ( - self.get_revocation_list_json()) - - token = self.token_dict['revoked_token'] - resp = self.call_middleware(headers={'X-Auth-Token': token}) - self.assertEqual(401, resp.status_int) - - def _test_revoked_hashed_token(self, token_name): - # If hash_algorithms is set as ['sha256', 'md5'], - # and check_revocations_for_cached is True, - # and a token is in the cache because it was successfully validated - # using the md5 hash, then - # if the token is in the revocation list by md5 hash, it'll be - # rejected and auth_token returns 401. - self.conf['hash_algorithms'] = ','.join(['sha256', 'md5']) - self.conf['check_revocations_for_cached'] = 'true' - self.set_middleware() - - token = self.token_dict[token_name] - - # Put the token in the revocation list. - token_hashed = cms.cms_hash_token(token) - self.middleware._revocations._list = self.get_revocation_list_json( - token_ids=[token_hashed]) - - # First, request is using the hashed token, is valid so goes in - # cache using the given hash. - resp = self.call_middleware(headers={'X-Auth-Token': token_hashed}) - self.assertEqual(200, resp.status_int) - - # This time use the PKI(Z) token - resp = self.call_middleware(headers={'X-Auth-Token': token}) - - # Should find the token in the cache and revocation list. - self.assertEqual(401, resp.status_int) - - def test_revoked_hashed_pki_token(self): - self._test_revoked_hashed_token('signed_token_scoped') - - def test_revoked_hashed_pkiz_token(self): - self._test_revoked_hashed_token('signed_token_scoped_pkiz') - - def test_revoked_pki_token_by_audit_id(self): - # When the audit ID is in the revocation list, the token is invalid. - self.set_middleware() - token = self.token_dict['signed_token_scoped'] - - # Put the token audit ID in the revocation list, - # the entry will have a false token ID so the token ID doesn't match. - fake_token_id = uuid.uuid4().hex - # The audit_id value is in examples/pki/cms/auth_*_token_scoped.json. - audit_id = 'SLIXlXQUQZWUi9VJrqdXqA' - revocation_list_data = { - 'revoked': [ - { - 'id': fake_token_id, - 'audit_id': audit_id - }, - ] - } - self.middleware._revocations._list = jsonutils.dumps( - revocation_list_data) - - resp = self.call_middleware(headers={'X-Auth-Token': token}) - self.assertEqual(401, resp.status_int) - - def get_revocation_list_json(self, token_ids=None, mode=None): - if token_ids is None: - key = 'revoked_token_hash' + (('_' + mode) if mode else '') - token_ids = [self.token_dict[key]] - revocation_list = {'revoked': [{'id': x, 'expires': timeutils.utcnow()} - for x in token_ids]} - return jsonutils.dumps(revocation_list) - - def test_is_signed_token_revoked_returns_false(self): - # explicitly setting an empty revocation list here to document intent - self.middleware._revocations._list = jsonutils.dumps( - {"revoked": [], "extra": "success"}) - result = self.middleware._revocations._any_revoked( - [self.token_dict['revoked_token_hash']]) - self.assertFalse(result) - - def test_is_signed_token_revoked_returns_true(self): - self.middleware._revocations._list = ( - self.get_revocation_list_json()) - result = self.middleware._revocations._any_revoked( - [self.token_dict['revoked_token_hash']]) - self.assertTrue(result) - - def test_is_signed_token_revoked_returns_true_sha256(self): - self.conf['hash_algorithms'] = ','.join(['sha256', 'md5']) - self.set_middleware() - self.middleware._revocations._list = ( - self.get_revocation_list_json(mode='sha256')) - result = self.middleware._revocations._any_revoked( - [self.token_dict['revoked_token_hash_sha256']]) - self.assertTrue(result) - - def test_verify_signed_token_raises_exception_for_revoked_token(self): - self.middleware._revocations._list = ( - self.get_revocation_list_json()) - self.assertRaises(exc.InvalidToken, - self.middleware._verify_signed_token, - self.token_dict['revoked_token'], - [self.token_dict['revoked_token_hash']]) - - def test_verify_signed_token_raises_exception_for_revoked_token_s256(self): - self.conf['hash_algorithms'] = ','.join(['sha256', 'md5']) - self.set_middleware() - self.middleware._revocations._list = ( - self.get_revocation_list_json(mode='sha256')) - self.assertRaises(exc.InvalidToken, - self.middleware._verify_signed_token, - self.token_dict['revoked_token'], - [self.token_dict['revoked_token_hash_sha256'], - self.token_dict['revoked_token_hash']]) - - def test_verify_signed_token_raises_exception_for_revoked_pkiz_token(self): - self.middleware._revocations._list = ( - self.examples.REVOKED_TOKEN_PKIZ_LIST_JSON) - self.assertRaises(exc.InvalidToken, - self.middleware._verify_pkiz_token, - self.token_dict['revoked_token_pkiz'], - [self.token_dict['revoked_token_pkiz_hash']]) - - def assertIsValidJSON(self, text): - json.loads(text) - - def test_verify_signed_token_succeeds_for_unrevoked_token(self): - self.middleware._revocations._list = ( - self.get_revocation_list_json()) - text = self.middleware._verify_signed_token( - self.token_dict['signed_token_scoped'], - [self.token_dict['signed_token_scoped_hash']]) - self.assertIsValidJSON(text) - - def test_verify_signed_compressed_token_succeeds_for_unrevoked_token(self): - self.middleware._revocations._list = ( - self.get_revocation_list_json()) - text = self.middleware._verify_pkiz_token( - self.token_dict['signed_token_scoped_pkiz'], - [self.token_dict['signed_token_scoped_hash']]) - self.assertIsValidJSON(text) - - def test_verify_signed_token_succeeds_for_unrevoked_token_sha256(self): - self.conf['hash_algorithms'] = ','.join(['sha256', 'md5']) - self.set_middleware() - self.middleware._revocations._list = ( - self.get_revocation_list_json(mode='sha256')) - text = self.middleware._verify_signed_token( - self.token_dict['signed_token_scoped'], - [self.token_dict['signed_token_scoped_hash_sha256'], - self.token_dict['signed_token_scoped_hash']]) - self.assertIsValidJSON(text) - - def test_get_token_revocation_list_fetched_time_returns_min(self): - self.middleware._revocations._fetched_time = None - - # Get rid of the revoked file - revoked_path = self.middleware._signing_directory.calc_path( - _revocations.Revocations._FILE_NAME) - os.remove(revoked_path) - - self.assertEqual(self.middleware._revocations._fetched_time, - datetime.datetime.min) - - # FIXME(blk-u): move the unit tests into unit/test_auth_token.py - def test_get_token_revocation_list_fetched_time_returns_mtime(self): - self.middleware._revocations._fetched_time = None - revoked_path = self.middleware._signing_directory.calc_path( - _revocations.Revocations._FILE_NAME) - mtime = os.path.getmtime(revoked_path) - fetched_time = datetime.datetime.utcfromtimestamp(mtime) - self.assertEqual(fetched_time, - self.middleware._revocations._fetched_time) - - @testtools.skipUnless(TimezoneFixture.supported(), - 'TimezoneFixture not supported') - def test_get_token_revocation_list_fetched_time_returns_utc(self): - with TimezoneFixture('UTC-1'): - self.middleware._revocations._list = jsonutils.dumps( - self.examples.REVOCATION_LIST) - self.middleware._revocations._fetched_time = None - fetched_time = self.middleware._revocations._fetched_time - self.assertTrue(timeutils.is_soon(fetched_time, 1)) - - def test_get_token_revocation_list_fetched_time_returns_value(self): - expected = self.middleware._revocations._fetched_time - self.assertEqual(self.middleware._revocations._fetched_time, - expected) - - def test_get_revocation_list_returns_fetched_list(self): - # auth_token uses v2 to fetch this, so don't allow the v3 - # tests to override the fake http connection - self.middleware._revocations._fetched_time = None - - # Get rid of the revoked file - revoked_path = self.middleware._signing_directory.calc_path( - _revocations.Revocations._FILE_NAME) - os.remove(revoked_path) - - self.assertEqual(self.middleware._revocations._list, - self.examples.REVOCATION_LIST) - - def test_get_revocation_list_returns_current_list_from_memory(self): - self.assertEqual(self.middleware._revocations._list, - self.middleware._revocations._list_prop) - - def test_get_revocation_list_returns_current_list_from_disk(self): - in_memory_list = self.middleware._revocations._list - self.middleware._revocations._list_prop = None - self.assertEqual(self.middleware._revocations._list, - in_memory_list) - - def test_invalid_revocation_list_raises_error(self): - self.requests_mock.get(self.revocation_url, json={}) - self.assertRaises(exc.RevocationListError, - self.middleware._revocations._fetch) - - def test_fetch_revocation_list(self): - # auth_token uses v2 to fetch this, so don't allow the v3 - # tests to override the fake http connection - fetched = jsonutils.loads(self.middleware._revocations._fetch()) - self.assertEqual(fetched, self.examples.REVOCATION_LIST) - - def test_request_invalid_uuid_token(self): - # remember because we are testing the middleware we stub the connection - # to the keystone server, but this is not what gets returned - invalid_uri = "%s/v2.0/tokens/invalid-token" % BASE_URI - self.requests_mock.get(invalid_uri, status_code=404) - - resp = self.call_middleware(headers={'X-Auth-Token': 'invalid-token'}) - self.assertEqual(401, resp.status_int) - self.assertEqual("Keystone uri='https://keystone.example.com:1234'", - resp.headers['WWW-Authenticate']) - - def test_request_invalid_signed_token(self): - token = self.examples.INVALID_SIGNED_TOKEN - resp = self.call_middleware(headers={'X-Auth-Token': token}) - self.assertEqual(401, resp.status_int) - self.assertEqual("Keystone uri='https://keystone.example.com:1234'", - resp.headers['WWW-Authenticate']) - - def test_request_invalid_signed_pkiz_token(self): - token = self.examples.INVALID_SIGNED_PKIZ_TOKEN - resp = self.call_middleware(headers={'X-Auth-Token': token}) - self.assertEqual(401, resp.status_int) - self.assertEqual("Keystone uri='https://keystone.example.com:1234'", - resp.headers['WWW-Authenticate']) - - def test_request_no_token(self): - resp = self.call_middleware() - self.assertEqual(401, resp.status_int) - self.assertEqual("Keystone uri='https://keystone.example.com:1234'", - resp.headers['WWW-Authenticate']) - - def test_request_no_token_http(self): - resp = self.call_middleware(method='HEAD') - self.assertEqual(401, resp.status_int) - self.assertEqual("Keystone uri='https://keystone.example.com:1234'", - resp.headers['WWW-Authenticate']) - - def test_request_blank_token(self): - resp = self.call_middleware(headers={'X-Auth-Token': ''}) - self.assertEqual(401, resp.status_int) - self.assertEqual("Keystone uri='https://keystone.example.com:1234'", - resp.headers['WWW-Authenticate']) - - def _get_cached_token(self, token, mode='md5'): - token_id = cms.cms_hash_token(token, mode=mode) - return self.middleware._token_cache.get(token_id) - - def test_memcache(self): - token = self.token_dict['signed_token_scoped'] - self.call_middleware(headers={'X-Auth-Token': token}) - self.assertIsNotNone(self._get_cached_token(token)) - - def test_expired(self): - token = self.token_dict['signed_token_scoped_expired'] - resp = self.call_middleware(headers={'X-Auth-Token': token}) - self.assertEqual(401, resp.status_int) - - def test_memcache_set_invalid_uuid(self): - invalid_uri = "%s/v2.0/tokens/invalid-token" % BASE_URI - self.requests_mock.get(invalid_uri, status_code=404) - - token = 'invalid-token' - self.call_middleware(headers={'X-Auth-Token': token}) - self.assertRaises(exc.InvalidToken, self._get_cached_token, token) - - def test_memcache_set_expired(self, extra_conf={}, extra_environ={}): - token_cache_time = 10 - conf = { - 'token_cache_time': '%s' % token_cache_time, - } - conf.update(extra_conf) - self.set_middleware(conf=conf) - - token = self.token_dict['signed_token_scoped'] - self.call_middleware(headers={'X-Auth-Token': token}) - - req = webob.Request.blank('/') - req.headers['X-Auth-Token'] = token - req.environ.update(extra_environ) - - now = datetime.datetime.utcnow() - self.useFixture(TimeFixture(now)) - req.get_response(self.middleware) - self.assertIsNotNone(self._get_cached_token(token)) - - timeutils.advance_time_seconds(token_cache_time) - self.assertIsNone(self._get_cached_token(token)) - - def test_swift_memcache_set_expired(self): - extra_conf = {'cache': 'swift.cache'} - extra_environ = {'swift.cache': memorycache.Client()} - self.test_memcache_set_expired(extra_conf, extra_environ) - - def test_http_error_not_cached_token(self): - """Test to don't cache token as invalid on network errors. - - We use UUID tokens since they are the easiest one to reach - get_http_connection. - """ - self.middleware._http_request_max_retries = 0 - self.call_middleware(headers={'X-Auth-Token': ERROR_TOKEN}) - self.assertIsNone(self._get_cached_token(ERROR_TOKEN)) - self.assert_valid_last_url(ERROR_TOKEN) - - def test_http_request_max_retries(self): - times_retry = 10 - - conf = {'http_request_max_retries': '%s' % times_retry} - self.set_middleware(conf=conf) - - with mock.patch('time.sleep') as mock_obj: - self.call_middleware(headers={'X-Auth-Token': ERROR_TOKEN}) - - self.assertEqual(mock_obj.call_count, times_retry) - - def test_nocatalog(self): - conf = { - 'include_service_catalog': 'False' - } - self.set_middleware(conf=conf) - self.assert_valid_request_200(self.token_dict['uuid_token_default'], - with_catalog=False) - - def assert_kerberos_bind(self, token, bind_level, - use_kerberos=True, success=True): - conf = { - 'enforce_token_bind': bind_level, - 'auth_version': self.auth_version, - } - self.set_middleware(conf=conf) - - req = webob.Request.blank('/') - req.headers['X-Auth-Token'] = token - - if use_kerberos: - if use_kerberos is True: - req.environ['REMOTE_USER'] = self.examples.KERBEROS_BIND - else: - req.environ['REMOTE_USER'] = use_kerberos - - req.environ['AUTH_TYPE'] = 'Negotiate' - - resp = req.get_response(self.middleware) - - if success: - self.assertEqual(200, resp.status_int) - self.assertEqual(FakeApp.SUCCESS, resp.body) - self.assertIn('keystone.token_info', req.environ) - self.assert_valid_last_url(token) - else: - self.assertEqual(401, resp.status_int) - msg = "Keystone uri='https://keystone.example.com:1234'" - self.assertEqual(msg, resp.headers['WWW-Authenticate']) - - def test_uuid_bind_token_disabled_with_kerb_user(self): - for use_kerberos in [True, False]: - self.assert_kerberos_bind(self.token_dict['uuid_token_bind'], - bind_level='disabled', - use_kerberos=use_kerberos, - success=True) - - def test_uuid_bind_token_disabled_with_incorrect_ticket(self): - self.assert_kerberos_bind(self.token_dict['uuid_token_bind'], - bind_level='kerberos', - use_kerberos='ronald@MCDONALDS.COM', - success=False) - - def test_uuid_bind_token_permissive_with_kerb_user(self): - self.assert_kerberos_bind(self.token_dict['uuid_token_bind'], - bind_level='permissive', - use_kerberos=True, - success=True) - - def test_uuid_bind_token_permissive_without_kerb_user(self): - self.assert_kerberos_bind(self.token_dict['uuid_token_bind'], - bind_level='permissive', - use_kerberos=False, - success=False) - - def test_uuid_bind_token_permissive_with_unknown_bind(self): - token = self.token_dict['uuid_token_unknown_bind'] - - for use_kerberos in [True, False]: - self.assert_kerberos_bind(token, - bind_level='permissive', - use_kerberos=use_kerberos, - success=True) - - def test_uuid_bind_token_permissive_with_incorrect_ticket(self): - self.assert_kerberos_bind(self.token_dict['uuid_token_bind'], - bind_level='kerberos', - use_kerberos='ronald@MCDONALDS.COM', - success=False) - - def test_uuid_bind_token_strict_with_kerb_user(self): - self.assert_kerberos_bind(self.token_dict['uuid_token_bind'], - bind_level='strict', - use_kerberos=True, - success=True) - - def test_uuid_bind_token_strict_with_kerbout_user(self): - self.assert_kerberos_bind(self.token_dict['uuid_token_bind'], - bind_level='strict', - use_kerberos=False, - success=False) - - def test_uuid_bind_token_strict_with_unknown_bind(self): - token = self.token_dict['uuid_token_unknown_bind'] - - for use_kerberos in [True, False]: - self.assert_kerberos_bind(token, - bind_level='strict', - use_kerberos=use_kerberos, - success=False) - - def test_uuid_bind_token_required_with_kerb_user(self): - self.assert_kerberos_bind(self.token_dict['uuid_token_bind'], - bind_level='required', - use_kerberos=True, - success=True) - - def test_uuid_bind_token_required_without_kerb_user(self): - self.assert_kerberos_bind(self.token_dict['uuid_token_bind'], - bind_level='required', - use_kerberos=False, - success=False) - - def test_uuid_bind_token_required_with_unknown_bind(self): - token = self.token_dict['uuid_token_unknown_bind'] - - for use_kerberos in [True, False]: - self.assert_kerberos_bind(token, - bind_level='required', - use_kerberos=use_kerberos, - success=False) - - def test_uuid_bind_token_required_without_bind(self): - for use_kerberos in [True, False]: - self.assert_kerberos_bind(self.token_dict['uuid_token_default'], - bind_level='required', - use_kerberos=use_kerberos, - success=False) - - def test_uuid_bind_token_named_kerberos_with_kerb_user(self): - self.assert_kerberos_bind(self.token_dict['uuid_token_bind'], - bind_level='kerberos', - use_kerberos=True, - success=True) - - def test_uuid_bind_token_named_kerberos_without_kerb_user(self): - self.assert_kerberos_bind(self.token_dict['uuid_token_bind'], - bind_level='kerberos', - use_kerberos=False, - success=False) - - def test_uuid_bind_token_named_kerberos_with_unknown_bind(self): - token = self.token_dict['uuid_token_unknown_bind'] - - for use_kerberos in [True, False]: - self.assert_kerberos_bind(token, - bind_level='kerberos', - use_kerberos=use_kerberos, - success=False) - - def test_uuid_bind_token_named_kerberos_without_bind(self): - for use_kerberos in [True, False]: - self.assert_kerberos_bind(self.token_dict['uuid_token_default'], - bind_level='kerberos', - use_kerberos=use_kerberos, - success=False) - - def test_uuid_bind_token_named_kerberos_with_incorrect_ticket(self): - self.assert_kerberos_bind(self.token_dict['uuid_token_bind'], - bind_level='kerberos', - use_kerberos='ronald@MCDONALDS.COM', - success=False) - - def test_uuid_bind_token_with_unknown_named_FOO(self): - token = self.token_dict['uuid_token_bind'] - - for use_kerberos in [True, False]: - self.assert_kerberos_bind(token, - bind_level='FOO', - use_kerberos=use_kerberos, - success=False) - - def test_caching_token_on_verify(self): - # When the token is cached it isn't cached again when it's verified. - - # The token cache has to be initialized with our cache instance. - self.middleware._token_cache._env_cache_name = 'cache' - cache = memorycache.Client() - self.middleware._token_cache.initialize(env={'cache': cache}) - - # Mock cache.set since then the test can verify call_count. - orig_cache_set = cache.set - cache.set = mock.Mock(side_effect=orig_cache_set) - - token = self.token_dict['signed_token_scoped'] - - resp = self.call_middleware(headers={'X-Auth-Token': token}) - self.assertEqual(200, resp.status_int) - - self.assertThat(1, matchers.Equals(cache.set.call_count)) - - resp = self.call_middleware(headers={'X-Auth-Token': token}) - self.assertEqual(200, resp.status_int) - - # Assert that the token wasn't cached again. - self.assertThat(1, matchers.Equals(cache.set.call_count)) - - def test_auth_plugin(self): - - for service_url in (self.examples.UNVERSIONED_SERVICE_URL, - self.examples.SERVICE_URL): - self.requests_mock.get(service_url, - json=VERSION_LIST_v3, - status_code=300) - - token = self.token_dict['uuid_token_default'] - resp = self.call_middleware(headers={'X-Auth-Token': token}) - self.assertEqual(200, resp.status_int) - self.assertEqual(FakeApp.SUCCESS, resp.body) - - token_auth = resp.request.environ['keystone.token_auth'] - endpoint_filter = {'service_type': self.examples.SERVICE_TYPE, - 'version': 3} - - url = token_auth.get_endpoint(session.Session(), **endpoint_filter) - self.assertEqual('%s/v3' % BASE_URI, url) - - self.assertTrue(token_auth.has_user_token) - self.assertFalse(token_auth.has_service_token) - self.assertIsNone(token_auth.service) - - def test_doesnt_auto_set_content_type(self): - # webob will set content_type = 'text/html' by default if nothing is - # provided. We don't want our middleware messing with the content type - # of the underlying applications. - - text = uuid.uuid4().hex - - def _middleware(environ, start_response): - start_response(200, []) - return text - - def _start_response(status_code, headerlist, exc_info=None): - self.assertIn('200', status_code) # will be '200 OK' - self.assertEqual([], headerlist) - - m = auth_token.AuthProtocol(_middleware, self.conf) - - env = {'REQUEST_METHOD': 'GET', - 'HTTP_X_AUTH_TOKEN': self.token_dict['uuid_token_default']} - - r = m(env, _start_response) - self.assertEqual(text, r) - - -class V2CertDownloadMiddlewareTest(BaseAuthTokenMiddlewareTest, - testresources.ResourcedTestCase): - - resources = [('examples', client_fixtures.EXAMPLES_RESOURCE)] - - def __init__(self, *args, **kwargs): - super(V2CertDownloadMiddlewareTest, self).__init__(*args, **kwargs) - self.auth_version = 'v2.0' - self.fake_app = None - self.ca_path = '/v2.0/certificates/ca' - self.signing_path = '/v2.0/certificates/signing' - - def setUp(self): - super(V2CertDownloadMiddlewareTest, self).setUp( - auth_version=self.auth_version, - fake_app=self.fake_app) - self.base_dir = tempfile.mkdtemp() - self.addCleanup(shutil.rmtree, self.base_dir) - self.cert_dir = os.path.join(self.base_dir, 'certs') - os.makedirs(self.cert_dir, stat.S_IRWXU) - conf = { - 'signing_dir': self.cert_dir, - 'auth_version': self.auth_version, - } - - self.requests_mock.get(BASE_URI, - json=VERSION_LIST_v3, - status_code=300) - - self.set_middleware(conf=conf) - - # Usually we supply a signed_dir with pre-installed certificates, - # so invocation of /usr/bin/openssl succeeds. This time we give it - # an empty directory, so it fails. - def test_request_no_token_dummy(self): - cms._ensure_subprocess() - - self.requests_mock.get('%s%s' % (BASE_URI, self.ca_path), - status_code=404) - self.requests_mock.get('%s%s' % (BASE_URI, self.signing_path), - status_code=404) - self.assertRaises(exceptions.CertificateConfigError, - self.middleware._verify_signed_token, - self.examples.SIGNED_TOKEN_SCOPED, - [self.examples.SIGNED_TOKEN_SCOPED_HASH]) - - def test_fetch_signing_cert(self): - data = 'FAKE CERT' - url = "%s%s" % (BASE_URI, self.signing_path) - self.requests_mock.get(url, text=data) - self.middleware._fetch_signing_cert() - - signing_cert_path = self.middleware._signing_directory.calc_path( - self.middleware._SIGNING_CERT_FILE_NAME) - with open(signing_cert_path, 'r') as f: - self.assertEqual(f.read(), data) - - self.assertEqual(url, self.requests_mock.last_request.url) - - def test_fetch_signing_ca(self): - data = 'FAKE CA' - url = "%s%s" % (BASE_URI, self.ca_path) - self.requests_mock.get(url, text=data) - self.middleware._fetch_ca_cert() - - ca_file_path = self.middleware._signing_directory.calc_path( - self.middleware._SIGNING_CA_FILE_NAME) - with open(ca_file_path, 'r') as f: - self.assertEqual(f.read(), data) - - self.assertEqual(url, self.requests_mock.last_request.url) - - def test_prefix_trailing_slash(self): - del self.conf['identity_uri'] - self.conf['auth_protocol'] = 'https' - self.conf['auth_host'] = 'keystone.example.com' - self.conf['auth_port'] = '1234' - self.conf['auth_admin_prefix'] = '/newadmin/' - - base_url = '%s/newadmin' % BASE_HOST - ca_url = "%s%s" % (base_url, self.ca_path) - signing_url = "%s%s" % (base_url, self.signing_path) - - self.requests_mock.get(base_url, - json=VERSION_LIST_v3, - status_code=300) - self.requests_mock.get(ca_url, text='FAKECA') - self.requests_mock.get(signing_url, text='FAKECERT') - - self.set_middleware(conf=self.conf) - - self.middleware._fetch_ca_cert() - self.assertEqual(ca_url, self.requests_mock.last_request.url) - - self.middleware._fetch_signing_cert() - self.assertEqual(signing_url, self.requests_mock.last_request.url) - - def test_without_prefix(self): - del self.conf['identity_uri'] - self.conf['auth_protocol'] = 'https' - self.conf['auth_host'] = 'keystone.example.com' - self.conf['auth_port'] = '1234' - self.conf['auth_admin_prefix'] = '' - - ca_url = "%s%s" % (BASE_HOST, self.ca_path) - signing_url = "%s%s" % (BASE_HOST, self.signing_path) - - self.requests_mock.get(BASE_HOST, - json=VERSION_LIST_v3, - status_code=300) - self.requests_mock.get(ca_url, text='FAKECA') - self.requests_mock.get(signing_url, text='FAKECERT') - - self.set_middleware(conf=self.conf) - - self.middleware._fetch_ca_cert() - self.assertEqual(ca_url, self.requests_mock.last_request.url) - - self.middleware._fetch_signing_cert() - self.assertEqual(signing_url, self.requests_mock.last_request.url) - - -class V3CertDownloadMiddlewareTest(V2CertDownloadMiddlewareTest): - - def __init__(self, *args, **kwargs): - super(V3CertDownloadMiddlewareTest, self).__init__(*args, **kwargs) - self.auth_version = 'v3.0' - self.fake_app = v3FakeApp - self.ca_path = '/v3/OS-SIMPLE-CERT/ca' - self.signing_path = '/v3/OS-SIMPLE-CERT/certificates' - - -def network_error_response(request, context): - raise exceptions.ConnectionRefused("Network connection refused.") - - -class v2AuthTokenMiddlewareTest(BaseAuthTokenMiddlewareTest, - CommonAuthTokenMiddlewareTest, - testresources.ResourcedTestCase): - """v2 token specific tests. - - There are some differences between how the auth-token middleware handles - v2 and v3 tokens over and above the token formats, namely: - - - A v3 keystone server will auto scope a token to a user's default project - if no scope is specified. A v2 server assumes that the auth-token - middleware will do that. - - A v2 keystone server may issue a token without a catalog, even with a - tenant - - The tests below were originally part of the generic AuthTokenMiddlewareTest - class, but now, since they really are v2 specific, they are included here. - - """ - - resources = [('examples', client_fixtures.EXAMPLES_RESOURCE)] - - def setUp(self): - super(v2AuthTokenMiddlewareTest, self).setUp() - - self.token_dict = { - 'uuid_token_default': self.examples.UUID_TOKEN_DEFAULT, - 'uuid_token_unscoped': self.examples.UUID_TOKEN_UNSCOPED, - 'uuid_token_bind': self.examples.UUID_TOKEN_BIND, - 'uuid_token_unknown_bind': self.examples.UUID_TOKEN_UNKNOWN_BIND, - 'signed_token_scoped': self.examples.SIGNED_TOKEN_SCOPED, - 'signed_token_scoped_pkiz': self.examples.SIGNED_TOKEN_SCOPED_PKIZ, - 'signed_token_scoped_hash': self.examples.SIGNED_TOKEN_SCOPED_HASH, - 'signed_token_scoped_hash_sha256': - self.examples.SIGNED_TOKEN_SCOPED_HASH_SHA256, - 'signed_token_scoped_expired': - self.examples.SIGNED_TOKEN_SCOPED_EXPIRED, - 'revoked_token': self.examples.REVOKED_TOKEN, - 'revoked_token_pkiz': self.examples.REVOKED_TOKEN_PKIZ, - 'revoked_token_pkiz_hash': - self.examples.REVOKED_TOKEN_PKIZ_HASH, - 'revoked_token_hash': self.examples.REVOKED_TOKEN_HASH, - 'revoked_token_hash_sha256': - self.examples.REVOKED_TOKEN_HASH_SHA256, - } - - self.requests_mock.get(BASE_URI, - json=VERSION_LIST_v2, - status_code=300) - - self.requests_mock.post('%s/v2.0/tokens' % BASE_URI, - text=FAKE_ADMIN_TOKEN) - - self.revocation_url = '%s/v2.0/tokens/revoked' % BASE_URI - self.requests_mock.get(self.revocation_url, - text=self.examples.SIGNED_REVOCATION_LIST) - - for token in (self.examples.UUID_TOKEN_DEFAULT, - self.examples.UUID_TOKEN_UNSCOPED, - self.examples.UUID_TOKEN_BIND, - self.examples.UUID_TOKEN_UNKNOWN_BIND, - self.examples.UUID_TOKEN_NO_SERVICE_CATALOG, - self.examples.SIGNED_TOKEN_SCOPED_KEY, - self.examples.SIGNED_TOKEN_SCOPED_PKIZ_KEY,): - url = "%s/v2.0/tokens/%s" % (BASE_URI, token) - text = self.examples.JSON_TOKEN_RESPONSES[token] - self.requests_mock.get(url, text=text) - - url = '%s/v2.0/tokens/%s' % (BASE_URI, ERROR_TOKEN) - self.requests_mock.get(url, text=network_error_response) - - self.set_middleware() - - def assert_unscoped_default_tenant_auto_scopes(self, token): - """Unscoped v2 requests with a default tenant should "auto-scope." - - The implied scope is the user's tenant ID. - - """ - resp = self.call_middleware(headers={'X-Auth-Token': token}) - self.assertEqual(200, resp.status_int) - self.assertEqual(FakeApp.SUCCESS, resp.body) - self.assertIn('keystone.token_info', resp.request.environ) - - def assert_valid_last_url(self, token_id): - self.assertLastPath("/v2.0/tokens/%s" % token_id) - - def test_default_tenant_uuid_token(self): - self.assert_unscoped_default_tenant_auto_scopes( - self.examples.UUID_TOKEN_DEFAULT) - - def test_default_tenant_signed_token(self): - self.assert_unscoped_default_tenant_auto_scopes( - self.examples.SIGNED_TOKEN_SCOPED) - - def assert_unscoped_token_receives_401(self, token): - """Unscoped requests with no default tenant ID should be rejected.""" - resp = self.call_middleware(headers={'X-Auth-Token': token}) - self.assertEqual(401, resp.status_int) - self.assertEqual("Keystone uri='https://keystone.example.com:1234'", - resp.headers['WWW-Authenticate']) - - def test_unscoped_uuid_token_receives_401(self): - self.assert_unscoped_token_receives_401( - self.examples.UUID_TOKEN_UNSCOPED) - - def test_unscoped_pki_token_receives_401(self): - self.assert_unscoped_token_receives_401( - self.examples.SIGNED_TOKEN_UNSCOPED) - - def test_request_prevent_service_catalog_injection(self): - token = self.examples.UUID_TOKEN_NO_SERVICE_CATALOG - resp = self.call_middleware(headers={'X-Service-Catalog': '[]', - 'X-Auth-Token': token}) - - self.assertEqual(200, resp.status_int) - self.assertFalse(resp.request.headers.get('X-Service-Catalog')) - self.assertEqual(FakeApp.SUCCESS, resp.body) - - def test_user_plugin_token_properties(self): - token = self.examples.UUID_TOKEN_DEFAULT - token_data = self.examples.TOKEN_RESPONSES[token] - - resp = self.call_middleware(headers={'X-Service-Catalog': '[]', - 'X-Auth-Token': token, - 'X-Service-Token': token}) - - self.assertEqual(200, resp.status_int) - self.assertEqual(FakeApp.SUCCESS, resp.body) - - token_auth = resp.request.environ['keystone.token_auth'] - - self.assertTrue(token_auth.has_user_token) - self.assertTrue(token_auth.has_service_token) - - for t in [token_auth.user, token_auth.service]: - self.assertEqual(token_data.user_id, t.user_id) - self.assertEqual(token_data.tenant_id, t.project_id) - - self.assertThat(t.role_names, matchers.HasLength(2)) - self.assertIn('role1', t.role_names) - self.assertIn('role2', t.role_names) - - self.assertIsNone(t.trust_id) - self.assertIsNone(t.user_domain_id) - self.assertIsNone(t.project_domain_id) - - -class CrossVersionAuthTokenMiddlewareTest(BaseAuthTokenMiddlewareTest, - testresources.ResourcedTestCase): - - resources = [('examples', client_fixtures.EXAMPLES_RESOURCE)] - - def test_valid_uuid_request_forced_to_2_0(self): - """Test forcing auth_token to use lower api version. - - By installing the v3 http hander, auth_token will be get - a version list that looks like a v3 server - from which it - would normally chose v3.0 as the auth version. However, here - we specify v2.0 in the configuration - which should force - auth_token to use that version instead. - - """ - conf = { - 'auth_version': 'v2.0' - } - - self.requests_mock.get(BASE_URI, - json=VERSION_LIST_v3, - status_code=300) - - self.requests_mock.post('%s/v2.0/tokens' % BASE_URI, - text=FAKE_ADMIN_TOKEN) - - token = self.examples.UUID_TOKEN_DEFAULT - url = "%s/v2.0/tokens/%s" % (BASE_URI, token) - text = self.examples.JSON_TOKEN_RESPONSES[token] - self.requests_mock.get(url, text=text) - - self.set_middleware(conf=conf) - - # This tests will only work is auth_token has chosen to use the - # lower, v2, api version - resp = self.call_middleware(headers={'X-Auth-Token': token}) - self.assertEqual(200, resp.status_int) - self.assertEqual(url, self.requests_mock.last_request.url) - - -class v3AuthTokenMiddlewareTest(BaseAuthTokenMiddlewareTest, - CommonAuthTokenMiddlewareTest, - testresources.ResourcedTestCase): - """Test auth_token middleware with v3 tokens. - - Re-execute the AuthTokenMiddlewareTest class tests, but with the - auth_token middleware configured to expect v3 tokens back from - a keystone server. - - This is done by configuring the AuthTokenMiddlewareTest class via - its Setup(), passing in v3 style data that will then be used by - the tests themselves. This approach has been used to ensure we - really are running the same tests for both v2 and v3 tokens. - - There a few additional specific test for v3 only: - - - We allow an unscoped token to be validated (as unscoped), where - as for v2 tokens, the auth_token middleware is expected to try and - auto-scope it (and fail if there is no default tenant) - - Domain scoped tokens - - Since we don't specify an auth version for auth_token to use, by - definition we are thefore implicitely testing that it will use - the highest available auth version, i.e. v3.0 - - """ - - resources = [('examples', client_fixtures.EXAMPLES_RESOURCE)] - - def setUp(self): - super(v3AuthTokenMiddlewareTest, self).setUp( - auth_version='v3.0', - fake_app=v3FakeApp) - - self.token_dict = { - 'uuid_token_default': self.examples.v3_UUID_TOKEN_DEFAULT, - 'uuid_token_unscoped': self.examples.v3_UUID_TOKEN_UNSCOPED, - 'uuid_token_bind': self.examples.v3_UUID_TOKEN_BIND, - 'uuid_token_unknown_bind': - self.examples.v3_UUID_TOKEN_UNKNOWN_BIND, - 'signed_token_scoped': self.examples.SIGNED_v3_TOKEN_SCOPED, - 'signed_token_scoped_pkiz': - self.examples.SIGNED_v3_TOKEN_SCOPED_PKIZ, - 'signed_token_scoped_hash': - self.examples.SIGNED_v3_TOKEN_SCOPED_HASH, - 'signed_token_scoped_hash_sha256': - self.examples.SIGNED_v3_TOKEN_SCOPED_HASH_SHA256, - 'signed_token_scoped_expired': - self.examples.SIGNED_TOKEN_SCOPED_EXPIRED, - 'revoked_token': self.examples.REVOKED_v3_TOKEN, - 'revoked_token_pkiz': self.examples.REVOKED_v3_TOKEN_PKIZ, - 'revoked_token_hash': self.examples.REVOKED_v3_TOKEN_HASH, - 'revoked_token_hash_sha256': - self.examples.REVOKED_v3_TOKEN_HASH_SHA256, - 'revoked_token_pkiz_hash': - self.examples.REVOKED_v3_PKIZ_TOKEN_HASH, - } - - self.requests_mock.get(BASE_URI, - json=VERSION_LIST_v3, - status_code=300) - - # TODO(jamielennox): auth_token middleware uses a v2 admin token - # regardless of the auth_version that is set. - self.requests_mock.post('%s/v2.0/tokens' % BASE_URI, - text=FAKE_ADMIN_TOKEN) - - self.revocation_url = '%s/v3/auth/tokens/OS-PKI/revoked' % BASE_URI - self.requests_mock.get(self.revocation_url, - text=self.examples.SIGNED_REVOCATION_LIST) - - self.requests_mock.get('%s/v3/auth/tokens' % BASE_URI, - text=self.token_response, - headers={'X-Subject-Token': uuid.uuid4().hex}) - - self.set_middleware() - - def token_response(self, request, context): - auth_id = request.headers.get('X-Auth-Token') - token_id = request.headers.get('X-Subject-Token') - self.assertEqual(auth_id, FAKE_ADMIN_TOKEN_ID) - - if token_id == ERROR_TOKEN: - raise exceptions.ConnectionRefused("Network connection refused.") - - try: - response = self.examples.JSON_TOKEN_RESPONSES[token_id] - except KeyError: - response = "" - context.status_code = 404 - - return response - - def assert_valid_last_url(self, token_id): - self.assertLastPath('/v3/auth/tokens') - - def test_valid_unscoped_uuid_request(self): - # Remove items that won't be in an unscoped token - delta_expected_env = { - 'HTTP_X_PROJECT_ID': None, - 'HTTP_X_PROJECT_NAME': None, - 'HTTP_X_PROJECT_DOMAIN_ID': None, - 'HTTP_X_PROJECT_DOMAIN_NAME': None, - 'HTTP_X_TENANT_ID': None, - 'HTTP_X_TENANT_NAME': None, - 'HTTP_X_ROLES': '', - 'HTTP_X_TENANT': None, - 'HTTP_X_ROLE': '', - } - self.set_middleware(expected_env=delta_expected_env) - self.assert_valid_request_200(self.examples.v3_UUID_TOKEN_UNSCOPED, - with_catalog=False) - self.assertLastPath('/v3/auth/tokens') - - def test_domain_scoped_uuid_request(self): - # Modify items compared to default token for a domain scope - delta_expected_env = { - 'HTTP_X_DOMAIN_ID': 'domain_id1', - 'HTTP_X_DOMAIN_NAME': 'domain_name1', - 'HTTP_X_PROJECT_ID': None, - 'HTTP_X_PROJECT_NAME': None, - 'HTTP_X_PROJECT_DOMAIN_ID': None, - 'HTTP_X_PROJECT_DOMAIN_NAME': None, - 'HTTP_X_TENANT_ID': None, - 'HTTP_X_TENANT_NAME': None, - 'HTTP_X_TENANT': None - } - self.set_middleware(expected_env=delta_expected_env) - self.assert_valid_request_200( - self.examples.v3_UUID_TOKEN_DOMAIN_SCOPED) - self.assertLastPath('/v3/auth/tokens') - - def test_gives_v2_catalog(self): - self.set_middleware() - req = self.assert_valid_request_200( - self.examples.SIGNED_v3_TOKEN_SCOPED) - - catalog = jsonutils.loads(req.headers['X-Service-Catalog']) - - for service in catalog: - for endpoint in service['endpoints']: - # no point checking everything, just that it's in v2 format - self.assertIn('adminURL', endpoint) - self.assertIn('publicURL', endpoint) - self.assertIn('adminURL', endpoint) - - def test_fallback_to_online_validation_with_signing_error(self): - self.requests_mock.get('%s/v3/OS-SIMPLE-CERT/certificates' % BASE_URI, - status_code=404) - self.assert_valid_request_200(self.token_dict['signed_token_scoped']) - self.assert_valid_request_200( - self.token_dict['signed_token_scoped_pkiz']) - - def test_fallback_to_online_validation_with_ca_error(self): - self.requests_mock.get('%s/v3/OS-SIMPLE-CERT/ca' % BASE_URI, - status_code=404) - self.assert_valid_request_200(self.token_dict['signed_token_scoped']) - self.assert_valid_request_200( - self.token_dict['signed_token_scoped_pkiz']) - - def test_fallback_to_online_validation_with_revocation_list_error(self): - self.requests_mock.get(self.revocation_url, status_code=404) - self.assert_valid_request_200(self.token_dict['signed_token_scoped']) - self.assert_valid_request_200( - self.token_dict['signed_token_scoped_pkiz']) - - def test_user_plugin_token_properties(self): - token = self.examples.v3_UUID_TOKEN_DEFAULT - token_data = self.examples.TOKEN_RESPONSES[token] - - resp = self.call_middleware(headers={'X-Service-Catalog': '[]', - 'X-Auth-Token': token, - 'X-Service-Token': token}) - - self.assertEqual(200, resp.status_int) - self.assertEqual(FakeApp.SUCCESS, resp.body) - - token_auth = resp.request.environ['keystone.token_auth'] - - self.assertTrue(token_auth.has_user_token) - self.assertTrue(token_auth.has_service_token) - - for t in [token_auth.user, token_auth.service]: - self.assertEqual(token_data.user_id, t.user_id) - self.assertEqual(token_data.project_id, t.project_id) - self.assertEqual(token_data.user_domain_id, t.user_domain_id) - self.assertEqual(token_data.project_domain_id, t.project_domain_id) - - self.assertThat(t.role_names, matchers.HasLength(2)) - self.assertIn('role1', t.role_names) - self.assertIn('role2', t.role_names) - - self.assertIsNone(t.trust_id) - - def test_expire_stored_in_cache(self): - # tests the upgrade path from storing a tuple vs just the data in the - # cache. Can be removed in the future. - token = 'mytoken' - data = 'this_data' - self.set_middleware() - self.middleware._token_cache.initialize({}) - now = datetime.datetime.utcnow() - delta = datetime.timedelta(hours=1) - expires = strtime(at=(now + delta)) - self.middleware._token_cache.store(token, (data, expires)) - self.assertEqual(self.middleware._token_cache.get(token), data) - - -class DelayedAuthTests(BaseAuthTokenMiddlewareTest): - - def test_header_in_401(self): - body = uuid.uuid4().hex - auth_uri = 'http://local.test' - conf = {'delay_auth_decision': 'True', - 'auth_version': 'v3.0', - 'auth_uri': auth_uri} - - middleware = self.create_simple_middleware(status='401 Unauthorized', - body=body, - conf=conf) - resp = self.call(middleware) - self.assertEqual(six.b(body), resp.body) - - self.assertEqual(401, resp.status_int) - self.assertEqual("Keystone uri='%s'" % auth_uri, - resp.headers['WWW-Authenticate']) - - def test_delayed_auth_values(self): - conf = {'auth_uri': 'http://local.test'} - status = '401 Unauthorized' - - middleware = self.create_simple_middleware(status=status, conf=conf) - self.assertFalse(middleware._delay_auth_decision) - - for v in ('True', '1', 'on', 'yes'): - conf = {'delay_auth_decision': v, - 'auth_uri': 'http://local.test'} - - middleware = self.create_simple_middleware(status=status, - conf=conf) - self.assertTrue(middleware._delay_auth_decision) - - for v in ('False', '0', 'no'): - conf = {'delay_auth_decision': v, - 'auth_uri': 'http://local.test'} - - middleware = self.create_simple_middleware(status=status, - conf=conf) - self.assertFalse(middleware._delay_auth_decision) - - def test_auth_plugin_with_no_tokens(self): - body = uuid.uuid4().hex - auth_uri = 'http://local.test' - conf = {'delay_auth_decision': True, 'auth_uri': auth_uri} - - middleware = self.create_simple_middleware(body=body, conf=conf) - resp = self.call(middleware) - self.assertEqual(six.b(body), resp.body) - - token_auth = resp.request.environ['keystone.token_auth'] - - self.assertFalse(token_auth.has_user_token) - self.assertIsNone(token_auth.user) - self.assertFalse(token_auth.has_service_token) - self.assertIsNone(token_auth.service) - - -class CommonCompositeAuthTests(object): - """Test Composite authentication. - - Test the behaviour of adding a service-token. - """ - - def test_composite_auth_ok(self): - token = self.token_dict['uuid_token_default'] - service_token = self.token_dict['uuid_service_token_default'] - fake_logger = fixtures.FakeLogger(level=logging.DEBUG) - self.middleware.logger = self.useFixture(fake_logger) - resp = self.call_middleware(headers={'X-Auth-Token': token, - 'X-Service-Token': service_token}) - self.assertEqual(200, resp.status_int) - self.assertEqual(FakeApp.SUCCESS, resp.body) - expected_env = dict(EXPECTED_V2_DEFAULT_ENV_RESPONSE) - expected_env.update(EXPECTED_V2_DEFAULT_SERVICE_ENV_RESPONSE) - - # role list may get reordered, check for string pieces individually - self.assertIn('Received request from user: ', fake_logger.output) - self.assertIn('user_id %(HTTP_X_USER_ID)s, ' - 'project_id %(HTTP_X_TENANT_ID)s, ' - 'roles ' % expected_env, fake_logger.output) - self.assertIn('service: user_id %(HTTP_X_SERVICE_USER_ID)s, ' - 'project_id %(HTTP_X_SERVICE_PROJECT_ID)s, ' - 'roles ' % expected_env, fake_logger.output) - - roles = ','.join([expected_env['HTTP_X_SERVICE_ROLES'], - expected_env['HTTP_X_ROLES']]) - - for r in roles.split(','): - self.assertIn(r, fake_logger.output) - - def test_composite_auth_invalid_service_token(self): - token = self.token_dict['uuid_token_default'] - service_token = 'invalid-service-token' - resp = self.call_middleware(headers={'X-Auth-Token': token, - 'X-Service-Token': service_token}) - self.assertEqual(401, resp.status_int) - self.assertEqual(b'Authentication required', resp.body) - - def test_composite_auth_no_service_token(self): - self.purge_service_token_expected_env() - req = webob.Request.blank('/') - req.headers['X-Auth-Token'] = self.token_dict['uuid_token_default'] - - # Ensure injection of service headers is not possible - for key, value in six.iteritems(self.service_token_expected_env): - header_key = key[len('HTTP_'):].replace('_', '-') - req.headers[header_key] = value - # Check arbitrary headers not removed - req.headers['X-Foo'] = 'Bar' - resp = req.get_response(self.middleware) - for key in six.iterkeys(self.service_token_expected_env): - header_key = key[len('HTTP_'):].replace('_', '-') - self.assertFalse(req.headers.get(header_key)) - self.assertEqual('Bar', req.headers.get('X-Foo')) - self.assertEqual(418, resp.status_int) - self.assertEqual(FakeApp.FORBIDDEN, resp.body) - - def test_composite_auth_invalid_user_token(self): - token = 'invalid-token' - service_token = self.token_dict['uuid_service_token_default'] - resp = self.call_middleware(headers={'X-Auth-Token': token, - 'X-Service-Token': service_token}) - self.assertEqual(401, resp.status_int) - self.assertEqual(b'Authentication required', resp.body) - - def test_composite_auth_no_user_token(self): - service_token = self.token_dict['uuid_service_token_default'] - resp = self.call_middleware(headers={'X-Service-Token': service_token}) - self.assertEqual(401, resp.status_int) - self.assertEqual(b'Authentication required', resp.body) - - def test_composite_auth_delay_ok(self): - self.middleware._delay_auth_decision = True - token = self.token_dict['uuid_token_default'] - service_token = self.token_dict['uuid_service_token_default'] - resp = self.call_middleware(headers={'X-Auth-Token': token, - 'X-Service-Token': service_token}) - self.assertEqual(200, resp.status_int) - self.assertEqual(FakeApp.SUCCESS, resp.body) - - def test_composite_auth_delay_invalid_service_token(self): - self.middleware._delay_auth_decision = True - self.purge_service_token_expected_env() - expected_env = { - 'HTTP_X_SERVICE_IDENTITY_STATUS': 'Invalid', - } - self.update_expected_env(expected_env) - - token = self.token_dict['uuid_token_default'] - service_token = 'invalid-service-token' - resp = self.call_middleware(headers={'X-Auth-Token': token, - 'X-Service-Token': service_token}) - self.assertEqual(420, resp.status_int) - self.assertEqual(FakeApp.FORBIDDEN, resp.body) - - def test_composite_auth_delay_invalid_service_and_user_tokens(self): - self.middleware._delay_auth_decision = True - self.purge_service_token_expected_env() - self.purge_token_expected_env() - expected_env = { - 'HTTP_X_IDENTITY_STATUS': 'Invalid', - 'HTTP_X_SERVICE_IDENTITY_STATUS': 'Invalid', - } - self.update_expected_env(expected_env) - - token = 'invalid-token' - service_token = 'invalid-service-token' - resp = self.call_middleware(headers={'X-Auth-Token': token, - 'X-Service-Token': service_token}) - self.assertEqual(419, resp.status_int) - self.assertEqual(FakeApp.FORBIDDEN, resp.body) - - def test_composite_auth_delay_no_service_token(self): - self.middleware._delay_auth_decision = True - self.purge_service_token_expected_env() - - req = webob.Request.blank('/') - req.headers['X-Auth-Token'] = self.token_dict['uuid_token_default'] - - # Ensure injection of service headers is not possible - for key, value in six.iteritems(self.service_token_expected_env): - header_key = key[len('HTTP_'):].replace('_', '-') - req.headers[header_key] = value - # Check arbitrary headers not removed - req.headers['X-Foo'] = 'Bar' - resp = req.get_response(self.middleware) - for key in six.iterkeys(self.service_token_expected_env): - header_key = key[len('HTTP_'):].replace('_', '-') - self.assertFalse(req.headers.get(header_key)) - self.assertEqual('Bar', req.headers.get('X-Foo')) - self.assertEqual(418, resp.status_int) - self.assertEqual(FakeApp.FORBIDDEN, resp.body) - - def test_composite_auth_delay_invalid_user_token(self): - self.middleware._delay_auth_decision = True - self.purge_token_expected_env() - expected_env = { - 'HTTP_X_IDENTITY_STATUS': 'Invalid', - } - self.update_expected_env(expected_env) - - token = 'invalid-token' - service_token = self.token_dict['uuid_service_token_default'] - resp = self.call_middleware(headers={'X-Auth-Token': token, - 'X-Service-Token': service_token}) - self.assertEqual(403, resp.status_int) - self.assertEqual(FakeApp.FORBIDDEN, resp.body) - - def test_composite_auth_delay_no_user_token(self): - self.middleware._delay_auth_decision = True - self.purge_token_expected_env() - expected_env = { - 'HTTP_X_IDENTITY_STATUS': 'Invalid', - } - self.update_expected_env(expected_env) - - service_token = self.token_dict['uuid_service_token_default'] - resp = self.call_middleware(headers={'X-Service-Token': service_token}) - self.assertEqual(403, resp.status_int) - self.assertEqual(FakeApp.FORBIDDEN, resp.body) - - -class v2CompositeAuthTests(BaseAuthTokenMiddlewareTest, - CommonCompositeAuthTests, - testresources.ResourcedTestCase): - """Test auth_token middleware with v2 token based composite auth. - - Execute the Composite auth class tests, but with the - auth_token middleware configured to expect v2 tokens back from - a keystone server. - """ - - resources = [('examples', client_fixtures.EXAMPLES_RESOURCE)] - - def setUp(self): - super(v2CompositeAuthTests, self).setUp( - expected_env=EXPECTED_V2_DEFAULT_SERVICE_ENV_RESPONSE, - fake_app=CompositeFakeApp) - - uuid_token_default = self.examples.UUID_TOKEN_DEFAULT - uuid_service_token_default = self.examples.UUID_SERVICE_TOKEN_DEFAULT - self.token_dict = { - 'uuid_token_default': uuid_token_default, - 'uuid_service_token_default': uuid_service_token_default, - } - - self.requests_mock.get(BASE_URI, - json=VERSION_LIST_v2, - status_code=300) - - self.requests_mock.post('%s/v2.0/tokens' % BASE_URI, - text=FAKE_ADMIN_TOKEN) - - self.requests_mock.get('%s/v2.0/tokens/revoked' % BASE_URI, - text=self.examples.SIGNED_REVOCATION_LIST, - status_code=200) - - for token in (self.examples.UUID_TOKEN_DEFAULT, - self.examples.UUID_SERVICE_TOKEN_DEFAULT,): - text = self.examples.JSON_TOKEN_RESPONSES[token] - self.requests_mock.get('%s/v2.0/tokens/%s' % (BASE_URI, token), - text=text) - - for invalid_uri in ("%s/v2.0/tokens/invalid-token" % BASE_URI, - "%s/v2.0/tokens/invalid-service-token" % BASE_URI): - self.requests_mock.get(invalid_uri, text='', status_code=404) - - self.token_expected_env = dict(EXPECTED_V2_DEFAULT_ENV_RESPONSE) - self.service_token_expected_env = dict( - EXPECTED_V2_DEFAULT_SERVICE_ENV_RESPONSE) - self.set_middleware() - - -class v3CompositeAuthTests(BaseAuthTokenMiddlewareTest, - CommonCompositeAuthTests, - testresources.ResourcedTestCase): - """Test auth_token middleware with v3 token based composite auth. - - Execute the Composite auth class tests, but with the - auth_token middleware configured to expect v3 tokens back from - a keystone server. - """ - - resources = [('examples', client_fixtures.EXAMPLES_RESOURCE)] - - def setUp(self): - super(v3CompositeAuthTests, self).setUp( - auth_version='v3.0', - fake_app=v3CompositeFakeApp) - - uuid_token_default = self.examples.v3_UUID_TOKEN_DEFAULT - uuid_serv_token_default = self.examples.v3_UUID_SERVICE_TOKEN_DEFAULT - self.token_dict = { - 'uuid_token_default': uuid_token_default, - 'uuid_service_token_default': uuid_serv_token_default, - } - - self.requests_mock.get(BASE_URI, json=VERSION_LIST_v3, status_code=300) - - # TODO(jamielennox): auth_token middleware uses a v2 admin token - # regardless of the auth_version that is set. - self.requests_mock.post('%s/v2.0/tokens' % BASE_URI, - text=FAKE_ADMIN_TOKEN) - - self.requests_mock.get('%s/v3/auth/tokens/OS-PKI/revoked' % BASE_URI, - text=self.examples.SIGNED_REVOCATION_LIST) - - self.requests_mock.get('%s/v3/auth/tokens' % BASE_URI, - text=self.token_response, - headers={'X-Subject-Token': uuid.uuid4().hex}) - - self.token_expected_env = dict(EXPECTED_V2_DEFAULT_ENV_RESPONSE) - self.token_expected_env.update(EXPECTED_V3_DEFAULT_ENV_ADDITIONS) - self.service_token_expected_env = dict( - EXPECTED_V2_DEFAULT_SERVICE_ENV_RESPONSE) - self.service_token_expected_env.update( - EXPECTED_V3_DEFAULT_SERVICE_ENV_ADDITIONS) - self.set_middleware() - - def token_response(self, request, context): - auth_id = request.headers.get('X-Auth-Token') - token_id = request.headers.get('X-Subject-Token') - self.assertEqual(auth_id, FAKE_ADMIN_TOKEN_ID) - - status = 200 - response = "" - - if token_id == ERROR_TOKEN: - raise exceptions.ConnectionRefused("Network connection refused.") - - try: - response = self.examples.JSON_TOKEN_RESPONSES[token_id] - except KeyError: - status = 404 - - context.status_code = status - return response - - -class OtherTests(BaseAuthTokenMiddlewareTest): - - def setUp(self): - super(OtherTests, self).setUp() - self.logger = self.useFixture(fixtures.FakeLogger()) - - def test_unknown_server_versions(self): - versions = fixture.DiscoveryList(v2=False, v3_id='v4', href=BASE_URI) - self.set_middleware() - - self.requests_mock.get(BASE_URI, json=versions, status_code=300) - - resp = self.call_middleware(headers={'X-Auth-Token': uuid.uuid4().hex}) - self.assertEqual(503, resp.status_int) - - self.assertIn('versions [v3.0, v2.0]', self.logger.output) - - def _assert_auth_version(self, conf_version, identity_server_version): - self.set_middleware(conf={'auth_version': conf_version}) - identity_server = self.middleware._create_identity_server() - self.assertEqual(identity_server_version, - identity_server.auth_version) - - def test_micro_version(self): - self._assert_auth_version('v2', (2, 0)) - self._assert_auth_version('v2.0', (2, 0)) - self._assert_auth_version('v3', (3, 0)) - self._assert_auth_version('v3.0', (3, 0)) - self._assert_auth_version('v3.1', (3, 0)) - self._assert_auth_version('v3.2', (3, 0)) - self._assert_auth_version('v3.9', (3, 0)) - self._assert_auth_version('v3.3.1', (3, 0)) - self._assert_auth_version('v3.3.5', (3, 0)) - - def test_default_auth_version(self): - # VERSION_LIST_v3 contains both v2 and v3 version elements - self.requests_mock.get(BASE_URI, json=VERSION_LIST_v3, status_code=300) - self._assert_auth_version(None, (3, 0)) - - # VERSION_LIST_v2 contains only v2 version elements - self.requests_mock.get(BASE_URI, json=VERSION_LIST_v2, status_code=300) - self._assert_auth_version(None, (2, 0)) - - def test_unsupported_auth_version(self): - # If the requested version isn't supported we will use v2 - self._assert_auth_version('v1', (2, 0)) - self._assert_auth_version('v10', (2, 0)) - - -class AuthProtocolLoadingTests(BaseAuthTokenMiddlewareTest): - - AUTH_URL = 'http://auth.url/prefix' - DISC_URL = 'http://disc.url/prefix' - KEYSTONE_BASE_URL = 'http://keystone.url/prefix' - CRUD_URL = 'http://crud.url/prefix' - - # NOTE(jamielennox): use the /v2.0 prefix here because this is what's most - # likely to be in the service catalog and we should be able to ignore it. - KEYSTONE_URL = KEYSTONE_BASE_URL + '/v2.0' - - def setUp(self): - super(AuthProtocolLoadingTests, self).setUp() - - self.project_id = uuid.uuid4().hex - - # first touch is to discover the available versions at the auth_url - self.requests_mock.get(self.AUTH_URL, - json=fixture.DiscoveryList(href=self.DISC_URL), - status_code=300) - - # then we do discovery on the URL from the service catalog. In practice - # this is mostly the same URL as before but test the full range. - self.requests_mock.get(self.KEYSTONE_BASE_URL + '/', - json=fixture.DiscoveryList(href=self.CRUD_URL), - status_code=300) - - def good_request(self, app): - # admin_token is the token that the service will get back from auth - admin_token_id = uuid.uuid4().hex - admin_token = fixture.V3Token(project_id=self.project_id) - s = admin_token.add_service('identity', name='keystone') - s.add_standard_endpoints(admin=self.KEYSTONE_URL) - - self.requests_mock.post(self.DISC_URL + '/v3/auth/tokens', - json=admin_token, - headers={'X-Subject-Token': admin_token_id}) - - # user_token is the data from the user's inputted token - user_token_id = uuid.uuid4().hex - user_token = fixture.V3Token() - user_token.set_project_scope() - - request_headers = {'X-Subject-Token': user_token_id, - 'X-Auth-Token': admin_token_id} - - self.requests_mock.get(self.CRUD_URL + '/v3/auth/tokens', - request_headers=request_headers, - json=user_token, - headers={'X-Subject-Token': uuid.uuid4().hex}) - - resp = self.call(app, headers={'X-Auth-Token': user_token_id}) - self.assertEqual(200, resp.status_int) - return resp - - def test_loading_password_plugin(self): - # the password options aren't set on config until loading time, but we - # need them set so we can override the values for testing, so force it - opts = auth.get_plugin_options('password') - self.cfg.register_opts(opts, group=_base.AUTHTOKEN_GROUP) - - project_id = uuid.uuid4().hex - - # Register the authentication options - auth.register_conf_options(self.cfg.conf, group=_base.AUTHTOKEN_GROUP) - - # configure the authentication options - self.cfg.config(auth_plugin='password', - username='testuser', - password='testpass', - auth_url=self.AUTH_URL, - project_id=project_id, - user_domain_id='userdomainid', - group=_base.AUTHTOKEN_GROUP) - - body = uuid.uuid4().hex - app = self.create_simple_middleware(body=body) - - resp = self.good_request(app) - self.assertEqual(six.b(body), resp.body) - - @staticmethod - def get_plugin(app): - return app._identity_server._adapter.auth - - def test_invalid_plugin_fails_to_initialize(self): - auth.register_conf_options(self.cfg.conf, group=_base.AUTHTOKEN_GROUP) - self.cfg.config(auth_plugin=uuid.uuid4().hex, - group=_base.AUTHTOKEN_GROUP) - - self.assertRaises( - exceptions.NoMatchingPlugin, - self.create_simple_middleware) - - def test_plugin_loading_mixed_opts(self): - # some options via override and some via conf - opts = auth.get_plugin_options('password') - self.cfg.register_opts(opts, group=_base.AUTHTOKEN_GROUP) - - username = 'testuser' - password = 'testpass' - - # Register the authentication options - auth.register_conf_options(self.cfg.conf, group=_base.AUTHTOKEN_GROUP) - - # configure the authentication options - self.cfg.config(auth_plugin='password', - password=password, - project_id=self.project_id, - user_domain_id='userdomainid', - group=_base.AUTHTOKEN_GROUP) - - conf = {'username': username, 'auth_url': self.AUTH_URL} - - body = uuid.uuid4().hex - app = self.create_simple_middleware(body=body, conf=conf) - - resp = self.good_request(app) - self.assertEqual(six.b(body), resp.body) - - plugin = self.get_plugin(app) - - self.assertEqual(self.AUTH_URL, plugin.auth_url) - self.assertEqual(username, plugin._username) - self.assertEqual(password, plugin._password) - self.assertEqual(self.project_id, plugin._project_id) - - def test_plugin_loading_with_auth_section(self): - # some options via override and some via conf - section = 'testsection' - username = 'testuser' - password = 'testpass' - - auth.register_conf_options(self.cfg.conf, group=section) - opts = auth.get_plugin_options('password') - self.cfg.register_opts(opts, group=section) - - # Register the authentication options - auth.register_conf_options(self.cfg.conf, group=_base.AUTHTOKEN_GROUP) - - # configure the authentication options - self.cfg.config(auth_section=section, group=_base.AUTHTOKEN_GROUP) - self.cfg.config(auth_plugin='password', - password=password, - project_id=self.project_id, - user_domain_id='userdomainid', - group=section) - - conf = {'username': username, 'auth_url': self.AUTH_URL} - - body = uuid.uuid4().hex - app = self.create_simple_middleware(body=body, conf=conf) - - resp = self.good_request(app) - self.assertEqual(six.b(body), resp.body) - - plugin = self.get_plugin(app) - - self.assertEqual(self.AUTH_URL, plugin.auth_url) - self.assertEqual(username, plugin._username) - self.assertEqual(password, plugin._password) - self.assertEqual(self.project_id, plugin._project_id) - - -class TestAuthPluginUserAgentGeneration(BaseAuthTokenMiddlewareTest): - - def setUp(self): - super(TestAuthPluginUserAgentGeneration, self).setUp() - self.auth_url = uuid.uuid4().hex - self.project_id = uuid.uuid4().hex - self.username = uuid.uuid4().hex - self.password = uuid.uuid4().hex - self.section = uuid.uuid4().hex - self.user_domain_id = uuid.uuid4().hex - - auth.register_conf_options(self.cfg.conf, group=self.section) - opts = auth.get_plugin_options('password') - self.cfg.register_opts(opts, group=self.section) - - # Register the authentication options - auth.register_conf_options(self.cfg.conf, group=_base.AUTHTOKEN_GROUP) - - # configure the authentication options - self.cfg.config(auth_section=self.section, group=_base.AUTHTOKEN_GROUP) - self.cfg.config(auth_plugin='password', - password=self.password, - project_id=self.project_id, - user_domain_id=self.user_domain_id, - group=self.section) - - def test_no_project_configured(self): - ksm_version = uuid.uuid4().hex - conf = {'username': self.username, 'auth_url': self.auth_url} - - app = self._create_app(conf, ksm_version) - self._assert_user_agent(app, '', ksm_version) - - def test_project_in_configuration(self): - project = uuid.uuid4().hex - project_version = uuid.uuid4().hex - - conf = {'username': self.username, - 'auth_url': self.auth_url, - 'project': project} - app = self._create_app(conf, project_version) - project_with_version = '{0}/{1} '.format(project, project_version) - self._assert_user_agent(app, project_with_version, project_version) - - def test_project_in_oslo_configuration(self): - project = uuid.uuid4().hex - project_version = uuid.uuid4().hex - - conf = {'username': self.username, 'auth_url': self.auth_url} - with mock.patch.object(cfg.CONF, 'project', new=project, create=True): - app = self._create_app(conf, project_version) - project = '{0}/{1} '.format(project, project_version) - self._assert_user_agent(app, project, project_version) - - def _create_app(self, conf, project_version): - fake_pkg_resources = mock.Mock() - fake_pkg_resources.get_distribution().version = project_version - - body = uuid.uuid4().hex - with mock.patch('keystonemiddleware.auth_token.pkg_resources', - new=fake_pkg_resources): - return self.create_simple_middleware(body=body, conf=conf, - use_global_conf=True) - - def _assert_user_agent(self, app, project, ksm_version): - sess = app._identity_server._adapter.session - expected_ua = ('{0}keystonemiddleware.auth_token/{1}' - .format(project, ksm_version)) - self.assertEqual(expected_ua, sess.user_agent) - - -class TestAuthPluginLocalOsloConfig(BaseAuthTokenMiddlewareTest): - def test_project_in_local_oslo_configuration(self): - options = { - 'auth_plugin': 'password', - 'auth_uri': uuid.uuid4().hex, - 'password': uuid.uuid4().hex, - } - - content = ("[keystone_authtoken]\n" - "auth_plugin=%(auth_plugin)s\n" - "auth_uri=%(auth_uri)s\n" - "password=%(password)s\n" % options) - conf_file_fixture = self.useFixture( - createfile.CreateFileWithContent("my_app", content)) - conf = {'oslo_config_project': 'my_app', - 'oslo_config_file': conf_file_fixture.path} - app = self._create_app(conf, uuid.uuid4().hex) - for option in options: - self.assertEqual(options[option], app._conf_get(option)) - - def _create_app(self, conf, project_version): - fake_pkg_resources = mock.Mock() - fake_pkg_resources.get_distribution().version = project_version - - body = uuid.uuid4().hex - with mock.patch('keystonemiddleware.auth_token.pkg_resources', - new=fake_pkg_resources): - return self.create_simple_middleware(body=body, conf=conf) - - -def load_tests(loader, tests, pattern): - return testresources.OptimisingTestSuite(tests) diff --git a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_base_middleware.py b/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_base_middleware.py deleted file mode 100644 index b213f546..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_base_middleware.py +++ /dev/null @@ -1,202 +0,0 @@ -# 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. - -import datetime -import uuid - -from keystoneclient import fixture -import mock -import six -import testtools -import webob - -from keystonemiddleware import auth_token -from keystonemiddleware.auth_token import _request - - -class FakeApp(object): - - @webob.dec.wsgify - def __call__(self, req): - return webob.Response() - - -class FetchingMiddleware(auth_token._BaseAuthProtocol): - - def __init__(self, app, token_dict={}, **kwargs): - super(FetchingMiddleware, self).__init__(app, **kwargs) - self.token_dict = token_dict - - def _fetch_token(self, token): - try: - return self.token_dict[token] - except KeyError: - raise auth_token.InvalidToken() - - -class BaseAuthProtocolTests(testtools.TestCase): - - @mock.patch.multiple(auth_token._BaseAuthProtocol, - process_request=mock.DEFAULT, - process_response=mock.DEFAULT) - def test_process_flow(self, process_request, process_response): - m = auth_token._BaseAuthProtocol(FakeApp()) - - process_request.return_value = None - process_response.side_effect = lambda x: x - - req = webob.Request.blank('/', method='GET') - resp = req.get_response(m) - - self.assertEqual(200, resp.status_code) - - self.assertEqual(1, process_request.call_count) - self.assertIsInstance(process_request.call_args[0][0], - _request._AuthTokenRequest) - - self.assertEqual(1, process_response.call_count) - self.assertIsInstance(process_response.call_args[0][0], webob.Response) - - @classmethod - def call(cls, middleware, method='GET', path='/', headers=None): - req = webob.Request.blank(path) - req.method = method - - for k, v in six.iteritems(headers or {}): - req.headers[k] = v - - resp = req.get_response(middleware) - resp.request = req - return resp - - def test_good_v3_user_token(self): - t = fixture.V3Token() - t.set_project_scope() - role = t.add_role() - - token_id = uuid.uuid4().hex - token_dict = {token_id: t} - - @webob.dec.wsgify - def _do_cb(req): - self.assertEqual(token_id, req.headers['X-Auth-Token']) - - self.assertEqual('Confirmed', req.headers['X-Identity-Status']) - self.assertNotIn('X-Service-Token', req.headers) - - p = req.environ['keystone.token_auth'] - - self.assertTrue(p.has_user_token) - self.assertFalse(p.has_service_token) - - self.assertEqual(t.project_id, p.user.project_id) - self.assertEqual(t.project_domain_id, p.user.project_domain_id) - self.assertEqual(t.user_id, p.user.user_id) - self.assertEqual(t.user_domain_id, p.user.user_domain_id) - self.assertIn(role['name'], p.user.role_names) - - return webob.Response() - - m = FetchingMiddleware(_do_cb, token_dict) - self.call(m, headers={'X-Auth-Token': token_id}) - - def test_invalid_user_token(self): - token_id = uuid.uuid4().hex - - @webob.dec.wsgify - def _do_cb(req): - self.assertEqual('Invalid', req.headers['X-Identity-Status']) - self.assertEqual(token_id, req.headers['X-Auth-Token']) - return webob.Response() - - m = FetchingMiddleware(_do_cb) - self.call(m, headers={'X-Auth-Token': token_id}) - - def test_expired_user_token(self): - t = fixture.V3Token() - t.set_project_scope() - t.expires = datetime.datetime.utcnow() - datetime.timedelta(minutes=10) - - token_id = uuid.uuid4().hex - token_dict = {token_id: t} - - @webob.dec.wsgify - def _do_cb(req): - self.assertEqual('Invalid', req.headers['X-Identity-Status']) - self.assertEqual(token_id, req.headers['X-Auth-Token']) - return webob.Response() - - m = FetchingMiddleware(_do_cb, token_dict=token_dict) - self.call(m, headers={'X-Auth-Token': token_id}) - - def test_good_v3_service_token(self): - t = fixture.V3Token() - t.set_project_scope() - role = t.add_role() - - token_id = uuid.uuid4().hex - token_dict = {token_id: t} - - @webob.dec.wsgify - def _do_cb(req): - self.assertEqual(token_id, req.headers['X-Service-Token']) - - self.assertEqual('Confirmed', - req.headers['X-Service-Identity-Status']) - self.assertNotIn('X-Auth-Token', req.headers) - - p = req.environ['keystone.token_auth'] - - self.assertFalse(p.has_user_token) - self.assertTrue(p.has_service_token) - - self.assertEqual(t.project_id, p.service.project_id) - self.assertEqual(t.project_domain_id, p.service.project_domain_id) - self.assertEqual(t.user_id, p.service.user_id) - self.assertEqual(t.user_domain_id, p.service.user_domain_id) - self.assertIn(role['name'], p.service.role_names) - - return webob.Response() - - m = FetchingMiddleware(_do_cb, token_dict) - self.call(m, headers={'X-Service-Token': token_id}) - - def test_invalid_service_token(self): - token_id = uuid.uuid4().hex - - @webob.dec.wsgify - def _do_cb(req): - self.assertEqual('Invalid', - req.headers['X-Service-Identity-Status']) - self.assertEqual(token_id, req.headers['X-Service-Token']) - return webob.Response() - - m = FetchingMiddleware(_do_cb) - self.call(m, headers={'X-Service-Token': token_id}) - - def test_expired_service_token(self): - t = fixture.V3Token() - t.set_project_scope() - t.expires = datetime.datetime.utcnow() - datetime.timedelta(minutes=10) - - token_id = uuid.uuid4().hex - token_dict = {token_id: t} - - @webob.dec.wsgify - def _do_cb(req): - self.assertEqual('Invalid', - req.headers['X-Service-Identity-Status']) - self.assertEqual(token_id, req.headers['X-Service-Token']) - return webob.Response() - - m = FetchingMiddleware(_do_cb, token_dict=token_dict) - self.call(m, headers={'X-Service-Token': token_id}) diff --git a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_connection_pool.py b/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_connection_pool.py deleted file mode 100644 index 074d1e5d..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_connection_pool.py +++ /dev/null @@ -1,118 +0,0 @@ -# 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. - -import time - -import mock -from six.moves import queue -import testtools -from testtools import matchers - -from keystonemiddleware.auth_token import _memcache_pool -from keystonemiddleware.tests.unit import utils - - -class _TestConnectionPool(_memcache_pool.ConnectionPool): - destroyed_value = 'destroyed' - - def _create_connection(self): - return mock.MagicMock() - - def _destroy_connection(self, conn): - conn(self.destroyed_value) - - -class TestConnectionPool(utils.TestCase): - def setUp(self): - super(TestConnectionPool, self).setUp() - self.unused_timeout = 10 - self.maxsize = 2 - self.connection_pool = _TestConnectionPool( - maxsize=self.maxsize, - unused_timeout=self.unused_timeout) - - def test_get_context_manager(self): - self.assertThat(self.connection_pool.queue, matchers.HasLength(0)) - with self.connection_pool.acquire() as conn: - self.assertEqual(1, self.connection_pool._acquired) - self.assertEqual(0, self.connection_pool._acquired) - self.assertThat(self.connection_pool.queue, matchers.HasLength(1)) - self.assertEqual(conn, self.connection_pool.queue[0].connection) - - def test_cleanup_pool(self): - self.test_get_context_manager() - newtime = time.time() + self.unused_timeout * 2 - non_expired_connection = _memcache_pool._PoolItem( - ttl=(newtime * 2), - connection=mock.MagicMock()) - self.connection_pool.queue.append(non_expired_connection) - self.assertThat(self.connection_pool.queue, matchers.HasLength(2)) - with mock.patch.object(time, 'time', return_value=newtime): - conn = self.connection_pool.queue[0].connection - with self.connection_pool.acquire(): - pass - conn.assert_has_calls( - [mock.call(self.connection_pool.destroyed_value)]) - self.assertThat(self.connection_pool.queue, matchers.HasLength(1)) - self.assertEqual(0, non_expired_connection.connection.call_count) - - def test_acquire_conn_exception_returns_acquired_count(self): - class TestException(Exception): - pass - - with mock.patch.object(_TestConnectionPool, '_create_connection', - side_effect=TestException): - with testtools.ExpectedException(TestException): - with self.connection_pool.acquire(): - pass - self.assertThat(self.connection_pool.queue, - matchers.HasLength(0)) - self.assertEqual(0, self.connection_pool._acquired) - - def test_connection_pool_limits_maximum_connections(self): - # NOTE(morganfainberg): To ensure we don't lockup tests until the - # job limit, explicitly call .get_nowait() and .put_nowait() in this - # case. - conn1 = self.connection_pool.get_nowait() - conn2 = self.connection_pool.get_nowait() - - # Use a nowait version to raise an Empty exception indicating we would - # not get another connection until one is placed back into the queue. - self.assertRaises(queue.Empty, self.connection_pool.get_nowait) - - # Place the connections back into the pool. - self.connection_pool.put_nowait(conn1) - self.connection_pool.put_nowait(conn2) - - # Make sure we can get a connection out of the pool again. - self.connection_pool.get_nowait() - - def test_connection_pool_maximum_connection_get_timeout(self): - connection_pool = _TestConnectionPool( - maxsize=1, - unused_timeout=self.unused_timeout, - conn_get_timeout=0) - - def _acquire_connection(): - with connection_pool.acquire(): - pass - - # Make sure we've consumed the only available connection from the pool - conn = connection_pool.get_nowait() - - self.assertRaises(_memcache_pool.ConnectionGetTimeoutException, - _acquire_connection) - - # Put the connection back and ensure we can acquire the connection - # after it is available. - connection_pool.put_nowait(conn) - _acquire_connection() diff --git a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_memcache_crypt.py b/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_memcache_crypt.py deleted file mode 100644 index e9189831..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_memcache_crypt.py +++ /dev/null @@ -1,97 +0,0 @@ -# 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. - -import six - -from keystonemiddleware.auth_token import _memcache_crypt as memcache_crypt -from keystonemiddleware.tests.unit import utils - - -class MemcacheCryptPositiveTests(utils.BaseTestCase): - def _setup_keys(self, strategy): - return memcache_crypt.derive_keys(b'token', b'secret', strategy) - - def test_constant_time_compare(self): - # make sure it works as a compare, the "constant time" aspect - # isn't appropriate to test in unittests - ctc = memcache_crypt.constant_time_compare - self.assertTrue(ctc('abcd', 'abcd')) - self.assertTrue(ctc('', '')) - self.assertFalse(ctc('abcd', 'efgh')) - self.assertFalse(ctc('abc', 'abcd')) - self.assertFalse(ctc('abc', 'abc\x00')) - self.assertFalse(ctc('', 'abc')) - - # For Python 3, we want to test these functions with both str and bytes - # as input. - if six.PY3: - self.assertTrue(ctc(b'abcd', b'abcd')) - self.assertTrue(ctc(b'', b'')) - self.assertFalse(ctc(b'abcd', b'efgh')) - self.assertFalse(ctc(b'abc', b'abcd')) - self.assertFalse(ctc(b'abc', b'abc\x00')) - self.assertFalse(ctc(b'', b'abc')) - - def test_derive_keys(self): - keys = self._setup_keys(b'strategy') - self.assertEqual(len(keys['ENCRYPTION']), - len(keys['CACHE_KEY'])) - self.assertEqual(len(keys['CACHE_KEY']), - len(keys['MAC'])) - self.assertNotEqual(keys['ENCRYPTION'], - keys['MAC']) - self.assertIn('strategy', keys.keys()) - - def test_key_strategy_diff(self): - k1 = self._setup_keys(b'MAC') - k2 = self._setup_keys(b'ENCRYPT') - self.assertNotEqual(k1, k2) - - def test_sign_data(self): - keys = self._setup_keys(b'MAC') - sig = memcache_crypt.sign_data(keys['MAC'], b'data') - self.assertEqual(len(sig), memcache_crypt.DIGEST_LENGTH_B64) - - def test_encryption(self): - keys = self._setup_keys(b'ENCRYPT') - # what you put in is what you get out - for data in [b'data', b'1234567890123456', b'\x00\xFF' * 13 - ] + [six.int2byte(x % 256) * x for x in range(768)]: - crypt = memcache_crypt.encrypt_data(keys['ENCRYPTION'], data) - decrypt = memcache_crypt.decrypt_data(keys['ENCRYPTION'], crypt) - self.assertEqual(data, decrypt) - self.assertRaises(memcache_crypt.DecryptError, - memcache_crypt.decrypt_data, - keys['ENCRYPTION'], crypt[:-1]) - - def test_protect_wrappers(self): - data = b'My Pretty Little Data' - for strategy in [b'MAC', b'ENCRYPT']: - keys = self._setup_keys(strategy) - protected = memcache_crypt.protect_data(keys, data) - self.assertNotEqual(protected, data) - if strategy == b'ENCRYPT': - self.assertNotIn(data, protected) - unprotected = memcache_crypt.unprotect_data(keys, protected) - self.assertEqual(data, unprotected) - self.assertRaises(memcache_crypt.InvalidMacError, - memcache_crypt.unprotect_data, - keys, protected[:-1]) - self.assertIsNone(memcache_crypt.unprotect_data(keys, None)) - - def test_no_pycrypt(self): - aes = memcache_crypt.AES - memcache_crypt.AES = None - self.assertRaises(memcache_crypt.CryptoUnavailableError, - memcache_crypt.encrypt_data, 'token', 'secret', - 'data') - memcache_crypt.AES = aes diff --git a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_request.py b/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_request.py deleted file mode 100644 index 223433f8..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_request.py +++ /dev/null @@ -1,253 +0,0 @@ -# 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. - -import itertools -import uuid - -from keystoneclient import access -from keystoneclient import fixture - -from keystonemiddleware.auth_token import _request -from keystonemiddleware.tests.unit import utils - - -class RequestObjectTests(utils.TestCase): - - def setUp(self): - super(RequestObjectTests, self).setUp() - self.request = _request._AuthTokenRequest.blank('/') - - def test_setting_user_token_valid(self): - self.assertNotIn('X-Identity-Status', self.request.headers) - - self.request.user_token_valid = True - self.assertEqual('Confirmed', - self.request.headers['X-Identity-Status']) - self.assertTrue(self.request.user_token_valid) - - self.request.user_token_valid = False - self.assertEqual('Invalid', - self.request.headers['X-Identity-Status']) - self.assertFalse(self.request.user_token_valid) - - def test_setting_service_token_valid(self): - self.assertNotIn('X-Service-Identity-Status', self.request.headers) - - self.request.service_token_valid = True - self.assertEqual('Confirmed', - self.request.headers['X-Service-Identity-Status']) - self.assertTrue(self.request.service_token_valid) - - self.request.service_token_valid = False - self.assertEqual('Invalid', - self.request.headers['X-Service-Identity-Status']) - self.assertFalse(self.request.service_token_valid) - - def test_removing_headers(self): - GOOD = ('X-Auth-Token', - 'unknownstring', - uuid.uuid4().hex) - - BAD = ('X-Domain-Id', - 'X-Domain-Name', - 'X-Project-Id', - 'X-Project-Name', - 'X-Project-Domain-Id', - 'X-Project-Domain-Name', - 'X-User-Id', - 'X-User-Name', - 'X-User-Domain-Id', - 'X-User-Domain-Name', - 'X-Roles', - 'X-Identity-Status', - - 'X-Service-Domain-Id', - 'X-Service-Domain-Name', - 'X-Service-Project-Id', - 'X-Service-Project-Name', - 'X-Service-Project-Domain-Id', - 'X-Service-Project-Domain-Name', - 'X-Service-User-Id', - 'X-Service-User-Name', - 'X-Service-User-Domain-Id', - 'X-Service-User-Domain-Name', - 'X-Service-Roles', - 'X-Service-Identity-Status', - - 'X-Service-Catalog', - - 'X-Role', - 'X-User', - 'X-Tenant-Id', - 'X-Tenant-Name', - 'X-Tenant', - ) - - header_vals = {} - - for header in itertools.chain(GOOD, BAD): - v = uuid.uuid4().hex - header_vals[header] = v - self.request.headers[header] = v - - self.request.remove_auth_headers() - - for header in BAD: - self.assertNotIn(header, self.request.headers) - - for header in GOOD: - self.assertEqual(header_vals[header], self.request.headers[header]) - - def _test_v3_headers(self, token, prefix): - self.assertEqual(token.domain_id, - self.request.headers['X%s-Domain-Id' % prefix]) - self.assertEqual(token.domain_name, - self.request.headers['X%s-Domain-Name' % prefix]) - self.assertEqual(token.project_id, - self.request.headers['X%s-Project-Id' % prefix]) - self.assertEqual(token.project_name, - self.request.headers['X%s-Project-Name' % prefix]) - self.assertEqual( - token.project_domain_id, - self.request.headers['X%s-Project-Domain-Id' % prefix]) - self.assertEqual( - token.project_domain_name, - self.request.headers['X%s-Project-Domain-Name' % prefix]) - - self.assertEqual(token.user_id, - self.request.headers['X%s-User-Id' % prefix]) - self.assertEqual(token.user_name, - self.request.headers['X%s-User-Name' % prefix]) - self.assertEqual( - token.user_domain_id, - self.request.headers['X%s-User-Domain-Id' % prefix]) - self.assertEqual( - token.user_domain_name, - self.request.headers['X%s-User-Domain-Name' % prefix]) - - def test_project_scoped_user_headers(self): - token = fixture.V3Token() - token.set_project_scope() - token_id = uuid.uuid4().hex - - auth_ref = access.AccessInfo.factory(token_id=token_id, body=token) - self.request.set_user_headers(auth_ref, include_service_catalog=True) - - self._test_v3_headers(token, '') - - def test_project_scoped_service_headers(self): - token = fixture.V3Token() - token.set_project_scope() - token_id = uuid.uuid4().hex - - auth_ref = access.AccessInfo.factory(token_id=token_id, body=token) - self.request.set_service_headers(auth_ref) - - self._test_v3_headers(token, '-Service') - - def test_auth_type(self): - self.assertIsNone(self.request.auth_type) - self.request.environ['AUTH_TYPE'] = 'NeGoTiatE' - self.assertEqual('negotiate', self.request.auth_type) - - def test_user_token(self): - token = uuid.uuid4().hex - self.assertIsNone(self.request.user_token) - self.request.headers['X-Auth-Token'] = token - self.assertEqual(token, self.request.user_token) - - def test_storage_token(self): - storage_token = uuid.uuid4().hex - user_token = uuid.uuid4().hex - - self.assertIsNone(self.request.user_token) - self.request.headers['X-Storage-Token'] = storage_token - self.assertEqual(storage_token, self.request.user_token) - self.request.headers['X-Auth-Token'] = user_token - self.assertEqual(user_token, self.request.user_token) - - def test_service_token(self): - token = uuid.uuid4().hex - self.assertIsNone(self.request.service_token) - self.request.headers['X-Service-Token'] = token - self.assertEqual(token, self.request.service_token) - - def test_token_auth(self): - plugin = object() - - self.assertNotIn('keystone.token_auth', self.request.environ) - self.request.token_auth = plugin - self.assertIs(plugin, self.request.environ['keystone.token_auth']) - self.assertIs(plugin, self.request.token_auth) - - -class CatalogConversionTests(utils.TestCase): - - PUBLIC_URL = 'http://server:5000/v2.0' - ADMIN_URL = 'http://admin:35357/v2.0' - INTERNAL_URL = 'http://internal:5000/v2.0' - - REGION_ONE = 'RegionOne' - REGION_TWO = 'RegionTwo' - REGION_THREE = 'RegionThree' - - def test_basic_convert(self): - token = fixture.V3Token() - s = token.add_service(type='identity') - s.add_standard_endpoints(public=self.PUBLIC_URL, - admin=self.ADMIN_URL, - internal=self.INTERNAL_URL, - region=self.REGION_ONE) - - auth_ref = access.AccessInfo.factory(body=token) - catalog_data = auth_ref.service_catalog.get_data() - catalog = _request._v3_to_v2_catalog(catalog_data) - - self.assertEqual(1, len(catalog)) - service = catalog[0] - self.assertEqual(1, len(service['endpoints'])) - endpoints = service['endpoints'][0] - - self.assertEqual('identity', service['type']) - self.assertEqual(4, len(endpoints)) - self.assertEqual(self.PUBLIC_URL, endpoints['publicURL']) - self.assertEqual(self.ADMIN_URL, endpoints['adminURL']) - self.assertEqual(self.INTERNAL_URL, endpoints['internalURL']) - self.assertEqual(self.REGION_ONE, endpoints['region']) - - def test_multi_region(self): - token = fixture.V3Token() - s = token.add_service(type='identity') - - s.add_endpoint('internal', self.INTERNAL_URL, region=self.REGION_ONE) - s.add_endpoint('public', self.PUBLIC_URL, region=self.REGION_TWO) - s.add_endpoint('admin', self.ADMIN_URL, region=self.REGION_THREE) - - auth_ref = access.AccessInfo.factory(body=token) - catalog_data = auth_ref.service_catalog.get_data() - catalog = _request._v3_to_v2_catalog(catalog_data) - - self.assertEqual(1, len(catalog)) - service = catalog[0] - - # the 3 regions will come through as 3 separate endpoints - expected = [{'internalURL': self.INTERNAL_URL, - 'region': self.REGION_ONE}, - {'publicURL': self.PUBLIC_URL, - 'region': self.REGION_TWO}, - {'adminURL': self.ADMIN_URL, - 'region': self.REGION_THREE}] - - self.assertEqual('identity', service['type']) - self.assertEqual(3, len(service['endpoints'])) - for e in expected: - self.assertIn(e, expected) diff --git a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_revocations.py b/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_revocations.py deleted file mode 100644 index 258e195a..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_revocations.py +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright 2014 IBM Corp. -# -# 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. - -import datetime -import json -import shutil -import uuid - -import mock - -from keystonemiddleware.auth_token import _exceptions as exc -from keystonemiddleware.auth_token import _revocations -from keystonemiddleware.auth_token import _signing_dir -from keystonemiddleware.tests.unit import utils - - -class RevocationsTests(utils.BaseTestCase): - - def _setup_revocations(self, revoked_list): - directory_name = '/tmp/%s' % uuid.uuid4().hex - signing_directory = _signing_dir.SigningDirectory(directory_name) - self.addCleanup(shutil.rmtree, directory_name) - - identity_server = mock.Mock() - - verify_result_obj = {'revoked': revoked_list} - cms_verify = mock.Mock(return_value=json.dumps(verify_result_obj)) - - revocations = _revocations.Revocations( - timeout=datetime.timedelta(1), signing_directory=signing_directory, - identity_server=identity_server, cms_verify=cms_verify) - return revocations - - def _check_with_list(self, revoked_list, token_ids): - revoked_list = list({'id': r} for r in revoked_list) - revocations = self._setup_revocations(revoked_list) - revocations.check(token_ids) - - def test_check_empty_list(self): - # When the identity server returns an empty list, a token isn't - # revoked. - - revoked_tokens = [] - token_ids = [uuid.uuid4().hex] - # No assert because this would raise - self._check_with_list(revoked_tokens, token_ids) - - def test_check_revoked(self): - # When the identity server returns a list with a token in it, that - # token is revoked. - - token_id = uuid.uuid4().hex - revoked_tokens = [token_id] - token_ids = [token_id] - self.assertRaises(exc.InvalidToken, - self._check_with_list, revoked_tokens, token_ids) - - def test_check_by_audit_id_revoked(self): - # When the audit ID is in the revocation list, InvalidToken is raised. - audit_id = uuid.uuid4().hex - revoked_list = [{'id': uuid.uuid4().hex, 'audit_id': audit_id}] - revocations = self._setup_revocations(revoked_list) - self.assertRaises(exc.InvalidToken, - revocations.check_by_audit_id, [audit_id]) - - def test_check_by_audit_id_chain_revoked(self): - # When the token's audit chain ID is in the revocation list, - # InvalidToken is raised. - revoked_audit_id = uuid.uuid4().hex - revoked_list = [{'id': uuid.uuid4().hex, 'audit_id': revoked_audit_id}] - revocations = self._setup_revocations(revoked_list) - - token_audit_ids = [uuid.uuid4().hex, revoked_audit_id] - self.assertRaises(exc.InvalidToken, - revocations.check_by_audit_id, token_audit_ids) - - def test_check_by_audit_id_not_revoked(self): - # When the audit ID is not in the revocation list no exception. - revoked_list = [{'id': uuid.uuid4().hex, 'audit_id': uuid.uuid4().hex}] - revocations = self._setup_revocations(revoked_list) - - audit_id = uuid.uuid4().hex - revocations.check_by_audit_id([audit_id]) - - def test_check_by_audit_id_no_audit_ids(self): - # Older identity servers don't send audit_ids in the revocation list. - # When this happens, check_by_audit_id still works, just doesn't - # verify anything. - revoked_list = [{'id': uuid.uuid4().hex}] - revocations = self._setup_revocations(revoked_list) - - audit_id = uuid.uuid4().hex - revocations.check_by_audit_id([audit_id]) diff --git a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_signing_dir.py b/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_signing_dir.py deleted file mode 100644 index b2ef95dd..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_signing_dir.py +++ /dev/null @@ -1,137 +0,0 @@ -# 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. - -import os -import shutil -import stat -import uuid - -from keystonemiddleware.auth_token import _signing_dir -from keystonemiddleware.tests.unit import utils - - -class SigningDirectoryTests(utils.BaseTestCase): - - def test_directory_created_when_doesnt_exist(self): - # When _SigningDirectory is created, if the directory doesn't exist - # it's created with the expected permissions. - tmp_name = uuid.uuid4().hex - parent_directory = '/tmp/%s' % tmp_name - directory_name = '/tmp/%s/%s' % ((tmp_name,) * 2) - - # Directories are created by __init__. - _signing_dir.SigningDirectory(directory_name) - self.addCleanup(shutil.rmtree, parent_directory) - - self.assertTrue(os.path.isdir(directory_name)) - self.assertTrue(os.access(directory_name, os.W_OK)) - self.assertEqual(os.stat(directory_name).st_uid, os.getuid()) - self.assertEqual(stat.S_IMODE(os.stat(directory_name).st_mode), - stat.S_IRWXU) - - def test_use_directory_already_exists(self): - # The directory can already exist. - - tmp_name = uuid.uuid4().hex - parent_directory = '/tmp/%s' % tmp_name - directory_name = '/tmp/%s/%s' % ((tmp_name,) * 2) - os.makedirs(directory_name, stat.S_IRWXU) - self.addCleanup(shutil.rmtree, parent_directory) - - _signing_dir.SigningDirectory(directory_name) - - def test_write_file(self): - # write_file when the file doesn't exist creates the file. - - signing_directory = _signing_dir.SigningDirectory() - self.addCleanup(shutil.rmtree, signing_directory._directory_name) - - file_name = self.getUniqueString() - contents = self.getUniqueString() - signing_directory.write_file(file_name, contents) - - file_path = signing_directory.calc_path(file_name) - with open(file_path) as f: - actual_contents = f.read() - - self.assertEqual(contents, actual_contents) - - def test_replace_file(self): - # write_file when the file already exists overwrites it. - - signing_directory = _signing_dir.SigningDirectory() - self.addCleanup(shutil.rmtree, signing_directory._directory_name) - - file_name = self.getUniqueString() - orig_contents = self.getUniqueString() - signing_directory.write_file(file_name, orig_contents) - - new_contents = self.getUniqueString() - signing_directory.write_file(file_name, new_contents) - - file_path = signing_directory.calc_path(file_name) - with open(file_path) as f: - actual_contents = f.read() - - self.assertEqual(new_contents, actual_contents) - - def test_recreate_directory(self): - # If the original directory is lost, it gets recreated when a file - # is written. - - signing_directory = _signing_dir.SigningDirectory() - self.addCleanup(shutil.rmtree, signing_directory._directory_name) - - # Delete the directory. - shutil.rmtree(signing_directory._directory_name) - - file_name = self.getUniqueString() - contents = self.getUniqueString() - signing_directory.write_file(file_name, contents) - - actual_contents = signing_directory.read_file(file_name) - self.assertEqual(contents, actual_contents) - - def test_read_file(self): - # Can read a file that was written. - - signing_directory = _signing_dir.SigningDirectory() - self.addCleanup(shutil.rmtree, signing_directory._directory_name) - - file_name = self.getUniqueString() - contents = self.getUniqueString() - signing_directory.write_file(file_name, contents) - - actual_contents = signing_directory.read_file(file_name) - - self.assertEqual(contents, actual_contents) - - def test_read_file_doesnt_exist(self): - # Show what happens when try to read a file that wasn't written. - - signing_directory = _signing_dir.SigningDirectory() - self.addCleanup(shutil.rmtree, signing_directory._directory_name) - - file_name = self.getUniqueString() - self.assertRaises(IOError, signing_directory.read_file, file_name) - - def test_calc_path(self): - # calc_path returns the actual filename built from the directory name. - - signing_directory = _signing_dir.SigningDirectory() - self.addCleanup(shutil.rmtree, signing_directory._directory_name) - - file_name = self.getUniqueString() - actual_path = signing_directory.calc_path(file_name) - expected_path = os.path.join(signing_directory._directory_name, - file_name) - self.assertEqual(expected_path, actual_path) diff --git a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_user_auth_plugin.py b/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_user_auth_plugin.py deleted file mode 100644 index 19d3d7a9..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_user_auth_plugin.py +++ /dev/null @@ -1,201 +0,0 @@ -# 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. - -import uuid -import warnings - -from keystoneclient import auth -from keystoneclient import fixture - -from keystonemiddleware.auth_token import _base -from keystonemiddleware.tests.unit.auth_token import base - -# NOTE(jamielennox): just some sample values that we can use for testing -BASE_URI = 'https://keystone.example.com:1234' -AUTH_URL = 'https://keystone.auth.com:1234' - - -class BaseUserPluginTests(object): - - def configure_middleware(self, - auth_plugin, - group='keystone_authtoken', - **kwargs): - # NOTE(gyee): For this test suite and for the stable liberty branch - # only, we will ignore deprecated calls that keystonemiddleware makes. - warnings.filterwarnings('ignore', category=DeprecationWarning, - module='^keystonemiddleware\\.') - - opts = auth.get_plugin_class(auth_plugin).get_options() - self.cfg.register_opts(opts, group=group) - - # Since these tests cfg.config() themselves rather than waiting for - # auth_token to do it on __init__ we need to register the base auth - # options (e.g., auth_plugin) - auth.register_conf_options(self.cfg.conf, group=_base.AUTHTOKEN_GROUP) - - self.cfg.config(group=group, - auth_plugin=auth_plugin, - **kwargs) - - def assertTokenDataEqual(self, token_id, token, token_data): - self.assertEqual(token_id, token_data.auth_token) - self.assertEqual(token.user_id, token_data.user_id) - try: - trust_id = token.trust_id - except KeyError: - trust_id = None - self.assertEqual(trust_id, token_data.trust_id) - self.assertEqual(self.get_role_names(token), token_data.role_names) - - def get_plugin(self, token_id, service_token_id=None): - headers = {'X-Auth-Token': token_id} - - if service_token_id: - headers['X-Service-Token'] = service_token_id - - m = self.create_simple_middleware() - - resp = self.call(m, headers=headers) - self.assertEqual(200, resp.status_int) - return resp.request.environ['keystone.token_auth'] - - def test_user_information(self): - token_id, token = self.get_token() - plugin = self.get_plugin(token_id) - - self.assertTokenDataEqual(token_id, token, plugin.user) - self.assertFalse(plugin.has_service_token) - self.assertIsNone(plugin.service) - - def test_with_service_information(self): - token_id, token = self.get_token() - service_id, service = self.get_token() - - plugin = self.get_plugin(token_id, service_id) - - self.assertTokenDataEqual(token_id, token, plugin.user) - self.assertTokenDataEqual(service_id, service, plugin.service) - - -class V2UserPluginTests(BaseUserPluginTests, base.BaseAuthTokenTestCase): - - def setUp(self): - super(V2UserPluginTests, self).setUp() - - self.service_token = fixture.V2Token() - self.service_token.set_scope() - s = self.service_token.add_service('identity', name='keystone') - - s.add_endpoint(public=BASE_URI, - admin=BASE_URI, - internal=BASE_URI) - - self.configure_middleware(auth_plugin='v2password', - auth_url='%s/v2.0/' % AUTH_URL, - user_id=self.service_token.user_id, - password=uuid.uuid4().hex, - tenant_id=self.service_token.tenant_id) - - auth_discovery = fixture.DiscoveryList(href=AUTH_URL, v3=False) - self.requests_mock.get(AUTH_URL, json=auth_discovery) - - base_discovery = fixture.DiscoveryList(href=BASE_URI, v3=False) - self.requests_mock.get(BASE_URI, json=base_discovery) - - url = '%s/v2.0/tokens' % AUTH_URL - self.requests_mock.post(url, json=self.service_token) - - def get_role_names(self, token): - return set(x['name'] for x in token['access']['user'].get('roles', [])) - - def get_token(self): - token = fixture.V2Token() - token.set_scope() - token.add_role() - - request_headers = {'X-Auth-Token': self.service_token.token_id} - - url = '%s/v2.0/tokens/%s' % (BASE_URI, token.token_id) - self.requests_mock.get(url, - request_headers=request_headers, - json=token) - - return token.token_id, token - - def assertTokenDataEqual(self, token_id, token, token_data): - super(V2UserPluginTests, self).assertTokenDataEqual(token_id, - token, - token_data) - - self.assertEqual(token.tenant_id, token_data.project_id) - self.assertIsNone(token_data.user_domain_id) - self.assertIsNone(token_data.project_domain_id) - - -class V3UserPluginTests(BaseUserPluginTests, base.BaseAuthTokenTestCase): - - def setUp(self): - super(V3UserPluginTests, self).setUp() - - self.service_token_id = uuid.uuid4().hex - self.service_token = fixture.V3Token() - s = self.service_token.add_service('identity', name='keystone') - s.add_standard_endpoints(public=BASE_URI, - admin=BASE_URI, - internal=BASE_URI) - - self.configure_middleware(auth_plugin='v3password', - auth_url='%s/v3/' % AUTH_URL, - user_id=self.service_token.user_id, - password=uuid.uuid4().hex, - project_id=self.service_token.project_id) - - auth_discovery = fixture.DiscoveryList(href=AUTH_URL) - self.requests_mock.get(AUTH_URL, json=auth_discovery) - - base_discovery = fixture.DiscoveryList(href=BASE_URI) - self.requests_mock.get(BASE_URI, json=base_discovery) - - self.requests_mock.post( - '%s/v3/auth/tokens' % AUTH_URL, - headers={'X-Subject-Token': self.service_token_id}, - json=self.service_token) - - def get_role_names(self, token): - return set(x['name'] for x in token['token'].get('roles', [])) - - def get_token(self): - token_id = uuid.uuid4().hex - token = fixture.V3Token() - token.set_project_scope() - token.add_role() - - request_headers = {'X-Auth-Token': self.service_token_id, - 'X-Subject-Token': token_id} - headers = {'X-Subject-Token': token_id} - - self.requests_mock.get('%s/v3/auth/tokens' % BASE_URI, - request_headers=request_headers, - headers=headers, - json=token) - - return token_id, token - - def assertTokenDataEqual(self, token_id, token, token_data): - super(V3UserPluginTests, self).assertTokenDataEqual(token_id, - token, - token_data) - - self.assertEqual(token.user_domain_id, token_data.user_domain_id) - self.assertEqual(token.project_id, token_data.project_id) - self.assertEqual(token.project_domain_id, token_data.project_domain_id) diff --git a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_utils.py b/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_utils.py deleted file mode 100644 index fcd1e628..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_utils.py +++ /dev/null @@ -1,37 +0,0 @@ -# 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. - -import testtools - -from keystonemiddleware.auth_token import _utils - - -class TokenEncodingTest(testtools.TestCase): - - def test_unquoted_token(self): - self.assertEqual('foo%20bar', _utils.safe_quote('foo bar')) - - def test_quoted_token(self): - self.assertEqual('foo%20bar', _utils.safe_quote('foo%20bar')) - - def test_messages_encoded_as_bytes(self): - """Test that string are passed around as bytes for PY3.""" - msg = "This is an error" - - class FakeResp(_utils.MiniResp): - def __init__(self, error, env): - super(FakeResp, self).__init__(error, env) - - fake_resp = FakeResp(msg, dict(REQUEST_METHOD='GET')) - # On Py2 .encode() don't do much but that's better than to - # have a ifdef with six.PY3 - self.assertEqual(msg.encode(), fake_resp.body[0]) diff --git a/keystonemiddleware-moon/keystonemiddleware/tests/unit/client_fixtures.py b/keystonemiddleware-moon/keystonemiddleware/tests/unit/client_fixtures.py deleted file mode 100644 index ee4111ec..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/tests/unit/client_fixtures.py +++ /dev/null @@ -1,452 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# -# 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. - -import os - -import fixtures -from keystoneclient.common import cms -from keystoneclient import fixture -from keystoneclient import utils -from oslo_serialization import jsonutils -from oslo_utils import timeutils -import six -import testresources - - -TESTDIR = os.path.dirname(os.path.abspath(__file__)) -ROOTDIR = os.path.normpath(os.path.join(TESTDIR, '..', '..', '..')) -CERTDIR = os.path.join(ROOTDIR, 'examples', 'pki', 'certs') -CMSDIR = os.path.join(ROOTDIR, 'examples', 'pki', 'cms') -KEYDIR = os.path.join(ROOTDIR, 'examples', 'pki', 'private') - - -def _hash_signed_token_safe(signed_text, **kwargs): - if isinstance(signed_text, six.text_type): - signed_text = signed_text.encode('utf-8') - return utils.hash_signed_token(signed_text, **kwargs) - - -class Examples(fixtures.Fixture): - """Example tokens and certs loaded from the examples directory. - - To use this class correctly, the module needs to override the test suite - class to use testresources.OptimisingTestSuite (otherwise the files will - be read on every test). This is done by defining a load_tests function - in the module, like this: - - def load_tests(loader, tests, pattern): - return testresources.OptimisingTestSuite(tests) - - (see http://docs.python.org/2/library/unittest.html#load-tests-protocol ) - - """ - - def setUp(self): - super(Examples, self).setUp() - - # The data for several tests are signed using openssl and are stored in - # files in the signing subdirectory. In order to keep the values - # consistent between the tests and the signed documents, we read them - # in for use in the tests. - with open(os.path.join(CMSDIR, 'auth_token_scoped.json')) as f: - self.TOKEN_SCOPED_DATA = cms.cms_to_token(f.read()) - - with open(os.path.join(CMSDIR, 'auth_token_scoped.pem')) as f: - self.SIGNED_TOKEN_SCOPED = cms.cms_to_token(f.read()) - self.SIGNED_TOKEN_SCOPED_HASH = _hash_signed_token_safe( - self.SIGNED_TOKEN_SCOPED) - self.SIGNED_TOKEN_SCOPED_HASH_SHA256 = _hash_signed_token_safe( - self.SIGNED_TOKEN_SCOPED, mode='sha256') - with open(os.path.join(CMSDIR, 'auth_token_unscoped.pem')) as f: - self.SIGNED_TOKEN_UNSCOPED = cms.cms_to_token(f.read()) - with open(os.path.join(CMSDIR, 'auth_v3_token_scoped.pem')) as f: - self.SIGNED_v3_TOKEN_SCOPED = cms.cms_to_token(f.read()) - self.SIGNED_v3_TOKEN_SCOPED_HASH = _hash_signed_token_safe( - self.SIGNED_v3_TOKEN_SCOPED) - self.SIGNED_v3_TOKEN_SCOPED_HASH_SHA256 = _hash_signed_token_safe( - self.SIGNED_v3_TOKEN_SCOPED, mode='sha256') - with open(os.path.join(CMSDIR, 'auth_token_revoked.pem')) as f: - self.REVOKED_TOKEN = cms.cms_to_token(f.read()) - with open(os.path.join(CMSDIR, 'auth_token_scoped_expired.pem')) as f: - self.SIGNED_TOKEN_SCOPED_EXPIRED = cms.cms_to_token(f.read()) - with open(os.path.join(CMSDIR, 'auth_v3_token_revoked.pem')) as f: - self.REVOKED_v3_TOKEN = cms.cms_to_token(f.read()) - with open(os.path.join(CMSDIR, 'auth_token_scoped.pkiz')) as f: - self.SIGNED_TOKEN_SCOPED_PKIZ = cms.cms_to_token(f.read()) - with open(os.path.join(CMSDIR, 'auth_token_unscoped.pkiz')) as f: - self.SIGNED_TOKEN_UNSCOPED_PKIZ = cms.cms_to_token(f.read()) - with open(os.path.join(CMSDIR, 'auth_v3_token_scoped.pkiz')) as f: - self.SIGNED_v3_TOKEN_SCOPED_PKIZ = cms.cms_to_token(f.read()) - with open(os.path.join(CMSDIR, 'auth_token_revoked.pkiz')) as f: - self.REVOKED_TOKEN_PKIZ = cms.cms_to_token(f.read()) - with open(os.path.join(CMSDIR, - 'auth_token_scoped_expired.pkiz')) as f: - self.SIGNED_TOKEN_SCOPED_EXPIRED_PKIZ = cms.cms_to_token(f.read()) - with open(os.path.join(CMSDIR, 'auth_v3_token_revoked.pkiz')) as f: - self.REVOKED_v3_TOKEN_PKIZ = cms.cms_to_token(f.read()) - with open(os.path.join(CMSDIR, 'revocation_list.json')) as f: - self.REVOCATION_LIST = jsonutils.loads(f.read()) - with open(os.path.join(CMSDIR, 'revocation_list.pem')) as f: - self.SIGNED_REVOCATION_LIST = jsonutils.dumps({'signed': f.read()}) - - self.SIGNING_CERT_FILE = os.path.join(CERTDIR, 'signing_cert.pem') - with open(self.SIGNING_CERT_FILE) as f: - self.SIGNING_CERT = f.read() - - self.KERBEROS_BIND = 'USER@REALM' - - self.SIGNING_KEY_FILE = os.path.join(KEYDIR, 'signing_key.pem') - with open(self.SIGNING_KEY_FILE) as f: - self.SIGNING_KEY = f.read() - - self.SIGNING_CA_FILE = os.path.join(CERTDIR, 'cacert.pem') - with open(self.SIGNING_CA_FILE) as f: - self.SIGNING_CA = f.read() - - self.UUID_TOKEN_DEFAULT = "ec6c0710ec2f471498484c1b53ab4f9d" - self.UUID_TOKEN_NO_SERVICE_CATALOG = '8286720fbe4941e69fa8241723bb02df' - self.UUID_TOKEN_UNSCOPED = '731f903721c14827be7b2dc912af7776' - self.UUID_TOKEN_BIND = '3fc54048ad64405c98225ce0897af7c5' - self.UUID_TOKEN_UNKNOWN_BIND = '8885fdf4d42e4fb9879e6379fa1eaf48' - self.VALID_DIABLO_TOKEN = 'b0cf19b55dbb4f20a6ee18e6c6cf1726' - self.v3_UUID_TOKEN_DEFAULT = '5603457654b346fdbb93437bfe76f2f1' - self.v3_UUID_TOKEN_UNSCOPED = 'd34835fdaec447e695a0a024d84f8d79' - self.v3_UUID_TOKEN_DOMAIN_SCOPED = 'e8a7b63aaa4449f38f0c5c05c3581792' - self.v3_UUID_TOKEN_BIND = '2f61f73e1c854cbb9534c487f9bd63c2' - self.v3_UUID_TOKEN_UNKNOWN_BIND = '7ed9781b62cd4880b8d8c6788ab1d1e2' - - self.UUID_SERVICE_TOKEN_DEFAULT = 'fe4c0710ec2f492748596c1b53ab124' - self.v3_UUID_SERVICE_TOKEN_DEFAULT = 'g431071bbc2f492748596c1b53cb229' - - revoked_token = self.REVOKED_TOKEN - if isinstance(revoked_token, six.text_type): - revoked_token = revoked_token.encode('utf-8') - self.REVOKED_TOKEN_HASH = utils.hash_signed_token(revoked_token) - self.REVOKED_TOKEN_HASH_SHA256 = utils.hash_signed_token(revoked_token, - mode='sha256') - self.REVOKED_TOKEN_LIST = ( - {'revoked': [{'id': self.REVOKED_TOKEN_HASH, - 'expires': timeutils.utcnow()}]}) - self.REVOKED_TOKEN_LIST_JSON = jsonutils.dumps(self.REVOKED_TOKEN_LIST) - - revoked_v3_token = self.REVOKED_v3_TOKEN - if isinstance(revoked_v3_token, six.text_type): - revoked_v3_token = revoked_v3_token.encode('utf-8') - self.REVOKED_v3_TOKEN_HASH = utils.hash_signed_token(revoked_v3_token) - hash = utils.hash_signed_token(revoked_v3_token, mode='sha256') - self.REVOKED_v3_TOKEN_HASH_SHA256 = hash - self.REVOKED_v3_TOKEN_LIST = ( - {'revoked': [{'id': self.REVOKED_v3_TOKEN_HASH, - 'expires': timeutils.utcnow()}]}) - self.REVOKED_v3_TOKEN_LIST_JSON = jsonutils.dumps( - self.REVOKED_v3_TOKEN_LIST) - - revoked_token_pkiz = self.REVOKED_TOKEN_PKIZ - if isinstance(revoked_token_pkiz, six.text_type): - revoked_token_pkiz = revoked_token_pkiz.encode('utf-8') - self.REVOKED_TOKEN_PKIZ_HASH = utils.hash_signed_token( - revoked_token_pkiz) - revoked_v3_token_pkiz = self.REVOKED_v3_TOKEN_PKIZ - if isinstance(revoked_v3_token_pkiz, six.text_type): - revoked_v3_token_pkiz = revoked_v3_token_pkiz.encode('utf-8') - self.REVOKED_v3_PKIZ_TOKEN_HASH = utils.hash_signed_token( - revoked_v3_token_pkiz) - - self.REVOKED_TOKEN_PKIZ_LIST = ( - {'revoked': [{'id': self.REVOKED_TOKEN_PKIZ_HASH, - 'expires': timeutils.utcnow()}, - {'id': self.REVOKED_v3_PKIZ_TOKEN_HASH, - 'expires': timeutils.utcnow()}, - ]}) - self.REVOKED_TOKEN_PKIZ_LIST_JSON = jsonutils.dumps( - self.REVOKED_TOKEN_PKIZ_LIST) - - self.SIGNED_TOKEN_SCOPED_KEY = cms.cms_hash_token( - self.SIGNED_TOKEN_SCOPED) - self.SIGNED_TOKEN_UNSCOPED_KEY = cms.cms_hash_token( - self.SIGNED_TOKEN_UNSCOPED) - self.SIGNED_v3_TOKEN_SCOPED_KEY = cms.cms_hash_token( - self.SIGNED_v3_TOKEN_SCOPED) - - self.SIGNED_TOKEN_SCOPED_PKIZ_KEY = cms.cms_hash_token( - self.SIGNED_TOKEN_SCOPED_PKIZ) - self.SIGNED_TOKEN_UNSCOPED_PKIZ_KEY = cms.cms_hash_token( - self.SIGNED_TOKEN_UNSCOPED_PKIZ) - self.SIGNED_v3_TOKEN_SCOPED_PKIZ_KEY = cms.cms_hash_token( - self.SIGNED_v3_TOKEN_SCOPED_PKIZ) - - self.INVALID_SIGNED_TOKEN = ( - "MIIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" - "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" - "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "0000000000000000000000000000000000000000000000000000000000000000" - "1111111111111111111111111111111111111111111111111111111111111111" - "2222222222222222222222222222222222222222222222222222222222222222" - "3333333333333333333333333333333333333333333333333333333333333333" - "4444444444444444444444444444444444444444444444444444444444444444" - "5555555555555555555555555555555555555555555555555555555555555555" - "6666666666666666666666666666666666666666666666666666666666666666" - "7777777777777777777777777777777777777777777777777777777777777777" - "8888888888888888888888888888888888888888888888888888888888888888" - "9999999999999999999999999999999999999999999999999999999999999999" - "0000000000000000000000000000000000000000000000000000000000000000") - - self.INVALID_SIGNED_PKIZ_TOKEN = ( - "PKIZ_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" - "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" - "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "0000000000000000000000000000000000000000000000000000000000000000" - "1111111111111111111111111111111111111111111111111111111111111111" - "2222222222222222222222222222222222222222222222222222222222222222" - "3333333333333333333333333333333333333333333333333333333333333333" - "4444444444444444444444444444444444444444444444444444444444444444" - "5555555555555555555555555555555555555555555555555555555555555555" - "6666666666666666666666666666666666666666666666666666666666666666" - "7777777777777777777777777777777777777777777777777777777777777777" - "8888888888888888888888888888888888888888888888888888888888888888" - "9999999999999999999999999999999999999999999999999999999999999999" - "0000000000000000000000000000000000000000000000000000000000000000") - - # JSON responses keyed by token ID - self.TOKEN_RESPONSES = {} - - # basic values - PROJECT_ID = 'tenant_id1' - PROJECT_NAME = 'tenant_name1' - USER_ID = 'user_id1' - USER_NAME = 'user_name1' - DOMAIN_ID = 'domain_id1' - DOMAIN_NAME = 'domain_name1' - ROLE_NAME1 = 'role1' - ROLE_NAME2 = 'role2' - - SERVICE_PROJECT_ID = 'service_project_id1' - SERVICE_PROJECT_NAME = 'service_project_name1' - SERVICE_USER_ID = 'service_user_id1' - SERVICE_USER_NAME = 'service_user_name1' - SERVICE_DOMAIN_ID = 'service_domain_id1' - SERVICE_DOMAIN_NAME = 'service_domain_name1' - SERVICE_ROLE_NAME1 = 'service_role1' - SERVICE_ROLE_NAME2 = 'service_role2' - - self.SERVICE_TYPE = 'identity' - self.UNVERSIONED_SERVICE_URL = 'http://keystone.server:5000/' - self.SERVICE_URL = self.UNVERSIONED_SERVICE_URL + 'v2.0' - - # Old Tokens - - self.TOKEN_RESPONSES[self.VALID_DIABLO_TOKEN] = { - 'access': { - 'token': { - 'id': self.VALID_DIABLO_TOKEN, - 'expires': '2020-01-01T00:00:10.000123Z', - 'tenantId': PROJECT_ID, - }, - 'user': { - 'id': USER_ID, - 'name': USER_NAME, - 'roles': [ - {'name': ROLE_NAME1}, - {'name': ROLE_NAME2}, - ], - }, - }, - } - - # Generated V2 Tokens - - token = fixture.V2Token(token_id=self.UUID_TOKEN_DEFAULT, - tenant_id=PROJECT_ID, - tenant_name=PROJECT_NAME, - user_id=USER_ID, - user_name=USER_NAME) - token.add_role(name=ROLE_NAME1) - token.add_role(name=ROLE_NAME2) - svc = token.add_service(self.SERVICE_TYPE) - svc.add_endpoint(public=self.SERVICE_URL) - self.TOKEN_RESPONSES[self.UUID_TOKEN_DEFAULT] = token - - token = fixture.V2Token(token_id=self.UUID_TOKEN_UNSCOPED, - user_id=USER_ID, - user_name=USER_NAME) - self.TOKEN_RESPONSES[self.UUID_TOKEN_UNSCOPED] = token - - token = fixture.V2Token(token_id='valid-token', - tenant_id=PROJECT_ID, - tenant_name=PROJECT_NAME, - user_id=USER_ID, - user_name=USER_NAME) - token.add_role(ROLE_NAME1) - token.add_role(ROLE_NAME2) - self.TOKEN_RESPONSES[self.UUID_TOKEN_NO_SERVICE_CATALOG] = token - - token = fixture.V2Token(token_id=self.SIGNED_TOKEN_SCOPED_KEY, - tenant_id=PROJECT_ID, - tenant_name=PROJECT_NAME, - user_id=USER_ID, - user_name=USER_NAME) - token.add_role(ROLE_NAME1) - token.add_role(ROLE_NAME2) - self.TOKEN_RESPONSES[self.SIGNED_TOKEN_SCOPED_KEY] = token - - token = fixture.V2Token(token_id=self.SIGNED_TOKEN_UNSCOPED_KEY, - user_id=USER_ID, - user_name=USER_NAME) - self.TOKEN_RESPONSES[self.SIGNED_TOKEN_UNSCOPED_KEY] = token - - token = fixture.V2Token(token_id=self.UUID_TOKEN_BIND, - tenant_id=PROJECT_ID, - tenant_name=PROJECT_NAME, - user_id=USER_ID, - user_name=USER_NAME) - token.add_role(ROLE_NAME1) - token.add_role(ROLE_NAME2) - token['access']['token']['bind'] = {'kerberos': self.KERBEROS_BIND} - self.TOKEN_RESPONSES[self.UUID_TOKEN_BIND] = token - - token = fixture.V2Token(token_id=self.UUID_TOKEN_UNKNOWN_BIND, - tenant_id=PROJECT_ID, - tenant_name=PROJECT_NAME, - user_id=USER_ID, - user_name=USER_NAME) - token.add_role(ROLE_NAME1) - token.add_role(ROLE_NAME2) - token['access']['token']['bind'] = {'FOO': 'BAR'} - self.TOKEN_RESPONSES[self.UUID_TOKEN_UNKNOWN_BIND] = token - - token = fixture.V2Token(token_id=self.UUID_SERVICE_TOKEN_DEFAULT, - tenant_id=SERVICE_PROJECT_ID, - tenant_name=SERVICE_PROJECT_NAME, - user_id=SERVICE_USER_ID, - user_name=SERVICE_USER_NAME) - token.add_role(name=SERVICE_ROLE_NAME1) - token.add_role(name=SERVICE_ROLE_NAME2) - svc = token.add_service(self.SERVICE_TYPE) - svc.add_endpoint(public=self.SERVICE_URL) - self.TOKEN_RESPONSES[self.UUID_SERVICE_TOKEN_DEFAULT] = token - - # Generated V3 Tokens - - token = fixture.V3Token(user_id=USER_ID, - user_name=USER_NAME, - user_domain_id=DOMAIN_ID, - user_domain_name=DOMAIN_NAME, - project_id=PROJECT_ID, - project_name=PROJECT_NAME, - project_domain_id=DOMAIN_ID, - project_domain_name=DOMAIN_NAME) - token.add_role(id=ROLE_NAME1, name=ROLE_NAME1) - token.add_role(id=ROLE_NAME2, name=ROLE_NAME2) - svc = token.add_service(self.SERVICE_TYPE) - svc.add_endpoint('public', self.SERVICE_URL) - self.TOKEN_RESPONSES[self.v3_UUID_TOKEN_DEFAULT] = token - - token = fixture.V3Token(user_id=USER_ID, - user_name=USER_NAME, - user_domain_id=DOMAIN_ID, - user_domain_name=DOMAIN_NAME) - self.TOKEN_RESPONSES[self.v3_UUID_TOKEN_UNSCOPED] = token - - token = fixture.V3Token(user_id=USER_ID, - user_name=USER_NAME, - user_domain_id=DOMAIN_ID, - user_domain_name=DOMAIN_NAME, - domain_id=DOMAIN_ID, - domain_name=DOMAIN_NAME) - token.add_role(id=ROLE_NAME1, name=ROLE_NAME1) - token.add_role(id=ROLE_NAME2, name=ROLE_NAME2) - svc = token.add_service(self.SERVICE_TYPE) - svc.add_endpoint('public', self.SERVICE_URL) - self.TOKEN_RESPONSES[self.v3_UUID_TOKEN_DOMAIN_SCOPED] = token - - token = fixture.V3Token(user_id=USER_ID, - user_name=USER_NAME, - user_domain_id=DOMAIN_ID, - user_domain_name=DOMAIN_NAME, - project_id=PROJECT_ID, - project_name=PROJECT_NAME, - project_domain_id=DOMAIN_ID, - project_domain_name=DOMAIN_NAME) - token.add_role(name=ROLE_NAME1) - token.add_role(name=ROLE_NAME2) - svc = token.add_service(self.SERVICE_TYPE) - svc.add_endpoint('public', self.SERVICE_URL) - self.TOKEN_RESPONSES[self.SIGNED_v3_TOKEN_SCOPED_KEY] = token - - token = fixture.V3Token(user_id=USER_ID, - user_name=USER_NAME, - user_domain_id=DOMAIN_ID, - user_domain_name=DOMAIN_NAME, - project_id=PROJECT_ID, - project_name=PROJECT_NAME, - project_domain_id=DOMAIN_ID, - project_domain_name=DOMAIN_NAME) - token.add_role(name=ROLE_NAME1) - token.add_role(name=ROLE_NAME2) - svc = token.add_service(self.SERVICE_TYPE) - svc.add_endpoint('public', self.SERVICE_URL) - token['token']['bind'] = {'kerberos': self.KERBEROS_BIND} - self.TOKEN_RESPONSES[self.v3_UUID_TOKEN_BIND] = token - - token = fixture.V3Token(user_id=USER_ID, - user_name=USER_NAME, - user_domain_id=DOMAIN_ID, - user_domain_name=DOMAIN_NAME, - project_id=PROJECT_ID, - project_name=PROJECT_NAME, - project_domain_id=DOMAIN_ID, - project_domain_name=DOMAIN_NAME) - token.add_role(name=ROLE_NAME1) - token.add_role(name=ROLE_NAME2) - svc = token.add_service(self.SERVICE_TYPE) - svc.add_endpoint('public', self.SERVICE_URL) - token['token']['bind'] = {'FOO': 'BAR'} - self.TOKEN_RESPONSES[self.v3_UUID_TOKEN_UNKNOWN_BIND] = token - - token = fixture.V3Token(user_id=SERVICE_USER_ID, - user_name=SERVICE_USER_NAME, - user_domain_id=SERVICE_DOMAIN_ID, - user_domain_name=SERVICE_DOMAIN_NAME, - project_id=SERVICE_PROJECT_ID, - project_name=SERVICE_PROJECT_NAME, - project_domain_id=SERVICE_DOMAIN_ID, - project_domain_name=SERVICE_DOMAIN_NAME) - token.add_role(id=SERVICE_ROLE_NAME1, - name=SERVICE_ROLE_NAME1) - token.add_role(id=SERVICE_ROLE_NAME2, - name=SERVICE_ROLE_NAME2) - svc = token.add_service(self.SERVICE_TYPE) - svc.add_endpoint('public', self.SERVICE_URL) - self.TOKEN_RESPONSES[self.v3_UUID_SERVICE_TOKEN_DEFAULT] = token - - # PKIZ tokens generally link to above tokens - - self.TOKEN_RESPONSES[self.SIGNED_TOKEN_SCOPED_PKIZ_KEY] = ( - self.TOKEN_RESPONSES[self.SIGNED_TOKEN_SCOPED_KEY]) - self.TOKEN_RESPONSES[self.SIGNED_TOKEN_UNSCOPED_PKIZ_KEY] = ( - self.TOKEN_RESPONSES[self.SIGNED_TOKEN_UNSCOPED_KEY]) - self.TOKEN_RESPONSES[self.SIGNED_v3_TOKEN_SCOPED_PKIZ_KEY] = ( - self.TOKEN_RESPONSES[self.SIGNED_v3_TOKEN_SCOPED_KEY]) - - self.JSON_TOKEN_RESPONSES = dict([(k, jsonutils.dumps(v)) for k, v in - six.iteritems(self.TOKEN_RESPONSES)]) - - -EXAMPLES_RESOURCE = testresources.FixtureResource(Examples()) diff --git a/keystonemiddleware-moon/keystonemiddleware/tests/unit/test_audit_middleware.py b/keystonemiddleware-moon/keystonemiddleware/tests/unit/test_audit_middleware.py deleted file mode 100644 index fc761c0f..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/tests/unit/test_audit_middleware.py +++ /dev/null @@ -1,560 +0,0 @@ -# -# 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. - -import os -import tempfile -import uuid -import warnings - -import mock -from oslo_config import cfg -from pycadf import identifier -from testtools import matchers -import webob - -from keystonemiddleware import audit -from keystonemiddleware.tests.unit import utils - - -class FakeApp(object): - def __call__(self, env, start_response): - body = 'Some response' - start_response('200 OK', [ - ('Content-Type', 'text/plain'), - ('Content-Length', str(sum(map(len, body)))) - ]) - return [body] - - -class FakeFailingApp(object): - def __call__(self, env, start_response): - raise Exception('It happens!') - - -class BaseAuditMiddlewareTest(utils.BaseTestCase): - def setUp(self): - super(BaseAuditMiddlewareTest, self).setUp() - self.fd, self.audit_map = tempfile.mkstemp() - - with open(self.audit_map, "w") as f: - f.write("[custom_actions]\n") - f.write("reboot = start/reboot\n") - f.write("os-migrations/get = read\n\n") - f.write("[path_keywords]\n") - f.write("action = None\n") - f.write("os-hosts = host\n") - f.write("os-migrations = None\n") - f.write("reboot = None\n") - f.write("servers = server\n\n") - f.write("[service_endpoints]\n") - f.write("compute = service/compute") - - cfg.CONF([], project='keystonemiddleware') - - self.middleware = audit.AuditMiddleware( - FakeApp(), audit_map_file=self.audit_map, - service_name='pycadf') - - # NOTE(stevemar): For this test suite and for the stable liberty branch - # only, we will ignore deprecated calls that keystonemiddleware makes. - warnings.filterwarnings('ignore', category=DeprecationWarning, - module='^keystonemiddleware\\.') - - self.addCleanup(lambda: os.close(self.fd)) - self.addCleanup(cfg.CONF.reset) - - @staticmethod - def get_environ_header(req_type): - env_headers = {'HTTP_X_SERVICE_CATALOG': - '''[{"endpoints_links": [], - "endpoints": [{"adminURL": - "http://admin_host:8774", - "region": "RegionOne", - "publicURL": - "http://public_host:8774", - "internalURL": - "http://internal_host:8774", - "id": "resource_id"}], - "type": "compute", - "name": "nova"},]''', - 'HTTP_X_USER_ID': 'user_id', - 'HTTP_X_USER_NAME': 'user_name', - 'HTTP_X_AUTH_TOKEN': 'token', - 'HTTP_X_PROJECT_ID': 'tenant_id', - 'HTTP_X_IDENTITY_STATUS': 'Confirmed'} - env_headers['REQUEST_METHOD'] = req_type - return env_headers - - -@mock.patch('oslo_messaging.get_transport', mock.MagicMock()) -class AuditMiddlewareTest(BaseAuditMiddlewareTest): - - def test_api_request(self): - req = webob.Request.blank('/foo/bar', - environ=self.get_environ_header('GET')) - with mock.patch('oslo_messaging.Notifier.info') as notify: - self.middleware(req) - # Check first notification with only 'request' - call_args = notify.call_args_list[0][0] - self.assertEqual('audit.http.request', call_args[1]) - self.assertEqual('/foo/bar', call_args[2]['requestPath']) - self.assertEqual('pending', call_args[2]['outcome']) - self.assertNotIn('reason', call_args[2]) - self.assertNotIn('reporterchain', call_args[2]) - - # Check second notification with request + response - call_args = notify.call_args_list[1][0] - self.assertEqual('audit.http.response', call_args[1]) - self.assertEqual('/foo/bar', call_args[2]['requestPath']) - self.assertEqual('success', call_args[2]['outcome']) - self.assertIn('reason', call_args[2]) - self.assertIn('reporterchain', call_args[2]) - - def test_api_request_failure(self): - self.middleware = audit.AuditMiddleware( - FakeFailingApp(), - audit_map_file=self.audit_map, - service_name='pycadf') - req = webob.Request.blank('/foo/bar', - environ=self.get_environ_header('GET')) - with mock.patch('oslo_messaging.Notifier.info') as notify: - try: - self.middleware(req) - self.fail('Application exception has not been re-raised') - except Exception: - pass - # Check first notification with only 'request' - call_args = notify.call_args_list[0][0] - self.assertEqual('audit.http.request', call_args[1]) - self.assertEqual('/foo/bar', call_args[2]['requestPath']) - self.assertEqual('pending', call_args[2]['outcome']) - self.assertNotIn('reporterchain', call_args[2]) - - # Check second notification with request + response - call_args = notify.call_args_list[1][0] - self.assertEqual('audit.http.response', call_args[1]) - self.assertEqual('/foo/bar', call_args[2]['requestPath']) - self.assertEqual('unknown', call_args[2]['outcome']) - self.assertIn('reporterchain', call_args[2]) - - def test_process_request_fail(self): - req = webob.Request.blank('/foo/bar', - environ=self.get_environ_header('GET')) - with mock.patch('oslo_messaging.Notifier.info', - side_effect=Exception('error')) as notify: - self.middleware._process_request(req) - self.assertTrue(notify.called) - - def test_process_response_fail(self): - req = webob.Request.blank('/foo/bar', - environ=self.get_environ_header('GET')) - with mock.patch('oslo_messaging.Notifier.info', - side_effect=Exception('error')) as notify: - self.middleware._process_response(req, webob.response.Response()) - self.assertTrue(notify.called) - - def test_ignore_req_opt(self): - self.middleware = audit.AuditMiddleware(FakeApp(), - audit_map_file=self.audit_map, - ignore_req_list='get, PUT') - req = webob.Request.blank('/skip/foo', - environ=self.get_environ_header('GET')) - req1 = webob.Request.blank('/skip/foo', - environ=self.get_environ_header('PUT')) - req2 = webob.Request.blank('/accept/foo', - environ=self.get_environ_header('POST')) - with mock.patch('oslo_messaging.Notifier.info') as notify: - # Check GET/PUT request does not send notification - self.middleware(req) - self.middleware(req1) - self.assertEqual([], notify.call_args_list) - - # Check non-GET/PUT request does send notification - self.middleware(req2) - self.assertThat(notify.call_args_list, matchers.HasLength(2)) - call_args = notify.call_args_list[0][0] - self.assertEqual('audit.http.request', call_args[1]) - self.assertEqual('/accept/foo', call_args[2]['requestPath']) - - call_args = notify.call_args_list[1][0] - self.assertEqual('audit.http.response', call_args[1]) - self.assertEqual('/accept/foo', call_args[2]['requestPath']) - - def test_api_request_no_messaging(self): - req = webob.Request.blank('/foo/bar', - environ=self.get_environ_header('GET')) - with mock.patch('keystonemiddleware.audit.messaging', None): - with mock.patch('keystonemiddleware.audit._LOG.info') as log: - self.middleware(req) - # Check first notification with only 'request' - call_args = log.call_args_list[0][0] - self.assertEqual('audit.http.request', - call_args[1]['event_type']) - - # Check second notification with request + response - call_args = log.call_args_list[1][0] - self.assertEqual('audit.http.response', - call_args[1]['event_type']) - - def test_cadf_event_scoped_to_request(self): - middleware = audit.AuditMiddleware( - FakeApp(), - audit_map_file=self.audit_map, - service_name='pycadf') - req = webob.Request.blank('/foo/bar', - environ=self.get_environ_header('GET')) - with mock.patch('oslo_messaging.Notifier.info') as notify: - middleware(req) - self.assertIsNotNone(req.environ.get('cadf_event')) - - # ensure exact same event is used between request and response - self.assertEqual(notify.call_args_list[0][0][2]['id'], - notify.call_args_list[1][0][2]['id']) - - def test_cadf_event_scoped_to_request_on_error(self): - middleware = audit.AuditMiddleware( - FakeApp(), - audit_map_file=self.audit_map, - service_name='pycadf') - req = webob.Request.blank('/foo/bar', - environ=self.get_environ_header('GET')) - with mock.patch('oslo_messaging.Notifier.info', - side_effect=Exception('error')) as notify: - middleware._process_request(req) - self.assertTrue(notify.called) - req2 = webob.Request.blank('/foo/bar', - environ=self.get_environ_header('GET')) - with mock.patch('oslo_messaging.Notifier.info') as notify: - middleware._process_response(req2, webob.response.Response()) - self.assertTrue(notify.called) - # ensure event is not the same across requests - self.assertNotEqual(req.environ['cadf_event'].id, - notify.call_args_list[0][0][2]['id']) - - -@mock.patch('oslo_messaging.rpc', mock.MagicMock()) -class AuditApiLogicTest(BaseAuditMiddlewareTest): - - def api_request(self, method, url): - req = webob.Request.blank(url, environ=self.get_environ_header(method), - remote_addr='192.168.0.1') - self.middleware._process_request(req) - return req - - def test_get_list(self): - req = self.api_request('GET', 'http://admin_host:8774/v2/' - + str(uuid.uuid4()) + '/servers') - payload = req.environ['cadf_event'].as_dict() - self.assertEqual(payload['action'], 'read/list') - self.assertEqual(payload['typeURI'], - 'http://schemas.dmtf.org/cloud/audit/1.0/event') - self.assertEqual(payload['outcome'], 'pending') - self.assertEqual(payload['eventType'], 'activity') - self.assertEqual(payload['target']['name'], 'nova') - self.assertEqual(payload['target']['id'], 'openstack:resource_id') - self.assertEqual(payload['target']['typeURI'], - 'service/compute/servers') - self.assertEqual(len(payload['target']['addresses']), 3) - self.assertEqual(payload['target']['addresses'][0]['name'], 'admin') - self.assertEqual(payload['target']['addresses'][0]['url'], - 'http://admin_host:8774') - self.assertEqual(payload['initiator']['id'], 'openstack:user_id') - self.assertEqual(payload['initiator']['name'], 'user_name') - self.assertEqual(payload['initiator']['project_id'], - 'openstack:tenant_id') - self.assertEqual(payload['initiator']['host']['address'], - '192.168.0.1') - self.assertEqual(payload['initiator']['typeURI'], - 'service/security/account/user') - self.assertNotEqual(payload['initiator']['credential']['token'], - 'token') - self.assertEqual(payload['initiator']['credential']['identity_status'], - 'Confirmed') - self.assertNotIn('reason', payload) - self.assertNotIn('reporterchain', payload) - self.assertEqual(payload['observer']['id'], 'target') - self.assertEqual(req.path, payload['requestPath']) - - def test_get_read(self): - req = self.api_request('GET', 'http://admin_host:8774/v2/' - + str(uuid.uuid4()) + '/servers/' - + str(uuid.uuid4())) - payload = req.environ['cadf_event'].as_dict() - self.assertEqual(payload['target']['typeURI'], - 'service/compute/servers/server') - self.assertEqual(payload['action'], 'read') - self.assertEqual(payload['outcome'], 'pending') - - def test_get_unknown_endpoint(self): - req = self.api_request('GET', 'http://unknown:8774/v2/' - + str(uuid.uuid4()) + '/servers') - payload = req.environ['cadf_event'].as_dict() - self.assertEqual(payload['action'], 'read/list') - self.assertEqual(payload['outcome'], 'pending') - self.assertEqual(payload['target']['name'], 'unknown') - self.assertEqual(payload['target']['id'], 'unknown') - self.assertEqual(payload['target']['typeURI'], 'unknown') - - def test_get_unknown_endpoint_default_set(self): - with open(self.audit_map, "w") as f: - f.write("[DEFAULT]\n") - f.write("target_endpoint_type = compute\n") - f.write("[path_keywords]\n") - f.write("servers = server\n\n") - f.write("[service_endpoints]\n") - f.write("compute = service/compute") - - self.middleware = audit.AuditMiddleware( - FakeApp(), audit_map_file=self.audit_map, - service_name='pycadf') - - req = self.api_request('GET', 'http://unknown:8774/v2/' - + str(uuid.uuid4()) + '/servers') - payload = req.environ['cadf_event'].as_dict() - self.assertEqual(payload['action'], 'read/list') - self.assertEqual(payload['outcome'], 'pending') - self.assertEqual(payload['target']['name'], 'nova') - self.assertEqual(payload['target']['id'], 'openstack:resource_id') - self.assertEqual(payload['target']['typeURI'], - 'service/compute/servers') - - def test_put(self): - req = self.api_request('PUT', 'http://admin_host:8774/v2/' - + str(uuid.uuid4()) + '/servers') - payload = req.environ['cadf_event'].as_dict() - self.assertEqual(payload['target']['typeURI'], - 'service/compute/servers') - self.assertEqual(payload['action'], 'update') - self.assertEqual(payload['outcome'], 'pending') - - def test_delete(self): - req = self.api_request('DELETE', 'http://admin_host:8774/v2/' - + str(uuid.uuid4()) + '/servers') - payload = req.environ['cadf_event'].as_dict() - self.assertEqual(payload['target']['typeURI'], - 'service/compute/servers') - self.assertEqual(payload['action'], 'delete') - self.assertEqual(payload['outcome'], 'pending') - - def test_head(self): - req = self.api_request('HEAD', 'http://admin_host:8774/v2/' - + str(uuid.uuid4()) + '/servers') - payload = req.environ['cadf_event'].as_dict() - self.assertEqual(payload['target']['typeURI'], - 'service/compute/servers') - self.assertEqual(payload['action'], 'read') - self.assertEqual(payload['outcome'], 'pending') - - def test_post_update(self): - req = self.api_request('POST', - 'http://admin_host:8774/v2/' - + str(uuid.uuid4()) + '/servers/' - + str(uuid.uuid4())) - payload = req.environ['cadf_event'].as_dict() - self.assertEqual(payload['target']['typeURI'], - 'service/compute/servers/server') - self.assertEqual(payload['action'], 'update') - self.assertEqual(payload['outcome'], 'pending') - - def test_post_create(self): - req = self.api_request('POST', 'http://admin_host:8774/v2/' - + str(uuid.uuid4()) + '/servers') - payload = req.environ['cadf_event'].as_dict() - self.assertEqual(payload['target']['typeURI'], - 'service/compute/servers') - self.assertEqual(payload['action'], 'create') - self.assertEqual(payload['outcome'], 'pending') - - def test_post_action(self): - req = webob.Request.blank('http://admin_host:8774/v2/' - + str(uuid.uuid4()) + '/servers/action', - environ=self.get_environ_header('POST')) - req.body = b'{"createImage" : {"name" : "new-image","metadata": ' \ - b'{"ImageType": "Gold","ImageVersion": "2.0"}}}' - self.middleware._process_request(req) - payload = req.environ['cadf_event'].as_dict() - self.assertEqual(payload['target']['typeURI'], - 'service/compute/servers/action') - self.assertEqual(payload['action'], 'update/createImage') - self.assertEqual(payload['outcome'], 'pending') - - def test_post_empty_body_action(self): - req = self.api_request('POST', 'http://admin_host:8774/v2/' - + str(uuid.uuid4()) + '/servers/action') - payload = req.environ['cadf_event'].as_dict() - self.assertEqual(payload['target']['typeURI'], - 'service/compute/servers/action') - self.assertEqual(payload['action'], 'create') - self.assertEqual(payload['outcome'], 'pending') - - def test_custom_action(self): - req = self.api_request('GET', 'http://admin_host:8774/v2/' - + str(uuid.uuid4()) + '/os-hosts/' - + str(uuid.uuid4()) + '/reboot') - payload = req.environ['cadf_event'].as_dict() - self.assertEqual(payload['target']['typeURI'], - 'service/compute/os-hosts/host/reboot') - self.assertEqual(payload['action'], 'start/reboot') - self.assertEqual(payload['outcome'], 'pending') - - def test_custom_action_complex(self): - req = self.api_request('GET', 'http://admin_host:8774/v2/' - + str(uuid.uuid4()) + '/os-migrations') - payload = req.environ['cadf_event'].as_dict() - self.assertEqual(payload['target']['typeURI'], - 'service/compute/os-migrations') - self.assertEqual(payload['action'], 'read') - req = self.api_request('POST', 'http://admin_host:8774/v2/' - + str(uuid.uuid4()) + '/os-migrations') - payload = req.environ['cadf_event'].as_dict() - self.assertEqual(payload['target']['typeURI'], - 'service/compute/os-migrations') - self.assertEqual(payload['action'], 'create') - - def test_response_mod_msg(self): - req = self.api_request('GET', 'http://admin_host:8774/v2/' - + str(uuid.uuid4()) + '/servers') - payload = req.environ['cadf_event'].as_dict() - self.middleware._process_response(req, webob.Response()) - payload2 = req.environ['cadf_event'].as_dict() - self.assertEqual(payload['id'], payload2['id']) - self.assertEqual(payload['tags'], payload2['tags']) - self.assertEqual(payload2['outcome'], 'success') - self.assertEqual(payload2['reason']['reasonType'], 'HTTP') - self.assertEqual(payload2['reason']['reasonCode'], '200') - self.assertEqual(len(payload2['reporterchain']), 1) - self.assertEqual(payload2['reporterchain'][0]['role'], 'modifier') - self.assertEqual(payload2['reporterchain'][0]['reporter']['id'], - 'target') - - def test_no_response(self): - req = self.api_request('GET', 'http://admin_host:8774/v2/' - + str(uuid.uuid4()) + '/servers') - payload = req.environ['cadf_event'].as_dict() - self.middleware._process_response(req, None) - payload2 = req.environ['cadf_event'].as_dict() - self.assertEqual(payload['id'], payload2['id']) - self.assertEqual(payload['tags'], payload2['tags']) - self.assertEqual(payload2['outcome'], 'unknown') - self.assertNotIn('reason', payload2) - self.assertEqual(len(payload2['reporterchain']), 1) - self.assertEqual(payload2['reporterchain'][0]['role'], 'modifier') - self.assertEqual(payload2['reporterchain'][0]['reporter']['id'], - 'target') - - def test_missing_req(self): - req = webob.Request.blank('http://admin_host:8774/v2/' - + str(uuid.uuid4()) + '/servers', - environ=self.get_environ_header('GET')) - self.assertNotIn('cadf_event', req.environ) - self.middleware._process_response(req, webob.Response()) - self.assertIn('cadf_event', req.environ) - payload = req.environ['cadf_event'].as_dict() - self.assertEqual(payload['outcome'], 'success') - self.assertEqual(payload['reason']['reasonType'], 'HTTP') - self.assertEqual(payload['reason']['reasonCode'], '200') - self.assertEqual(payload['observer']['id'], 'target') - - def test_missing_catalog_endpoint_id(self): - env_headers = {'HTTP_X_SERVICE_CATALOG': - '''[{"endpoints_links": [], - "endpoints": [{"adminURL": - "http://admin_host:8774", - "region": "RegionOne", - "publicURL": - "http://public_host:8774", - "internalURL": - "http://internal_host:8774"}], - "type": "compute", - "name": "nova"},]''', - 'HTTP_X_USER_ID': 'user_id', - 'HTTP_X_USER_NAME': 'user_name', - 'HTTP_X_AUTH_TOKEN': 'token', - 'HTTP_X_PROJECT_ID': 'tenant_id', - 'HTTP_X_IDENTITY_STATUS': 'Confirmed', - 'REQUEST_METHOD': 'GET'} - req = webob.Request.blank('http://admin_host:8774/v2/' - + str(uuid.uuid4()) + '/servers', - environ=env_headers) - self.middleware._process_request(req) - payload = req.environ['cadf_event'].as_dict() - self.assertEqual(payload['target']['id'], identifier.norm_ns('nova')) - - def test_endpoint_missing_internal_url(self): - env_headers = {'HTTP_X_SERVICE_CATALOG': - '''[{"endpoints_links": [], - "endpoints": [{"adminURL": - "http://admin_host:8774", - "region": "RegionOne", - "publicURL": - "http://public_host:8774"}], - "type": "compute", - "name": "nova"},]''', - 'HTTP_X_USER_ID': 'user_id', - 'HTTP_X_USER_NAME': 'user_name', - 'HTTP_X_AUTH_TOKEN': 'token', - 'HTTP_X_PROJECT_ID': 'tenant_id', - 'HTTP_X_IDENTITY_STATUS': 'Confirmed', - 'REQUEST_METHOD': 'GET'} - req = webob.Request.blank('http://admin_host:8774/v2/' - + str(uuid.uuid4()) + '/servers', - environ=env_headers) - self.middleware._process_request(req) - payload = req.environ['cadf_event'].as_dict() - self.assertEqual((payload['target']['addresses'][1]['url']), "unknown") - - def test_endpoint_missing_public_url(self): - env_headers = {'HTTP_X_SERVICE_CATALOG': - '''[{"endpoints_links": [], - "endpoints": [{"adminURL": - "http://admin_host:8774", - "region": "RegionOne", - "internalURL": - "http://internal_host:8774"}], - "type": "compute", - "name": "nova"},]''', - 'HTTP_X_USER_ID': 'user_id', - 'HTTP_X_USER_NAME': 'user_name', - 'HTTP_X_AUTH_TOKEN': 'token', - 'HTTP_X_PROJECT_ID': 'tenant_id', - 'HTTP_X_IDENTITY_STATUS': 'Confirmed', - 'REQUEST_METHOD': 'GET'} - req = webob.Request.blank('http://admin_host:8774/v2/' - + str(uuid.uuid4()) + '/servers', - environ=env_headers) - self.middleware._process_request(req) - payload = req.environ['cadf_event'].as_dict() - self.assertEqual((payload['target']['addresses'][2]['url']), "unknown") - - def test_endpoint_missing_admin_url(self): - env_headers = {'HTTP_X_SERVICE_CATALOG': - '''[{"endpoints_links": [], - "endpoints": [{"region": "RegionOne", - "publicURL": - "http://public_host:8774", - "internalURL": - "http://internal_host:8774"}], - "type": "compute", - "name": "nova"},]''', - 'HTTP_X_USER_ID': 'user_id', - 'HTTP_X_USER_NAME': 'user_name', - 'HTTP_X_AUTH_TOKEN': 'token', - 'HTTP_X_PROJECT_ID': 'tenant_id', - 'HTTP_X_IDENTITY_STATUS': 'Confirmed', - 'REQUEST_METHOD': 'GET'} - req = webob.Request.blank('http://public_host:8774/v2/' - + str(uuid.uuid4()) + '/servers', - environ=env_headers) - self.middleware._process_request(req) - payload = req.environ['cadf_event'].as_dict() - self.assertEqual((payload['target']['addresses'][0]['url']), "unknown") diff --git a/keystonemiddleware-moon/keystonemiddleware/tests/unit/test_opts.py b/keystonemiddleware-moon/keystonemiddleware/tests/unit/test_opts.py deleted file mode 100644 index 9ddb8005..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/tests/unit/test_opts.py +++ /dev/null @@ -1,86 +0,0 @@ -# Copyright (c) 2014 OpenStack Foundation. -# -# 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. - -import stevedore -from testtools import matchers - -from keystonemiddleware import opts -from keystonemiddleware.tests.unit import utils - - -class OptsTestCase(utils.TestCase): - - def _test_list_auth_token_opts(self, result): - self.assertThat(result, matchers.HasLength(1)) - - for group in (g for (g, _l) in result): - self.assertEqual('keystone_authtoken', group) - - expected_opt_names = [ - 'auth_admin_prefix', - 'auth_host', - 'auth_port', - 'auth_protocol', - 'auth_uri', - 'identity_uri', - 'auth_version', - 'delay_auth_decision', - 'http_connect_timeout', - 'http_request_max_retries', - 'admin_token', - 'admin_user', - 'admin_password', - 'admin_tenant_name', - 'cache', - 'certfile', - 'keyfile', - 'cafile', - 'region_name', - 'insecure', - 'signing_dir', - 'memcached_servers', - 'token_cache_time', - 'revocation_cache_time', - 'memcache_security_strategy', - 'memcache_secret_key', - 'memcache_use_advanced_pool', - 'memcache_pool_dead_retry', - 'memcache_pool_maxsize', - 'memcache_pool_unused_timeout', - 'memcache_pool_conn_get_timeout', - 'memcache_pool_socket_timeout', - 'include_service_catalog', - 'enforce_token_bind', - 'check_revocations_for_cached', - 'hash_algorithms' - ] - opt_names = [o.name for (g, l) in result for o in l] - self.assertThat(opt_names, matchers.HasLength(len(expected_opt_names))) - - for opt in opt_names: - self.assertIn(opt, expected_opt_names) - - def test_list_auth_token_opts(self): - self._test_list_auth_token_opts(opts.list_auth_token_opts()) - - def test_entry_point(self): - em = stevedore.ExtensionManager('oslo.config.opts', - invoke_on_load=True) - for extension in em: - if extension.name == 'keystonemiddleware.auth_token': - break - else: - self.fail('keystonemiddleware.auth_token not found') - - self._test_list_auth_token_opts(extension.obj) diff --git a/keystonemiddleware-moon/keystonemiddleware/tests/unit/test_s3_token_middleware.py b/keystonemiddleware-moon/keystonemiddleware/tests/unit/test_s3_token_middleware.py deleted file mode 100644 index b0993886..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/tests/unit/test_s3_token_middleware.py +++ /dev/null @@ -1,268 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# -# 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. - -import mock -from oslo_serialization import jsonutils -import requests -from requests_mock.contrib import fixture as rm_fixture -import six -from six.moves import urllib -import webob - -from keystonemiddleware import s3_token -from keystonemiddleware.tests.unit import utils - - -GOOD_RESPONSE = {'access': {'token': {'id': 'TOKEN_ID', - 'tenant': {'id': 'TENANT_ID'}}}} - - -class FakeApp(object): - """This represents a WSGI app protected by the auth_token middleware.""" - def __call__(self, env, start_response): - resp = webob.Response() - resp.environ = env - return resp(env, start_response) - - -class S3TokenMiddlewareTestBase(utils.TestCase): - - TEST_PROTOCOL = 'https' - TEST_HOST = 'fakehost' - TEST_PORT = 35357 - TEST_URL = '%s://%s:%d/v2.0/s3tokens' % (TEST_PROTOCOL, - TEST_HOST, - TEST_PORT) - - def setUp(self): - super(S3TokenMiddlewareTestBase, self).setUp() - - self.conf = { - 'auth_host': self.TEST_HOST, - 'auth_port': self.TEST_PORT, - 'auth_protocol': self.TEST_PROTOCOL, - } - - self.requests_mock = self.useFixture(rm_fixture.Fixture()) - - def start_fake_response(self, status, headers): - self.response_status = int(status.split(' ', 1)[0]) - self.response_headers = dict(headers) - - -class S3TokenMiddlewareTestGood(S3TokenMiddlewareTestBase): - - def setUp(self): - super(S3TokenMiddlewareTestGood, self).setUp() - self.middleware = s3_token.S3Token(FakeApp(), self.conf) - - self.requests_mock.post(self.TEST_URL, - status_code=201, - json=GOOD_RESPONSE) - - # Ignore the request and pass to the next middleware in the - # pipeline if no path has been specified. - def test_no_path_request(self): - req = webob.Request.blank('/') - self.middleware(req.environ, self.start_fake_response) - self.assertEqual(self.response_status, 200) - - # Ignore the request and pass to the next middleware in the - # pipeline if no Authorization header has been specified - def test_without_authorization(self): - req = webob.Request.blank('/v1/AUTH_cfa/c/o') - self.middleware(req.environ, self.start_fake_response) - self.assertEqual(self.response_status, 200) - - def test_without_auth_storage_token(self): - req = webob.Request.blank('/v1/AUTH_cfa/c/o') - req.headers['Authorization'] = 'badboy' - self.middleware(req.environ, self.start_fake_response) - self.assertEqual(self.response_status, 200) - - def test_authorized(self): - req = webob.Request.blank('/v1/AUTH_cfa/c/o') - req.headers['Authorization'] = 'access:signature' - req.headers['X-Storage-Token'] = 'token' - req.get_response(self.middleware) - self.assertTrue(req.path.startswith('/v1/AUTH_TENANT_ID')) - self.assertEqual(req.headers['X-Auth-Token'], 'TOKEN_ID') - - def test_authorized_http(self): - self.requests_mock.post(self.TEST_URL.replace('https', 'http'), - status_code=201, - json=GOOD_RESPONSE) - - self.middleware = ( - s3_token.filter_factory({'auth_protocol': 'http', - 'auth_host': self.TEST_HOST, - 'auth_port': self.TEST_PORT})(FakeApp())) - req = webob.Request.blank('/v1/AUTH_cfa/c/o') - req.headers['Authorization'] = 'access:signature' - req.headers['X-Storage-Token'] = 'token' - req.get_response(self.middleware) - self.assertTrue(req.path.startswith('/v1/AUTH_TENANT_ID')) - self.assertEqual(req.headers['X-Auth-Token'], 'TOKEN_ID') - - def test_authorization_nova_toconnect(self): - req = webob.Request.blank('/v1/AUTH_swiftint/c/o') - req.headers['Authorization'] = 'access:FORCED_TENANT_ID:signature' - req.headers['X-Storage-Token'] = 'token' - req.get_response(self.middleware) - path = req.environ['PATH_INFO'] - self.assertTrue(path.startswith('/v1/AUTH_FORCED_TENANT_ID')) - - @mock.patch.object(requests, 'post') - def test_insecure(self, MOCK_REQUEST): - self.middleware = ( - s3_token.filter_factory({'insecure': 'True'})(FakeApp())) - - text_return_value = jsonutils.dumps(GOOD_RESPONSE) - if six.PY3: - text_return_value = text_return_value.encode() - MOCK_REQUEST.return_value = utils.TestResponse({ - 'status_code': 201, - 'text': text_return_value}) - - req = webob.Request.blank('/v1/AUTH_cfa/c/o') - req.headers['Authorization'] = 'access:signature' - req.headers['X-Storage-Token'] = 'token' - req.get_response(self.middleware) - - self.assertTrue(MOCK_REQUEST.called) - mock_args, mock_kwargs = MOCK_REQUEST.call_args - self.assertIs(mock_kwargs['verify'], False) - - def test_insecure_option(self): - # insecure is passed as a string. - - # Some non-secure values. - true_values = ['true', 'True', '1', 'yes'] - for val in true_values: - config = {'insecure': val, 'certfile': 'false_ind'} - middleware = s3_token.filter_factory(config)(FakeApp()) - self.assertIs(False, middleware._verify) - - # Some "secure" values, including unexpected value. - false_values = ['false', 'False', '0', 'no', 'someweirdvalue'] - for val in false_values: - config = {'insecure': val, 'certfile': 'false_ind'} - middleware = s3_token.filter_factory(config)(FakeApp()) - self.assertEqual('false_ind', middleware._verify) - - # Default is secure. - config = {'certfile': 'false_ind'} - middleware = s3_token.filter_factory(config)(FakeApp()) - self.assertIs('false_ind', middleware._verify) - - def test_unicode_path(self): - url = u'/v1/AUTH_cfa/c/euro\u20ac'.encode('utf8') - req = webob.Request.blank(urllib.parse.quote(url)) - req.headers['Authorization'] = 'access:signature' - req.headers['X-Storage-Token'] = 'token' - req.get_response(self.middleware) - - -class S3TokenMiddlewareTestBad(S3TokenMiddlewareTestBase): - def setUp(self): - super(S3TokenMiddlewareTestBad, self).setUp() - self.middleware = s3_token.S3Token(FakeApp(), self.conf) - - def test_unauthorized_token(self): - ret = {"error": - {"message": "EC2 access key not found.", - "code": 401, - "title": "Unauthorized"}} - self.requests_mock.post(self.TEST_URL, status_code=403, json=ret) - req = webob.Request.blank('/v1/AUTH_cfa/c/o') - req.headers['Authorization'] = 'access:signature' - req.headers['X-Storage-Token'] = 'token' - resp = req.get_response(self.middleware) - s3_denied_req = self.middleware._deny_request('AccessDenied') - self.assertEqual(resp.body, s3_denied_req.body) - self.assertEqual(resp.status_int, s3_denied_req.status_int) - - def test_bogus_authorization(self): - req = webob.Request.blank('/v1/AUTH_cfa/c/o') - req.headers['Authorization'] = 'badboy' - req.headers['X-Storage-Token'] = 'token' - resp = req.get_response(self.middleware) - self.assertEqual(resp.status_int, 400) - s3_invalid_req = self.middleware._deny_request('InvalidURI') - self.assertEqual(resp.body, s3_invalid_req.body) - self.assertEqual(resp.status_int, s3_invalid_req.status_int) - - def test_fail_to_connect_to_keystone(self): - with mock.patch.object(self.middleware, '_json_request') as o: - s3_invalid_req = self.middleware._deny_request('InvalidURI') - o.side_effect = s3_token.ServiceError(s3_invalid_req) - - req = webob.Request.blank('/v1/AUTH_cfa/c/o') - req.headers['Authorization'] = 'access:signature' - req.headers['X-Storage-Token'] = 'token' - resp = req.get_response(self.middleware) - self.assertEqual(resp.body, s3_invalid_req.body) - self.assertEqual(resp.status_int, s3_invalid_req.status_int) - - def test_bad_reply(self): - self.requests_mock.post(self.TEST_URL, - status_code=201, - text="") - - req = webob.Request.blank('/v1/AUTH_cfa/c/o') - req.headers['Authorization'] = 'access:signature' - req.headers['X-Storage-Token'] = 'token' - resp = req.get_response(self.middleware) - s3_invalid_req = self.middleware._deny_request('InvalidURI') - self.assertEqual(resp.body, s3_invalid_req.body) - self.assertEqual(resp.status_int, s3_invalid_req.status_int) - - -class S3TokenMiddlewareTestUtil(utils.BaseTestCase): - def test_split_path_failed(self): - self.assertRaises(ValueError, s3_token._split_path, '') - self.assertRaises(ValueError, s3_token._split_path, '/') - self.assertRaises(ValueError, s3_token._split_path, '//') - self.assertRaises(ValueError, s3_token._split_path, '//a') - self.assertRaises(ValueError, s3_token._split_path, '/a/c') - self.assertRaises(ValueError, s3_token._split_path, '//c') - self.assertRaises(ValueError, s3_token._split_path, '/a/c/') - self.assertRaises(ValueError, s3_token._split_path, '/a//') - self.assertRaises(ValueError, s3_token._split_path, '/a', 2) - self.assertRaises(ValueError, s3_token._split_path, '/a', 2, 3) - self.assertRaises(ValueError, s3_token._split_path, '/a', 2, 3, True) - self.assertRaises(ValueError, s3_token._split_path, '/a/c/o/r', 3, 3) - self.assertRaises(ValueError, s3_token._split_path, '/a', 5, 4) - - def test_split_path_success(self): - self.assertEqual(s3_token._split_path('/a'), ['a']) - self.assertEqual(s3_token._split_path('/a/'), ['a']) - self.assertEqual(s3_token._split_path('/a/c', 2), ['a', 'c']) - self.assertEqual(s3_token._split_path('/a/c/o', 3), ['a', 'c', 'o']) - self.assertEqual(s3_token._split_path('/a/c/o/r', 3, 3, True), - ['a', 'c', 'o/r']) - self.assertEqual(s3_token._split_path('/a/c', 2, 3, True), - ['a', 'c', None]) - self.assertEqual(s3_token._split_path('/a/c/', 2), ['a', 'c']) - self.assertEqual(s3_token._split_path('/a/c/', 2, 3), ['a', 'c', '']) - - def test_split_path_invalid_path(self): - try: - s3_token._split_path('o\nn e', 2) - except ValueError as err: - self.assertEqual(str(err), 'Invalid path: o%0An%20e') - try: - s3_token._split_path('o\nn e', 2, 3, True) - except ValueError as err: - self.assertEqual(str(err), 'Invalid path: o%0An%20e') diff --git a/keystonemiddleware-moon/keystonemiddleware/tests/unit/utils.py b/keystonemiddleware-moon/keystonemiddleware/tests/unit/utils.py deleted file mode 100644 index 8c6c0e9a..00000000 --- a/keystonemiddleware-moon/keystonemiddleware/tests/unit/utils.py +++ /dev/null @@ -1,150 +0,0 @@ -# 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. - -import logging -import sys -import time -import warnings - -import fixtures -import mock -import oslotest.base as oslotest -import requests -import uuid - - -class BaseTestCase(oslotest.BaseTestCase): - def setUp(self): - super(BaseTestCase, self).setUp() - - # If keystonemiddleware calls any deprecated function this will raise - # an exception. - warnings.filterwarnings('error', category=DeprecationWarning, - module='^keystonemiddleware\\.') - self.addCleanup(warnings.resetwarnings) - - -class TestCase(BaseTestCase): - TEST_DOMAIN_ID = '1' - TEST_DOMAIN_NAME = 'aDomain' - TEST_GROUP_ID = uuid.uuid4().hex - TEST_ROLE_ID = uuid.uuid4().hex - TEST_TENANT_ID = '1' - TEST_TENANT_NAME = 'aTenant' - TEST_TOKEN = 'aToken' - TEST_TRUST_ID = 'aTrust' - TEST_USER = 'test' - TEST_USER_ID = uuid.uuid4().hex - - TEST_ROOT_URL = 'http://127.0.0.1:5000/' - - def setUp(self): - super(TestCase, self).setUp() - self.logger = self.useFixture(fixtures.FakeLogger(level=logging.DEBUG)) - self.time_patcher = mock.patch.object(time, 'time', lambda: 1234) - self.time_patcher.start() - - def tearDown(self): - self.time_patcher.stop() - super(TestCase, self).tearDown() - - -if tuple(sys.version_info)[0:2] < (2, 7): - - def assertDictEqual(self, d1, d2, msg=None): - # Simple version taken from 2.7 - self.assertIsInstance(d1, dict, - 'First argument is not a dictionary') - self.assertIsInstance(d2, dict, - 'Second argument is not a dictionary') - if d1 != d2: - if msg: - self.fail(msg) - else: - standardMsg = '%r != %r' % (d1, d2) - self.fail(standardMsg) - - TestCase.assertDictEqual = assertDictEqual - - -class TestResponse(requests.Response): - """Class used to wrap requests.Response and provide some - convenience to initialize with a dict. - """ - - def __init__(self, data): - self._text = None - super(TestResponse, self).__init__() - if isinstance(data, dict): - self.status_code = data.get('status_code', 200) - headers = data.get('headers') - if headers: - self.headers.update(headers) - # Fake the text attribute to streamline Response creation - # _content is defined by requests.Response - self._content = data.get('text') - else: - self.status_code = data - - def __eq__(self, other): - return self.__dict__ == other.__dict__ - - @property - def text(self): - return self.content - - -class DisableModuleFixture(fixtures.Fixture): - """A fixture to provide support for unloading/disabling modules.""" - - def __init__(self, module, *args, **kw): - super(DisableModuleFixture, self).__init__(*args, **kw) - self.module = module - self._finders = [] - self._cleared_modules = {} - - def tearDown(self): - super(DisableModuleFixture, self).tearDown() - for finder in self._finders: - sys.meta_path.remove(finder) - sys.modules.update(self._cleared_modules) - - def clear_module(self): - cleared_modules = {} - for fullname in list(sys.modules.keys()): - if (fullname == self.module or - fullname.startswith(self.module + '.')): - cleared_modules[fullname] = sys.modules.pop(fullname) - return cleared_modules - - def setUp(self): - """Ensure ImportError for the specified module.""" - - super(DisableModuleFixture, self).setUp() - - # Clear 'module' references in sys.modules - self._cleared_modules.update(self.clear_module()) - - finder = NoModuleFinder(self.module) - self._finders.append(finder) - sys.meta_path.insert(0, finder) - - -class NoModuleFinder(object): - """Disallow further imports of 'module'.""" - - def __init__(self, module): - self.module = module - - def find_module(self, fullname, path): - if fullname == self.module or fullname.startswith(self.module + '.'): - raise ImportError diff --git a/keystonemiddleware-moon/openstack-common.conf b/keystonemiddleware-moon/openstack-common.conf deleted file mode 100644 index abdd7b30..00000000 --- a/keystonemiddleware-moon/openstack-common.conf +++ /dev/null @@ -1,7 +0,0 @@ -[DEFAULT] - -# The list of modules to copy from oslo-incubator -module=memorycache - -# The base module to hold the copy of openstack.common -base=keystonemiddleware diff --git a/keystonemiddleware-moon/requirements.txt b/keystonemiddleware-moon/requirements.txt deleted file mode 100644 index 4d39b223..00000000 --- a/keystonemiddleware-moon/requirements.txt +++ /dev/null @@ -1,16 +0,0 @@ -# The order of packages is significant, because pip processes them in the order -# of appearance. Changing the order has an impact on the overall integration -# process, which may cause wedges in the gate later. - -Babel>=1.3 -oslo.config>=2.3.0 # Apache-2.0 -oslo.context>=0.2.0 # Apache-2.0 -oslo.i18n>=1.5.0 # Apache-2.0 -oslo.serialization>=1.4.0 # Apache-2.0 -oslo.utils!=2.6.0,>=2.0.0 # Apache-2.0 -pbr>=1.6 -pycadf>=1.1.0 -python-keystoneclient!=1.8.0,>=1.6.0 -requests!=2.8.0,!=2.9.0,>=2.5.2 -six>=1.9.0 -WebOb>=1.2.3 diff --git a/keystonemiddleware-moon/setup.cfg b/keystonemiddleware-moon/setup.cfg deleted file mode 100644 index 6893198b..00000000 --- a/keystonemiddleware-moon/setup.cfg +++ /dev/null @@ -1,57 +0,0 @@ -[metadata] -name = keystonemiddleware -summary = Middleware for OpenStack Identity -description-file = - README.rst -author = OpenStack -author-email = openstack-dev@lists.openstack.org -home-page = http://launchpad.net/keystonemiddleware -license = Apache-2.0 -classifier = - Environment :: OpenStack - Intended Audience :: Information Technology - 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 - Programming Language :: Python :: 3.4 - -[files] -packages = - keystonemiddleware - -[global] -setup-hooks = - pbr.hooks.setup_hook - -[entry_points] -oslo.config.opts = - keystonemiddleware.auth_token = keystonemiddleware.opts:list_auth_token_opts - -[build_sphinx] -source-dir = doc/source -build-dir = doc/build -all_files = 1 - -[upload_sphinx] -upload-dir = doc/build/html - -[compile_catalog] -directory = keystonemiddleware/locale -domain = keystonemiddleware - -[update_catalog] -domain = keystonemiddleware -output_dir = keystonemiddleware/locale -input_file = keystonemiddleware/locale/keystonemiddleware.pot - -[extract_messages] -keywords = _ gettext ngettext l_ lazy_gettext -mapping_file = babel.cfg -output_file = keystonemiddleware/locale/keystonemiddleware.pot - -[wheel] -universal = 1 diff --git a/keystonemiddleware-moon/setup.py b/keystonemiddleware-moon/setup.py deleted file mode 100644 index 782bb21f..00000000 --- a/keystonemiddleware-moon/setup.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. -# -# 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. - -# 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) diff --git a/keystonemiddleware-moon/test-requirements-py3.txt b/keystonemiddleware-moon/test-requirements-py3.txt deleted file mode 100644 index ff9e614c..00000000 --- a/keystonemiddleware-moon/test-requirements-py3.txt +++ /dev/null @@ -1,18 +0,0 @@ -# The order of packages is significant, because pip processes them in the order -# of appearance. Changing the order has an impact on the overall integration -# process, which may cause wedges in the gate later. - -coverage>=3.6 -discover -fixtures>=0.3.14 -hacking>=0.8.0,<0.9 -mock>=1.0 -pycrypto>=2.6 -oslosphinx>=2.2.0 # Apache-2.0 -oslotest>=1.2.0 # Apache-2.0 -oslo.messaging>=1.6.0 # Apache-2.0 -requests-mock>=0.5.1 # Apache-2.0 -sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3 -testrepository>=0.0.18 -testresources>=0.2.4 -testtools>=0.9.36,!=1.2.0 diff --git a/keystonemiddleware-moon/test-requirements.txt b/keystonemiddleware-moon/test-requirements.txt deleted file mode 100644 index 261a8ffc..00000000 --- a/keystonemiddleware-moon/test-requirements.txt +++ /dev/null @@ -1,24 +0,0 @@ -# The order of packages is significant, because pip processes them in the order -# of appearance. Changing the order has an impact on the overall integration -# process, which may cause wedges in the gate later. - -hacking<0.11,>=0.10.0 - -coverage>=3.6 -fixtures>=1.3.1 -mock>=1.2 -pycrypto>=2.6 -oslosphinx>=2.5.0 # Apache-2.0 -oslotest>=1.10.0 # Apache-2.0 -oslo.messaging!=1.17.0,!=1.17.1,!=2.6.0,!=2.6.1,!=2.7.0,!=2.8.0,!=2.8.1,!=2.9.0,!=3.1.0,>=1.16.0 # Apache-2.0 -requests-mock>=0.6.0 # Apache-2.0 -sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 -stevedore>=1.5.0 # Apache-2.0 -testrepository>=0.0.18 -testresources>=0.2.4 -testtools>=1.4.0 -python-memcached>=1.56 - -# Bandit security code scanner -bandit>=0.13.2 - diff --git a/keystonemiddleware-moon/tools/install_venv_common.py b/keystonemiddleware-moon/tools/install_venv_common.py deleted file mode 100644 index e279159a..00000000 --- a/keystonemiddleware-moon/tools/install_venv_common.py +++ /dev/null @@ -1,172 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# Copyright 2013 IBM Corp. -# -# 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. - -"""Provides methods needed by installation script for OpenStack development -virtual environments. - -Since this script is used to bootstrap a virtualenv from the system's Python -environment, it should be kept strictly compatible with Python 2.6. - -Synced in from openstack-common -""" - -from __future__ import print_function - -import optparse -import os -import subprocess -import sys - - -class InstallVenv(object): - - def __init__(self, root, venv, requirements, - test_requirements, py_version, - project): - self.root = root - self.venv = venv - self.requirements = requirements - self.test_requirements = test_requirements - self.py_version = py_version - self.project = project - - def die(self, message, *args): - print(message % args, file=sys.stderr) - sys.exit(1) - - def check_python_version(self): - if sys.version_info < (2, 6): - self.die("Need Python Version >= 2.6") - - def run_command_with_code(self, cmd, redirect_output=True, - check_exit_code=True): - """Runs a command in an out-of-process shell. - - Returns the output of that command. Working directory is self.root. - """ - if redirect_output: - stdout = subprocess.PIPE - else: - stdout = None - - proc = subprocess.Popen(cmd, cwd=self.root, stdout=stdout) - output = proc.communicate()[0] - if check_exit_code and proc.returncode != 0: - self.die('Command "%s" failed.\n%s', ' '.join(cmd), output) - return (output, proc.returncode) - - def run_command(self, cmd, redirect_output=True, check_exit_code=True): - return self.run_command_with_code(cmd, redirect_output, - check_exit_code)[0] - - def get_distro(self): - if (os.path.exists('/etc/fedora-release') or - os.path.exists('/etc/redhat-release')): - return Fedora( - self.root, self.venv, self.requirements, - self.test_requirements, self.py_version, self.project) - else: - return Distro( - self.root, self.venv, self.requirements, - self.test_requirements, self.py_version, self.project) - - def check_dependencies(self): - self.get_distro().install_virtualenv() - - def create_virtualenv(self, no_site_packages=True): - """Creates the virtual environment and installs PIP. - - Creates the virtual environment and installs PIP only into the - virtual environment. - """ - if not os.path.isdir(self.venv): - print('Creating venv...', end=' ') - if no_site_packages: - self.run_command(['virtualenv', '-q', '--no-site-packages', - self.venv]) - else: - self.run_command(['virtualenv', '-q', self.venv]) - print('done.') - else: - print("venv already exists...") - pass - - def pip_install(self, *args): - self.run_command(['tools/with_venv.sh', - 'pip', 'install', '--upgrade'] + list(args), - redirect_output=False) - - def install_dependencies(self): - print('Installing dependencies with pip (this can take a while)...') - - # First things first, make sure our venv has the latest pip and - # setuptools and pbr - self.pip_install('pip>=1.4') - self.pip_install('setuptools') - self.pip_install('pbr') - - self.pip_install('-r', self.requirements, '-r', self.test_requirements) - - def parse_args(self, argv): - """Parses command-line arguments.""" - parser = optparse.OptionParser() - parser.add_option('-n', '--no-site-packages', - action='store_true', - help="Do not inherit packages from global Python " - "install.") - return parser.parse_args(argv[1:])[0] - - -class Distro(InstallVenv): - - def check_cmd(self, cmd): - return bool(self.run_command(['which', cmd], - check_exit_code=False).strip()) - - def install_virtualenv(self): - if self.check_cmd('virtualenv'): - return - - if self.check_cmd('easy_install'): - print('Installing virtualenv via easy_install...', end=' ') - if self.run_command(['easy_install', 'virtualenv']): - print('Succeeded') - return - else: - print('Failed') - - self.die('ERROR: virtualenv not found.\n\n%s development' - ' requires virtualenv, please install it using your' - ' favorite package management tool' % self.project) - - -class Fedora(Distro): - """This covers all Fedora-based distributions. - - Includes: Fedora, RHEL, CentOS, Scientific Linux - """ - - def check_pkg(self, pkg): - return self.run_command_with_code(['rpm', '-q', pkg], - check_exit_code=False)[1] == 0 - - def install_virtualenv(self): - if self.check_cmd('virtualenv'): - return - - if not self.check_pkg('python-virtualenv'): - self.die("Please install 'python-virtualenv'.") - - super(Fedora, self).install_virtualenv() diff --git a/keystonemiddleware-moon/tox.ini b/keystonemiddleware-moon/tox.ini deleted file mode 100644 index 790bf027..00000000 --- a/keystonemiddleware-moon/tox.ini +++ /dev/null @@ -1,50 +0,0 @@ -[tox] -minversion = 1.6 -skipsdist = True -envlist = py26,py27,py34,pep8 - -[testenv] -usedevelop = True -install_command = pip install -U {opts} {packages} -setenv = VIRTUAL_ENV={envdir} - OS_STDOUT_NOCAPTURE=False - OS_STDERR_NOCAPTURE=False - -deps = -r{toxinidir}/requirements.txt - -r{toxinidir}/test-requirements.txt -commands = python setup.py testr --testr-args='{posargs}' - -[testenv:pep8] -commands = - flake8 - -[testenv:venv] -commands = {posargs} - -[testenv:cover] -commands = python setup.py testr --coverage --testr-args='{posargs}' - -[tox:jenkins] -downloadcache = ~/cache/pip - -[testenv:debug] - -commands = oslo_debug_helper {posargs} - -[testenv:bandit] -deps = -r{toxinidir}/test-requirements.txt -commands = bandit -c bandit.yaml -r keystonemiddleware -n5 -p keystone_conservative - -[flake8] -# H405: multi line docstring summary not separated with an empty line -ignore = H405 -show-source = True -exclude = .venv,.tox,dist,doc,*egg,build,*openstack/common* - -[testenv:docs] -commands= - python setup.py build_sphinx - -[hacking] -import_exceptions = - keystonemiddleware.i18n diff --git a/kubernetes/README.md b/kubernetes/README.md new file mode 100644 index 00000000..04d54924 --- /dev/null +++ b/kubernetes/README.md @@ -0,0 +1,50 @@ + +# Installation + +Choose the right deployment: + +## Minikube installation + +```bash +curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl +chmod +x ./kubectl +sudo mv ./kubectl /usr/local/bin/kubectl +curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.21.0/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/ +``` + +## Kubeadm installation + +see: https://kubernetes.io/docs/setup/independent/install-kubeadm/ + +```bash +apt-get update && apt-get install -y apt-transport-https +curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - +cat </etc/apt/sources.list.d/kubernetes.list +deb http://apt.kubernetes.io/ kubernetes-xenial main +EOF +apt-get update +apt-get install -y kubelet kubeadm kubectl +``` + +# Platform + +## Creation + +Execute the script : init_k8s.sh + +```bash +sudo bash init_k8s.sh +watch kubectl get po --namespace=kube-system +``` + +Wait until all pods are in "Running" state (crtl-c to stop the watch command) + +## Execution + +Execute the script : start_moon.sh + +```bash +sudo bash start_moon.sh +watch kubectl get po --namespace=moon +``` + diff --git a/kubernetes/conf/password_moon.txt b/kubernetes/conf/password_moon.txt new file mode 100644 index 00000000..bb9bcf7d --- /dev/null +++ b/kubernetes/conf/password_moon.txt @@ -0,0 +1 @@ +p4sswOrd1 \ No newline at end of file diff --git a/kubernetes/conf/password_root.txt b/kubernetes/conf/password_root.txt new file mode 100644 index 00000000..bb9bcf7d --- /dev/null +++ b/kubernetes/conf/password_root.txt @@ -0,0 +1 @@ +p4sswOrd1 \ No newline at end of file diff --git a/kubernetes/conf/ports.conf b/kubernetes/conf/ports.conf new file mode 100644 index 00000000..487945c0 --- /dev/null +++ b/kubernetes/conf/ports.conf @@ -0,0 +1,24 @@ +manager: + port: 8082 + kport: 30001 +gui: + port: 3000 + kport: 30002 +orchestrator: + port: 8083 + kport: 30003 + +consul: + port: 8500 + kport: 30005 +keystone: + port: 5000 + kport: 30006 + +wrapper: + port: 8080 + kport: 30010 +interface: + port: 8080 +authz: + port: 8081 diff --git a/kubernetes/init_k8s.sh b/kubernetes/init_k8s.sh new file mode 100644 index 00000000..6eb94e78 --- /dev/null +++ b/kubernetes/init_k8s.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +set -x + +sudo kubeadm reset + +sudo swapoff -a + +sudo kubeadm init --pod-network-cidr=192.168.0.0/16 +#sudo kubeadm init --pod-network-cidr=10.244.0.0/16 + +mkdir -p $HOME/.kube +sudo cp -f /etc/kubernetes/admin.conf $HOME/.kube/config +sudo chown $(id -u):$(id -g) $HOME/.kube/config + +kubectl apply -f http://docs.projectcalico.org/v2.4/getting-started/kubernetes/installation/hosted/kubeadm/1.6/calico.yaml +#kubectl apply -f https://raw.githubusercontent.com/projectcalico/canal/master/k8s-install/1.6/rbac.yaml +#kubectl apply -f https://raw.githubusercontent.com/projectcalico/canal/master/k8s-install/1.6/canal.yaml + +#kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml + +kubectl delete deployment kube-dns --namespace=kube-system +kubectl apply -f kubernetes/templates/kube-dns.yaml + +kubectl taint nodes --all node-role.kubernetes.io/master- + +kubectl proxy& +sleep 5 +echo ========================================= +kubectl get po --namespace=kube-system +echo ========================================= + + diff --git a/kubernetes/start_moon.sh b/kubernetes/start_moon.sh new file mode 100644 index 00000000..8121e319 --- /dev/null +++ b/kubernetes/start_moon.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +set -x + +kubectl create namespace moon +kubectl create configmap moon-config --from-file conf/moon.conf -n moon +kubectl create configmap config --from-file ~/.kube/config -n moon +kubectl create secret generic mysql-root-pass --from-file=kubernetes/conf/password_root.txt -n moon +kubectl create secret generic mysql-pass --from-file=kubernetes/conf/password_moon.txt -n moon + +kubectl create -n moon -f kubernetes/templates/consul.yaml +kubectl create -n moon -f kubernetes/templates/db.yaml +kubectl create -n moon -f kubernetes/templates/keystone.yaml + +echo ========================================= +kubectl get pods -n moon +echo ========================================= + +sleep 10 +kubectl create -n moon -f kubernetes/templates/moon_configuration.yaml + +echo Waiting for jobs moonforming +sleep 5 +kubectl get jobs -n moon +kubectl logs -n moon jobs/moonforming + +sleep 5 + +kubectl create -n moon -f kubernetes/templates/moon_manager.yaml + +sleep 2 + +kubectl create -n moon -f kubernetes/templates/moon_orchestrator.yaml + +kubectl create -n moon -f kubernetes/templates/moon_gui.yaml + + diff --git a/kubernetes/templates/consul.yaml b/kubernetes/templates/consul.yaml new file mode 100644 index 00000000..f0fb764e --- /dev/null +++ b/kubernetes/templates/consul.yaml @@ -0,0 +1,33 @@ +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + namespace: moon + name: consul +spec: + replicas: 1 + template: + metadata: + labels: + app: consul + spec: + hostname: consul + containers: + - name: consul + image: consul:latest + ports: + - containerPort: 8500 +--- + +apiVersion: v1 +kind: Service +metadata: + name: consul + namespace: moon +spec: + ports: + - port: 8500 + targetPort: 8500 + nodePort: 30005 + selector: + app: consul + type: NodePort diff --git a/kubernetes/templates/db.yaml b/kubernetes/templates/db.yaml new file mode 100644 index 00000000..38418643 --- /dev/null +++ b/kubernetes/templates/db.yaml @@ -0,0 +1,84 @@ +#apiVersion: v1 +#kind: PersistentVolume +#metadata: +# name: local-pv-1 +# labels: +# type: local +#spec: +# capacity: +# storage: 5Gi +# accessModes: +# - ReadWriteOnce +# hostPath: +# path: /tmp/data/pv-1 +#--- +# +#apiVersion: v1 +#kind: PersistentVolumeClaim +#metadata: +# name: mysql-pv-claim +# labels: +# platform: moon +# app: db +#spec: +# accessModes: +# - ReadWriteOnce +# resources: +# requests: +# storage: 5Gi +#--- + +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + namespace: moon + name: db +spec: + replicas: 1 + strategy: + type: Recreate + template: + metadata: + labels: + app: db + spec: + containers: + - name: db + image: mysql:latest + env: + - name: MYSQL_DATABASE + value: "moon" + - name: MYSQL_USER + value: "moon" + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + name: mysql-pass + key: password_moon.txt + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: mysql-root-pass + key: password_root.txt + ports: + - containerPort: 3306 + name: mysql +# volumeMounts: +# - name: mysql-persistent-storage +# mountPath: /var/lib/mysql +# volumes: +# - name: mysql-persistent-storage +# persistentVolumeClaim: +# claimName: mysql-pv-claim +--- +apiVersion: v1 +kind: Service +metadata: + namespace: moon + name: db +spec: + ports: + - port: 3306 + selector: + app: db +--- \ No newline at end of file diff --git a/kubernetes/templates/keystone.yaml b/kubernetes/templates/keystone.yaml new file mode 100644 index 00000000..e4218e4c --- /dev/null +++ b/kubernetes/templates/keystone.yaml @@ -0,0 +1,39 @@ +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + namespace: moon + name: keystone +spec: + replicas: 1 + template: + metadata: + labels: + app: keystone + spec: + hostname: keystone + containers: + - name: keystone + image: asteroide/keystone:pike-cors + env: + - name: KEYSTONE_HOSTNAME + value: "127.0.0.1" + - name: KEYSTONE_PORT + value: "30006" + ports: + - containerPort: 35357 + containerPort: 5000 +--- + +apiVersion: v1 +kind: Service +metadata: + name: keystone + namespace: moon +spec: + ports: + - port: 5000 + targetPort: 5000 + nodePort: 30006 + selector: + app: keystone + type: NodePort diff --git a/kubernetes/templates/kube-dns.yaml b/kubernetes/templates/kube-dns.yaml new file mode 100644 index 00000000..c8f18fd8 --- /dev/null +++ b/kubernetes/templates/kube-dns.yaml @@ -0,0 +1,183 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "2" + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"extensions/v1beta1","kind":"Deployment","metadata":{"annotations":{"deployment.kubernetes.io/revision":"1"},"creationTimestamp":"2017-10-30T09:03:59Z","generation":1,"labels":{"k8s-app":"kube-dns"},"name":"kube-dns","namespace":"kube-system","resourceVersion":"556","selfLink":"/apis/extensions/v1beta1/namespaces/kube-system/deployments/kube-dns","uid":"4433b709-bd51-11e7-a055-80fa5b15034a"},"spec":{"replicas":1,"selector":{"matchLabels":{"k8s-app":"kube-dns"}},"strategy":{"rollingUpdate":{"maxSurge":"10%","maxUnavailable":0},"type":"RollingUpdate"},"template":{"metadata":{"creationTimestamp":null,"labels":{"k8s-app":"kube-dns"}},"spec":{"affinity":{"nodeAffinity":{"requiredDuringSchedulingIgnoredDuringExecution":{"nodeSelectorTerms":[{"matchExpressions":[{"key":"beta.kubernetes.io/arch","operator":"In","values":["amd64"]}]}]}}},"containers":[{"args":["--domain=cluster.local.","--dns-port=10053","--config-dir=/kube-dns-config","--v=2"],"env":[{"name":"PROMETHEUS_PORT","value":"10055"}],"image":"gcr.io/google_containers/k8s-dns-kube-dns-amd64:1.14.5","imagePullPolicy":"IfNotPresent","livenessProbe":{"failureThreshold":5,"httpGet":{"path":"/healthcheck/kubedns","port":10054,"scheme":"HTTP"},"initialDelaySeconds":60,"periodSeconds":10,"successThreshold":1,"timeoutSeconds":5},"name":"kubedns","ports":[{"containerPort":10053,"name":"dns-local","protocol":"UDP"},{"containerPort":10053,"name":"dns-tcp-local","protocol":"TCP"},{"containerPort":10055,"name":"metrics","protocol":"TCP"}],"readinessProbe":{"failureThreshold":3,"httpGet":{"path":"/readiness","port":8081,"scheme":"HTTP"},"initialDelaySeconds":3,"periodSeconds":10,"successThreshold":1,"timeoutSeconds":5},"resources":{"limits":{"memory":"170Mi"},"requests":{"cpu":"100m","memory":"70Mi"}},"terminationMessagePath":"/dev/termination-log","terminationMessagePolicy":"File","volumeMounts":[{"mountPath":"/kube-dns-config","name":"kube-dns-config"}]},{"args":["-v=2","-logtostderr","-configDir=/etc/k8s/dns/dnsmasq-nanny","-restartDnsmasq=true","--","-k","--cache-size=1000","--log-facility=-","--server=/cluster.local/127.0.0.1#10053","--server=/in-addr.arpa/127.0.0.1#10053","--server=/ip6.arpa/127.0.0.1#10053","--server=8.8.8.8"],"image":"gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64:1.14.5","imagePullPolicy":"IfNotPresent","livenessProbe":{"failureThreshold":5,"httpGet":{"path":"/healthcheck/dnsmasq","port":10054,"scheme":"HTTP"},"initialDelaySeconds":60,"periodSeconds":10,"successThreshold":1,"timeoutSeconds":5},"name":"dnsmasq","ports":[{"containerPort":53,"name":"dns","protocol":"UDP"},{"containerPort":53,"name":"dns-tcp","protocol":"TCP"}],"resources":{"requests":{"cpu":"150m","memory":"20Mi"}},"terminationMessagePath":"/dev/termination-log","terminationMessagePolicy":"File","volumeMounts":[{"mountPath":"/etc/k8s/dns/dnsmasq-nanny","name":"kube-dns-config"}]},{"args":["--v=2","--logtostderr","--probe=kubedns,127.0.0.1:10053,kubernetes.default.svc.cluster.local,5,A","--probe=dnsmasq,127.0.0.1:53,kubernetes.default.svc.cluster.local,5,A"],"image":"gcr.io/google_containers/k8s-dns-sidecar-amd64:1.14.5","imagePullPolicy":"IfNotPresent","livenessProbe":{"failureThreshold":5,"httpGet":{"path":"/metrics","port":10054,"scheme":"HTTP"},"initialDelaySeconds":60,"periodSeconds":10,"successThreshold":1,"timeoutSeconds":5},"name":"sidecar","ports":[{"containerPort":10054,"name":"metrics","protocol":"TCP"}],"resources":{"requests":{"cpu":"10m","memory":"20Mi"}},"terminationMessagePath":"/dev/termination-log","terminationMessagePolicy":"File"}],"dnsPolicy":"Default","restartPolicy":"Always","schedulerName":"default-scheduler","securityContext":{},"serviceAccount":"kube-dns","serviceAccountName":"kube-dns","terminationGracePeriodSeconds":30,"tolerations":[{"key":"CriticalAddonsOnly","operator":"Exists"},{"effect":"NoSchedule","key":"node-role.kubernetes.io/master"}],"volumes":[{"configMap":{"defaultMode":420,"name":"kube-dns","optional":true},"name":"kube-dns-config"}]}}},"status":{"availableReplicas":1,"conditions":[{"lastTransitionTime":"2017-10-30T09:05:11Z","lastUpdateTime":"2017-10-30T09:05:11Z","message":"Deployment has minimum availability.","reason":"MinimumReplicasAvailable","status":"True","type":"Available"}],"observedGeneration":1,"readyReplicas":1,"replicas":1,"updatedReplicas":1}} + creationTimestamp: 2017-10-30T09:03:59Z + generation: 2 + labels: + k8s-app: kube-dns + name: kube-dns + namespace: kube-system + resourceVersion: "300076" + selfLink: /apis/extensions/v1beta1/namespaces/kube-system/deployments/kube-dns + uid: 4433b709-bd51-11e7-a055-80fa5b15034a +spec: + replicas: 1 + selector: + matchLabels: + k8s-app: kube-dns + strategy: + rollingUpdate: + maxSurge: 10% + maxUnavailable: 0 + type: RollingUpdate + template: + metadata: + creationTimestamp: null + labels: + k8s-app: kube-dns + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: beta.kubernetes.io/arch + operator: In + values: + - amd64 + containers: + - args: + - --domain=cluster.local. + - --dns-port=10053 + - --config-dir=/kube-dns-config + - --v=2 + env: + - name: PROMETHEUS_PORT + value: "10055" + image: gcr.io/google_containers/k8s-dns-kube-dns-amd64:1.14.5 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthcheck/kubedns + port: 10054 + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + name: kubedns + ports: + - containerPort: 10053 + name: dns-local + protocol: UDP + - containerPort: 10053 + name: dns-tcp-local + protocol: TCP + - containerPort: 10055 + name: metrics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /readiness + port: 8081 + scheme: HTTP + initialDelaySeconds: 3 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + resources: + limits: + memory: 340Mi + requests: + cpu: 200m + memory: 140Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /kube-dns-config + name: kube-dns-config + - args: + - -v=2 + - -logtostderr + - -configDir=/etc/k8s/dns/dnsmasq-nanny + - -restartDnsmasq=true + - -- + - -k + - --dns-forward-max=300 + - --cache-size=1000 + - --log-facility=- + - --server=/cluster.local/127.0.0.1#10053 + - --server=/in-addr.arpa/127.0.0.1#10053 + - --server=/ip6.arpa/127.0.0.1#10053 + - --server=8.8.8.8 + image: gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64:1.14.5 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthcheck/dnsmasq + port: 10054 + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + name: dnsmasq + ports: + - containerPort: 53 + name: dns + protocol: UDP + - containerPort: 53 + name: dns-tcp + protocol: TCP + resources: + requests: + cpu: 150m + memory: 20Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /etc/k8s/dns/dnsmasq-nanny + name: kube-dns-config + - args: + - --v=2 + - --logtostderr + - --probe=kubedns,127.0.0.1:10053,kubernetes.default.svc.cluster.local,5,A + - --probe=dnsmasq,127.0.0.1:53,kubernetes.default.svc.cluster.local,5,A + image: gcr.io/google_containers/k8s-dns-sidecar-amd64:1.14.5 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 5 + httpGet: + path: /metrics + port: 10054 + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + name: sidecar + ports: + - containerPort: 10054 + name: metrics + protocol: TCP + resources: + requests: + cpu: 10m + memory: 20Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: Default + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + serviceAccount: kube-dns + serviceAccountName: kube-dns + terminationGracePeriodSeconds: 30 + tolerations: + - key: CriticalAddonsOnly + operator: Exists + - effect: NoSchedule + key: node-role.kubernetes.io/master + volumes: + - configMap: + defaultMode: 420 + name: kube-dns + optional: true + name: kube-dns-config diff --git a/kubernetes/templates/moon_configuration.yaml b/kubernetes/templates/moon_configuration.yaml new file mode 100644 index 00000000..3bcaa533 --- /dev/null +++ b/kubernetes/templates/moon_configuration.yaml @@ -0,0 +1,25 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: moonforming + namespace: moon +spec: + template: + metadata: + name: moonforming + spec: + containers: + - name: moonforming + image: asteroide/moonforming:v1.3 + env: + - name: POPULATE_ARGS + value: "--verbose" # debug mode: --debug + volumeMounts: + - name: config-volume + mountPath: /etc/moon + volumes: + - name: config-volume + configMap: + name: moon-config + restartPolicy: Never + #backoffLimit: 4 \ No newline at end of file diff --git a/kubernetes/templates/moon_gui.yaml b/kubernetes/templates/moon_gui.yaml new file mode 100644 index 00000000..2d355216 --- /dev/null +++ b/kubernetes/templates/moon_gui.yaml @@ -0,0 +1,42 @@ +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + namespace: moon + name: gui +spec: + replicas: 1 + template: + metadata: + labels: + app: gui + spec: + hostname: gui + containers: + - name: gui + image: wukongsun/moon_gui:v4.3.1 + env: + - name: MANAGER_HOST + value: "127.0.0.1" + - name: MANAGER_PORT + value: "30001" + - name: KEYSTONE_HOST + value: "127.0.0.1" + - name: KEYSTONE_PORT + value: "30006" + ports: + - containerPort: 80 +--- + +apiVersion: v1 +kind: Service +metadata: + name: gui + namespace: moon +spec: + ports: + - port: 80 + targetPort: 80 + nodePort: 30002 + selector: + app: gui + type: NodePort diff --git a/kubernetes/templates/moon_manager.yaml b/kubernetes/templates/moon_manager.yaml new file mode 100644 index 00000000..9d4a09a8 --- /dev/null +++ b/kubernetes/templates/moon_manager.yaml @@ -0,0 +1,33 @@ +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: manager + namespace: moon +spec: + replicas: 3 + template: + metadata: + labels: + app: manager + spec: + hostname: manager + containers: + - name: manager + image: wukongsun/moon_manager:v4.3.1 + ports: + - containerPort: 8082 +--- + +apiVersion: v1 +kind: Service +metadata: + name: manager + namespace: moon +spec: + ports: + - port: 8082 + targetPort: 8082 + nodePort: 30001 + selector: + app: manager + type: NodePort diff --git a/kubernetes/templates/moon_orchestrator.yaml b/kubernetes/templates/moon_orchestrator.yaml new file mode 100644 index 00000000..419f2d52 --- /dev/null +++ b/kubernetes/templates/moon_orchestrator.yaml @@ -0,0 +1,40 @@ +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + namespace: moon + name: orchestrator +spec: + replicas: 1 + template: + metadata: + labels: + app: orchestrator + spec: + hostname: orchestrator + containers: + - name: orchestrator + image: wukongsun/moon_orchestrator:v4.3 + ports: + - containerPort: 8083 + volumeMounts: + - name: config-volume + mountPath: /root/.kube + volumes: + - name: config-volume + configMap: + name: config +--- + +apiVersion: v1 +kind: Service +metadata: + name: orchestrator + namespace: moon +spec: + ports: + - port: 8083 + targetPort: 8083 + nodePort: 30003 + selector: + app: orchestrator + type: NodePort diff --git a/moon_authz/Dockerfile b/moon_authz/Dockerfile new file mode 100644 index 00000000..7ab172b0 --- /dev/null +++ b/moon_authz/Dockerfile @@ -0,0 +1,12 @@ +FROM ubuntu:latest + +RUN apt update && apt install python3.5 python3-pip -y +RUN pip3 install pip --upgrade + +ADD . /root +WORKDIR /root/ +RUN pip3 install -r requirements.txt --upgrade +RUN pip3 install /root/dist/* --upgrade +RUN pip3 install . + +CMD ["python3", "-m", "moon_authz"] \ No newline at end of file diff --git a/moon_authz/LICENSE b/moon_authz/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/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/moon_authz/MANIFEST.in b/moon_authz/MANIFEST.in new file mode 100644 index 00000000..1f674d50 --- /dev/null +++ b/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/moon_authz/README.rst b/moon_authz/README.rst new file mode 100644 index 00000000..ded4e99a --- /dev/null +++ b/moon_authz/README.rst @@ -0,0 +1,9 @@ +Core module for the Moon project +================================ + +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/moon_authz/moon_authz/__init__.py b/moon_authz/moon_authz/__init__.py new file mode 100644 index 00000000..903c6518 --- /dev/null +++ b/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__ = "0.1.0" diff --git a/moon_authz/moon_authz/__main__.py b/moon_authz/moon_authz/__main__.py new file mode 100644 index 00000000..699c008c --- /dev/null +++ b/moon_authz/moon_authz/__main__.py @@ -0,0 +1,4 @@ +from moon_authz.server import main + +server = main() +server.run() diff --git a/moon_authz/moon_authz/api/__init__.py b/moon_authz/moon_authz/api/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/moon_authz/moon_authz/api/authorization.py b/moon_authz/moon_authz/api/authorization.py new file mode 100644 index 00000000..4cd8de06 --- /dev/null +++ b/moon_authz/moon_authz/api/authorization.py @@ -0,0 +1,376 @@ +# 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 binascii +import itertools +import pickle +from uuid import uuid4 +import logging +from python_moonutilities import exceptions +import flask +from flask import request +from flask_restful import Resource + +# TODO (asteroide): +# - end the dev of the context +# - rebuild the authorization function according to the context +# - call the next security function +# - call the master if an element is absent + +LOG = logging.getLogger("moon.api." + __name__) + + +class Authz(Resource): + """ + Endpoint for authz requests + """ + + __urls__ = ( + "/authz", + "/authz/", + "/authz////", + ) + __version__ = "0.1.0" + 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, uuid=None, subject_name=None, object_name=None, action_name=None): + """Get a response on an authorization request + + :param uuid: uuid of a tenant or an intra_extension + :param subject_name: name of the subject or the request + :param object_name: name of the object + :param action_name: name of the action + :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.run() + self.context.delete_cache() + response = flask.make_response(pickle.dumps(self.context)) + response.headers['content-type'] = 'application/octet-stream' + return response + + def run(self): + LOG.info("self.context.pdp_set={}".format(self.context.pdp_set)) + result, message = self.__check_rules() + if result: + return self.__exec_instructions(result) + else: + 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) + current_pdp = self.context.pdp_set[current_header_id] + category_list = list() + 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"]) + for category in category_list: + scope = list(current_pdp['target'][category]) + scopes_list.append(scope) + # policy_id = self.cache.get_policy_from_meta_rules("admin", current_header_id) + + for item in itertools.product(*scopes_list): + req = list(item) + for rule in self.cache.rules[self.context.current_policy_id]["rules"]: + LOG.info("rule={}".format(rule)) + if req == rule['rule']: + return rule['instructions'], "" + LOG.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: + LOG.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: + LOG.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: + LOG.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: + LOG.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): + for instruction in instructions: + for key in instruction: + if key == "decision": + if instruction["decision"] == "grant": + self.context.current_state = "grant" + LOG.info("__exec_instructions True {}".format( + self.context.current_state)) + return True + else: + 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" + LOG.info("__exec_instructions False {}".format(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(self.payload["authz_context"]) + 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: + LOG.error(self.payload["authz_context"]) + except KeyError: + LOG.error("Cannot find \"authz_context\" in context") + LOG.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): + LOG.info("HEAD request") + return "", 200 \ No newline at end of file diff --git a/moon_authz/moon_authz/api/generic.py b/moon_authz/moon_authz/api/generic.py new file mode 100644 index 00000000..f4e13e42 --- /dev/null +++ b/moon_authz/moon_authz/api/generic.py @@ -0,0 +1,131 @@ +# 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'. +""" +Those API are helping API used to manage the Moon platform. +""" + +from flask_restful import Resource, request +from oslo_log import log as logging +import moon_authz.api +from python_moonutilities.security_functions import check_auth + +__version__ = "0.1.0" + +LOG = logging.getLogger("moon.authz.api." + __name__) + + +class Status(Resource): + """ + Endpoint for status requests + """ + + __urls__ = ("/status", "/status/", "/status/") + + def get(self, component_id=None): + """Retrieve status of all components + + :return: { + "orchestrator": { + "status": "Running" + }, + "security_router": { + "status": "Running" + } + } + """ + raise NotImplemented + + +class Logs(Resource): + """ + Endpoint for logs requests + """ + + __urls__ = ("/logs", "/logs/", "/logs/") + + def get(self, component_id=None): + """Get logs from the Moon platform + + :param component_id: the ID of the component your are looking for (optional) + :return: [ + "2015-04-15-13:45:20 + "2015-04-15-13:45:21 + "2015-04-15-13:45:22 + "2015-04-15-13:45:23 + ] + """ + filter_str = request.args.get('filter', '') + from_str = request.args.get('from', '') + to_str = request.args.get('to', '') + event_number = request.args.get('event_number', '') + try: + event_number = int(event_number) + except ValueError: + event_number = None + args = dict() + args["filter"] = filter_str + args["from"] = from_str + args["to"] = to_str + args["event_number"] = event_number + + raise NotImplemented + + +class API(Resource): + """ + Endpoint for API requests + """ + + __urls__ = ( + "/api", + "/api/", + "/api/", + "/api//", + "/api//") + + @check_auth + def get(self, group_id="", endpoint_id="", user_id=""): + """Retrieve all API endpoints or a specific endpoint if endpoint_id is given + + :param group_id: the name of one existing group (ie generic, ...) + :param endpoint_id: the name of one existing component (ie Logs, Status, ...) + :return: { + "group_name": { + "endpoint_name": { + "description": "a description", + "methods": { + "get": "description of the HTTP method" + }, + "urls": ('/api', '/api/', '/api/') + } + } + """ + __methods = ("get", "post", "put", "delete", "options", "patch") + api_list = filter(lambda x: "__" not in x, dir(moon_authz.api)) + api_desc = dict() + for api_name in api_list: + api_desc[api_name] = {} + group_api_obj = eval("moon_interface.api.{}".format(api_name)) + api_desc[api_name]["description"] = group_api_obj.__doc__ + if "__version__" in dir(group_api_obj): + api_desc[api_name]["version"] = group_api_obj.__version__ + object_list = list(filter(lambda x: "__" not in x, dir(group_api_obj))) + for obj in map(lambda x: eval("moon_interface.api.{}.{}".format(api_name, x)), object_list): + if "__urls__" in dir(obj): + api_desc[api_name][obj.__name__] = dict() + api_desc[api_name][obj.__name__]["urls"] = obj.__urls__ + api_desc[api_name][obj.__name__]["methods"] = dict() + for _method in filter(lambda x: x in __methods, dir(obj)): + docstring = eval("moon_interface.api.{}.{}.{}.__doc__".format(api_name, obj.__name__, _method)) + api_desc[api_name][obj.__name__]["methods"][_method] = docstring + api_desc[api_name][obj.__name__]["description"] = str(obj.__doc__) + if group_id in api_desc: + if endpoint_id in api_desc[group_id]: + return {group_id: {endpoint_id: api_desc[group_id][endpoint_id]}} + elif len(endpoint_id) > 0: + LOG.error("Unknown endpoint_id {}".format(endpoint_id)) + return {"error": "Unknown endpoint_id {}".format(endpoint_id)} + return {group_id: api_desc[group_id]} + return api_desc diff --git a/moon_authz/moon_authz/http_server.py b/moon_authz/moon_authz/http_server.py new file mode 100644 index 00000000..50e878d3 --- /dev/null +++ b/moon_authz/moon_authz/http_server.py @@ -0,0 +1,140 @@ +# 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 flask import Flask, request +# from flask_cors import CORS, cross_origin +from flask_restful import Resource, Api, reqparse +import logging +from moon_authz import __version__ +from moon_authz.api.authorization import Authz +from python_moonutilities.cache import Cache +from python_moonutilities import exceptions + +logger = logging.getLogger("moon." + __name__) + +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, + ) + + +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="0.0.0.0", 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 + # Todo : specify only few urls instead of * + # CORS(self.app) + 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) # nosec diff --git a/moon_authz/moon_authz/server.py b/moon_authz/moon_authz/server.py new file mode 100644 index 00000000..974012dc --- /dev/null +++ b/moon_authz/moon_authz/server.py @@ -0,0 +1,48 @@ +# 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 +from oslo_log import log as logging +from moon_authz.http_server import HTTPServer as Server +from python_moonutilities import configuration + +LOG = logging.getLogger("moon.server") +DOMAIN = "moon_authz" + +__CWD__ = os.path.dirname(os.path.abspath(__file__)) + + +def main(): + 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") + configuration.init_logging() + LOG.info("component_type={}".format(component_type)) + conf = configuration.get_configuration("plugins/{}".format(component_type)) + conf["plugins/{}".format(component_type)]['id'] = component_id + hostname = conf["plugins/{}".format(component_type)].get('hostname', component_id) + port = conf["plugins/{}".format(component_type)].get('port', tcp_port) + bind = conf["plugins/{}".format(component_type)].get('bind', "0.0.0.0") + + LOG.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 + + +if __name__ == '__main__': + main() diff --git a/moon_authz/requirements.txt b/moon_authz/requirements.txt new file mode 100644 index 00000000..8cad7a7a --- /dev/null +++ b/moon_authz/requirements.txt @@ -0,0 +1,5 @@ +flask +flask_restful +flask_cors +python_moondb +python_moonutilities diff --git a/moon_authz/setup.py b/moon_authz/setup.py new file mode 100644 index 00000000..a8dcd0c4 --- /dev/null +++ b/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.rst').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:main', + ], + } + +) diff --git a/moon_authz/tests/unit_python/conftest.py b/moon_authz/tests/unit_python/conftest.py new file mode 100644 index 00000000..a6e62078 --- /dev/null +++ b/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/moon_authz/tests/unit_python/mock_pods.py b/moon_authz/tests/unit_python/mock_pods.py new file mode 100644 index 00000000..7488f4f3 --- /dev/null +++ b/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": "...", + "security_pipeline": ["policy_id_1", "policy_id_2"], + "keystone_project_id": "keystone_project_id1", + "description": "...", + }, + "pdp_id12": { + "name": "...", + "security_pipeline": ["policy_id_1", "policy_id_2"], + "keystone_project_id": "keystone_project_id1", + "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", + "partner_id": "" + } + }, + "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_id1", + "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", + "partner_id": "", + "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", + "partner_id": "", + "policy_list": [ + "f8f49a779ceb47b3ac810f01ef71b4e0", + "636cd473324f4c0bbd9102cb5b62a16d" + ] + }, + "cdb3df220dc04a6ea3334b994827b068": { + "name": "stop", + "description": "test", + "id": "cdb3df220dc04a6ea3334b994827b068", + "partner_id": "", + "policy_list": [ + "f8f49a779ceb47b3ac810f01ef71b4e0", + "636cd473324f4c0bbd9102cb5b62a16d" + ] + }, + "9f5112afe9b34a6c894eb87246ccb7aa": { + "name": "start", + "description": "test", + "id": "9f5112afe9b34a6c894eb87246ccb7aa", + "partner_id": "", + "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/moon_authz/tests/unit_python/requirements.txt b/moon_authz/tests/unit_python/requirements.txt new file mode 100644 index 00000000..21975ce3 --- /dev/null +++ b/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/moon_authz/tests/unit_python/test_authz.py b/moon_authz/tests/unit_python/test_authz.py new file mode 100644 index 00000000..f98abebc --- /dev/null +++ b/moon_authz/tests/unit_python/test_authz.py @@ -0,0 +1,50 @@ +import json +import pickle + + +def get_data(data): + return pickle.loads(data) + + +def get_json(data): + return json.loads(data.decode("utf-8")) + + +def test_authz_true(context): + import moon_authz.server + from python_moonutilities.security_functions import Context + from python_moonutilities.cache import Cache + server = moon_authz.server.main() + 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.security_functions import Context + from python_moonutilities.cache import Cache + server = moon_authz.server.main() + 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" diff --git a/moon_authz/tests/unit_python/utilities.py b/moon_authz/tests/unit_python/utilities.py new file mode 100644 index 00000000..19b9354c --- /dev/null +++ b/moon_authz/tests/unit_python/utilities.py @@ -0,0 +1,173 @@ +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" + }, + "interface": { + "bind": "0.0.0.0", + "port": 8080, + "container": "wukongsun/moon_interface:v4.3", + "hostname": "interface" + } + }, + "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/interface", + "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/moon_bouchon/Dockerfile b/moon_bouchon/Dockerfile new file mode 100644 index 00000000..ed013935 --- /dev/null +++ b/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/moon_bouchon/README.md b/moon_bouchon/README.md new file mode 100644 index 00000000..11733cef --- /dev/null +++ b/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/moon_bouchon/moon_bouchon/__init__.py b/moon_bouchon/moon_bouchon/__init__.py new file mode 100644 index 00000000..8811d91d --- /dev/null +++ b/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/moon_bouchon/moon_bouchon/__main__.py b/moon_bouchon/moon_bouchon/__main__.py new file mode 100644 index 00000000..4499a96b --- /dev/null +++ b/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/moon_bouchon/moon_bouchon/server.py b/moon_bouchon/moon_bouchon/server.py new file mode 100644 index 00000000..29e9101e --- /dev/null +++ b/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/moon_bouchon/requirements.txt b/moon_bouchon/requirements.txt new file mode 100644 index 00000000..8ab6294c --- /dev/null +++ b/moon_bouchon/requirements.txt @@ -0,0 +1 @@ +flask \ No newline at end of file diff --git a/moon_bouchon/setup.cfg b/moon_bouchon/setup.cfg new file mode 100644 index 00000000..7c2b2874 --- /dev/null +++ b/moon_bouchon/setup.cfg @@ -0,0 +1,2 @@ +[bdist_wheel] +universal = 1 \ No newline at end of file diff --git a/moon_bouchon/setup.py b/moon_bouchon/setup.py new file mode 100644 index 00000000..a875be40 --- /dev/null +++ b/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/moon_bouchon/tests/test_interface.py b/moon_bouchon/tests/test_interface.py new file mode 100644 index 00000000..425ba2e5 --- /dev/null +++ b/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/moon_bouchon/tests/test_wrapper.py b/moon_bouchon/tests/test_wrapper.py new file mode 100644 index 00000000..3d5e150c --- /dev/null +++ b/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/moon_gui/.gitignore b/moon_gui/.gitignore new file mode 100644 index 00000000..04bca1bc --- /dev/null +++ b/moon_gui/.gitignore @@ -0,0 +1,4 @@ +db.sqlite3 +idea/* +node_modules/* +dist/ \ No newline at end of file diff --git a/moon_gui/.jshintrc b/moon_gui/.jshintrc new file mode 100644 index 00000000..b9955f87 --- /dev/null +++ b/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/moon_gui/DEV.md b/moon_gui/DEV.md new file mode 100644 index 00000000..28743da3 --- /dev/null +++ b/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/moon_gui/Dockerfile b/moon_gui/Dockerfile new file mode 100644 index 00000000..428e1037 --- /dev/null +++ b/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/moon_gui/README.md b/moon_gui/README.md new file mode 100644 index 00000000..ff6e5a97 --- /dev/null +++ b/moon_gui/README.md @@ -0,0 +1,63 @@ + +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 + + +### Constants +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. + +In order to modify Keystone : + +`cd $pathtoVmSpace/docker/keystone` + +Concerned file is run.sh + +In order to modify Moon : + +`cd $MOON_HOME/moon_interface/interface` + +Concerned file is http_server.py + + diff --git a/moon_gui/delivery/assets/css/main.css b/moon_gui/delivery/assets/css/main.css new file mode 100644 index 00000000..dbc15489 --- /dev/null +++ b/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;/* inline-block for ie7 */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;/* styles required for IE to work */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/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.eot b/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 00000000..4a4ca865 Binary files /dev/null and b/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.eot differ diff --git a/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.svg b/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.svg new file mode 100644 index 00000000..e3e2dc73 --- /dev/null +++ b/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.svg @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.ttf b/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 00000000..67fa00bf Binary files /dev/null and b/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.ttf differ diff --git a/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.woff b/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.woff new file mode 100644 index 00000000..8c54182a Binary files /dev/null and b/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.woff differ diff --git a/moon_gui/delivery/assets/i18n/en.json b/moon_gui/delivery/assets/i18n/en.json new file mode 100755 index 00000000..dd54e112 --- /dev/null +++ b/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 Rules", + "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}} a(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/moon_gui/delivery/assets/i18n/fr.json b/moon_gui/delivery/assets/i18n/fr.json new file mode 100755 index 00000000..85c513b3 --- /dev/null +++ b/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/moon_gui/delivery/assets/img/ajax-loader.gif b/moon_gui/delivery/assets/img/ajax-loader.gif new file mode 100755 index 00000000..d0bce154 Binary files /dev/null and b/moon_gui/delivery/assets/img/ajax-loader.gif differ diff --git a/moon_gui/delivery/assets/img/ajax-waiting.gif b/moon_gui/delivery/assets/img/ajax-waiting.gif new file mode 100755 index 00000000..d84f6537 Binary files /dev/null and b/moon_gui/delivery/assets/img/ajax-waiting.gif differ diff --git a/moon_gui/delivery/assets/img/arrow-link.gif b/moon_gui/delivery/assets/img/arrow-link.gif new file mode 100755 index 00000000..ca17f44b Binary files /dev/null and b/moon_gui/delivery/assets/img/arrow-link.gif differ diff --git a/moon_gui/delivery/assets/img/favicon.ico b/moon_gui/delivery/assets/img/favicon.ico new file mode 100755 index 00000000..a7910bf5 Binary files /dev/null and b/moon_gui/delivery/assets/img/favicon.ico differ diff --git a/moon_gui/delivery/assets/img/logo-openstack.png b/moon_gui/delivery/assets/img/logo-openstack.png new file mode 100755 index 00000000..60ab0e1e Binary files /dev/null and b/moon_gui/delivery/assets/img/logo-openstack.png differ diff --git a/moon_gui/delivery/assets/img/logo-orange.gif b/moon_gui/delivery/assets/img/logo-orange.gif new file mode 100755 index 00000000..9c612291 Binary files /dev/null and b/moon_gui/delivery/assets/img/logo-orange.gif differ diff --git a/moon_gui/delivery/html/authentication/authentication.tpl.html b/moon_gui/delivery/html/authentication/authentication.tpl.html new file mode 100644 index 00000000..d942d8e8 --- /dev/null +++ b/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/moon_gui/delivery/html/common/404/404.tpl.html b/moon_gui/delivery/html/common/404/404.tpl.html new file mode 100644 index 00000000..f03a2e98 --- /dev/null +++ b/moon_gui/delivery/html/common/404/404.tpl.html @@ -0,0 +1 @@ +
Not found!
\ No newline at end of file diff --git a/moon_gui/delivery/html/common/compatibility/compatibility.tpl.html b/moon_gui/delivery/html/common/compatibility/compatibility.tpl.html new file mode 100644 index 00000000..7a39554e --- /dev/null +++ b/moon_gui/delivery/html/common/compatibility/compatibility.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moon_gui/delivery/html/common/footer/footer.tpl.html b/moon_gui/delivery/html/common/footer/footer.tpl.html new file mode 100644 index 00000000..6c01bd92 --- /dev/null +++ b/moon_gui/delivery/html/common/footer/footer.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moon_gui/delivery/html/common/header/header.tpl.html b/moon_gui/delivery/html/common/header/header.tpl.html new file mode 100644 index 00000000..6f46cf8f --- /dev/null +++ b/moon_gui/delivery/html/common/header/header.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moon_gui/delivery/html/common/loader/loader.tpl.html b/moon_gui/delivery/html/common/loader/loader.tpl.html new file mode 100644 index 00000000..dc52e911 --- /dev/null +++ b/moon_gui/delivery/html/common/loader/loader.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moon_gui/delivery/html/common/waiting/waiting.tpl.html b/moon_gui/delivery/html/common/waiting/waiting.tpl.html new file mode 100644 index 00000000..eca2ae9e --- /dev/null +++ b/moon_gui/delivery/html/common/waiting/waiting.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moon_gui/delivery/html/dashboard/dashboard.tpl.html b/moon_gui/delivery/html/dashboard/dashboard.tpl.html new file mode 100644 index 00000000..caee0db0 --- /dev/null +++ b/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/moon_gui/delivery/html/logs/logs.tpl.html b/moon_gui/delivery/html/logs/logs.tpl.html new file mode 100644 index 00000000..bb6dd686 --- /dev/null +++ b/moon_gui/delivery/html/logs/logs.tpl.html @@ -0,0 +1 @@ +
Logs
\ No newline at end of file diff --git a/moon_gui/delivery/html/model/action/model-add.tpl.html b/moon_gui/delivery/html/model/action/model-add.tpl.html new file mode 100644 index 00000000..5741b537 --- /dev/null +++ b/moon_gui/delivery/html/model/action/model-add.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moon_gui/delivery/html/model/action/model-delete.tpl.html b/moon_gui/delivery/html/model/action/model-delete.tpl.html new file mode 100644 index 00000000..79e4aa0d --- /dev/null +++ b/moon_gui/delivery/html/model/action/model-delete.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moon_gui/delivery/html/model/action/model-view.tpl.html b/moon_gui/delivery/html/model/action/model-view.tpl.html new file mode 100644 index 00000000..46673c0a --- /dev/null +++ b/moon_gui/delivery/html/model/action/model-view.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moon_gui/delivery/html/model/edit/metadata/metadata-edit.tpl.html b/moon_gui/delivery/html/model/edit/metadata/metadata-edit.tpl.html new file mode 100644 index 00000000..7d53a991 --- /dev/null +++ b/moon_gui/delivery/html/model/edit/metadata/metadata-edit.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moon_gui/delivery/html/model/edit/metadata/metadata-list.tpl.html b/moon_gui/delivery/html/model/edit/metadata/metadata-list.tpl.html new file mode 100644 index 00000000..050bfbce --- /dev/null +++ b/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/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-add.tpl.html b/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-add.tpl.html new file mode 100644 index 00000000..8593236d --- /dev/null +++ b/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/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-map.tpl.html b/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-map.tpl.html new file mode 100644 index 00000000..0170fc2e --- /dev/null +++ b/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/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-unmap.tpl.html b/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-unmap.tpl.html new file mode 100644 index 00000000..76e1e486 --- /dev/null +++ b/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/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit-basic.tpl.html b/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit-basic.tpl.html new file mode 100644 index 00000000..3a171600 --- /dev/null +++ b/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/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit.tpl.html b/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit.tpl.html new file mode 100644 index 00000000..fe37cc90 --- /dev/null +++ b/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moon_gui/delivery/html/model/edit/metarules/metarules-list.tpl.html b/moon_gui/delivery/html/model/edit/metarules/metarules-list.tpl.html new file mode 100644 index 00000000..c6d6c92e --- /dev/null +++ b/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/moon_gui/delivery/html/model/edit/model-edit-basic.tpl.html b/moon_gui/delivery/html/model/edit/model-edit-basic.tpl.html new file mode 100644 index 00000000..a645b1ee --- /dev/null +++ b/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/moon_gui/delivery/html/model/edit/model-edit.tpl.html b/moon_gui/delivery/html/model/edit/model-edit.tpl.html new file mode 100644 index 00000000..10f4545b --- /dev/null +++ b/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/moon_gui/delivery/html/model/model-list.tpl.html b/moon_gui/delivery/html/model/model-list.tpl.html new file mode 100644 index 00000000..138a66b7 --- /dev/null +++ b/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/moon_gui/delivery/html/pdp/action/pdp-add.tpl.html b/moon_gui/delivery/html/pdp/action/pdp-add.tpl.html new file mode 100644 index 00000000..e372a8c3 --- /dev/null +++ b/moon_gui/delivery/html/pdp/action/pdp-add.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moon_gui/delivery/html/pdp/action/pdp-delete.tpl.html b/moon_gui/delivery/html/pdp/action/pdp-delete.tpl.html new file mode 100644 index 00000000..2c8a5f34 --- /dev/null +++ b/moon_gui/delivery/html/pdp/action/pdp-delete.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moon_gui/delivery/html/pdp/edit/pdp-edit-basic.tpl.html b/moon_gui/delivery/html/pdp/edit/pdp-edit-basic.tpl.html new file mode 100644 index 00000000..e15e27e0 --- /dev/null +++ b/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/moon_gui/delivery/html/pdp/edit/pdp-edit.tpl.html b/moon_gui/delivery/html/pdp/edit/pdp-edit.tpl.html new file mode 100644 index 00000000..96b3dd78 --- /dev/null +++ b/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/moon_gui/delivery/html/pdp/pdp-list.tpl.html b/moon_gui/delivery/html/pdp/pdp-list.tpl.html new file mode 100644 index 00000000..31d1aae0 --- /dev/null +++ b/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/moon_gui/delivery/html/policy/action/mapping/policy-map.tpl.html b/moon_gui/delivery/html/policy/action/mapping/policy-map.tpl.html new file mode 100644 index 00000000..9d115c18 --- /dev/null +++ b/moon_gui/delivery/html/policy/action/mapping/policy-map.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moon_gui/delivery/html/policy/action/mapping/policy-unmap.tpl.html b/moon_gui/delivery/html/policy/action/mapping/policy-unmap.tpl.html new file mode 100644 index 00000000..3892782d --- /dev/null +++ b/moon_gui/delivery/html/policy/action/mapping/policy-unmap.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moon_gui/delivery/html/policy/action/policy-add.tpl.html b/moon_gui/delivery/html/policy/action/policy-add.tpl.html new file mode 100644 index 00000000..e1220479 --- /dev/null +++ b/moon_gui/delivery/html/policy/action/policy-add.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moon_gui/delivery/html/policy/action/policy-delete.tpl.html b/moon_gui/delivery/html/policy/action/policy-delete.tpl.html new file mode 100644 index 00000000..d2c679e3 --- /dev/null +++ b/moon_gui/delivery/html/policy/action/policy-delete.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moon_gui/delivery/html/policy/edit/parameter/assignments/assignments-list.tpl.html b/moon_gui/delivery/html/policy/edit/parameter/assignments/assignments-list.tpl.html new file mode 100644 index 00000000..6cae38d8 --- /dev/null +++ b/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/moon_gui/delivery/html/policy/edit/parameter/data/data-list.tpl.html b/moon_gui/delivery/html/policy/edit/parameter/data/data-list.tpl.html new file mode 100644 index 00000000..ef9b2ba7 --- /dev/null +++ b/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/moon_gui/delivery/html/policy/edit/parameter/perimeter/perimeter-list.tpl.html b/moon_gui/delivery/html/policy/edit/parameter/perimeter/perimeter-list.tpl.html new file mode 100644 index 00000000..5331e640 --- /dev/null +++ b/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/moon_gui/delivery/html/policy/edit/parameter/rules/rules-list.tpl.html b/moon_gui/delivery/html/policy/edit/parameter/rules/rules-list.tpl.html new file mode 100644 index 00000000..98669f6f --- /dev/null +++ b/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 Rules

.
\ No newline at end of file diff --git a/moon_gui/delivery/html/policy/edit/policy-edit-basic.tpl.html b/moon_gui/delivery/html/policy/edit/policy-edit-basic.tpl.html new file mode 100644 index 00000000..23f760d4 --- /dev/null +++ b/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/moon_gui/delivery/html/policy/edit/policy-edit.tpl.html b/moon_gui/delivery/html/policy/edit/policy-edit.tpl.html new file mode 100644 index 00000000..0e4525f7 --- /dev/null +++ b/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/moon_gui/delivery/html/policy/policy-list.tpl.html b/moon_gui/delivery/html/policy/policy-list.tpl.html new file mode 100644 index 00000000..2e8a981c --- /dev/null +++ b/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/moon_gui/delivery/html/policy/policy-mapped-list.tpl.html b/moon_gui/delivery/html/policy/policy-mapped-list.tpl.html new file mode 100644 index 00000000..2e18a1b5 --- /dev/null +++ b/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/moon_gui/delivery/html/project/action/mapping/project-map.tpl.html b/moon_gui/delivery/html/project/action/mapping/project-map.tpl.html new file mode 100644 index 00000000..dd47853f --- /dev/null +++ b/moon_gui/delivery/html/project/action/mapping/project-map.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moon_gui/delivery/html/project/action/mapping/project-unmap.tpl.html b/moon_gui/delivery/html/project/action/mapping/project-unmap.tpl.html new file mode 100644 index 00000000..bde6982e --- /dev/null +++ b/moon_gui/delivery/html/project/action/mapping/project-unmap.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moon_gui/delivery/html/project/action/project-add.tpl.html b/moon_gui/delivery/html/project/action/project-add.tpl.html new file mode 100644 index 00000000..612aa9b5 --- /dev/null +++ b/moon_gui/delivery/html/project/action/project-add.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moon_gui/delivery/html/project/action/project-delete.tpl.html b/moon_gui/delivery/html/project/action/project-delete.tpl.html new file mode 100644 index 00000000..a3a2d3e4 --- /dev/null +++ b/moon_gui/delivery/html/project/action/project-delete.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moon_gui/delivery/html/project/action/project-view.tpl.html b/moon_gui/delivery/html/project/action/project-view.tpl.html new file mode 100644 index 00000000..b2bd975b --- /dev/null +++ b/moon_gui/delivery/html/project/action/project-view.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moon_gui/delivery/html/project/project-list.tpl.html b/moon_gui/delivery/html/project/project-list.tpl.html new file mode 100644 index 00000000..d0ab8886 --- /dev/null +++ b/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/moon_gui/delivery/index.html b/moon_gui/delivery/index.html new file mode 100644 index 00000000..0631ab7a --- /dev/null +++ b/moon_gui/delivery/index.html @@ -0,0 +1,34 @@ + + + + + + + Moon + + + + + + + + +
+
+
+ +
+
+
+ +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/moon_gui/delivery/js/app.js b/moon_gui/delivery/js/app.js new file mode 100644 index 00000000..ef98d469 --- /dev/null +++ b/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("","/project"),e.when("/","/project"),e.otherwise("/404"),t(d),o(d),n(d),c(d),i(d),a(d),r(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 a(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 r(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,a){function r(e,t,o){-1===["/login"].indexOf(a.path())&&!c.currentUser&&a.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,a,r,l){var s=u(t,i,c,a,r,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 a={};return a.status=c.status,a.message=c.statusText,a.state=t,a.params=o,a}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",r),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://192.168.102.118:38001/pdp/",MODELS:"http://192.168.102.118:38001/models/",METARULES:"http://192.168.102.118:38001/meta_rules/",RULES:"http://192.168.102.118:38001/rules/",POLICIES:"http://192.168.102.118:38001/policies/",METADATA:{subject:"http://192.168.102.118:38001/subject_categories/",object:"http://192.168.102.118:38001/object_categories/",action:"http://192.168.102.118:38001/action_categories/"},PERIMETERS:{subject:"http://192.168.102.118:38001/subjects/",object:"http://192.168.102.118:38001/objects/",action:"http://192.168.102.118:38001/actions/"},KEYSTONE:"http://192.168.102.118:5000/v3/"})}(),function(){"use strict";function e(e,t,o,n,i){function c(){l.loading=!0,e.Login(l.credentials,a,r)}function a(){t("moon.login.success").then(function(e){o.alertSuccess(e),n.go("moon.dashboard"),l.loading=!1})}function r(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 a(){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 r(){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=r,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(){a()}();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 P in T)e.$on("$destroy",T[P])}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,a){function r(){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,a.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 P(e,t){A.addPDP(t),A.refreshPDPs(),A.add.modal.hide()}function E(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=r,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 M={"event:pdpCreatedSuccess":e.$on("event:pdpCreatedSuccess",P),"event:pdpCreatedError":e.$on("event:pdpCreatedError",E),"event:pdpDeletedSuccess":e.$on("event:pdpDeletedSuccess",C),"event:pdpDeletedError":e.$on("event:pdpDeletedError",O)};_.each(M,function(e){t.$on("$destroy",M[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 a(){return j.policies?j.policies:[]}function r(){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=a,j.hasPolicies=r,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 a(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():r()}))}function r(){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,a(!0),y.map.modal.hide()}function f(e){y.map.modal.hide()}function h(e,t){y.pdp=t,a(!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(){a(!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,a){function r(){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 P(e,t){k.deleteProject(t),k.refreshProjects(),k.del.modal.hide()}function E(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){r(),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 M(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 R(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=a,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},r();var L={"event:projectCreatedSuccess":e.$on("event:projectCreatedSuccess",j),"event:projectCreatedError":e.$on("event:projectCreatedError",S),"event:projectDeletedSuccess":e.$on("event:projectDeletedSuccess",P),"event:projectDeletedError":e.$on("event:projectDeletedError",E),"event:projectMappedSuccess":e.$on("event:projectMappedSuccess",C),"event:projectMappedError":e.$on("event:projectMappedError",O),"event:projectUnmappedSuccess":e.$on("event:projectUnmappedSuccess",M),"event:projectUnmappedError":e.$on("event:projectUnmappedError",R)};for(var w in L)t.$on("$destroy",L[w])}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),a.currentLanguage=t}function c(){o.Logout(),e("moon.logout.success").then(function(e){n.alertSuccess(e)})}var a=this;a.isProjectTabActive=t.isProjectTabActive,a.isPDPTabActive=t.isPDPTabActive,a.isLogsTabActive=t.isLogsTabActive,a.isPolicyTabActive=t.isPolicyTabActive,a.isModelTabActive=t.isModelTabActive,a.changeLocale=i,a.logout=c,a.currentLanguage=e.use(),a.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 a(){function a(t){var i=c.transformOne(t,"models");n("moon.model.add.success",{modelName:i.name}).then(function(e){o.alertSuccess(e)}),r.loading=!1,e.$emit("event:modelCreatedSuccess",i)}function l(t){n("moon.model.add.error",{modelName:r.model.name}).then(function(e){o.alertError(e)}),r.loading=!1,e.$emit("event:modelCreatedError",r.project)}i.isInvalid(r.form)?i.checkFieldsValidity(r.form):(r.loading=!0,t.data.create({},r.model,a,l))}var r=this;r.form={},r.loading=!1,r.model={name:null,description:null,meta_rules:[]},r.create=a}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 a(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,a)}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 a={"event:modelUpdatedSuccess":t.$on("event:modelUpdatedSuccess",i),"event:updateModelFromMetaRuleAddSuccess":t.$on("event:updateModelFromMetaRuleAddSuccess",i)};for(var r in a)e.$on("$destroy",a[r])}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 a(){function a(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 r(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,a,r))}function r(){l.modelToEdit=angular.copy(l.model)}var l=this;l.editModel=a,l.init=r,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,a){function r(c){function r(n){t("moon.pdp.add.success",{pdpName:c.name}).then(function(e){o.alertSuccess(e)});var i=a.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},r,s))}var l=this;l.form={},l.pdp={},l.policies=[],l.selectedPolicy=null,l.loading=!1,l.loadingPolicies=!0,l.create=r,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 a(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,a)}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 a={"event:pdpUpdatedSuccess":t.$on("event:pdpUpdatedSuccess",i)};for(var r in a)e.$on("$destroy",a[r])}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 a(){function a(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 r(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,a,r))}function r(){l.pdpToEdit=angular.copy(l.pdp)}var l=this;l.editPdp=a,l.init=r,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,a){function r(){a.findAllWithCallBack(l)}function l(e){d.models=e,d.modelsLoading=!1}function s(){function a(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 r(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},a,r))}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(){r()}()}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 a(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,a)}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(){a.loadingModel=!0,n.findOneWithCallback(a.policy.model_id,function(e){a.loadingModel=!1,a.policy.model=e})}function c(e,t){a.policy=t,i()}var a=this;a.policy=o,a.editBasic=!1,a.showPerimeters=!1,a.showData=!1,a.showRules=!1,a.showAssignments=!1,function(){i()}();var r={"event:policyUpdatedSuccess":t.$on("event:policyUpdatedSuccess",c)};for(var l in r)e.$on("$destroy",r[l])}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,a){function r(){a.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 a(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 r(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,a,r))}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),r()}()}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){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 a={};return a.isProjectTabActive=t,a.isPDPTabActive=o,a.isPolicyTabActive=n,a.isLogsTabActive=i,a.isModelTabActive=c,a}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 a(){delete o.currentUser,n.defaults.headers.common["X-Auth-Token"]="",i.path("/")}function r(){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:r,Logout:a}}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(e,t,o,n,i,c){function a(){function c(n){var i=n.project;t("moon.project.add.success",{projectName:i.name}).then(function(e){o.alertSuccess(e)}),r.loading=!1,e.$emit("event:projectCreatedSuccess",i)}function a(n){t("moon.project.add.error",{projectName:r.project.project.name}).then(function(e){o.alertError(e)}),r.loading=!1,e.$emit("event:projectCreatedError",r.project)}n.isInvalid(r.form)?n.checkFieldsValidity(r.form):(r.loading=!0,i.data.projects.create({},r.project,c,a))}var r=this;r.form={},r.loading=!1,r.project={project:{name:null,description:null,enabled:!0,domain:c.DOMAIN.DEFAULT}},r.create=a}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 a(){return _.has(d.project,"pdp")}function r(){d.loading=!0,a()?l(s):s()}function l(n){function c(n){t("moon.project.remove.mapping.remove.error",{pdpName:a}).then(function(e){o.alertError(e)}),d.loading=!1,e.$emit("event:projectDeletedError",d.project)}var a=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=r,d.isProjectMapped=a,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(){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,a,r){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=r.transformOne(t,"meta_rules"),e.$emit("event:updateMetaRuleFromMetaDataAddSuccess",l),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=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)}a.update(l,t,c)}}function d(){function e(e){var t={};switch(g.metaDataType){case o.TYPE.SUBJECT:t=r.transformOne(e,"subject_categories");break;case o.TYPE.OBJECT:t=r.transformOne(e,"object_categories");break;case o.TYPE.ACTION:t=r.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 a(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,a);break;case o.TYPE.OBJECT:t.object.add(l,e,a);break;case o.TYPE.ACTION:t.action.add(l,e,a)}}}function u(){function c(t){i("moon.model.metadata.edit.delete.success",{name:s.name}).then(function(e){n.alertSuccess(e)}),a.findOneWithMetaData(g.metaRule.id).then(function(t){g.metaRule=t,m(),l(),f(),e.$emit("event:deleteMetaDataFromMetaDataAddSuccess",g.metaRule)})}function r(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,r);break;case o.TYPE.OBJECT:t.object.delete(s,c,r);break;case o.TYPE.ACTION:t.action.delete(s,c,r)}}}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.laoading=!1,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:"=",shortDisplay:"="},restrict:"E",replace:!0}}function t(e,t,o,n,i,c,a,r){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)}),j.metaRule=c.findMetaDataFromMetaRule(r.transformOne(t,"meta_rules")),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 a=angular.copy(j.metaRule);a.subject_categories=_.without(a.subject_categories,e.id),c.update(a,t,o)}function p(e){function t(t){n("moon.model.metarules.update.success",{metaRuleName:j.metaRule.name}).then(function(e){i.alertSuccess(e)}),j.metaRule=c.findMetaDataFromMetaRule(r.transformOne(t,"meta_rules")),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 a=angular.copy(j.metaRule);a.object_categories=_.without(a.object_categories,e.id),c.update(a,t,o)}function f(e){function t(t){n("moon.model.metarules.update.success",{metaRuleName:j.metaRule.name}).then(function(e){i.alertSuccess(e)}),j.metaRule=c.findMetaDataFromMetaRule(r.transformOne(t,"meta_rules")),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 a=angular.copy(j.metaRule);a.action_categories=_.without(a.action_categories,e.id),c.update(a,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=a.TYPE.SUBJECT,j.typeOfObject=a.TYPE.OBJECT,j.typeOfAction=a.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 a(){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 r(){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=r,_.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(){a()}();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,a){function r(){s.policiesLoading=!0,i.findAllWithCallback(function(e){s.policies=e,s.policiesLoading=!1})}function l(){function i(n){var i=a.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 r(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,r)}}var s=this;s.pdps=[],s.pdp=e.pdp,s.addPolicyToList=!1,s.map=l,function(){r()}()}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:a.pdp.name,policyName:a.policy.name}).then(function(e){o.alertSuccess(e)}),a.unMappingLoading=!1,e.$emit("event:policyUnMappedToPdpSuccess",i.transformOne(n,"pdps"))}function r(n){t("moon.policy.unmap.error",{pdpName:a.pdp.name,policyName:a.policy.name}).then(function(e){o.alertError(e)}),a.unMappingLoading=!1,e.$emit("event:policyUnMappedToPdpError")}a.unMappingLoading=!0;var l=angular.copy(a.pdp);l.security_pipeline=_.without(l.security_pipeline,a.policy.id),n.update(l,c,r)}var a=this;a.pdp=e.pdp,a.policy=e.policy,a.unMappingLoading=!1,a.unmap=c}angular.module("moon").controller("PolicyUnMapController",e),e.$inject=["$scope","$translate","alertService","pdpService","utilService"]}(),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){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,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[];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,i){function c(){i.findAllWithCallBack(a)}function a(e){l.pdps=_.filter(e,function(e){return _.isNull(e.keystone_project_id)}),l.pdpsLoading=!1}function r(){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 a(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,a))}var l=this;l.form={},l.project=e.project,l.pdps=[],l.pdpsLoading=!0,l.selectedPDP=null,l.map=r,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:r}).then(function(e){o.alertSuccess(e)}),c.unMappingLoading=!1,delete c.project.mapping,delete c.project.pdp,e.$emit("event:projectUnmappedSuccess",c.project)}function a(n){t("moon.project.unmap.error",{projectName:c.project.name,pdpName:r}).then(function(e){o.alertError(e)}),c.unMappingLoading=!1,e.$emit("event:projectUnmappedError",c.project)}c.unMappingLoading=!0;var r=c.project.pdp.name;n.unMap(c.project.pdp,i,a)}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){function o(e,t){n.metaRule=t}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 a(){function a(t){var o=c.transformOne(t,"meta_rules");i("moon.model.metarules.edit.basic.success",{metaRuleName:o.name}).then(function(e){n.alertSuccess(e)}),l.loading=!1,e.$emit("event:metaRuleBasicUpdatedSuccess",o)}function r(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,a,r))}function r(){l.metaRuleToEdit=angular.copy(l.metaRule)}var l=this;l.editMetaRule=a,l.init=r,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,a,r,l,s,d){function u(){E.assignments={id:null,category_id:null,data_id:null,policy_id:null},p(),h()}function m(){function c(t){var i={};switch(E.assignmentsType){case l.TYPE.SUBJECT:i=a.transformOne(t,"subject_assignments");break;case l.TYPE.OBJECT:i=a.transformOne(t,"object_assignments");break;case l.TYPE.ACTION:i=a.transformOne(t,"action_assignments")}n("moon.policy.assignments.edit.create.success").then(function(e){o.alertSuccess(e)}),s&&i.policy_id===E.policy.id?(e.$emit("event:createAssignmentsFromAssignmentsEditSuccess",E.assignmentsType),u(),P()):s&&(u(),P())}function r(e){n("moon.policy.rules.edit.action.add.create.error").then(function(e){o.alertError(e)}),P()}if(E.assignementsAttributeValid=!0,S(),i.isInvalid(E.form))i.checkFieldsValidity(E.form);else if(E.assignementsAttributeValid){T();var s=!1;E.assignments.id=E.selectedPerimeter.id,E.assignments.category_id=E.selectedCategory.id,E.assignments.policy_id=E.selectedPolicy.id;var d=angular.copy(E.selectedDataList);_.each(d,function(e){E.assignments.data_id=e.id;var o=angular.copy(E.assignments);switch(E.assignmentsType){case l.TYPE.SUBJECT:t.subject.add(o,E.policy.id,c,r);break;case l.TYPE.OBJECT:t.object.add(o,E.policy.id,c,r);break;case l.TYPE.ACTION:t.action.add(o,E.policy.id,c,r)}}),s=!0}}function p(){E.policyList=[],E.loadingPolicies=!0,c.findAllWithCallback(function(e){_.each(e,function(e){e.id===E.policy.id&&(E.selectedPolicy=e)}),E.policyList=e,E.loadingPolicies=!1})}function f(){function e(e){E.perimeterList=e,E.loadingPerimeters=!1}switch(E.perimeterList=[],E.loadingPerimeters=!0,E.assignmentsType){case l.TYPE.SUBJECT:r.subject.findAllFromPolicyWithCallback(E.selectedPolicy.id,e);break;case l.TYPE.OBJECT:r.object.findAllFromPolicyWithCallback(E.selectedPolicy.id,e);break;case l.TYPE.ACTION:r.action.findAllFromPolicyWithCallback(E.selectedPolicy.id,e);break;default:E.perimeterList=[],E.loadingPerimeters=!1}}function h(){function e(e){E.categoryList=e,E.loadingCategories=!1}switch(E.categoryList=[],E.loadingCategories=!0,E.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:E.categoryList=[],E.loadingCategories=!1}}function g(e){function t(e){E.dataList=e,E.dataToBeSelected=angular.copy(E.dataList),E.selectedDataList=[],E.loadingData=!1}switch(E.dataList=[],E.dataToBeSelected=[],E.selectedDataList=[],E.loadingData=!0,E.assignmentsType){case l.TYPE.SUBJECT:d.subject.findAllFromCategoriesWithCallback(E.selectedPolicy.id,e,t);break;case l.TYPE.OBJECT:d.object.findAllFromCategoriesWithCallback(E.selectedPolicy.id,e,t);break;case l.TYPE.ACTION:d.action.findAllFromCategoriesWithCallback(E.selectedPolicy.id,e,t);break;default:E.loadingData=!1}}function y(){E.dataToBeSelected=_.without(E.dataToBeSelected,E.selectedData),E.selectedDataList.push(E.selectedData),b()}function v(e){E.dataToBeSelected.push(e),E.selectedDataList=_.without(E.selectedDataList,e)}function b(){E.selectedData=void 0}function j(e){if(_.isUndefined(e))return"(None)";switch(E.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(){E.selectedDataList.length>=1?E.assignementsAttributeValid=!0:E.assignementsAttributeValid=!1}function T(){E.loading=!0}function P(){E.loading=!1}var E=this;E.assignmentsType=e.edit.assignmentsType,E.policy=e.edit.policy,E.laoading=!1,E.form={},E.policyList=[],E.loadingPolicies=!0,E.categoryList=[],E.loadingCategories=!0,E.perimeterList=[],E.loadingPerimeters=!0,E.dataList=[],E.dataToBeSelected=[],E.selectedDataList=[],E.loadingData=!0,E.assignementsAttributeValid=!0,E.addSelectedData=y,E.removeSelectedData=v,E.getName=j,E.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,a,r,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 a.TYPE.SUBJECT:s.subject.findOneFromPolicyWithCallback($.policy.id,e.subject_id,o);break;case a.TYPE.OBJECT:s.object.findOneFromPolicyWithCallback($.policy.id,e.object_id,o);break;case a.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 a.TYPE.SUBJECT:l.subject.findOne(e.subject_cat_id,o);break;case a.TYPE.OBJECT:l.object.findOne(e.object_cat_id,o);break;case a.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 a.TYPE.SUBJECT:d.subject.data.findOne($.policy.id,t.category_id,t.assignments[e],n);break;case a.TYPE.OBJECT:d.object.data.findOne($.policy.id,t.category_id,t.assignments[e],n);break;case a.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 a(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,a)}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 a(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,a)}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 a(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,a)}function S(){return $.subjects?$.subjects:[]}function T(){return $.objects?$.objects:[]}function P(){return $.actions?$.actions:[]}function E(e,t){switch(t){case a.TYPE.SUBJECT:m();break;case a.TYPE.OBJECT:p();break;case a.TYPE.ACTION:f();break;default:u()}}var $=this;$.policy=e.list.policy,$.editMode=e.list.editMode,$.typeOfSubject=a.TYPE.SUBJECT,$.typeOfObject=a.TYPE.OBJECT,$.typeOfAction=a.TYPE.ACTION,$.deleteSub=v,$.deleteObj=b,$.deleteAct=j,$.getSubjects=S,$.getObjects=T,$.getActions=P,$.getCategoryFromAssignment=g,$.getPerimeterFromAssignment=h,$.getDataFromAssignmentsIndex=y,u();var C={"event:createAssignmentsFromAssignmentsEditSuccess":t.$on("event:createAssignmentsFromAssignmentsEditSuccess",E)};_.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,a,r,l){function s(){function e(e){f.categoriesToBeSelected=e}switch(f.dataType){case o.TYPE.SUBJECT:l.subject.findAllWithCallback(e);break;case o.TYPE.OBJECT:l.object.findAllWithCallback(e);break;case o.TYPE.ACTION:l.action.findAllWithCallback(e);break;default:f.categoriesToBeSelected=[]}}function d(){f.policyList=[],a.findAllWithCallback(function(e){_.each(e,function(e){e.id===f.policy.id&&(f.selectedPolicy=e)}),f.policyList=e})}function u(){function a(t){var c={};switch(f.dataType){case o.TYPE.SUBJECT:c=r.transformOne(t.subject_data,"data");break;case o.TYPE.OBJECT:c=r.transformOne(t.object_data,"data");break;case o.TYPE.ACTION:c=r.transformOne(t.action_data,"data")}i("moon.policy.data.edit.create.success",{name:c.name}).then(function(e){n.alertSuccess(e)}),e.$emit("event:createDataFromDataEditSuccess",c,f.dataType),p(),f.list.push(c)}function l(e){i("moon.policy.data.edit.create.error",{name:s.name}).then(function(e){n.alertError(e)}),p()}if(c.isInvalid(f.form))c.checkFieldsValidity(f.form);else{m();var s=angular.copy(f.data);switch(f.dataType){case o.TYPE.SUBJECT:t.subject.add(s,f.policy.id,f.selectedCategory.id,a,l);break;case o.TYPE.OBJECT:t.object.add(s,f.policy.id,f.selectedCategory.id,a,l);break;case o.TYPE.ACTION:t.action.add(s,f.policy.id,f.selectedCategory.id,a,l)}}}function m(){f.loading=!0}function p(){f.loading=!1}var f=this;f.dataType=e.edit.mnDataType,f.policy=e.edit.policy,f.fromList=!1,f.loading=!1,f.form={},f.data={name:null,description:null},f.list=[],f.policyList=[],f.categoriesToBeSelected=[],f.create=u,function(){function e(e){_.each(e,function(e){e.policy_id!==f.policy.id&&f.list.push(e)})}switch(s(),d(),f.dataType){case o.TYPE.SUBJECT:t.subject.findAllFromPolicyWithCallback(f.policy.id,e);break;case o.TYPE.OBJECT:t.object.findAllFromPolicyWithCallback(f.policy.id,e);break;case o.TYPE.ACTION:t.action.findAllFromPolicyWithCallback(f.policy.id,e);break;default:f.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"]}(),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,a){function r(){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:a.subject.findOne(e.category_id,o);break;case c.TYPE.OBJECT:a.object.findOne(e.category_id,o);break;case c.TYPE.ACTION:a.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(){r(),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,a,r,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=[],r.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:a.name}).then(function(e){i.alertSuccess(e)}),b()}function t(e){c("moon.policy.update.error",{policyName:a.name,reason:e.message}).then(function(e){i.alertError(e)}),b()}if(T.selectedPerimeter){v();var a=T.selectedPerimeter;switch(a.policy_list.push(T.policy.id),T.perimeterType){case n.TYPE.SUBJECT:o.subject.update(a,e,t);break;case n.TYPE.OBJECT:o.object.update(a,e,t);break;case n.TYPE.ACTION:o.action.update(a,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 r(e){c("moon.policy.perimeter.edit.create.error",{name:s.name}).then(function(e){i.alertError(e)}),b()}if(a.isInvalid(T.form))a.checkFieldsValidity(T.form);else{v();var s=angular.copy(T.perimeter);switch(T.perimeterType){case n.TYPE.SUBJECT:o.subject.add(s,t,r);break;case n.TYPE.OBJECT:o.object.add(s,t,r);break;case n.TYPE.ACTION:o.action.add(s,t,r)}}}function g(){function t(t){c("moon.policy.perimeter.edit.delete.success",{name:d.name}).then(function(e){i.alertSuccess(e)}),r.findOneReturningPromise(T.policy.id).then(function(t){T.policy=l.transformOne(t,"policies"),y(),s(),b(),e.$emit("event:deletePerimeterFromPerimeterAddSuccess",T.policy)})}function a(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,a);break;case n.TYPE.OBJECT:o.object.delete(d,t,a);break;case n.TYPE.ACTION:o.action.delete(d,t,a)}}}function y(){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 P={"event:unMapPerimeterFromPerimeterList":t.$on("event:unMapPerimeterFromPerimeterList",S)};_.each(P,function(t){e.$on("$destroy",P[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 a(){r(),l(),s()}function r(){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 r(o){n("moon.policy.perimeter.update.success",{perimeterName:s.name}).then(function(e){i.alertSuccess(e)}),e.$emit("event:unMapPerimeterFromPerimeterList",t,c.TYPE.SUBJECT),a(),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,r,l)}function u(t){function r(o){n("moon.policy.perimeter.update.success",{perimeterName:s.name}).then(function(e){i.alertSuccess(e)}),e.$emit("event:unMapPerimeterFromPerimeterList",t,c.TYPE.OBJECT),a(),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,r,l)}function m(t){function r(o){n("moon.policy.perimeter.update.success",{perimeterName:s.name}).then(function(e){i.alertSuccess(e)}),e.$emit("event:unMapPerimeterFromPerimeterList",t,c.TYPE.ACTION),a(),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,r,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,a()}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,a();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,a,r,l,s,d,u){function m(){R.rules={meta_rule_id:null,rule:[],policy_id:null,instructions:'[{"decision": "grant"}]',enabled:!0},M(),p(),P()}function p(){R.policyList=[],c.findAllWithCallback(function(e){_.each(e,function(e){e.id===R.policy.id&&(R.selectedPolicy=e)}),R.policyList=e})}function f(){R.selectedPolicy.meta_rules_values=void 0,s.findOneWithCallback(R.selectedPolicy.model_id,function(e){r.findSomeWithCallback(e.meta_rules,function(e){R.selectedPolicy.meta_rules_values=e})})}function h(e,t,o){l.subject.findSomeWithCallback(e,function(e){R.categories.subject=e,R.categories.loadingSubjects=!1,_.each(R.categories.subject,function(e){d.subject.findAllFromCategoriesWithCallback(R.selectedPolicy.id,e.id,function(e){R.data.subject=e,R.data.loadingSubjects=!1,R.data.subjectsToBeSelected=angular.copy(R.data.subject)})})}),l.object.findSomeWithCallback(t,function(e){R.categories.object=e,R.categories.loadingObjects=!1,_.each(R.categories.object,function(e){d.object.findAllFromCategoriesWithCallback(R.selectedPolicy.id,e.id,function(e){R.data.object=e,R.data.loadingObjects=!1,R.data.objectsToBeSelected=angular.copy(R.data.object)})})}),l.action.findSomeWithCallback(o,function(e){R.categories.action=e,R.categories.loadingActions=!1,_.each(R.categories.action,function(e){d.action.findAllFromCategoriesWithCallback(R.selectedPolicy.id,e.id,function(e){R.data.action=e,R.data.loadingActions=!1,R.data.actionsToBeSelected=angular.copy(R.data.action)})})})}function g(){function c(t){var i=a.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 r(e){n("moon.policy.rules.edit.action.add.create.error").then(function(e){o.alertError(e)}),T()}if(R.instructionsValid=!0,R.numberOfSelectedSubjectValid=!0,R.numberOfSelectedObjecttValid=!0,R.numberOfSelectedActionsValid=!0,y(),v(),i.isInvalid(R.form))i.checkFieldsValidity(R.form);else if(R.instructionsValid&&v()){S(),A(),R.rules.meta_rule_id=R.selectedMetaRules.id,R.rules.policy_id=R.selectedPolicy.id;var l=angular.copy(R.rules);l.instructions=JSON.parse(R.rules.instructions),t.add(l,R.policy.id,c,r)}}function y(){b(R.rules.instructions)?R.instructionsValid=!0:R.instructionsValid=!1}function v(){return $(u.TYPE.SUBJECT)?R.numberOfSelectedSubjectValid=!0:R.numberOfSelectedSubjectValid=!1,$(u.TYPE.OBJECT)?R.numberOfSelectedObjecttValid=!0:R.numberOfSelectedObjecttValid=!1,$(u.TYPE.ACTION)?R.numberOfSelectedActionsValid=!0:R.numberOfSelectedActionsValid=!1,R.numberOfSelectedSubjectValid&&R.numberOfSelectedObjecttValid&&R.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(){R.loading=!0}function T(){R.loading=!1}function P(){R.selectedMetaRules=void 0,E()}function E(){R.selectedSubject=void 0,R.selectedObject=void 0,R.selectedAction=void 0}function $(e){if(!R.selectedMetaRules)return!1;switch(e){case u.TYPE.SUBJECT:return R.data.selectedSubjectsList.length===R.selectedMetaRules.subject_categories.length;case u.TYPE.OBJECT:return R.data.selectedObjectsList.length===R.selectedMetaRules.object_categories.length;case u.TYPE.ACTION:return R.data.selectedActionsList.length===R.selectedMetaRules.action_categories.length}}function C(e){switch(e){case u.TYPE.SUBJECT:if(!R.selectedSubject||$(e)||_.contains(R.data.selectedSubjectsList,R.selectedSubject))return;R.data.selectedSubjectsList.push(R.selectedSubject),R.data.subjectsToBeSelected=_.without(R.data.subjectsToBeSelected,R.selectedSubject);break;case u.TYPE.OBJECT:if(!R.selectedObject||$(e)||_.contains(R.data.selectedObjectsList,R.selectedObject))return;R.data.selectedObjectsList.push(R.selectedObject),R.data.objectsToBeSelected=_.without(R.data.objectsToBeSelected,R.selectedObject);break;case u.TYPE.ACTION:if(!R.selectedAction||$(e)||_.contains(R.data.selectedActionsList,R.selectedAction))return;R.data.selectedActionsList.push(R.selectedAction),R.data.actionsToBeSelected=_.without(R.data.actionsToBeSelected,R.selectedAction)}}function O(e,t){switch(t){case u.TYPE.SUBJECT:R.data.subjectsToBeSelected.push(e),R.data.selectedSubjectsList=_.without(R.data.selectedSubjectsList,e);break;case u.TYPE.OBJECT:R.data.objectsToBeSelected.push(e),R.data.selectedObjectsList=_.without(R.data.selectedObjectsList,e);break;case u.TYPE.ACTION:R.data.actionsToBeSelected.push(e),R.data.selectedActionsList=_.without(R.data.selectedActionsList,e)}}function A(){function e(e){R.rules.rule.push(e.id)}_.each(R.data.selectedSubjectsList,e),_.each(R.data.selectedObjectsList,e),_.each(R.data.selectedActionsList,e)}function M(){R.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 R=this;R.policy=e.edit.policy,R.editMode=!0,R.fromList=!1,R.loading=!1,R.form={},R.showDetailselectedMetaRules=!1,R.list=[],R.policyList=[],R.categories={subject:[],loadingSubjects:!0,object:[],loadingObjects:!0,action:[],loadingActions:!0},R.data={},R.create=g,R.addDataToRules=C,R.removeSelectedDataFromRules=O,R.isNumberSelectedDataAtMaximum=$,R.instructionsValid=!0,R.numberOfSelectedSubjectValid=!0,R.numberOfSelectedObjecttValid=!0,R.numberOfSelectedActionsValid=!0,m(),e.$watch("edit.selectedPolicy",function(e){P(),_.isUndefined(e)||f()}),e.$watch("edit.selectedMetaRules",function(e){E(),R.categories={subject:[],loadingSubjects:!0,object:[],loadingObjects:!0,action:[],loadingActions:!0},M(),_.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,a,r,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],a.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],a.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],a.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(){r("moon.policy.rules.edit.action.add.delete.success").then(function(e){l.alertSuccess(e)}),S(e),v(),e.loader=!1}function o(t){r("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 P={"event:createRulesFromDataRulesSuccess":t.$on("event:createRulesFromDataRulesSuccess",b)};_.each(P,function(t){e.$on("$destroy",P[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,a){n.subject.policy.remove({policy_id:e,perimeter_id:t,category_id:o,data_id:i},{},c,a)},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,a){n.object.policy.remove({policy_id:e,perimeter_id:t,category_id:o,data_id:i},{},c,a)},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,a){n.action.policy.remove({policy_id:e,perimeter_id:t,category_id:o,data_id:i},{},c,a)},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"}})},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 a(){function a(t){var i=c.transformOne(t,"meta_rules");n("moon.model.metarules.add.success",{metaRuleName:i.name}).then(function(e){o.alertSuccess(e)}),r.loading=!1,e.$emit("event:metaRuleCreatedSuccess",i)}function l(t){n("moon.model.metarules.add.error",{metaRuleName:r.metaRule.name}).then(function(e){o.alertError(e)}),r.loading=!1,e.$emit("event:metaRuleCreatedError",r.project)}i.isInvalid(r.form)?i.checkFieldsValidity(r.form):(r.loading=!0,t.data.create({},r.metaRule,a,l))}var r=this;r.laoading=!1,r.form={},r.metaRule={name:null,description:null,subject_categories:[],object_categories:[],action_categories:[]},r.create=a}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,a,r){function l(){h.metaRulesLoading=!0,c.findAllWithCallback(function(e){h.metaRules=e,h.metaRulesLoading=!1})}function s(){function t(t){var i=r.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),a.update(s,t,l)}}function d(){delete h.selectedMetaRule}function u(){function t(t){n("moon.model.metarules.delete.success",{metaRuleName:a.name}).then(function(e){o.alertSuccess(e)}),d(),h.mappingLoading=!1,l(),e.$emit("event:deleteMetaRule",a)}function i(e){n("moon.model.metarules.delete.error",{metaRuleName:a.name}).then(function(e){o.alertError(e)}),h.mappingLoading=!1}if(h.selectedMetaRule){h.mappingLoading=!0;var a=angular.copy(h.selectedMetaRule);c.delete(a,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",r)}function a(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 r=angular.copy(c.model);r.meta_rules=_.without(r.meta_rules,c.metaRule.id),n.update(r,i,a)}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/moon_gui/delivery/js/modules.js b/moon_gui/delivery/js/modules.js new file mode 100644 index 00000000..834d4eb8 --- /dev/null +++ b/moon_gui/delivery/js/modules.js @@ -0,0 +1,19 @@ +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 h(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function p(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 h(e,n,i){for(var r=0,o=n.length;r-1&&(i[c]=!(a[c]=d))}}else y=p(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),h=[function(e,n,i){return!o&&(i||n!==E)||((t=n).nodeType?l(e,n,i):c(e,n,i))}];s1&&f(h),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,h=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)&&h--,i&&m.push(u))}if(h+=g,r&&g!==h){for(d=0;f=n[d++];)f(m,v,a,s);if(i){if(h>0)for(;g--;)m[g]||v[g]||(v[g]=G.call(l));v=p(v)}Z.apply(l,v),c&&!i&&v.length>0&&h+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")},he=/^(?:input|select|textarea|button)$/i,pe=/^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,h,p,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;p=g="only"===e&&!p&&"nextSibling"}return!0}if(p=[a?m.firstChild:m.lastChild],a&&$){for(u=m[L]||(m[L]={}),c=u[e]||[],h=c[0]===V&&c[1],f=c[0]===V&&c[2],d=h&&m.childNodes[h];d=++h&&d&&d[g]||(f=h=0)||p.pop();)if(1===d.nodeType&&++f&&d===t){u[e]=[V,h,f];break}}else if($&&(c=(t[L]||(t[L]={}))[e])&&c[0]===V)f=c[1];else for(;(d=++h&&d&&d[g]||(f=h=0)||p.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 pe.test(e.nodeName)},input:function(e){return he.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||(he.resolveWith(Z,[J]),J.fn.triggerHandler&&(J(Z).triggerHandler("ready"),J(Z).off("ready"))))}}),J.ready.promise=function(t){return he||(he=J.Deferred(),"complete"===Z.readyState?setTimeout(J.ready):(Z.addEventListener("DOMContentLoaded",a,!1),e.addEventListener("load",a,!1))),he.promise(t)},J.ready.promise();var pe=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,h,p,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])||[],h=g=s[1],p=(s[2]||"").split(".").sort(),h&&(d=J.event.special[h]||{},h=(r?d.delegateType:d.bindType)||h,d=J.event.special[h]||{},u=J.extend({type:h,origType:g,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&J.expr.match.needsContext.test(r),namespace:p.join(".")},o),(f=l[h])||(f=l[h]=[],f.delegateCount=0,d.setup&&!1!==d.setup.call(e,i,p,a)||e.addEventListener&&e.addEventListener(h,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[h]=!0)},remove:function(e,t,n,i,r){var o,a,s,l,c,u,d,f,h,p,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])||[],h=g=s[1],p=(s[2]||"").split(".").sort(),h){for(d=J.event.special[h]||{},h=(i?d.delegateType:d.bindType)||h,f=l[h]||[],s=s[2]&&new RegExp("(^|\\.)"+p.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,p,m.handle)||J.removeEvent(e,h,m.handle),delete l[h])}else for(h in l)J.event.remove(e,h+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],h=G.call(t,"type")?t.type:t,p=G.call(t,"namespace")?t.namespace.split("."):[];if(a=s=i=i||Z,3!==i.nodeType&&8!==i.nodeType&&!Se.test(h+J.event.triggered)&&(h.indexOf(".")>=0&&(p=h.split("."),h=p.shift(),p.sort()),c=h.indexOf(":")<0&&"on"+h,t=t[J.expando]?t:new J.Event(h,"object"==typeof t&&t),t.isTrigger=r?2:3,t.namespace=p.join("."),t.namespace_re=t.namespace?new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=i),n=null==n?[t]:J.makeArray(n,[t]),d=J.event.special[h]||{},r||!d.trigger||!1!==d.trigger.apply(i,n))){if(!r&&!d.noBubble&&!J.isWindow(i)){for(l=d.delegateType||h,Se.test(l+h)||(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||h,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=h,r||t.isDefaultPrevented()||d._default&&!1!==d._default.apply(f.pop(),n)||!J.acceptData(i)||c&&J.isFunction(i[h])&&!J.isWindow(i)&&(s=i[c],s&&(i[c]=null),J.event.triggered=h,i[h](),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,h=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 pe(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 pe(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"),h),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 pe(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):$/,ht=/^(?:GET|HEAD)$/,pt=/^\/\//,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?p.resolveWith(f,[u,x,w]):p.rejectWith(f,[w,x,v]),w.statusCode(m),m=void 0,c&&h.trigger(l?"ajaxSuccess":"ajaxError",[w,d,l?u:v]),g.fireWith(f,[w,x]),c&&(h.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,h=d.context&&(f.nodeType||f.jquery)?J(f):J.event,p=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(p.promise(w).complete=g.add,w.success=w.done,w.error=w.fail,d.url=((e||d.url||lt)+"").replace(ct,"").replace(pt,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=!ht.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&&h.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(" - - - - - \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/js/app.js b/moonv4/moon_gui/delivery/js/app.js deleted file mode 100644 index ef98d469..00000000 --- a/moonv4/moon_gui/delivery/js/app.js +++ /dev/null @@ -1,4 +0,0 @@ -!function(){"use strict";function e(e,s,d,u){s.useStaticFilesLoader({prefix:"assets/i18n/",suffix:".json"}).preferredLanguage("en").useCookieStorage(),u.theme="selectize",e.when("","/project"),e.when("/","/project"),e.otherwise("/404"),t(d),o(d),n(d),c(d),i(d),a(d),r(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 a(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 r(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,a){function r(e,t,o){-1===["/login"].indexOf(a.path())&&!c.currentUser&&a.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,a,r,l){var s=u(t,i,c,a,r,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 a={};return a.status=c.status,a.message=c.statusText,a.state=t,a.params=o,a}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",r),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://192.168.102.118:38001/pdp/",MODELS:"http://192.168.102.118:38001/models/",METARULES:"http://192.168.102.118:38001/meta_rules/",RULES:"http://192.168.102.118:38001/rules/",POLICIES:"http://192.168.102.118:38001/policies/",METADATA:{subject:"http://192.168.102.118:38001/subject_categories/",object:"http://192.168.102.118:38001/object_categories/",action:"http://192.168.102.118:38001/action_categories/"},PERIMETERS:{subject:"http://192.168.102.118:38001/subjects/",object:"http://192.168.102.118:38001/objects/",action:"http://192.168.102.118:38001/actions/"},KEYSTONE:"http://192.168.102.118:5000/v3/"})}(),function(){"use strict";function e(e,t,o,n,i){function c(){l.loading=!0,e.Login(l.credentials,a,r)}function a(){t("moon.login.success").then(function(e){o.alertSuccess(e),n.go("moon.dashboard"),l.loading=!1})}function r(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 a(){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 r(){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=r,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(){a()}();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 P in T)e.$on("$destroy",T[P])}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,a){function r(){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,a.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 P(e,t){A.addPDP(t),A.refreshPDPs(),A.add.modal.hide()}function E(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=r,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 M={"event:pdpCreatedSuccess":e.$on("event:pdpCreatedSuccess",P),"event:pdpCreatedError":e.$on("event:pdpCreatedError",E),"event:pdpDeletedSuccess":e.$on("event:pdpDeletedSuccess",C),"event:pdpDeletedError":e.$on("event:pdpDeletedError",O)};_.each(M,function(e){t.$on("$destroy",M[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 a(){return j.policies?j.policies:[]}function r(){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=a,j.hasPolicies=r,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 a(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():r()}))}function r(){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,a(!0),y.map.modal.hide()}function f(e){y.map.modal.hide()}function h(e,t){y.pdp=t,a(!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(){a(!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,a){function r(){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 P(e,t){k.deleteProject(t),k.refreshProjects(),k.del.modal.hide()}function E(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){r(),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 M(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 R(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=a,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},r();var L={"event:projectCreatedSuccess":e.$on("event:projectCreatedSuccess",j),"event:projectCreatedError":e.$on("event:projectCreatedError",S),"event:projectDeletedSuccess":e.$on("event:projectDeletedSuccess",P),"event:projectDeletedError":e.$on("event:projectDeletedError",E),"event:projectMappedSuccess":e.$on("event:projectMappedSuccess",C),"event:projectMappedError":e.$on("event:projectMappedError",O),"event:projectUnmappedSuccess":e.$on("event:projectUnmappedSuccess",M),"event:projectUnmappedError":e.$on("event:projectUnmappedError",R)};for(var w in L)t.$on("$destroy",L[w])}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),a.currentLanguage=t}function c(){o.Logout(),e("moon.logout.success").then(function(e){n.alertSuccess(e)})}var a=this;a.isProjectTabActive=t.isProjectTabActive,a.isPDPTabActive=t.isPDPTabActive,a.isLogsTabActive=t.isLogsTabActive,a.isPolicyTabActive=t.isPolicyTabActive,a.isModelTabActive=t.isModelTabActive,a.changeLocale=i,a.logout=c,a.currentLanguage=e.use(),a.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 a(){function a(t){var i=c.transformOne(t,"models");n("moon.model.add.success",{modelName:i.name}).then(function(e){o.alertSuccess(e)}),r.loading=!1,e.$emit("event:modelCreatedSuccess",i)}function l(t){n("moon.model.add.error",{modelName:r.model.name}).then(function(e){o.alertError(e)}),r.loading=!1,e.$emit("event:modelCreatedError",r.project)}i.isInvalid(r.form)?i.checkFieldsValidity(r.form):(r.loading=!0,t.data.create({},r.model,a,l))}var r=this;r.form={},r.loading=!1,r.model={name:null,description:null,meta_rules:[]},r.create=a}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 a(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,a)}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 a={"event:modelUpdatedSuccess":t.$on("event:modelUpdatedSuccess",i),"event:updateModelFromMetaRuleAddSuccess":t.$on("event:updateModelFromMetaRuleAddSuccess",i)};for(var r in a)e.$on("$destroy",a[r])}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 a(){function a(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 r(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,a,r))}function r(){l.modelToEdit=angular.copy(l.model)}var l=this;l.editModel=a,l.init=r,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,a){function r(c){function r(n){t("moon.pdp.add.success",{pdpName:c.name}).then(function(e){o.alertSuccess(e)});var i=a.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},r,s))}var l=this;l.form={},l.pdp={},l.policies=[],l.selectedPolicy=null,l.loading=!1,l.loadingPolicies=!0,l.create=r,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 a(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,a)}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 a={"event:pdpUpdatedSuccess":t.$on("event:pdpUpdatedSuccess",i)};for(var r in a)e.$on("$destroy",a[r])}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 a(){function a(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 r(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,a,r))}function r(){l.pdpToEdit=angular.copy(l.pdp)}var l=this;l.editPdp=a,l.init=r,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,a){function r(){a.findAllWithCallBack(l)}function l(e){d.models=e,d.modelsLoading=!1}function s(){function a(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 r(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},a,r))}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(){r()}()}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 a(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,a)}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(){a.loadingModel=!0,n.findOneWithCallback(a.policy.model_id,function(e){a.loadingModel=!1,a.policy.model=e})}function c(e,t){a.policy=t,i()}var a=this;a.policy=o,a.editBasic=!1,a.showPerimeters=!1,a.showData=!1,a.showRules=!1,a.showAssignments=!1,function(){i()}();var r={"event:policyUpdatedSuccess":t.$on("event:policyUpdatedSuccess",c)};for(var l in r)e.$on("$destroy",r[l])}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,a){function r(){a.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 a(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 r(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,a,r))}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),r()}()}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){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 a={};return a.isProjectTabActive=t,a.isPDPTabActive=o,a.isPolicyTabActive=n,a.isLogsTabActive=i,a.isModelTabActive=c,a}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 a(){delete o.currentUser,n.defaults.headers.common["X-Auth-Token"]="",i.path("/")}function r(){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:r,Logout:a}}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(e,t,o,n,i,c){function a(){function c(n){var i=n.project;t("moon.project.add.success",{projectName:i.name}).then(function(e){o.alertSuccess(e)}),r.loading=!1,e.$emit("event:projectCreatedSuccess",i)}function a(n){t("moon.project.add.error",{projectName:r.project.project.name}).then(function(e){o.alertError(e)}),r.loading=!1,e.$emit("event:projectCreatedError",r.project)}n.isInvalid(r.form)?n.checkFieldsValidity(r.form):(r.loading=!0,i.data.projects.create({},r.project,c,a))}var r=this;r.form={},r.loading=!1,r.project={project:{name:null,description:null,enabled:!0,domain:c.DOMAIN.DEFAULT}},r.create=a}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 a(){return _.has(d.project,"pdp")}function r(){d.loading=!0,a()?l(s):s()}function l(n){function c(n){t("moon.project.remove.mapping.remove.error",{pdpName:a}).then(function(e){o.alertError(e)}),d.loading=!1,e.$emit("event:projectDeletedError",d.project)}var a=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=r,d.isProjectMapped=a,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(){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,a,r){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=r.transformOne(t,"meta_rules"),e.$emit("event:updateMetaRuleFromMetaDataAddSuccess",l),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=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)}a.update(l,t,c)}}function d(){function e(e){var t={};switch(g.metaDataType){case o.TYPE.SUBJECT:t=r.transformOne(e,"subject_categories");break;case o.TYPE.OBJECT:t=r.transformOne(e,"object_categories");break;case o.TYPE.ACTION:t=r.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 a(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,a);break;case o.TYPE.OBJECT:t.object.add(l,e,a);break;case o.TYPE.ACTION:t.action.add(l,e,a)}}}function u(){function c(t){i("moon.model.metadata.edit.delete.success",{name:s.name}).then(function(e){n.alertSuccess(e)}),a.findOneWithMetaData(g.metaRule.id).then(function(t){g.metaRule=t,m(),l(),f(),e.$emit("event:deleteMetaDataFromMetaDataAddSuccess",g.metaRule)})}function r(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,r);break;case o.TYPE.OBJECT:t.object.delete(s,c,r);break;case o.TYPE.ACTION:t.action.delete(s,c,r)}}}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.laoading=!1,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:"=",shortDisplay:"="},restrict:"E",replace:!0}}function t(e,t,o,n,i,c,a,r){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)}),j.metaRule=c.findMetaDataFromMetaRule(r.transformOne(t,"meta_rules")),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 a=angular.copy(j.metaRule);a.subject_categories=_.without(a.subject_categories,e.id),c.update(a,t,o)}function p(e){function t(t){n("moon.model.metarules.update.success",{metaRuleName:j.metaRule.name}).then(function(e){i.alertSuccess(e)}),j.metaRule=c.findMetaDataFromMetaRule(r.transformOne(t,"meta_rules")),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 a=angular.copy(j.metaRule);a.object_categories=_.without(a.object_categories,e.id),c.update(a,t,o)}function f(e){function t(t){n("moon.model.metarules.update.success",{metaRuleName:j.metaRule.name}).then(function(e){i.alertSuccess(e)}),j.metaRule=c.findMetaDataFromMetaRule(r.transformOne(t,"meta_rules")),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 a=angular.copy(j.metaRule);a.action_categories=_.without(a.action_categories,e.id),c.update(a,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=a.TYPE.SUBJECT,j.typeOfObject=a.TYPE.OBJECT,j.typeOfAction=a.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 a(){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 r(){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=r,_.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(){a()}();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,a){function r(){s.policiesLoading=!0,i.findAllWithCallback(function(e){s.policies=e,s.policiesLoading=!1})}function l(){function i(n){var i=a.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 r(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,r)}}var s=this;s.pdps=[],s.pdp=e.pdp,s.addPolicyToList=!1,s.map=l,function(){r()}()}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:a.pdp.name,policyName:a.policy.name}).then(function(e){o.alertSuccess(e)}),a.unMappingLoading=!1,e.$emit("event:policyUnMappedToPdpSuccess",i.transformOne(n,"pdps"))}function r(n){t("moon.policy.unmap.error",{pdpName:a.pdp.name,policyName:a.policy.name}).then(function(e){o.alertError(e)}),a.unMappingLoading=!1,e.$emit("event:policyUnMappedToPdpError")}a.unMappingLoading=!0;var l=angular.copy(a.pdp);l.security_pipeline=_.without(l.security_pipeline,a.policy.id),n.update(l,c,r)}var a=this;a.pdp=e.pdp,a.policy=e.policy,a.unMappingLoading=!1,a.unmap=c}angular.module("moon").controller("PolicyUnMapController",e),e.$inject=["$scope","$translate","alertService","pdpService","utilService"]}(),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){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,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[];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,i){function c(){i.findAllWithCallBack(a)}function a(e){l.pdps=_.filter(e,function(e){return _.isNull(e.keystone_project_id)}),l.pdpsLoading=!1}function r(){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 a(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,a))}var l=this;l.form={},l.project=e.project,l.pdps=[],l.pdpsLoading=!0,l.selectedPDP=null,l.map=r,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:r}).then(function(e){o.alertSuccess(e)}),c.unMappingLoading=!1,delete c.project.mapping,delete c.project.pdp,e.$emit("event:projectUnmappedSuccess",c.project)}function a(n){t("moon.project.unmap.error",{projectName:c.project.name,pdpName:r}).then(function(e){o.alertError(e)}),c.unMappingLoading=!1,e.$emit("event:projectUnmappedError",c.project)}c.unMappingLoading=!0;var r=c.project.pdp.name;n.unMap(c.project.pdp,i,a)}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){function o(e,t){n.metaRule=t}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 a(){function a(t){var o=c.transformOne(t,"meta_rules");i("moon.model.metarules.edit.basic.success",{metaRuleName:o.name}).then(function(e){n.alertSuccess(e)}),l.loading=!1,e.$emit("event:metaRuleBasicUpdatedSuccess",o)}function r(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,a,r))}function r(){l.metaRuleToEdit=angular.copy(l.metaRule)}var l=this;l.editMetaRule=a,l.init=r,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,a,r,l,s,d){function u(){E.assignments={id:null,category_id:null,data_id:null,policy_id:null},p(),h()}function m(){function c(t){var i={};switch(E.assignmentsType){case l.TYPE.SUBJECT:i=a.transformOne(t,"subject_assignments");break;case l.TYPE.OBJECT:i=a.transformOne(t,"object_assignments");break;case l.TYPE.ACTION:i=a.transformOne(t,"action_assignments")}n("moon.policy.assignments.edit.create.success").then(function(e){o.alertSuccess(e)}),s&&i.policy_id===E.policy.id?(e.$emit("event:createAssignmentsFromAssignmentsEditSuccess",E.assignmentsType),u(),P()):s&&(u(),P())}function r(e){n("moon.policy.rules.edit.action.add.create.error").then(function(e){o.alertError(e)}),P()}if(E.assignementsAttributeValid=!0,S(),i.isInvalid(E.form))i.checkFieldsValidity(E.form);else if(E.assignementsAttributeValid){T();var s=!1;E.assignments.id=E.selectedPerimeter.id,E.assignments.category_id=E.selectedCategory.id,E.assignments.policy_id=E.selectedPolicy.id;var d=angular.copy(E.selectedDataList);_.each(d,function(e){E.assignments.data_id=e.id;var o=angular.copy(E.assignments);switch(E.assignmentsType){case l.TYPE.SUBJECT:t.subject.add(o,E.policy.id,c,r);break;case l.TYPE.OBJECT:t.object.add(o,E.policy.id,c,r);break;case l.TYPE.ACTION:t.action.add(o,E.policy.id,c,r)}}),s=!0}}function p(){E.policyList=[],E.loadingPolicies=!0,c.findAllWithCallback(function(e){_.each(e,function(e){e.id===E.policy.id&&(E.selectedPolicy=e)}),E.policyList=e,E.loadingPolicies=!1})}function f(){function e(e){E.perimeterList=e,E.loadingPerimeters=!1}switch(E.perimeterList=[],E.loadingPerimeters=!0,E.assignmentsType){case l.TYPE.SUBJECT:r.subject.findAllFromPolicyWithCallback(E.selectedPolicy.id,e);break;case l.TYPE.OBJECT:r.object.findAllFromPolicyWithCallback(E.selectedPolicy.id,e);break;case l.TYPE.ACTION:r.action.findAllFromPolicyWithCallback(E.selectedPolicy.id,e);break;default:E.perimeterList=[],E.loadingPerimeters=!1}}function h(){function e(e){E.categoryList=e,E.loadingCategories=!1}switch(E.categoryList=[],E.loadingCategories=!0,E.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:E.categoryList=[],E.loadingCategories=!1}}function g(e){function t(e){E.dataList=e,E.dataToBeSelected=angular.copy(E.dataList),E.selectedDataList=[],E.loadingData=!1}switch(E.dataList=[],E.dataToBeSelected=[],E.selectedDataList=[],E.loadingData=!0,E.assignmentsType){case l.TYPE.SUBJECT:d.subject.findAllFromCategoriesWithCallback(E.selectedPolicy.id,e,t);break;case l.TYPE.OBJECT:d.object.findAllFromCategoriesWithCallback(E.selectedPolicy.id,e,t);break;case l.TYPE.ACTION:d.action.findAllFromCategoriesWithCallback(E.selectedPolicy.id,e,t);break;default:E.loadingData=!1}}function y(){E.dataToBeSelected=_.without(E.dataToBeSelected,E.selectedData),E.selectedDataList.push(E.selectedData),b()}function v(e){E.dataToBeSelected.push(e),E.selectedDataList=_.without(E.selectedDataList,e)}function b(){E.selectedData=void 0}function j(e){if(_.isUndefined(e))return"(None)";switch(E.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(){E.selectedDataList.length>=1?E.assignementsAttributeValid=!0:E.assignementsAttributeValid=!1}function T(){E.loading=!0}function P(){E.loading=!1}var E=this;E.assignmentsType=e.edit.assignmentsType,E.policy=e.edit.policy,E.laoading=!1,E.form={},E.policyList=[],E.loadingPolicies=!0,E.categoryList=[],E.loadingCategories=!0,E.perimeterList=[],E.loadingPerimeters=!0,E.dataList=[],E.dataToBeSelected=[],E.selectedDataList=[],E.loadingData=!0,E.assignementsAttributeValid=!0,E.addSelectedData=y,E.removeSelectedData=v,E.getName=j,E.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,a,r,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 a.TYPE.SUBJECT:s.subject.findOneFromPolicyWithCallback($.policy.id,e.subject_id,o);break;case a.TYPE.OBJECT:s.object.findOneFromPolicyWithCallback($.policy.id,e.object_id,o);break;case a.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 a.TYPE.SUBJECT:l.subject.findOne(e.subject_cat_id,o);break;case a.TYPE.OBJECT:l.object.findOne(e.object_cat_id,o);break;case a.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 a.TYPE.SUBJECT:d.subject.data.findOne($.policy.id,t.category_id,t.assignments[e],n);break;case a.TYPE.OBJECT:d.object.data.findOne($.policy.id,t.category_id,t.assignments[e],n);break;case a.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 a(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,a)}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 a(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,a)}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 a(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,a)}function S(){return $.subjects?$.subjects:[]}function T(){return $.objects?$.objects:[]}function P(){return $.actions?$.actions:[]}function E(e,t){switch(t){case a.TYPE.SUBJECT:m();break;case a.TYPE.OBJECT:p();break;case a.TYPE.ACTION:f();break;default:u()}}var $=this;$.policy=e.list.policy,$.editMode=e.list.editMode,$.typeOfSubject=a.TYPE.SUBJECT,$.typeOfObject=a.TYPE.OBJECT,$.typeOfAction=a.TYPE.ACTION,$.deleteSub=v,$.deleteObj=b,$.deleteAct=j,$.getSubjects=S,$.getObjects=T,$.getActions=P,$.getCategoryFromAssignment=g,$.getPerimeterFromAssignment=h,$.getDataFromAssignmentsIndex=y,u();var C={"event:createAssignmentsFromAssignmentsEditSuccess":t.$on("event:createAssignmentsFromAssignmentsEditSuccess",E)};_.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,a,r,l){function s(){function e(e){f.categoriesToBeSelected=e}switch(f.dataType){case o.TYPE.SUBJECT:l.subject.findAllWithCallback(e);break;case o.TYPE.OBJECT:l.object.findAllWithCallback(e);break;case o.TYPE.ACTION:l.action.findAllWithCallback(e);break;default:f.categoriesToBeSelected=[]}}function d(){f.policyList=[],a.findAllWithCallback(function(e){_.each(e,function(e){e.id===f.policy.id&&(f.selectedPolicy=e)}),f.policyList=e})}function u(){function a(t){var c={};switch(f.dataType){case o.TYPE.SUBJECT:c=r.transformOne(t.subject_data,"data");break;case o.TYPE.OBJECT:c=r.transformOne(t.object_data,"data");break;case o.TYPE.ACTION:c=r.transformOne(t.action_data,"data")}i("moon.policy.data.edit.create.success",{name:c.name}).then(function(e){n.alertSuccess(e)}),e.$emit("event:createDataFromDataEditSuccess",c,f.dataType),p(),f.list.push(c)}function l(e){i("moon.policy.data.edit.create.error",{name:s.name}).then(function(e){n.alertError(e)}),p()}if(c.isInvalid(f.form))c.checkFieldsValidity(f.form);else{m();var s=angular.copy(f.data);switch(f.dataType){case o.TYPE.SUBJECT:t.subject.add(s,f.policy.id,f.selectedCategory.id,a,l);break;case o.TYPE.OBJECT:t.object.add(s,f.policy.id,f.selectedCategory.id,a,l);break;case o.TYPE.ACTION:t.action.add(s,f.policy.id,f.selectedCategory.id,a,l)}}}function m(){f.loading=!0}function p(){f.loading=!1}var f=this;f.dataType=e.edit.mnDataType,f.policy=e.edit.policy,f.fromList=!1,f.loading=!1,f.form={},f.data={name:null,description:null},f.list=[],f.policyList=[],f.categoriesToBeSelected=[],f.create=u,function(){function e(e){_.each(e,function(e){e.policy_id!==f.policy.id&&f.list.push(e)})}switch(s(),d(),f.dataType){case o.TYPE.SUBJECT:t.subject.findAllFromPolicyWithCallback(f.policy.id,e);break;case o.TYPE.OBJECT:t.object.findAllFromPolicyWithCallback(f.policy.id,e);break;case o.TYPE.ACTION:t.action.findAllFromPolicyWithCallback(f.policy.id,e);break;default:f.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"]}(),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,a){function r(){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:a.subject.findOne(e.category_id,o);break;case c.TYPE.OBJECT:a.object.findOne(e.category_id,o);break;case c.TYPE.ACTION:a.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(){r(),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,a,r,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=[],r.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:a.name}).then(function(e){i.alertSuccess(e)}),b()}function t(e){c("moon.policy.update.error",{policyName:a.name,reason:e.message}).then(function(e){i.alertError(e)}),b()}if(T.selectedPerimeter){v();var a=T.selectedPerimeter;switch(a.policy_list.push(T.policy.id),T.perimeterType){case n.TYPE.SUBJECT:o.subject.update(a,e,t);break;case n.TYPE.OBJECT:o.object.update(a,e,t);break;case n.TYPE.ACTION:o.action.update(a,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 r(e){c("moon.policy.perimeter.edit.create.error",{name:s.name}).then(function(e){i.alertError(e)}),b()}if(a.isInvalid(T.form))a.checkFieldsValidity(T.form);else{v();var s=angular.copy(T.perimeter);switch(T.perimeterType){case n.TYPE.SUBJECT:o.subject.add(s,t,r);break;case n.TYPE.OBJECT:o.object.add(s,t,r);break;case n.TYPE.ACTION:o.action.add(s,t,r)}}}function g(){function t(t){c("moon.policy.perimeter.edit.delete.success",{name:d.name}).then(function(e){i.alertSuccess(e)}),r.findOneReturningPromise(T.policy.id).then(function(t){T.policy=l.transformOne(t,"policies"),y(),s(),b(),e.$emit("event:deletePerimeterFromPerimeterAddSuccess",T.policy)})}function a(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,a);break;case n.TYPE.OBJECT:o.object.delete(d,t,a);break;case n.TYPE.ACTION:o.action.delete(d,t,a)}}}function y(){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 P={"event:unMapPerimeterFromPerimeterList":t.$on("event:unMapPerimeterFromPerimeterList",S)};_.each(P,function(t){e.$on("$destroy",P[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 a(){r(),l(),s()}function r(){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 r(o){n("moon.policy.perimeter.update.success",{perimeterName:s.name}).then(function(e){i.alertSuccess(e)}),e.$emit("event:unMapPerimeterFromPerimeterList",t,c.TYPE.SUBJECT),a(),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,r,l)}function u(t){function r(o){n("moon.policy.perimeter.update.success",{perimeterName:s.name}).then(function(e){i.alertSuccess(e)}),e.$emit("event:unMapPerimeterFromPerimeterList",t,c.TYPE.OBJECT),a(),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,r,l)}function m(t){function r(o){n("moon.policy.perimeter.update.success",{perimeterName:s.name}).then(function(e){i.alertSuccess(e)}),e.$emit("event:unMapPerimeterFromPerimeterList",t,c.TYPE.ACTION),a(),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,r,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,a()}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,a();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,a,r,l,s,d,u){function m(){R.rules={meta_rule_id:null,rule:[],policy_id:null,instructions:'[{"decision": "grant"}]',enabled:!0},M(),p(),P()}function p(){R.policyList=[],c.findAllWithCallback(function(e){_.each(e,function(e){e.id===R.policy.id&&(R.selectedPolicy=e)}),R.policyList=e})}function f(){R.selectedPolicy.meta_rules_values=void 0,s.findOneWithCallback(R.selectedPolicy.model_id,function(e){r.findSomeWithCallback(e.meta_rules,function(e){R.selectedPolicy.meta_rules_values=e})})}function h(e,t,o){l.subject.findSomeWithCallback(e,function(e){R.categories.subject=e,R.categories.loadingSubjects=!1,_.each(R.categories.subject,function(e){d.subject.findAllFromCategoriesWithCallback(R.selectedPolicy.id,e.id,function(e){R.data.subject=e,R.data.loadingSubjects=!1,R.data.subjectsToBeSelected=angular.copy(R.data.subject)})})}),l.object.findSomeWithCallback(t,function(e){R.categories.object=e,R.categories.loadingObjects=!1,_.each(R.categories.object,function(e){d.object.findAllFromCategoriesWithCallback(R.selectedPolicy.id,e.id,function(e){R.data.object=e,R.data.loadingObjects=!1,R.data.objectsToBeSelected=angular.copy(R.data.object)})})}),l.action.findSomeWithCallback(o,function(e){R.categories.action=e,R.categories.loadingActions=!1,_.each(R.categories.action,function(e){d.action.findAllFromCategoriesWithCallback(R.selectedPolicy.id,e.id,function(e){R.data.action=e,R.data.loadingActions=!1,R.data.actionsToBeSelected=angular.copy(R.data.action)})})})}function g(){function c(t){var i=a.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 r(e){n("moon.policy.rules.edit.action.add.create.error").then(function(e){o.alertError(e)}),T()}if(R.instructionsValid=!0,R.numberOfSelectedSubjectValid=!0,R.numberOfSelectedObjecttValid=!0,R.numberOfSelectedActionsValid=!0,y(),v(),i.isInvalid(R.form))i.checkFieldsValidity(R.form);else if(R.instructionsValid&&v()){S(),A(),R.rules.meta_rule_id=R.selectedMetaRules.id,R.rules.policy_id=R.selectedPolicy.id;var l=angular.copy(R.rules);l.instructions=JSON.parse(R.rules.instructions),t.add(l,R.policy.id,c,r)}}function y(){b(R.rules.instructions)?R.instructionsValid=!0:R.instructionsValid=!1}function v(){return $(u.TYPE.SUBJECT)?R.numberOfSelectedSubjectValid=!0:R.numberOfSelectedSubjectValid=!1,$(u.TYPE.OBJECT)?R.numberOfSelectedObjecttValid=!0:R.numberOfSelectedObjecttValid=!1,$(u.TYPE.ACTION)?R.numberOfSelectedActionsValid=!0:R.numberOfSelectedActionsValid=!1,R.numberOfSelectedSubjectValid&&R.numberOfSelectedObjecttValid&&R.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(){R.loading=!0}function T(){R.loading=!1}function P(){R.selectedMetaRules=void 0,E()}function E(){R.selectedSubject=void 0,R.selectedObject=void 0,R.selectedAction=void 0}function $(e){if(!R.selectedMetaRules)return!1;switch(e){case u.TYPE.SUBJECT:return R.data.selectedSubjectsList.length===R.selectedMetaRules.subject_categories.length;case u.TYPE.OBJECT:return R.data.selectedObjectsList.length===R.selectedMetaRules.object_categories.length;case u.TYPE.ACTION:return R.data.selectedActionsList.length===R.selectedMetaRules.action_categories.length}}function C(e){switch(e){case u.TYPE.SUBJECT:if(!R.selectedSubject||$(e)||_.contains(R.data.selectedSubjectsList,R.selectedSubject))return;R.data.selectedSubjectsList.push(R.selectedSubject),R.data.subjectsToBeSelected=_.without(R.data.subjectsToBeSelected,R.selectedSubject);break;case u.TYPE.OBJECT:if(!R.selectedObject||$(e)||_.contains(R.data.selectedObjectsList,R.selectedObject))return;R.data.selectedObjectsList.push(R.selectedObject),R.data.objectsToBeSelected=_.without(R.data.objectsToBeSelected,R.selectedObject);break;case u.TYPE.ACTION:if(!R.selectedAction||$(e)||_.contains(R.data.selectedActionsList,R.selectedAction))return;R.data.selectedActionsList.push(R.selectedAction),R.data.actionsToBeSelected=_.without(R.data.actionsToBeSelected,R.selectedAction)}}function O(e,t){switch(t){case u.TYPE.SUBJECT:R.data.subjectsToBeSelected.push(e),R.data.selectedSubjectsList=_.without(R.data.selectedSubjectsList,e);break;case u.TYPE.OBJECT:R.data.objectsToBeSelected.push(e),R.data.selectedObjectsList=_.without(R.data.selectedObjectsList,e);break;case u.TYPE.ACTION:R.data.actionsToBeSelected.push(e),R.data.selectedActionsList=_.without(R.data.selectedActionsList,e)}}function A(){function e(e){R.rules.rule.push(e.id)}_.each(R.data.selectedSubjectsList,e),_.each(R.data.selectedObjectsList,e),_.each(R.data.selectedActionsList,e)}function M(){R.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 R=this;R.policy=e.edit.policy,R.editMode=!0,R.fromList=!1,R.loading=!1,R.form={},R.showDetailselectedMetaRules=!1,R.list=[],R.policyList=[],R.categories={subject:[],loadingSubjects:!0,object:[],loadingObjects:!0,action:[],loadingActions:!0},R.data={},R.create=g,R.addDataToRules=C,R.removeSelectedDataFromRules=O,R.isNumberSelectedDataAtMaximum=$,R.instructionsValid=!0,R.numberOfSelectedSubjectValid=!0,R.numberOfSelectedObjecttValid=!0,R.numberOfSelectedActionsValid=!0,m(),e.$watch("edit.selectedPolicy",function(e){P(),_.isUndefined(e)||f()}),e.$watch("edit.selectedMetaRules",function(e){E(),R.categories={subject:[],loadingSubjects:!0,object:[],loadingObjects:!0,action:[],loadingActions:!0},M(),_.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,a,r,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],a.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],a.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],a.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(){r("moon.policy.rules.edit.action.add.delete.success").then(function(e){l.alertSuccess(e)}),S(e),v(),e.loader=!1}function o(t){r("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 P={"event:createRulesFromDataRulesSuccess":t.$on("event:createRulesFromDataRulesSuccess",b)};_.each(P,function(t){e.$on("$destroy",P[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,a){n.subject.policy.remove({policy_id:e,perimeter_id:t,category_id:o,data_id:i},{},c,a)},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,a){n.object.policy.remove({policy_id:e,perimeter_id:t,category_id:o,data_id:i},{},c,a)},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,a){n.action.policy.remove({policy_id:e,perimeter_id:t,category_id:o,data_id:i},{},c,a)},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"}})},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 a(){function a(t){var i=c.transformOne(t,"meta_rules");n("moon.model.metarules.add.success",{metaRuleName:i.name}).then(function(e){o.alertSuccess(e)}),r.loading=!1,e.$emit("event:metaRuleCreatedSuccess",i)}function l(t){n("moon.model.metarules.add.error",{metaRuleName:r.metaRule.name}).then(function(e){o.alertError(e)}),r.loading=!1,e.$emit("event:metaRuleCreatedError",r.project)}i.isInvalid(r.form)?i.checkFieldsValidity(r.form):(r.loading=!0,t.data.create({},r.metaRule,a,l))}var r=this;r.laoading=!1,r.form={},r.metaRule={name:null,description:null,subject_categories:[],object_categories:[],action_categories:[]},r.create=a}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,a,r){function l(){h.metaRulesLoading=!0,c.findAllWithCallback(function(e){h.metaRules=e,h.metaRulesLoading=!1})}function s(){function t(t){var i=r.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),a.update(s,t,l)}}function d(){delete h.selectedMetaRule}function u(){function t(t){n("moon.model.metarules.delete.success",{metaRuleName:a.name}).then(function(e){o.alertSuccess(e)}),d(),h.mappingLoading=!1,l(),e.$emit("event:deleteMetaRule",a)}function i(e){n("moon.model.metarules.delete.error",{metaRuleName:a.name}).then(function(e){o.alertError(e)}),h.mappingLoading=!1}if(h.selectedMetaRule){h.mappingLoading=!0;var a=angular.copy(h.selectedMetaRule);c.delete(a,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",r)}function a(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 r=angular.copy(c.model);r.meta_rules=_.without(r.meta_rules,c.metaRule.id),n.update(r,i,a)}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/moonv4/moon_gui/delivery/js/modules.js b/moonv4/moon_gui/delivery/js/modules.js deleted file mode 100644 index 834d4eb8..00000000 --- a/moonv4/moon_gui/delivery/js/modules.js +++ /dev/null @@ -1,19 +0,0 @@ -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 h(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function p(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 h(e,n,i){for(var r=0,o=n.length;r-1&&(i[c]=!(a[c]=d))}}else y=p(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),h=[function(e,n,i){return!o&&(i||n!==E)||((t=n).nodeType?l(e,n,i):c(e,n,i))}];s1&&f(h),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,h=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)&&h--,i&&m.push(u))}if(h+=g,r&&g!==h){for(d=0;f=n[d++];)f(m,v,a,s);if(i){if(h>0)for(;g--;)m[g]||v[g]||(v[g]=G.call(l));v=p(v)}Z.apply(l,v),c&&!i&&v.length>0&&h+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")},he=/^(?:input|select|textarea|button)$/i,pe=/^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,h,p,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;p=g="only"===e&&!p&&"nextSibling"}return!0}if(p=[a?m.firstChild:m.lastChild],a&&$){for(u=m[L]||(m[L]={}),c=u[e]||[],h=c[0]===V&&c[1],f=c[0]===V&&c[2],d=h&&m.childNodes[h];d=++h&&d&&d[g]||(f=h=0)||p.pop();)if(1===d.nodeType&&++f&&d===t){u[e]=[V,h,f];break}}else if($&&(c=(t[L]||(t[L]={}))[e])&&c[0]===V)f=c[1];else for(;(d=++h&&d&&d[g]||(f=h=0)||p.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 pe.test(e.nodeName)},input:function(e){return he.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||(he.resolveWith(Z,[J]),J.fn.triggerHandler&&(J(Z).triggerHandler("ready"),J(Z).off("ready"))))}}),J.ready.promise=function(t){return he||(he=J.Deferred(),"complete"===Z.readyState?setTimeout(J.ready):(Z.addEventListener("DOMContentLoaded",a,!1),e.addEventListener("load",a,!1))),he.promise(t)},J.ready.promise();var pe=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,h,p,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])||[],h=g=s[1],p=(s[2]||"").split(".").sort(),h&&(d=J.event.special[h]||{},h=(r?d.delegateType:d.bindType)||h,d=J.event.special[h]||{},u=J.extend({type:h,origType:g,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&J.expr.match.needsContext.test(r),namespace:p.join(".")},o),(f=l[h])||(f=l[h]=[],f.delegateCount=0,d.setup&&!1!==d.setup.call(e,i,p,a)||e.addEventListener&&e.addEventListener(h,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[h]=!0)},remove:function(e,t,n,i,r){var o,a,s,l,c,u,d,f,h,p,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])||[],h=g=s[1],p=(s[2]||"").split(".").sort(),h){for(d=J.event.special[h]||{},h=(i?d.delegateType:d.bindType)||h,f=l[h]||[],s=s[2]&&new RegExp("(^|\\.)"+p.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,p,m.handle)||J.removeEvent(e,h,m.handle),delete l[h])}else for(h in l)J.event.remove(e,h+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],h=G.call(t,"type")?t.type:t,p=G.call(t,"namespace")?t.namespace.split("."):[];if(a=s=i=i||Z,3!==i.nodeType&&8!==i.nodeType&&!Se.test(h+J.event.triggered)&&(h.indexOf(".")>=0&&(p=h.split("."),h=p.shift(),p.sort()),c=h.indexOf(":")<0&&"on"+h,t=t[J.expando]?t:new J.Event(h,"object"==typeof t&&t),t.isTrigger=r?2:3,t.namespace=p.join("."),t.namespace_re=t.namespace?new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=i),n=null==n?[t]:J.makeArray(n,[t]),d=J.event.special[h]||{},r||!d.trigger||!1!==d.trigger.apply(i,n))){if(!r&&!d.noBubble&&!J.isWindow(i)){for(l=d.delegateType||h,Se.test(l+h)||(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||h,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=h,r||t.isDefaultPrevented()||d._default&&!1!==d._default.apply(f.pop(),n)||!J.acceptData(i)||c&&J.isFunction(i[h])&&!J.isWindow(i)&&(s=i[c],s&&(i[c]=null),J.event.triggered=h,i[h](),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,h=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 pe(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 pe(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"),h),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 pe(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):$/,ht=/^(?:GET|HEAD)$/,pt=/^\/\//,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?p.resolveWith(f,[u,x,w]):p.rejectWith(f,[w,x,v]),w.statusCode(m),m=void 0,c&&h.trigger(l?"ajaxSuccess":"ajaxError",[w,d,l?u:v]),g.fireWith(f,[w,x]),c&&(h.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,h=d.context&&(f.nodeType||f.jquery)?J(f):J.event,p=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(p.promise(w).complete=g.add,w.success=w.done,w.error=w.fail,d.url=((e||d.url||lt)+"").replace(ct,"").replace(pt,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=!ht.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&&h.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("