Merge lp:~adamhjk/swift/lp607912 into lp:~hudson-openstack/swift/trunk

Proposed by Adam Jacob
Status: Work in progress
Proposed branch: lp:~adamhjk/swift/lp607912
Merge into: lp:~hudson-openstack/swift/trunk
Diff against target: 76 lines (+36/-8)
2 files modified
swift/auth/server.py (+28/-7)
test/unit/auth/test_server.py (+8/-1)
To merge this branch: bzr merge lp:~adamhjk/swift/lp607912
Reviewer Review Type Date Requested Status
Swift Core security contacts Pending
Review via email: mp+30588@code.launchpad.net

Description of the change

Fixes lp:607912. We now do a SELECT to find out if we have an account with the matching username - if we do, we grab the cfaccount hash from that row, and re-use it when we update the record. The corresponding INSERT is changed to an INSERT OR REPLACE, which will ensure that repeat creations of the same user with a new password will get the correct behavior.

To post a comment you must log in.
lp:~adamhjk/swift/lp607912 updated
37. By Adam Jacob <adam@latte>

Removing errant debug statement

Revision history for this message
Chuck Thier (cthier) wrote :

Hey Adam,

I just tested this, and creating the same user still adds extra entries in the db:

cthier@swiftchuck:~/swift/lp607912$ swift-auth-create-account test tester testing
http://127.0.0.1:8080/v1/4db8017a-68d1-485a-98dd-b94785a2f855
cthier@swiftchuck:~/swift/lp607912$ swift-auth-create-account test tester testing
http://127.0.0.1:8080/v1/4db8017a-68d1-485a-98dd-b94785a2f855
cthier@swiftchuck:~/swift/lp607912$ swift-auth-create-account test tester testing2
http://127.0.0.1:8080/v1/4db8017a-68d1-485a-98dd-b94785a2f855
cthier@swiftchuck:~/swift/lp607912$ sqlite3 /etc/swift/auth.db
SQLite version 3.6.22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select * from account;
test|http://127.0.0.1:8080/v1/4db8017a-68d1-485a-98dd-b94785a2f855|4db8017a-68d1-485a-98dd-b94785a2f855|tester|testing
test|http://127.0.0.1:8080/v1/4db8017a-68d1-485a-98dd-b94785a2f855|4db8017a-68d1-485a-98dd-b94785a2f855|tester|testing
test|http://127.0.0.1:8080/v1/4db8017a-68d1-485a-98dd-b94785a2f855|4db8017a-68d1-485a-98dd-b94785a2f855|tester|testing2

I think that the "INSERT OR REPLACE" sql isn't working the way you are expecting to. I wold recommend doing an "UPDATE" instead if it finds the account_hash.

Revision history for this message
Adam Jacob (adamhjk) wrote :

Ah, yeah, I should look at the schema. I'll fox.

Sent from my iPhone

On Jul 21, 2010, at 7:41 PM, Chuck Thier <email address hidden> wrote:

> Hey Adam,
>
> I just tested this, and creating the same user still adds extra entries in the db:
>
> cthier@swiftchuck:~/swift/lp607912$ swift-auth-create-account test tester testing
> http://127.0.0.1:8080/v1/4db8017a-68d1-485a-98dd-b94785a2f855
> cthier@swiftchuck:~/swift/lp607912$ swift-auth-create-account test tester testing
> http://127.0.0.1:8080/v1/4db8017a-68d1-485a-98dd-b94785a2f855
> cthier@swiftchuck:~/swift/lp607912$ swift-auth-create-account test tester testing2
> http://127.0.0.1:8080/v1/4db8017a-68d1-485a-98dd-b94785a2f855
> cthier@swiftchuck:~/swift/lp607912$ sqlite3 /etc/swift/auth.db
> SQLite version 3.6.22
> Enter ".help" for instructions
> Enter SQL statements terminated with a ";"
> sqlite> select * from account;
> test|http://127.0.0.1:8080/v1/4db8017a-68d1-485a-98dd-b94785a2f855|4db8017a-68d1-485a-98dd-b94785a2f855|tester|testing
> test|http://127.0.0.1:8080/v1/4db8017a-68d1-485a-98dd-b94785a2f855|4db8017a-68d1-485a-98dd-b94785a2f855|tester|testing
> test|http://127.0.0.1:8080/v1/4db8017a-68d1-485a-98dd-b94785a2f855|4db8017a-68d1-485a-98dd-b94785a2f855|tester|testing2
>
> I think that the "INSERT OR REPLACE" sql isn't working the way you are expecting to. I wold recommend doing an "UPDATE" instead if it finds the account_hash.
>
> --
> https://code.launchpad.net/~adamhjk/swift/lp607912/+merge/30588
> You are the owner of lp:~adamhjk/swift/lp607912.

