Don't give clients made up tokens

If we can't set the token in memcache return the client a service
unavailable error.

Change-Id: I33a672f49dc09886f26b58f4fef6916d11f69547
This commit is contained in:
Clay Gerrard 2022-05-02 17:28:03 -05:00
parent 9bed525bfb
commit 94226bdd39
2 changed files with 36 additions and 15 deletions

View File

@ -183,9 +183,10 @@ import base64
from eventlet import Timeout
import six
from swift.common.memcached import MemcacheConnectionError
from swift.common.swob import Response, Request, wsgi_to_str
from swift.common.swob import HTTPBadRequest, HTTPForbidden, HTTPNotFound, \
HTTPUnauthorized, HTTPMethodNotAllowed
HTTPUnauthorized, HTTPMethodNotAllowed, HTTPServiceUnavailable
from swift.common.request_helpers import get_sys_meta_prefix
from swift.common.middleware.acl import (
@ -690,7 +691,7 @@ class TempAuth(object):
self.logger.increment('errors')
start_response('500 Server Error',
[('Content-Type', 'text/plain')])
return ['Internal server error.\n']
return [b'Internal server error.\n']
def handle_request(self, req):
"""
@ -720,6 +721,25 @@ class TempAuth(object):
req.response = handler(req)
return req.response
def _create_new_token(self, memcache_client,
account, account_user, account_id):
# Generate new token
token = '%stk%s' % (self.reseller_prefix, uuid4().hex)
expires = time() + self.token_life
groups = self._get_user_groups(account, account_user, account_id)
# Save token
memcache_token_key = '%s/token/%s' % (self.reseller_prefix, token)
memcache_client.set(memcache_token_key, (expires, groups),
time=float(expires - time()),
raise_on_error=True)
# Record the token with the user info for future use.
memcache_user_key = \
'%s/user/%s' % (self.reseller_prefix, account_user)
memcache_client.set(memcache_user_key, token,
time=float(expires - time()),
raise_on_error=True)
return token, expires
def handle_get_token(self, req):
"""
Handles the various `request for token and service end point(s)` calls.
@ -827,19 +847,11 @@ class TempAuth(object):
token = candidate_token
# Create a new token if one didn't exist
if not token:
# Generate new token
token = '%stk%s' % (self.reseller_prefix, uuid4().hex)
expires = time() + self.token_life
groups = self._get_user_groups(account, account_user, account_id)
# Save token
memcache_token_key = '%s/token/%s' % (self.reseller_prefix, token)
memcache_client.set(memcache_token_key, (expires, groups),
time=float(expires - time()))
# Record the token with the user info for future use.
memcache_user_key = \
'%s/user/%s' % (self.reseller_prefix, account_user)
memcache_client.set(memcache_user_key, token,
time=float(expires - time()))
try:
token, expires = self._create_new_token(
memcache_client, account, account_user, account_id)
except MemcacheConnectionError:
return HTTPServiceUnavailable(request=req)
resp = Response(request=req, headers={
'x-auth-token': token, 'x-storage-token': token,
'x-auth-token-expires': str(int(expires - time()))})

View File

@ -627,6 +627,15 @@ class TestAuth(unittest.TestCase):
auth.DEFAULT_TOKEN_LIFE - 0.5, delta=0.5)
self.assertGreater(len(resp.headers['x-auth-token']), 10)
def test_get_token_memcache_error(self):
test_auth = auth.filter_factory({'user_ac_user': 'testing'})(FakeApp())
req = self._make_request(
'/auth/v1.0',
headers={'X-Auth-User': 'ac:user', 'X-Auth-Key': 'testing'})
req.environ['swift.cache'] = FakeMemcache(error_on_set=[True])
resp = req.get_response(test_auth)
self.assertEqual(resp.status_int, 503)
def test_get_token_success_other_auth_prefix(self):
test_auth = auth.filter_factory({'user_ac_user': 'testing',
'auth_prefix': '/other/'})(FakeApp())