Merge "Move the auth plugins abstract base class out of core"

This commit is contained in:
Jenkins 2016-07-08 23:54:56 +00:00 committed by Gerrit Code Review
commit 3e07bf6c57
11 changed files with 118 additions and 92 deletions

View File

@ -325,7 +325,7 @@ How to Implement an Authentication Plugin
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
All authentication plugins must extend the
:class:`keystone.auth.core.AuthMethodHandler` class and implement the
:class:`keystone.auth.plugins.base.AuthMethodHandler` class and implement the
``authenticate()`` method. The ``authenticate()`` method expects the following
parameters.

View File

@ -13,4 +13,3 @@
# under the License.
from keystone.auth import controllers # noqa
from keystone.auth.core import * # noqa

View File

@ -12,83 +12,15 @@
# License for the specific language governing permissions and limitations
# under the License.
import abc
from oslo_log import versionutils
import six
from keystone import exception
from keystone.auth.plugins import base
@six.add_metaclass(abc.ABCMeta)
class AuthMethodHandler(object):
"""Abstract base class for an authentication plugin."""
def __init__(self):
pass
@abc.abstractmethod
def authenticate(self, context, auth_payload, auth_context):
"""Authenticate user and return an authentication context.
:param context: keystone's request context
:param auth_payload: the content of the authentication for a given
method
:param auth_context: user authentication context, a dictionary shared
by all plugins. It contains "method_names" and
"extras" by default. "method_names" is a list and
"extras" is a dictionary.
If successful, plugin must set ``user_id`` in ``auth_context``.
``method_name`` is used to convey any additional authentication methods
in case authentication is for re-scoping. For example, if the
authentication is for re-scoping, plugin must append the previous
method names into ``method_names``. Also, plugin may add any additional
information into ``extras``. Anything in ``extras`` will be conveyed in
the token's ``extras`` attribute. Here's an example of ``auth_context``
on successful authentication::
{
"extras": {},
"methods": [
"password",
"token"
],
"user_id": "abc123"
}
Plugins are invoked in the order in which they are specified in the
``methods`` attribute of the ``identity`` object. For example,
``custom-plugin`` is invoked before ``password``, which is invoked
before ``token`` in the following authentication request::
{
"auth": {
"identity": {
"custom-plugin": {
"custom-data": "sdfdfsfsfsdfsf"
},
"methods": [
"custom-plugin",
"password",
"token"
],
"password": {
"user": {
"id": "s23sfad1",
"password": "secrete"
}
},
"token": {
"id": "sdfafasdfsfasfasdfds"
}
}
}
}
:returns: None if authentication is successful.
Authentication payload in the form of a dictionary for the
next authentication step if this is a multi step
authentication.
:raises keystone.exception.Unauthorized: for authentication failure
"""
raise exception.Unauthorized()
@versionutils.deprecated(
versionutils.deprecated.NEWTON,
what='keystone.auth.AuthMethodHandler',
in_favor_of='keystone.auth.plugins.base.AuthMethodHandler',
remove_in=+1)
class AuthMethodHandler(base.AuthMethodHandler):
pass

View File

@ -0,0 +1,94 @@
# Copyright 2013 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import abc
import six
from keystone import exception
@six.add_metaclass(abc.ABCMeta)
class AuthMethodHandler(object):
"""Abstract base class for an authentication plugin."""
def __init__(self):
pass
@abc.abstractmethod
def authenticate(self, context, auth_payload, auth_context):
"""Authenticate user and return an authentication context.
:param context: keystone's request context
:param auth_payload: the content of the authentication for a given
method
:param auth_context: user authentication context, a dictionary shared
by all plugins. It contains "method_names" and
"extras" by default. "method_names" is a list and
"extras" is a dictionary.
If successful, plugin must set ``user_id`` in ``auth_context``.
``method_name`` is used to convey any additional authentication methods
in case authentication is for re-scoping. For example, if the
authentication is for re-scoping, plugin must append the previous
method names into ``method_names``. Also, plugin may add any additional
information into ``extras``. Anything in ``extras`` will be conveyed in
the token's ``extras`` attribute. Here's an example of ``auth_context``
on successful authentication::
{
"extras": {},
"methods": [
"password",
"token"
],
"user_id": "abc123"
}
Plugins are invoked in the order in which they are specified in the
``methods`` attribute of the ``identity`` object. For example,
``custom-plugin`` is invoked before ``password``, which is invoked
before ``token`` in the following authentication request::
{
"auth": {
"identity": {
"custom-plugin": {
"custom-data": "sdfdfsfsfsdfsf"
},
"methods": [
"custom-plugin",
"password",
"token"
],
"password": {
"user": {
"id": "s23sfad1",
"password": "secrete"
}
},
"token": {
"id": "sdfafasdfsfasfasdfds"
}
}
}
}
:returns: None if authentication is successful.
Authentication payload in the form of a dictionary for the
next authentication step if this is a multi step
authentication.
:raises keystone.exception.Unauthorized: for authentication failure
"""
raise exception.Unauthorized()