lp:~adamhjk/swift/lp607912 updated
38. By Adam Jacob <adam@latte>

Moving to direct INSERT or UPDATE

Unmerged revisions

38. By Adam Jacob <adam@latte>

Moving to direct INSERT or UPDATE

37. By Adam Jacob <adam@latte>

Removing errant debug statement

36. By Adam Jacob <adam@latte>

Re-creates existing users on multiple calls - fixes lp:607912

35. By Adam Jacob <adam@latte>

Adding test for existing account behavior

34. By Adam Jacob <adam@latte>

Select first to preserve the account hash

33. By Adam Jacob <adam@latte>

Creating users with INSERT OR REPLACE

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'swift/auth/server.py'
2--- swift/auth/server.py 2010-07-25 16:15:40 +0000
3+++ swift/auth/server.py 2010-07-26 17:48:48 +0000
4@@ -254,12 +254,27 @@
5 :param new_user: The name for the new user
6 :param new_password: The password for the new account
7
8- :returns: False if the create fails, storage url if successful
9+ :returns: False if the create fails or the user exists, storage url if successful
10 """
11 begin = time()
12 if not all((new_account, new_user, new_password)):
13 return False
14- account_hash = self.add_storage_account()
15+
16+ account_hash = False
17+ update_or_insert = "insert"
18+ with self.get_conn() as conn:
19+ row = conn.execute('''SELECT cfaccount FROM account WHERE
20+ account = ? AND user = ?''',
21+ (new_account, new_user)).fetchone()
22+ if row:
23+ update_or_insert = "update"
24+ account_hash = row[0]
25+
26+ if not account_hash:
27+ account_hash = self.add_storage_account()
28+ else:
29+ account_hash = self.add_storage_account(account_hash)
30+
31 if not account_hash:
32 self.logger.info(
33 'FAILED create_account(%s, %s, _,) [%.02f]' %
34@@ -267,11 +282,17 @@
35 return False
36 url = self.default_cluster_url.rstrip('/') + '/' + account_hash
37 with self.get_conn() as conn:
38- conn.execute('''INSERT INTO account
39- (account, url, cfaccount, user, password)
40- VALUES (?, ?, ?, ?, ?)''',
41- (new_account, url, account_hash, new_user, new_password))
42- conn.commit()
43+ if update_or_insert == "insert":
44+ conn.execute('''INSERT INTO account
45+ (account, url, cfaccount, user, password)
46+ VALUES (?, ?, ?, ?, ?)''',
47+ (new_account, url, account_hash, new_user, new_password))
48+ conn.commit()
49+ elif update_or_insert == "update":
50+ conn.execute('''UPDATE account SET password = ?
51+ WHERE account = ? AND user = ?''',
52+ (new_password, new_account, new_user))
53+ conn.commit()
54 self.logger.info(
55 'SUCCESS create_account(%s, %s, _) = %s [%.02f]' %
56 (repr(new_account), repr(new_user), repr(url), time() - begin))
57
58=== modified file 'test/unit/auth/test_server.py'
59--- test/unit/auth/test_server.py 2010-07-19 16:25:18 +0000
60+++ test/unit/auth/test_server.py 2010-07-26 17:48:48 +0000
61@@ -181,7 +181,14 @@
62 url = self.controller.create_account('test', 'tester', 'testing')
63 self.assert_(url)
64 self.assertEquals('/'.join(url.split('/')[:-1]),
65- self.controller.default_cluster_url.rstrip('/'), repr(url))
66+ self.controller.default_cluster_url.rstrip('/'), repr(url))
67+
68+ def test_create_account_already_exists(self):
69+ auth_server.http_connect = fake_http_connect(201, 201, 201)
70+ first_url = self.controller.create_account('test', 'tester', 'testing')
71+ auth_server.http_connect = fake_http_connect(201, 201, 201)
72+ second_url = self.controller.create_account('test', 'tester', 'testily')
73+ self.assertEquals(first_url, second_url)
74
75 def test_recreate_accounts_none(self):
76 auth_server.http_connect = fake_http_connect(201, 201, 201)