Consolidated OAuth Configuration, added enable flag to oauth cleaner.

The OAuth configuration elements were moved into a single block
within storyboard.conf, so that relevant other components could
add their own configuration. The OAuth Token Cleaner was then provided
with its own configuration flag so that it can be disabled.

Change-Id: I9c02ea913f184c0734e2b694469d36c5e96339b5
This commit is contained in:
Michael Krotscheck 2014-12-29 12:00:25 -08:00
parent 16e11b0beb
commit e0c1c11bf3
12 changed files with 97 additions and 42 deletions

View File

@ -37,6 +37,17 @@ lock_path = $state_path/lock
# Port the bind the API server to
# bind_port = 8080
# List paging configuration options.
# page_size_maximum = 500
# page_size_default = 20
# Enable notifications. This feature drives deferred processing, reporting,
# and subscriptions.
# enable_notifications = True
[oauth]
# StoryBoard's oauth configuration.
# OpenId Authentication endpoint
# openid_url = https://login.launchpad.net/+openid
@ -46,14 +57,6 @@ lock_path = $state_path/lock
# Time in seconds before an refresh_token expires
# refresh_token_ttl = 604800
# List paging configuration options.
# page_size_maximum = 500
# page_size_default = 20
# Enable notifications. This feature drives deferred processing, reporting,
# and subscriptions.
# enable_notifications = True
[cron]
# Storyboard's cron management configuration
@ -137,3 +140,8 @@ lock_path = $state_path/lock
# If set, use this value for pool_timeout with sqlalchemy
# pool_timeout = 10
[plugin_token_cleaner]
# Enable/Disable the token cleaning cron plugin. This requires cron
# management to be enabled.
# enable = True

View File

@ -42,7 +42,7 @@ storyboard.worker.task =
storyboard.plugin.user_preferences =
storyboard.plugin.cron =
cron-management = storyboard.plugin.cron.manager:CronManager
token-cleaner = storyboard.plugin.oauth.cleaner:TokenCleaner
token-cleaner = storyboard.plugin.token_cleaner.cleaner:TokenCleaner
[build_sphinx]
source-dir = doc/source

View File

@ -0,0 +1,33 @@
# Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied. See the License for the specific language governing permissions and
# limitations under the License.
from oslo.config import cfg
CONF = cfg.CONF
OAUTH_OPTS = [
cfg.StrOpt('openid_url',
default='https://login.launchpad.net/+openid',
help='OpenId Authentication endpoint'),
cfg.IntOpt("access_token_ttl",
default=60 * 60, # One hour
help="Time in seconds before an access_token expires"),
cfg.IntOpt("refresh_token_ttl",
default=60 * 60 * 24 * 7, # One week
help="Time in seconds before an refresh_token expires")
]
CONF.register_opts(OAUTH_OPTS, "oauth")

View File

