diff --git a/README.md b/README.md index b6ea063a..52383326 100644 --- a/README.md +++ b/README.md @@ -1043,6 +1043,7 @@ Input: - (optional) `mailbox_id` in request body - (optional) `name` in request body - (optional) `mailbox_ids` in request body: array of mailbox_id +- (optional) `disable_pgp` in request body: boolean Output: If success, return 200 diff --git a/app/api/views/alias.py b/app/api/views/alias.py index db7cb9ac..cb11f375 100644 --- a/app/api/views/alias.py +++ b/app/api/views/alias.py @@ -257,6 +257,7 @@ def update_alias(alias_id): note (optional): in body name (optional): in body mailbox_id (optional): in body + disable_pgp (optional): in body Output: 200 """ @@ -319,6 +320,10 @@ def update_alias(alias_id): alias.name = new_name changed = True + if "disable_pgp" in data: + alias.disable_pgp = data.get("disable_pgp") + changed = True + if changed: db.session.commit() diff --git a/app/dashboard/templates/dashboard/index.html b/app/dashboard/templates/dashboard/index.html index c90ba35c..e6b0d32a 100644 --- a/app/dashboard/templates/dashboard/index.html +++ b/app/dashboard/templates/dashboard/index.html @@ -211,7 +211,7 @@ {% endif %} style="padding-left: 0px" > - @@ -372,10 +372,26 @@ Save - - + {% if alias.mailbox_support_pgp() %} +
+ PGP + +
+
+ +
+ {% endif %} +
@@ -527,7 +543,7 @@ }); - $(".custom-switch-input").change(async function (e) { + $(".enable-disable-alias").change(async function (e) { let aliasId = $(this).data("alias"); let alias = $(this).data("alias-email"); @@ -563,6 +579,41 @@ } }) + $(".enable-disable-pgp").change(async function (e) { + let aliasId = $(this).data("alias"); + let alias = $(this).data("alias-email"); + var oldValue = !$(this).prop("checked"); + let newValue = !oldValue; + + try { + let res = await fetch(`/api/aliases/${aliasId}`, { + method: "PUT", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + disable_pgp: oldValue, + }), + }); + + if (res.ok) { + if (newValue) { + toastr.success(`PGP is enabled for ${alias}`); + } else { + toastr.info(`PGP is disabled for ${alias}`); + } + } else { + toastr.error("Sorry for the inconvenience! Could you refresh the page & retry please?", "Unknown Error"); + // reset to the original value + $(this).prop("checked", oldValue); + } + } catch (e) { + toastr.error("Sorry for the inconvenience! Could you refresh the page & retry please?", "Unknown Error"); + // reset to the original value + $(this).prop("checked", oldValue); + } + }) + $(".save-note").on("click", async function () { let aliasId = $(this).data("alias"); let note = $(`#note-${aliasId}`).val(); diff --git a/app/models.py b/app/models.py index 7f710c63..7ce2f710 100644 --- a/app/models.py +++ b/app/models.py @@ -657,6 +657,12 @@ class Alias(db.Model, ModelMixin): # To have the list of all mailboxes, should use AliasInfo instead _mailboxes = db.relationship("Mailbox", secondary="alias_mailbox", lazy="joined") + # If the mailbox has PGP-enabled, user can choose disable the PGP on the alias + # this is useful when some senders already support PGP + disable_pgp = db.Column( + db.Boolean, nullable=False, default=False, server_default="0" + ) + user = db.relationship(User) mailbox = db.relationship("Mailbox", lazy="joined") @@ -668,6 +674,18 @@ class Alias(db.Model, ModelMixin): return ret + def mailbox_support_pgp(self) -> bool: + """return True of one of the mailboxes support PGP""" + for mb in self.mailboxes: + if mb.pgp_finger_print: + return True + return False + + def pgp_enabled(self) -> bool: + if self.mailbox_support_pgp() and not self.disable_pgp: + return True + return False + @classmethod def create(cls, **kw): r = cls(**kw) diff --git a/email_handler.py b/email_handler.py index e356f4c6..521d8033 100644 --- a/email_handler.py +++ b/email_handler.py @@ -379,7 +379,6 @@ def forward_email_to_mailbox( user, ) -> (bool, str): LOG.d("Forward %s -> %s -> %s", contact, alias, mailbox) - spam_check = True is_spam, spam_status = get_spam_info(msg) if is_spam: LOG.warning("Email detected as spam. Alias: %s, from: %s", alias, contact) @@ -390,7 +389,7 @@ def forward_email_to_mailbox( return False, "550 SL E1" # create PGP email if needed - if mailbox.pgp_finger_print and user.is_premium(): + if mailbox.pgp_finger_print and user.is_premium() and not alias.disable_pgp: LOG.d("Encrypt message using mailbox %s", mailbox) msg = prepare_pgp_message(msg, mailbox.pgp_finger_print) diff --git a/migrations/versions/2020_051712_659d979b64ce_.py b/migrations/versions/2020_051712_659d979b64ce_.py new file mode 100644 index 00000000..e871231c --- /dev/null +++ b/migrations/versions/2020_051712_659d979b64ce_.py @@ -0,0 +1,29 @@ +"""empty message + +Revision ID: 659d979b64ce +Revises: c31cdf879ee3 +Create Date: 2020-05-17 12:50:53.360910 + +""" +import sqlalchemy_utils +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '659d979b64ce' +down_revision = 'c31cdf879ee3' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('alias', sa.Column('disable_pgp', sa.Boolean(), server_default='0', nullable=False)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('alias', 'disable_pgp') + # ### end Alembic commands ### diff --git a/server.py b/server.py index d88d799e..d29727a7 100644 --- a/server.py +++ b/server.py @@ -167,7 +167,12 @@ def fake_data(): api_key = ApiKey.create(user_id=user.id, name="Firefox") api_key.code = "codeFF" - m1 = Mailbox.create(user_id=user.id, email="m1@cd.ef", verified=True) + m1 = Mailbox.create( + user_id=user.id, + email="m1@cd.ef", + verified=True, + pgp_finger_print="fake fingerprint", + ) db.session.commit() for i in range(31): diff --git a/tests/api/test_alias.py b/tests/api/test_alias.py index 9ee1217f..3d2eaf92 100644 --- a/tests/api/test_alias.py +++ b/tests/api/test_alias.py @@ -399,6 +399,31 @@ def test_update_alias_mailboxes(flask_client): assert r.status_code == 400 +def test_update_disable_pgp(flask_client): + user = User.create( + email="a@b.c", password="password", name="Test User", activated=True + ) + db.session.commit() + + # create api_key + api_key = ApiKey.create(user.id, "for test") + db.session.commit() + + alias = Alias.create_new_random(user) + db.session.commit() + assert not alias.disable_pgp + + r = flask_client.put( + url_for("api.update_alias", alias_id=alias.id), + headers={"Authentication": api_key.code}, + json={"disable_pgp": True}, + ) + + assert r.status_code == 200 + alias = Alias.get(alias.id) + assert alias.disable_pgp + + def test_alias_contacts(flask_client): user = User.create( email="a@b.c", password="password", name="Test User", activated=True