7a760caa5d
The default discovery URLs for when the admin_endpoint and public_endpoint configuration values are unset is to point to the localhost. This is wrong in all but the most trivial cases. It also has the problem of not being able to distinguish for the public service whether it was accessed via the 'public' or 'private' endpoint, meaning that all clients that correctly do discovery will end up routing to the public URL. The most sensible default is to simply use the requested URL as the basis for pointing to the versioned endpoints as it at least assumes that the endpoint is accessible relative to the location used to arrive on the page. As mentioned in comments this is not a perfect solution. HOST_URL is the URL not including path (ie http://server:port) so we do not have access to the prefix automatically. Unfortunately the way keystone uses these endpoints I don't see a way of improving that without a more substantial redesign. This patch is ugly because our layers are so intertwined. It should be nicer with pecan. DocImpact: Changes the default values of admin_endpoint and public_endpoint and how they are used. In most situations now these values should be ignored in configuration. Change-Id: Ia6d9fbeb60ada661dc2052c9bd51db7a1dc8cd4b Closes-Bug: #1288009
75 lines
2.7 KiB
Python
75 lines
2.7 KiB
Python
# 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.
|
|
|
|
from keystone import auth
|
|
from keystone.common import controller
|
|
from keystone.common import dependency
|
|
from keystone.contrib.oauth1 import core as oauth
|
|
from keystone.contrib.oauth1 import validator
|
|
from keystone import exception
|
|
from keystone.openstack.common.gettextutils import _
|
|
from keystone.openstack.common import log
|
|
from keystone.openstack.common import timeutils
|
|
|
|
|
|
LOG = log.getLogger(__name__)
|
|
|
|
|
|
@dependency.optional('oauth_api')
|
|
class OAuth(auth.AuthMethodHandler):
|
|
|
|
method = 'oauth1'
|
|
|
|
def authenticate(self, context, auth_info, auth_context):
|
|
"""Turn a signed request with an access key into a keystone token."""
|
|
|
|
if not self.oauth_api:
|
|
raise exception.Unauthorized(_('%s not supported') % self.method)
|
|
|
|
headers = context['headers']
|
|
oauth_headers = oauth.get_oauth_headers(headers)
|
|
access_token_id = oauth_headers.get('oauth_token')
|
|
|
|
if not access_token_id:
|
|
raise exception.ValidationError(
|
|
attribute='oauth_token', target='request')
|
|
|
|
acc_token = self.oauth_api.get_access_token(access_token_id)
|
|
|
|
expires_at = acc_token['expires_at']
|
|
if expires_at:
|
|
now = timeutils.utcnow()
|
|
expires = timeutils.normalize_time(
|
|
timeutils.parse_isotime(expires_at))
|
|
if now > expires:
|
|
raise exception.Unauthorized(_('Access token is expired'))
|
|
|
|
url = controller.V3Controller.base_url(context, context['path'])
|
|
access_verifier = oauth.ResourceEndpoint(
|
|
request_validator=validator.OAuthValidator(),
|
|
token_generator=oauth.token_generator)
|
|
result, request = access_verifier.validate_protected_resource_request(
|
|
url,
|
|
http_method='POST',
|
|
body=context['query_string'],
|
|
headers=headers,
|
|
realms=None
|
|
)
|
|
if not result:
|
|
msg = _('Could not validate the access token')
|
|
raise exception.Unauthorized(msg)
|
|
auth_context['user_id'] = acc_token['authorizing_user_id']
|
|
auth_context['access_token_id'] = access_token_id
|
|
auth_context['project_id'] = acc_token['project_id']
|