@ -26,18 +26,6 @@ from storyboard.openstack.common import log
CONF = cfg.CONF
LOG = log.getLogger(__name__)
TOKEN_OPTS = [
cfg.IntOpt("access_token_ttl",
default=60 * 60, # One hour
help="Time in seconds before an access_token expires"),
cfg.IntOpt("refresh_token_ttl",
default=60 * 60 * 24 * 7, # One week
help="Time in seconds before an refresh_token expires")
]
CONF.register_opts(TOKEN_OPTS)
class SkeletonValidator(RequestValidator):
"""This is oauth skeleton for handling all kind of validations and storage
@ -259,7 +247,7 @@ class SkeletonValidator(RequestValidator):
class OpenIdConnectServer(WebApplicationServer):
def __init__(self, request_validator):
access_token_ttl = CONF.access_token_ttl
access_token_ttl = CONF.oauth.access_token_ttl
super(OpenIdConnectServer, self).__init__(
request_validator,
token_expires_in=access_token_ttl)

View File

@ -24,19 +24,10 @@ LOG = log.getLogger(__name__)
CONF = cfg.CONF
OPENID_OPTS = [
cfg.StrOpt('openid_url',
default='https://login.launchpad.net/+openid',
help='OpenId Authentication endpoint')
]
CONF.register_opts(OPENID_OPTS)
class OpenIdClient(object):
def send_openid_redirect(self, request, response):
redirect_location = CONF.openid_url
redirect_location = CONF.oauth.openid_url
response.status_code = 303
return_params = {
@ -91,7 +82,8 @@ class OpenIdClient(object):
verify_params = dict(request.params.copy())
verify_params["openid.mode"] = "check_authentication"
verify_response = requests.post(CONF.openid_url, data=verify_params)
verify_response = requests.post(CONF.oauth.openid_url,
data=verify_params)
verify_data_tokens = verify_response.content.split()
verify_dict = dict((token.split(":")[0], token.split(":")[1])
for token in verify_data_tokens)

View File

@ -55,7 +55,7 @@ class DBTokenStorage(storage.StorageBase):
# Oauthlib does not provide a separate expiration time for a
# refresh_token so taking it from config directly.
refresh_expires_in = CONF.refresh_token_ttl
refresh_expires_in = CONF.oauth.refresh_token_ttl
refresh_token_values = {
"refresh_token": refresh_token,

View File

@ -0,0 +1,25 @@
# Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied. See the License for the specific language governing permissions and
# limitations under the License.
from oslo.config import cfg
CONF = cfg.CONF
PLUGIN_OPTS = [
cfg.BoolOpt("enable",
default=False, # By default, we don't scrub old oauth tokens.
help="Enable, or disable, the oauth token cleaner")
]
CONF.register_opts(PLUGIN_OPTS, "plugin_token_cleaner")

View File

@ -31,7 +31,9 @@ class TokenCleaner(CronPluginBase):
"""Indicate whether this plugin is enabled. This indicates whether
this plugin alone is runnable, as opposed to the entire cron system.
"""
return True
if 'plugin_token_cleaner' in self.config:
return self.config.plugin_token_cleaner.enable or False
return False
def interval(self):
"""This plugin executes on startup, and once every hour after that.

View File

@ -245,8 +245,8 @@ class TestCronManager(base.TestCase):
manager = cronmanager.CronManager(CONF, tabfile=self.tabfile)
manager.execute()
# We're expecting 2 in-branch plugins.
self.assertCronLength(2, command='storyboard-cron')
# We're expecting 1 enabled in-branch plugins.
self.assertCronLength(1, command='storyboard-cron')
def test_execute_update(self):
"""Test that execute() method updates plugins."""
@ -312,7 +312,7 @@ class TestCronManager(base.TestCase):
# Check a new crontab to see what we find.
self.assertCronLength(0, command=plugin_command)
self.assertCronLength(2, command='storyboard-cron')
self.assertCronLength(1, command='storyboard-cron')
# Cleanup after ourselves.
manager.remove()
@ -343,7 +343,7 @@ class TestCronManager(base.TestCase):
manager.execute()
# Check a new crontab to see what we find.
self.assertCronLength(2, command='storyboard-cron')
self.assertCronLength(1, command='storyboard-cron')
# Cleanup after ourselves.
manager.remove()

View File

@ -18,7 +18,7 @@ from datetime import timedelta
from oslo.config import cfg
import storyboard.db.api.base as db_api
from storyboard.db.models import AccessToken
from storyboard.plugin.oauth.cleaner import TokenCleaner
from storyboard.plugin.token_cleaner.cleaner import TokenCleaner
import storyboard.tests.base as base
from storyboard.tests.mock_data import load_data
@ -36,12 +36,19 @@ class TestTokenCleaner(base.FunctionalTest):
super(TestTokenCleaner, self).tearDown()
def test_enabled(self):
"""This plugin must always be enabled. The only time it's not enabled
is when cron has been disabled.
"""Assert that this plugin responds to the flag set in our
oauth configuration block.
"""
CONF.set_override('enable', False, 'plugin_token_cleaner')
plugin = TokenCleaner(CONF)
self.assertFalse(plugin.enabled())
CONF.set_override('enable', True, 'plugin_token_cleaner')
plugin = TokenCleaner(CONF)
self.assertTrue(plugin.enabled())
CONF.clear_override('enable', 'plugin_token_cleaner')
def test_interval(self):
"""Assert that the cron manager runs every 5 minutes."""
plugin = TokenCleaner(CONF)