Merge lp:~facundo/canonical-identity-provider/refuse-refresh-password-changed into lp:canonical-identity-provider/release

Proposed by Facundo Batista
Status: Merged
Approved by: Facundo Batista
Approved revision: no longer in the source branch.
Merged at revision: 1418
Proposed branch: lp:~facundo/canonical-identity-provider/refuse-refresh-password-changed
Merge into: lp:canonical-identity-provider/release
Prerequisite: lp:~facundo/canonical-identity-provider/add-password-changed-timestamp
Diff against target: 74 lines (+29/-3)
2 files modified
src/identityprovider/auth.py (+10/-3)
src/identityprovider/tests/test_auth.py (+19/-0)
To merge this branch: bzr merge lp:~facundo/canonical-identity-provider/refuse-refresh-password-changed
Reviewer Review Type Date Requested Status
Matias Bordese (community) Approve
Daniel Manrique (community) Approve
Review via email: mp+289938@code.launchpad.net

Commit message

Check if account's password changed before refreshing the macaroon.

Description of the change

Check if account's password changed before refreshing the macaroon.

To post a comment you must log in.
Revision history for this message
Daniel Manrique (roadmr) wrote :

The test, I think, is not really doing what we expect it to do. See longish comment below and I think we have some fixing to do :(

review: Needs Fixing
Revision history for this message
Matias Bordese (matiasb) :
Revision history for this message
Facundo Batista (facundo) wrote :

Answered a comment, pushed the fix for the other.

Revision history for this message
Daniel Manrique (roadmr) wrote :

Looks OK to me, Matías suggested another way to achieve the None value using update(), your choice on which one to use.

I'd still prefer a more explicit check than "just run this and ensure it didn't exception out" but am OK if you think this is reasonable.

I'll +1 in case you want to merge as is, or if you want to apply the update() change.

review: Approve
Revision history for this message
Daniel Manrique (roadmr) wrote :

Thanks for the assert.

review: Approve
Revision history for this message
Matias Bordese (matiasb) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/identityprovider/auth.py'
2--- src/identityprovider/auth.py 2016-03-22 14:04:53 +0000
3+++ src/identityprovider/auth.py 2016-03-23 18:07:17 +0000
4@@ -46,6 +46,8 @@
5
6 logger = logging.getLogger(__name__)
7
8+MACAROON_TIMESTAMP_FORMAT = '%Y-%m-%dT%H:%M:%S.%f'
9+
10
11 class BCrypt13PasswordHasher(BCryptPasswordHasher):
12 rounds = 13
13@@ -541,12 +543,12 @@
14 d.add_first_party_caveat(service_location + '|account|' + account_info)
15
16 # add timestamp values
17- now_string = now().strftime('%Y-%m-%dT%H:%M:%S.%f')
18+ now_string = now().strftime(MACAROON_TIMESTAMP_FORMAT)
19 if last_auth is None:
20 last_auth = now_string
21 if expires is None:
22 expires_ts = now() + datetime.timedelta(seconds=settings.MACAROON_TTL)
23- expires = expires_ts.strftime('%Y-%m-%dT%H:%M:%S.%f')
24+ expires = expires_ts.strftime(MACAROON_TIMESTAMP_FORMAT)
25
26 d.add_first_party_caveat(service_location + '|valid_since|' + now_string)
27 d.add_first_party_caveat(service_location + '|last_auth|' + last_auth)
28@@ -608,10 +610,15 @@
29 except:
30 raise AuthenticationError("Not verifying macaroons")
31
32- # verify that the account is still fine
33+ # verify that the account is still active and password didn't change
34 account = Account.objects.active_by_openid(info_holder['openid'])
35 if account is None:
36 raise AccountDeactivated()
37+ if account.accountpassword.date_changed is not None:
38+ last_auth_ts = datetime.datetime.strptime(info_holder['last_auth'],
39+ MACAROON_TIMESTAMP_FORMAT)
40+ if account.accountpassword.date_changed > last_auth_ts:
41+ raise AuthenticationError("Password changed")
42
43 # create the new discharge macaroon with same location, key and
44 # identifier than it's original 3rd-party caveat (so they can
45
46=== modified file 'src/identityprovider/tests/test_auth.py'
47--- src/identityprovider/tests/test_auth.py 2016-03-22 19:47:29 +0000
48+++ src/identityprovider/tests/test_auth.py 2016-03-23 18:07:17 +0000
49@@ -1161,6 +1161,25 @@
50 self.root_macaroon.serialize(),
51 self.discharge_macaroon.serialize())
52
53+ def test_password_changed(self):
54+ self.account.set_password("a new password")
55+ self.assertRaises(AuthenticationError, refresh_macaroons,
56+ self.root_macaroon.serialize(),
57+ self.discharge_macaroon.serialize())
58+
59+ def test_password_with_no_datetime(self):
60+ # simulate an "old" account password (before we started to keep the
61+ # changed date); note that I'm bypassing the AccountPassword save(),
62+ # which will update the attribute that I want in Null! (and we confirm
63+ # that in the assert)
64+ self.account.accountpassword.date_changed = None
65+ super(AccountPassword, self.account.accountpassword).save()
66+ assert self.account.accountpassword.date_changed is None
67+
68+ # check that auths ok
69+ refresh_macaroons(self.root_macaroon.serialize(),
70+ self.discharge_macaroon.serialize())
71+
72 def test_proper_refreshing(self):
73 old_discharge = self.discharge_macaroon # just rename for readability
74 service_location = settings.MACAROON_SERVICE_LOCATION