Files
keystone/keystone/auth/plugins/oauth1.py
T
Jamie Lennox 7a760caa5d Change the default version discovery URLs
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
2014-03-25 10:15:15 +10:00

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']