예제 #1
0
def lookup():
    msgs = []
    flagged = False
    for fn in os.listdir(g.loc):
        if fn == '_FLAG':
            flagged = True
            continue
        if fn.startswith('reply-'):
            msgs.append(dict(
                id=fn,
                date=str(
                    datetime.fromtimestamp(
                        os.stat(store.path(g.sid, fn)).st_mtime)),
                msg=crypto_util.decrypt(
                    g.sid, g.codename, file(store.path(g.sid, fn)).read())
            ))
    if flagged:
        session['flagged'] = True

    def async_genkey(sid, codename):
        with app.app_context():
            background.execute(lambda: crypto_util.genkeypair(sid, codename))

    # Generate a keypair to encrypt replies from the journalist
    # Only do this if the journalist has flagged the source as one
    # that they would like to reply to. (Issue #140.)
    if not crypto_util.getkey(g.sid) and flagged:
        async_genkey(g.sid, g.codename)

    return render_template(
        'lookup.html', codename=g.codename, msgs=msgs, flagged=flagged,
        haskey=crypto_util.getkey(g.sid))
예제 #2
0
def lookup():
    replies = []
    for reply in g.source.replies:
        reply_path = store.path(g.filesystem_id, reply.filename)
        try:
            reply.decrypted = crypto_util.decrypt(
                g.codename,
                open(reply_path).read()).decode('utf-8')
        except UnicodeDecodeError:
            app.logger.error("Could not decode reply %s" % reply.filename)
        else:
            reply.date = datetime.utcfromtimestamp(
                os.stat(reply_path).st_mtime)
            replies.append(reply)

    # Sort the replies by date
    replies.sort(key=operator.attrgetter('date'), reverse=True)

    # Generate a keypair to encrypt replies from the journalist
    # Only do this if the journalist has flagged the source as one
    # that they would like to reply to. (Issue #140.)
    if not crypto_util.getkey(g.filesystem_id) and g.source.flagged:
        async_genkey(g.filesystem_id, g.codename)

    return render_template('lookup.html',
                           codename=g.codename,
                           replies=replies,
                           flagged=g.source.flagged,
                           haskey=crypto_util.getkey(g.filesystem_id))
예제 #3
0
def lookup():
    replies = []
    for fn in os.listdir(g.loc):
        if fn.startswith('reply-'):
            try:
                msg = crypto_util.decrypt(g.sid, g.codename,
                        file(store.path(g.sid, fn)).read()).decode("utf-8")
            except UnicodeDecodeError:
                app.logger.error("Could not decode reply %s" % fn)
            else:
                date = str(datetime.fromtimestamp(
                           os.stat(store.path(g.sid, fn)).st_mtime))
                replies.append(dict(id=fn, date=date, msg=msg))

    def async_genkey(sid, codename):
        with app.app_context():
            background.execute(lambda: crypto_util.genkeypair(sid, codename))

    # Generate a keypair to encrypt replies from the journalist
    # Only do this if the journalist has flagged the source as one
    # that they would like to reply to. (Issue #140.)
    if not crypto_util.getkey(g.sid) and g.source.flagged:
        async_genkey(g.sid, g.codename)

    return render_template('lookup.html', codename=g.codename, msgs=replies,
            flagged=g.source.flagged, haskey=crypto_util.getkey(g.sid))
예제 #4
0
    def test_encrypt_fingerprints_not_a_list_or_tuple(self):
        """If passed a single fingerprint as a string, encrypt should
        correctly place that string in a list, and encryption/
        decryption should work as intended."""
        source, codename = utils.db_helper.init_source()
        message = str(os.urandom(1))
        ciphertext = crypto_util.encrypt(
            message, crypto_util.getkey(source.filesystem_id),
            store.path(source.filesystem_id, 'somefile.gpg'))
        plaintext = crypto_util.decrypt(codename, ciphertext)

        self.assertEqual(message, plaintext)
예제 #5
0
    def test_encrypt_without_output(self):
        """We simply do not specify the option output keyword argument
        to crypto_util.encrypt() here in order to confirm encryption
        works when it defaults to `None`.
        """
        source, codename = utils.db_helper.init_source()
        message = str(os.urandom(1))
        ciphertext = crypto_util.encrypt(
            message,
            [crypto_util.getkey(source.filesystem_id), config.JOURNALIST_KEY])
        plaintext = crypto_util.decrypt(codename, ciphertext)

        self.assertEqual(message, plaintext)
