diff --git a/securedrop/journalist_app/api.py b/securedrop/journalist_app/api.py index f499844fbf4..cd09b435bc3 100644 --- a/securedrop/journalist_app/api.py +++ b/securedrop/journalist_app/api.py @@ -16,8 +16,7 @@ from db import db from journalist_app import utils -from models import (Journalist, Reply, SeenFile, SeenMessage, - SeenReply, Source, Submission, +from models import (Journalist, Reply, SeenReply, Source, Submission, LoginThrottledException, InvalidUsernameException, BadTokenException, WrongPasswordException) from sdconfig import SDConfig diff --git a/securedrop/journalist_app/col.py b/securedrop/journalist_app/col.py index 0c45619a1dc..3c056e25b28 100644 --- a/securedrop/journalist_app/col.py +++ b/securedrop/journalist_app/col.py @@ -13,16 +13,15 @@ url_for, ) from flask_babel import gettext -from sqlalchemy.exc import IntegrityError from sqlalchemy.orm.exc import NoResultFound from db import db -from models import Reply, SeenFile, SeenMessage, SeenReply, Submission +from models import Reply, Submission from journalist_app.forms import ReplyForm from journalist_app.utils import (make_star_true, make_star_false, get_source, delete_collection, col_download_unread, col_download_all, col_star, col_un_star, - col_delete) + col_delete, mark_seen) def make_blueprint(config): @@ -94,25 +93,18 @@ def download_single_file(filesystem_id, fn): # mark as seen by the current user try: - journalist_id = g.get("user").id + journalist = g.get("user") if fn.endswith("reply.gpg"): reply = Reply.query.filter(Reply.filename == fn).one() - seen_reply = SeenReply(reply_id=reply.id, journalist_id=journalist_id) - db.session.add(seen_reply) + mark_seen([reply], journalist) elif fn.endswith("-doc.gz.gpg") or fn.endswith("doc.zip.gpg"): file = Submission.query.filter(Submission.filename == fn).one() - seen_file = SeenFile(file_id=file.id, journalist_id=journalist_id) - db.session.add(seen_file) + mark_seen([file], journalist) else: message = Submission.query.filter(Submission.filename == fn).one() - seen_message = SeenMessage(message_id=message.id, journalist_id=journalist_id) - db.session.add(seen_message) - - db.session.commit() + mark_seen(message, journalist) except NoResultFound as e: current_app.logger.error("Could not mark {} as seen: {}".format(fn, e)) - except IntegrityError: - pass # expected not to store that a file was seen by the same user multiple times return send_file(current_app.storage.path(filesystem_id, fn), mimetype="application/pgp-encrypted") diff --git a/securedrop/tests/test_journalist.py b/securedrop/tests/test_journalist.py index a677cae8e01..4f30da3fd9b 100644 --- a/securedrop/tests/test_journalist.py +++ b/securedrop/tests/test_journalist.py @@ -18,6 +18,7 @@ import crypto_util import journalist_app as journalist_app_module +from journalist_app.utils import mark_seen import models from db import db from models import ( @@ -1847,11 +1848,11 @@ def test_delete_collection_updates_db(journalist_app, test_journo, test_source): source = Source.query.get(test_source["id"]) journo = Journalist.query.get(test_journo["id"]) files = utils.db_helper.submit(source, 2) - utils.db_helper.mark_files_seen(journo.id, files) + mark_seen(files, journo) messages = utils.db_helper.submit(source, 2) - utils.db_helper.mark_messages_seen(journo.id, messages) + mark_seen(messages, journo) replies = utils.db_helper.reply(journo, source, 2) - utils.db_helper.mark_replies_seen(journo.id, replies) + mark_seen(replies, journo) journalist_app_module.utils.delete_collection(test_source["filesystem_id"]) @@ -2074,9 +2075,7 @@ def test_download_selected_submissions_and_replies_previously_seen( db.session.add(seen_file) seen_message = SeenMessage(message_id=selected_submissions[1].id, journalist_id=journo.id) db.session.add(seen_message) - for reply in selected_replies: - seen_reply = SeenReply(reply_id=reply.id, journalist_id=journo.id) - db.session.add(seen_reply) + mark_seen(selected_replies, journo) db.session.commit() with journalist_app.test_client() as app: diff --git a/securedrop/tests/utils/db_helper.py b/securedrop/tests/utils/db_helper.py index 99e70f70503..3e81e54b3b2 100644 --- a/securedrop/tests/utils/db_helper.py +++ b/securedrop/tests/utils/db_helper.py @@ -13,7 +13,8 @@ from flask import current_app from db import db -from models import Journalist, Reply, SeenFile, SeenMessage, SeenReply, Source, Submission +from journalist_app.utils import mark_seen +from models import Journalist, Reply, SeenReply, Source, Submission from sdconfig import config os.environ['SECUREDROP_ENV'] = 'test' # noqa @@ -205,38 +206,6 @@ def new_codename(client, session): return codename -def mark_replies_seen(journalist_id: int, replies: List[Reply]): - """ - Mark replies as seen. - """ - for reply in replies: - seen_reply = SeenReply(journalist_id=journalist_id, reply_id=reply.id) - db.session.add(seen_reply) - db.session.commit() - - -def mark_messages_seen(journalist_id: int, messages: List[Submission]): - """ - Mark messages as seen. - """ - for message in messages: - message.downloaded = True - seen_message = SeenMessage(journalist_id=journalist_id, message_id=message.id) - db.session.add(seen_message) - db.session.commit() - - -def mark_files_seen(journalist_id: int, files: List[Submission]): - """ - Mark files as seen. - """ - for file in files: - file.downloaded = True - seen_file = SeenFile(journalist_id=journalist_id, file_id=file.id) - db.session.add(seen_file) - db.session.commit() - - def bulk_setup_for_seen_only(journo) -> List[Dict]: """ Create some sources with some seen submissions that are not marked as 'downloaded' in the @@ -260,9 +229,9 @@ def bulk_setup_for_seen_only(journo) -> List[Dict]: seen_messages = random.sample(messages, math.ceil(len(messages) / 2)) seen_replies = random.sample(replies, math.ceil(len(replies) / 2)) - mark_files_seen(journo.id, seen_files) - mark_messages_seen(journo.id, seen_messages) - mark_replies_seen(journo.id, seen_replies) + mark_seen(seen_files, journo) + mark_seen(seen_messages, journo) + mark_seen(seen_replies, journo) unseen_files = list(set(files).difference(set(seen_files))) unseen_messages = list(set(messages).difference(set(seen_messages)))