def test_journalist_reply(self): # Submit the message through the source app test_msg = 'This msg is for your eyes only' res, codename = self._do_submission(msg=test_msg) # Wait until the source key has been generated... # (the reply form won't be available unless the key exists) source_id = crypto.shash(codename) while not crypto.getkey(source_id): sleep(0.1) # Check the journalist app for the submitted message res = self.journalist_app.get('/') soup = BeautifulSoup(res.normal_body) res = res.click(href=soup.li.a['href']) # Send a reply to the source test_reply = "Thanks for sharing this. We'll follow up soon." res.form.set('msg', test_reply) res = res.form.submit() self.assertIn("Thanks! Your reply has been stored.", res.normal_body) # Check the source page for a reply res = self.source_app.get('/lookup/') res.form.set('id', codename) res = res.form.submit() self.assertIn( "You have received a reply. For your security, please delete all replies when you're done with them.", res.normal_body) soup = BeautifulSoup(res.normal_body) message = soup.find_all('blockquote', class_='message')[0].text self.assertEquals(message, test_reply)
def test_journalist_reply(self): # Submit the message through the source app test_msg = 'This msg is for your eyes only' res, codename = self._do_submission(msg=test_msg) # Wait until the source key has been generated... # (the reply form won't be available unless the key exists) source_id = crypto.shash(codename) while not crypto.getkey(source_id): sleep(0.1) # Check the journalist app for the submitted message res = self.journalist_app.get('/') soup = BeautifulSoup(res.normal_body) res = res.click(href=soup.li.a['href']) # Send a reply to the source test_reply = "Thanks for sharing this. We'll follow up soon." res.form.set('msg', test_reply) res = res.form.submit() self.assertIn("Thanks! Your reply has been stored.", res.normal_body) # Check the source page for a reply res = self.source_app.get('/lookup/') res.form.set('id', codename) res = res.form.submit() self.assertIn("You have received a reply. For your security, please delete all replies when you're done with them.", res.normal_body) soup = BeautifulSoup(res.normal_body) message = soup.find_all('blockquote', class_='message')[0].text self.assertEquals(message, test_reply)
def POST(self): i = web.input('sid', 'msg') crypto.encrypt(crypto.getkey(i.sid), i.msg, output= store.path(i.sid, 'reply-%s.gpg' % time.time()) ) web.header('Cache-Control', 'no-cache, no-store, must-revalidate') web.header('Pragma', 'no-cache') web.header('Expires', '-1') return render.reply(i.sid)
def POST(self): i = web.input('sid', 'msg') crypto.encrypt(crypto.getkey(i.sid), i.msg, output=store.path(i.sid, 'reply-%s.gpg' % time.time())) web.header('Cache-Control', 'no-cache, no-store, must-revalidate') web.header('Pragma', 'no-cache') web.header('Expires', '-1') return render.reply(i.sid)
def store_endpoint(i): sid = crypto.shash(i.id) loc = store.path(sid) if not os.path.exists(loc): raise web.notfound() received = False if i.action == 'upload': if i.msg: loc1 = store.path(sid, '%.2f_msg.gpg' % (uuid.uuid4().int, )) crypto.encrypt(config.JOURNALIST_KEY, i.msg, loc1) received = 2 if not isinstance(i.fh, dict) and i.fh.done != -1 and i.fh.filename: # we put two zeroes here so that we don't save a file # with the same name as the message loc2 = store.path(sid, '%.2f_doc.zip.gpg' % (uuid.uuid4().int, )) s = cStringIO.StringIO() zip_file = zipfile.ZipFile(s, 'w') zip_file.writestr(i.fh.filename, i.fh.file.getvalue()) zip_file.close() s.reset() crypto.encrypt(config.JOURNALIST_KEY, s, loc2) received = i.fh.filename or '[unnamed]' if not crypto.getkey(sid): background.execute(lambda: crypto.genkeypair(sid, i.id)) elif i.action == 'delete': potential_files = os.listdir(loc) if i.mid not in potential_files: raise web.notfound() assert '/' not in i.mid crypto.secureunlink(store.path(sid, i.mid)) msgs = [] for fn in os.listdir(loc): if fn.startswith('reply-'): msgs.append( web.storage(id=fn, date=str( datetime.datetime.fromtimestamp( os.stat(store.path(sid, fn)).st_mtime)), msg=crypto.decrypt( sid, i.id, file(store.path(sid, fn)).read()))) web.header('Cache-Control', 'no-cache, no-store, must-revalidate') web.header('Pragma', 'no-cache') web.header('Expires', '-1') return render.lookup(i.id, msgs, received=received)
def POST(self): i = web.input('id', fh={}, msg=None, mid=None, action=None) sid = crypto.shash(i.id) loc = store.path(sid) if not os.path.exists(loc): raise web.notfound() received = False if i.action == 'upload': if i.msg: loc1 = store.path(sid, '%.2f_msg.gpg' % (uuid.uuid4().int, )) crypto.encrypt(config.JOURNALIST_KEY, i.msg, loc1) received = 2 if i.fh.value: # we put two zeroes here so that we don't save a file # with the same name as the message loc2 = store.path(sid, '%.2f_doc.gpg' % (uuid.uuid4().int, )) crypto.encrypt(config.JOURNALIST_KEY, i.fh.file, loc2, fn=i.fh.filename) received = i.fh.filename or '[unnamed]' if not crypto.getkey(sid): background.execute(lambda: crypto.genkeypair(sid, i.id)) elif i.action == 'delete': potential_files = os.listdir(loc) if i.mid not in potential_files: raise web.notfound() assert '/' not in i.mid crypto.secureunlink(store.path(sid, i.mid)) msgs = [] for fn in os.listdir(loc): if fn.startswith('reply-'): msgs.append( web.storage(id=fn, date=str( datetime.datetime.fromtimestamp( os.stat(store.path(sid, fn)).st_mtime)), msg=crypto.decrypt( sid, i.id, file(store.path(sid, fn)).read()))) web.header('Cache-Control', 'no-cache, no-store, must-revalidate') web.header('Pragma', 'no-cache') web.header('Expires', '-1') return render.lookup(i.id, msgs, received=received)
def store_endpoint(i): sid = crypto.shash(i.id) loc = store.path(sid) if not os.path.exists(loc): raise web.notfound() received = False if i.action == 'upload': if i.msg: loc1 = store.path(sid, '%.2f_msg.gpg' % (uuid.uuid4().int, )) crypto.encrypt(config.JOURNALIST_KEY, i.msg, loc1) received = 2 if not isinstance(i.fh, dict) and i.fh.done != -1 and i.fh.filename: # we put two zeroes here so that we don't save a file # with the same name as the message loc2 = store.path(sid, '%.2f_doc.zip.gpg' % (uuid.uuid4().int, )) s = cStringIO.StringIO() zip_file = zipfile.ZipFile(s, 'w') zip_file.writestr(i.fh.filename, i.fh.file.getvalue()) zip_file.close() s.reset() crypto.encrypt(config.JOURNALIST_KEY, s, loc2) received = i.fh.filename or '[unnamed]' if not crypto.getkey(sid): background.execute(lambda: crypto.genkeypair(sid, i.id)) elif i.action == 'delete': potential_files = os.listdir(loc) if i.mid not in potential_files: raise web.notfound() assert '/' not in i.mid crypto.secureunlink(store.path(sid, i.mid)) msgs = [] for fn in os.listdir(loc): if fn.startswith('reply-'): msgs.append(web.storage( id=fn, date=str(datetime.datetime.fromtimestamp(os.stat(store.path(sid, fn)).st_mtime)), msg=crypto.decrypt(sid, i.id, file(store.path(sid, fn)).read()) )) web.header('Cache-Control', 'no-cache, no-store, must-revalidate') web.header('Pragma', 'no-cache') web.header('Expires', '-1') return render.lookup(i.id, msgs, received=received)
def GET(self, sid): fns = os.listdir(store.path(sid)) docs = [] for f in fns: docs.append(web.storage( name=f, date=str(datetime.datetime.fromtimestamp(float(store.cleanname(f)))).split('.')[0] )) docs.sort(lambda x,y: cmp(x.date, y.date)) haskey = bool(crypto.getkey(sid)) web.header('Cache-Control', 'no-cache, no-store, must-revalidate') web.header('Pragma', 'no-cache') web.header('Expires', '-1') return render.col(docs, sid, haskey, codename=crypto.displayid(sid))
def GET(self, sid): fns = os.listdir(store.path(sid)) docs = [] for f in fns: docs.append(web.storage( name=f, date=str(datetime.datetime.fromtimestamp(os.stat(store.path(sid, f)).st_mtime)) )) docs.sort(lambda x,y: cmp(x.date, y.date)) haskey = bool(crypto.getkey(sid)) web.header('Cache-Control', 'no-cache, no-store, must-revalidate') web.header('Pragma', 'no-cache') web.header('Expires', '-1') return render.col(docs, sid, haskey, codename=crypto.displayid(sid))
def store_endpoint(i): sid = crypto.shash(i.id) loc = store.path(sid) if not os.path.exists(loc): raise web.notfound() received = False if i.action == "upload": if i.msg: loc1 = store.path(sid, "%.2f_msg.gpg" % (uuid.uuid4().int,)) crypto.encrypt(config.JOURNALIST_KEY, i.msg, loc1) received = 2 if not isinstance(i.fh, dict) and i.fh.done != -1 and i.fh.filename: # we put two zeroes here so that we don't save a file # with the same name as the message loc2 = store.path(sid, "%.2f_doc.gpg" % (uuid.uuid4().int,)) crypto.encrypt(config.JOURNALIST_KEY, i.fh.file, loc2, fn=i.fh.filename) received = i.fh.filename or "[unnamed]" if not crypto.getkey(sid): background.execute(lambda: crypto.genkeypair(sid, i.id)) elif i.action == "delete": potential_files = os.listdir(loc) if i.mid not in potential_files: raise web.notfound() assert "/" not in i.mid crypto.secureunlink(store.path(sid, i.mid)) msgs = [] for fn in os.listdir(loc): if fn.startswith("reply-"): msgs.append( web.storage( id=fn, date=str(datetime.datetime.fromtimestamp(os.stat(store.path(sid, fn)).st_mtime)), msg=crypto.decrypt(sid, i.id, file(store.path(sid, fn)).read()), ) ) web.header("Cache-Control", "no-cache, no-store, must-revalidate") web.header("Pragma", "no-cache") web.header("Expires", "-1") return render.lookup(i.id, msgs, received=received)
def POST(self): i = web.input('id', fh={}, msg=None, mid=None, action=None) sid = crypto.shash(i.id) loc = store.path(sid) if not os.path.exists(loc): raise web.notfound() received = False if i.action == 'upload': if i.msg: loc1 = store.path(sid, '%s_msg.gpg' % time.time()) crypto.encrypt(config.JOURNALIST_KEY, i.msg, loc1) received = 2 if i.fh.value: # we put two zeroes here so that we don't save a file # with the same name as the message loc2 = store.path(sid, '%s_doc.gpg' % time.time()) crypto.encrypt(config.JOURNALIST_KEY, i.fh.file, loc2, fn=i.fh.filename) received = i.fh.filename or '[unnamed]' if not crypto.getkey(sid): background.execute(lambda: crypto.genkeypair(sid, i.id)) elif i.action == 'delete': potential_files = os.listdir(loc) if i.mid not in potential_files: raise web.notfound() assert '/' not in i.mid crypto.secureunlink(store.path(sid, i.mid)) msgs = [] for fn in os.listdir(loc): if fn.startswith('reply-'): msgs.append(web.storage( id=fn, date=datetime.datetime.fromtimestamp(float(store.cleanname(fn))), msg=crypto.decrypt(sid, i.id, file(store.path(sid, fn)).read()) )) web.header('Cache-Control', 'no-cache, no-store, must-revalidate') web.header('Pragma', 'no-cache') web.header('Expires', '-1') return render.lookup(i.id, msgs, received=received)