예제 #6
0
    def test_basic_encrypt_then_decrypt_multiple_recipients(self):
        source, codename = utils.db_helper.init_source()
        message = str(os.urandom(1))
        ciphertext = crypto_util.encrypt(
            message,
            [crypto_util.getkey(source.filesystem_id), config.JOURNALIST_KEY],
            store.path(source.filesystem_id, 'somefile.gpg'))
        plaintext = crypto_util.decrypt(codename, ciphertext)

        self.assertEqual(message, plaintext)

        # Since there's no way to specify which key to use for
        # decryption to python-gnupg, we delete the `source`'s key and
        # ensure we can decrypt with the `config.JOURNALIST_KEY`.
        crypto_util.delete_reply_keypair(source.filesystem_id)
        plaintext_ = crypto_util.gpg.decrypt(ciphertext).data

        self.assertEqual(message, plaintext_)
예제 #7
0
def lookup():
    msgs = []
    flagged = False
    for fn in os.listdir(g.loc):
        # TODO: make 'flag' a db column, so we can replace this with a db
        # lookup in the future
        if fn == '_FLAG':
            flagged = True
            continue
        if fn.startswith('reply-'):
            msg_candidate = crypto_util.decrypt(
                g.sid, g.codename,
                file(store.path(g.sid, fn)).read())
            try:
                msgs.append(
                    dict(id=fn,
                         date=str(
                             datetime.fromtimestamp(
                                 os.stat(store.path(g.sid, fn)).st_mtime)),
                         msg=msg_candidate.decode()))
            except UnicodeDecodeError:
                # todo: we should have logging here!
                pass
    if flagged:
        session['flagged'] = True

    def async_genkey(sid, codename):
        with app.app_context():
            background.execute(lambda: crypto_util.genkeypair(sid, codename))

    # Generate a keypair to encrypt replies from the journalist
    # Only do this if the journalist has flagged the source as one
    # that they would like to reply to. (Issue #140.)
    if not crypto_util.getkey(g.sid) and flagged:
        async_genkey(g.sid, g.codename)

    return render_template('lookup.html',
                           codename=g.codename,
                           msgs=msgs,
                           flagged=flagged,
                           haskey=crypto_util.getkey(g.sid))
예제 #8
0
def lookup():
    msgs = []
    flagged = False
    for fn in os.listdir(g.loc):
        # TODO: make 'flag' a db column, so we can replace this with a db
        # lookup in the future
        if fn == '_FLAG':
            flagged = True
            continue
        if fn.startswith('reply-'):
            msg_candidate = crypto_util.decrypt(
                g.sid, g.codename, file(store.path(g.sid, fn)).read())
            try:
                msgs.append(dict(
                        id=fn,
                        date=str(
                            datetime.fromtimestamp(
                                os.stat(store.path(g.sid, fn)).st_mtime)),
                        msg=msg_candidate.decode()))
            except UnicodeDecodeError:
                # todo: we should have logging here!
                pass
    if flagged:
        session['flagged'] = True

    def async_genkey(sid, codename):
        with app.app_context():
            background.execute(lambda: crypto_util.genkeypair(sid, codename))

    # Generate a keypair to encrypt replies from the journalist
    # Only do this if the journalist has flagged the source as one
    # that they would like to reply to. (Issue #140.)
    if not crypto_util.getkey(g.sid) and flagged:
        async_genkey(g.sid, g.codename)

    return render_template(
        'lookup.html', codename=g.codename, msgs=msgs, flagged=flagged,
        haskey=crypto_util.getkey(g.sid))
예제 #9
0
    def test_encrypt_binary_stream(self):
        """Generally, we pass unicode strings (the type form data is
        returned as) as plaintext to crypto_util.encrypt(). These have
        to be converted to "binary stream" types (such as `file`) before
        we can actually call gnupg.GPG.encrypt() on them. This is done
        in crypto_util.encrypt() with an `if` branch that uses
        `gnupg._util._is_stream(plaintext)` as the predicate, and calls
        `gnupg._util._make_binary_stream(plaintext)` if necessary. This
        test ensures our encrypt function works even if we provide
        inputs such that this `if` branch is skipped (i.e., the object
        passed for `plaintext` is one such that
        `gnupg._util._is_stream(plaintext)` returns `True`).
        """
        source, codename = utils.db_helper.init_source()
        with open(os.path.realpath(__file__)) as fh:
            ciphertext = crypto_util.encrypt(
                fh,
                [crypto_util.getkey(source.filesystem_id),
                 config.JOURNALIST_KEY],
                store.path(source.filesystem_id, 'somefile.gpg'))
        plaintext = crypto_util.decrypt(codename, ciphertext)

        with open(os.path.realpath(__file__)) as fh:
            self.assertEqual(fh.read(), plaintext)