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: current_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, new_user=session.get('new_user', None), haskey=crypto_util.getkey(g.filesystem_id))
def lookup() -> str: replies = [] source_inbox = Reply.query.filter(Reply.source_id == g.source.id) \ .filter(Reply.deleted_by_source == False).all() # noqa for reply in source_inbox: reply_path = current_app.storage.path( g.filesystem_id, reply.filename, ) try: with io.open(reply_path, "rb") as f: contents = f.read() reply_obj = current_app.crypto_util.decrypt( g.codename, contents) reply.decrypted = reply_obj except UnicodeDecodeError: current_app.logger.error("Could not decode reply %s" % reply.filename) except FileNotFoundError: current_app.logger.error("Reply file missing: %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 current_app.crypto_util.get_fingerprint(g.filesystem_id) and \ g.source.flagged: db_uri = current_app.config['SQLALCHEMY_DATABASE_URI'] async_genkey(current_app.crypto_util, db_uri, g.filesystem_id, g.codename) return render_template( 'lookup.html', allow_document_uploads=current_app.instance_config. allow_document_uploads, codename=g.codename, replies=replies, flagged=g.source.flagged, new_user=session.get('new_user', None), haskey=current_app.crypto_util.get_fingerprint(g.filesystem_id), form=SubmissionForm(), )
def submit() -> werkzeug.Response: allow_document_uploads = current_app.instance_config.allow_document_uploads form = SubmissionForm() if not form.validate(): for field, errors in form.errors.items(): for error in errors: flash(error, "error") return redirect(url_for('main.lookup')) msg = request.form['msg'] fh = None if allow_document_uploads and 'fh' in request.files: fh = request.files['fh'] # Don't submit anything if it was an "empty" submission. #878 if not (msg or fh): if allow_document_uploads: flash( gettext( "You must enter a message or choose a file to submit." ), "error") else: flash(gettext("You must enter a message."), "error") return redirect(url_for('main.lookup')) fnames = [] journalist_filename = g.source.journalist_filename first_submission = g.source.interaction_count == 0 if msg: g.source.interaction_count += 1 fnames.append( current_app.storage.save_message_submission( g.filesystem_id, g.source.interaction_count, journalist_filename, msg)) if fh: g.source.interaction_count += 1 fnames.append( current_app.storage.save_file_submission( g.filesystem_id, g.source.interaction_count, journalist_filename, fh.filename, fh.stream)) if first_submission: flash_message = render_template( 'first_submission_flashed_message.html') flash(Markup(flash_message), "success") else: if msg and not fh: html_contents = gettext('Thanks! We received your message.') elif fh and not msg: html_contents = gettext('Thanks! We received your document.') else: html_contents = gettext('Thanks! We received your message and ' 'document.') flash_message = render_template( 'next_submission_flashed_message.html', html_contents=html_contents) flash(Markup(flash_message), "success") new_submissions = [] for fname in fnames: submission = Submission(g.source, fname) db.session.add(submission) new_submissions.append(submission) if g.source.pending: g.source.pending = False # Generate a keypair now, if there's enough entropy (issue #303) # (gpg reads 300 bytes from /dev/random) entropy_avail = get_entropy_estimate() if entropy_avail >= 2400: db_uri = current_app.config['SQLALCHEMY_DATABASE_URI'] async_genkey(current_app.crypto_util, db_uri, g.filesystem_id, g.codename) current_app.logger.info( "generating key, entropy: {}".format(entropy_avail)) else: current_app.logger.warning( "skipping key generation. entropy: {}".format( entropy_avail)) g.source.last_updated = datetime.utcnow() db.session.commit() for sub in new_submissions: store.async_add_checksum_for_file(sub) normalize_timestamps(g.filesystem_id) return redirect(url_for('main.lookup'))
def submit(): msg = request.form['msg'] fh = request.files['fh'] # Don't submit anything if it was an "empty" submission. #878 if not (msg or fh): flash( gettext( "You must enter a message or choose a file to submit."), "error") return redirect(url_for('main.lookup')) fnames = [] journalist_filename = g.source.journalist_filename first_submission = g.source.interaction_count == 0 if msg: g.source.interaction_count += 1 fnames.append( store.save_message_submission(g.filesystem_id, g.source.interaction_count, journalist_filename, msg)) if fh: g.source.interaction_count += 1 fnames.append( store.save_file_submission(g.filesystem_id, g.source.interaction_count, journalist_filename, fh.filename, fh.stream)) if first_submission: msg = render_template('first_submission_flashed_message.html') flash(Markup(msg), "success") else: if msg and not fh: html_contents = gettext('Thanks! We received your message.') elif not msg and fh: html_contents = gettext('Thanks! We received your document.') else: html_contents = gettext('Thanks! We received your message and ' 'document.') msg = render_template('next_submission_flashed_message.html', html_contents=html_contents) flash(Markup(msg), "success") for fname in fnames: submission = Submission(g.source, fname) db_session.add(submission) if g.source.pending: g.source.pending = False # Generate a keypair now, if there's enough entropy (issue #303) # (gpg reads 300 bytes from /dev/random) entropy_avail = get_entropy_estimate() if entropy_avail >= 2400: async_genkey(g.filesystem_id, g.codename) current_app.logger.info( "generating key, entropy: {}".format(entropy_avail)) else: current_app.logger.warn( "skipping key generation. entropy: {}".format( entropy_avail)) g.source.last_updated = datetime.utcnow() db_session.commit() normalize_timestamps(g.filesystem_id) return redirect(url_for('main.lookup'))