python-django-openstack-auth-1.1.3/0000755000175000017500000000000012222632612016173 5ustar chuckchuckpython-django-openstack-auth-1.1.3/.tx/0000755000175000017500000000000012222632612016704 5ustar chuckchuckpython-django-openstack-auth-1.1.3/.tx/config0000644000175000017500000000030512222632545020077 0ustar chuckchuck[main] host = https://www.transifex.com [horizon.djangopo] file_filter = openstack_auth/locale//LC_MESSAGES/django.po source_file = openstack_auth/locale/openstack_auth.pot source_lang = en python-django-openstack-auth-1.1.3/LICENSE0000644000175000017500000002363712222632545017220 0ustar chuckchuck 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. python-django-openstack-auth-1.1.3/requirements.txt0000644000175000017500000000007712222632545021470 0ustar chuckchuckpbr>=0.5.21,<1.0 Django>=1.4,<1.6 python-keystoneclient>=0.3.2 python-django-openstack-auth-1.1.3/README.rst0000644000175000017500000000220112222632545017662 0ustar chuckchuck===================== Django OpenStack Auth ===================== Django OpenStack Auth is a pluggable Django authentication backend that works with Django's ``contrib.auth`` framework to authenticate a user against OpenStack's Keystone Identity API. The current version is designed to work with the Keystone V2 API. You can `view the documentation`_ on Read The Docs. .. _view the documentation: http://django-openstack-auth.readthedocs.org/en/latest/ Installation ============ Installing is quick and easy: #. Run ``pip install django_openstack_auth``. #. Add ``openstack_auth`` to ``settings.INSTALLED_APPS``. #. Add ``'keystone_auth.backend.KeystoneBackend'`` to your ``settings.AUTHENTICATION_BACKENDS``, e.g.:: AUTHENTICATION_BACKENDS = ('keystone_auth.backend.KeystoneBackend',) #. Configure your API endpoint(s) in ``settings.py``:: OPENSTACK_KEYSTONE_URL = "http://example.com:5000/v2.0" #. Include ``'keystone_auth.urls'`` somewhere in your ``urls.py`` file. #. Use it as you would any other Django auth backend. Running The Tests ================= Download the repository and run:: python setup.py testpython-django-openstack-auth-1.1.3/doc/0000755000175000017500000000000012222632612016740 5ustar chuckchuckpython-django-openstack-auth-1.1.3/doc/source/0000755000175000017500000000000012222632612020240 5ustar chuckchuckpython-django-openstack-auth-1.1.3/doc/source/installation.rst0000644000175000017500000000135012222632545023477 0ustar chuckchuck=============== Getting Started =============== Installation ============ Installing is quick and easy: #. Run ``pip install django_openstack_auth``. #. Add ``openstack_auth`` to ``settings.INSTALLED_APPS``. #. Add ``'keystone_auth.backend.KeystoneBackend'`` to your ``settings.AUTHENTICATION_BACKENDS``, e.g.:: AUTHENTICATION_BACKENDS = ('keystone_auth.backend.KeystoneBackend',) #. Configure your API endpoint(s) in ``settings.py``:: OPENSTACK_KEYSTONE_URL = "http://example.com:5000/v2.0" #. Include ``'keystone_auth.urls'`` somewhere in your ``urls.py`` file. #. Use it as you would any other Django auth backend. Running The Tests ================= Download the repository and run:: python setup.py testpython-django-openstack-auth-1.1.3/doc/source/conf.py0000644000175000017500000001673212222632545021555 0ustar chuckchuck# -*- coding: utf-8 -*- # # Django OpenStack Auth documentation build configuration file, created by # sphinx-quickstart on Sun Jul 8 15:13:36 2012. # # 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. # 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.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # 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.viewcode', 'oslo.sphinx'] # 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-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'Django OpenStack Auth' copyright = u'2012, Gabriel Hurley' # 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 patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] # 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 = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # 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_domain_indices = 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, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'DjangoOpenStackAuthdoc' # -- Options for LaTeX output -------------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). #'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). #'pointsize': '10pt', # Additional stuff for the LaTeX preamble. #'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'DjangoOpenStackAuth.tex', u'Django OpenStack Auth Documentation', u'Gabriel Hurley', '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 # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'djangoopenstackauth', u'Django OpenStack Auth Documentation', [u'Gabriel Hurley'], 1) ] # If true, show URL addresses after external links. #man_show_urls = False # -- Options for Texinfo output ------------------------------------------------ # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ('index', 'DjangoOpenStackAuth', u'Django OpenStack Auth Documentation', u'Gabriel Hurley', 'DjangoOpenStackAuth', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. #texinfo_appendices = [] # If false, no module index is generated. #texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. #texinfo_show_urls = 'footnote' python-django-openstack-auth-1.1.3/doc/source/index.rst0000644000175000017500000000101512222632545022103 0ustar chuckchuck===================== Django OpenStack Auth ===================== Django OpenStack Auth is a pluggable Django authentication backend that works with Django's ``contrib.auth`` framework to authenticate a user against OpenStack's Keystone Identity API. The current version is designed to work with the Keystone V2 API. .. toctree:: :maxdepth: 2 installation ref/user ref/views ref/forms ref/backend ref/utils Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` python-django-openstack-auth-1.1.3/doc/source/ref/0000755000175000017500000000000012222632612021014 5ustar chuckchuckpython-django-openstack-auth-1.1.3/doc/source/ref/forms.rst0000644000175000017500000000014612222632545022702 0ustar chuckchuck================ The Forms Module ================ .. automodule:: openstack_auth.forms :members: python-django-openstack-auth-1.1.3/doc/source/ref/views.rst0000644000175000017500000000014612222632545022711 0ustar chuckchuck================ The Views Module ================ .. automodule:: openstack_auth.views :members: python-django-openstack-auth-1.1.3/doc/source/ref/utils.rst0000644000175000017500000000014612222632545022714 0ustar chuckchuck================ The Utils Module ================ .. automodule:: openstack_auth.utils :members: python-django-openstack-auth-1.1.3/doc/source/ref/backend.rst0000644000175000017500000000015612222632545023144 0ustar chuckchuck================== The Backend Module ================== .. automodule:: openstack_auth.backend :members: python-django-openstack-auth-1.1.3/doc/source/ref/user.rst0000644000175000017500000000015312222632545022530 0ustar chuckchuck================== The ``User`` Class ================== .. automodule:: openstack_auth.user :members: python-django-openstack-auth-1.1.3/setup.py0000755000175000017500000000141512222632545017716 0ustar chuckchuck#!/usr/bin/env python # 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 setuptools.setup( setup_requires=['pbr'], pbr=True) python-django-openstack-auth-1.1.3/test-requirements.txt0000644000175000017500000000012412222632545022436 0ustar chuckchuckhacking>=0.5.6,<0.8 Babel>=0.9.6 coverage>=3.6 mox>=0.5.3 sphinx>=1.1.2 oslo.sphinx python-django-openstack-auth-1.1.3/PKG-INFO0000644000175000017500000000463112222632612017274 0ustar chuckchuckMetadata-Version: 1.1 Name: django_openstack_auth Version: 1.1.3 Summary: Django authentication backend for use with OpenStack Identity Home-page: http://www.openstack.org/ Author: OpenStack Author-email: openstack-dev@lists.openstack.org License: UNKNOWN Description: ===================== Django OpenStack Auth ===================== Django OpenStack Auth is a pluggable Django authentication backend that works with Django's ``contrib.auth`` framework to authenticate a user against OpenStack's Keystone Identity API. The current version is designed to work with the Keystone V2 API. You can `view the documentation`_ on Read The Docs. .. _view the documentation: http://django-openstack-auth.readthedocs.org/en/latest/ Installation ============ Installing is quick and easy: #. Run ``pip install django_openstack_auth``. #. Add ``openstack_auth`` to ``settings.INSTALLED_APPS``. #. Add ``'keystone_auth.backend.KeystoneBackend'`` to your ``settings.AUTHENTICATION_BACKENDS``, e.g.:: AUTHENTICATION_BACKENDS = ('keystone_auth.backend.KeystoneBackend',) #. Configure your API endpoint(s) in ``settings.py``:: OPENSTACK_KEYSTONE_URL = "http://example.com:5000/v2.0" #. Include ``'keystone_auth.urls'`` somewhere in your ``urls.py`` file. #. Use it as you would any other Django auth backend. Running The Tests ================= Download the repository and run:: python setup.py test Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: OpenStack Classifier: Framework :: Django Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Information Technology Classifier: Intended Audience :: System Administrators Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: OS Independent Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 2.6 Classifier: Topic :: Internet :: WWW/HTTP python-django-openstack-auth-1.1.3/babel.cfg0000644000175000017500000000002012222632545017716 0ustar chuckchuck[python: **.py] python-django-openstack-auth-1.1.3/tox.ini0000644000175000017500000000303612222632545017515 0ustar chuckchuck[tox] envlist = py26,py27,py27dj14,pep8,py33 [testenv] setenv = VIRTUAL_ENV={envdir} NOSE_WITH_OPENSTACK=1 NOSE_OPENSTACK_COLOR=1 NOSE_OPENSTACK_RED=0.05 NOSE_OPENSTACK_YELLOW=0.025 NOSE_OPENSTACK_SHOW_ELAPSED=1 deps = -r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt commands = python openstack_auth/tests/run_tests.py [testenv:pep8] commands = flake8 [testenv:venv] commands = {posargs} [tox:jenkins] downloadcache = ~/cache/pip [flake8] builtins = _ exclude = .venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build,panel_template,dash_template,local_settings.py # E121 continuation line indentation is not a multiple of four # E126 continuation line over-indented for hanging indent # E127 continuation line over-indented for visual indent # E128 continuation line under-indented for visual indent # F401 '' imported but unused # F403 'from import *' used; unable to detect undefined names # F841 local variable '' is assigned to but never used # F999 syntax error in doctest # H201 no 'except:' at least use 'except Exception:' # H302 import only modules.'from optparse import make_option' does not import a module # H303 No wildcard (*) import. # H304 No relative imports. 'from .views import IndexView' is a relative import # H4xx docstrings # H701 empty localization string # H702 Formatting operation should be outside of localization method call ignore = E121,E126,E127,E128,E501,E502,F403,F841,F999,H201,H301,H306,H302,H303,H304,H4,H701,H702,H803 python-django-openstack-auth-1.1.3/.mailmap0000644000175000017500000000047712222632545017631 0ustar chuckchuck Eric Peterson ericpeterson-l Eric Peterson erpet Lin Hua Cheng linhuacheng python-django-openstack-auth-1.1.3/setup.cfg0000644000175000017500000000227712222632612020024 0ustar chuckchuck[metadata] name = django_openstack_auth summary = Django authentication backend for use with OpenStack Identity description-file = README.rst author = OpenStack author-email = openstack-dev@lists.openstack.org home-page = http://www.openstack.org/ classifier = Development Status :: 5 - Production/Stable Environment :: OpenStack Framework :: Django Intended Audience :: Developers Intended Audience :: Information Technology Intended Audience :: System Administrators License :: OSI Approved :: Apache Software License Operating System :: OS Independent Operating System :: POSIX :: Linux Programming Language :: Python Programming Language :: Python :: 2 Programming Language :: Python :: 2.7 Programming Language :: Python :: 2.6 Topic :: Internet :: WWW/HTTP [files] packages = openstack_auth [build_sphinx] all_files = 1 build-dir = doc/build source-dir = doc/source [nosetests] verbosity = 2 detailed-errors = 1 [extract_messages] keywords = _ gettext ngettext l_ lazy_gettext mapping_file = babel.cfg output_file = openstack_auth/locale/openstack_auth.pot [compile_catalog] directory = openstack_auth/locale domain = django [egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 python-django-openstack-auth-1.1.3/MANIFEST.in0000644000175000017500000000013612222632545017736 0ustar chuckchuckinclude AUTHORS include ChangeLog exclude .gitignore exclude .gitreview global-exclude *.pyc python-django-openstack-auth-1.1.3/AUTHORS0000644000175000017500000000122012222632612017236 0ustar chuckchuckAkihiro MOTOKI David Lyle Dirk Mueller Eric Peterson Gabriel Hurley Kieran Spear Lin Hua Cheng Matthias Runge Maxime Vidori Monty Taylor Sam Stoelinga Sascha Peilicke Timur Sufiev Vincent Untz Yves-Gwenael Bourhis daisy-ycguo linhuacheng Łukasz Oleś python-django-openstack-auth-1.1.3/openstack_auth/0000755000175000017500000000000012222632612021203 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/user.py0000644000175000017500000002603612222632545022547 0ustar chuckchuck# 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 hashlib import logging from django.contrib.auth.models import AnonymousUser from django.conf import settings from keystoneclient import exceptions as keystone_exceptions from .utils import check_token_expiration from .utils import get_keystone_version from .utils import get_project_list from .utils import is_ans1_token LOG = logging.getLogger(__name__) def set_session_from_user(request, user): request.session['token'] = user.token request.session['user_id'] = user.id request.session['region_endpoint'] = user.endpoint request.session['services_region'] = user.services_region def create_user_from_token(request, token, endpoint, services_region=None): return User(id=token.user['id'], token=token, user=token.user['name'], user_domain_id=token.user_domain_id, project_id=token.project['id'], project_name=token.project['name'], domain_id=token.domain['id'], domain_name=token.domain['name'], enabled=True, service_catalog=token.serviceCatalog, roles=token.roles, endpoint=endpoint, services_region=services_region) class Token(object): """Token object that encapsulates the auth_ref (AccessInfo)from keystone client. Added for maintaining backward compatibility with horizon that expects Token object in the user object. """ def __init__(self, auth_ref): # User-related attributes user = {} user['id'] = auth_ref.user_id user['name'] = auth_ref.username self.user = user self.user_domain_id = auth_ref.user_domain_id #Token-related attributes self.id = auth_ref.auth_token if is_ans1_token(self.id): self.id = hashlib.md5(self.id).hexdigest() self.expires = auth_ref.expires # Project-related attributes project = {} project['id'] = auth_ref.project_id project['name'] = auth_ref.project_name self.project = project self.tenant = self.project # Domain-related attributes domain = {} domain['id'] = auth_ref.domain_id domain['name'] = auth_ref.domain_name self.domain = domain if auth_ref.version == 'v2.0': self.roles = auth_ref['user'].get('roles', []) else: self.roles = auth_ref.get('roles', []) if get_keystone_version() < 3: self.serviceCatalog = auth_ref.get('serviceCatalog', []) else: self.serviceCatalog = auth_ref.get('catalog', []) class User(AnonymousUser): """A User class with some extra special sauce for Keystone. In addition to the standard Django user attributes, this class also has the following: .. attribute:: token The Keystone token object associated with the current user/tenant. The token object is deprecated, user auth_ref instead. .. attribute:: tenant_id The id of the Keystone tenant for the current user/token. The tenant_id keyword argument is deprecated, use project_id instead. .. attribute:: tenant_name The name of the Keystone tenant for the current user/token. The tenant_name keyword argument is deprecated, use project_name instead. .. attribute:: project_id The id of the Keystone project for the current user/token. .. attribute:: project_name The name of the Keystone project for the current user/token. .. attribute:: service_catalog The ``ServiceCatalog`` data returned by Keystone. .. attribute:: roles A list of dictionaries containing role names and ids as returned by Keystone. .. attribute:: services_region A list of non-identity service endpoint regions extracted from the service catalog. .. attribute:: user_domain_id The domain id of the current user. .. attribute:: domain_id The id of the Keystone domain scoped for the current user/token. """ def __init__(self, id=None, token=None, user=None, tenant_id=None, service_catalog=None, tenant_name=None, roles=None, authorized_tenants=None, endpoint=None, enabled=False, services_region=None, user_domain_id=None, domain_id=None, domain_name=None, project_id=None, project_name=None): self.id = id self.pk = id self.token = token self.username = user self.user_domain_id = user_domain_id self.domain_id = domain_id self.domain_name = domain_name self.project_id = project_id or tenant_id self.project_name = project_name or tenant_name self.service_catalog = service_catalog self._services_region = services_region or \ self.default_services_region() self.roles = roles or [] self.endpoint = endpoint self.enabled = enabled self._authorized_tenants = authorized_tenants # List of variables to be deprecated. self.tenant_id = self.project_id self.tenant_name = self.project_name def __unicode__(self): return self.username def __repr__(self): return "<%s: %s>" % (self.__class__.__name__, self.username) def is_token_expired(self): """ Returns ``True`` if the token is expired, ``False`` if not, and ``None`` if there is no token set. """ if self.token is None: return None return not check_token_expiration(self.token) def is_authenticated(self): """ Checks for a valid token that has not yet expired. """ return self.token is not None and check_token_expiration(self.token) def is_anonymous(self): """ Returns ``True`` if the user is not authenticated,``False`` otherwise. """ return not self.is_authenticated() @property def is_active(self): return self.enabled @property def is_superuser(self): """ Evaluates whether this user has admin privileges. Returns ``True`` or ``False``. """ return 'admin' in [role['name'].lower() for role in self.roles] @property def authorized_tenants(self): """ Returns a memoized list of tenants this user may access. """ insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False) if self.is_authenticated() and self._authorized_tenants is None: endpoint = self.endpoint token = self.token try: self._authorized_tenants = get_project_list( user_id=self.id, auth_url=endpoint, token=token.id, insecure=insecure, debug=settings.DEBUG) except (keystone_exceptions.ClientException, keystone_exceptions.AuthorizationFailure): LOG.exception('Unable to retrieve project list.') return self._authorized_tenants or [] @authorized_tenants.setter def authorized_tenants(self, tenant_list): self._authorized_tenants = tenant_list def default_services_region(self): """ Returns the first endpoint region for first non-identity service in the service catalog """ if self.service_catalog: for service in self.service_catalog: if service['type'] == 'identity': continue for endpoint in service['endpoints']: return endpoint['region'] return None @property def services_region(self): return self._services_region @services_region.setter def services_region(self, region): self._services_region = region @property def available_services_regions(self): """ Returns list of unique region name values found in service catalog """ regions = [] if self.service_catalog: for service in self.service_catalog: if service['type'] == 'identity': continue for endpoint in service['endpoints']: if endpoint['region'] not in regions: regions.append(endpoint['region']) return regions def save(*args, **kwargs): # Presume we can't write to Keystone. pass def delete(*args, **kwargs): # Presume we can't write to Keystone. pass # Check for OR'd permission rules, check that user has one of the # required permission. def has_a_matching_perm(self, perm_list, obj=None): """ Returns True if the user has one of the specified permissions. If object is passed, it checks if the user has any of the required perms for this object. """ # If there are no permissions to check, just return true if not perm_list: return True # Check that user has at least one of the required permissions. for perm in perm_list: if self.has_perm(perm, obj): return True return False # Override the default has_perms method. Allowing for more # complex combinations of permissions. Will check for logical AND of # all top level permissions. Will use logical OR for all first level # tuples (check that use has one permissions in the tuple) # # Examples: # Checks for all required permissions # ('openstack.roles.admin', 'openstack.roles.L3-support') # # Checks for admin AND (L2 or L3) # ('openstack.roles.admin', ('openstack.roles.L3-support', # 'openstack.roles.L2-support'),) def has_perms(self, perm_list, obj=None): """ Returns True if the user has all of the specified permissions. Tuples in the list will possess the required permissions if the user has a permissions matching one of the elements of that tuple """ # If there are no permissions to check, just return true if not perm_list: return True for perm in perm_list: if isinstance(perm, basestring): # check that the permission matches if not self.has_perm(perm, obj): return False else: # check that a permission in the tuple matches if not self.has_a_matching_perm(perm, obj): return False return True python-django-openstack-auth-1.1.3/openstack_auth/locale/0000755000175000017500000000000012222632612022442 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/ar/0000755000175000017500000000000012222632612023044 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/ar/LC_MESSAGES/0000755000175000017500000000000012222632612024631 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/ar/LC_MESSAGES/django.mo0000644000175000017500000000304012222632545026432 0ustar chuckchuck t9-6D=1' (\mFv YW:8<An error occurred authenticating. Please try again later.DomainInvalid user name or password.PasswordRegionThe authentication token issued by the Identity service has expired.Unable to authenticate to any available projects.Unable to retrieve authorized projects.User NameYou are not authorized for any projects.Project-Id-Version: Horizon Report-Msgid-Bugs-To: POT-Creation-Date: 2013-09-11 13:43+0800 PO-Revision-Date: 2013-09-14 21:13+0000 Last-Translator: kamelia Language-Team: Arabic (http://www.transifex.com/projects/p/openstack/language/ar/) Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 حدث خطأ أثناء المصادقة , يرجى اعادة المحاولة لاحقا.نطاقاسم المستخدم أو كلمة المرور غير صالحينكلمة المرورالمجالانتهت صلاحية الرمز الموثوق الصادر عن خدمة الهويةلايمكن المصادقة لولوج أيٍّ من المشاريع المتاحة.لايمكن اظهار المشاريع المتاحة.اسم المستخدملايوجد لديك تصريح لدخول أي مشروع.python-django-openstack-auth-1.1.3/openstack_auth/locale/ar/LC_MESSAGES/django.po0000644000175000017500000000367112222632545026447 0ustar chuckchuck# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # kamelia , 2013 msgid "" msgstr "" "Project-Id-Version: Horizon\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-09-11 13:43+0800\n" "PO-Revision-Date: 2013-09-14 21:13+0000\n" "Last-Translator: kamelia \n" "Language-Team: Arabic (http://www.transifex.com/projects/p/openstack/language/ar/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ar\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" #: backend.py:44 msgid "The authentication token issued by the Identity service has expired." msgstr "انتهت صلاحية الرمز الموثوق الصادر عن خدمة الهوية" #: backend.py:92 msgid "Invalid user name or password." msgstr "اسم المستخدم أو كلمة المرور غير صالحين" #: backend.py:97 msgid "An error occurred authenticating. Please try again later." msgstr "حدث خطأ أثناء المصادقة , يرجى اعادة المحاولة لاحقا." #: backend.py:119 msgid "Unable to retrieve authorized projects." msgstr "لايمكن اظهار المشاريع المتاحة." #: backend.py:124 msgid "You are not authorized for any projects." msgstr "لايوجد لديك تصريح لدخول أي مشروع." #: backend.py:143 msgid "Unable to authenticate to any available projects." msgstr "لايمكن المصادقة لولوج أيٍّ من المشاريع المتاحة." #: forms.py:48 msgid "Region" msgstr "المجال" #: forms.py:49 msgid "User Name" msgstr "اسم المستخدم" #: forms.py:50 msgid "Password" msgstr "كلمة المرور" #: forms.py:59 msgid "Domain" msgstr "نطاق" python-django-openstack-auth-1.1.3/openstack_auth/locale/ko_KR/0000755000175000017500000000000012222632612023447 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/ko_KR/LC_MESSAGES/0000755000175000017500000000000012222632612025234 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/ko_KR/LC_MESSAGES/django.mo0000644000175000017500000000255412222632545027046 0ustar chuckchuck t9-6D=1' (K > R_Jf=/;0An error occurred authenticating. Please try again later.DomainInvalid user name or password.PasswordRegionThe authentication token issued by the Identity service has expired.Unable to authenticate to any available projects.Unable to retrieve authorized projects.User NameYou are not authorized for any projects.Project-Id-Version: Horizon Report-Msgid-Bugs-To: POT-Creation-Date: 2013-09-11 13:43+0800 PO-Revision-Date: 2013-09-12 10:00+0000 Last-Translator: daisy.ycguo Language-Team: Korean (Korea) (http://www.transifex.com/projects/p/openstack/language/ko_KR/) Plural-Forms: nplurals=1; plural=0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 인증 중 오류가 발생했습니다. 잠시 후 다시 시도하세요.도메인사용자 이름이나 비밀 번호가 잘못되었습니다.비밀번호지역Identity 서비스에서 발급한 인증 토큰이 만료되었습니다.사용 가능한 프로젝트에 인증 할 수 없습니다.프로젝트 권한을 찾을 수 없습니다.사용자 이름당신은 어떤 프로젝트에도 권한이 없습니다.python-django-openstack-auth-1.1.3/openstack_auth/locale/ko_KR/LC_MESSAGES/django.po0000644000175000017500000000337612222632545027054 0ustar chuckchuck# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # ujuc Gang , 2013 msgid "" msgstr "" "Project-Id-Version: Horizon\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-09-11 13:43+0800\n" "PO-Revision-Date: 2013-09-12 10:00+0000\n" "Last-Translator: daisy.ycguo \n" "Language-Team: Korean (Korea) (http://www.transifex.com/projects/p/openstack/language/ko_KR/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ko_KR\n" "Plural-Forms: nplurals=1; plural=0;\n" #: backend.py:44 msgid "The authentication token issued by the Identity service has expired." msgstr "Identity 서비스에서 발급한 인증 토큰이 만료되었습니다." #: backend.py:92 msgid "Invalid user name or password." msgstr "사용자 이름이나 비밀 번호가 잘못되었습니다." #: backend.py:97 msgid "An error occurred authenticating. Please try again later." msgstr "인증 중 오류가 발생했습니다. 잠시 후 다시 시도하세요." #: backend.py:119 msgid "Unable to retrieve authorized projects." msgstr "프로젝트 권한을 찾을 수 없습니다." #: backend.py:124 msgid "You are not authorized for any projects." msgstr "당신은 어떤 프로젝트에도 권한이 없습니다." #: backend.py:143 msgid "Unable to authenticate to any available projects." msgstr "사용 가능한 프로젝트에 인증 할 수 없습니다." #: forms.py:48 msgid "Region" msgstr "지역" #: forms.py:49 msgid "User Name" msgstr "사용자 이름" #: forms.py:50 msgid "Password" msgstr "비밀번호" #: forms.py:59 msgid "Domain" msgstr "도메인" python-django-openstack-auth-1.1.3/openstack_auth/locale/pt_BR/0000755000175000017500000000000012222632612023450 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/pt_BR/LC_MESSAGES/0000755000175000017500000000000012222632612025235 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/pt_BR/LC_MESSAGES/django.mo0000644000175000017500000000245012222632545027042 0ustar chuckchuck t9-6D=1' (C%&,F48{10An error occurred authenticating. Please try again later.DomainInvalid user name or password.PasswordRegionThe authentication token issued by the Identity service has expired.Unable to authenticate to any available projects.Unable to retrieve authorized projects.User NameYou are not authorized for any projects.Project-Id-Version: Horizon Report-Msgid-Bugs-To: POT-Creation-Date: 2013-09-11 13:43+0800 PO-Revision-Date: 2013-09-16 12:57+0000 Last-Translator: Gabriel Wainer Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/openstack/language/pt_BR/) Plural-Forms: nplurals=2; plural=(n > 1) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 Um erro ocorreu autenticando. Por favor tente novamente mais tarde.DomínioNome de usuário ou senha inválidos.SenhaRegiãoO token de autenticação emitido pelo serviço de identidade expirou.Não foi possível autenticar nos projetos disponíveis.Não foi possível obter os projetos autorizados.Nome do UsuárioVocê não está autorizado para nenhum projeto.python-django-openstack-auth-1.1.3/openstack_auth/locale/pt_BR/LC_MESSAGES/django.po0000644000175000017500000000325312222632545027047 0ustar chuckchuck# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # Gabriel Wainer, 2013 msgid "" msgstr "" "Project-Id-Version: Horizon\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-09-11 13:43+0800\n" "PO-Revision-Date: 2013-09-16 12:57+0000\n" "Last-Translator: Gabriel Wainer\n" "Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/openstack/language/pt_BR/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: pt_BR\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #: backend.py:44 msgid "The authentication token issued by the Identity service has expired." msgstr "O token de autenticação emitido pelo serviço de identidade expirou." #: backend.py:92 msgid "Invalid user name or password." msgstr "Nome de usuário ou senha inválidos." #: backend.py:97 msgid "An error occurred authenticating. Please try again later." msgstr "Um erro ocorreu autenticando. Por favor tente novamente mais tarde." #: backend.py:119 msgid "Unable to retrieve authorized projects." msgstr "Não foi possível obter os projetos autorizados." #: backend.py:124 msgid "You are not authorized for any projects." msgstr "Você não está autorizado para nenhum projeto." #: backend.py:143 msgid "Unable to authenticate to any available projects." msgstr "Não foi possível autenticar nos projetos disponíveis." #: forms.py:48 msgid "Region" msgstr "Região" #: forms.py:49 msgid "User Name" msgstr "Nome do Usuário" #: forms.py:50 msgid "Password" msgstr "Senha" #: forms.py:59 msgid "Domain" msgstr "Domínio" python-django-openstack-auth-1.1.3/openstack_auth/locale/de/0000755000175000017500000000000012222632612023032 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/de/LC_MESSAGES/0000755000175000017500000000000012222632612024617 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/de/LC_MESSAGES/django.mo0000644000175000017500000000244112222632545026424 0ustar chuckchuck t9-6D=1' (c3 =F,MDz- &An error occurred authenticating. Please try again later.DomainInvalid user name or password.PasswordRegionThe authentication token issued by the Identity service has expired.Unable to authenticate to any available projects.Unable to retrieve authorized projects.User NameYou are not authorized for any projects.Project-Id-Version: Horizon Report-Msgid-Bugs-To: POT-Creation-Date: 2013-09-11 13:43+0800 PO-Revision-Date: 2013-09-17 08:42+0000 Last-Translator: saschpe Language-Team: German (http://www.transifex.com/projects/p/openstack/language/de/) Plural-Forms: nplurals=2; plural=(n != 1) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 Während der Authentifizierung ist ein Fehler aufgetretenBitte versuchen Sie es später noch einmalDomäneUngültiger Benutzername oder ungültiges Passwort.PasswortRegionDas Authentifizierungs-Token ist abgelaufen.Außerstande bei irgendeinem verfügbaren Projekt zu authentisieren.Außerstande autorisierte Projekte abzurufen.BenutzernameSie sind für kein Projekt berechtigt.python-django-openstack-auth-1.1.3/openstack_auth/locale/de/LC_MESSAGES/django.po0000644000175000017500000000330512222632545026427 0ustar chuckchuck# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # Matthias Runge , 2013 # saschpe, 2013 msgid "" msgstr "" "Project-Id-Version: Horizon\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-09-11 13:43+0800\n" "PO-Revision-Date: 2013-09-17 08:42+0000\n" "Last-Translator: saschpe\n" "Language-Team: German (http://www.transifex.com/projects/p/openstack/language/de/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: backend.py:44 msgid "The authentication token issued by the Identity service has expired." msgstr "Das Authentifizierungs-Token ist abgelaufen." #: backend.py:92 msgid "Invalid user name or password." msgstr "Ungültiger Benutzername oder ungültiges Passwort." #: backend.py:97 msgid "An error occurred authenticating. Please try again later." msgstr "Während der Authentifizierung ist ein Fehler aufgetretenBitte versuchen Sie es später noch einmal" #: backend.py:119 msgid "Unable to retrieve authorized projects." msgstr "Außerstande autorisierte Projekte abzurufen." #: backend.py:124 msgid "You are not authorized for any projects." msgstr "Sie sind für kein Projekt berechtigt." #: backend.py:143 msgid "Unable to authenticate to any available projects." msgstr "Außerstande bei irgendeinem verfügbaren Projekt zu authentisieren." #: forms.py:48 msgid "Region" msgstr "Region" #: forms.py:49 msgid "User Name" msgstr "Benutzername" #: forms.py:50 msgid "Password" msgstr "Passwort" #: forms.py:59 msgid "Domain" msgstr "Domäne" python-django-openstack-auth-1.1.3/openstack_auth/locale/ru/0000755000175000017500000000000012222632612023070 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/ru/LC_MESSAGES/0000755000175000017500000000000012222632612024655 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/ru/LC_MESSAGES/django.mo0000644000175000017500000000316612222632545026467 0ustar chuckchuck t9-6D=1' ( mDx  ylQQE0An error occurred authenticating. Please try again later.DomainInvalid user name or password.PasswordRegionThe authentication token issued by the Identity service has expired.Unable to authenticate to any available projects.Unable to retrieve authorized projects.User NameYou are not authorized for any projects.Project-Id-Version: Horizon Report-Msgid-Bugs-To: POT-Creation-Date: 2013-09-11 13:43+0800 PO-Revision-Date: 2013-09-17 08:28+0000 Last-Translator: adiantum Language-Team: Russian Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 Произошла ошибка аутентификации. Пожалуйста, повторите попытку позже.ДоменНеверное имя пользователя или парольПарольРегионВремя действия токена, выданного сервисом идентификации, истекло.Невозможно аутентифицировать ни в одном доступном проектеНевозможно получить авторизованные проектыИмя пользователяВы не авторизованы ни в одном проекте.python-django-openstack-auth-1.1.3/openstack_auth/locale/ru/LC_MESSAGES/django.po0000644000175000017500000000413412222632545026466 0ustar chuckchuck# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # orkon , 2013 # adiantum , 2013 # Stas Maksimov , 2013 msgid "" msgstr "" "Project-Id-Version: Horizon\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-09-11 13:43+0800\n" "PO-Revision-Date: 2013-09-17 08:28+0000\n" "Last-Translator: adiantum \n" "Language-Team: Russian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ru\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #: backend.py:44 msgid "The authentication token issued by the Identity service has expired." msgstr "Время действия токена, выданного сервисом идентификации, истекло." #: backend.py:92 msgid "Invalid user name or password." msgstr "Неверное имя пользователя или пароль" #: backend.py:97 msgid "An error occurred authenticating. Please try again later." msgstr "Произошла ошибка аутентификации. Пожалуйста, повторите попытку позже." #: backend.py:119 msgid "Unable to retrieve authorized projects." msgstr "Невозможно получить авторизованные проекты" #: backend.py:124 msgid "You are not authorized for any projects." msgstr "Вы не авторизованы ни в одном проекте." #: backend.py:143 msgid "Unable to authenticate to any available projects." msgstr "Невозможно аутентифицировать ни в одном доступном проекте" #: forms.py:48 msgid "Region" msgstr "Регион" #: forms.py:49 msgid "User Name" msgstr "Имя пользователя" #: forms.py:50 msgid "Password" msgstr "Пароль" #: forms.py:59 msgid "Domain" msgstr "Домен" python-django-openstack-auth-1.1.3/openstack_auth/locale/en_AU/0000755000175000017500000000000012222632612023431 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/en_AU/LC_MESSAGES/0000755000175000017500000000000012222632612025216 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/en_AU/LC_MESSAGES/django.mo0000644000175000017500000000241312222632545027022 0ustar chuckchuck t9-6D=1' (9 )2D91~' (An error occurred authenticating. Please try again later.DomainInvalid user name or password.PasswordRegionThe authentication token issued by the Identity service has expired.Unable to authenticate to any available projects.Unable to retrieve authorized projects.User NameYou are not authorized for any projects.Project-Id-Version: Horizon Report-Msgid-Bugs-To: POT-Creation-Date: 2013-09-11 13:43+0800 PO-Revision-Date: 2013-09-12 10:00+0000 Last-Translator: daisy.ycguo Language-Team: English (Australia) (http://www.transifex.com/projects/p/openstack/language/en_AU/) Plural-Forms: nplurals=2; plural=(n != 1) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 An error occurred authenticating. Please try again later.DomainInvalid user name or password.PasswordRegionThe authentication token issued by the Identity service has expired.Unable to authenticate to any available projects.Unable to retrieve authorized projects.User NameYou are not authorized for any projects.python-django-openstack-auth-1.1.3/openstack_auth/locale/en_AU/LC_MESSAGES/django.po0000644000175000017500000000323712222632545027032 0ustar chuckchuck# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # Tom Fifield , 2013 msgid "" msgstr "" "Project-Id-Version: Horizon\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-09-11 13:43+0800\n" "PO-Revision-Date: 2013-09-12 10:00+0000\n" "Last-Translator: daisy.ycguo \n" "Language-Team: English (Australia) (http://www.transifex.com/projects/p/openstack/language/en_AU/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: en_AU\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: backend.py:44 msgid "The authentication token issued by the Identity service has expired." msgstr "The authentication token issued by the Identity service has expired." #: backend.py:92 msgid "Invalid user name or password." msgstr "Invalid user name or password." #: backend.py:97 msgid "An error occurred authenticating. Please try again later." msgstr "An error occurred authenticating. Please try again later." #: backend.py:119 msgid "Unable to retrieve authorized projects." msgstr "Unable to retrieve authorized projects." #: backend.py:124 msgid "You are not authorized for any projects." msgstr "You are not authorized for any projects." #: backend.py:143 msgid "Unable to authenticate to any available projects." msgstr "Unable to authenticate to any available projects." #: forms.py:48 msgid "Region" msgstr "Region" #: forms.py:49 msgid "User Name" msgstr "User Name" #: forms.py:50 msgid "Password" msgstr "Password" #: forms.py:59 msgid "Domain" msgstr "Domain" python-django-openstack-auth-1.1.3/openstack_auth/locale/zh_CN/0000755000175000017500000000000012222632612023443 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/zh_CN/LC_MESSAGES/0000755000175000017500000000000012222632612025230 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/zh_CN/LC_MESSAGES/django.mo0000644000175000017500000000225712222632545027042 0ustar chuckchuck t9-6D=1' (-'9a $An error occurred authenticating. Please try again later.DomainInvalid user name or password.PasswordRegionThe authentication token issued by the Identity service has expired.Unable to authenticate to any available projects.Unable to retrieve authorized projects.User NameYou are not authorized for any projects.Project-Id-Version: Horizon Report-Msgid-Bugs-To: POT-Creation-Date: 2013-09-11 13:43+0800 PO-Revision-Date: 2013-09-17 08:40+0000 Last-Translator: daisy.ycguo Language-Team: Chinese (China) (http://www.transifex.com/projects/p/openstack/language/zh_CN/) Plural-Forms: nplurals=1; plural=0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 认证发生错误。请稍后再试一次。域无效的用户名或密码。密码域身份认证令牌已过期。无法跟可用的项目验证通过。无法获取授权的项目。用户名您未被授权访问任何项目。python-django-openstack-auth-1.1.3/openstack_auth/locale/zh_CN/LC_MESSAGES/django.po0000644000175000017500000000310712222632545027040 0ustar chuckchuck# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # daisy.ycguo , 2013 msgid "" msgstr "" "Project-Id-Version: Horizon\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-09-11 13:43+0800\n" "PO-Revision-Date: 2013-09-17 08:40+0000\n" "Last-Translator: daisy.ycguo \n" "Language-Team: Chinese (China) (http://www.transifex.com/projects/p/openstack/language/zh_CN/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: zh_CN\n" "Plural-Forms: nplurals=1; plural=0;\n" #: backend.py:44 msgid "The authentication token issued by the Identity service has expired." msgstr "身份认证令牌已过期。" #: backend.py:92 msgid "Invalid user name or password." msgstr "无效的用户名或密码。" #: backend.py:97 msgid "An error occurred authenticating. Please try again later." msgstr "认证发生错误。请稍后再试一次。" #: backend.py:119 msgid "Unable to retrieve authorized projects." msgstr "无法获取授权的项目。" #: backend.py:124 msgid "You are not authorized for any projects." msgstr "您未被授权访问任何项目。" #: backend.py:143 msgid "Unable to authenticate to any available projects." msgstr "无法跟可用的项目验证通过。" #: forms.py:48 msgid "Region" msgstr "域" #: forms.py:49 msgid "User Name" msgstr "用户名" #: forms.py:50 msgid "Password" msgstr "密码" #: forms.py:59 msgid "Domain" msgstr "域" python-django-openstack-auth-1.1.3/openstack_auth/locale/fr/0000755000175000017500000000000012222632612023051 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/fr/LC_MESSAGES/0000755000175000017500000000000012222632612024636 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/fr/LC_MESSAGES/django.mo0000644000175000017500000000247412222632545026451 0ustar chuckchuck t9-6D=1' (T+  9FKN41(An error occurred authenticating. Please try again later.DomainInvalid user name or password.PasswordRegionThe authentication token issued by the Identity service has expired.Unable to authenticate to any available projects.Unable to retrieve authorized projects.User NameYou are not authorized for any projects.Project-Id-Version: Horizon Report-Msgid-Bugs-To: POT-Creation-Date: 2013-09-11 13:43+0800 PO-Revision-Date: 2013-09-26 11:16+0000 Last-Translator: jftalta Language-Team: French (http://www.transifex.com/projects/p/openstack/language/fr/) Plural-Forms: nplurals=2; plural=(n > 1) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 Une erreur s'est produite durant l'authentification. Veuillez recommencer plus tard.DomaineNom d'utilisateur ou mot de passe invalide.Mot de PasseRégionLe jeton d'authentification délivré par le service d'Identité a expiré.Authentification impossible quel que soit le projet.Impossible de récupérer les projets autorisés.Nom d'UtilisateurVous n'êtes autorisé sur aucun projet.python-django-openstack-auth-1.1.3/openstack_auth/locale/fr/LC_MESSAGES/django.po0000644000175000017500000000340212222632545026444 0ustar chuckchuck# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # François Bureau , 2013 # jftalta , 2013 msgid "" msgstr "" "Project-Id-Version: Horizon\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-09-11 13:43+0800\n" "PO-Revision-Date: 2013-09-26 11:16+0000\n" "Last-Translator: jftalta \n" "Language-Team: French (http://www.transifex.com/projects/p/openstack/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #: backend.py:44 msgid "The authentication token issued by the Identity service has expired." msgstr "Le jeton d'authentification délivré par le service d'Identité a expiré." #: backend.py:92 msgid "Invalid user name or password." msgstr "Nom d'utilisateur ou mot de passe invalide." #: backend.py:97 msgid "An error occurred authenticating. Please try again later." msgstr "Une erreur s'est produite durant l'authentification. Veuillez recommencer plus tard." #: backend.py:119 msgid "Unable to retrieve authorized projects." msgstr "Impossible de récupérer les projets autorisés." #: backend.py:124 msgid "You are not authorized for any projects." msgstr "Vous n'êtes autorisé sur aucun projet." #: backend.py:143 msgid "Unable to authenticate to any available projects." msgstr "Authentification impossible quel que soit le projet." #: forms.py:48 msgid "Region" msgstr "Région" #: forms.py:49 msgid "User Name" msgstr "Nom d'Utilisateur" #: forms.py:50 msgid "Password" msgstr "Mot de Passe" #: forms.py:59 msgid "Domain" msgstr "Domaine" python-django-openstack-auth-1.1.3/openstack_auth/locale/pt/0000755000175000017500000000000012222632612023065 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/pt/LC_MESSAGES/0000755000175000017500000000000012222632612024652 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/pt/LC_MESSAGES/django.mo0000644000175000017500000000236512222632545026464 0ustar chuckchuck t9-6D=1' (>!(1"90\%.An error occurred authenticating. Please try again later.DomainInvalid user name or password.PasswordRegionThe authentication token issued by the Identity service has expired.Unable to authenticate to any available projects.Unable to retrieve authorized projects.User NameYou are not authorized for any projects.Project-Id-Version: Horizon Report-Msgid-Bugs-To: POT-Creation-Date: 2013-09-11 13:43+0800 PO-Revision-Date: 2013-09-13 21:02+0000 Last-Translator: belmoreira Language-Team: Portuguese (http://www.transifex.com/projects/p/openstack/language/pt/) Plural-Forms: nplurals=2; plural=(n != 1) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 Ocorreu um erro de autenticação. Por favor, tente novamente.DomínioUtilizador ou password inválida.PasswordRegiãoO token de autenticação expirou.Não foi possível autenticar em nenhum projeto.Não foi possível obter os projetos.Nome do UtilizadorNão possui autorização para nenhum projeto.python-django-openstack-auth-1.1.3/openstack_auth/locale/pt/LC_MESSAGES/django.po0000644000175000017500000000321312222632545026460 0ustar chuckchuck# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # belmoreira , 2013 msgid "" msgstr "" "Project-Id-Version: Horizon\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-09-11 13:43+0800\n" "PO-Revision-Date: 2013-09-13 21:02+0000\n" "Last-Translator: belmoreira \n" "Language-Team: Portuguese (http://www.transifex.com/projects/p/openstack/language/pt/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: pt\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: backend.py:44 msgid "The authentication token issued by the Identity service has expired." msgstr "O token de autenticação expirou." #: backend.py:92 msgid "Invalid user name or password." msgstr "Utilizador ou password inválida." #: backend.py:97 msgid "An error occurred authenticating. Please try again later." msgstr "Ocorreu um erro de autenticação. Por favor, tente novamente." #: backend.py:119 msgid "Unable to retrieve authorized projects." msgstr "Não foi possível obter os projetos." #: backend.py:124 msgid "You are not authorized for any projects." msgstr "Não possui autorização para nenhum projeto." #: backend.py:143 msgid "Unable to authenticate to any available projects." msgstr "Não foi possível autenticar em nenhum projeto." #: forms.py:48 msgid "Region" msgstr "Região" #: forms.py:49 msgid "User Name" msgstr "Nome do Utilizador" #: forms.py:50 msgid "Password" msgstr "Password" #: forms.py:59 msgid "Domain" msgstr "Domínio" python-django-openstack-auth-1.1.3/openstack_auth/locale/es/0000755000175000017500000000000012222632612023051 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/es/LC_MESSAGES/0000755000175000017500000000000012222632612024636 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/es/LC_MESSAGES/django.mo0000644000175000017500000000247612222632545026453 0ustar chuckchuck t9-6D=1' (F, 3?OG35*An error occurred authenticating. Please try again later.DomainInvalid user name or password.PasswordRegionThe authentication token issued by the Identity service has expired.Unable to authenticate to any available projects.Unable to retrieve authorized projects.User NameYou are not authorized for any projects.Project-Id-Version: Horizon Report-Msgid-Bugs-To: POT-Creation-Date: 2013-09-11 13:43+0800 PO-Revision-Date: 2013-09-18 12:20+0000 Last-Translator: mariantb Language-Team: Spanish (http://www.transifex.com/projects/p/openstack/language/es/) Plural-Forms: nplurals=2; plural=(n != 1) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 Se produjo un error de autenticación. Inténtelo de nuevo más tarde.DominioNombre de usuario o contraseña no válidos.ContraseñaRegiónEl token de autenticación emitido por el servicio de la Identidad ha expirado.No se puede autenticar a los proyectos disponibles.No ha sido posible obtener los proyectos autorizados.Nombre de usuarioNo está autorizado para ningún proyecto.python-django-openstack-auth-1.1.3/openstack_auth/locale/es/LC_MESSAGES/django.po0000644000175000017500000000336512222632545026454 0ustar chuckchuck# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # aloga , 2013 # mariantb , 2013 msgid "" msgstr "" "Project-Id-Version: Horizon\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-09-11 13:43+0800\n" "PO-Revision-Date: 2013-09-18 12:20+0000\n" "Last-Translator: mariantb \n" "Language-Team: Spanish (http://www.transifex.com/projects/p/openstack/language/es/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: es\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: backend.py:44 msgid "The authentication token issued by the Identity service has expired." msgstr "El token de autenticación emitido por el servicio de la Identidad ha expirado." #: backend.py:92 msgid "Invalid user name or password." msgstr "Nombre de usuario o contraseña no válidos." #: backend.py:97 msgid "An error occurred authenticating. Please try again later." msgstr "Se produjo un error de autenticación. Inténtelo de nuevo más tarde." #: backend.py:119 msgid "Unable to retrieve authorized projects." msgstr "No ha sido posible obtener los proyectos autorizados." #: backend.py:124 msgid "You are not authorized for any projects." msgstr "No está autorizado para ningún proyecto." #: backend.py:143 msgid "Unable to authenticate to any available projects." msgstr "No se puede autenticar a los proyectos disponibles." #: forms.py:48 msgid "Region" msgstr "Región" #: forms.py:49 msgid "User Name" msgstr "Nombre de usuario" #: forms.py:50 msgid "Password" msgstr "Contraseña" #: forms.py:59 msgid "Domain" msgstr "Dominio" python-django-openstack-auth-1.1.3/openstack_auth/locale/es_MX/0000755000175000017500000000000012222632612023455 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/es_MX/LC_MESSAGES/0000755000175000017500000000000012222632612025242 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/es_MX/LC_MESSAGES/django.mo0000644000175000017500000000253012222632545027046 0ustar chuckchuck t9-6D=1' (U+$ P\Me31,+An error occurred authenticating. Please try again later.DomainInvalid user name or password.PasswordRegionThe authentication token issued by the Identity service has expired.Unable to authenticate to any available projects.Unable to retrieve authorized projects.User NameYou are not authorized for any projects.Project-Id-Version: Horizon Report-Msgid-Bugs-To: POT-Creation-Date: 2013-09-11 13:43+0800 PO-Revision-Date: 2013-09-24 18:04+0000 Last-Translator: Marco Bravo Language-Team: Spanish (Mexico) (http://www.transifex.com/projects/p/openstack/language/es_MX/) Plural-Forms: nplurals=2; plural=(n != 1) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 Se ha producido un error de autenticación. Por favor inténtelo de nuevo más tarde.DominioNombre de usuario o contraseña inválidos.ContraseñaRegión.El token de autenticación otorgado por el servicio de identidad ha expirado.No se puede autenticar a los proyectos disponibles.No se pueden recuperar los proyectos autorizados.Nombre de UsuarioNo estás autorizado para algunos proyectos.python-django-openstack-auth-1.1.3/openstack_auth/locale/es_MX/LC_MESSAGES/django.po0000644000175000017500000000342612222632545027056 0ustar chuckchuck# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # Marco Bravo , 2013 # Makika , 2013 msgid "" msgstr "" "Project-Id-Version: Horizon\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-09-11 13:43+0800\n" "PO-Revision-Date: 2013-09-24 18:04+0000\n" "Last-Translator: Marco Bravo \n" "Language-Team: Spanish (Mexico) (http://www.transifex.com/projects/p/openstack/language/es_MX/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: es_MX\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: backend.py:44 msgid "The authentication token issued by the Identity service has expired." msgstr "El token de autenticación otorgado por el servicio de identidad ha expirado." #: backend.py:92 msgid "Invalid user name or password." msgstr "Nombre de usuario o contraseña inválidos." #: backend.py:97 msgid "An error occurred authenticating. Please try again later." msgstr "Se ha producido un error de autenticación. Por favor inténtelo de nuevo más tarde." #: backend.py:119 msgid "Unable to retrieve authorized projects." msgstr "No se pueden recuperar los proyectos autorizados." #: backend.py:124 msgid "You are not authorized for any projects." msgstr "No estás autorizado para algunos proyectos." #: backend.py:143 msgid "Unable to authenticate to any available projects." msgstr "No se puede autenticar a los proyectos disponibles." #: forms.py:48 msgid "Region" msgstr "Región." #: forms.py:49 msgid "User Name" msgstr "Nombre de Usuario" #: forms.py:50 msgid "Password" msgstr "Contraseña" #: forms.py:59 msgid "Domain" msgstr "Dominio" python-django-openstack-auth-1.1.3/openstack_auth/locale/hi/0000755000175000017500000000000012222632612023042 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/hi/LC_MESSAGES/0000755000175000017500000000000012222632612024627 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/hi/LC_MESSAGES/django.mo0000644000175000017500000000343712222632545026442 0ustar chuckchuck t9-6D=1' (z8YWruAn error occurred authenticating. Please try again later.DomainInvalid user name or password.PasswordRegionThe authentication token issued by the Identity service has expired.Unable to authenticate to any available projects.Unable to retrieve authorized projects.User NameYou are not authorized for any projects.Project-Id-Version: Horizon Report-Msgid-Bugs-To: POT-Creation-Date: 2013-09-11 13:43+0800 PO-Revision-Date: 2013-09-12 10:00+0000 Last-Translator: coolsvap Language-Team: Hindi (http://www.transifex.com/projects/p/openstack/language/hi/) Plural-Forms: nplurals=2; plural=(n != 1) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 पहचान सेवा में त्रुटि. बाद में पुन: प्रयास करें.अनुक्षेत्रअमान्य उपयोगकर्ता नाम या पासवर्ड.पासवर्डक्षेत्रपहचान सेवा द्वारा जारी प्रमाणीकरण टोकन समाप्त हो गया है.किसी भी उपलब्ध परियोजनाओं को प्रमाणित करने में असमर्थ.अधिकृत परियोजनाओं को पुनः प्राप्त करने में असमर्थ.उपयोगकर्ताआप किसी भी परियोजनाओं के लिए अधिकृत नहीं हैं.python-django-openstack-auth-1.1.3/openstack_auth/locale/hi/LC_MESSAGES/django.po0000644000175000017500000000427112222632545026442 0ustar chuckchuck# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # coolsvap , 2013 msgid "" msgstr "" "Project-Id-Version: Horizon\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-09-11 13:43+0800\n" "PO-Revision-Date: 2013-09-12 10:00+0000\n" "Last-Translator: coolsvap \n" "Language-Team: Hindi (http://www.transifex.com/projects/p/openstack/language/hi/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: hi\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: backend.py:44 msgid "The authentication token issued by the Identity service has expired." msgstr "पहचान सेवा द्वारा जारी प्रमाणीकरण टोकन समाप्त हो गया है." #: backend.py:92 msgid "Invalid user name or password." msgstr "अमान्य उपयोगकर्ता नाम या पासवर्ड." #: backend.py:97 msgid "An error occurred authenticating. Please try again later." msgstr "पहचान सेवा में त्रुटि. बाद में पुन: प्रयास करें." #: backend.py:119 msgid "Unable to retrieve authorized projects." msgstr "अधिकृत परियोजनाओं को पुनः प्राप्त करने में असमर्थ." #: backend.py:124 msgid "You are not authorized for any projects." msgstr "आप किसी भी परियोजनाओं के लिए अधिकृत नहीं हैं." #: backend.py:143 msgid "Unable to authenticate to any available projects." msgstr "किसी भी उपलब्ध परियोजनाओं को प्रमाणित करने में असमर्थ." #: forms.py:48 msgid "Region" msgstr "क्षेत्र" #: forms.py:49 msgid "User Name" msgstr "उपयोगकर्ता" #: forms.py:50 msgid "Password" msgstr "पासवर्ड" #: forms.py:59 msgid "Domain" msgstr "अनुक्षेत्र" python-django-openstack-auth-1.1.3/openstack_auth/locale/uk/0000755000175000017500000000000012222632612023061 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/uk/LC_MESSAGES/0000755000175000017500000000000012222632612024646 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/uk/LC_MESSAGES/django.mo0000644000175000017500000000316112222632545026453 0ustar chuckchuck t9-6D=1' (g dAo  ]^L F*An error occurred authenticating. Please try again later.DomainInvalid user name or password.PasswordRegionThe authentication token issued by the Identity service has expired.Unable to authenticate to any available projects.Unable to retrieve authorized projects.User NameYou are not authorized for any projects.Project-Id-Version: Horizon Report-Msgid-Bugs-To: POT-Creation-Date: 2013-09-11 13:43+0800 PO-Revision-Date: 2013-09-22 10:05+0000 Last-Translator: azpekt Language-Team: Ukrainian (http://www.transifex.com/projects/p/openstack/language/uk/) Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 Помилка у автентифікації. Будь-ласка, спробуйте пізніше.ДоменНевірне ім’я користувача чи парольПарольРегіонАвтентифікаційний токен, виданий Ідентифікаційним сервісом, більше не дійсний.Неможливо автентифікуватися щодо жодного проекту.Неможливо отримати авторизовані проекти.Ім’я КористувачаВи не авторизовані до жодного проекту.python-django-openstack-auth-1.1.3/openstack_auth/locale/uk/LC_MESSAGES/django.po0000644000175000017500000000377412222632545026470 0ustar chuckchuck# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # azpekt , 2013 msgid "" msgstr "" "Project-Id-Version: Horizon\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-09-11 13:43+0800\n" "PO-Revision-Date: 2013-09-22 10:05+0000\n" "Last-Translator: azpekt \n" "Language-Team: Ukrainian (http://www.transifex.com/projects/p/openstack/language/uk/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: uk\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #: backend.py:44 msgid "The authentication token issued by the Identity service has expired." msgstr "Автентифікаційний токен, виданий Ідентифікаційним сервісом, більше не дійсний." #: backend.py:92 msgid "Invalid user name or password." msgstr "Невірне ім’я користувача чи пароль" #: backend.py:97 msgid "An error occurred authenticating. Please try again later." msgstr "Помилка у автентифікації. Будь-ласка, спробуйте пізніше." #: backend.py:119 msgid "Unable to retrieve authorized projects." msgstr "Неможливо отримати авторизовані проекти." #: backend.py:124 msgid "You are not authorized for any projects." msgstr "Ви не авторизовані до жодного проекту." #: backend.py:143 msgid "Unable to authenticate to any available projects." msgstr "Неможливо автентифікуватися щодо жодного проекту." #: forms.py:48 msgid "Region" msgstr "Регіон" #: forms.py:49 msgid "User Name" msgstr "Ім’я Користувача" #: forms.py:50 msgid "Password" msgstr "Пароль" #: forms.py:59 msgid "Domain" msgstr "Домен" python-django-openstack-auth-1.1.3/openstack_auth/locale/pl_PL/0000755000175000017500000000000012222632612023450 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/pl_PL/LC_MESSAGES/0000755000175000017500000000000012222632612025235 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/pl_PL/LC_MESSAGES/django.mo0000644000175000017500000000260212222632545027041 0ustar chuckchuck t9-6D=1' (LK-RFA0H&[An error occurred authenticating. Please try again later.DomainInvalid user name or password.PasswordRegionThe authentication token issued by the Identity service has expired.Unable to authenticate to any available projects.Unable to retrieve authorized projects.User NameYou are not authorized for any projects.Project-Id-Version: Horizon Report-Msgid-Bugs-To: POT-Creation-Date: 2013-09-11 13:43+0800 PO-Revision-Date: 2013-09-14 21:02+0000 Last-Translator: Łukasz Jernaś Language-Team: Polish (Poland) (http://www.transifex.com/projects/p/openstack/language/pl_PL/) Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 Wystąpił błąd w trakcie uwierzytelniania. Proszę spróbować później.DomenaNieprawidłowa nazwa użytkownika lub hasło.HasłoRegionTonek uwierzytelniania wydany przez usługę uwierzytelniania wygasł.Nie można uwierzytelnić do żadnego z istniejących projektów.Nie można pobrać uwierzytelnionych projektów.Nazwa użytkownikaNie upoważniono do żadnego projektu.python-django-openstack-auth-1.1.3/openstack_auth/locale/pl_PL/LC_MESSAGES/django.po0000644000175000017500000000343112222632545027045 0ustar chuckchuck# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # Łukasz Jernaś , 2013 msgid "" msgstr "" "Project-Id-Version: Horizon\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-09-11 13:43+0800\n" "PO-Revision-Date: 2013-09-14 21:02+0000\n" "Last-Translator: Łukasz Jernaś \n" "Language-Team: Polish (Poland) (http://www.transifex.com/projects/p/openstack/language/pl_PL/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: pl_PL\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #: backend.py:44 msgid "The authentication token issued by the Identity service has expired." msgstr "Tonek uwierzytelniania wydany przez usługę uwierzytelniania wygasł." #: backend.py:92 msgid "Invalid user name or password." msgstr "Nieprawidłowa nazwa użytkownika lub hasło." #: backend.py:97 msgid "An error occurred authenticating. Please try again later." msgstr "Wystąpił błąd w trakcie uwierzytelniania. Proszę spróbować później." #: backend.py:119 msgid "Unable to retrieve authorized projects." msgstr "Nie można pobrać uwierzytelnionych projektów." #: backend.py:124 msgid "You are not authorized for any projects." msgstr "Nie upoważniono do żadnego projektu." #: backend.py:143 msgid "Unable to authenticate to any available projects." msgstr "Nie można uwierzytelnić do żadnego z istniejących projektów." #: forms.py:48 msgid "Region" msgstr "Region" #: forms.py:49 msgid "User Name" msgstr "Nazwa użytkownika" #: forms.py:50 msgid "Password" msgstr "Hasło" #: forms.py:59 msgid "Domain" msgstr "Domena" python-django-openstack-auth-1.1.3/openstack_auth/locale/en_GB/0000755000175000017500000000000012222632612023414 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/en_GB/LC_MESSAGES/0000755000175000017500000000000012222632612025201 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/en_GB/LC_MESSAGES/django.mo0000644000175000017500000000241412222632545027006 0ustar chuckchuck t9-6D=1' (9 *3D:1' (An error occurred authenticating. Please try again later.DomainInvalid user name or password.PasswordRegionThe authentication token issued by the Identity service has expired.Unable to authenticate to any available projects.Unable to retrieve authorized projects.User NameYou are not authorized for any projects.Project-Id-Version: Horizon Report-Msgid-Bugs-To: POT-Creation-Date: 2013-09-11 13:43+0800 PO-Revision-Date: 2013-09-21 08:12+0000 Last-Translator: Tom Fifield Language-Team: English (United Kingdom) (http://www.transifex.com/projects/p/openstack/language/en_GB/) Plural-Forms: nplurals=2; plural=(n != 1) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 An error occurred authenticating. Please try again later.DomainInvalid user name or password.PasswordRegionThe authentication token issued by the Identity service has expired.Unable to authenticate to any available projects.Unable to retrieve authorised projects.User NameYou are not authorised for any projects.python-django-openstack-auth-1.1.3/openstack_auth/locale/en_GB/LC_MESSAGES/django.po0000644000175000017500000000324012222632545027007 0ustar chuckchuck# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # Tom Fifield , 2013 msgid "" msgstr "" "Project-Id-Version: Horizon\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-09-11 13:43+0800\n" "PO-Revision-Date: 2013-09-21 08:12+0000\n" "Last-Translator: Tom Fifield \n" "Language-Team: English (United Kingdom) (http://www.transifex.com/projects/p/openstack/language/en_GB/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: en_GB\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: backend.py:44 msgid "The authentication token issued by the Identity service has expired." msgstr "The authentication token issued by the Identity service has expired." #: backend.py:92 msgid "Invalid user name or password." msgstr "Invalid user name or password." #: backend.py:97 msgid "An error occurred authenticating. Please try again later." msgstr "An error occurred authenticating. Please try again later." #: backend.py:119 msgid "Unable to retrieve authorized projects." msgstr "Unable to retrieve authorised projects." #: backend.py:124 msgid "You are not authorized for any projects." msgstr "You are not authorised for any projects." #: backend.py:143 msgid "Unable to authenticate to any available projects." msgstr "Unable to authenticate to any available projects." #: forms.py:48 msgid "Region" msgstr "Region" #: forms.py:49 msgid "User Name" msgstr "User Name" #: forms.py:50 msgid "Password" msgstr "Password" #: forms.py:59 msgid "Domain" msgstr "Domain" python-django-openstack-auth-1.1.3/openstack_auth/locale/openstack_auth.pot0000644000175000017500000000235112222632545026204 0ustar chuckchuck# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-09-11 13:43+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: backend.py:44 msgid "The authentication token issued by the Identity service has expired." msgstr "" #: backend.py:92 msgid "Invalid user name or password." msgstr "" #: backend.py:97 msgid "An error occurred authenticating. Please try again later." msgstr "" #: backend.py:119 msgid "Unable to retrieve authorized projects." msgstr "" #: backend.py:124 msgid "You are not authorized for any projects." msgstr "" #: backend.py:143 msgid "Unable to authenticate to any available projects." msgstr "" #: forms.py:48 msgid "Region" msgstr "" #: forms.py:49 msgid "User Name" msgstr "" #: forms.py:50 msgid "Password" msgstr "" #: forms.py:59 msgid "Domain" msgstr "" python-django-openstack-auth-1.1.3/openstack_auth/locale/ja/0000755000175000017500000000000012222632612023034 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/ja/LC_MESSAGES/0000755000175000017500000000000012222632612024621 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/ja/LC_MESSAGES/django.mo0000644000175000017500000000270612222632545026432 0ustar chuckchuck t9-6D=1' (] 9XhYxWE*pEAn error occurred authenticating. Please try again later.DomainInvalid user name or password.PasswordRegionThe authentication token issued by the Identity service has expired.Unable to authenticate to any available projects.Unable to retrieve authorized projects.User NameYou are not authorized for any projects.Project-Id-Version: Horizon Report-Msgid-Bugs-To: POT-Creation-Date: 2013-09-11 13:43+0800 PO-Revision-Date: 2013-09-26 05:36+0000 Last-Translator: Akihiro MOTOKI Language-Team: Japanese (http://www.transifex.com/projects/p/openstack/language/ja/) Plural-Forms: nplurals=1; plural=0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 認証中にエラーが発生しました。後ほどもう一度お試してください。ドメインユーザー名またはパスワードが無効です。パスワードリージョンIdentity Service により発行された認証トークンの期限が切れました。どの利用可能なプロジェクトに対しても認証できませんでした。権限のあるプロジェクトの情報を取得できません。ユーザー名どのプロジェクトに対しても認可されていません。python-django-openstack-auth-1.1.3/openstack_auth/locale/ja/LC_MESSAGES/django.po0000644000175000017500000000361112222632545026431 0ustar chuckchuck# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # Akihiro MOTOKI , 2013 # Tomoyuki KATO , 2013 msgid "" msgstr "" "Project-Id-Version: Horizon\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-09-11 13:43+0800\n" "PO-Revision-Date: 2013-09-26 05:36+0000\n" "Last-Translator: Akihiro MOTOKI \n" "Language-Team: Japanese (http://www.transifex.com/projects/p/openstack/language/ja/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ja\n" "Plural-Forms: nplurals=1; plural=0;\n" #: backend.py:44 msgid "The authentication token issued by the Identity service has expired." msgstr "Identity Service により発行された認証トークンの期限が切れました。" #: backend.py:92 msgid "Invalid user name or password." msgstr "ユーザー名またはパスワードが無効です。" #: backend.py:97 msgid "An error occurred authenticating. Please try again later." msgstr "認証中にエラーが発生しました。後ほどもう一度お試してください。" #: backend.py:119 msgid "Unable to retrieve authorized projects." msgstr "権限のあるプロジェクトの情報を取得できません。" #: backend.py:124 msgid "You are not authorized for any projects." msgstr "どのプロジェクトに対しても認可されていません。" #: backend.py:143 msgid "Unable to authenticate to any available projects." msgstr "どの利用可能なプロジェクトに対しても認証できませんでした。" #: forms.py:48 msgid "Region" msgstr "リージョン" #: forms.py:49 msgid "User Name" msgstr "ユーザー名" #: forms.py:50 msgid "Password" msgstr "パスワード" #: forms.py:59 msgid "Domain" msgstr "ドメイン" python-django-openstack-auth-1.1.3/openstack_auth/locale/nl_NL/0000755000175000017500000000000012222632612023444 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/nl_NL/LC_MESSAGES/0000755000175000017500000000000012222632612025231 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/nl_NL/LC_MESSAGES/django.mo0000644000175000017500000000251312222632545027036 0ustar chuckchuck t9-6D=1' (L ' ;FGL>=* An error occurred authenticating. Please try again later.DomainInvalid user name or password.PasswordRegionThe authentication token issued by the Identity service has expired.Unable to authenticate to any available projects.Unable to retrieve authorized projects.User NameYou are not authorized for any projects.Project-Id-Version: Horizon Report-Msgid-Bugs-To: POT-Creation-Date: 2013-09-11 13:43+0800 PO-Revision-Date: 2013-09-19 10:01+0000 Last-Translator: toMeloos Language-Team: Dutch (Netherlands) (http://www.transifex.com/projects/p/openstack/language/nl_NL/) Plural-Forms: nplurals=2; plural=(n != 1) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 Er is een fout opgetreden bij de verificatie. Probeert u het later nog eens.DomeinOngeldige gebruikersnaam of wachtwoord.WachtwoordRegioDe door de identiteitsdienst verstrekte authenticatietoken is verlopen.Niet in staat u te authenticeren bij enig beschikbaar project.Niet in staat om de geauthentificeerde projecten op te halen.GebruikersnaamU bent voor geen enkel project gemachtigd.python-django-openstack-auth-1.1.3/openstack_auth/locale/nl_NL/LC_MESSAGES/django.po0000644000175000017500000000333112222632545027040 0ustar chuckchuck# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # toMeloos , 2013 msgid "" msgstr "" "Project-Id-Version: Horizon\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-09-11 13:43+0800\n" "PO-Revision-Date: 2013-09-19 10:01+0000\n" "Last-Translator: toMeloos \n" "Language-Team: Dutch (Netherlands) (http://www.transifex.com/projects/p/openstack/language/nl_NL/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: nl_NL\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: backend.py:44 msgid "The authentication token issued by the Identity service has expired." msgstr "De door de identiteitsdienst verstrekte authenticatietoken is verlopen." #: backend.py:92 msgid "Invalid user name or password." msgstr "Ongeldige gebruikersnaam of wachtwoord." #: backend.py:97 msgid "An error occurred authenticating. Please try again later." msgstr "Er is een fout opgetreden bij de verificatie. Probeert u het later nog eens." #: backend.py:119 msgid "Unable to retrieve authorized projects." msgstr "Niet in staat om de geauthentificeerde projecten op te halen." #: backend.py:124 msgid "You are not authorized for any projects." msgstr "U bent voor geen enkel project gemachtigd." #: backend.py:143 msgid "Unable to authenticate to any available projects." msgstr "Niet in staat u te authenticeren bij enig beschikbaar project." #: forms.py:48 msgid "Region" msgstr "Regio" #: forms.py:49 msgid "User Name" msgstr "Gebruikersnaam" #: forms.py:50 msgid "Password" msgstr "Wachtwoord" #: forms.py:59 msgid "Domain" msgstr "Domein" python-django-openstack-auth-1.1.3/openstack_auth/locale/zh_TW/0000755000175000017500000000000012222632612023475 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/zh_TW/LC_MESSAGES/0000755000175000017500000000000012222632612025262 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/locale/zh_TW/LC_MESSAGES/django.mo0000644000175000017500000000231212222632545027064 0ustar chuckchuck t9-6D=1' ('$-'K!s$An error occurred authenticating. Please try again later.DomainInvalid user name or password.PasswordRegionThe authentication token issued by the Identity service has expired.Unable to authenticate to any available projects.Unable to retrieve authorized projects.User NameYou are not authorized for any projects.Project-Id-Version: Horizon Report-Msgid-Bugs-To: POT-Creation-Date: 2013-09-11 13:43+0800 PO-Revision-Date: 2013-09-23 05:00+0000 Last-Translator: Tom Fifield Language-Team: Chinese (Taiwan) (http://www.transifex.com/projects/p/openstack/language/zh_TW/) Plural-Forms: nplurals=1; plural=0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 1.3 認證發生錯誤。請稍後再試。地域無效的使用者名稱或密碼。密碼區域認證伺服器發佈的憑證已經過期。無法認證到任何可用的專案。無法取回已認證的專案。使用者名稱您沒有被授權任何的專案。python-django-openstack-auth-1.1.3/openstack_auth/locale/zh_TW/LC_MESSAGES/django.po0000644000175000017500000000313612222632545027074 0ustar chuckchuck# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # zero00072 , 2013 msgid "" msgstr "" "Project-Id-Version: Horizon\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-09-11 13:43+0800\n" "PO-Revision-Date: 2013-09-23 05:00+0000\n" "Last-Translator: Tom Fifield \n" "Language-Team: Chinese (Taiwan) (http://www.transifex.com/projects/p/openstack/language/zh_TW/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: zh_TW\n" "Plural-Forms: nplurals=1; plural=0;\n" #: backend.py:44 msgid "The authentication token issued by the Identity service has expired." msgstr "認證伺服器發佈的憑證已經過期。" #: backend.py:92 msgid "Invalid user name or password." msgstr "無效的使用者名稱或密碼。" #: backend.py:97 msgid "An error occurred authenticating. Please try again later." msgstr "認證發生錯誤。請稍後再試。" #: backend.py:119 msgid "Unable to retrieve authorized projects." msgstr "無法取回已認證的專案。" #: backend.py:124 msgid "You are not authorized for any projects." msgstr "您沒有被授權任何的專案。" #: backend.py:143 msgid "Unable to authenticate to any available projects." msgstr "無法認證到任何可用的專案。" #: forms.py:48 msgid "Region" msgstr "區域" #: forms.py:49 msgid "User Name" msgstr "使用者名稱" #: forms.py:50 msgid "Password" msgstr "密碼" #: forms.py:59 msgid "Domain" msgstr "地域" python-django-openstack-auth-1.1.3/openstack_auth/utils.py0000644000175000017500000001257212222632545022731 0ustar chuckchuck# 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 urlparse from django.conf import settings from django.contrib import auth from django.contrib.auth.models import AnonymousUser from django.contrib.auth import middleware from django.utils import timezone from keystoneclient.v2_0 import client as client_v2 from keystoneclient.v3 import client as client_v3 """ We need the request object to get the user, so we'll slightly modify the existing django.contrib.auth.get_user method. To do so we update the auth middleware to point to our overridden method. Calling the "patch_middleware_get_user" method somewhere like our urls.py file takes care of hooking it in appropriately. """ def middleware_get_user(request): if not hasattr(request, '_cached_user'): request._cached_user = get_user(request) return request._cached_user def get_user(request): try: user_id = request.session[auth.SESSION_KEY] backend_path = request.session[auth.BACKEND_SESSION_KEY] backend = auth.load_backend(backend_path) backend.request = request user = backend.get_user(user_id) or AnonymousUser() except KeyError: user = AnonymousUser() return user def patch_middleware_get_user(): middleware.get_user = middleware_get_user auth.get_user = get_user """ End Monkey-Patching. """ def check_token_expiration(token): """ Timezone-aware checking of the auth token's expiration timestamp. Returns ``True`` if the token has not yet expired, otherwise ``False``. """ expiration = token.expires if settings.USE_TZ and timezone.is_naive(expiration): # Presumes that the Keystone is using UTC. expiration = timezone.make_aware(expiration, timezone.utc) # In case we get an unparseable expiration timestamp, return False # so you can't have a "forever" token just by breaking the expires param. if expiration: return expiration > timezone.now() else: return False # Copied from Keystone's keystone/common/cms.py file. PKI_ANS1_PREFIX = 'MII' def is_ans1_token(token): ''' thx to ayoung for sorting this out. base64 decoded hex representation of MII is 3082 In [3]: binascii.hexlify(base64.b64decode('MII=')) Out[3]: '3082' re: http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf pg4: For tags from 0 to 30 the first octet is the identfier pg10: Hex 30 means sequence, followed by the length of that sequence. pg5: Second octet is the length octet first bit indicates short or long form, next 7 bits encode the number of subsequent octets that make up the content length octets as an unsigned binary int 82 = 10000010 (first bit indicates long form) 0000010 = 2 octets of content length so read the next 2 octets to get the length of the content. In the case of a very large content length there could be a requirement to have more than 2 octets to designate the content length, therefore requiring us to check for MIM, MIQ, etc. In [4]: base64.b64encode(binascii.a2b_hex('3083')) Out[4]: 'MIM=' In [5]: base64.b64encode(binascii.a2b_hex('3084')) Out[5]: 'MIQ=' Checking for MI would become invalid at 16 octets of content length 10010000 = 90 In [6]: base64.b64encode(binascii.a2b_hex('3090')) Out[6]: 'MJA=' Checking for just M is insufficient But we will only check for MII: Max length of the content using 2 octets is 7FFF or 32767 It's not practical to support a token of this length or greater in http therefore, we will check for MII only and ignore the case of larger tokens ''' return token[:3] == PKI_ANS1_PREFIX # From django.contrib.auth.views # Added in Django 1.4.3, 1.5b2 # Vendored here for compatibility with old Django versions. def is_safe_url(url, host=None): """ Return ``True`` if the url is a safe redirection (i.e. it doesn't point to a different host). Always returns ``False`` on an empty url. """ if not url: return False netloc = urlparse.urlparse(url)[1] return not netloc or netloc == host # Helper for figuring out keystone version # Implementation will change when API version discovery is available def get_keystone_version(): return getattr(settings, 'OPENSTACK_API_VERSIONS', {}).get('identity', 2.0) def get_keystone_client(): if get_keystone_version() < 3: return client_v2 else: return client_v3 def get_project_list(*args, **kwargs): if get_keystone_version() < 3: client = get_keystone_client().Client(*args, **kwargs) return client.tenants.list() else: auth_url = kwargs.get('auth_url', '').replace('v2.0', 'v3') kwargs['auth_url'] = auth_url client = get_keystone_client().Client(*args, **kwargs) client.management_url = auth_url return client.projects.list(user=kwargs.get('user_id')) python-django-openstack-auth-1.1.3/openstack_auth/views.py0000644000175000017500000001532112222632545022721 0ustar chuckchuck# 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 django import shortcuts from django.conf import settings from django.contrib.auth import REDIRECT_FIELD_NAME from django.contrib.auth.views import (login as django_login, logout_then_login as django_logout) from django.contrib.auth.decorators import login_required from django.views.decorators.debug import sensitive_post_parameters from django.utils.functional import curry from django.views.decorators.cache import never_cache from django.views.decorators.csrf import csrf_protect try: from django.utils.http import is_safe_url except ImportError: from .utils import is_safe_url from keystoneclient.v2_0 import client as keystone_client_v2 from keystoneclient import exceptions as keystone_exceptions from .forms import Login from .user import set_session_from_user, create_user_from_token, Token from .utils import get_keystone_client from .utils import get_keystone_version LOG = logging.getLogger(__name__) @sensitive_post_parameters() @csrf_protect @never_cache def login(request): """ Logs a user in using the :class:`~openstack_auth.forms.Login` form. """ # Get our initial region for the form. initial = {} current_region = request.session.get('region_endpoint', None) requested_region = request.GET.get('region', None) regions = dict(getattr(settings, "AVAILABLE_REGIONS", [])) if requested_region in regions and requested_region != current_region: initial.update({'region': requested_region}) if request.method == "POST": form = curry(Login, request) else: form = curry(Login, initial=initial) extra_context = {'redirect_field_name': REDIRECT_FIELD_NAME} if request.is_ajax(): template_name = 'auth/_login.html' extra_context['hide'] = True else: template_name = 'auth/login.html' res = django_login(request, template_name=template_name, authentication_form=form, extra_context=extra_context) # Set the session data here because django's session key rotation # will erase it if we set it earlier. if request.user.is_authenticated(): set_session_from_user(request, request.user) regions = dict(Login.get_region_choices()) region = request.user.endpoint region_name = regions.get(region) request.session['region_endpoint'] = region request.session['region_name'] = region_name return res def logout(request): msg = 'Logging out user "%(username)s".' % \ {'username': request.user.username} LOG.info(msg) endpoint = request.session.get('region_endpoint') token = request.session.get('token') if token and endpoint: delete_token(endpoint=endpoint, token_id=token.id) """ Securely logs a user out. """ return django_logout(request) def delete_token(endpoint, token_id): """Delete a token.""" insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False) try: if get_keystone_version() < 3: client = keystone_client_v2.Client( endpoint=endpoint, token=token_id, insecure=insecure, debug=settings.DEBUG ) client.tokens.delete(token=token_id) LOG.info('Deleted token %s' % token_id) else: # FIXME: KS-client does not have delete token available # Need to add this later when it is exposed. pass except keystone_exceptions.ClientException as e: LOG.info('Could not delete token') @login_required def switch(request, tenant_id, redirect_field_name=REDIRECT_FIELD_NAME): """ Switches an authenticated user from one project to another. """ LOG.debug('Switching to tenant %s for user "%s".' % (tenant_id, request.user.username)) insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False) endpoint = request.user.endpoint try: if get_keystone_version() >= 3: endpoint = endpoint.replace('v2.0', 'v3') client = get_keystone_client().Client(tenant_id=tenant_id, token=request.user.token.id, auth_url=endpoint, insecure=insecure, debug=settings.DEBUG) auth_ref = client.auth_ref msg = 'Project switch successful for user "%(username)s".' % \ {'username': request.user.username} LOG.info(msg) except keystone_exceptions.ClientException: msg = 'Project switch failed for user "%(username)s".' % \ {'username': request.user.username} LOG.warning(msg) auth_ref = None LOG.exception('An error occurred while switching sessions.') # Ensure the user-originating redirection url is safe. # Taken from django.contrib.auth.views.login() redirect_to = request.REQUEST.get(redirect_field_name, '') if not is_safe_url(url=redirect_to, host=request.get_host()): redirect_to = settings.LOGIN_REDIRECT_URL if auth_ref: old_endpoint = request.session.get('region_endpoint') old_token = request.session.get('token') if old_token and old_endpoint and old_token.id != auth_ref.auth_token: delete_token(endpoint=old_endpoint, token_id=old_token.id) user = create_user_from_token(request, Token(auth_ref), endpoint) set_session_from_user(request, user) return shortcuts.redirect(redirect_to) def switch_region(request, region_name, redirect_field_name=REDIRECT_FIELD_NAME): """ Switches the non-identity services region that is being managed for the scoped project. """ if region_name in request.user.available_services_regions: request.session['services_region'] = region_name LOG.debug('Switching services region to %s for user "%s".' % (region_name, request.user.username)) redirect_to = request.REQUEST.get(redirect_field_name, '') if not is_safe_url(url=redirect_to, host=request.get_host()): redirect_to = settings.LOGIN_REDIRECT_URL return shortcuts.redirect(redirect_to) python-django-openstack-auth-1.1.3/openstack_auth/forms.py0000644000175000017500000001034612222632545022714 0ustar chuckchuck# 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 django import forms from django.conf import settings from django.contrib.auth import authenticate from django.contrib.auth.forms import AuthenticationForm from django.utils.translation import ugettext_lazy as _ from django.views.decorators.debug import sensitive_variables from .exceptions import KeystoneAuthException LOG = logging.getLogger(__name__) class Login(AuthenticationForm): """ Form used for logging in a user. Handles authentication with Keystone by providing the domain name, username and password. A scoped token is fetched after successful authentication. A domain name is required if authenticating with Keystone V3 running multi-domain configuration. If the user authenticated has a default project set, the token will be automatically scoped to their default project. If the user authenticated has no default project set, the authentication backend will try to scope to the projects returned from the user's assigned projects. The first successful project scoped will be returned. Inherits from the base ``django.contrib.auth.forms.AuthenticationForm`` class for added security features. """ region = forms.ChoiceField(label=_("Region"), required=False) username = forms.CharField(label=_("User Name")) password = forms.CharField(label=_("Password"), widget=forms.PasswordInput(render_value=False)) def __init__(self, *args, **kwargs): super(Login, self).__init__(*args, **kwargs) self.fields.keyOrder = ['username', 'password', 'region'] if getattr(settings, 'OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT', False): self.fields['domain'] = forms.CharField(label=_("Domain"), required=True) self.fields.keyOrder = ['domain', 'username', 'password', 'region'] self.fields['region'].choices = self.get_region_choices() if len(self.fields['region'].choices) == 1: self.fields['region'].initial = self.fields['region'].choices[0][0] self.fields['region'].widget = forms.widgets.HiddenInput() @staticmethod def get_region_choices(): default_region = (settings.OPENSTACK_KEYSTONE_URL, "Default Region") return getattr(settings, 'AVAILABLE_REGIONS', [default_region]) @sensitive_variables() def clean(self): default_domain = getattr(settings, 'OPENSTACK_KEYSTONE_DEFAULT_DOMAIN', 'Default') username = self.cleaned_data.get('username') password = self.cleaned_data.get('password') region = self.cleaned_data.get('region') domain = self.cleaned_data.get('domain', default_domain) if not (username and password): # Don't authenticate, just let the other validators handle it. return self.cleaned_data try: self.user_cache = authenticate(request=self.request, username=username, password=password, user_domain_name=domain, auth_url=region) msg = 'Login successful for user "%(username)s".' % \ {'username': username} LOG.info(msg) except KeystoneAuthException as exc: msg = 'Login failed for user "%(username)s".' % \ {'username': username} LOG.warning(msg) self.request.session.flush() raise forms.ValidationError(exc) self.check_for_test_cookie() return self.cleaned_data python-django-openstack-auth-1.1.3/openstack_auth/__init__.py0000644000175000017500000000005212222632545023316 0ustar chuckchuck# following PEP 386 __version__ = "1.1.3" python-django-openstack-auth-1.1.3/openstack_auth/tests/0000755000175000017500000000000012222632612022345 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/tests/settings.py0000644000175000017500000000260612222632545024570 0ustar chuckchuck# 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. DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3'}} INSTALLED_APPS = [ 'django', 'django.contrib.contenttypes', 'django.contrib.auth', 'django.contrib.sessions', 'openstack_auth', 'openstack_auth.tests' ] MIDDLEWARE_CLASSES = [ 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware' ] AUTHENTICATION_BACKENDS = ['openstack_auth.backend.KeystoneBackend'] OPENSTACK_KEYSTONE_URL = "http://localhost:5000/v2.0" ROOT_URLCONF = 'openstack_auth.tests.urls' LOGIN_REDIRECT_URL = '/' SECRET_KEY = 'badcafe' OPENSTACK_API_VERSIONS = { "identity": 2.0 } USE_TZ = True OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = False OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = 'domain' python-django-openstack-auth-1.1.3/openstack_auth/tests/data_v2.py0000644000175000017500000001234612222632545024252 0ustar chuckchuck# 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 from datetime import timedelta from django.utils import datetime_safe from keystoneclient.access import AccessInfo from keystoneclient.service_catalog import ServiceCatalog from keystoneclient.v2_0.roles import Role, RoleManager from keystoneclient.v2_0.tenants import Tenant, TenantManager from keystoneclient.v2_0.users import User, UserManager class TestDataContainer(object): """ Arbitrary holder for test data in an object-oriented fashion. """ pass def generate_test_data(): ''' Builds a set of test_data data as returned by Keystone V2. ''' test_data = TestDataContainer() keystone_service = { 'type': 'identity', 'name': 'keystone', 'endpoints_links': [], 'endpoints': [ { 'region': 'RegionOne', 'adminURL': 'http://admin.localhost:35357/v2.0', 'internalURL': 'http://internal.localhost:5000/v2.0', 'publicURL': 'http://public.localhost:5000/v2.0' } ] } # Users user_dict = {'id': uuid.uuid4().hex, 'name': 'gabriel', 'email': 'gabriel@example.com', 'password': 'swordfish', 'token': '', 'enabled': True} test_data.user = User(UserManager(None), user_dict, loaded=True) # Tenants tenant_dict_1 = {'id': uuid.uuid4().hex, 'name': 'tenant_one', 'description': '', 'enabled': True} tenant_dict_2 = {'id': uuid.uuid4().hex, 'name': '', 'description': '', 'enabled': False} test_data.tenant_one = Tenant(TenantManager(None), tenant_dict_1, loaded=True) test_data.tenant_two = Tenant(TenantManager(None), tenant_dict_2, loaded=True) nova_service = { 'type': 'compute', 'name': 'nova', 'endpoint_links': [], 'endpoints': [ { 'region': 'RegionOne', 'adminURL': 'http://nova-admin.localhost:8774/v2.0/%s' \ % (tenant_dict_1['id']), 'internalURL': 'http://nova-internal.localhost:8774/v2.0/%s' \ % (tenant_dict_1['id']), 'publicURL': 'http://nova-public.localhost:8774/v2.0/%s' \ % (tenant_dict_1['id']) }, { 'region': 'RegionTwo', 'adminURL': 'http://nova2-admin.localhost:8774/v2.0/%s' \ % (tenant_dict_1['id']), 'internalURL': 'http://nova2-internal.localhost:8774/v2.0/%s' \ % (tenant_dict_1['id']), 'publicURL': 'http://nova2-public.localhost:8774/v2.0/%s' \ % (tenant_dict_1['id']) } ] } # Roles role_dict = {'id': uuid.uuid4().hex, 'name': 'Member'} test_data.role = Role(RoleManager, role_dict) # Tokens tomorrow = datetime_safe.datetime.now() + timedelta(days=1) expiration = datetime_safe.datetime.isoformat(tomorrow) scoped_token_dict = { 'access': { 'token': { 'id': uuid.uuid4().hex, 'expires': expiration, 'tenant': tenant_dict_1, 'tenants': [tenant_dict_1, tenant_dict_2]}, 'user': { 'id': user_dict['id'], 'name': user_dict['name'], 'roles': [role_dict]}, 'serviceCatalog': [keystone_service, nova_service] } } test_data.scoped_access_info = AccessInfo.factory( resp=None, body=scoped_token_dict) unscoped_token_dict = { 'access': { 'token': { 'id': uuid.uuid4().hex, 'expires': expiration}, 'user': { 'id': user_dict['id'], 'name': user_dict['name'], 'roles': [role_dict]}, 'serviceCatalog': [keystone_service] } } test_data.unscoped_access_info = AccessInfo.factory( resp=None, body=unscoped_token_dict) # Service Catalog test_data.service_catalog = ServiceCatalog.factory({ 'serviceCatalog': [keystone_service, nova_service], 'token': { 'id': scoped_token_dict['access']['token']['id'], 'expires': scoped_token_dict['access']['token']['expires'], 'user_id': user_dict['id'], 'tenant_id': tenant_dict_1['id'] } }) return test_data python-django-openstack-auth-1.1.3/openstack_auth/tests/models.py0000644000175000017500000000000012222632545024175 0ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/tests/__init__.py0000644000175000017500000000000012222632545024451 0ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/tests/tests.py0000644000175000017500000010747112222632545024100 0ustar chuckchuck# 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 mox from django import test from django.conf import settings from django.contrib.auth import REDIRECT_FIELD_NAME from django.core.urlresolvers import reverse from keystoneclient import exceptions as keystone_exceptions from keystoneclient.v2_0 import client as client_v2 from keystoneclient.v3 import client as client_v3 from .data_v2 import generate_test_data as data_v2 from .data_v3 import generate_test_data as data_v3 import copy DEFAULT_DOMAIN = settings.OPENSTACK_KEYSTONE_DEFAULT_DOMAIN class OpenStackAuthTestsV2(test.TestCase): def setUp(self): super(OpenStackAuthTestsV2, self).setUp() self.mox = mox.Mox() self.data = data_v2() self.ks_client_module = client_v2 endpoint = settings.OPENSTACK_KEYSTONE_URL self.keystone_client_unscoped = self.ks_client_module.Client( endpoint=endpoint, auth_ref=self.data.unscoped_access_info) self.keystone_client_scoped = self.ks_client_module.Client( endpoint=endpoint, auth_ref=self.data.scoped_access_info) def tearDown(self): self.mox.UnsetStubs() self.mox.VerifyAll() def test_login(self): tenants = [self.data.tenant_one, self.data.tenant_two] user = self.data.user unscoped = self.data.unscoped_access_info form_data = {'region': settings.OPENSTACK_KEYSTONE_URL, 'domain': DEFAULT_DOMAIN, 'password': user.password, 'username': user.name} self.mox.StubOutWithMock(self.ks_client_module, "Client") self.mox.StubOutWithMock(self.keystone_client_unscoped.tenants, "list") self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, password=user.password, username=user.name, user_domain_name=DEFAULT_DOMAIN, insecure=False, debug=False)\ .AndReturn(self.keystone_client_unscoped) self.keystone_client_unscoped.tenants.list().AndReturn(tenants) self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, tenant_id=self.data.tenant_two.id, insecure=False, token=unscoped.auth_token, debug=False) \ .AndReturn(self.keystone_client_scoped) self.mox.ReplayAll() url = reverse('login') # GET the page to set the test cookie. response = self.client.get(url, form_data) self.assertEqual(response.status_code, 200) # POST to the page to log in. response = self.client.post(url, form_data) self.assertRedirects(response, settings.LOGIN_REDIRECT_URL) def test_login_with_disabled_tenants(self): # Test to validate that authentication will try to get # scoped token if the first project is disabled. tenants = [self.data.tenant_one, self.data.tenant_two] user = self.data.user unscoped = self.data.unscoped_access_info form_data = {'region': settings.OPENSTACK_KEYSTONE_URL, 'domain': DEFAULT_DOMAIN, 'password': user.password, 'username': user.name} self.mox.StubOutWithMock(self.ks_client_module, "Client") self.mox.StubOutWithMock(self.keystone_client_unscoped.tenants, "list") self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, password=user.password, username=user.name, user_domain_name=DEFAULT_DOMAIN, insecure=False, debug=False)\ .AndReturn(self.keystone_client_unscoped) self.keystone_client_unscoped.tenants.list().AndReturn(tenants) exc = keystone_exceptions.AuthorizationFailure self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, tenant_id=self.data.tenant_two.id, insecure=False, token=unscoped.auth_token, debug=False) \ .AndRaise(exc) self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, tenant_id=self.data.tenant_one.id, insecure=False, token=unscoped.auth_token, debug=False) \ .AndReturn(self.keystone_client_scoped) self.mox.ReplayAll() url = reverse('login') # GET the page to set the test cookie. response = self.client.get(url, form_data) self.assertEqual(response.status_code, 200) # POST to the page to log in. response = self.client.post(url, form_data) self.assertRedirects(response, settings.LOGIN_REDIRECT_URL) def test_no_enabled_tenants(self): tenants = [self.data.tenant_one, self.data.tenant_two] user = self.data.user unscoped = self.data.unscoped_access_info form_data = {'region': settings.OPENSTACK_KEYSTONE_URL, 'domain': DEFAULT_DOMAIN, 'password': user.password, 'username': user.name} self.mox.StubOutWithMock(self.ks_client_module, "Client") self.mox.StubOutWithMock(self.keystone_client_unscoped.tenants, "list") self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, password=user.password, username=user.name, user_domain_name=DEFAULT_DOMAIN, insecure=False, debug=False)\ .AndReturn(self.keystone_client_unscoped) self.keystone_client_unscoped.tenants.list().AndReturn(tenants) exc = keystone_exceptions.AuthorizationFailure self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, tenant_id=self.data.tenant_two.id, insecure=False, token=unscoped.auth_token, debug=False) \ .AndRaise(exc) self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, tenant_id=self.data.tenant_one.id, insecure=False, token=unscoped.auth_token, debug=False) \ .AndRaise(exc) self.mox.ReplayAll() url = reverse('login') # GET the page to set the test cookie. response = self.client.get(url, form_data) self.assertEqual(response.status_code, 200) # POST to the page to log in. response = self.client.post(url, form_data) self.assertTemplateUsed(response, 'auth/login.html') self.assertContains(response, 'Unable to authenticate to any available' ' projects.') def test_no_tenants(self): user = self.data.user form_data = {'region': settings.OPENSTACK_KEYSTONE_URL, 'domain': DEFAULT_DOMAIN, 'password': user.password, 'username': user.name} self.mox.StubOutWithMock(self.ks_client_module, "Client") self.mox.StubOutWithMock(self.keystone_client_unscoped.tenants, "list") self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, password=user.password, username=user.name, user_domain_name=DEFAULT_DOMAIN, insecure=False, debug=False)\ .AndReturn(self.keystone_client_unscoped) self.keystone_client_unscoped.tenants.list().AndReturn([]) self.mox.ReplayAll() url = reverse('login') # GET the page to set the test cookie. response = self.client.get(url, form_data) self.assertEqual(response.status_code, 200) # POST to the page to log in. response = self.client.post(url, form_data) self.assertTemplateUsed(response, 'auth/login.html') self.assertContains(response, 'You are not authorized for any projects.') def test_invalid_credentials(self): user = self.data.user form_data = {'region': settings.OPENSTACK_KEYSTONE_URL, 'domain': DEFAULT_DOMAIN, 'password': "invalid", 'username': user.name} self.mox.StubOutWithMock(self.ks_client_module, "Client") exc = keystone_exceptions.Unauthorized(401) self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, password="invalid", username=user.name, user_domain_name=DEFAULT_DOMAIN, insecure=False, debug=False).AndRaise(exc) self.mox.ReplayAll() url = reverse('login') # GET the page to set the test cookie. response = self.client.get(url, form_data) self.assertEqual(response.status_code, 200) # POST to the page to log in. response = self.client.post(url, form_data) self.assertTemplateUsed(response, 'auth/login.html') self.assertContains(response, "Invalid user name or password.") def test_exception(self): user = self.data.user form_data = {'region': settings.OPENSTACK_KEYSTONE_URL, 'domain': DEFAULT_DOMAIN, 'password': user.password, 'username': user.name} self.mox.StubOutWithMock(self.ks_client_module, "Client") exc = keystone_exceptions.ClientException(500) self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, password=user.password, username=user.name, user_domain_name=DEFAULT_DOMAIN, insecure=False, debug=False).AndRaise(exc) self.mox.ReplayAll() url = reverse('login') # GET the page to set the test cookie. response = self.client.get(url, form_data) self.assertEqual(response.status_code, 200) # POST to the page to log in. response = self.client.post(url, form_data) self.assertTemplateUsed(response, 'auth/login.html') self.assertContains(response, ("An error occurred authenticating. Please try " "again later.")) def test_switch(self, next=None): tenant = self.data.tenant_two tenants = [self.data.tenant_one, self.data.tenant_two] user = self.data.user unscoped = self.data.unscoped_access_info scoped = self.data.scoped_access_info sc = self.data.service_catalog et = getattr(settings, 'OPENSTACK_ENDPOINT_TYPE', 'publicURL') form_data = {'region': settings.OPENSTACK_KEYSTONE_URL, 'domain': DEFAULT_DOMAIN, 'username': user.name, 'password': user.password} self.mox.StubOutWithMock(self.ks_client_module, "Client") self.mox.StubOutWithMock(self.keystone_client_unscoped.tenants, "list") self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, password=user.password, username=user.name, user_domain_name=DEFAULT_DOMAIN, insecure=False, debug=False) \ .AndReturn(self.keystone_client_unscoped) self.keystone_client_unscoped.tenants.list().AndReturn(tenants) self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, tenant_id=self.data.tenant_two.id, insecure=False, token=unscoped.auth_token, debug=False) \ .AndReturn(self.keystone_client_scoped) self.ks_client_module.Client(auth_url=sc.url_for(endpoint_type=et), tenant_id=tenant.id, token=scoped.auth_token, insecure=False, debug=False) \ .AndReturn(self.keystone_client_scoped) self.mox.ReplayAll() url = reverse('login') response = self.client.get(url) self.assertEqual(response.status_code, 200) response = self.client.post(url, form_data) self.assertRedirects(response, settings.LOGIN_REDIRECT_URL) url = reverse('switch_tenants', args=[tenant.id]) scoped['token']['tenant']['id'] = self.data.tenant_two.id if next: form_data.update({REDIRECT_FIELD_NAME: next}) response = self.client.get(url, form_data) if next: expected_url = 'http://testserver%s' % next self.assertEqual(response['location'], expected_url) else: self.assertRedirects(response, settings.LOGIN_REDIRECT_URL) self.assertEqual(self.client.session['token'].tenant['id'], scoped.tenant_id) def test_switch_with_next(self): self.test_switch(next='/next_url') def test_switch_region(self, next=None): tenants = [self.data.tenant_one, self.data.tenant_two] user = self.data.user unscoped = self.data.unscoped_access_info sc = self.data.service_catalog form_data = {'region': settings.OPENSTACK_KEYSTONE_URL, 'domain': DEFAULT_DOMAIN, 'username': user.name, 'password': user.password} self.mox.StubOutWithMock(self.ks_client_module, "Client") self.mox.StubOutWithMock(self.keystone_client_unscoped.tenants, "list") self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, password=user.password, username=user.name, user_domain_name=DEFAULT_DOMAIN, insecure=False, debug=False) \ .AndReturn(self.keystone_client_unscoped) self.keystone_client_unscoped.tenants.list().AndReturn(tenants) self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, tenant_id=self.data.tenant_two.id, insecure=False, token=unscoped.auth_token, debug=False) \ .AndReturn(self.keystone_client_scoped) self.mox.ReplayAll() url = reverse('login') response = self.client.get(url) self.assertEqual(response.status_code, 200) response = self.client.post(url, form_data) self.assertRedirects(response, settings.LOGIN_REDIRECT_URL) old_region = sc.get_endpoints()['compute'][0]['region'] self.assertEqual(self.client.session['services_region'], old_region) region = sc.get_endpoints()['compute'][1]['region'] url = reverse('switch_services_region', args=[region]) form_data['region_name'] = region if next: form_data.update({REDIRECT_FIELD_NAME: next}) response = self.client.get(url, form_data) if next: expected_url = 'http://testserver%s' % next self.assertEqual(response['location'], expected_url) else: self.assertRedirects(response, settings.LOGIN_REDIRECT_URL) self.assertEqual(self.client.session['services_region'], region) def test_switch_region_with_next(self, next=None): self.test_switch_region(next='/next_url') def EndpointMetaFactory(endpoint_type): def endpoint_wrapper(func): def new_func(*args, **kwargs): _endpoint_type = getattr(settings, 'OPENSTACK_ENDPOINT_TYPE', None) # set settings.OPENSTACK_ENDPOINT_TYPE to given value setattr(settings, 'OPENSTACK_ENDPOINT_TYPE', endpoint_type) # ensure that ret won't be touched by del/setattr below ret = copy.deepcopy(func(*args, **kwargs)) # and restore it if _endpoint_type is None: del settings.OPENSTACK_ENDPOINT_TYPE else: setattr(settings, 'OPENSTACK_ENDPOINT_TYPE', _endpoint_type) return ret return new_func class EndPointMeta(type): # wrap each test with OPENSTACK_ENDPOINT_TYPE parameter set/restore def __new__(cls, name, bases, attrs): base, = bases for k, v in base.__dict__.iteritems(): if not k.startswith('__') and getattr(v, '__call__', None): attrs[k] = endpoint_wrapper(v) return super(EndPointMeta, cls).__new__(cls, name, bases, attrs) return EndPointMeta class OpenStackAuthTestsV2WithPublicURL(OpenStackAuthTestsV2): """Test V2 with settings.OPENSTACK_ENDPOINT_TYPE = 'publicURL'.""" __metaclass__ = EndpointMetaFactory('publicURL') class OpenStackAuthTestsV2WithInternalURL(OpenStackAuthTestsV2): """Test V2 with settings.OPENSTACK_ENDPOINT_TYPE = 'internalURL'.""" __metaclass__ = EndpointMetaFactory('internalURL') class OpenStackAuthTestsV2WithAdminURL(OpenStackAuthTestsV2): """Test V2 with settings.OPENSTACK_ENDPOINT_TYPE = 'adminURL'.""" __metaclass__ = EndpointMetaFactory('adminURL') class OpenStackAuthTestsV3(test.TestCase): def setUp(self): super(OpenStackAuthTestsV3, self).setUp() self.mox = mox.Mox() self.data = data_v3() self.ks_client_module = client_v3 endpoint = settings.OPENSTACK_KEYSTONE_URL self.keystone_client_unscoped = self.ks_client_module.Client( endpoint=endpoint, auth_ref=self.data.unscoped_access_info) self.keystone_client_scoped = self.ks_client_module.Client( endpoint=endpoint, auth_ref=self.data.scoped_access_info) settings.OPENSTACK_API_VERSIONS['identity'] = 3 settings.OPENSTACK_KEYSTONE_URL = "http://localhost:5000/v3" def tearDown(self): self.mox.UnsetStubs() self.mox.VerifyAll() def test_login(self): projects = [self.data.project_one, self.data.project_two] user = self.data.user unscoped = self.data.unscoped_access_info form_data = {'region': settings.OPENSTACK_KEYSTONE_URL, 'domain': DEFAULT_DOMAIN, 'password': user.password, 'username': user.name} self.mox.StubOutWithMock(self.ks_client_module, "Client") self.mox.StubOutWithMock(self.keystone_client_unscoped.projects, "list") self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, password=user.password, username=user.name, user_domain_name=DEFAULT_DOMAIN, insecure=False, debug=False)\ .AndReturn(self.keystone_client_unscoped) self.keystone_client_unscoped.projects.list(user=user.id) \ .AndReturn(projects) self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, tenant_id=self.data.project_two.id, insecure=False, token=unscoped.auth_token, debug=False) \ .AndReturn(self.keystone_client_scoped) self.mox.ReplayAll() url = reverse('login') # GET the page to set the test cookie. response = self.client.get(url, form_data) self.assertEqual(response.status_code, 200) # POST to the page to log in. response = self.client.post(url, form_data) self.assertRedirects(response, settings.LOGIN_REDIRECT_URL) def test_login_with_disabled_projects(self): projects = [self.data.project_one, self.data.project_two] user = self.data.user unscoped = self.data.unscoped_access_info form_data = {'region': settings.OPENSTACK_KEYSTONE_URL, 'domain': DEFAULT_DOMAIN, 'password': user.password, 'username': user.name} self.mox.StubOutWithMock(self.ks_client_module, "Client") self.mox.StubOutWithMock(self.keystone_client_unscoped.projects, "list") self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, password=user.password, username=user.name, user_domain_name=DEFAULT_DOMAIN, insecure=False, debug=False)\ .AndReturn(self.keystone_client_unscoped) self.keystone_client_unscoped.projects.list(user=user.id) \ .AndReturn(projects) exc = keystone_exceptions.AuthorizationFailure self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, tenant_id=self.data.project_two.id, insecure=False, token=unscoped.auth_token, debug=False) \ .AndRaise(exc) self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, tenant_id=self.data.project_one.id, insecure=False, token=unscoped.auth_token, debug=False) \ .AndReturn(self.keystone_client_scoped) self.mox.ReplayAll() url = reverse('login') # GET the page to set the test cookie. response = self.client.get(url, form_data) self.assertEqual(response.status_code, 200) # POST to the page to log in. response = self.client.post(url, form_data) self.assertRedirects(response, settings.LOGIN_REDIRECT_URL) def test_no_enabled_projects(self): projects = [self.data.project_one, self.data.project_two] user = self.data.user unscoped = self.data.unscoped_access_info form_data = {'region': settings.OPENSTACK_KEYSTONE_URL, 'domain': DEFAULT_DOMAIN, 'password': user.password, 'username': user.name} self.mox.StubOutWithMock(self.ks_client_module, "Client") self.mox.StubOutWithMock(self.keystone_client_unscoped.projects, "list") self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, password=user.password, username=user.name, user_domain_name=DEFAULT_DOMAIN, insecure=False, debug=False)\ .AndReturn(self.keystone_client_unscoped) self.keystone_client_unscoped.projects.list(user=user.id) \ .AndReturn(projects) exc = keystone_exceptions.AuthorizationFailure self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, tenant_id=self.data.project_two.id, insecure=False, token=unscoped.auth_token, debug=False) \ .AndRaise(exc) self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, tenant_id=self.data.project_one.id, insecure=False, token=unscoped.auth_token, debug=False) \ .AndRaise(exc) self.mox.ReplayAll() url = reverse('login') # GET the page to set the test cookie. response = self.client.get(url, form_data) self.assertEqual(response.status_code, 200) # POST to the page to log in. response = self.client.post(url, form_data) self.assertTemplateUsed(response, 'auth/login.html') self.assertContains(response, 'Unable to authenticate to any available' ' projects.') def test_no_projects(self): user = self.data.user form_data = {'region': settings.OPENSTACK_KEYSTONE_URL, 'domain': DEFAULT_DOMAIN, 'password': user.password, 'username': user.name} self.mox.StubOutWithMock(self.ks_client_module, "Client") self.mox.StubOutWithMock(self.keystone_client_unscoped.projects, "list") self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, password=user.password, username=user.name, user_domain_name=DEFAULT_DOMAIN, insecure=False, debug=False)\ .AndReturn(self.keystone_client_unscoped) self.keystone_client_unscoped.projects.list(user=user.id) \ .AndReturn([]) self.mox.ReplayAll() url = reverse('login') # GET the page to set the test cookie. response = self.client.get(url, form_data) self.assertEqual(response.status_code, 200) # POST to the page to log in. response = self.client.post(url, form_data) self.assertTemplateUsed(response, 'auth/login.html') self.assertContains(response, 'You are not authorized for any projects.') def test_invalid_credentials(self): user = self.data.user form_data = {'region': settings.OPENSTACK_KEYSTONE_URL, 'domain': DEFAULT_DOMAIN, 'password': "invalid", 'username': user.name} self.mox.StubOutWithMock(self.ks_client_module, "Client") exc = keystone_exceptions.Unauthorized(401) self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, password="invalid", username=user.name, user_domain_name=DEFAULT_DOMAIN, insecure=False, debug=False).AndRaise(exc) self.mox.ReplayAll() url = reverse('login') # GET the page to set the test cookie. response = self.client.get(url, form_data) self.assertEqual(response.status_code, 200) # POST to the page to log in. response = self.client.post(url, form_data) self.assertTemplateUsed(response, 'auth/login.html') self.assertContains(response, "Invalid user name or password.") def test_exception(self): user = self.data.user form_data = {'region': settings.OPENSTACK_KEYSTONE_URL, 'domain': DEFAULT_DOMAIN, 'password': user.password, 'username': user.name} self.mox.StubOutWithMock(self.ks_client_module, "Client") exc = keystone_exceptions.ClientException(500) self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, password=user.password, username=user.name, user_domain_name=DEFAULT_DOMAIN, insecure=False, debug=False).AndRaise(exc) self.mox.ReplayAll() url = reverse('login') # GET the page to set the test cookie. response = self.client.get(url, form_data) self.assertEqual(response.status_code, 200) # POST to the page to log in. response = self.client.post(url, form_data) self.assertTemplateUsed(response, 'auth/login.html') self.assertContains(response, ("An error occurred authenticating. Please try " "again later.")) def test_switch(self, next=None): project = self.data.project_two projects = [self.data.project_one, self.data.project_two] user = self.data.user unscoped = self.data.unscoped_access_info scoped = self.data.scoped_access_info sc = self.data.service_catalog et = getattr(settings, 'OPENSTACK_ENDPOINT_TYPE', 'publicURL') form_data = {'region': settings.OPENSTACK_KEYSTONE_URL, 'domain': DEFAULT_DOMAIN, 'username': user.name, 'password': user.password} self.mox.StubOutWithMock(self.ks_client_module, "Client") self.mox.StubOutWithMock(self.keystone_client_unscoped.projects, "list") self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, password=user.password, username=user.name, user_domain_name=DEFAULT_DOMAIN, insecure=False, debug=False) \ .AndReturn(self.keystone_client_unscoped) self.keystone_client_unscoped.projects.list(user=user.id) \ .AndReturn(projects) self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, tenant_id=self.data.project_two.id, insecure=False, token=unscoped.auth_token, debug=False) \ .AndReturn(self.keystone_client_scoped) self.ks_client_module.Client(auth_url=sc.url_for(endpoint_type=et), tenant_id=project.id, token=scoped.auth_token, insecure=False, debug=False) \ .AndReturn(self.keystone_client_scoped) self.mox.ReplayAll() url = reverse('login') response = self.client.get(url) self.assertEqual(response.status_code, 200) response = self.client.post(url, form_data) self.assertRedirects(response, settings.LOGIN_REDIRECT_URL) url = reverse('switch_tenants', args=[project.id]) scoped['project']['id'] = self.data.project_two.id if next: form_data.update({REDIRECT_FIELD_NAME: next}) response = self.client.get(url, form_data) if next: expected_url = 'http://testserver%s' % next self.assertEqual(response['location'], expected_url) else: self.assertRedirects(response, settings.LOGIN_REDIRECT_URL) self.assertEqual(self.client.session['token'].project['id'], scoped.project_id) def test_switch_with_next(self): self.test_switch(next='/next_url') def test_switch_region(self, next=None): projects = [self.data.project_one, self.data.project_two] user = self.data.user unscoped = self.data.unscoped_access_info sc = self.data.service_catalog form_data = {'region': settings.OPENSTACK_KEYSTONE_URL, 'domain': DEFAULT_DOMAIN, 'username': user.name, 'password': user.password} self.mox.StubOutWithMock(self.ks_client_module, "Client") self.mox.StubOutWithMock(self.keystone_client_unscoped.projects, "list") self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, password=user.password, username=user.name, user_domain_name=DEFAULT_DOMAIN, insecure=False, debug=False) \ .AndReturn(self.keystone_client_unscoped) self.keystone_client_unscoped.projects.list(user=user.id) \ .AndReturn(projects) self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, tenant_id=self.data.project_two.id, insecure=False, token=unscoped.auth_token, debug=False) \ .AndReturn(self.keystone_client_scoped) self.mox.ReplayAll() url = reverse('login') response = self.client.get(url) self.assertEqual(response.status_code, 200) response = self.client.post(url, form_data) self.assertRedirects(response, settings.LOGIN_REDIRECT_URL) old_region = sc.get_endpoints()['compute'][0]['region'] self.assertEqual(self.client.session['services_region'], old_region) region = sc.get_endpoints()['compute'][1]['region'] url = reverse('switch_services_region', args=[region]) form_data['region_name'] = region if next: form_data.update({REDIRECT_FIELD_NAME: next}) response = self.client.get(url, form_data) if next: expected_url = 'http://testserver%s' % next self.assertEqual(response['location'], expected_url) else: self.assertRedirects(response, settings.LOGIN_REDIRECT_URL) self.assertEqual(self.client.session['services_region'], region) def test_switch_region_with_next(self, next=None): self.test_switch_region(next='/next_url') class OpenStackAuthTestsV3WithPublicURL(OpenStackAuthTestsV3): """Test V3 with settings.OPENSTACK_ENDPOINT_TYPE = 'publicURL'.""" __metaclass__ = EndpointMetaFactory('publicURL') class OpenStackAuthTestsV3WithInternalURL(OpenStackAuthTestsV3): """Test V3 with settings.OPENSTACK_ENDPOINT_TYPE = 'internalURL'.""" __metaclass__ = EndpointMetaFactory('internalURL') class OpenStackAuthTestsV3WithAdminURL(OpenStackAuthTestsV3): """Test V3 with settings.OPENSTACK_ENDPOINT_TYPE = 'adminURL'.""" __metaclass__ = EndpointMetaFactory('adminURL') python-django-openstack-auth-1.1.3/openstack_auth/tests/data_v3.py0000644000175000017500000001733112222632545024252 0ustar chuckchuck# 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 requests import uuid from datetime import timedelta from django.utils import datetime_safe from keystoneclient.access import AccessInfo from keystoneclient.service_catalog import ServiceCatalog from keystoneclient.v3.domains import Domain, DomainManager from keystoneclient.v3.roles import Role, RoleManager from keystoneclient.v3.projects import Project, ProjectManager from keystoneclient.v3.users import User, UserManager class TestDataContainer(object): """ Arbitrary holder for test data in an object-oriented fashion. """ pass 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) if isinstance(data, dict): self.status_code = data.get('status_code', None) self.headers = data.get('headers', None) # Fake the text attribute to streamline Response creation self._text = data.get('text', None) else: self.status_code = data def __eq__(self, other): return self.__dict__ == other.__dict__ @property def text(self): return self._text def generate_test_data(): ''' Builds a set of test_data data as returned by Keystone V2. ''' test_data = TestDataContainer() keystone_service = { 'type': 'identity', 'id': uuid.uuid4().hex, 'endpoints': [ { 'url': 'http://admin.localhost:35357/v3', 'region': 'RegionOne', 'interface': 'admin', 'id': uuid.uuid4().hex, }, { 'url': 'http://internal.localhost:5000/v3', 'region': 'RegionOne', 'interface': 'internal', 'id': uuid.uuid4().hex }, { 'url': 'http://public.localhost:5000/v3', 'region': 'RegionOne', 'interface': 'public', 'id': uuid.uuid4().hex } ] } # Domains domain_dict = {'id': uuid.uuid4().hex, 'name': 'domain', 'description': '', 'enabled': True} test_data.domain = Domain(DomainManager(None), domain_dict, loaded=True) # Users user_dict = {'id': uuid.uuid4().hex, 'name': 'gabriel', 'email': 'gabriel@example.com', 'password': 'swordfish', 'domain_id': domain_dict['id'], 'token': '', 'enabled': True} test_data.user = User(UserManager(None), user_dict, loaded=True) # Projects project_dict_1 = {'id': uuid.uuid4().hex, 'name': 'tenant_one', 'description': '', 'domain_id': domain_dict['id'], 'enabled': True} project_dict_2 = {'id': uuid.uuid4().hex, 'name': '', 'description': '', 'domain_id': domain_dict['id'], 'enabled': False} test_data.project_one = Project(ProjectManager(None), project_dict_1, loaded=True) test_data.project_two = Project(ProjectManager(None), project_dict_2, loaded=True) # Roles role_dict = {'id': uuid.uuid4().hex, 'name': 'Member'} test_data.role = Role(RoleManager, role_dict) nova_service = { 'type': 'compute', 'id': uuid.uuid4().hex, 'endpoints': [ { 'url': 'http://nova-admin.localhost:8774/v2.0/%s' \ % (project_dict_1['id']), 'region': 'RegionOne', 'interface': 'admin', 'id': uuid.uuid4().hex, }, { 'url': 'http://nova-internal.localhost:8774/v2.0/%s' \ % (project_dict_1['id']), 'region': 'RegionOne', 'interface': 'internal', 'id': uuid.uuid4().hex }, { 'url': 'http://nova-public.localhost:8774/v2.0/%s' \ % (project_dict_1['id']), 'region': 'RegionOne', 'interface': 'public', 'id': uuid.uuid4().hex }, { 'url': 'http://nova2-admin.localhost:8774/v2.0/%s' \ % (project_dict_1['id']), 'region': 'RegionTwo', 'interface': 'admin', 'id': uuid.uuid4().hex, }, { 'url': 'http://nova2-internal.localhost:8774/v2.0/%s' \ % (project_dict_1['id']), 'region': 'RegionTwo', 'interface': 'internal', 'id': uuid.uuid4().hex }, { 'url': 'http://nova2-public.localhost:8774/v2.0/%s' \ % (project_dict_1['id']), 'region': 'RegionTwo', 'interface': 'public', 'id': uuid.uuid4().hex } ] } # Tokens tomorrow = datetime_safe.datetime.now() + timedelta(days=1) expiration = datetime_safe.datetime.isoformat(tomorrow) auth_token = uuid.uuid4().hex auth_response_headers = { 'X-Subject-Token': auth_token } auth_response = TestResponse({ "headers": auth_response_headers }) scoped_token_dict = { 'token': { 'methods': ['password'], 'expires_at': expiration, 'project': { 'id': project_dict_1['id'], 'name': project_dict_1['name'], 'domain': { 'id': domain_dict['id'], 'name': domain_dict['name'] } }, 'user': { 'id': user_dict['id'], 'name': user_dict['name'], 'domain': { 'id': domain_dict['id'], 'name': domain_dict['name'] } }, 'roles': [role_dict], 'catalog': [keystone_service, nova_service] } } test_data.scoped_access_info = AccessInfo.factory( resp=auth_response, body=scoped_token_dict ) unscoped_token_dict = { 'token': { 'methods': ['password'], 'expires_at': expiration, 'user': { 'id': user_dict['id'], 'name': user_dict['name'], 'domain': { 'id': domain_dict['id'], 'name': domain_dict['name'] } }, 'catalog': [keystone_service] } } test_data.unscoped_access_info = AccessInfo.factory( resp=auth_response, body=unscoped_token_dict ) # Service Catalog test_data.service_catalog = ServiceCatalog.factory({ 'methods': ['password'], 'user': {}, 'catalog': [keystone_service, nova_service], }, token=auth_token) return test_data python-django-openstack-auth-1.1.3/openstack_auth/tests/urls.py0000644000175000017500000000157212222632545023716 0ustar chuckchuck# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. from django.conf.urls.defaults import patterns, include, url from django.views.generic import TemplateView from openstack_auth.utils import patch_middleware_get_user patch_middleware_get_user() urlpatterns = patterns('', url(r"", include('openstack_auth.urls')), url(r"^$", TemplateView.as_view(template_name="auth/blank.html")) ) python-django-openstack-auth-1.1.3/openstack_auth/tests/templates/0000755000175000017500000000000012222632612024343 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/tests/templates/auth/0000755000175000017500000000000012222632612025304 5ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/tests/templates/auth/login.html0000644000175000017500000000031512222632545027306 0ustar chuckchuck Login
{{ csrf_token }} {{ form.as_p }}
python-django-openstack-auth-1.1.3/openstack_auth/tests/templates/auth/blank.html0000644000175000017500000000000012222632545027254 0ustar chuckchuckpython-django-openstack-auth-1.1.3/openstack_auth/tests/run_tests.py0000644000175000017500000000205712222632545024756 0ustar chuckchuck#!/usr/bin/env 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 os import sys os.environ['DJANGO_SETTINGS_MODULE'] = 'openstack_auth.tests.settings' from django.test.simple import DjangoTestSuiteRunner def run(*test_args): if not test_args: test_args = ['tests'] parent = os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "..", ) sys.path.insert(0, parent) failures = DjangoTestSuiteRunner().run_tests(test_args) sys.exit(failures) if __name__ == '__main__': run(*sys.argv[1:]) python-django-openstack-auth-1.1.3/openstack_auth/backend.py0000644000175000017500000002020712222632545023152 0ustar chuckchuck# 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. """ Module defining the Django auth backend class for the Keystone API. """ import logging from django.conf import settings from django.utils.translation import ugettext_lazy as _ from keystoneclient import exceptions as keystone_exceptions from .exceptions import KeystoneAuthException from .user import create_user_from_token from .user import Token from .utils import check_token_expiration from .utils import get_keystone_client from .utils import get_keystone_version LOG = logging.getLogger(__name__) KEYSTONE_CLIENT_ATTR = "_keystoneclient" class KeystoneBackend(object): """Django authentication backend class for use with ``django.contrib.auth``. """ def check_auth_expiry(self, auth_ref): if not check_token_expiration(auth_ref): msg = _("The authentication token issued by the Identity service " "has expired.") LOG.warning("The authentication token issued by the Identity " "service appears to have expired before it was " "issued. This may indicate a problem with either your " "server or client configuration.") raise KeystoneAuthException(msg) return True def get_user(self, user_id): """Returns the current user (if authenticated) based on the user ID and session data. Note: this required monkey-patching the ``contrib.auth`` middleware to make the ``request`` object available to the auth backend class. """ if (hasattr(self, 'request') and user_id == self.request.session["user_id"]): token = self.request.session['token'] endpoint = self.request.session['region_endpoint'] services_region = self.request.session['services_region'] user = create_user_from_token(self.request, token, endpoint, services_region) return user else: return None def authenticate(self, request=None, username=None, password=None, user_domain_name=None, auth_url=None): """Authenticates a user via the Keystone Identity API. """ LOG.debug('Beginning user authentication for user "%s".' % username) insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False) endpoint_type = getattr( settings, 'OPENSTACK_ENDPOINT_TYPE', 'publicURL') keystone_client = get_keystone_client() try: client = keystone_client.Client( user_domain_name=user_domain_name, username=username, password=password, auth_url=auth_url, insecure=insecure, debug=settings.DEBUG) unscoped_auth_ref = client.auth_ref unscoped_token = Token(auth_ref=unscoped_auth_ref) except (keystone_exceptions.Unauthorized, keystone_exceptions.Forbidden, keystone_exceptions.NotFound) as exc: msg = _('Invalid user name or password.') LOG.debug(exc.message) raise KeystoneAuthException(msg) except (keystone_exceptions.ClientException, keystone_exceptions.AuthorizationFailure) as exc: msg = _("An error occurred authenticating. " "Please try again later.") LOG.debug(exc.message) raise KeystoneAuthException(msg) # Check expiry for our unscoped auth ref. self.check_auth_expiry(unscoped_auth_ref) # Check if token is automatically scoped to default_project if unscoped_auth_ref.project_scoped: auth_ref = unscoped_auth_ref else: # For now we list all the user's projects and iterate through. try: if get_keystone_version() < 3: projects = client.tenants.list() else: client.management_url = auth_url projects = client.projects.list( user=unscoped_auth_ref.user_id) except (keystone_exceptions.ClientException, keystone_exceptions.AuthorizationFailure) as exc: msg = _('Unable to retrieve authorized projects.') raise KeystoneAuthException(msg) # Abort if there are no projects for this user if not projects: msg = _('You are not authorized for any projects.') raise KeystoneAuthException(msg) while projects: project = projects.pop() try: client = keystone_client.Client( tenant_id=project.id, token=unscoped_auth_ref.auth_token, auth_url=auth_url, insecure=insecure, debug=settings.DEBUG) auth_ref = client.auth_ref break except (keystone_exceptions.ClientException, keystone_exceptions.AuthorizationFailure): auth_ref = None if auth_ref is None: msg = _("Unable to authenticate to any available projects.") raise KeystoneAuthException(msg) # Check expiry for our new scoped token. self.check_auth_expiry(auth_ref) # If we made it here we succeeded. Create our User! user = create_user_from_token( request, Token(auth_ref), client.service_catalog.url_for(endpoint_type=endpoint_type)) if request is not None: request.session['unscoped_token'] = unscoped_token.id request.user = user # Support client caching to save on auth calls. setattr(request, KEYSTONE_CLIENT_ATTR, client) LOG.debug('Authentication completed for user "%s".' % username) return user def get_group_permissions(self, user, obj=None): """Returns an empty set since Keystone doesn't support "groups". """ # Keystone V3 added "groups". The Auth token response includes the # roles from the user's Group assignment. It should be fine just # returning an empty set here. return set() def get_all_permissions(self, user, obj=None): """Returns a set of permission strings that this user has through his/her Keystone "roles". The permissions are returned as ``"openstack.{{ role.name }}"``. """ if user.is_anonymous() or obj is not None: return set() # TODO(gabrielhurley): Integrate policy-driven RBAC # when supported by Keystone. role_perms = set(["openstack.roles.%s" % role['name'].lower() for role in user.roles]) service_perms = set(["openstack.services.%s" % service['type'].lower() for service in user.service_catalog]) return role_perms | service_perms def has_perm(self, user, perm, obj=None): """Returns True if the given user has the specified permission. """ if not user.is_active: return False return perm in self.get_all_permissions(user, obj) def has_module_perms(self, user, app_label): """Returns True if user has any permissions in the given app_label. Currently this matches for the app_label ``"openstack"``. """ if not user.is_active: return False for perm in self.get_all_permissions(user): if perm[:perm.index('.')] == app_label: return True return False python-django-openstack-auth-1.1.3/openstack_auth/urls.py0000644000175000017500000000176312222632545022556 0ustar chuckchuck# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. from django.conf.urls.defaults import patterns, url from .utils import patch_middleware_get_user patch_middleware_get_user() urlpatterns = patterns('openstack_auth.views', url(r"^login/$", "login", name='login'), url(r"^logout/$", 'logout', name='logout'), url(r'^switch/(?P[^/]+)/$', 'switch', name='switch_tenants'), url(r'^switch_services_region/(?P[^/]+)/$', 'switch_region', name='switch_services_region') ) python-django-openstack-auth-1.1.3/openstack_auth/exceptions.py0000644000175000017500000000016712222632545023747 0ustar chuckchuckclass KeystoneAuthException(Exception): """ Generic error class to identify and catch our own errors. """ pass python-django-openstack-auth-1.1.3/ChangeLog0000644000175000017500000006134212222632612017753 0ustar chuckchuckcommit 259c57b5b6c8fa0820a584edcae713ffca7c5b3d Author: Gabriel Hurley Date: Tue Oct 1 13:23:50 2013 -0700 Bump version for 1.1.3 Change-Id: I967419f07702820b60a8ee8a57544a3af5c57108 commit 88a513299498b65dccd55b5e4e95903f750bc7b0 Merge: 730142d da13f01 Author: Jenkins Date: Tue Oct 1 20:21:46 2013 +0000 Merge "Import translations from Transifex for Havana RC1" commit 730142d3928dabfe150680db297f8e396420a5a7 Merge: 7431b5b bd28461 Author: Jenkins Date: Mon Sep 30 19:08:19 2013 +0000 Merge "Missing check, supporting changes in horizon for middleware changes" commit 7431b5b334f1bfb944bf7f8ac86c8ff185b6def4 Merge: e6d9060 c661a8e Author: Jenkins Date: Sat Sep 28 13:09:38 2013 +0000 Merge "Add I18N related configurations" commit da13f016d22f397fd33f7c81f10e5b4e38075079 Author: Akihiro MOTOKI Date: Fri Sep 27 22:30:27 2013 +0900 Import translations from Transifex for Havana RC1 Related-Bug: #1229993 Change-Id: I0c5fba2184ea48f180883965b5d53896f6f10a62 commit c661a8ec251dfed55156f152c3c452fda5eea0dc Author: Akihiro MOTOKI Date: Fri Sep 27 22:49:41 2013 +0900 Add I18N related configurations * Add Transifex config * Add babel config to setup.cfg (extract_messages, compile_catalog) * Add Babel to test-requirements.txt (It is only required when extracting and compiling catalogs * Move English PO file to openstack_auth.pot (following other OpenStack projects) * Remove English MO file Change-Id: I7a908006c7a2c586d9d86cbfe3970b56f1461125 commit e6d9060611e48b7e952f2881a7687ee64af0f8c5 Author: Yves-Gwenael Bourhis Date: Fri Sep 20 18:17:10 2013 +0200 Revoking token when switching tenant or loging out Tokens where added to a list which was continuesly growing after each project switch. When session storage is configured to use signed cookies, this was leading to having cookies growing above the 4KB limit. Change-Id: I636ee34546a3a2bc59ae727cf8b1b64cd816e867 Closes-Bug: #1227754 commit 3225ad1261e77cca8102f58491f52e793bdf06d5 Merge: 649664c 6e285e8 Author: Jenkins Date: Wed Sep 25 18:40:34 2013 +0000 Merge "Add Apache2 licence header in data_v3.py" commit 649664cc88cb5ad77c839fbbe1bd65256b84282a Merge: 17f2a92 4698988 Author: Jenkins Date: Tue Sep 24 20:16:59 2013 +0000 Merge "Make auth backend use OPENSTACK_ENDPOINT_TYPE parameter from settings." commit 6e285e8e2291a3468df4f2bd360fd151bbc241df Author: Maxime Vidori Date: Tue Sep 24 13:01:46 2013 +0200 Add Apache2 licence header in data_v3.py Fix pep8 error: missing H102 Apache 2.0 license header not found. Fixes bug #1229642 Change-Id: I0cdcad569cef14f0d72f1e8619ca10f239954d59 commit 4698988c4d8ec4f50e8ce4688e8d868044ab9ac6 Author: Timur Sufiev Date: Mon Sep 9 14:26:18 2013 +0400 Make auth backend use OPENSTACK_ENDPOINT_TYPE parameter from settings. And if parameter is missing in dashboard's settings, use default value of 'publicURL'. This default value doesn't fit documentation at http://docs.openstack.org/developer/horizon/topics/settings.html#openstack-endpoint-type, but as lin-hua.cheng@hp.com said (see https://review.openstack.org/#/c/45679/) documentation should be fixed itself. More tests were added: same checks for V2 and V3 are also run for three possible values of settings.OPENSTACK_ENDPOINT_TYPE ('publicURL', 'internalURL' and 'adminURL'). Old test suites correspond to settings.OPENSTACK_ENDPOINT_TYPE parameter not being set. Closes-bug: #1221563 Change-Id: Ic164d1cfcb0c7606c7ca51b869a738b2976bf6ea commit bd28461d0805bb024004a271bf0e18cceabd1a24 Author: ericpeterson-l Date: Thu Aug 15 08:52:16 2013 -0600 Missing check, supporting changes in horizon for middleware changes Change-Id: I6c228d43af43a3b3136088d8a25e9b01efc5d9a5 Fixes: bug#1211535 commit 17f2a927178a2dbd1e42fa3c4344c43614760dda Author: daisy-ycguo Date: Wed Sep 11 13:43:28 2013 +0800 Update message translation files Change-Id: Iff65352927620cf31440021e5fcb1364553679e0 commit 985bf5659cddec4e60d33f0e1c709e0647fab4ca Author: Monty Taylor Date: Tue Sep 10 16:57:19 2013 -0500 Align with OpenStack project standards Change-Id: If03b325c941dcac257b25b90c8b152dcead5edd2 commit 7c92eee987f576f0082781b868058bad7d98e9df Author: Gabriel Hurley Date: Wed Sep 4 12:51:28 2013 -0700 Bump version for H3 release. Change-Id: Ic40ac559447ce68b64f738a8838c817c6497d185 commit bd5b2957e0011ee1da9f1a6fb5ea63de6b3168ae Author: Lin Hua Cheng Date: Thu Aug 15 14:12:14 2013 -0700 Try to scope token for all available projects When scoping fails on the first project, continue trying until a scoped token can be acquired. Change-Id: I2827595423d5be0f5be9a24eded2a63ab7771ca7 Fixes: bug 1212748 commit ebaf37163212b5c1900de6b5cf7be442a2ecda62 Author: Gabriel Hurley Date: Tue Jul 30 16:39:54 2013 -0700 Bumping version for release. Change-Id: Iddfcc3f83eba10db500426bbd7c3f512f42645eb commit 047f7b5ff1809f984ccfd6622dbfc84513eb8ab2 Author: Lin Hua Cheng Date: Wed Jul 17 13:47:11 2013 -0700 Fix issue with V3 Authentication. Unscoped token does not have a roles attribute in it. Fix the code to handle non-existent of roles in the Auth Token. Fixes: bug #1202385 Change-Id: I2bd101e3ed2dd37da86f84773c2b9dafc0717d3b commit 546716c5856a3f76bfc58f24a8222aa1cd1919f7 Author: Monty Taylor Date: Wed Jul 17 11:43:32 2013 -0700 Add tox.ini file and flake8 ignores Change-Id: I11c89c3902d974e94f4fee29211970546579f29e commit afad771fff6bf74e3591e9c5a7ca78c8a524a2dd Author: Monty Taylor Date: Wed Jul 17 11:22:38 2013 -0700 Add OpenStack .gitreview file Change-Id: I42b0dc944cc6c838f0dd2eabcf90b133311f9159 commit 7d8527894fecade27d701d76aaa526c15942ed9e Author: Gabriel Hurley Date: Wed Jul 3 01:37:22 2013 -0700 Dump version for release w/ v3 auth. commit cb24ff88ef24b973a9fc1480da6a9ebb82961d21 Merge: 74f8006 b63d876 Author: Gabriel Hurley Date: Tue Jul 9 10:40:02 2013 -0700 Merge pull request #47 from linhuacheng/login-domain-support Add capability for Keystone V3 Authentication. commit b63d87697402a5cd0322df24091d1046cb95874e Author: Lin Hua Cheng Date: Wed Jul 3 14:25:33 2013 -0700 Add capability for Keystone V3 Authentication. For multi-domain model, set OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT to True and the login form will prompt the user for Domain name. For single-domain model, set OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT to False. The application will use the name of the default domain in OPENSTACK_KEYSTONE_DEFAULT_DOMAIN to login. Cleanup the unused Tenant field in the login form. Implements blueprint login-domain-support commit 74f800684a80f42e034ba68e0bed2138764b67d8 Merge: 036e34e a13abea Author: Gabriel Hurley Date: Mon Jul 1 11:44:37 2013 -0700 Merge pull request #45 from saschpe/master-client025plus-fix Fix testsuite after "Support keystoneclient 0.2.5+" commit a13abea67f0ccdf62489f3fd65e449132b3606cd Author: Sascha Peilicke Date: Mon Jul 1 10:58:43 2013 +0200 Fix testsuite after "Support keystoneclient 0.2.5+" access.AccessInfo.factory() does a (keystone) API version check, thus add versioned_scoped_token_dict to tests/data.py. commit 036e34e1945765ae465383f487c41aec59e93a4f Merge: e070645 d6b252d Author: Gabriel Hurley Date: Tue Jun 25 19:01:30 2013 -0700 Merge pull request #44 from dirkmueller/master Support keystoneclient >= 0.2.5 commit d6b252dc8505af021f1e81845bd3bc662bcba862 Author: Dirk Mueller Date: Sat Jun 22 18:10:17 2013 +0200 Support keystoneclient 0.2.5+ service_catalog became a read-only property. Inject test data via auth_ref now. commit e070645f8637160ca3c95583c0c659fadafe8581 Author: Gabriel Hurley Date: Tue Jun 4 23:57:01 2013 -0700 Adding missing files from docs to sdist tarball. commit 7b7360366d131c88ca67dc17c7dc2501d25d085e Author: Gabriel Hurley Date: Mon May 20 11:21:35 2013 -0700 Bumping version for PyPI release. commit 03b58cbcb433b46b8a32ddd5e6650f2d270b6be8 Merge: d1c92c7 7a1d24f Author: Gabriel Hurley Date: Mon May 20 11:19:18 2013 -0700 Merge pull request #39 from linhuacheng/patch-11 Add username on the log for logout and rescope. commit d1c92c7f1cfee0020ca24adde10e044201458be9 Merge: fcee315 b78a77f Author: Gabriel Hurley Date: Mon May 20 11:18:49 2013 -0700 Merge pull request #42 from dklyle/multi-region Adding basic multi-region support commit b78a77f147bb31ee29f52b62c95c676e66712235 Author: David Lyle Date: Thu May 9 17:02:55 2013 -0600 Adding basic multi-region support This work will enable users to view which regions they have access to based on their service catalog. And set a current region when combined with Horizon changes that build on this. commit 7a1d24f7d6c271280cc33afd023f653af3788f11 Author: linhuacheng Date: Thu Apr 25 17:10:06 2013 -0700 Add username on the log for logout and rescope. commit fcee315e161d54c0a5641ae767201d68ca70b892 Merge: 473f4a2 81588a0 Author: Gabriel Hurley Date: Thu Apr 25 12:21:55 2013 -0700 Merge pull request #37 from mrunge/master typo... commit 81588a071cebe040bed63bd1e589e29f45ca69a6 Author: Matthias Runge Date: Thu Apr 25 08:09:29 2013 +0200 fix typo commit 473f4a2f0cc3df98d1efa56a92d41eb06e5b2fa1 Merge: eeac08d d9709c0 Author: Gabriel Hurley Date: Wed Apr 24 14:29:01 2013 -0700 Merge pull request #35 from linhuacheng/patch-8 Add logging for success/failed login. commit eeac08d9e79cf4dff594b736a07b2d54fc08384f Merge: 72cc5b6 6e36509 Author: Gabriel Hurley Date: Wed Apr 24 14:28:41 2013 -0700 Merge pull request #36 from linhuacheng/patch-10 Add logging on logout and token rescoping commit 6e36509ac972b30f1eecfa1893d8e28dd8d2034f Author: linhuacheng Date: Wed Apr 24 14:11:04 2013 -0700 Add logging on logout and token rescoping User events is useful for data analysis of usage and audit commit d9709c013f9ae7d1569d6793d174f9caf0ff129c Author: linhuacheng Date: Wed Apr 24 14:04:18 2013 -0700 Add logging for success/failed login. The log can be useful for analysis of usage of horizon. commit 72cc5b6c4ac1c4173eced1a6f64a9786958ff13f Author: Gabriel Hurley Date: Wed Apr 24 13:56:35 2013 -0700 Bump version for release to PyPI. commit 92e60b45f0c5ebdb1b63e0cfd9669954cd124414 Merge: 1b41200 ce38374 Author: Gabriel Hurley Date: Wed Apr 24 13:55:22 2013 -0700 Merge pull request #34 from mrunge/master Setting of SECRET_KEY is required for tests to complete on Django-1.5 commit ce3837499e8c01daa5bc2902d2fc74dc1a2f02a0 Author: Matthias Runge Date: Wed Apr 24 09:25:29 2013 +0200 setting of SECRET_KEY is required for Django-1.5 commit 1b4120087a0134ddb31478322b573ce81bd26cb5 Author: Gabriel Hurley Date: Tue Apr 23 13:43:17 2013 -0700 Bump version for new release to PyPI. commit d79912d8782dd27775fdc6f3b2621dcd8c5aefcb Merge: 5cb2862 6235d54 Author: Gabriel Hurley Date: Fri Apr 19 11:57:04 2013 -0700 Merge pull request #31 from linhuacheng/patch-7 Set the pk of User object for Django 1.5 compatibility. commit 5cb2862bf4359d0726b018d6790ddb02833c70c2 Merge: 0ad712a 917be38 Author: Gabriel Hurley Date: Fri Apr 19 11:56:47 2013 -0700 Merge pull request #32 from loles/master Allow insecure authentication commit 917be38f6125af62451853f23ff65d8fb878b6a5 Author: Łukasz Oleś Date: Tue Apr 9 11:07:55 2013 +0400 Fix unit tests after adding insecure flag commit 574e9d5f383fd8551fefcbd604e916d7bff6427c Author: Łukasz Oleś Date: Mon Apr 8 11:54:00 2013 +0400 Allow insecure authentication Pass through the value of OPENSTACK_SSL_NO_VERIFY from settings.py to keystoneclient. This allows connecting to servers with self-signed or otherwise invalid certificates for testing purposes. It extends commit 8759ad4804271d0f86eed514a8007157f44d4ba4 commit 6235d54def515137b1fe49b80113d21adcf231c1 Author: linhuacheng Date: Fri Apr 5 17:48:47 2013 -0700 Updated User object for Django 1.5 compatibility. Setting the pk attribute of the User object for Django 1.5 compatibility. In Django 1.4, the id of the User object was used as the unique identifier. In Django 1.5, the pk is now used instead of id. Here is the related code change in Django: https://github.com/django/django/commit/0eeae15056edf07f786d3be5b47c14ab62eacd31 commit 0ad712a52c7490fb07938fb52495b7c20e49dc4e Merge: 397379e 4e40eed Author: Gabriel Hurley Date: Mon Apr 1 12:03:58 2013 -0700 Merge pull request #25 from dklyle/master Allowing more complex permissions checks commit 397379e5ce4aaf7d5e267d3df110180519d375bb Merge: f6efb0f e9b9c5a Author: Gabriel Hurley Date: Tue Mar 19 12:35:33 2013 -0700 Merge pull request #27 from conkiztador/fix-django-dep Fix compatibility with Django < 1.4.3 commit e9b9c5abff196fe409380e50b725ea6591646267 Author: Kieran Spear Date: Tue Mar 19 10:43:26 2013 +1100 Fix compatibility with Django < 1.4.3 The is_safe_url function used in a previous commit was introduced in Django 1.4.3. I think breaking compatibility with the old version is unnecessary, and Ubuntu has backported the security fixes so I'm hesitant to require a new Django version. This commit moves the function into openstack_auth.utils, and uses it if the Django version is missing. commit 4e40eed8133473ede43942c88c52169838e313a0 Author: David Lyle Date: Thu Mar 7 16:03:45 2013 -0700 Allowing for more complex combinations of permissions. Will check for logical AND of all top level permissions. Will use logical OR for all first level tuples (check that use has one permissions in the tuple) Allows users with different roles to access a panel, while a user with a third role won't be allowed to access the same panel. Examples: Checks for all required permissions ('openstack.roles.admin', 'openstack.roles.L3-support') Checks for admin AND (L2 or L3) ('openstack.roles.admin', ('openstack.roles.L3-support', 'openstack.roles.L2-support'),) commit f6efb0ff31ae8d0db5682cd7ad5b0921e3a4e924 Author: Gabriel Hurley Date: Tue Mar 5 14:18:47 2013 -0800 Bump version for new release. commit 2fabeb84a2f0721e46be509f2df9ffdec3ba7f01 Merge: 808b029 f09875e Author: Gabriel Hurley Date: Wed Feb 27 20:47:58 2013 -0800 Merge pull request #24 from conkiztador/switch_redirect_to Support custom redirect url from the 'switch' view commit f09875e53d45c126adcedd9d3661571e26ba803e Author: Kieran Spear Date: Mon Feb 25 15:19:09 2013 +1100 Support custom redirect url from the 'switch' view The 'login' view currently accepts a parameter specifying the URL to redirect to after a successful login (via ?next=). This adds the same support for the 'switch' view by reusing a couple of lines of code from the Django login view. commit 808b0296e568aba9d0e3a6bf715a5dd0315819ac Merge: b6fe60c 185f855 Author: Gabriel Hurley Date: Sun Feb 10 13:36:50 2013 -0800 Merge pull request #23 from linhuacheng/patch-4 Turn log level down for failure on delete token. commit 185f855e6e9a4ad8565ed9f655a1b19aa8d1a9f4 Author: linhuacheng Date: Fri Feb 8 13:22:20 2013 -0800 Turn log level down for failure on delete token. Delete token is not a published Keystone API, and deleting an expired token might also cause an exception. Instead of logging an error, this should fail silently and log it as just info so that it won't be flagged as error in the application. commit b6fe60c642760bfab466ba606ee119585a13649a Merge: 4b898d5 00d96fb Author: Gabriel Hurley Date: Wed Jan 30 15:37:05 2013 -0800 Merge pull request #22 from dklyle/master Fixing tests to work with keystoneclient v0.2 commit 00d96fb24224fb8b3fd8faefc45386e95b035f9f Author: David Lyle Date: Wed Jan 30 15:19:03 2013 -0700 Fixing tests that broke in transition to python-keystoneclient v0.2 commit 4b898d502213ffde1bd7b40787b66b10b6365564 Merge: b5d55ff 6f378a8 Author: Gabriel Hurley Date: Tue Jan 29 16:38:24 2013 -0800 Merge pull request #20 from linhuacheng/patch-2 Update openstack_auth/views.py commit 6f378a81d5876fe4fa16fafebca1571a1f5ccfd3 Author: linhuacheng Date: Mon Jan 28 16:55:24 2013 -0800 Update openstack_auth/views.py This patch fixes an issue when there are multiples tokens to be deleted, it ensures that the token passed in the header is always the active token. Fixes bug: https://bugs.launchpad.net/horizon/+bug/1108393 commit b5d55ff5eefb95a761e441e31df980147e69ac75 Merge: 2e0ec6b ea954ca Author: Gabriel Hurley Date: Sat Jan 26 10:51:56 2013 -0800 Merge pull request #18 from ericpeterson-l/master missed obvious bug when moving to background thread commit 2e0ec6b5de847aee397a310bf89a608476d53cb0 Merge: b613c78 e2523bb Author: Gabriel Hurley Date: Sat Jan 26 10:51:19 2013 -0800 Merge pull request #17 from samos123/localization Fixed l10n bugs and added zh_CN translation commit b613c787dc2a79673ca6b57a8b7f59d42737c22d Merge: 9c0e61e 253b254 Author: Gabriel Hurley Date: Sat Jan 26 10:50:55 2013 -0800 Merge pull request #16 from mrunge/master German translation commit ea954ca84295e605acb2d38412d145562fa4ac7f Author: erpet Date: Fri Jan 25 14:12:17 2013 -0700 missed obvious bug when moving to new thread commit e2523bb2a7d8bb210a74fff834200e8df554a918 Author: Sam Stoelinga Date: Fri Jan 25 14:22:43 2013 +0800 Fixed l10n bugs and added zh_CN translation Some strings were not being localized because the string was already translated at import time it seems. Also added Chinese translation with help of Zhanghui commit 253b254083f534fa64431635d050287f43411d62 Author: Matthias Runge Date: Thu Jan 24 10:34:06 2013 +0100 Added german translation commit 9c0e61ef84111e727e4066842eaa1b941ecc84c6 Merge: ce96d17 b319ac7 Author: Gabriel Hurley Date: Wed Jan 16 15:13:04 2013 -0800 Merge pull request #15 from ericpeterson-l/master horizon token delete on logout commit b319ac78c81a2b0ad66fa998adf9347c4eec7ec0 Author: ericpeterson-l Date: Tue Dec 11 15:16:48 2012 -0700 horizon bug 1079832 Logout does not revoke the tokens created, correcting to keep tuple of endpoints and clients commit ce96d1712765b173640297d670dcb68c19afa541 Merge: b95664d 8759ad4 Author: Gabriel Hurley Date: Wed Jan 16 12:10:03 2013 -0800 Merge pull request #14 from conkiztador/allow-insecure-ssl Allow insecure authentication commit 8759ad4804271d0f86eed514a8007157f44d4ba4 Author: Kieran Spear Date: Tue Jan 15 15:23:03 2013 +1100 Allow insecure authentication Pass through the value of OPENSTACK_SSL_NO_VERIFY from settings.py to keystoneclient. This allows connecting to servers with self-signed or otherwise invalid certificates for testing purposes. commit b95664d5baf54bfff7c13c8869db5507a377005d Author: Gabriel Hurley Date: Sun Dec 9 19:28:13 2012 -0800 Fixes compatibility with keystoneclient v0.2. commit f8b1be84bf4560d010f99662316372ab9b119b8c Author: Gabriel Hurley Date: Sun Dec 9 18:39:53 2012 -0800 Improves error handling; fixes failing test. Fixes #8, thanks to mrunge for the report. Fixes #10. commit 8a88978154e50ecc385d483e5b4e4f010a578c6d Author: Gabriel Hurley Date: Fri Nov 16 11:51:26 2012 -0800 Slimming down the session size. Uses the MD5 hash for the unscoped token as well as the scoped token, and removes unused (duplicate) data from the session. commit b7c6d9b93e0073bc7f6afdf43ab6c2bb745406a3 Author: Gabriel Hurley Date: Fri Nov 2 14:29:27 2012 -0700 Use the MD5 hash of PKI-signed tokens. Since Keystone's default token format is now PKI, the length of the tokens increased by several orders of magnitude, causing problems with session cookie size exceeding the maximum cookie size. This patch imports the "is_ans1_token" function from Keystone and uses the MD5 hash for PKI-signed tokens since that's supported in Keystone as well. commit ef030ff77a435ef1d327ad8be595cb59b11b64f3 Author: Gabriel Hurley Date: Mon Aug 20 14:49:44 2012 -0700 Bumping version number for bugfix release with redirect fix. commit 8ac8c7e375014fe0be1e31f88851125cde9cbc37 Merge: 0273b91 47ffb62 Author: Gabriel Hurley Date: Mon Aug 20 14:37:46 2012 -0700 Merge pull request #7 from vuntz/redirect-next Fix redirection in login form. commit 47ffb622b62d601d12dab5f86a10acd6bf70cabe Author: Vincent Untz Date: Mon Aug 20 16:25:50 2012 +0200 Fix redirection in logging form The redirection was being ignored because the template in horizon needs the a value for redirect_field_name. We simply set it to the default. commit 0273b9186e6ef191ea4aefb585350863dadbf157 Author: Gabriel Hurley Date: Sun Jul 8 19:33:03 2012 -0700 Bumping version number for permission support release. commit 03fe09c5a5f72dbba9528cbb89daf4d2aea606aa Author: Gabriel Hurley Date: Sun Jul 8 19:30:51 2012 -0700 Adds permissions support. Fixes #1. commit a1ff650761cb641164bcfa7419692a50b568a069 Author: Gabriel Hurley Date: Sun Jul 8 17:18:45 2012 -0700 Catch AuthorizationFailure. Fixes #5. commit a31c1dae93a1033702390b767250d7ec3534d847 Author: Gabriel Hurley Date: Sun Jul 8 16:25:22 2012 -0700 Adding manifest file. commit 0bc387b463753a76385e1c4a72db784789129c36 Author: Gabriel Hurley Date: Sun Jul 8 16:13:13 2012 -0700 Fixed typo in readme. commit 25c0ff6fe7637dda327ed8742b3ca4f816754fef Author: Gabriel Hurley Date: Sun Jul 8 16:12:44 2012 -0700 Added docs to readme. commit 30dddae11243e40d7a4867a783b01d4922924594 Author: Gabriel Hurley Date: Sun Jul 8 16:03:33 2012 -0700 Adding a few translation files. Fixes issue #3. commit 998c96cfaefbf7e6271226688034883e23ce2ca3 Author: Gabriel Hurley Date: Sun Jul 8 15:39:38 2012 -0700 Adds docs. Fixes #2. commit 9d45964b02e98212025399e69395296f288bd546 Author: Gabriel Hurley Date: Sun Jul 8 14:55:31 2012 -0700 Check for expired tokens during authentication. Fixes issue #4. commit df30fe0887e5ce74120459ad3585f7658252be13 Author: Gabriel Hurley Date: Tue Jul 3 02:29:22 2012 -0700 Added note about unit tests. commit afc7a64ff425a71092a61bb7c7f9b229886c5d48 Author: Gabriel Hurley Date: Tue Jul 3 02:27:34 2012 -0700 Fixed README typo. commit 9962375e0c5209ff82b7d6b5fda92bfec8dc4e1c Author: Gabriel Hurley Date: Tue Jul 3 02:25:01 2012 -0700 Initial commit.python-django-openstack-auth-1.1.3/django_openstack_auth.egg-info/0000755000175000017500000000000012222632612024217 5ustar chuckchuckpython-django-openstack-auth-1.1.3/django_openstack_auth.egg-info/top_level.txt0000644000175000017500000000001712222632612026747 0ustar chuckchuckopenstack_auth python-django-openstack-auth-1.1.3/django_openstack_auth.egg-info/not-zip-safe0000644000175000017500000000000112222632550026446 0ustar chuckchuck python-django-openstack-auth-1.1.3/django_openstack_auth.egg-info/requires.txt0000644000175000017500000000007612222632612026622 0ustar chuckchuckpbr>=0.5.21,<1.0 Django>=1.4,<1.6 python-keystoneclient>=0.3.2python-django-openstack-auth-1.1.3/django_openstack_auth.egg-info/SOURCES.txt0000644000175000017500000000557512222632612026117 0ustar chuckchuck.mailmap AUTHORS ChangeLog LICENSE MANIFEST.in README.rst babel.cfg requirements.txt setup.cfg setup.py test-requirements.txt tox.ini .tx/config django_openstack_auth.egg-info/PKG-INFO django_openstack_auth.egg-info/SOURCES.txt django_openstack_auth.egg-info/dependency_links.txt django_openstack_auth.egg-info/not-zip-safe django_openstack_auth.egg-info/requires.txt django_openstack_auth.egg-info/top_level.txt doc/source/conf.py doc/source/index.rst doc/source/installation.rst doc/source/ref/backend.rst doc/source/ref/forms.rst doc/source/ref/user.rst doc/source/ref/utils.rst doc/source/ref/views.rst openstack_auth/__init__.py openstack_auth/backend.py openstack_auth/exceptions.py openstack_auth/forms.py openstack_auth/urls.py openstack_auth/user.py openstack_auth/utils.py openstack_auth/views.py openstack_auth/locale/openstack_auth.pot openstack_auth/locale/ar/LC_MESSAGES/django.mo openstack_auth/locale/ar/LC_MESSAGES/django.po openstack_auth/locale/de/LC_MESSAGES/django.mo openstack_auth/locale/de/LC_MESSAGES/django.po openstack_auth/locale/en_AU/LC_MESSAGES/django.mo openstack_auth/locale/en_AU/LC_MESSAGES/django.po openstack_auth/locale/en_GB/LC_MESSAGES/django.mo openstack_auth/locale/en_GB/LC_MESSAGES/django.po openstack_auth/locale/es/LC_MESSAGES/django.mo openstack_auth/locale/es/LC_MESSAGES/django.po openstack_auth/locale/es_MX/LC_MESSAGES/django.mo openstack_auth/locale/es_MX/LC_MESSAGES/django.po openstack_auth/locale/fr/LC_MESSAGES/django.mo openstack_auth/locale/fr/LC_MESSAGES/django.po openstack_auth/locale/hi/LC_MESSAGES/django.mo openstack_auth/locale/hi/LC_MESSAGES/django.po openstack_auth/locale/ja/LC_MESSAGES/django.mo openstack_auth/locale/ja/LC_MESSAGES/django.po openstack_auth/locale/ko_KR/LC_MESSAGES/django.mo openstack_auth/locale/ko_KR/LC_MESSAGES/django.po openstack_auth/locale/nl_NL/LC_MESSAGES/django.mo openstack_auth/locale/nl_NL/LC_MESSAGES/django.po openstack_auth/locale/pl_PL/LC_MESSAGES/django.mo openstack_auth/locale/pl_PL/LC_MESSAGES/django.po openstack_auth/locale/pt/LC_MESSAGES/django.mo openstack_auth/locale/pt/LC_MESSAGES/django.po openstack_auth/locale/pt_BR/LC_MESSAGES/django.mo openstack_auth/locale/pt_BR/LC_MESSAGES/django.po openstack_auth/locale/ru/LC_MESSAGES/django.mo openstack_auth/locale/ru/LC_MESSAGES/django.po openstack_auth/locale/uk/LC_MESSAGES/django.mo openstack_auth/locale/uk/LC_MESSAGES/django.po openstack_auth/locale/zh_CN/LC_MESSAGES/django.mo openstack_auth/locale/zh_CN/LC_MESSAGES/django.po openstack_auth/locale/zh_TW/LC_MESSAGES/django.mo openstack_auth/locale/zh_TW/LC_MESSAGES/django.po openstack_auth/tests/__init__.py openstack_auth/tests/data_v2.py openstack_auth/tests/data_v3.py openstack_auth/tests/models.py openstack_auth/tests/run_tests.py openstack_auth/tests/settings.py openstack_auth/tests/tests.py openstack_auth/tests/urls.py openstack_auth/tests/templates/auth/blank.html openstack_auth/tests/templates/auth/login.htmlpython-django-openstack-auth-1.1.3/django_openstack_auth.egg-info/PKG-INFO0000644000175000017500000000463112222632612025320 0ustar chuckchuckMetadata-Version: 1.1 Name: django-openstack-auth Version: 1.1.3 Summary: Django authentication backend for use with OpenStack Identity Home-page: http://www.openstack.org/ Author: OpenStack Author-email: openstack-dev@lists.openstack.org License: UNKNOWN Description: ===================== Django OpenStack Auth ===================== Django OpenStack Auth is a pluggable Django authentication backend that works with Django's ``contrib.auth`` framework to authenticate a user against OpenStack's Keystone Identity API. The current version is designed to work with the Keystone V2 API. You can `view the documentation`_ on Read The Docs. .. _view the documentation: http://django-openstack-auth.readthedocs.org/en/latest/ Installation ============ Installing is quick and easy: #. Run ``pip install django_openstack_auth``. #. Add ``openstack_auth`` to ``settings.INSTALLED_APPS``. #. Add ``'keystone_auth.backend.KeystoneBackend'`` to your ``settings.AUTHENTICATION_BACKENDS``, e.g.:: AUTHENTICATION_BACKENDS = ('keystone_auth.backend.KeystoneBackend',) #. Configure your API endpoint(s) in ``settings.py``:: OPENSTACK_KEYSTONE_URL = "http://example.com:5000/v2.0" #. Include ``'keystone_auth.urls'`` somewhere in your ``urls.py`` file. #. Use it as you would any other Django auth backend. Running The Tests ================= Download the repository and run:: python setup.py test Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: OpenStack Classifier: Framework :: Django Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Information Technology Classifier: Intended Audience :: System Administrators Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: OS Independent Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 2.6 Classifier: Topic :: Internet :: WWW/HTTP python-django-openstack-auth-1.1.3/django_openstack_auth.egg-info/dependency_links.txt0000644000175000017500000000000112222632612030265 0ustar chuckchuck