aboutsummaryrefslogtreecommitdiffstats
path: root/keystonemiddleware-moon
diff options
context:
space:
mode:
authorWuKong <rebirthmonkey@gmail.com>2017-12-23 21:49:35 +0100
committerWuKong <rebirthmonkey@gmail.com>2017-12-23 21:49:58 +0100
commit1100c66ce03a059ebe7ece9734e799b49b3a5a9e (patch)
treea057e7e7511f6675a9327b79e6919f07c5f89f07 /keystonemiddleware-moon
parent7a4dfdde6314476ae2a1a1c881ff1e3c430f790e (diff)
moonv4 cleanup
Change-Id: Icef927f3236d985ac13ff7376f6ce6314b2b39b0 Signed-off-by: WuKong <rebirthmonkey@gmail.com>
Diffstat (limited to 'keystonemiddleware-moon')
-rw-r--r--keystonemiddleware-moon/.coveragerc7
-rw-r--r--keystonemiddleware-moon/.gitignore55
-rw-r--r--keystonemiddleware-moon/.gitreview4
-rw-r--r--keystonemiddleware-moon/.testr.conf8
-rw-r--r--keystonemiddleware-moon/CONTRIBUTING.rst16
-rw-r--r--keystonemiddleware-moon/HACKING.rst24
-rw-r--r--keystonemiddleware-moon/LICENSE210
-rw-r--r--keystonemiddleware-moon/MANIFEST.in7
-rw-r--r--keystonemiddleware-moon/README.rst19
-rw-r--r--keystonemiddleware-moon/babel.cfg3
-rw-r--r--keystonemiddleware-moon/bandit.yaml134
-rw-r--r--keystonemiddleware-moon/debian/changelog121
-rw-r--r--keystonemiddleware-moon/debian/compat1
-rw-r--r--keystonemiddleware-moon/debian/control136
-rw-r--r--keystonemiddleware-moon/debian/copyright27
-rw-r--r--keystonemiddleware-moon/debian/create_deb.py196
-rw-r--r--keystonemiddleware-moon/debian/gbp.conf9
-rw-r--r--keystonemiddleware-moon/debian/patches/no-intersphinx.patch17
-rw-r--r--keystonemiddleware-moon/debian/patches/re-add-missing-auth-options.patch18
-rw-r--r--keystonemiddleware-moon/debian/patches/series2
-rw-r--r--keystonemiddleware-moon/debian/python-keystonemiddleware-doc.doc-base9
-rwxr-xr-xkeystonemiddleware-moon/debian/rules54
-rw-r--r--keystonemiddleware-moon/debian/source/format1
-rw-r--r--keystonemiddleware-moon/debian/source/options1
-rw-r--r--keystonemiddleware-moon/debian/watch3
-rw-r--r--keystonemiddleware-moon/doc/.gitignore2
-rw-r--r--keystonemiddleware-moon/doc/Makefile90
-rw-r--r--keystonemiddleware-moon/doc/ext/__init__.py0
-rw-r--r--keystonemiddleware-moon/doc/ext/apidoc.py46
-rw-r--r--keystonemiddleware-moon/doc/source/audit.rst81
-rw-r--r--keystonemiddleware-moon/doc/source/conf.py237
-rw-r--r--keystonemiddleware-moon/doc/source/images/audit.pngbin48742 -> 0 bytes
-rw-r--r--keystonemiddleware-moon/doc/source/images/graphs_authComp.svg48
-rw-r--r--keystonemiddleware-moon/doc/source/images/graphs_authCompDelegate.svg53
-rw-r--r--keystonemiddleware-moon/doc/source/index.rst46
-rw-r--r--keystonemiddleware-moon/doc/source/middlewarearchitecture.rst472
-rw-r--r--keystonemiddleware-moon/examples/pki/certs/cacert.pem23
-rw-r--r--keystonemiddleware-moon/examples/pki/certs/middleware.pem50
-rw-r--r--keystonemiddleware-moon/examples/pki/certs/signing_cert.pem22
-rw-r--r--keystonemiddleware-moon/examples/pki/certs/ssl_cert.pem22
-rw-r--r--keystonemiddleware-moon/examples/pki/cms/auth_token_revoked.json85
-rw-r--r--keystonemiddleware-moon/examples/pki/cms/auth_token_revoked.pem75
-rw-r--r--keystonemiddleware-moon/examples/pki/cms/auth_token_revoked.pkiz1
-rw-r--r--keystonemiddleware-moon/examples/pki/cms/auth_token_scoped.json88
-rw-r--r--keystonemiddleware-moon/examples/pki/cms/auth_token_scoped.pem77
-rw-r--r--keystonemiddleware-moon/examples/pki/cms/auth_token_scoped.pkiz1
-rw-r--r--keystonemiddleware-moon/examples/pki/cms/auth_token_scoped_expired.json85
-rw-r--r--keystonemiddleware-moon/examples/pki/cms/auth_token_scoped_expired.pem75
-rw-r--r--keystonemiddleware-moon/examples/pki/cms/auth_token_scoped_expired.pkiz1
-rw-r--r--keystonemiddleware-moon/examples/pki/cms/auth_token_unscoped.json23
-rw-r--r--keystonemiddleware-moon/examples/pki/cms/auth_token_unscoped.pem25
-rw-r--r--keystonemiddleware-moon/examples/pki/cms/auth_token_unscoped.pkiz1
-rw-r--r--keystonemiddleware-moon/examples/pki/cms/auth_v3_token_revoked.json88
-rw-r--r--keystonemiddleware-moon/examples/pki/cms/auth_v3_token_revoked.pem76
-rw-r--r--keystonemiddleware-moon/examples/pki/cms/auth_v3_token_revoked.pkiz1
-rw-r--r--keystonemiddleware-moon/examples/pki/cms/auth_v3_token_scoped.json123
-rw-r--r--keystonemiddleware-moon/examples/pki/cms/auth_v3_token_scoped.pem100
-rw-r--r--keystonemiddleware-moon/examples/pki/cms/auth_v3_token_scoped.pkiz1
-rw-r--r--keystonemiddleware-moon/examples/pki/cms/revocation_list.der0
-rw-r--r--keystonemiddleware-moon/examples/pki/cms/revocation_list.json20
-rw-r--r--keystonemiddleware-moon/examples/pki/cms/revocation_list.pem24
-rw-r--r--keystonemiddleware-moon/examples/pki/cms/revocation_list.pkiz1
-rw-r--r--keystonemiddleware-moon/examples/pki/gen_cmsz.py117
-rwxr-xr-xkeystonemiddleware-moon/examples/pki/gen_pki.sh213
-rw-r--r--keystonemiddleware-moon/examples/pki/private/cakey.pem28
-rw-r--r--keystonemiddleware-moon/examples/pki/private/signing_key.pem28
-rw-r--r--keystonemiddleware-moon/examples/pki/private/ssl_key.pem28
-rwxr-xr-xkeystonemiddleware-moon/examples/pki/run_all.sh31
-rw-r--r--keystonemiddleware-moon/keystonemiddleware.egg-info/dependency_links.txt1
-rw-r--r--keystonemiddleware-moon/keystonemiddleware.egg-info/entry_points.txt3
-rw-r--r--keystonemiddleware-moon/keystonemiddleware.egg-info/not-zip-safe1
-rw-r--r--keystonemiddleware-moon/keystonemiddleware.egg-info/top_level.txt1
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/__init__.py0
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/audit.py449
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/auth_token/__init__.py1129
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/auth_token/_auth.py194
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/auth_token/_base.py13
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/auth_token/_cache.py338
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/auth_token/_exceptions.py27
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/auth_token/_identity.py252
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/auth_token/_memcache_crypt.py210
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/auth_token/_memcache_pool.py184
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/auth_token/_request.py224
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/auth_token/_revocations.py128
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/auth_token/_signing_dir.py83
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/auth_token/_user_plugin.py193
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/auth_token/_utils.py32
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/authz.py292
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/ec2_token.py130
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/echo/__init__.py0
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/echo/__main__.py7
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/echo/service.py48
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/i18n.py37
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/moon_agent.py310
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/moon_mgrs/__init__.py1
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/moon_mgrs/abe_mgr/__init__.py0
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/moon_mgrs/authz_mgr/__init__.py0
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/moon_mgrs/authz_mgr/authz_mgr.py106
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/openstack/__init__.py0
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/openstack/common/__init__.py0
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/openstack/common/memorycache.py97
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/opts.py52
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/s3_token.py270
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/tests/__init__.py0
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/tests/unit/__init__.py0
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/__init__.py0
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/base.py73
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_auth.py102
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py2634
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_base_middleware.py202
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_connection_pool.py118
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_memcache_crypt.py97
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_request.py253
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_revocations.py104
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_signing_dir.py137
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_user_auth_plugin.py201
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/test_utils.py37
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/tests/unit/client_fixtures.py452
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/tests/unit/test_audit_middleware.py560
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/tests/unit/test_opts.py86
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/tests/unit/test_s3_token_middleware.py268
-rw-r--r--keystonemiddleware-moon/keystonemiddleware/tests/unit/utils.py150
-rw-r--r--keystonemiddleware-moon/openstack-common.conf7
-rw-r--r--keystonemiddleware-moon/requirements.txt16
-rw-r--r--keystonemiddleware-moon/setup.cfg57
-rw-r--r--keystonemiddleware-moon/setup.py29
-rw-r--r--keystonemiddleware-moon/test-requirements-py3.txt18
-rw-r--r--keystonemiddleware-moon/test-requirements.txt24
-rw-r--r--keystonemiddleware-moon/tools/install_venv_common.py172
-rw-r--r--keystonemiddleware-moon/tox.ini50
130 files changed, 0 insertions, 14349 deletions
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
-<https://github.com/openstack/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ý <novy@ondrej.org> 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 <zigo@debian.org> 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 <zigo@debian.org> 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 <zigo@debian.org> 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 <zigo@debian.org> 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 <zigo@debian.org> Fri, 04 Dec 2015 11:02:00 +0100
-
-python-keystonemiddleware (2.3.0-3) unstable; urgency=medium
-
- * Uploading to unstable.
-
- -- Thomas Goirand <zigo@debian.org> Fri, 16 Oct 2015 10:04:17 +0000
-
-python-keystonemiddleware (2.3.0-2) experimental; urgency=medium
-
- * Added Python 3 support.
-
- -- Thomas Goirand <zigo@debian.org> 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 <corey.bryant@canonical.com> Wed, 30 Sep 2015 14:42:41 -0400
-
-python-keystonemiddleware (2.1.0-2) experimental; urgency=medium
-
- * Removed python-bandit build-depends.
-
- -- Thomas Goirand <zigo@debian.org> 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 <zigo@debian.org> 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 <zigo@debian.org> 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 <zigo@debian.org> 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 <luciano@debian.org> for the report (Closes: #762748).
-
- -- Thomas Goirand <zigo@debian.org> 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 <zigo@debian.org> Mon, 28 Jul 2014 00:29:44 +0800
-
-python-keystonemiddleware (1.0.0-1) unstable; urgency=medium
-
- * Initial release. (Closes: #755135)
-
- -- Thomas Goirand <zigo@debian.org> 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 <openstack-devel@lists.alioth.debian.org>
-Uploaders: Thomas Goirand <zigo@debian.org>,
- Corey Bryant <corey.bryant@canonical.com>,
-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 <openstack-dev@lists.openstack.org>
-License: Apache-2
-
-Files: debian/*
-Copyright: (c) 2014-2016, Thomas Goirand <zigo@debian.org>
-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 <thomas.duval@orange.com> {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 <zigo@debian.org>
-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 <zigo@debian.org>
-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 <target>' where <target> 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
--- a/keystonemiddleware-moon/doc/ext/__init__.py
+++ /dev/null
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
-# "<project> v<release> 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 <link> 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
--- a/keystonemiddleware-moon/doc/source/images/audit.png
+++ /dev/null
Binary files 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 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545)
- -->
-<!-- Title: AuthComp Pages: 1 -->
-<svg width="510pt" height="118pt"
- viewBox="0.00 0.00 510.00 118.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 114)">
-<title>AuthComp</title>
-<polygon fill="white" stroke="white" points="-4,5 -4,-114 507,-114 507,5 -4,5"/>
-<!-- AuthComp -->
-<g id="node2" class="node"><title>AuthComp</title>
-<polygon fill="#fdefe3" stroke="#c00000" points="292,-65 194,-65 194,-25 292,-25 292,-65"/>
-<text text-anchor="middle" x="243" y="-48.4" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text>
-<text text-anchor="middle" x="243" y="-32.4" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text>
-</g>
-<!-- Reject -->
-<!-- AuthComp&#45;&gt;Reject -->
-<g id="edge3" class="edge"><title>AuthComp&#45;&gt;Reject</title>
-<path fill="none" stroke="black" d="M193.933,-51.2787C157.514,-55.939 108.38,-62.2263 73.8172,-66.649"/>
-<polygon fill="black" stroke="black" points="73.0637,-63.2168 63.5888,-67.9578 73.9522,-70.1602 73.0637,-63.2168"/>
-<text text-anchor="middle" x="129" y="-97.4" font-family="Times,serif" font-size="14.00">Reject</text>
-<text text-anchor="middle" x="129" y="-82.4" font-family="Times,serif" font-size="14.00">Unauthenticated</text>
-<text text-anchor="middle" x="129" y="-67.4" font-family="Times,serif" font-size="14.00">Requests</text>
-</g>
-<!-- Service -->
-<g id="node6" class="node"><title>Service</title>
-<polygon fill="#d1ebf1" stroke="#1f477d" points="502,-65 408,-65 408,-25 502,-25 502,-65"/>
-<text text-anchor="middle" x="455" y="-48.4" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text>
-<text text-anchor="middle" x="455" y="-32.4" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text>
-</g>
-<!-- AuthComp&#45;&gt;Service -->
-<g id="edge5" class="edge"><title>AuthComp&#45;&gt;Service</title>
-<path fill="none" stroke="black" d="M292.17,-45C323.626,-45 364.563,-45 397.52,-45"/>
-<polygon fill="black" stroke="black" points="397.917,-48.5001 407.917,-45 397.917,-41.5001 397.917,-48.5001"/>
-<text text-anchor="middle" x="350" y="-77.4" font-family="Times,serif" font-size="14.00">Forward</text>
-<text text-anchor="middle" x="350" y="-62.4" font-family="Times,serif" font-size="14.00">Authenticated</text>
-<text text-anchor="middle" x="350" y="-47.4" font-family="Times,serif" font-size="14.00">Requests</text>
-</g>
-<!-- Start -->
-<!-- Start&#45;&gt;AuthComp -->
-<g id="edge7" class="edge"><title>Start&#45;&gt;AuthComp</title>
-<path fill="none" stroke="black" d="M59.1526,-21.4745C90.4482,-25.4792 142.816,-32.1802 183.673,-37.4084"/>
-<polygon fill="black" stroke="black" points="183.43,-40.9057 193.793,-38.7034 184.318,-33.9623 183.43,-40.9057"/>
-</g>
-</g>
-</svg>
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 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545)
- -->
-<!-- Title: AuthCompDelegate Pages: 1 -->
-<svg width="588pt" height="104pt"
- viewBox="0.00 0.00 588.00 104.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 100)">
-<title>AuthCompDelegate</title>
-<polygon fill="white" stroke="white" points="-4,5 -4,-100 585,-100 585,5 -4,5"/>
-<!-- AuthComp -->
-<g id="node2" class="node"><title>AuthComp</title>
-<polygon fill="#fdefe3" stroke="#c00000" points="338,-65 240,-65 240,-25 338,-25 338,-65"/>
-<text text-anchor="middle" x="289" y="-48.4" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text>
-<text text-anchor="middle" x="289" y="-32.4" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text>
-</g>
-<!-- Reject -->
-<!-- AuthComp&#45;&gt;Reject -->
-<g id="edge3" class="edge"><title>AuthComp&#45;&gt;Reject</title>
-<path fill="none" stroke="black" d="M239.6,-50.1899C191.406,-55.2531 118.917,-62.8686 73.5875,-67.6309"/>
-<polygon fill="black" stroke="black" points="73.0928,-64.1635 63.5132,-68.6893 73.8242,-71.1252 73.0928,-64.1635"/>
-<text text-anchor="middle" x="152" y="-83.4" font-family="Times,serif" font-size="14.00">Reject Requests</text>
-<text text-anchor="middle" x="152" y="-68.4" font-family="Times,serif" font-size="14.00">Indicated by the Service</text>
-</g>
-<!-- Service -->
-<g id="node6" class="node"><title>Service</title>
-<polygon fill="#d1ebf1" stroke="#1f477d" points="580,-65 486,-65 486,-25 580,-25 580,-65"/>
-<text text-anchor="middle" x="533" y="-48.4" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text>
-<text text-anchor="middle" x="533" y="-32.4" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text>
-</g>
-<!-- AuthComp&#45;&gt;Service -->
-<g id="edge5" class="edge"><title>AuthComp&#45;&gt;Service</title>
-<path fill="none" stroke="black" d="M338.009,-49.0804C344.065,-49.4598 350.172,-49.7828 356,-50 405.743,-51.8535 418.259,-51.9103 468,-50 470.523,-49.9031 473.101,-49.7851 475.704,-49.6504"/>
-<polygon fill="black" stroke="black" points="476.03,-53.1374 485.807,-49.0576 475.62,-46.1494 476.03,-53.1374"/>
-<text text-anchor="middle" x="412" y="-68.4" font-family="Times,serif" font-size="14.00">Forward Requests</text>
-<text text-anchor="middle" x="412" y="-53.4" font-family="Times,serif" font-size="14.00">with Identiy Status</text>
-</g>
-<!-- Service&#45;&gt;AuthComp -->
-<g id="edge7" class="edge"><title>Service&#45;&gt;AuthComp</title>
-<path fill="none" stroke="black" d="M495.062,-24.9037C486.397,-21.2187 477.064,-17.9304 468,-16 419.314,-5.63183 404.743,-5.9037 356,-16 349.891,-17.2653 343.655,-19.116 337.566,-21.2803"/>
-<polygon fill="black" stroke="black" points="336.234,-18.0426 328.158,-24.9003 338.748,-24.5757 336.234,-18.0426"/>
-<text text-anchor="middle" x="412" y="-33.4" font-family="Times,serif" font-size="14.00">Send Response OR</text>
-<text text-anchor="middle" x="412" y="-18.4" font-family="Times,serif" font-size="14.00">Reject Message</text>
-</g>
-<!-- Start -->
-<!-- Start&#45;&gt;AuthComp -->
-<g id="edge9" class="edge"><title>Start&#45;&gt;AuthComp</title>
-<path fill="none" stroke="black" d="M59.0178,-20.8384C99.2135,-25.0613 175.782,-33.1055 229.492,-38.7482"/>
-<polygon fill="black" stroke="black" points="229.265,-42.2435 239.576,-39.8076 229.997,-35.2818 229.265,-42.2435"/>
-</g>
-</g>
-</svg>
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=<None>
-
- # API version of the admin Identity API endpoint (string
- # value)
- #auth_version=<None>
-
- # 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=<None>
-
- # 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=<None>
-
- # Keystone account username (string value)
- #admin_user=<None>
-
- # 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=<None>
-
- # Required if Keystone server requires client certificate
- # (string value)
- #certfile=<None>
-
- # Required if Keystone server requires client certificate
- # (string value)
- #keyfile=<None>
-
- # A PEM encoded Certificate Authority to use when verifying
- # HTTPs connections. Defaults to system CAs. (string value)
- #cafile=<None>
-
- # Verify HTTPS connections. (boolean value)
- #insecure=false
-
- # Directory used to cache files related to PKI tokens (string
- # value)
- #signing_dir=<None>
-
- # If defined, the memcached server(s) to use for caching (list
- # value)
- # Deprecated group/name - [DEFAULT]/memcache_servers
- #memcached_servers=<None>
-
- # 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=<None>
-
- # (optional, mandatory if memcache_security_strategy is
- # defined) this string is used for key derivation. (string
- # value)
- #memcache_secret_key=<None>
-
- # (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
--- a/keystonemiddleware-moon/examples/pki/cms/revocation_list.der
+++ /dev/null
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
--- a/keystonemiddleware-moon/keystonemiddleware/__init__.py
+++ /dev/null
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<account>[\w_-]+)$", "GET", "get_account_details"),
- ("^/v1/(?P<account>[\w_-]+)$", "POST", "modify_account"),
- ("^/v1/(?P<account>[\w_-]+)$", "HEAD", "get_account"),
- ("^/v1/(?P<account>[\w_-]+)/(?P<container>[\w-]+)$", "GET", "get_container"),
- ("^/v1/(?P<account>[\w_-]+)/(?P<container>[\w-]+)$", "PUT", "create_container"),
- ("^/v1/(?P<account>[\w_-]+)/(?P<container>[\w-]+)$", "POST", "update_container_metadata"),
- ("^/v1/(?P<account>[\w_-]+)/(?P<container>[\w-]+)$", "DELETE", "delete_container"),
- ("^/v1/(?P<account>[\w_-]+)/(?P<container>[\w-]+)$", "HEAD", "get_container_metadata"),
- ("^/v1/(?P<account>[\w_-]+)/(?P<container>[\w-]+)/(?P<object>.+)$", "GET", "get_object"),
- ("^/v1/(?P<account>[\w_-]+)/(?P<container>[\w-]+)/(?P<object>.+)$", "PUT", "create_object"),
- ("^/v1/(?P<account>[\w_-]+)/(?P<container>[\w-]+)/(?P<object>.+)$", "COPY", "copy_object"),
- ("^/v1/(?P<account>[\w_-]+)/(?P<container>[\w-]+)/(?P<object>.+)$", "POST", "update_object_metadata"),
- ("^/v1/(?P<account>[\w_-]+)/(?P<container>[\w-]+)/(?P<object>.+)$", "DELETE", "delete_object"),
- ("^/v1/(?P<account>[\w_-]+)/(?P<container>[\w-]+)/(?P<object>.+)$", "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 = ('<?xml version="1.0" encoding="UTF-8"?>\r\n'
- '<Error>\r\n <Code>%s</Code>\r\n '
- '<Message>%s</Message>\r\n</Error>\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:
- # /<tenant_id>/servers/<server_id>
- # list details for server_id
- # /<tenant_id>/servers/<server_id>/action
- # execute action to server_id
- # /<tenant_id>/servers/<server_id>/metadata
- # show metadata from server_id
- # /<tenant_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
--- a/keystonemiddleware-moon/keystonemiddleware/echo/__init__.py
+++ /dev/null
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<account>[\w_-]+)$", "GET", "get_account_details"),
- ("^/v1/(?P<account>[\w_-]+)$", "POST", "modify_account"),
- ("^/v1/(?P<account>[\w_-]+)$", "HEAD", "get_account"),
- ("^/v1/(?P<account>[\w_-]+)/(?P<container>[\w-]+)$", "GET", "get_container"),
- ("^/v1/(?P<account>[\w_-]+)/(?P<container>[\w-]+)$", "PUT", "create_container"),
- ("^/v1/(?P<account>[\w_-]+)/(?P<container>[\w-]+)$", "POST", "update_container_metadata"),
- ("^/v1/(?P<account>[\w_-]+)/(?P<container>[\w-]+)$", "DELETE", "delete_container"),
- ("^/v1/(?P<account>[\w_-]+)/(?P<container>[\w-]+)$", "HEAD", "get_container_metadata"),
- ("^/v1/(?P<account>[\w_-]+)/(?P<container>[\w-]+)/(?P<object>.+)$", "GET", "get_object"),
- ("^/v1/(?P<account>[\w_-]+)/(?P<container>[\w-]+)/(?P<object>.+)$", "PUT", "create_object"),
- ("^/v1/(?P<account>[\w_-]+)/(?P<container>[\w-]+)/(?P<object>.+)$", "COPY", "copy_object"),
- ("^/v1/(?P<account>[\w_-]+)/(?P<container>[\w-]+)/(?P<object>.+)$", "POST", "update_object_metadata"),
- ("^/v1/(?P<account>[\w_-]+)/(?P<container>[\w-]+)/(?P<object>.+)$", "DELETE", "delete_object"),
- ("^/v1/(?P<account>[\w_-]+)/(?P<container>[\w-]+)/(?P<object>.+)$", "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:
- # /<tenant_id>/servers/<server_id>
- # list details for server_id
- # /<tenant_id>/servers/<server_id>/action
- # execute action to server_id
- # /<tenant_id>/servers/<server_id>/metadata
- # show metadata from server_id
- # /<tenant_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
--- a/keystonemiddleware-moon/keystonemiddleware/moon_mgrs/abe_mgr/__init__.py
+++ /dev/null
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
--- a/keystonemiddleware-moon/keystonemiddleware/moon_mgrs/authz_mgr/__init__.py
+++ /dev/null
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 = ('<?xml version="1.0" encoding="UTF-8"?>\r\n'
- '<Error>\r\n <Code>%s</Code>\r\n '
- '<Message>%s</Message>\r\n</Error>\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
--- a/keystonemiddleware-moon/keystonemiddleware/openstack/__init__.py
+++ /dev/null
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
--- a/keystonemiddleware-moon/keystonemiddleware/openstack/common/__init__.py
+++ /dev/null
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 <akirayoshiyama@gmail.com>
-# 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 = ('<?xml version="1.0" encoding="UTF-8"?>\r\n'
- '<Error>\r\n <Code>%s</Code>\r\n '
- '<Message>%s</Message>\r\n</Error>\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
--- a/keystonemiddleware-moon/keystonemiddleware/tests/__init__.py
+++ /dev/null
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
--- a/keystonemiddleware-moon/keystonemiddleware/tests/unit/__init__.py
+++ /dev/null
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
--- a/keystonemiddleware-moon/keystonemiddleware/tests/unit/auth_token/__init__.py
+++ /dev/null
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="<badreply>")
-
- 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