def _set_quota(size): class FakeReq: host = "localhost" req = FakeReq() app = get_app(self.app) app.get_storage(req).quota_size = size
def test_password_reset_direct(self): # trying to call password reset with an unknown user captcha = 'captcha-challenge=x&captcha-response=y' res = self.app.get('/user/1.0/a/password_reset?%s' % captcha, status=400) self.assertEquals(res.json, ERROR_INVALID_USER) # now calling with the right user, but he has no email app = get_app(self.app) def _get_user_info(*args): return 'ok', None old = app.auth.backend.get_user_info app.auth.backend.get_user_info = _get_user_info try: res = self.app.get(self.root + '/password_reset?%s' % captcha, status=400) self.assertEquals(res.json, ERROR_NO_EMAIL_ADDRESS) finally: app.auth.backend.get_user_info = old # now a legitimate call res = self.app.get(self.root + '/password_reset?%s' % captcha) self.assertEqual(res.body, 'success')
def test_force_reset(self): captcha = 'captcha-challenge=x&captcha-response=y' res = self.app.get(self.root + '/password_reset?%s' % captcha) self.assertEquals(res.body, 'success') self.assertEquals(len(FakeSMTP.msgs), 1) app = get_app(self.app) # let's ask via the web form now # the Python web form does not support captcha old = app.config['captcha.use'] app.config['captcha.use'] = False try: res = self.app.get('/weave-password-reset') res.form['username'].value = self.user_name res = res.form.submit() self.assertTrue('next 6 hours' in res) self.assertEquals(len(FakeSMTP.msgs), 2) finally: app.config['captcha.use'] = old # let's cancel via the API url = self.root + '/password_reset' if app.config['captcha.use']: url += '?captcha-challenge=xxx&captcha-response=xxx' res = self.app.delete(url) self.assertEquals(res.body, 'success')
def test_reset_email(self): app = get_app(self.app) # let's ask via the web form now # the Python web form does not support captcha old = app.config['captcha.use'] app.config['captcha.use'] = False try: # let's try the reset process with an email user_name = extract_username('*****@*****.**') self.auth.create_user(user_name, self.password, '*****@*****.**') res = self.app.get('/weave-password-reset') res.form['username'].value = '*****@*****.**' res = res.form.submit() self.assertTrue('next 6 hours' in res) self.assertEquals(len(FakeSMTP.msgs), 1) # let's visit the link in the email msg = message_from_string(FakeSMTP.msgs[0][2]).get_payload() msg = base64.decodestring(msg) link = msg.split('\n')[2].strip() # let's call the real link, it's a form we can fill res = self.app.get(link) res.form['password'].value = 'mynewpassword' res.form['confirm'].value = 'mynewpassword' res = res.form.submit() self.assertTrue('Password successfully changed' in res) finally: app.config['captcha.use'] = old
def _set_quota(size): class FakeReq: host = 'localhost' req = FakeReq() app = get_app(self.app) app.get_storage(req).quota_size = size
def test_blacklisted_nodes(self): app = get_app(self.app) old = app.config.get("storage.check_blacklisted_nodes", False) app.config["storage.check_blacklisted_nodes"] = True try: if app.cache is None: return # memcached is probably not installed if not app.cache.set("TEST", 1): return # memcached server is probably down # "backoff:server" will add a X-Weave-Backoff header app.cache.set("backoff:localhost:80", 2) try: resp = self.app.get(self.root + "/info/collections") self.assertEquals(resp.headers["X-Weave-Backoff"], "2") finally: app.cache.delete("backoff:localhost:80") # "down:server" will make the node unavailable app.cache.set("down:localhost:80", 1) try: resp = self.app.get(self.root + "/info/collections", status=503) self.assertTrue("Server Problem Detected" in resp.body) finally: app.cache.delete("down:localhost:80") finally: app.config["storage.check_blacklisted_nodes"] = old
def test_batch_size(self): # This can't be run against a live server. if self.distant: raise SkipTest # check that the batch size is correctly set size = get_app(self.app).controllers['storage'].batch_size self.assertEqual(size, 25)
def test_fallback_node(self): app = get_app(self.app) proxy = app.controllers['user'].fallback_node = 'http://myhappy/proxy/' url = '/user/1.0/%s/node/weave' % self.user_name res = self.app.get(url) self.assertEqual(res.body, proxy) app.controllers['user'].fallback_node = None res = self.app.get(url) self.assertEqual(res.body, 'null')
def test_fallback_node(self): app = get_app(self.app) # With explicitly-set fallback node and no assignment backend, # should return the fallback value. proxy = app.controllers['user'].fallback_node = 'http://myhappy/proxy/' url = '/user/1.0/%s/node/weave' % self.user_name res = self.app.get(url) self.assertEqual(res.body, proxy) # With no fallback node, should return a 503. app.controllers['user'].fallback_node = None res = self.app.get(url, status=503)
def test_write_tabs_503(self): # This can't be run against a live server. if self.distant: raise SkipTest # make sure a tentative to write in tabs w/ memcached leads to a 503 try: from syncstorage.storage.memcachedsql import MemcachedSQLStorage except ImportError: raise SkipTest class BadCache(object): def incr(*args, **kw): return False def set(*args, **kw): pass def delete(*args, **kw): pass def get(*args, **kw): return None def set_tabs(*args, **kw): raise BackendError() app = get_app(self.app) fd, dbfile = mkstemp() os.close(fd) orig_storage = app.storages['default'] try: storage = MemcachedSQLStorage('sqlite:///%s' % dbfile) storage.cache = BadCache() app.storages['default'] = storage # send two wbos in the 'tabs' collection wbo1 = {'id': 'sure', 'payload': _PLD} wbo2 = {'id': 'thing', 'payload': _PLD} wbos = [wbo1, wbo2] # on batch, we get back a 200 - but only failures res = self.app.post_json(self.root + '/storage/tabs', wbos) self.assertEqual(len(res.json['failed']), 2) self.assertEqual(len(res.json['success']), 0) # on single PUT, we get a 503 self.app.put_json(self.root + '/storage/tabs/sure', wbo1, status=503) finally: app.storages['default'] = orig_storage os.remove(dbfile)
def test_debug_screen(self): # deactivated by default self.app.get(self.root + "/__debug__", status=404) # let's activate it app = get_app(self.app) app.debug_page = "__debug__" # what do we have ? res = self.app.get("/__debug__") self.assertTrue("- backend: sql" in res.body)
def test_debug_screen(self): # This can't be run against a live server. if self.distant: raise SkipTest # deactivated by default self.app.get(self.root + '/__debug__', status=404) # let's activate it app = get_app(self.app) app.debug_page = '__debug__' # what do we have ? res = self.app.get('/__debug__') self.assertTrue('- backend: sql' in res.body)
def test_prevent_bad_node(self): app = get_app(self.app) old_auth = app.auth.backend.get_user_id def _get_id(*args): raise BackendError() app.auth.backend.get_user_id = _get_id try: self.app.get('/user/1.0/%s/node/weave' % self.user_name, status=503) finally: app.auth.backend.get_user_id = old_auth
def esting_proxy(self): # XXX crazy dive into the middleware stack app = get_app(self.app) app.config['auth.proxy'] = True app.config['auth.proxy_scheme'] = 'http' app.config['auth.proxy_location'] = 'localhost:5000' # these tests should work fine with a proxy config res = self.app.get('/user/1.0/randomdude') if not json.loads(res.body): self.app.delete('/user/1.0/randomdude') self.test_create_user('randomdude')
def test_write_tabs_503(self): # make sure a tentative to write in tabs w/ memcached leads to a 503 try: from syncstorage.storage.memcachedsql import MemcachedSQLStorage except ImportError: return class BadCache(object): def incr(*args, **kw): return False def set(*args, **kw): pass def delete(*args, **kw): pass def get(*args, **kw): return None def set_tabs(*args, **kw): raise BackendError() app = get_app(self.app) fd, dbfile = mkstemp() os.close(fd) try: storage = MemcachedSQLStorage("sqlite:///%s" % dbfile) storage.cache = BadCache() app.storages["default"] = storage # send two wbos in the 'tabs' collection wbo1 = {"id": "sure", "payload": _PLD} wbo2 = {"id": "thing", "payload": _PLD} wbos = json.dumps([wbo1, wbo2]) # on batch, we get back a 200 - but only failures res = self.app.post(self.root + "/storage/tabs", params=wbos) self.assertEqual(len(res.json["failed"]), 2) self.assertEqual(len(res.json["success"]), 0) # on single PUT, we get a 503 wbo1 = json.dumps(wbo1) self.app.put(self.root + "/storage/tabs/sure", params=wbo1, status=503) finally: os.remove(dbfile)
def test_shared_secret(self): # creating a user email = '*****@*****.**' % (time.time(), random.randint(1, 100)) name = extract_username(email) user_url = '/user/1.0/%s' % name # we want the captcha to fail app = get_app(self.app) app.config['captcha.use'] = True def _failed(self, *args, **kw): return FakeCaptchaResponse(False) captcha.submit = _failed extra = {'X-Weave-Secret': 'xxx'} try: # everything is there, but bad secret. This should # fallback to the captcha test and eventually fail res = self.app.get(user_url) self.assertFalse(json.loads(res.body)) payload = {'email': email, 'password': '******' * 9} payload = json.dumps(payload) res = self.app.put(user_url, params=payload, headers=extra, status=400) self.assertEquals(res.json, ERROR_INVALID_CAPTCHA) # let's use the real secret extra['X-Weave-Secret'] = 'CHANGEME' res = self.app.put(user_url, params=payload, headers=extra) self.assertEquals(res.body, name) res = self.app.get(user_url) self.assertTrue(json.loads(res.body)) finally: self.auth.delete_user(User(name), 'x' * 9)
def test_recaptcha(self): # make sure the captcha is rendered when needed if not get_app(self.app).config['captcha.use']: self.app.get('/misc/1.0/captcha_html', status=404) else: self.app.get('/misc/1.0/captcha_html', status=200)
def test_node_assignment(self): app = get_app(self.app) app.controllers['user'].nodes = FakeNodesBackend("nodey-mcnode") url = '/user/1.0/%s/node/weave' % self.user_name res = self.app.get(url) self.assertEqual(res.body, "https://nodey-mcnode/")
def test_node_assignment_already_written(self): app = get_app(self.app) app.controllers['user'].nodes = FakeExistingNodesBackend("testnode") url = '/user/1.0/%s/node/weave' % self.user_name res = self.app.get(url) self.assertEqual(res.body, "https://testnode/")
def test_password_reset(self): # making sure a mail is sent captcha = 'captcha-challenge=x&captcha-response=y' res = self.app.get(self.root + '/password_reset?%s' % captcha) self.assertEquals(res.body, 'success') self.assertEquals(len(FakeSMTP.msgs), 1) # let's try some bad POSTs on weave-password-reset self.app.post('/weave-password-reset', params={'username': self.user_name, 'boo': 'foo'}, status=400) res = self.app.post('/weave-password-reset', params={'username': self.user_name, 'key': 'xxx', 'boo': 'foo'}) self.assertTrue('Password not provided' in res) # let's ask via the web form now app = get_app(self.app) # the Python web form does not support captcha old = app.config['captcha.use'] app.config['captcha.use'] = False try: res = self.app.get('/weave-password-reset') res.form['username'].value = self.user_name res = res.form.submit() self.assertTrue('next 6 hours' in res) self.assertEquals(len(FakeSMTP.msgs), 2) finally: app.config['captcha.use'] = old # let's visit the link in the email msg = message_from_string(FakeSMTP.msgs[1][2]).get_payload() msg = base64.decodestring(msg) link = msg.split('\n')[2].strip() # let's try some bad links (unknown user) badlink = link.replace(self.user_name, 'joe') res = self.app.get(badlink) res.form['password'].value = 'p' * 8 res.form['confirm'].value = 'p' * 8 res = res.form.submit() self.assertTrue('unable to locate your account' in res) badlink = link.replace('username=%s&' % self.user_name, '') res = self.app.get(badlink) res.form['password'].value = 'p' * 8 res.form['confirm'].value = 'p' * 8 res = res.form.submit() self.assertTrue('Username not provided' in res) # let's call the real link, it's a form we can fill # let's try bad values # mismatch res = self.app.get(link) res.form['password'].value = 'mynewpassword' res.form['confirm'].value = 'badconfirmation' res = res.form.submit() self.assertTrue('do not match' in res) # weak password res = self.app.get(link) res.form['password'].value = 'my' res.form['confirm'].value = 'my' res = res.form.submit() self.assertTrue('at least 8' in res) # wrong key if link[:-1] != 'X': res = self.app.get(link[:-1] + 'X') else: res = self.app.get(link[:-1] + 'Y') res.form['password'].value = 'mynewpassword' res.form['confirm'].value = 'mynewpassword' res = res.form.submit() self.assertTrue('Key does not match with username' in res) # all good res = self.app.get(link) res.form['password'].value = 'mynewpassword' res.form['confirm'].value = 'mynewpassword' res = res.form.submit() self.assertTrue('Password successfully changed' in res)
def test_node_assignment_failure(self): app = get_app(self.app) app.controllers['user'].nodes = FakeBrokenNodesBackend(RuntimeError) url = '/user/1.0/%s/node/weave' % self.user_name res = self.app.get(url) self.assertEqual(res.body, 'null')
def test_batch_size(self): # check that the batch size is correctly set size = get_app(self.app).controllers["storage"].batch_size self.assertEqual(size, 25)