View File

@ -18,7 +18,7 @@ import abc
import six
from keystone import auth
from keystone.auth.plugins import base
from keystone.common import dependency
import keystone.conf
from keystone import exception
@ -29,7 +29,7 @@ CONF = keystone.conf.CONF
@six.add_metaclass(abc.ABCMeta)
class Base(auth.AuthMethodHandler):
class Base(base.AuthMethodHandler):
def authenticate(self, request, auth_info, auth_context):
"""Use REMOTE_USER to look up the user in the identity backend.

View File

@ -15,8 +15,8 @@ import functools
from pycadf import cadftaxonomy as taxonomy
from six.moves.urllib import parse
from keystone import auth
from keystone.auth import plugins as auth_plugins
from keystone.auth.plugins import base
from keystone.common import dependency
from keystone import exception
from keystone.federation import constants as federation_constants
@ -31,7 +31,7 @@ METHOD_NAME = 'mapped'
@dependency.requires('federation_api', 'identity_api',
'resource_api', 'token_provider_api')
class Mapped(auth.AuthMethodHandler):
class Mapped(base.AuthMethodHandler):
def _get_token_ref(self, auth_payload):
token_id = auth_payload['id']

View File

@ -14,7 +14,7 @@
from oslo_utils import timeutils
from keystone import auth
from keystone.auth.plugins import base
from keystone.common import controller
from keystone.common import dependency
from keystone import exception
@ -24,7 +24,7 @@ from keystone.oauth1 import validator
@dependency.requires('oauth_api')
class OAuth(auth.AuthMethodHandler):
class OAuth(base.AuthMethodHandler):
def authenticate(self, request, auth_info, auth_context):
"""Turn a signed request with an access key into a keystone token."""
oauth_headers = oauth.get_oauth_headers(request.headers)

View File

@ -12,8 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
from keystone import auth
from keystone.auth import plugins as auth_plugins
from keystone.auth.plugins import base
from keystone.common import dependency
from keystone import exception
from keystone.i18n import _
@ -23,7 +23,7 @@ METHOD_NAME = 'password'
@dependency.requires('identity_api')
class Password(auth.AuthMethodHandler):
class Password(base.AuthMethodHandler):
def authenticate(self, request, auth_payload, auth_context):
"""Try to authenticate against the identity backend."""

View File

@ -15,7 +15,7 @@
from oslo_log import log
import six
from keystone import auth
from keystone.auth.plugins import base
from keystone.auth.plugins import mapped
from keystone.common import dependency
from keystone.common import wsgi
@ -31,7 +31,7 @@ CONF = keystone.conf.CONF
@dependency.requires('federation_api', 'identity_api', 'token_provider_api')
class Token(auth.AuthMethodHandler):
class Token(base.AuthMethodHandler):
def _get_token_ref(self, auth_payload):
token_id = auth_payload['id']

View File

@ -31,8 +31,8 @@ from oslo_log import log
from oslo_utils import timeutils
import six
from keystone import auth
from keystone.auth import plugins
from keystone.auth.plugins import base
from keystone.common import dependency
from keystone import exception
from keystone.i18n import _
@ -66,7 +66,7 @@ def _generate_totp_passcode(secret):
@dependency.requires('credential_api')
class TOTP(auth.AuthMethodHandler):
class TOTP(base.AuthMethodHandler):
def authenticate(self, request, auth_payload, auth_context):
"""Try to authenticate using TOTP."""

View File

@ -17,6 +17,7 @@ import uuid
import mock
from keystone import auth
from keystone.auth.plugins import base
from keystone import exception
from keystone.tests import unit
from keystone.tests.unit.ksfixtures import auth_plugins
@ -32,7 +33,7 @@ EXPECTED_RESPONSE = uuid.uuid4().hex
DEMO_USER_ID = uuid.uuid4().hex
class SimpleChallengeResponse(auth.AuthMethodHandler):
class SimpleChallengeResponse(base.AuthMethodHandler):
def authenticate(self, context, auth_payload, user_context):
if 'response' in auth_payload:
if auth_payload['response'] != EXPECTED_RESPONSE: