Fixed typos; bug fix in auth db upgrade; renamed a couple things to better reflect their new usage; updated docs

This commit is contained in:
gholt 2010-09-05 19:53:08 -07:00
parent 0066ed02d7
commit 235c0e9bd5
5 changed files with 84 additions and 87 deletions

View File

@ -31,7 +31,7 @@ if __name__ == '__main__':
'auth server (default: %s).' % default_conf)
parser.add_option('-a', '--admin', dest='admin', action='store_true',
default=False, help='Give the user administrator access; otherwise '
'the user will only have access to container specifically allowed '
'the user will only have access to containers specifically allowed '
'with ACLs.')
args = argv[1:]
if not args:

View File

@ -532,12 +532,9 @@ good idea what to do on other environments.
#. Check that `st` works: `st -A http://127.0.0.1:11000/v1.0 -U test:tester -K testing stat`
#. `swift-auth-add-user --admin test2 tester2 testing2`
#. `swift-auth-add-user test tester3 testing3`
#. Create `/etc/swift/func_test.conf`::
cp ~/swift/trunk/test/functional/sample.conf /etc/swift/func_test.conf
#. `cp ~/swift/trunk/test/functional/sample.conf /etc/swift/func_test.conf`
#. `cd ~/swift/trunk; ./.functests` (Note: functional tests will first delete
everything in the configured account.)
everything in the configured accounts.)
#. `cd ~/swift/trunk; ./.probetests` (Note: probe tests will reset your
environment as they call `resetswift` for each test.)

View File

@ -108,8 +108,8 @@ class AuthController(object):
self.conn.execute('SELECT admin FROM account LIMIT 1')
except sqlite3.OperationalError, err:
if str(err) == 'no such column: admin':
self.conn.execute(
"ALTER TABLE account ADD COLUMN admin TEXT DEFAULT 't'")
self.conn.execute("ALTER TABLE account ADD COLUMN admin TEXT")
self.conn.execute("UPDATE account SET admin = 't'")
self.conn.execute('''CREATE TABLE IF NOT EXISTS account (
account TEXT, url TEXT, cfaccount TEXT,
user TEXT, password TEXT, admin TEXT)''')
@ -248,25 +248,22 @@ class AuthController(object):
(repr(token), repr(rv), time() - begin))
return rv
def create_account(self, new_account, new_user, new_password,
admin=False):
def create_user(self, account, user, password, admin=False):
"""
Handles the create_account call for developers, used to request
an account be created both on a Swift cluster and in the auth server
database.
Handles the create_user call for developers, used to request a user be
added in the auth server database. If the account does not yet exist,
it will be created on the Swift cluster and the details recorded in the
auth server database.
This will make ReST requests to the Swift cluster's account servers
to have an account created on its side. The resulting account hash
along with the URL to use to access the account, the account name, the
user name, and the password is recorded in the auth server's database.
The url is constructed now and stored separately to support changing
the configuration file's default_cluster_url for directing new accounts
to a different Swift cluster while still supporting old accounts going
to the Swift clusters they were created on.
The url for the storage account is constructed now and stored
separately to support changing the configuration file's
default_cluster_url for directing new accounts to a different Swift
cluster while still supporting old accounts going to the Swift clusters
they were created on.
:param new_account: The name for the new account
:param new_user: The name for the new user
:param new_password: The password for the new account
:param account: The name for the new account
:param user: The name for the new user
:param password: The password for the new account
:param admin: If true, the user will be granted full access to the
account; otherwise, another user will have to add the
user to the ACLs for containers to grant access.
@ -275,21 +272,21 @@ class AuthController(object):
already exists, or storage url if successful
"""
begin = time()
if not all((new_account, new_user, new_password)):
if not all((account, user, password)):
return False
with self.get_conn() as conn:
row = conn.execute(
'SELECT url FROM account WHERE account = ? AND user = ?',
(new_account, new_user)).fetchone()
(account, user)).fetchone()
if row:
self.logger.info(
'ALREADY EXISTS create_account(%s, %s, _, %s) [%.02f]' %
(repr(new_account), repr(new_user), repr(admin),
'ALREADY EXISTS create_user(%s, %s, _, %s) [%.02f]' %
(repr(account), repr(user), repr(admin),
time() - begin))
return 'already exists'
row = conn.execute(
'SELECT url, cfaccount FROM account WHERE account = ?',
(new_account,)).fetchone()
(account,)).fetchone()
if row:
url = row[0]
account_hash = row[1]
@ -297,20 +294,20 @@ class AuthController(object):
account_hash = self.add_storage_account()
if not account_hash:
self.logger.info(
'FAILED create_account(%s, %s, _, %s) [%.02f]' %
(repr(new_account), repr(new_user), repr(admin),
'FAILED create_user(%s, %s, _, %s) [%.02f]' %
(repr(account), repr(user), repr(admin),
time() - begin))
return False
url = self.default_cluster_url.rstrip('/') + '/' + account_hash
conn.execute('''INSERT INTO account
(account, url, cfaccount, user, password, admin)
VALUES (?, ?, ?, ?, ?, ?)''',
(new_account, url, account_hash, new_user, new_password,
(account, url, account_hash, user, password,
admin and 't' or ''))
conn.commit()
self.logger.info(
'SUCCESS create_account(%s, %s, _, %s) = %s [%.02f]' %
(repr(new_account), repr(new_user), repr(admin), repr(url),
'SUCCESS create_user(%s, %s, _, %s) = %s [%.02f]' %
(repr(account), repr(user), repr(admin), repr(url),
time() - begin))
return url
@ -342,8 +339,10 @@ class AuthController(object):
Valid URL paths:
* GET /token/<token>
If the HTTP equest returns with a 204, then the token is valid,
and the TTL of the token will be available in the X-Auth-Ttl header.
If the HTTP request returns with a 204, then the token is valid, the
TTL of the token will be available in the X-Auth-Ttl header, and a
comma separated list of the "groups" the user belongs to will be in the
X-Auth-Groups header.
:param request: webob.Request object
"""
@ -359,7 +358,7 @@ class AuthController(object):
if validation[3]: # admin access to a cfaccount
groups.append(validation[3])
return HTTPNoContent(headers={'X-Auth-TTL': validation[0],
'X-Auth-User': ','.join(groups)})
'X-Auth-Groups': ','.join(groups)})
def handle_add_user(self, request):
"""
@ -387,7 +386,7 @@ class AuthController(object):
if 'X-Auth-User-Key' not in request.headers:
return HTTPBadRequest('X-Auth-User-Key is required')
password = request.headers['x-auth-user-key']
storage_url = self.create_account(account_name, user_name, password,
storage_url = self.create_user(account_name, user_name, password,
request.headers.get('x-auth-user-admin') == 'true')
if storage_url == 'already exists':
return HTTPBadRequest(storage_url)

View File

@ -39,19 +39,20 @@ class DevAuth(object):
"""
Accepts a standard WSGI application call, authenticating the request
and installing callback hooks for authorization and ACL header
validation.
validation. For an authenticated request, REMOTE_USER will be set to a
comma separated list of the user's groups.
"""
user = None
groups = None
token = env.get('HTTP_X_AUTH_TOKEN', env.get('HTTP_X_STORAGE_TOKEN'))
if token:
memcache_client = cache_from_env(env)
key = 'devauth/%s' % token
cached_auth_data = memcache_client.get(key)
if cached_auth_data:
start, expiration, user = cached_auth_data
start, expiration, groups = cached_auth_data
if time() - start > expiration:
user = None
if not user:
groups = None
if not groups:
with Timeout(self.timeout):
conn = http_connect(self.auth_host, self.auth_port, 'GET',
'/token/%s' % token, ssl=self.ssl)
@ -61,10 +62,10 @@ class DevAuth(object):
if resp.status // 100 != 2:
return HTTPUnauthorized()(env, start_response)
expiration = float(resp.getheader('x-auth-ttl'))
user = resp.getheader('x-auth-user')
memcache_client.set(key, (time(), expiration, user),
groups = resp.getheader('x-auth-groups')
memcache_client.set(key, (time(), expiration, groups),
timeout=expiration)
env['REMOTE_USER'] = user
env['REMOTE_USER'] = groups
env['swift.authorize'] = self.authorize
env['swift.clean_acl'] = clean_acl
return self.app(env, start_response)

View File

@ -106,7 +106,7 @@ class TestAuthServer(unittest.TestCase):
def test_validate_token_non_existant_token(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
cfaccount = self.controller.create_account(
cfaccount = self.controller.create_user(
'test', 'tester', 'testing',).split('/')[-1]
res = self.controller.handle_auth(Request.blank('/v1/test/auth',
environ={'REQUEST_METHOD': 'GET'},
@ -117,7 +117,7 @@ class TestAuthServer(unittest.TestCase):
def test_validate_token_good(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
cfaccount = self.controller.create_account(
cfaccount = self.controller.create_user(
'test', 'tester', 'testing',).split('/')[-1]
res = self.controller.handle_auth(Request.blank('/v1/test/auth',
environ={'REQUEST_METHOD': 'GET'},
@ -132,7 +132,7 @@ class TestAuthServer(unittest.TestCase):
try:
auth_server.time = lambda: 1
auth_server.http_connect = fake_http_connect(201, 201, 201)
cfaccount = self.controller.create_account('test', 'tester',
cfaccount = self.controller.create_user('test', 'tester',
'testing').split('/')[-1]
res = self.controller.handle_auth(Request.blank('/v1/test/auth',
environ={'REQUEST_METHOD': 'GET'},
@ -146,24 +146,24 @@ class TestAuthServer(unittest.TestCase):
finally:
auth_server.time = orig_time
def test_create_account_no_new_account(self):
def test_create_user_no_new_account(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
result = self.controller.create_account('', 'tester', 'testing')
result = self.controller.create_user('', 'tester', 'testing')
self.assertFalse(result)
def test_create_account_no_new_user(self):
def test_create_user_no_new_user(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
result = self.controller.create_account('test', '', 'testing')
result = self.controller.create_user('test', '', 'testing')
self.assertFalse(result)
def test_create_account_no_new_password(self):
def test_create_user_no_new_password(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
result = self.controller.create_account('test', 'tester', '')
result = self.controller.create_user('test', 'tester', '')
self.assertFalse(result)
def test_create_account_good(self):
def test_create_user_good(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
url = self.controller.create_account('test', 'tester', 'testing')
url = self.controller.create_user('test', 'tester', 'testing')
self.assert_(url)
self.assertEquals('/'.join(url.split('/')[:-1]),
self.controller.default_cluster_url.rstrip('/'), repr(url))
@ -176,7 +176,7 @@ class TestAuthServer(unittest.TestCase):
def test_recreate_accounts_one(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
self.controller.create_account('test', 'tester', 'testing')
self.controller.create_user('test', 'tester', 'testing')
auth_server.http_connect = fake_http_connect(201, 201, 201)
rv = self.controller.recreate_accounts()
self.assertEquals(rv.split()[0], '1', repr(rv))
@ -184,13 +184,13 @@ class TestAuthServer(unittest.TestCase):
def test_recreate_accounts_several(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
self.controller.create_account('test1', 'tester', 'testing')
self.controller.create_user('test1', 'tester', 'testing')
auth_server.http_connect = fake_http_connect(201, 201, 201)
self.controller.create_account('test2', 'tester', 'testing')
self.controller.create_user('test2', 'tester', 'testing')
auth_server.http_connect = fake_http_connect(201, 201, 201)
self.controller.create_account('test3', 'tester', 'testing')
self.controller.create_user('test3', 'tester', 'testing')
auth_server.http_connect = fake_http_connect(201, 201, 201)
self.controller.create_account('test4', 'tester', 'testing')
self.controller.create_user('test4', 'tester', 'testing')
auth_server.http_connect = fake_http_connect(201, 201, 201,
201, 201, 201,
201, 201, 201,
@ -201,7 +201,7 @@ class TestAuthServer(unittest.TestCase):
def test_recreate_accounts_one_fail(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
url = self.controller.create_account('test', 'tester', 'testing')
url = self.controller.create_user('test', 'tester', 'testing')
cfaccount = url.split('/')[-1]
auth_server.http_connect = fake_http_connect(500, 500, 500)
rv = self.controller.recreate_accounts()
@ -211,16 +211,16 @@ class TestAuthServer(unittest.TestCase):
def test_recreate_accounts_several_fail(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
url = self.controller.create_account('test1', 'tester', 'testing')
url = self.controller.create_user('test1', 'tester', 'testing')
cfaccounts = [url.split('/')[-1]]
auth_server.http_connect = fake_http_connect(201, 201, 201)
url = self.controller.create_account('test2', 'tester', 'testing')
url = self.controller.create_user('test2', 'tester', 'testing')
cfaccounts.append(url.split('/')[-1])
auth_server.http_connect = fake_http_connect(201, 201, 201)
url = self.controller.create_account('test3', 'tester', 'testing')
url = self.controller.create_user('test3', 'tester', 'testing')
cfaccounts.append(url.split('/')[-1])
auth_server.http_connect = fake_http_connect(201, 201, 201)
url = self.controller.create_account('test4', 'tester', 'testing')
url = self.controller.create_user('test4', 'tester', 'testing')
cfaccounts.append(url.split('/')[-1])
auth_server.http_connect = fake_http_connect(500, 500, 500,
500, 500, 500,
@ -233,16 +233,16 @@ class TestAuthServer(unittest.TestCase):
def test_recreate_accounts_several_fail_some(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
url = self.controller.create_account('test1', 'tester', 'testing')
url = self.controller.create_user('test1', 'tester', 'testing')
cfaccounts = [url.split('/')[-1]]
auth_server.http_connect = fake_http_connect(201, 201, 201)
url = self.controller.create_account('test2', 'tester', 'testing')
url = self.controller.create_user('test2', 'tester', 'testing')
cfaccounts.append(url.split('/')[-1])
auth_server.http_connect = fake_http_connect(201, 201, 201)
url = self.controller.create_account('test3', 'tester', 'testing')
url = self.controller.create_user('test3', 'tester', 'testing')
cfaccounts.append(url.split('/')[-1])
auth_server.http_connect = fake_http_connect(201, 201, 201)
url = self.controller.create_account('test4', 'tester', 'testing')
url = self.controller.create_user('test4', 'tester', 'testing')
cfaccounts.append(url.split('/')[-1])
auth_server.http_connect = fake_http_connect(500, 500, 500,
201, 201, 201,
@ -263,7 +263,7 @@ class TestAuthServer(unittest.TestCase):
def test_auth_SOSO_missing_headers(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
cfaccount = self.controller.create_account(
cfaccount = self.controller.create_user(
'test', 'tester', 'testing').split('/')[-1]
res = self.controller.handle_auth(Request.blank('/v1/test/auth',
environ={'REQUEST_METHOD': 'GET'},
@ -279,7 +279,7 @@ class TestAuthServer(unittest.TestCase):
def test_auth_SOSO_bad_account(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
cfaccount = self.controller.create_account(
cfaccount = self.controller.create_user(
'test', 'tester', 'testing').split('/')[-1]
res = self.controller.handle_auth(Request.blank('/v1/testbad/auth',
environ={'REQUEST_METHOD': 'GET'},
@ -294,7 +294,7 @@ class TestAuthServer(unittest.TestCase):
def test_auth_SOSO_bad_user(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
cfaccount = self.controller.create_account(
cfaccount = self.controller.create_user(
'test', 'tester', 'testing').split('/')[-1]
res = self.controller.handle_auth(Request.blank('/v1/test/auth',
environ={'REQUEST_METHOD': 'GET'},
@ -309,7 +309,7 @@ class TestAuthServer(unittest.TestCase):
def test_auth_SOSO_bad_password(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
cfaccount = self.controller.create_account(
cfaccount = self.controller.create_user(
'test', 'tester', 'testing').split('/')[-1]
res = self.controller.handle_auth(Request.blank('/v1/test/auth',
environ={'REQUEST_METHOD': 'GET'},
@ -324,7 +324,7 @@ class TestAuthServer(unittest.TestCase):
def test_auth_SOSO_good(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
cfaccount = self.controller.create_account(
cfaccount = self.controller.create_user(
'test', 'tester', 'testing').split('/')[-1]
res = self.controller.handle_auth(Request.blank('/v1/test/auth',
environ={'REQUEST_METHOD': 'GET'},
@ -336,7 +336,7 @@ class TestAuthServer(unittest.TestCase):
def test_auth_SOSO_good_Mosso_headers(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
cfaccount = self.controller.create_account(
cfaccount = self.controller.create_user(
'test', 'tester', 'testing').split('/')[-1]
res = self.controller.handle_auth(Request.blank('/v1/test/auth',
environ={'REQUEST_METHOD': 'GET'},
@ -348,7 +348,7 @@ class TestAuthServer(unittest.TestCase):
def test_auth_SOSO_bad_Mosso_headers(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
cfaccount = self.controller.create_account(
cfaccount = self.controller.create_user(
'test', 'tester', 'testing',).split('/')[-1]
res = self.controller.handle_auth(Request.blank('/v1/test/auth',
environ={'REQUEST_METHOD': 'GET'},
@ -368,7 +368,7 @@ class TestAuthServer(unittest.TestCase):
def test_auth_Mosso_missing_headers(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
cfaccount = self.controller.create_account(
cfaccount = self.controller.create_user(
'test', 'tester', 'testing').split('/')[-1]
res = self.controller.handle_auth(Request.blank('/auth',
environ={'REQUEST_METHOD': 'GET'}))
@ -384,7 +384,7 @@ class TestAuthServer(unittest.TestCase):
def test_auth_Mosso_bad_header_format(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
cfaccount = self.controller.create_account(
cfaccount = self.controller.create_user(
'test', 'tester', 'testing').split('/')[-1]
res = self.controller.handle_auth(Request.blank('/auth',
environ={'REQUEST_METHOD': 'GET'},
@ -399,7 +399,7 @@ class TestAuthServer(unittest.TestCase):
def test_auth_Mosso_bad_account(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
cfaccount = self.controller.create_account(
cfaccount = self.controller.create_user(
'test', 'tester', 'testing').split('/')[-1]
res = self.controller.handle_auth(Request.blank('/auth',
environ={'REQUEST_METHOD': 'GET'},
@ -414,7 +414,7 @@ class TestAuthServer(unittest.TestCase):
def test_auth_Mosso_bad_user(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
cfaccount = self.controller.create_account(
cfaccount = self.controller.create_user(
'test', 'tester', 'testing').split('/')[-1]
res = self.controller.handle_auth(Request.blank('/auth',
environ={'REQUEST_METHOD': 'GET'},
@ -429,7 +429,7 @@ class TestAuthServer(unittest.TestCase):
def test_auth_Mosso_bad_password(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
cfaccount = self.controller.create_account(
cfaccount = self.controller.create_user(
'test', 'tester', 'testing').split('/')[-1]
res = self.controller.handle_auth(Request.blank('/auth',
environ={'REQUEST_METHOD': 'GET'},
@ -444,7 +444,7 @@ class TestAuthServer(unittest.TestCase):
def test_auth_Mosso_good(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
cfaccount = self.controller.create_account(
cfaccount = self.controller.create_user(
'test', 'tester', 'testing').split('/')[-1]
res = self.controller.handle_auth(Request.blank('/auth',
environ={'REQUEST_METHOD': 'GET'},
@ -456,7 +456,7 @@ class TestAuthServer(unittest.TestCase):
def test_auth_Mosso_good_SOSO_header_names(self):
auth_server.http_connect = fake_http_connect(201, 201, 201)
cfaccount = self.controller.create_account(
cfaccount = self.controller.create_user(
'test', 'tester', 'testing').split('/')[-1]
res = self.controller.handle_auth(Request.blank('/auth',
environ={'REQUEST_METHOD': 'GET'},
@ -473,9 +473,9 @@ class TestAuthServer(unittest.TestCase):
logger.logger.addHandler(log_handler)
try:
auth_server.http_connect = fake_http_connect(201, 201, 201)
url = self.controller.create_account('test', 'tester', 'testing')
url = self.controller.create_user('test', 'tester', 'testing')
self.assertEquals(log.getvalue().rsplit(' ', 1)[0],
"auth SUCCESS create_account('test', 'tester', _, False) = %s"
"auth SUCCESS create_user('test', 'tester', _, False) = %s"
% repr(url))
log.truncate(0)
def start_response(*args):