0001-misc-fix-locking-in-clean_nonces-47122.patch
tests/test_api.py | ||
---|---|---|
296 | 296 |
assert [x['slug'] for x in output.json['user_roles']] == ['foo-bar'] |
297 | 297 | |
298 | 298 | |
299 |
def test_is_url_signed_check_nonce(pub, local_user): |
|
299 |
def test_is_url_signed_check_nonce(pub, local_user, freezer):
|
|
300 | 300 |
ORIG = 'xxx' |
301 | 301 |
KEY = 'xxx' |
302 | 302 | |
... | ... | |
306 | 306 |
# test clean_nonces do not bark when nonces directory is empty |
307 | 307 |
if os.path.exists(os.path.join(pub.app_dir, 'nonces')): |
308 | 308 |
shutil.rmtree(os.path.join(pub.app_dir, 'nonces')) |
309 |
pub.clean_nonces() |
|
309 |
pub.clean_nonces(now=0) |
|
310 |
nonce_dir = os.path.join(pub.app_dir, 'nonces') |
|
311 |
assert not os.path.exists(nonce_dir) or not os.listdir(nonce_dir) |
|
310 | 312 |
signed_url = sign_url('?format=json&orig=%s&email=%s' |
311 | 313 |
% (ORIG, urllib.quote(local_user.email)), KEY) |
312 | 314 |
req = HTTPRequest(None, {'SCRIPT_NAME': '/', |
... | ... | |
322 | 324 |
is_url_signed() |
323 | 325 |
assert exc_info.value.public_msg == 'nonce already used' |
324 | 326 |
# test that clean nonces works |
325 |
assert os.listdir(os.path.join(pub.app_dir, 'nonces')) |
|
326 |
pub.clean_nonces(delta=0) |
|
327 |
assert os.listdir(os.path.join(pub.app_dir, 'nonces')) |
|
328 |
pub.clean_nonces(delta=0, now=time.time() + 2 * DEFAULT_DURATION) |
|
329 |
assert not os.listdir(os.path.join(pub.app_dir, 'nonces')) |
|
327 |
pub.clean_nonces() |
|
328 |
assert os.listdir(nonce_dir) |
|
329 | ||
330 |
# 80 seconds in the future, nothing should be cleaned |
|
331 |
freezer.move_to(datetime.timedelta(seconds=80)) |
|
332 |
pub.clean_nonces() |
|
333 |
assert os.listdir(nonce_dir) |
|
334 | ||
335 |
# 90 seconds in the future, nonces should be removed |
|
336 |
freezer.move_to(datetime.timedelta(seconds=10)) |
|
337 |
pub.clean_nonces() |
|
338 |
assert not os.listdir(nonce_dir) |
|
330 | 339 | |
331 | 340 | |
332 | 341 |
def test_get_user_compat_endpoint(pub, local_user): |
wcs/qommon/publisher.py | ||
---|---|---|
62 | 62 |
import logging.handlers |
63 | 63 |
from . import logger |
64 | 64 |
from . import storage |
65 |
from .vendor import locket |
|
65 | 66 | |
66 | 67 | |
67 | 68 |
class ImmediateRedirectException(Exception): |
... | ... | |
571 | 572 | |
572 | 573 |
def clean_nonces(self, delta=60, now=None): |
573 | 574 |
nonce_dir = os.path.join(get_publisher().app_dir, 'nonces') |
574 |
now = now or time.time() |
|
575 | 575 |
if not os.path.exists(nonce_dir): |
576 | 576 |
return |
577 | 577 |
cleaning_lock_file = os.path.join(self.app_dir, 'cleaning_nonces.lock') |
578 |
fd = os.open(cleaning_lock_file, os.O_RDONLY | os.O_CREAT, 0o666) |
|
579 | 578 |
try: |
580 |
fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB) |
|
581 |
except IOError: |
|
582 |
# lock is currently held, that is fine. |
|
583 |
return |
|
584 |
try: |
|
585 |
for nonce in os.listdir(nonce_dir): |
|
586 |
nonce_path = os.path.join(nonce_dir, nonce) |
|
587 |
# we need delta so that os.utime in is_url_signed has time to update file timestamp |
|
588 |
if delta < now - os.stat(nonce_path)[8]: |
|
589 |
os.unlink(nonce_path) |
|
590 |
finally: |
|
591 |
os.close(fd) |
|
579 |
now = now or time.time() |
|
580 |
with locket.lock_file(cleaning_lock_file, timeout=0): |
|
581 |
for nonce in os.listdir(nonce_dir): |
|
582 |
nonce_path = os.path.join(nonce_dir, nonce) |
|
583 |
# we need delta so that os.utime in is_url_signed has time to update file timestamp |
|
584 |
if delta < now - os.stat(nonce_path)[8]: |
|
585 |
os.unlink(nonce_path) |
|
586 |
except locket.LockError: |
|
587 |
pass |
|
592 | 588 | |
593 | 589 |
def clean_sessions(self): |
594 | 590 |
cleaning_lock_file = os.path.join(self.app_dir, 'cleaning_sessions.lock') |
595 |
- |