Example #1
0
    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)
Example #2
0
    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)
Example #3
0
    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)
Example #4
0
    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)
Example #5
0
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)
Example #6
0
    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)
Example #7
0
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)
Example #8
0
    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))
Example #9
0
    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))
Example #10
0
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)
Example #11
0
    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)