|
12 | 12 |
|
13 | 13 | import datetime
|
14 | 14 |
|
| 15 | +from pyblake2 import blake2b |
15 | 16 | from pyramid.httpexceptions import HTTPMovedPermanently, HTTPSeeOther
|
16 | 17 | from pyramid.security import remember, forget
|
17 | 18 | from pyramid.view import view_config
|
|
25 | 26 | from warehouse.utils.http import is_safe_url
|
26 | 27 |
|
27 | 28 |
|
| 29 | +USER_ID_INSECURE_COOKIE = "user_id__insecure" |
| 30 | + |
| 31 | + |
28 | 32 | @view_config(
|
29 | 33 | route_name="accounts.profile",
|
30 | 34 | renderer="accounts/profile.html",
|
@@ -91,7 +95,23 @@ def login(request, redirect_field_name=REDIRECT_FIELD_NAME,
|
91 | 95 |
|
92 | 96 | # Now that we're logged in we'll want to redirect the user to either
|
93 | 97 | # where they were trying to go originally, or to the default view.
|
94 |
| - return HTTPSeeOther(redirect_to, headers=dict(headers)) |
| 98 | + resp = HTTPSeeOther(redirect_to, headers=dict(headers)) |
| 99 | + |
| 100 | + # We'll use this cookie so that client side javascript can Determine |
| 101 | + # the actual user ID (not username, user ID). This is *not* a security |
| 102 | + # sensitive context and it *MUST* not be used where security matters. |
| 103 | + # |
| 104 | + # We'll also hash this value just to avoid leaking the actual User IDs |
| 105 | + # here, even though it really shouldn't matter. |
| 106 | + resp.set_cookie( |
| 107 | + USER_ID_INSECURE_COOKIE, |
| 108 | + blake2b( |
| 109 | + str(userid).encode("ascii"), |
| 110 | + person=b"warehouse.userid", |
| 111 | + ).hexdigest().lower(), |
| 112 | + ) |
| 113 | + |
| 114 | + return resp |
95 | 115 |
|
96 | 116 | return {
|
97 | 117 | "form": form,
|
@@ -141,7 +161,13 @@ def logout(request, redirect_field_name=REDIRECT_FIELD_NAME):
|
141 | 161 |
|
142 | 162 | # Now that we're logged out we'll want to redirect the user to either
|
143 | 163 | # where they were originally, or to the default view.
|
144 |
| - return HTTPSeeOther(redirect_to, headers=dict(headers)) |
| 164 | + resp = HTTPSeeOther(redirect_to, headers=dict(headers)) |
| 165 | + |
| 166 | + # Ensure that we delete our user_id__insecure cookie, since the user is |
| 167 | + # no longer logged in. |
| 168 | + resp.delete_cookie(USER_ID_INSECURE_COOKIE) |
| 169 | + |
| 170 | + return resp |
145 | 171 |
|
146 | 172 | return {"redirect": {"field": REDIRECT_FIELD_NAME, "data": redirect_to}}
|
147 | 173 |
|
@@ -213,7 +239,7 @@ def _login_user(request, userid):
|
213 | 239 | request.session.update(data)
|
214 | 240 |
|
215 | 241 | # Remember the userid using the authentication policy.
|
216 |
| - headers = remember(request, userid) |
| 242 | + headers = remember(request, str(userid)) |
217 | 243 |
|
218 | 244 | # Cycle the CSRF token since we've crossed an authentication boundary
|
219 | 245 | # and we don't want to continue using the old one.
|
|
0 commit comments