Retire project
In Queens development cycle, openstack_auth code was merged into the horizon repository. blueprint merge-openstack-auth Change-Id: I74b10a90fe79fc768cfb8de6f68d3cd2f4938e51changes/28/523928/5
parent
1fa9ae26cc
commit
2baea728dd
|
@ -1,14 +0,0 @@
|
|||
*.pyc
|
||||
*.egg
|
||||
*.egg-info
|
||||
*.mo
|
||||
.DS_STORE
|
||||
doc/build
|
||||
build
|
||||
dist
|
||||
.tox
|
||||
AUTHORS
|
||||
ChangeLog
|
||||
.coverage
|
||||
reports
|
||||
coverage.xml
|
|
@ -1,4 +0,0 @@
|
|||
[gerrit]
|
||||
host=review.openstack.org
|
||||
port=29418
|
||||
project=openstack/django_openstack_auth.git
|
5
.mailmap
5
.mailmap
|
@ -1,5 +0,0 @@
|
|||
<david.lyle@hp.com> <david-lyle@davidlyle-VirtualBox.(none)>
|
||||
<lin-hua.cheng@hp.com> <lin_hua_cheng@yahoo.com>
|
||||
Eric Peterson <ericpeterson@hp.com> ericpeterson-l <ericpeterson@hp.com>
|
||||
Eric Peterson <ericpeterson@hp.com> erpet <ericpeterson@hp.com>
|
||||
Lin Hua Cheng <lin-hua.cheng@hp.com> linhuacheng <lin-hua.cheng@hp.com>
|
|
@ -1,17 +0,0 @@
|
|||
If you would like to contribute to the development of OpenStack,
|
||||
you must follow the steps documented at:
|
||||
|
||||
http://docs.openstack.org/infra/manual/developers.html
|
||||
|
||||
If you already have a good understanding of how the system works and
|
||||
your OpenStack accounts are set up, you can skip to the development
|
||||
workflow section of this documentation to learn how changes to
|
||||
OpenStack should be submitted for review via the Gerrit tool:
|
||||
|
||||
http://docs.openstack.org/infra/manual/developers.html#development-workflow
|
||||
|
||||
Pull requests submitted through GitHub will be ignored.
|
||||
|
||||
Bugs should be filed on Launchpad, not GitHub:
|
||||
|
||||
https://bugs.launchpad.net/django-openstack-auth
|
176
LICENSE
176
LICENSE
|
@ -1,176 +0,0 @@
|
|||
|
||||
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.
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
include AUTHORS
|
||||
include ChangeLog
|
||||
exclude .gitignore
|
||||
exclude .gitreview
|
||||
|
||||
global-exclude *.pyc
|
33
README.rst
33
README.rst
|
@ -1,27 +1,10 @@
|
|||
========================
|
||||
Team and repository tags
|
||||
========================
|
||||
The code has been merged into openstack/horizon.
|
||||
|
||||
.. image:: http://governance.openstack.org/badges/django_openstack_auth.svg
|
||||
:target: http://governance.openstack.org/reference/tags/index.html
|
||||
The contents of this repository are still available in the Git
|
||||
source code management system. To see the contents of this
|
||||
repository before it was merged into the horizon repo,
|
||||
please check out the previous commit with "git checkout HEAD^1".
|
||||
|
||||
.. Change things from this point on
|
||||
|
||||
=====================
|
||||
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.0 and v3 API.
|
||||
|
||||
You can `view the installation instructions`_ on Read The Docs.
|
||||
|
||||
.. _view the installation instructions: http://docs.openstack.org/developer/django_openstack_auth/
|
||||
|
||||
* License: Apache License, Version 2.0
|
||||
* Documentation: http://django-openstack-auth.readthedocs.org/en/latest/
|
||||
* Source: http://git.openstack.org/cgit/openstack/django_openstack_auth/
|
||||
* Bugs: https://bugs.launchpad.net/django-openstack-auth
|
||||
For any further questions, please email
|
||||
openstack-dev@lists.openstack.org or
|
||||
join #openstack-horizon on Freenode.
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
[python: **.py]
|
|
@ -1,170 +0,0 @@
|
|||
# -*- 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.
|
||||
|
||||
import os
|
||||
|
||||
import django
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'openstack_auth.tests.settings')
|
||||
|
||||
django.setup()
|
||||
|
||||
# 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', 'openstackdocstheme']
|
||||
|
||||
# openstackdocstheme options
|
||||
repository_name = 'openstack/django_openstack_auth'
|
||||
bug_project = 'django-openstack-auth'
|
||||
bug_tag = ''
|
||||
html_last_updated_fmt = '%Y-%m-%d %H:%M'
|
||||
|
||||
# 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 = ['openstack_auth.']
|
||||
|
||||
|
||||
# -- 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 = 'openstackdocs'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
#html_static_path = []
|
||||
|
||||
# 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 <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# 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'
|
|
@ -1,442 +0,0 @@
|
|||
=============
|
||||
Configuration
|
||||
=============
|
||||
|
||||
Django OpenStack Auth is configured through Django ``settings.py`` file.
|
||||
In most cases it is used combined with the OpenStack Dashboard,
|
||||
so the settings file will be ``local/local_settings.py`` file
|
||||
in your OpenStack Dashboard deployment.
|
||||
|
||||
This page covers the configuration options referred by Django OpenStack Auth.
|
||||
|
||||
:ref:`Some settings <settings-shared-with-horizon>` are also referred to
|
||||
by Horizon. Configure them carefully.
|
||||
|
||||
General settings
|
||||
================
|
||||
|
||||
``AUTHENTICATION_PLUGINS``
|
||||
--------------------------
|
||||
|
||||
Default: ``['openstack_auth.plugin.password.PasswordPlugin', 'openstack_auth.plugin.token.TokenPlugin']``
|
||||
|
||||
A list of authentication plugins to be used.
|
||||
In most cases, there is no need to configure this.
|
||||
|
||||
``AVAILABLE_REGIONS``
|
||||
---------------------
|
||||
|
||||
Default: ``None``
|
||||
|
||||
A list of tuples which define multiple regions. The tuple format is
|
||||
``('http://{{ keystone_host }}:5000/v2.0', '{{ region_name }}')``. If any regions
|
||||
are specified the login form will have a dropdown selector for authenticating
|
||||
to the appropriate region, and there will be a region switcher dropdown in
|
||||
the site header when logged in.
|
||||
|
||||
You should also define ``OPENSTACK_KEYSTONE_URL`` to indicate which of
|
||||
the regions is the default one.
|
||||
|
||||
|
||||
``DEFAULT_SERVICE_REGIONS``
|
||||
---------------------------
|
||||
|
||||
Default: ``{}``
|
||||
|
||||
The default service region is set on a per-endpoint basis, meaning that once
|
||||
the user logs into some Keystone endpoint, if a default service region is
|
||||
defined for it in this setting and exists within Keystone catalog, it will be
|
||||
set as the initial service region in this endpoint. By default it is an empty
|
||||
dictionary because upstream can neither predict service region names in a
|
||||
specific deployment, nor tell whether this behavior is desired. The key of the
|
||||
dictionary is a full url of a Keystone endpoint with version suffix, the value
|
||||
is a region name.
|
||||
|
||||
Example::
|
||||
|
||||
DEFAULT_SERVICE_REGIONS = {
|
||||
OPENSTACK_KEYSTONE_URL: 'RegionOne'
|
||||
}
|
||||
|
||||
|
||||
``OPENSTACK_API_VERSIONS``
|
||||
--------------------------
|
||||
|
||||
Default::
|
||||
|
||||
{
|
||||
"identity": 2.0,
|
||||
...,
|
||||
}
|
||||
|
||||
Overrides for OpenStack API versions. Use this setting to force the
|
||||
OpenStack dashboard to use a specific API version for a given service API.
|
||||
Django OpenStack Auth refers to only the ``"identity"`` entry.
|
||||
The current valid values are "2.0" or "3".
|
||||
|
||||
.. note::
|
||||
|
||||
See `Horizon settings
|
||||
<https://docs.openstack.org/developer/horizon/install/settings.html#openstack-api-versions>`__
|
||||
for the full description of this setting.
|
||||
|
||||
``OPENSTACK_ENDPOINT_TYPE``
|
||||
---------------------------
|
||||
|
||||
Default: ``"publicURL"``
|
||||
|
||||
A string which specifies the endpoint type to use for the endpoints in the
|
||||
Keystone service catalog. The default value for all services except for
|
||||
identity is ``"publicURL"``. The default value for the identity service is
|
||||
``"internalURL"``.
|
||||
|
||||
``OPENSTACK_KEYSTONE_ADMIN_ROLES``
|
||||
----------------------------------
|
||||
|
||||
Default: ``["admin"]``
|
||||
|
||||
The list of roles that have administrator privileges in this OpenStack
|
||||
installation. This check is very basic and essentially only works with
|
||||
keystone v2.0 and v3 with the default policy file. The setting assumes there
|
||||
is a common ``admin`` like role(s) across services. Example uses of this
|
||||
setting are:
|
||||
|
||||
* to rename the ``admin`` role to ``cloud-admin``
|
||||
* allowing multiple roles to have administrative privileges, like
|
||||
``["admin", "cloud-admin", "net-op"]``
|
||||
|
||||
``OPENSTACK_KEYSTONE_DEFAULT_DOMAIN``
|
||||
-------------------------------------
|
||||
|
||||
Default: ``"Default"``
|
||||
|
||||
Overrides the default domain used when running on single-domain model
|
||||
with Keystone V3. All entities will be created in the default domain.
|
||||
|
||||
.. note::
|
||||
|
||||
This value must be the name of the default domain, NOT the ID.
|
||||
Also, you will most likely have a value in the keystone policy file like
|
||||
``"cloud_admin": "rule:admin_required and domain_id:<your domain id>"``.
|
||||
This value must be the name of the domain whose ID is specified there.
|
||||
|
||||
``OPENSTACK_KEYSTONE_DOMAIN_CHOICES``
|
||||
-------------------------------------
|
||||
|
||||
.. versionadded:: 12.0.0(Pike)
|
||||
|
||||
Default::
|
||||
|
||||
(
|
||||
('Default', 'Default'),
|
||||
)
|
||||
|
||||
If OPENSTACK_KEYSTONE_DOMAIN_DROPDOWN is enabled, this option can be used to
|
||||
set the available domains to choose from. This is a list of pairs whose first
|
||||
value is the domain name and the second is the display name.
|
||||
|
||||
``OPENSTACK_KEYSTONE_DOMAIN_DROPDOWN``
|
||||
--------------------------------------
|
||||
|
||||
.. versionadded:: 12.0.0(Pike)
|
||||
|
||||
Default: ``False``
|
||||
Set this to True if you want available domains displayed as a dropdown menu on
|
||||
the login screen. It is strongly advised NOT to enable this for public clouds,
|
||||
as advertising enabled domains to unauthenticated customers irresponsibly
|
||||
exposes private information. This should only be used for private clouds where
|
||||
the dashboard sits behind a corporate firewall.
|
||||
|
||||
``OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT``
|
||||
------------------------------------------
|
||||
|
||||
Default: ``False``
|
||||
|
||||
Set this to True if running on multi-domain model. When this is enabled, it
|
||||
will require user to enter the Domain name in addition to username for login.
|
||||
|
||||
``OPENSTACK_KEYSTONE_URL``
|
||||
--------------------------
|
||||
|
||||
Default: ``"http://%s:5000/v2.0" % OPENSTACK_HOST``
|
||||
|
||||
The full URL for the Keystone endpoint used for authentication. Unless you
|
||||
are using HTTPS, running your Keystone server on a nonstandard port, or using
|
||||
a nonstandard URL scheme you shouldn't need to touch this setting.
|
||||
|
||||
``OPENSTACK_SSL_CACERT``
|
||||
------------------------
|
||||
|
||||
Default: ``None``
|
||||
|
||||
When unset or set to ``None`` the default CA certificate on the system is used
|
||||
for SSL verification.
|
||||
|
||||
When set with the path to a custom CA certificate file, this overrides use of
|
||||
the default system CA certificate. This custom certificate is used to verify all
|
||||
connections to openstack services when making API calls.
|
||||
|
||||
``OPENSTACK_SSL_NO_VERIFY``
|
||||
---------------------------
|
||||
|
||||
Default: ``False``
|
||||
|
||||
Disable SSL certificate checks in the OpenStack clients (useful for self-signed
|
||||
certificates).
|
||||
|
||||
``OPENSTACK_TOKEN_HASH_ALGORITHM``
|
||||
----------------------------------
|
||||
|
||||
Default: ``"md5"``
|
||||
|
||||
The hash algorithm to use for authentication tokens. This must match the hash
|
||||
algorithm that the identity (Keystone) server and the auth_token middleware
|
||||
are using. Allowed values are the algorithms supported by Python's hashlib
|
||||
library.
|
||||
|
||||
``OPENSTACK_TOKEN_HASH_ENABLED``
|
||||
--------------------------------
|
||||
|
||||
(Deprecated)
|
||||
|
||||
Default: ``True``
|
||||
|
||||
Hashing tokens from Keystone keeps the Horizon session data smaller, but it
|
||||
doesn't work in some cases when using PKI tokens. Uncomment this value and
|
||||
set it to False if using PKI tokens and there are 401 errors due to token
|
||||
hashing.
|
||||
|
||||
This option is now marked as "deprecated" and will be removed in Ocata or a
|
||||
later release. PKI tokens currently work with hashing, and Keystone will soon
|
||||
deprecate usage of PKI tokens.
|
||||
|
||||
``PASSWORD_EXPIRES_WARNING_THRESHOLD_DAYS``
|
||||
-------------------------------------------
|
||||
|
||||
Default: ``-1``
|
||||
|
||||
Password will have an expiration date when using keystone v3 and enabling the
|
||||
feature. This setting allows you to set the number of days that the user will
|
||||
be alerted prior to the password expiration. Once the password expires keystone
|
||||
will deny the access and users must contact an admin to change their password.
|
||||
Setting this value to ``N`` days means the user will be alerted when the
|
||||
password expires in less than ``N+1`` days. ``-1`` disables the feature.
|
||||
|
||||
``POLICY_DIRS``
|
||||
----------------
|
||||
|
||||
Default: ``{}``
|
||||
|
||||
Specifies a list of policy directories per service types. The directories
|
||||
are relative to ``POLICY_FILES_PATH``. Services whose additional policies
|
||||
are defined here must be defined in ``POLICY_FILES`` too. Otherwise,
|
||||
additional policies specified in ``POLICY_DIRS`` are not loaded.
|
||||
|
||||
Example::
|
||||
|
||||
POLICY_DIRS = {
|
||||
'identity': 'keystone_policy.d',
|
||||
'compute': 'nova_policy.d'
|
||||
}
|
||||
|
||||
``POLICY_FILES``
|
||||
----------------
|
||||
|
||||
Default: ``{'identity': 'keystone_policy.json', 'compute': 'nova_policy.json'}``
|
||||
|
||||
This should essentially be the mapping of the contents of ``POLICY_FILES_PATH``
|
||||
to service types. When policy.json files are added to ``POLICY_FILES_PATH``,
|
||||
they should be included here too.
|
||||
|
||||
``POLICY_FILES_PATH``
|
||||
---------------------
|
||||
|
||||
Default: ``os.path.join(ROOT_PATH, "conf")``
|
||||
|
||||
Specifies where service based policy files are located. These are used to
|
||||
define the policy rules actions are verified against.
|
||||
|
||||
``SECURE_PROXY_ADDR_HEADER``
|
||||
----------------------------
|
||||
|
||||
Default: ``False``
|
||||
|
||||
If horizon is behind a proxy server and the proxy is configured, the IP address
|
||||
from request is passed using header variables inside the request. The header
|
||||
name depends on a proxy or a load-balancer. This setting specifies the name of
|
||||
the header with remote IP address. The main use is for authentication log
|
||||
(success or fail) displaing the IP address of the user.
|
||||
The commom value for this setting is ``HTTP_X_REAL_IP`` or
|
||||
``HTTP_X_FORWARDED_FOR``.
|
||||
If not present, then ``REMOTE_ADDR`` header is used. (``REMOTE_ADDR`` is the
|
||||
field of Django HttpRequest object which contains IP address of the client.)
|
||||
|
||||
``SESSION_TIMEOUT``
|
||||
-------------------
|
||||
|
||||
Default: ``"3600"``
|
||||
|
||||
This ``SESSION_TIMEOUT`` is a method to supercede the token timeout with a
|
||||
shorter horizon session timeout (in seconds). So if your token expires in
|
||||
60 minutes, a value of 1800 will log users out after 30 minutes.
|
||||
|
||||
``TOKEN_DELETION_DISABLED``
|
||||
---------------------------
|
||||
|
||||
Default: ``False``
|
||||
|
||||
This setting allows deployers to control whether a token is deleted on log out.
|
||||
This can be helpful when there are often long running processes being run
|
||||
in the Horizon environment.
|
||||
|
||||
``TOKEN_TIMEOUT_MARGIN``
|
||||
------------------------
|
||||
|
||||
Default: ``0``
|
||||
|
||||
A time margin in seconds to subtract from the real token's validity.
|
||||
An example usage is that the token can be valid once the middleware
|
||||
passed, and invalid (timed-out) during a view rendering and this
|
||||
generates authorization errors during the view rendering.
|
||||
By setting this value to some smaller seconds, you can avoid token
|
||||
expiration during a view rendering.
|
||||
|
||||
``WEBROOT``
|
||||
-----------
|
||||
|
||||
Default: ``"/"``
|
||||
|
||||
Specifies the location where the access to the dashboard is configured in
|
||||
the web server.
|
||||
|
||||
For example, if you're accessing the Dashboard via
|
||||
https://<your server>/dashboard, you would set this to ``"/dashboard/"``.
|
||||
|
||||
.. note::
|
||||
|
||||
Additional settings may be required in the config files of your webserver
|
||||
of choice. For example to make ``"/dashboard/"`` the web root in Apache,
|
||||
the ``"sites-available/horizon.conf"`` requires a couple of additional
|
||||
aliases set::
|
||||
|
||||
Alias /dashboard/static %HORIZON_DIR%/static
|
||||
|
||||
Alias /dashboard/media %HORIZON_DIR%/openstack_dashboard/static
|
||||
|
||||
Apache also requires changing your WSGIScriptAlias to reflect the desired
|
||||
path. For example, you'd replace ``/`` with ``/dashboard`` for the
|
||||
alias.
|
||||
|
||||
Web SSO (Single Sign On) settings
|
||||
=================================
|
||||
|
||||
``WEBSSO_ENABLED``
|
||||
------------------
|
||||
|
||||
Default: ``False``
|
||||
|
||||
Enables keystone web single-sign-on if set to True. For this feature to work,
|
||||
make sure that you are using Keystone V3 and Django OpenStack Auth V1.2.0 or
|
||||
later.
|
||||
|
||||
``WEBSSO_INITIAL_CHOICE``
|
||||
-------------------------
|
||||
|
||||
Default: ``"credentials"``
|
||||
|
||||
Determines the default authentication mechanism. When user lands on the login
|
||||
page, this is the first choice they will see.
|
||||
|
||||
``WEBSSO_CHOICES``
|
||||
------------------
|
||||
|
||||
Default::
|
||||
|
||||
(
|
||||
("credentials", _("Keystone Credentials")),
|
||||
("oidc", _("OpenID Connect")),
|
||||
("saml2", _("Security Assertion Markup Language"))
|
||||
)
|
||||
|
||||
This is the list of authentication mechanisms available to the user. It
|
||||
includes Keystone federation protocols such as OpenID Connect and SAML, and
|
||||
also keys that map to specific identity provider and federation protocol
|
||||
combinations (as defined in ``WEBSSO_IDP_MAPPING``). The list of choices is
|
||||
completely configurable, so as long as the id remains intact. Do not remove
|
||||
the credentials mechanism unless you are sure. Once removed, even admins will
|
||||
have no way to log into the system via the dashboard.
|
||||
|
||||
``WEBSSO_IDP_MAPPING``
|
||||
----------------------
|
||||
|
||||
Default: ``{}``
|
||||
|
||||
A dictionary of specific identity provider and federation protocol combinations.
|
||||
From the selected authentication mechanism, the value will be looked up as keys
|
||||
in the dictionary. If a match is found, it will redirect the user to a identity
|
||||
provider and federation protocol specific WebSSO endpoint in keystone, otherwise
|
||||
it will use the value as the protocol_id when redirecting to the WebSSO by
|
||||
protocol endpoint.
|
||||
|
||||
Example::
|
||||
|
||||
WEBSSO_CHOICES = (
|
||||
("credentials", _("Keystone Credentials")),
|
||||
("oidc", _("OpenID Connect")),
|
||||
("saml2", _("Security Assertion Markup Language")),
|
||||
("acme_oidc", "ACME - OpenID Connect"),
|
||||
("acme_saml2", "ACME - SAML2")
|
||||
)
|
||||
|
||||
WEBSSO_IDP_MAPPING = {
|
||||
"acme_oidc": ("acme", "oidc"),
|
||||
"acme_saml2": ("acme", "saml2")
|
||||
}
|
||||
|
||||
.. note::
|
||||
The value is expected to be a tuple formatted as: (<idp_id>, <protocol_id>).
|
||||
|
||||
K2K (Keystone to Keystone) Federation settings
|
||||
==============================================
|
||||
|
||||
``KEYSTONE_PROVIDER_IDP_NAME``
|
||||
------------------------------
|
||||
|
||||
Default: ``Local Keystone``
|
||||
|
||||
The Keystone Provider drop down uses Keystone to Keystone federation
|
||||
to switch between Keystone service providers.
|
||||
This sets display name for Identity Provider (dropdown display name).
|
||||
|
||||
``KEYSTONE_PROVIDER_IDP_ID``
|
||||
----------------------------
|
||||
|
||||
Default:: ``localkeystone``
|
||||
|
||||
This ID is used for only for comparison with the service provider IDs.
|
||||
This ID should not match any service provider IDs.
|
||||
|
||||
.. _settings-shared-with-horizon:
|
||||
|
||||
Settings shared with Horizon
|
||||
============================
|
||||
|
||||
The following settings in Django OpenStack Auth are also used by Horizon.
|
||||
|
||||
* ``AVAILABLE_REGIONS``
|
||||
* ``OPENSTACK_API_VERSIONS``
|
||||
* ``OPENSTACK_KEYSTONE_URL``
|
||||
* ``OPENSTACK_ENDPOINT_TYPE``
|
||||
* ``OPENSTACK_SSL_CACERT``
|
||||
* ``OPENSTACK_SSL_NO_VERIFY``
|
||||
* ``WEBROOT``
|
||||
|
||||
Django OpenStack Auth also refers to the following Django settings.
|
||||
For more detail, see `Django settings documentation
|
||||
<https://docs.djangoproject.com/en/1.11/ref/settings/#auth>`__.
|
||||
They are usually configured as part of Horizon settings.
|
||||
|
||||
* ``LOGIN_REDIRECT_URL``
|
||||
* ``LOGIN_URL``
|
||||
* ``SESSION_ENGINE``
|
||||
* ``USE_TZ``
|
|
@ -1,21 +0,0 @@
|
|||
=====================
|
||||
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 or V3 API.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
install/index
|
||||
configuration/index
|
||||
reference/index
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
===============
|
||||
Getting Started
|
||||
===============
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
Installing is quick and easy:
|
||||
|
||||
#. Run ``pip install django_openstack_auth``.
|
||||
|
||||
#. Add ``openstack_auth`` to ``settings.INSTALLED_APPS``.
|
||||
|
||||
#. Add ``'openstack_auth.backend.KeystoneBackend'`` to your
|
||||
``settings.AUTHENTICATION_BACKENDS``, e.g.::
|
||||
|
||||
AUTHENTICATION_BACKENDS = ('openstack_auth.backend.KeystoneBackend',)
|
||||
|
||||
#. Configure your API endpoint(s) in ``settings.py``::
|
||||
|
||||
OPENSTACK_KEYSTONE_URL = "http://example.com:5000/v3"
|
||||
|
||||
#. Include ``'openstack_auth.urls'`` somewhere in your ``urls.py`` file.
|
||||
|
||||
#. Use it as you would any other Django auth backend.
|
||||
|
||||
Running Tests
|
||||
=============
|
||||
|
||||
Before running tests, you should have ``tox`` installed and available in your
|
||||
environment:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ pip install tox
|
||||
|
||||
.. NOTE::
|
||||
|
||||
You may need to perform both the above operation and the next inside a
|
||||
python virtualenv, or prefix the above command with ``sudo``, depending on
|
||||
your preference.
|
||||
|
||||
To execute the full suite of tests maintained within the project, simply run:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ tox
|
||||
|
||||
.. NOTE::
|
||||
|
||||
The first time you run ``tox``, it will take additional time to build
|
||||
virtualenvs. You can later use the ``-r`` option with ``tox`` to rebuild
|
||||
your virtualenv in a similar manner.
|
||||
|
||||
To run tests for one or more specific test environments (for example, the most
|
||||
common configuration of Python 2.7 and PEP-8), list the environments with the
|
||||
``-e`` option, separated by spaces:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ tox -e py27,pep8
|
||||
|
||||
See ``tox.ini`` for the full list of available test environments.
|
|
@ -1,6 +0,0 @@
|
|||
==================
|
||||
The Backend Module
|
||||
==================
|
||||
|
||||
.. automodule:: openstack_auth.backend
|
||||
:members:
|
|
@ -1,6 +0,0 @@
|
|||
================
|
||||
The Forms Module
|
||||
================
|
||||
|
||||
.. automodule:: openstack_auth.forms
|
||||
:members:
|
|
@ -1,13 +0,0 @@
|
|||
=====================================
|
||||
Django OpenStack Auth API Reference
|
||||
=====================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
user
|
||||
views
|
||||
forms
|
||||
backend
|
||||
utils
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
==============
|
||||
The User Class
|
||||
==============
|
||||
|
||||
.. automodule:: openstack_auth.user
|
||||
:members:
|
|
@ -1,6 +0,0 @@
|
|||
================
|
||||
The Utils Module
|
||||
================
|
||||
|
||||
.. automodule:: openstack_auth.utils
|
||||
:members:
|
|
@ -1,6 +0,0 @@
|
|||
================
|
||||
The Views Module
|
||||
================
|
||||
|
||||
.. automodule:: openstack_auth.views
|
||||
:members:
|
|
@ -1,17 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import pbr.version
|
||||
|
||||
|
||||
__version__ = pbr.version.VersionInfo('django_openstack_auth').version_string()
|
|
@ -1,282 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
""" Module defining the Django auth backend class for the Keystone API. """
|
||||
|
||||
import datetime
|
||||
import logging
|
||||
import pytz
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils.module_loading import import_string
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from openstack_auth import exceptions
|
||||
from openstack_auth import user as auth_user
|
||||
from openstack_auth import utils
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
KEYSTONE_CLIENT_ATTR = "_keystoneclient"
|
||||
|
||||
|
||||
class KeystoneBackend(object):
|
||||
"""Django authentication backend for use with ``django.contrib.auth``."""
|
||||
|
||||
def __init__(self):
|
||||
self._auth_plugins = None
|
||||
|
||||
@property
|
||||
def auth_plugins(self):
|
||||
if self._auth_plugins is None:
|
||||
plugins = getattr(
|
||||
settings,
|
||||
'AUTHENTICATION_PLUGINS',
|
||||
['openstack_auth.plugin.password.PasswordPlugin',
|
||||
'openstack_auth.plugin.token.TokenPlugin'])
|
||||
|
||||
self._auth_plugins = [import_string(p)() for p in plugins]
|
||||
|
||||
return self._auth_plugins
|
||||
|
||||
def check_auth_expiry(self, auth_ref, margin=None):
|
||||
if not utils.is_token_valid(auth_ref, margin):
|
||||
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 exceptions.KeystoneAuthException(msg)
|
||||
return True
|
||||
|
||||
def get_user(self, user_id):
|
||||
"""Returns the current user from the session data.
|
||||
|
||||
If authenticated, this return the user object 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 = auth_user.create_user_from_token(self.request, token,
|
||||
endpoint, services_region)
|
||||
return user
|
||||
else:
|
||||
return None
|
||||
|
||||
def authenticate(self, auth_url=None, **kwargs):
|
||||
"""Authenticates a user via the Keystone Identity API."""
|
||||
LOG.debug('Beginning user authentication')
|
||||
|
||||
if not auth_url:
|
||||
auth_url = settings.OPENSTACK_KEYSTONE_URL
|
||||
|
||||
auth_url, url_fixed = utils.fix_auth_url_version_prefix(auth_url)
|
||||
if url_fixed:
|
||||
LOG.warning("The OPENSTACK_KEYSTONE_URL setting points to a v2.0 "
|
||||
"Keystone endpoint, but v3 is specified as the API "
|
||||
"version to use by Horizon. Using v3 endpoint for "
|
||||
"authentication.")
|
||||
|
||||
for plugin in self.auth_plugins:
|
||||
unscoped_auth = plugin.get_plugin(auth_url=auth_url, **kwargs)
|
||||
|
||||
if unscoped_auth:
|
||||
break
|
||||
else:
|
||||
msg = _('No authentication backend could be determined to '
|
||||
'handle the provided credentials.')
|
||||
LOG.warning('No authentication backend could be determined to '
|
||||
'handle the provided credentials. This is likely a '
|
||||
'configuration error that should be addressed.')
|
||||
raise exceptions.KeystoneAuthException(msg)
|
||||
|
||||
# the recent project id a user might have set in a cookie
|
||||
recent_project = None
|
||||
request = kwargs.get('request')
|
||||
if request:
|
||||
# Grab recent_project found in the cookie, try to scope
|
||||
# to the last project used.
|
||||
recent_project = request.COOKIES.get('recent_project')
|
||||
unscoped_auth_ref = plugin.get_access_info(unscoped_auth)
|
||||
|
||||
# Check expiry for our unscoped auth ref.
|
||||
self.check_auth_expiry(unscoped_auth_ref)
|
||||
|
||||
domain_name = kwargs.get('user_domain_name', None)
|
||||
domain_auth, domain_auth_ref = plugin.get_domain_scoped_auth(
|
||||
unscoped_auth, unscoped_auth_ref, domain_name)
|
||||
scoped_auth, scoped_auth_ref = plugin.get_project_scoped_auth(
|
||||
unscoped_auth, unscoped_auth_ref, recent_project=recent_project)
|
||||
|
||||
# Abort if there are no projects for this user and a valid domain
|
||||
# token has not been obtained
|
||||
#
|
||||
# The valid use cases for a user login are:
|
||||
# Keystone v2: user must have a role on a project and be able
|
||||
# to obtain a project scoped token
|
||||
# Keystone v3: 1) user can obtain a domain scoped token (user
|
||||
# has a role on the domain they authenticated to),
|
||||
# only, no roles on a project
|
||||
# 2) user can obtain a domain scoped token and has
|
||||
# a role on a project in the domain they
|
||||
# authenticated to (and can obtain a project scoped
|
||||
# token)
|
||||
# 3) user cannot obtain a domain scoped token, but can
|
||||
# obtain a project scoped token
|
||||
if not scoped_auth_ref and domain_auth_ref:
|
||||
# if the user can't obtain a project scoped token, set the scoped
|
||||
# token to be the domain token, if valid
|
||||
scoped_auth = domain_auth
|
||||
scoped_auth_ref = domain_auth_ref
|
||||
elif not scoped_auth_ref and not domain_auth_ref:
|
||||
msg = _('You are not authorized for any projects.')
|
||||
if utils.get_keystone_version() >= 3:
|
||||
msg = _('You are not authorized for any projects or domains.')
|
||||
raise exceptions.KeystoneAuthException(msg)
|
||||
|
||||
# Check expiry for our new scoped token.
|
||||
self.check_auth_expiry(scoped_auth_ref)
|
||||
|
||||
# We want to try to use the same region we just logged into
|
||||
# which may or may not be the default depending upon the order
|
||||
# keystone uses
|
||||
region_name = None
|
||||
id_endpoints = scoped_auth_ref.service_catalog.\
|
||||
get_endpoints(service_type='identity')
|
||||
for id_endpoint in [cat for cat in id_endpoints['identity']]:
|
||||
if auth_url in id_endpoint.values():
|
||||
region_name = id_endpoint['region']
|
||||
break
|
||||
|
||||
interface = getattr(settings, 'OPENSTACK_ENDPOINT_TYPE', 'public')
|
||||
|
||||
endpoint, url_fixed = utils.fix_auth_url_version_prefix(
|
||||
scoped_auth_ref.service_catalog.url_for(
|
||||
service_type='identity',
|
||||
interface=interface,
|
||||
region_name=region_name))
|
||||
if url_fixed:
|
||||
LOG.warning("The Keystone URL in service catalog points to a v2.0 "
|
||||
"Keystone endpoint, but v3 is specified as the API "
|
||||
"version to use by Horizon. Using v3 endpoint for "
|
||||
"authentication.")
|
||||
|
||||
# If we made it here we succeeded. Create our User!
|
||||
unscoped_token = unscoped_auth_ref.auth_token
|
||||
|
||||
user = auth_user.create_user_from_token(
|
||||
request,
|
||||
auth_user.Token(scoped_auth_ref, unscoped_token=unscoped_token),
|
||||
endpoint,
|
||||
services_region=region_name)
|
||||
|
||||
if request is not None:
|
||||
# if no k2k providers exist then the function returns quickly
|
||||
utils.store_initial_k2k_session(auth_url, request, scoped_auth_ref,
|
||||
unscoped_auth_ref)
|
||||
request.session['unscoped_token'] = unscoped_token
|
||||
if domain_auth_ref:
|
||||
# check django session engine, if using cookies, this will not
|
||||
# work, as it will overflow the cookie so don't add domain
|
||||
# scoped token to the session and put error in the log
|
||||
if utils.using_cookie_backed_sessions():
|
||||
LOG.error('Using signed cookies as SESSION_ENGINE with '
|
||||
'OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT is '
|
||||
'enabled. This disables the ability to '
|
||||
'perform identity operations due to cookie size '
|
||||
'constraints.')
|
||||
else:
|
||||
request.session['domain_token'] = domain_auth_ref
|
||||
|
||||
request.user = user
|
||||
timeout = getattr(settings, "SESSION_TIMEOUT", 3600)
|
||||
token_life = user.token.expires - datetime.datetime.now(pytz.utc)
|
||||
session_time = min(timeout, int(token_life.total_seconds()))
|
||||
request.session.set_expiry(session_time)
|
||||
|
||||
keystone_client_class = utils.get_keystone_client().Client
|
||||
session = utils.get_session()
|
||||
scoped_client = keystone_client_class(session=session,
|
||||
auth=scoped_auth)
|
||||
|
||||
# Support client caching to save on auth calls.
|
||||
setattr(request, KEYSTONE_CLIENT_ATTR, scoped_client)
|
||||
|
||||
LOG.debug('Authentication completed.')
|
||||
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 the user has.
|
||||
|
||||
This permission available to the user is derived from the user's
|
||||
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 = {utils.get_role_permission(role['name'])
|
||||
for role in user.roles}
|
||||
|
||||
services = []
|
||||
for service in user.service_catalog:
|
||||
try:
|
||||
service_type = service['type']
|
||||
except KeyError:
|
||||
continue
|
||||
service_regions = [utils.get_endpoint_region(endpoint) for endpoint
|
||||
in service.get('endpoints', [])]
|
||||
if user.services_region in service_regions:
|
||||
services.append(service_type.lower())
|
||||
service_perms = {"openstack.services.%s" % service
|
||||
for service in services}
|
||||
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
|
|
@ -1,17 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
class KeystoneAuthException(Exception):
|
||||
"""Generic error class to identify and catch our own errors."""
|
||||
pass
|
|
@ -1,155 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import collections
|
||||
import logging
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import authenticate
|
||||
from django.contrib.auth import forms as django_auth_forms
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.views.decorators.debug import sensitive_variables
|
||||
|
||||
from openstack_auth import exceptions
|
||||
from openstack_auth import utils
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Login(django_auth_forms.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.
|
||||
"""
|
||||
use_required_attribute = False
|
||||
region = forms.ChoiceField(label=_("Region"), required=False)
|
||||
username = forms.CharField(
|
||||
label=_("User Name"),
|
||||
widget=forms.TextInput(attrs={"autofocus": "autofocus"}))
|
||||
password = forms.CharField(label=_("Password"),
|
||||
widget=forms.PasswordInput(render_value=False))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Login, self).__init__(*args, **kwargs)
|
||||
fields_ordering = ['username', 'password', 'region']
|
||||
if getattr(settings,
|
||||
'OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT',
|
||||
False):
|
||||
last_domain = self.request.COOKIES.get('login_domain', None)
|
||||
if getattr(settings,
|
||||
'OPENSTACK_KEYSTONE_DOMAIN_DROPDOWN',
|
||||
False):
|
||||
self.fields['domain'] = forms.ChoiceField(
|
||||
label=_("Domain"),
|
||||
initial=last_domain,
|
||||
required=True,
|
||||
choices=getattr(settings,
|
||||
'OPENSTACK_KEYSTONE_DOMAIN_CHOICES',
|
||||
()))
|
||||
else:
|
||||
self.fields['domain'] = forms.CharField(
|
||||
initial=last_domain,
|
||||
label=_("Domain"),
|
||||
required=True,
|
||||
widget=forms.TextInput(attrs={"autofocus": "autofocus"}))
|
||||
self.fields['username'].widget = forms.widgets.TextInput()
|
||||
fields_ordering = ['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()
|
||||
elif len(self.fields['region'].choices) > 1:
|
||||
self.fields['region'].initial = self.request.COOKIES.get(
|
||||
'login_region')
|
||||
|
||||
# if websso is enabled and keystone version supported
|
||||
# prepend the websso_choices select input to the form
|
||||
if utils.is_websso_enabled():
|
||||
initial = getattr(settings, 'WEBSSO_INITIAL_CHOICE', 'credentials')
|
||||
self.fields['auth_type'] = forms.ChoiceField(
|
||||
label=_("Authenticate using"),
|
||||
choices=getattr(settings, 'WEBSSO_CHOICES', ()),
|
||||
required=False,
|
||||
initial=initial)
|
||||
# add auth_type to the top of the list
|
||||
fields_ordering.insert(0, 'auth_type')
|
||||
|
||||
# websso is enabled, but keystone version is not supported
|
||||
elif getattr(settings, 'WEBSSO_ENABLED', False):
|
||||
msg = ("Websso is enabled but horizon is not configured to work " +
|
||||
"with keystone version 3 or above.")
|
||||
LOG.warning(msg)
|
||||
self.fields = collections.OrderedDict(
|
||||
(key, self.fields[key]) for key in fields_ordering)
|
||||
|
||||
@staticmethod
|
||||
def get_region_choices():
|
||||
default_region = (settings.OPENSTACK_KEYSTONE_URL, "Default Region")
|
||||
regions = getattr(settings, 'AVAILABLE_REGIONS', [])
|
||||
if not regions:
|
||||
regions = [default_region]
|
||||
return regions
|
||||
|
||||
@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", remote address '\
|
||||
'%(remote_ip)s.' % {
|
||||
'username': username,
|
||||
'remote_ip': utils.get_client_ip(self.request)
|
||||
}
|
||||
LOG.info(msg)
|
||||
except exceptions.KeystoneAuthException as exc:
|
||||
msg = 'Login failed for user "%(username)s", remote address '\
|
||||
'%(remote_ip)s.' % {
|
||||
'username': username,
|
||||
'remote_ip': utils.get_client_ip(self.request)
|
||||
}
|
||||
LOG.warning(msg)
|
||||
raise forms.ValidationError(exc)
|
||||
if hasattr(self, 'check_for_test_cookie'): # Dropped in django 1.7
|
||||
self.check_for_test_cookie()
|
||||
return self.cleaned_data
|
|
@ -1,74 +0,0 @@
|
|||
# Translations template for django_openstack_auth.
|
||||
# Copyright (C) 2015 ORGANIZATION
|
||||
# This file is distributed under the same license as the
|
||||
# django_openstack_auth project.
|
||||
#
|
||||
# Translators:
|
||||
# Zbyněk Schwarz <zbynek.schwarz@gmail.com>, 2014-2015
|
||||
# Stanislav Ulrych <stanislav.ulrych@ultimum.io>, 2016. #zanata
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: django_openstack_auth 3.1.1.dev1\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
|
||||
"POT-Creation-Date: 2017-01-25 19:41+0000\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"PO-Revision-Date: 2016-06-09 07:46+0000\n"
|
||||
"Last-Translator: Lenka Husáková <lenka.husakova@ultimum.io>\n"
|
||||
"Language: cs\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
|
||||
"Generated-By: Babel 2.0\n"
|
||||
"X-Generator: Zanata 3.7.3\n"
|
||||
"Language-Team: Czech\n"
|
||||
|
||||
msgid "An error occurred authenticating. Please try again later."
|
||||
msgstr "Při ověřování se vyskytla chyba. Zkuste to prosím znovu později."
|
||||
|
||||
msgid "Authenticate using"
|
||||
msgstr "Přihlásit se pomocí"
|
||||
|
||||
msgid "Domain"
|
||||
msgstr "Doména"
|
||||
|
||||
msgid "Invalid credentials."
|
||||
msgstr "Neplatné přihlašovací údaje."
|
||||
|
||||
msgid ""
|
||||
"No authentication backend could be determined to handle the provided "
|
||||
"credentials."
|
||||
msgstr ""
|
||||
"Nebyl rozpoznán žádný vhodný autentizační backend pro ověření zadaných "
|
||||
"přihlašovacích údajů."
|
||||
|
||||
msgid "Password"
|
||||
msgstr "Heslo"
|
||||
|
||||
#, python-format
|
||||
msgid "Project switch failed for user \"%(username)s\"."
|
||||
msgstr "Změna projektu selhala u uživatele \"%(username)s\"."
|
||||
|
||||
msgid "Region"
|
||||
msgstr "Region"
|
||||
|
||||
#, python-format
|
||||
msgid "Switch to project \"%(project_name)s\" successful."
|
||||
msgstr "Změna projektu \"%(project_name)s\" byla úspěšná."
|
||||
|
||||
msgid "The authentication token issued by the Identity service has expired."
|
||||
msgstr "Autentizační token poskytnutý službou identit vypršel."
|
||||
|
||||
msgid "Unable to establish connection to keystone endpoint."
|
||||
msgstr "Nelze se připojit ke keystone endpointu."
|
||||
|
||||
msgid "Unable to retrieve authorized projects."
|
||||
msgstr "Nelze získat oprávněné projekty."
|
||||
|
||||
msgid "User Name"
|
||||
msgstr "Uživatelské jméno"
|
||||
|
||||
msgid "You are not authorized for any projects or domains."
|
||||
msgstr "Nemáte oprávnění k žádným projektům či doménám."
|
||||
|
||||
msgid "You are not authorized for any projects."
|
||||
msgstr "Nemáte oprávnění k žádným projektům."
|
|
@ -1,103 +0,0 @@
|
|||
# Translations template for django_openstack_auth.
|
||||
# Copyright (C) 2015 ORGANIZATION
|
||||
# This file is distributed under the same license as the
|
||||
# django_openstack_auth project.
|
||||
#
|
||||
# Translators:
|
||||
# Andreas Jaeger <jaegerandi@gmail.com>, 2014
|
||||
# Robert Simai, 2015
|
||||
# Robert Simai, 2015
|
||||
# Frank Kloeker <eumel@arcor.de>, 2016. #zanata
|
||||
# Andreas Jaeger <jaegerandi@gmail.com>, 2017. #zanata
|
||||
# Robert Simai <robert.simai@suse.com>, 2017. #zanata
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: django_openstack_auth 3.1.2.dev14\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
|
||||
"POT-Creation-Date: 2017-04-07 13:52+0000\n"
|