Don't automatically enable revocation events.
Cuts any direct imports of revoke.model as that triggers the dependency registration. In order to fix a dependecy resolution issue, changes the syncronziation to using the same sort of chaching mechanism as the other drivers. Adds the ability to Lazy activate providers for future or optional dependency resolution. Closes-Bug: 1291099 Related-Bug: 1292283 Change-Id: I0db36b295c2040ec1fb248cf75dc55c44c059211
This commit is contained in:
parent
358674aada
commit
7c9746c49b
@ -110,40 +110,40 @@
|
||||
# Auto-delete queues in amqp. (boolean value)
|
||||
#amqp_auto_delete=false
|
||||
|
||||
# Size of RPC connection pool (integer value)
|
||||
# Size of RPC connection pool. (integer value)
|
||||
#rpc_conn_pool_size=30
|
||||
|
||||
# Modules of exceptions that are permitted to be recreatedupon
|
||||
# receiving exception data from an rpc call. (list value)
|
||||
# Modules of exceptions that are permitted to be recreated
|
||||
# upon receiving exception data from an rpc call. (list value)
|
||||
#allowed_rpc_exception_modules=oslo.messaging.exceptions,nova.exception,cinder.exception,exceptions
|
||||
|
||||
# Qpid broker hostname (string value)
|
||||
# Qpid broker hostname. (string value)
|
||||
#qpid_hostname=localhost
|
||||
|
||||
# Qpid broker port (integer value)
|
||||
# Qpid broker port. (integer value)
|
||||
#qpid_port=5672
|
||||
|
||||
# Qpid HA cluster host:port pairs (list value)
|
||||
# Qpid HA cluster host:port pairs. (list value)
|
||||
#qpid_hosts=$qpid_hostname:$qpid_port
|
||||
|
||||
# Username for Qpid connection (string value)
|
||||
# Username for Qpid connection. (string value)
|
||||
#qpid_username=
|
||||
|
||||
# Password for Qpid connection (string value)
|
||||
# Password for Qpid connection. (string value)
|
||||
#qpid_password=
|
||||
|
||||
# Space separated list of SASL mechanisms to use for auth
|
||||
# Space separated list of SASL mechanisms to use for auth.
|
||||
# (string value)
|
||||
#qpid_sasl_mechanisms=
|
||||
|
||||
# Seconds between connection keepalive heartbeats (integer
|
||||
# Seconds between connection keepalive heartbeats. (integer
|
||||
# value)
|
||||
#qpid_heartbeat=60
|
||||
|
||||
# Transport to use, either 'tcp' or 'ssl' (string value)
|
||||
# Transport to use, either 'tcp' or 'ssl'. (string value)
|
||||
#qpid_protocol=tcp
|
||||
|
||||
# Disable Nagle algorithm (boolean value)
|
||||
# Whether to disable the Nagle algorithm. (boolean value)
|
||||
#qpid_tcp_nodelay=true
|
||||
|
||||
# The qpid topology version to use. Version 1 is what was
|
||||
@ -156,52 +156,59 @@
|
||||
|
||||
# SSL version to use (valid only if SSL enabled). valid values
|
||||
# are TLSv1, SSLv23 and SSLv3. SSLv2 may be available on some
|
||||
# distributions (string value)
|
||||
# distributions. (string value)
|
||||
#kombu_ssl_version=
|
||||
|
||||
# SSL key file (valid only if SSL enabled) (string value)
|
||||
# SSL key file (valid only if SSL enabled). (string value)
|
||||
#kombu_ssl_keyfile=
|
||||
|
||||
# SSL cert file (valid only if SSL enabled) (string value)
|
||||
# SSL cert file (valid only if SSL enabled). (string value)
|
||||
#kombu_ssl_certfile=
|
||||
|
||||
# SSL certification authority file (valid only if SSL enabled)
|
||||
# (string value)
|
||||
# SSL certification authority file (valid only if SSL
|
||||
# enabled). (string value)
|
||||
#kombu_ssl_ca_certs=
|
||||
|
||||
# The RabbitMQ broker address where a single node is used
|
||||
# How long to wait before reconnecting in response to an AMQP
|
||||
# consumer cancel notification. (floating point value)
|
||||
#kombu_reconnect_delay=1.0
|
||||
|
||||
# The RabbitMQ broker address where a single node is used.
|
||||
# (string value)
|
||||
#rabbit_host=localhost
|
||||
|
||||
# The RabbitMQ broker port where a single node is used
|
||||
# The RabbitMQ broker port where a single node is used.
|
||||
# (integer value)
|
||||
#rabbit_port=5672
|
||||
|
||||
# RabbitMQ HA cluster host:port pairs (list value)
|
||||
# RabbitMQ HA cluster host:port pairs. (list value)
|
||||
#rabbit_hosts=$rabbit_host:$rabbit_port
|
||||
|
||||
# Connect over SSL for RabbitMQ (boolean value)
|
||||
# Connect over SSL for RabbitMQ. (boolean value)
|
||||
#rabbit_use_ssl=false
|
||||
|
||||
# The RabbitMQ userid (string value)
|
||||
# The RabbitMQ userid. (string value)
|
||||
#rabbit_userid=guest
|
||||
|
||||
# The RabbitMQ password (string value)
|
||||
# The RabbitMQ password. (string value)
|
||||
#rabbit_password=guest
|
||||
|
||||
# The RabbitMQ virtual host (string value)
|
||||
# the RabbitMQ login method (string value)
|
||||
#rabbit_login_method=AMQPLAIN
|
||||
|
||||
# The RabbitMQ virtual host. (string value)
|
||||
#rabbit_virtual_host=/
|
||||
|
||||
# How frequently to retry connecting with RabbitMQ (integer
|
||||
# How frequently to retry connecting with RabbitMQ. (integer
|
||||
# value)
|
||||
#rabbit_retry_interval=1
|
||||
|
||||
# How long to backoff for between retries when connecting to
|
||||
# RabbitMQ (integer value)
|
||||
# RabbitMQ. (integer value)
|
||||
#rabbit_retry_backoff=2
|
||||
|
||||
# Maximum number of RabbitMQ connection retries. Default is 0
|
||||
# (infinite retry count) (integer value)
|
||||
# (infinite retry count). (integer value)
|
||||
#rabbit_max_retries=0
|
||||
|
||||
# Use HA queues in RabbitMQ (x-ha-policy: all). If you change
|
||||
@ -209,7 +216,7 @@
|
||||
# value)
|
||||
#rabbit_ha_queues=false
|
||||
|
||||
# If passed, use a fake RabbitMQ provider (boolean value)
|
||||
# If passed, use a fake RabbitMQ provider. (boolean value)
|
||||
#fake_rabbit=false
|
||||
|
||||
# ZeroMQ bind address. Should be a wildcard (*), an ethernet
|
||||
@ -217,20 +224,20 @@
|
||||
# to this address. (string value)
|
||||
#rpc_zmq_bind_address=*
|
||||
|
||||
# MatchMaker driver (string value)
|
||||
# MatchMaker driver. (string value)
|
||||
#rpc_zmq_matchmaker=oslo.messaging._drivers.matchmaker.MatchMakerLocalhost
|
||||
|
||||
# ZeroMQ receiver listening port (integer value)
|
||||
# ZeroMQ receiver listening port. (integer value)
|
||||
#rpc_zmq_port=9501
|
||||
|
||||
# Number of ZeroMQ contexts, defaults to 1 (integer value)
|
||||
# Number of ZeroMQ contexts, defaults to 1. (integer value)
|
||||
#rpc_zmq_contexts=1
|
||||
|
||||
# Maximum number of ingress messages to locally buffer per
|
||||
# topic. Default is unlimited. (integer value)
|
||||
#rpc_zmq_topic_backlog=<None>
|
||||
|
||||
# Directory for holding IPC sockets (string value)
|
||||
# Directory for holding IPC sockets. (string value)
|
||||
#rpc_zmq_ipc_dir=/var/run/openstack
|
||||
|
||||
# Name of this node. Must be a valid hostname, FQDN, or IP
|
||||
@ -242,33 +249,33 @@
|
||||
# by impl_zmq. (integer value)
|
||||
#rpc_cast_timeout=30
|
||||
|
||||
# Heartbeat frequency (integer value)
|
||||
# Heartbeat frequency. (integer value)
|
||||
#matchmaker_heartbeat_freq=300
|
||||
|
||||
# Heartbeat time-to-live. (integer value)
|
||||
#matchmaker_heartbeat_ttl=600
|
||||
|
||||
# Host to locate redis (string value)
|
||||
# Host to locate redis. (string value)
|
||||
#host=127.0.0.1
|
||||
|
||||
# Use this port to connect to redis host. (integer value)
|
||||
#port=6379
|
||||
|
||||
# Password for Redis server. (optional) (string value)
|
||||
# Password for Redis server (optional). (string value)
|
||||
#password=<None>
|
||||
|
||||
# Size of RPC greenthread pool (integer value)
|
||||
# Size of RPC greenthread pool. (integer value)
|
||||
#rpc_thread_pool_size=64
|
||||
|
||||
# Driver or drivers to handle sending notifications (multi
|
||||
# Driver or drivers to handle sending notifications. (multi
|
||||
# valued)
|
||||
#notification_driver=
|
||||
|
||||
# AMQP topic used for OpenStack notifications (list value)
|
||||
# AMQP topic used for OpenStack notifications. (list value)
|
||||
# Deprecated group/name - [rpc_notifier2]/topics
|
||||
#notification_topics=notifications
|
||||
|
||||
# Seconds to wait for a response from a call (integer value)
|
||||
# Seconds to wait for a response from a call. (integer value)
|
||||
#rpc_response_timeout=60
|
||||
|
||||
# A URL representing the messaging driver to use and its full
|
||||
@ -1037,7 +1044,7 @@
|
||||
# Options defined in oslo.messaging
|
||||
#
|
||||
|
||||
# Matchmaker ring file (JSON) (string value)
|
||||
# Matchmaker ring file (JSON). (string value)
|
||||
# Deprecated group/name - [DEFAULT]/matchmaker_ringfile
|
||||
#ringfile=/etc/oslo/matchmaker_ring.json
|
||||
|
||||
@ -1126,6 +1133,10 @@
|
||||
# backend. (integer value)
|
||||
#expiration_buffer=1800
|
||||
|
||||
# Toggle for revocation event cacheing. This has no effect
|
||||
# unless global caching is enabled. (boolean value)
|
||||
#caching=true
|
||||
|
||||
|
||||
[signing]
|
||||
|
||||
@ -1200,23 +1211,6 @@
|
||||
#cert_subject=/C=US/ST=Unset/L=Unset/O=Unset/CN=localhost
|
||||
|
||||
|
||||
#
|
||||
# Options defined in keystone.openstack.common.sslutils
|
||||
#
|
||||
|
||||
# CA certificate file to use to verify connecting clients
|
||||
# (string value)
|
||||
#ca_file=<None>
|
||||
|
||||
# Certificate file to use when starting the server securely
|
||||
# (string value)
|
||||
#cert_file=<None>
|
||||
|
||||
# Private key file to use when starting the server securely
|
||||
# (string value)
|
||||
#key_file=<None>
|
||||
|
||||
|
||||
[stats]
|
||||
|
||||
#
|
||||
@ -1260,7 +1254,8 @@
|
||||
# global caching is enabled. (boolean value)
|
||||
#caching=true
|
||||
|
||||
# Time to cache the revocation list (in seconds). This has no
|
||||
# Time to cache the revocation list and the revocation events
|
||||
# if revoke extension is enabled (in seconds). This has no
|
||||
# effect unless global and token caching are enabled. (integer
|
||||
# value)
|
||||
#revocation_cache_time=3600
|
||||
|
@ -180,7 +180,8 @@ FILE_OPTIONS = {
|
||||
help='Toggle for token system cacheing. This has no '
|
||||
'effect unless global caching is enabled.'),
|
||||
cfg.IntOpt('revocation_cache_time', default=3600,
|
||||
help='Time to cache the revocation list (in seconds). '
|
||||
help='Time to cache the revocation list and the revocation '
|
||||
'events if revoke extension is enabled (in seconds). '
|
||||
'This has no effect unless global and token '
|
||||
'caching are enabled.'),
|
||||
cfg.IntOpt('cache_time', default=None,
|
||||
@ -205,7 +206,9 @@ FILE_OPTIONS = {
|
||||
help='This value (calculated in seconds) is added to token '
|
||||
'expiration before a revocation event may be removed '
|
||||
'from the backend.'),
|
||||
|
||||
cfg.BoolOpt('caching', default=True,
|
||||
help='Toggle for revocation event cacheing. This has no '
|
||||
'effect unless global caching is enabled.'),
|
||||
],
|
||||
'cache': [
|
||||
cfg.StrOpt('config_prefix', default='cache.keystone',
|
||||
|
@ -27,12 +27,14 @@ See also:
|
||||
import six
|
||||
|
||||
from keystone import notifications
|
||||
from keystone.openstack.common.gettextutils import _ # flake8: noqa
|
||||
|
||||
|
||||
REGISTRY = {}
|
||||
|
||||
_future_dependencies = {}
|
||||
_future_optionals = {}
|
||||
_factories = {}
|
||||
|
||||
|
||||
class UnresolvableDependencyException(Exception):
|
||||
@ -110,8 +112,8 @@ def provider(name):
|
||||
return __wrapped_init__
|
||||
|
||||
cls.__init__ = wrapped(cls.__init__)
|
||||
_factories[name] = cls
|
||||
return cls
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
@ -221,6 +223,7 @@ def resolve_future_dependencies(provider_name=None):
|
||||
the optional argument is used internally, and should be treated as an
|
||||
implementation detail.
|
||||
"""
|
||||
new_providers = dict()
|
||||
if provider_name:
|
||||
# A provider was registered, so take care of any objects depending on
|
||||
# it.
|
||||
@ -234,25 +237,37 @@ def resolve_future_dependencies(provider_name=None):
|
||||
|
||||
# Resolve optional dependencies, sets the attribute to None if there's no
|
||||
# provider registered.
|
||||
for dependency, targets in six.iteritems(_future_optionals):
|
||||
for dependency, targets in six.iteritems(_future_optionals.copy()):
|
||||
provider = REGISTRY.get(dependency)
|
||||
if provider is None:
|
||||
factory = _factories.get(dependency)
|
||||
if factory:
|
||||
provider = factory()
|
||||
REGISTRY[dependency] = provider
|
||||
new_providers[dependency] = provider
|
||||
for target in targets:
|
||||
setattr(target, dependency, provider)
|
||||
|
||||
_future_optionals.clear()
|
||||
|
||||
# Resolve optional dependencies, raises UnresolvableDependencyException if
|
||||
# Resolve future dependencies, raises UnresolvableDependencyException if
|
||||
# there's no provider registered.
|
||||
try:
|
||||
for dependency, targets in six.iteritems(_future_dependencies):
|
||||
for dependency, targets in six.iteritems(_future_dependencies.copy()):
|
||||
if dependency not in REGISTRY:
|
||||
raise UnresolvableDependencyException(dependency)
|
||||
# a Class was registered that could fulfill the dependency, but
|
||||
# it has not yet been initialized.
|
||||
factory = _factories.get(dependency)
|
||||
if factory:
|
||||
provider = factory()
|
||||
REGISTRY[dependency] = provider
|
||||
new_providers[dependency] = provider
|
||||
else:
|
||||
raise UnresolvableDependencyException(dependency)
|
||||
|
||||
for target in targets:
|
||||
setattr(target, dependency, REGISTRY[dependency])
|
||||
finally:
|
||||
_future_dependencies.clear()
|
||||
|
||||
return new_providers
|
||||
|
||||
def reset():
|
||||
"""Reset the registry of providers.
|
||||
|
@ -28,6 +28,7 @@ import six
|
||||
|
||||
from keystone.common import config
|
||||
from keystone import exception
|
||||
from keystone.openstack.common.gettextutils import _ # flake8: noqa
|
||||
from keystone.openstack.common import importutils
|
||||
from keystone.openstack.common import log
|
||||
|
||||
|
@ -15,9 +15,9 @@ import datetime
|
||||
|
||||
import six
|
||||
|
||||
from keystone.common import cache
|
||||
from keystone.common import dependency
|
||||
from keystone.common import extension
|
||||
from keystone.common import kvs
|
||||
from keystone.common import manager
|
||||
from keystone import config
|
||||
from keystone.contrib.revoke import model
|
||||
@ -50,6 +50,10 @@ EXTENSION_DATA = {
|
||||
extension.register_admin_extension(EXTENSION_DATA['alias'], EXTENSION_DATA)
|
||||
extension.register_public_extension(EXTENSION_DATA['alias'], EXTENSION_DATA)
|
||||
|
||||
SHOULD_CACHE = cache.should_cache_fn('revoke')
|
||||
# TODO(ayoung): migrate from the token section
|
||||
REVOCATION_CACHE_EXPIRATION_TIME = lambda: CONF.token.revocation_cache_time
|
||||
|
||||
|
||||
def revoked_before_cutoff_time():
|
||||
expire_delta = datetime.timedelta(
|
||||
@ -58,34 +62,6 @@ def revoked_before_cutoff_time():
|
||||
return oldest
|
||||
|
||||
|
||||
_TREE_KEY = 'os-revoke-tree'
|
||||
_KVS_BACKEND = 'openstack.kvs.Memory'
|
||||
|
||||
|
||||
class _Cache(object):
|
||||
def __init__(self, **kwargs):
|
||||
self._store = kvs.get_key_value_store('os-revoke-synchonize')
|
||||
self._store.configure(backing_store=_KVS_BACKEND, **kwargs)
|
||||
self._last_fetch = None
|
||||
self._current_events = []
|
||||
self.revoke_map = model.RevokeTree()
|
||||
|
||||
def synchronize_revoke_map(self, driver):
|
||||
cutoff = revoked_before_cutoff_time()
|
||||
|
||||
with self._store.get_lock(_TREE_KEY):
|
||||
for e in self._current_events:
|
||||
if e.revoked_at < cutoff:
|
||||
self.revoke_map.remove_event(e)
|
||||
self._current_events.remove(e)
|
||||
else:
|
||||
break
|
||||
events = driver.get_events(last_fetch=self._last_fetch)
|
||||
self._last_fetch = timeutils.utcnow()
|
||||
self.revoke_map.add_events(events)
|
||||
self._current_events = self._current_events + events
|
||||
|
||||
|
||||
@dependency.provider('revoke_api')
|
||||
class Manager(manager.Manager):
|
||||
"""Revoke API Manager.
|
||||
@ -97,7 +73,7 @@ class Manager(manager.Manager):
|
||||
def __init__(self):
|
||||
super(Manager, self).__init__(CONF.revoke.driver)
|
||||
self._register_listeners()
|
||||
self._cache = _Cache()
|
||||
self.model = model
|
||||
|
||||
def _user_callback(self, service, resource_type, operation,
|
||||
payload):
|
||||
@ -105,32 +81,32 @@ class Manager(manager.Manager):
|
||||
|
||||
def _role_callback(self, service, resource_type, operation,
|
||||
payload):
|
||||
self.driver.revoke(
|
||||
self.revoke(
|
||||
model.RevokeEvent(role_id=payload['resource_info']))
|
||||
|
||||
def _project_callback(self, service, resource_type, operation,
|
||||
payload):
|
||||
self.driver.revoke(
|
||||
self.revoke(
|
||||
model.RevokeEvent(project_id=payload['resource_info']))
|
||||
|
||||
def _domain_callback(self, service, resource_type, operation,
|
||||
payload):
|
||||
self.driver.revoke(
|
||||
self.revoke(
|
||||
model.RevokeEvent(domain_id=payload['resource_info']))
|
||||
|
||||
def _trust_callback(self, service, resource_type, operation,
|
||||
payload):
|
||||
self.driver.revoke(
|
||||
self.revoke(
|
||||
model.RevokeEvent(trust_id=payload['resource_info']))
|
||||
|
||||
def _consumer_callback(self, service, resource_type, operation,
|
||||
payload):
|
||||
self.driver.revoke(
|
||||
self.revoke(
|
||||
model.RevokeEvent(consumer_id=payload['resource_info']))
|
||||
|
||||
def _access_token_callback(self, service, resource_type, operation,
|
||||
payload):
|
||||
self.driver.revoke(
|
||||
self.revoke(
|
||||
model.RevokeEvent(access_token_id=payload['resource_info']))
|
||||
|
||||
def _register_listeners(self):
|
||||
@ -149,33 +125,38 @@ class Manager(manager.Manager):
|
||||
notifications.register_event_callback(*cb)
|
||||
|
||||
def revoke_by_user(self, user_id):
|
||||
return self.driver.revoke(model.RevokeEvent(user_id=user_id))
|
||||
return self.revoke(model.RevokeEvent(user_id=user_id))
|
||||
|
||||
def revoke_by_expiration(self, user_id, expires_at):
|
||||
self.driver.revoke(
|
||||
self.revoke(
|
||||
model.RevokeEvent(user_id=user_id,
|
||||
expires_at=expires_at))
|
||||
|
||||
def revoke_by_grant(self, role_id, user_id=None,
|
||||
domain_id=None, project_id=None):
|
||||
self.driver.revoke(
|
||||
self.revoke(
|
||||
model.RevokeEvent(user_id=user_id,
|
||||
role_id=role_id,
|
||||
domain_id=domain_id,
|
||||
project_id=project_id))
|
||||
|
||||
def revoke_by_user_and_project(self, user_id, project_id):
|
||||
self.driver.revoke(
|
||||
model.RevokeEvent(project_id=project_id,
|
||||
user_id=user_id))
|
||||
self.revoke(
|
||||
model.RevokeEvent(project_id=project_id, user_id=user_id))
|
||||
|
||||
def revoke_by_project_role_assignment(self, project_id, role_id):
|
||||
self.driver.revoke(model.RevokeEvent(project_id=project_id,
|
||||
role_id=role_id))
|
||||
self.revoke(model.RevokeEvent(project_id=project_id, role_id=role_id))
|
||||
|
||||
def revoke_by_domain_role_assignment(self, domain_id, role_id):
|
||||
self.driver.revoke(model.RevokeEvent(domain_id=domain_id,
|
||||
role_id=role_id))
|
||||
self.revoke(model.RevokeEvent(domain_id=domain_id, role_id=role_id))
|
||||
|
||||
@cache.on_arguments(should_cache_fn=SHOULD_CACHE,
|
||||
expiration_time=REVOCATION_CACHE_EXPIRATION_TIME)
|
||||
def _get_revoke_tree(self):
|
||||
events = self.driver.get_events()
|
||||
revoke_tree = model.RevokeTree(revoke_events=events)
|
||||
|
||||
return revoke_tree
|
||||
|
||||
def check_token(self, token_values):
|
||||
"""Checks the values from a token against the revocation list
|
||||
@ -187,10 +168,13 @@ class Manager(manager.Manager):
|
||||
:raises exception.TokenNotFound: if the token is invalid
|
||||
|
||||
"""
|
||||
self._cache.synchronize_revoke_map(self.driver)
|
||||
if self._cache.revoke_map.is_revoked(token_values):
|
||||
if self._get_revoke_tree().is_revoked(token_values):
|
||||
raise exception.TokenNotFound(_('Failed to validate token'))
|
||||
|
||||
def revoke(self, event):
|
||||
self.driver.revoke(event)
|
||||
self._get_revoke_tree.invalidate(self)
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class Driver(object):
|
||||
|
@ -15,6 +15,7 @@
|
||||
import six
|
||||
|
||||
from keystone.common import config
|
||||
from keystone.openstack.common.gettextutils import _ # flake8: noqa
|
||||
from keystone.openstack.common import log
|
||||
from keystone.openstack.common import strutils
|
||||
|
||||
|
@ -24,7 +24,6 @@ from keystone.common import cache
|
||||
from keystone.common import wsgi
|
||||
from keystone import config
|
||||
from keystone.contrib import endpoint_filter
|
||||
from keystone.contrib import revoke
|
||||
from keystone import controllers
|
||||
from keystone import credential
|
||||
from keystone import identity
|
||||
@ -56,7 +55,6 @@ def load_backends():
|
||||
endpoint_filter_api=endpoint_filter.Manager(),
|
||||
identity_api=_IDENTITY_API,
|
||||
policy_api=policy.Manager(),
|
||||
revoke_api=revoke.Manager(),
|
||||
token_api=token.Manager(),
|
||||
trust_api=trust.Manager(),
|
||||
token_provider_api=token.provider.Manager())
|
||||
|
@ -348,6 +348,7 @@ class BaseTestCase(testtools.TestCase):
|
||||
return cleanup
|
||||
|
||||
|
||||
@dependency.optional('revoke_api')
|
||||
class TestCase(BaseTestCase):
|
||||
|
||||
_config_file_list = [dirs.etc('keystone.conf.sample'),
|
||||
@ -426,15 +427,7 @@ class TestCase(BaseTestCase):
|
||||
self.clear_auth_plugin_registry()
|
||||
drivers = service.load_backends()
|
||||
|
||||
# TODO(stevemar): currently, load oauth1 driver as well, eventually
|
||||
# we need to have this as optional.
|
||||
from keystone.contrib import oauth1
|
||||
drivers['oauth1_api'] = oauth1.Manager()
|
||||
|
||||
from keystone.contrib import federation
|
||||
drivers['federation_api'] = federation.Manager()
|
||||
|
||||
dependency.resolve_future_dependencies()
|
||||
drivers.update(dependency.resolve_future_dependencies())
|
||||
|
||||
for manager_name, manager in six.iteritems(drivers):
|
||||
setattr(self, manager_name, manager)
|
||||
|
@ -20,6 +20,7 @@ import uuid
|
||||
from keystoneclient.common import cms
|
||||
|
||||
from keystone import auth
|
||||
from keystone.common import dependency
|
||||
from keystone import config
|
||||
from keystone import exception
|
||||
from keystone.openstack.common import timeutils
|
||||
@ -567,6 +568,7 @@ class TestTokenRevokeSelfAndAdmin(test_v3.RestfulTestCase):
|
||||
token=adminB_token)
|
||||
|
||||
|
||||
@dependency.requires('revoke_api')
|
||||
class TestTokenRevokeById(test_v3.RestfulTestCase):
|
||||
"""Test token revocation on the v3 Identity API."""
|
||||
|
||||
@ -1182,6 +1184,7 @@ class TestTokenRevokeById(test_v3.RestfulTestCase):
|
||||
self.head(role_path, expected_status=404)
|
||||
|
||||
|
||||
@dependency.requires('revoke_api')
|
||||
class TestTokenRevokeApi(TestTokenRevokeById):
|
||||
EXTENSION_NAME = 'revoke'
|
||||
EXTENSION_TO_ADD = 'revoke_extension'
|
||||
@ -2259,6 +2262,7 @@ class TestTrustOptional(test_v3.RestfulTestCase):
|
||||
self.post('/auth/tokens', body=auth_data, expected_status=403)
|
||||
|
||||
|
||||
@dependency.requires('revoke_api')
|
||||
class TestTrustAuth(TestAuthInfo):
|
||||
EXTENSION_NAME = 'revoke'
|
||||
EXTENSION_TO_ADD = 'revoke_extension'
|
||||
|
@ -14,6 +14,7 @@ import random
|
||||
import uuid
|
||||
|
||||
from keystone.auth import controllers as auth_controllers
|
||||
from keystone.common import dependency
|
||||
from keystone.common import sql
|
||||
from keystone.common.sql import migration_helpers
|
||||
from keystone import config
|
||||
@ -36,6 +37,7 @@ def dummy_validator(*args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
@dependency.requires('federation_api')
|
||||
class FederationTests(test_v3.RestfulTestCase):
|
||||
|
||||
EXTENSION_NAME = 'federation'
|
||||
|
@ -22,7 +22,6 @@ from keystone.common import cache
|
||||
from keystone.common import dependency
|
||||
from keystone.common import manager
|
||||
from keystone import config
|
||||
from keystone.contrib.revoke import model as revoke_model
|
||||
|
||||
from keystone import exception
|
||||
from keystone.openstack.common import log
|
||||
@ -124,9 +123,9 @@ class Manager(manager.Manager):
|
||||
except KeyError:
|
||||
raise exception.TokenNotFound(_('Failed to validate token'))
|
||||
|
||||
token_values = revoke_model.build_token_values_v2(
|
||||
token_data, CONF.identity.default_domain_id)
|
||||
if self.revoke_api is not None:
|
||||
token_values = self.revoke_api.model.build_token_values_v2(
|
||||
token_data, CONF.identity.default_domain_id)
|
||||
self.revoke_api.check_token(token_values)
|
||||
|
||||
def validate_v2_token(self, token_id, belongs_to=None):
|
||||
@ -144,8 +143,8 @@ class Manager(manager.Manager):
|
||||
token_data = token['token']
|
||||
except KeyError:
|
||||
raise exception.TokenNotFound(_('Failed to validate token'))
|
||||
token_values = revoke_model.build_token_values(token_data)
|
||||
if self.revoke_api is not None:
|
||||
token_values = self.revoke_api.model.build_token_values(token_data)
|
||||
self.revoke_api.check_token(token_values)
|
||||
|
||||
def check_revocation(self, token):
|
||||
|
@ -354,9 +354,9 @@ class V3TokenDataHelper(object):
|
||||
return {'token': token_data}
|
||||
|
||||
|
||||
@dependency.optional('oauth_api')
|
||||
@dependency.optional('oauth_api', 'revoke_api')
|
||||
@dependency.requires('assignment_api', 'catalog_api', 'identity_api',
|
||||
'revoke_api', 'token_api', 'trust_api')
|
||||
'token_api', 'trust_api')
|
||||
class BaseProvider(provider.Provider):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(BaseProvider, self).__init__(*args, **kwargs)
|
||||
|
Loading…
x
Reference in New Issue
Block a user