4.55.0
All checks were successful
Build-Release-Image / Build-Image (linux/amd64) (push) Successful in 3m43s
Build-Release-Image / Build-Image (linux/arm64) (push) Successful in 4m10s
Build-Release-Image / Merge-Images (push) Successful in 27s
Build-Release-Image / Create-Release (push) Successful in 10s
Build-Release-Image / Notify (push) Successful in 3s
All checks were successful
Build-Release-Image / Build-Image (linux/amd64) (push) Successful in 3m43s
Build-Release-Image / Build-Image (linux/arm64) (push) Successful in 4m10s
Build-Release-Image / Merge-Images (push) Successful in 27s
Build-Release-Image / Create-Release (push) Successful in 10s
Build-Release-Image / Notify (push) Successful in 3s
This commit is contained in:
@ -1,9 +1,13 @@
|
||||
from typing import Optional
|
||||
|
||||
from deprecated import deprecated
|
||||
from flask import g
|
||||
from flask import jsonify
|
||||
from flask import request
|
||||
|
||||
from app import alias_utils
|
||||
from app.alias_audit_log_utils import emit_alias_audit_log, AliasAuditLogAction
|
||||
from app.alias_mailbox_utils import set_mailboxes_for_alias
|
||||
from app.api.base import api_bp, require_api_auth
|
||||
from app.api.serializer import (
|
||||
AliasInfo,
|
||||
@ -26,7 +30,7 @@ from app.errors import (
|
||||
)
|
||||
from app.extensions import limiter
|
||||
from app.log import LOG
|
||||
from app.models import Alias, Contact, Mailbox, AliasMailbox, AliasDeleteReason
|
||||
from app.models import Alias, Contact, Mailbox, AliasDeleteReason
|
||||
|
||||
|
||||
@deprecated
|
||||
@ -185,7 +189,11 @@ def toggle_alias(alias_id):
|
||||
if not alias or alias.user_id != user.id:
|
||||
return jsonify(error="Forbidden"), 403
|
||||
|
||||
alias_utils.change_alias_status(alias, enabled=not alias.enabled)
|
||||
alias_utils.change_alias_status(
|
||||
alias,
|
||||
enabled=not alias.enabled,
|
||||
message=f"Set enabled={not alias.enabled} via API",
|
||||
)
|
||||
LOG.i(f"User {user} changed alias {alias} enabled status to {alias.enabled}")
|
||||
Session.commit()
|
||||
|
||||
@ -272,10 +280,12 @@ def update_alias(alias_id):
|
||||
if not alias or alias.user_id != user.id:
|
||||
return jsonify(error="Forbidden"), 403
|
||||
|
||||
changed_fields = []
|
||||
changed = False
|
||||
if "note" in data:
|
||||
new_note = data.get("note")
|
||||
alias.note = new_note
|
||||
changed_fields.append("note")
|
||||
changed = True
|
||||
|
||||
if "mailbox_id" in data:
|
||||
@ -285,35 +295,19 @@ def update_alias(alias_id):
|
||||
return jsonify(error="Forbidden"), 400
|
||||
|
||||
alias.mailbox_id = mailbox_id
|
||||
changed_fields.append(f"mailbox_id ({mailbox_id})")
|
||||
changed = True
|
||||
|
||||
if "mailbox_ids" in data:
|
||||
mailbox_ids = [int(m_id) for m_id in data.get("mailbox_ids")]
|
||||
mailboxes: [Mailbox] = []
|
||||
|
||||
# check if all mailboxes belong to user
|
||||
for mailbox_id in mailbox_ids:
|
||||
mailbox = Mailbox.get(mailbox_id)
|
||||
if not mailbox or mailbox.user_id != user.id or not mailbox.verified:
|
||||
return jsonify(error="Forbidden"), 400
|
||||
mailboxes.append(mailbox)
|
||||
|
||||
if not mailboxes:
|
||||
return jsonify(error="Must choose at least one mailbox"), 400
|
||||
|
||||
# <<< update alias mailboxes >>>
|
||||
# first remove all existing alias-mailboxes links
|
||||
AliasMailbox.filter_by(alias_id=alias.id).delete()
|
||||
Session.flush()
|
||||
|
||||
# then add all new mailboxes
|
||||
for i, mailbox in enumerate(mailboxes):
|
||||
if i == 0:
|
||||
alias.mailbox_id = mailboxes[0].id
|
||||
else:
|
||||
AliasMailbox.create(alias_id=alias.id, mailbox_id=mailbox.id)
|
||||
# <<< END update alias mailboxes >>>
|
||||
err = set_mailboxes_for_alias(
|
||||
user_id=user.id, alias=alias, mailbox_ids=mailbox_ids
|
||||
)
|
||||
if err:
|
||||
return jsonify(error=err.value), 400
|
||||
|
||||
mailbox_ids_string = ",".join(map(str, mailbox_ids))
|
||||
changed_fields.append(f"mailbox_ids ({mailbox_ids_string})")
|
||||
changed = True
|
||||
|
||||
if "name" in data:
|
||||
@ -325,17 +319,26 @@ def update_alias(alias_id):
|
||||
if new_name:
|
||||
new_name = new_name.replace("\n", "")
|
||||
alias.name = new_name
|
||||
changed_fields.append("name")
|
||||
changed = True
|
||||
|
||||
if "disable_pgp" in data:
|
||||
alias.disable_pgp = data.get("disable_pgp")
|
||||
changed_fields.append("disable_pgp")
|
||||
changed = True
|
||||
|
||||
if "pinned" in data:
|
||||
alias.pinned = data.get("pinned")
|
||||
changed_fields.append("pinned")
|
||||
changed = True
|
||||
|
||||
if changed:
|
||||
changed_fields_string = ",".join(changed_fields)
|
||||
emit_alias_audit_log(
|
||||
alias,
|
||||
AliasAuditLogAction.UpdateAlias,
|
||||
f"Alias fields updated ({changed_fields_string})",
|
||||
)
|
||||
Session.commit()
|
||||
|
||||
return jsonify(ok=True), 200
|
||||
@ -446,11 +449,16 @@ def delete_contact(contact_id):
|
||||
200
|
||||
"""
|
||||
user = g.user
|
||||
contact = Contact.get(contact_id)
|
||||
contact: Optional[Contact] = Contact.get(contact_id)
|
||||
|
||||
if not contact or contact.alias.user_id != user.id:
|
||||
return jsonify(error="Forbidden"), 403
|
||||
|
||||
emit_alias_audit_log(
|
||||
alias=contact.alias,
|
||||
action=AliasAuditLogAction.DeleteContact,
|
||||
message=f"Deleted contact {contact_id} ({contact.email})",
|
||||
)
|
||||
Contact.delete(contact_id)
|
||||
Session.commit()
|
||||
|
||||
@ -468,12 +476,17 @@ def toggle_contact(contact_id):
|
||||
200
|
||||
"""
|
||||
user = g.user
|
||||
contact = Contact.get(contact_id)
|
||||
contact: Optional[Contact] = Contact.get(contact_id)
|
||||
|
||||
if not contact or contact.alias.user_id != user.id:
|
||||
return jsonify(error="Forbidden"), 403
|
||||
|
||||
contact.block_forward = not contact.block_forward
|
||||
emit_alias_audit_log(
|
||||
alias=contact.alias,
|
||||
action=AliasAuditLogAction.UpdateContact,
|
||||
message=f"Set contact state {contact.id} {contact.email} -> {contact.website_email} to blocked {contact.block_forward}",
|
||||
)
|
||||
Session.commit()
|
||||
|
||||
return jsonify(block_forward=contact.block_forward), 200
|
||||
|
@ -2,8 +2,10 @@ from flask import g, request
|
||||
from flask import jsonify
|
||||
|
||||
from app.api.base import api_bp, require_api_auth
|
||||
from app.custom_domain_utils import set_custom_domain_mailboxes
|
||||
from app.db import Session
|
||||
from app.models import CustomDomain, DomainDeletedAlias, Mailbox, DomainMailbox
|
||||
from app.log import LOG
|
||||
from app.models import CustomDomain, DomainDeletedAlias
|
||||
|
||||
|
||||
def custom_domain_to_dict(custom_domain: CustomDomain):
|
||||
@ -100,23 +102,14 @@ def update_custom_domain(custom_domain_id):
|
||||
|
||||
if "mailbox_ids" in data:
|
||||
mailbox_ids = [int(m_id) for m_id in data.get("mailbox_ids")]
|
||||
if mailbox_ids:
|
||||
# check if mailbox is not tempered with
|
||||
mailboxes = []
|
||||
for mailbox_id in mailbox_ids:
|
||||
mailbox = Mailbox.get(mailbox_id)
|
||||
if not mailbox or mailbox.user_id != user.id or not mailbox.verified:
|
||||
return jsonify(error="Forbidden"), 400
|
||||
mailboxes.append(mailbox)
|
||||
|
||||
# first remove all existing domain-mailboxes links
|
||||
DomainMailbox.filter_by(domain_id=custom_domain.id).delete()
|
||||
Session.flush()
|
||||
|
||||
for mailbox in mailboxes:
|
||||
DomainMailbox.create(domain_id=custom_domain.id, mailbox_id=mailbox.id)
|
||||
|
||||
result = set_custom_domain_mailboxes(user.id, custom_domain, mailbox_ids)
|
||||
if result.success:
|
||||
changed = True
|
||||
else:
|
||||
LOG.info(
|
||||
f"Prevented from updating mailboxes [custom_domain_id={custom_domain.id}]: {result.reason.value}"
|
||||
)
|
||||
return jsonify(error="Forbidden"), 400
|
||||
|
||||
if changed:
|
||||
Session.commit()
|
||||
|
@ -6,6 +6,7 @@ from app import config
|
||||
from app.extensions import limiter
|
||||
from app.log import LOG
|
||||
from app.models import Job, ApiToCookieToken
|
||||
from app.user_audit_log_utils import emit_user_audit_log, UserAuditLogAction
|
||||
|
||||
|
||||
@api_bp.route("/user", methods=["DELETE"])
|
||||
@ -16,6 +17,11 @@ def delete_user():
|
||||
|
||||
"""
|
||||
# Schedule delete account job
|
||||
emit_user_audit_log(
|
||||
user=g.user,
|
||||
action=UserAuditLogAction.UserMarkedForDeletion,
|
||||
message=f"Marked user {g.user.id} ({g.user.email}) for deletion from API",
|
||||
)
|
||||
LOG.w("schedule delete account job for %s", g.user)
|
||||
Job.create(
|
||||
name=config.JOB_DELETE_ACCOUNT,
|
||||
|
Reference in New Issue
Block a user