Skip to content

Commit

Permalink
ran isort and black again after rebase
Browse files Browse the repository at this point in the history
  • Loading branch information
zenmonkeykstop committed Aug 16, 2022
1 parent 1acb3a5 commit 69b327b
Show file tree
Hide file tree
Showing 17 changed files with 290 additions and 749 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,88 +5,95 @@
Create Date: 2022-04-16 21:25:22.398189
"""
from alembic import op
import sqlalchemy as sa

from alembic import op

# revision identifiers, used by Alembic.
revision = 'c5a02eb52f2d'
down_revision = 'b7f98cfd6a70'
revision = "c5a02eb52f2d"
down_revision = "b7f98cfd6a70"
branch_labels = None
depends_on = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('revoked_tokens')
with op.batch_alter_table('journalists', schema=None) as batch_op:
batch_op.drop_column('session_nonce')
op.drop_table("revoked_tokens")
with op.batch_alter_table("journalists", schema=None) as batch_op:
batch_op.drop_column("session_nonce")

# ### end Alembic commands ###


def downgrade() -> None:
'''This would have been the easy way, however previous does not have
default value and thus up/down assertion fails'''
#op.add_column('journalists', sa.Column('session_nonce', sa.Integer(), nullable=False, server_default='0'))
"""This would have been the easy way, however previous does not have
default value and thus up/down assertion fails"""
# op.add_column('journalists', sa.Column('session_nonce', sa.Integer(), nullable=False, server_default='0'))

conn = op.get_bind()
conn.execute("PRAGMA legacy_alter_table=ON")
# Save existing journalist table.
op.rename_table('journalists', 'journalists_tmp')
op.rename_table("journalists", "journalists_tmp")

# Add nonce column.
op.add_column('journalists_tmp', sa.Column('session_nonce', sa.Integer()))
op.add_column("journalists_tmp", sa.Column("session_nonce", sa.Integer()))

# Populate nonce column.
journalists = conn.execute(
sa.text("SELECT * FROM journalists_tmp")).fetchall()
journalists = conn.execute(sa.text("SELECT * FROM journalists_tmp")).fetchall()

for journalist in journalists:
conn.execute(
sa.text("""UPDATE journalists_tmp SET session_nonce=0 WHERE
id=:id""").bindparams(id=journalist.id)
)
sa.text(
"""UPDATE journalists_tmp SET session_nonce=0 WHERE
id=:id"""
).bindparams(id=journalist.id)
)

# Now create new table with null constraint applied.
op.create_table('journalists',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('uuid', sa.String(length=36), nullable=False),
sa.Column('username', sa.String(length=255), nullable=False),
sa.Column('first_name', sa.String(length=255), nullable=True),
sa.Column('last_name', sa.String(length=255), nullable=True),
sa.Column('pw_salt', sa.Binary(), nullable=True),
sa.Column('pw_hash', sa.Binary(), nullable=True),
sa.Column('passphrase_hash', sa.String(length=256), nullable=True),
sa.Column('is_admin', sa.Boolean(), nullable=True),
sa.Column('session_nonce', sa.Integer(), nullable=False),
sa.Column('otp_secret', sa.String(length=32), nullable=True),
sa.Column('is_totp', sa.Boolean(), nullable=True),
sa.Column('hotp_counter', sa.Integer(), nullable=True),
sa.Column('last_token', sa.String(length=6), nullable=True),
sa.Column('created_on', sa.DateTime(), nullable=True),
sa.Column('last_access', sa.DateTime(), nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('username'),
sa.UniqueConstraint('uuid')
op.create_table(
"journalists",
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("uuid", sa.String(length=36), nullable=False),
sa.Column("username", sa.String(length=255), nullable=False),
sa.Column("first_name", sa.String(length=255), nullable=True),
sa.Column("last_name", sa.String(length=255), nullable=True),
sa.Column("pw_salt", sa.Binary(), nullable=True),
sa.Column("pw_hash", sa.Binary(), nullable=True),
sa.Column("passphrase_hash", sa.String(length=256), nullable=True),
sa.Column("is_admin", sa.Boolean(), nullable=True),
sa.Column("session_nonce", sa.Integer(), nullable=False),
sa.Column("otp_secret", sa.String(length=32), nullable=True),
sa.Column("is_totp", sa.Boolean(), nullable=True),
sa.Column("hotp_counter", sa.Integer(), nullable=True),
sa.Column("last_token", sa.String(length=6), nullable=True),
sa.Column("created_on", sa.DateTime(), nullable=True),
sa.Column("last_access", sa.DateTime(), nullable=True),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("username"),
sa.UniqueConstraint("uuid"),
)

conn.execute('''
conn.execute(
"""
INSERT INTO journalists
SELECT id, uuid, username, first_name, last_name, pw_salt, pw_hash,
passphrase_hash, is_admin, session_nonce, otp_secret, is_totp,
hotp_counter, last_token, created_on, last_access
FROM journalists_tmp
''')
"""
)

# Now delete the old table.
op.drop_table('journalists_tmp')

op.create_table('revoked_tokens',
sa.Column('id', sa.INTEGER(), nullable=False),
sa.Column('journalist_id', sa.INTEGER(), nullable=False),
sa.Column('token', sa.TEXT(), nullable=False),
sa.ForeignKeyConstraint(['journalist_id'], ['journalists.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('token')
op.drop_table("journalists_tmp")

op.create_table(
"revoked_tokens",
sa.Column("id", sa.INTEGER(), nullable=False),
sa.Column("journalist_id", sa.INTEGER(), nullable=False),
sa.Column("token", sa.TEXT(), nullable=False),
sa.ForeignKeyConstraint(
["journalist_id"],
["journalists.id"],
),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("token"),
)
13 changes: 3 additions & 10 deletions securedrop/journalist_app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import version
from db import db
from flask import Flask, abort, g, json, redirect, render_template, request, url_for
from flask_assets import Environment
from flask_babel import gettext
from flask_wtf.csrf import CSRFError, CSRFProtect
from journalist_app import account, admin, api, col, main
Expand Down Expand Up @@ -112,9 +111,7 @@ def _handle_http_exception(
app.jinja_env.globals["version"] = version.__version__
app.jinja_env.filters["rel_datetime_format"] = template_filters.rel_datetime_format
app.jinja_env.filters["filesizeformat"] = template_filters.filesizeformat
app.jinja_env.filters[
"html_datetime_format"
] = template_filters.html_datetime_format
app.jinja_env.filters["html_datetime_format"] = template_filters.html_datetime_format
app.jinja_env.add_extension("jinja2.ext.do")

@app.before_request
Expand All @@ -132,9 +129,7 @@ def setup_g() -> "Optional[Response]":
InstanceConfig.get_default().organization_name
) # pylint: disable=assigning-non-slot
else:
g.organization_name = gettext(
"SecureDrop"
) # pylint: disable=assigning-non-slot
g.organization_name = gettext("SecureDrop") # pylint: disable=assigning-non-slot

try:
g.logo = get_logo_url(app) # pylint: disable=assigning-non-slot
Expand All @@ -152,9 +147,7 @@ def setup_g() -> "Optional[Response]":
filesystem_id = request.form.get("filesystem_id")
if filesystem_id:
g.filesystem_id = filesystem_id # pylint: disable=assigning-non-slot
g.source = get_source(
filesystem_id
) # pylint: disable=assigning-non-slot
g.source = get_source(filesystem_id) # pylint: disable=assigning-non-slot

return None

Expand Down
8 changes: 2 additions & 6 deletions securedrop/journalist_app/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,13 @@ def new_two_factor() -> Union[str, werkzeug.Response]:
token = request.form["token"]
if session.get_user().verify_token(token):
flash(
gettext(
"Your two-factor credentials have been reset successfully."
),
gettext("Your two-factor credentials have been reset successfully."),
"notification",
)
return redirect(url_for("account.edit"))
else:
flash(
gettext(
"There was a problem verifying the two-factor code. Please try again."
),
gettext("There was a problem verifying the two-factor code. Please try again."),
"error",
)

Expand Down
48 changes: 11 additions & 37 deletions securedrop/journalist_app/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,9 @@
)
from flask_babel import gettext
from journalist_app.decorators import admin_required
from journalist_app.forms import (
LogoForm,
NewUserForm,
OrgNameForm,
SubmissionPreferencesForm,
)
from journalist_app.forms import LogoForm, NewUserForm, OrgNameForm, SubmissionPreferencesForm
from journalist_app.sessions import logout_user, session
from journalist_app.utils import (
commit_account_changes,
set_diceware_password,
validate_hotp_secret,
)
from journalist_app.utils import commit_account_changes, set_diceware_password, validate_hotp_secret
from models import (
FirstOrLastNameError,
InstanceConfig,
Expand Down Expand Up @@ -79,18 +70,14 @@ def manage_config() -> Union[str, werkzeug.Response]:

if current_app.static_folder is None:
abort(500)
custom_logo_filepath = os.path.join(
current_app.static_folder, "i", "custom_logo.png"
)
custom_logo_filepath = os.path.join(current_app.static_folder, "i", "custom_logo.png")
try:
f.save(custom_logo_filepath)
flash(gettext("Image updated."), "logo-success")
except Exception:
flash(
# Translators: This error is shown when an uploaded image cannot be used.
gettext(
"Unable to process the image file. Please try another one."
),
gettext("Unable to process the image file. Please try another one."),
"logo-error",
)
finally:
Expand Down Expand Up @@ -122,9 +109,7 @@ def update_submission_preferences() -> Optional[werkzeug.Response]:

reject_codenames = form.reject_codename_messages.data

InstanceConfig.update_submission_prefs(
allow_uploads, msg_length, reject_codenames
)
InstanceConfig.update_submission_prefs(allow_uploads, msg_length, reject_codenames)
flash(gettext("Preferences saved."), "submission-preferences-success")
return redirect(url_for("admin.manage_config") + "#config-preventuploads")
else:
Expand Down Expand Up @@ -200,9 +185,7 @@ def add_user() -> Union[str, werkzeug.Response]:
)
else:
flash(
gettext(
"An unexpected error occurred! " "Please inform your admin."
),
gettext("An unexpected error occurred! " "Please inform your admin."),
"error",
)
form_valid = False
Expand All @@ -215,9 +198,7 @@ def add_user() -> Union[str, werkzeug.Response]:
form_valid = False
if "UNIQUE constraint failed: journalists.username" in str(e):
flash(
gettext('Username "{username}" already taken.').format(
username=username
),
gettext('Username "{username}" already taken.').format(username=username),
"error",
)
else:
Expand All @@ -229,9 +210,7 @@ def add_user() -> Union[str, werkzeug.Response]:
),
"error",
)
current_app.logger.error(
"Adding user " "'{}' failed: {}".format(username, e)
)
current_app.logger.error("Adding user " "'{}' failed: {}".format(username, e))

if form_valid:
return redirect(url_for("admin.new_user_two_factor", uid=new_user.id))
Expand All @@ -251,17 +230,14 @@ def new_user_two_factor() -> Union[str, werkzeug.Response]:
if user.verify_token(token):
flash(
gettext(
'The two-factor code for user "{user}" was verified '
"successfully."
'The two-factor code for user "{user}" was verified ' "successfully."
).format(user=user.username),
"notification",
)
return redirect(url_for("admin.index"))
else:
flash(
gettext(
"There was a problem verifying the two-factor code. Please try again."
),
gettext("There was a problem verifying the two-factor code. Please try again."),
"error",
)

Expand Down Expand Up @@ -370,9 +346,7 @@ def delete_user(user_id: int) -> werkzeug.Response:
# Do not flash because the interface does not expose this.
# It can only happen by manually crafting a POST request
current_app.logger.error(
'Admin {} tried to delete "deleted" user'.format(
session.get_user().username
)
'Admin {} tried to delete "deleted" user'.format(session.get_user().username)
)
abort(403)
else:
Expand Down
32 changes: 7 additions & 25 deletions securedrop/journalist_app/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,19 +172,11 @@ def source_conversation(source_uuid: str) -> Tuple[flask.Response, int]:
def all_source_submissions(source_uuid: str) -> Tuple[flask.Response, int]:
source = get_or_404(Source, source_uuid, column=Source.uuid)
return (
jsonify(
{
"submissions": [
submission.to_json() for submission in source.submissions
]
}
),
jsonify({"submissions": [submission.to_json() for submission in source.submissions]}),
200,
)

@api.route(
"/sources/<source_uuid>/submissions/<submission_uuid>/download", methods=["GET"]
)
@api.route("/sources/<source_uuid>/submissions/<submission_uuid>/download", methods=["GET"])
def download_submission(source_uuid: str, submission_uuid: str) -> flask.Response:
get_or_404(Source, source_uuid, column=Source.uuid)
submission = get_or_404(Submission, submission_uuid, column=Submission.uuid)
Expand All @@ -201,9 +193,7 @@ def download_reply(source_uuid: str, reply_uuid: str) -> flask.Response:
"/sources/<source_uuid>/submissions/<submission_uuid>",
methods=["GET", "DELETE"],
)
def single_submission(
source_uuid: str, submission_uuid: str
) -> Tuple[flask.Response, int]:
def single_submission(source_uuid: str, submission_uuid: str) -> Tuple[flask.Response, int]:
if request.method == "GET":
get_or_404(Source, source_uuid, column=Source.uuid)
submission = get_or_404(Submission, submission_uuid, column=Submission.uuid)
Expand Down Expand Up @@ -306,9 +296,7 @@ def get_all_submissions() -> Tuple[flask.Response, int]:
jsonify(
{
"submissions": [
submission.to_json()
for submission in submissions
if submission.source
submission.to_json() for submission in submissions if submission.source
]
}
),
Expand All @@ -319,9 +307,7 @@ def get_all_submissions() -> Tuple[flask.Response, int]:
def get_all_replies() -> Tuple[flask.Response, int]:
replies = Reply.query.all()
return (
jsonify(
{"replies": [reply.to_json() for reply in replies if reply.source]}
),
jsonify({"replies": [reply.to_json() for reply in replies if reply.source]}),
200,
)

Expand All @@ -332,9 +318,7 @@ def seen() -> Tuple[flask.Response, int]:
"""

if request.method == "POST":
if request.json is None or not isinstance(
request.json, collections.abc.Mapping
):
if request.json is None or not isinstance(request.json, collections.abc.Mapping):
abort(400, "Please send requests in valid JSON.")

if not any(map(request.json.get, ["files", "messages", "replies"])):
Expand All @@ -350,9 +334,7 @@ def seen() -> Tuple[flask.Response, int]:
targets.add(f)

for message_uuid in request.json.get("messages", []):
m = Submission.query.filter(
Submission.uuid == message_uuid
).one_or_none()
m = Submission.query.filter(Submission.uuid == message_uuid).one_or_none()
if m is None or not m.is_message:
abort(404, "message not found: {}".format(message_uuid))
targets.add(m)
Expand Down
Loading

0 comments on commit 69b327b

Please sign in to comment.