@ -4,7 +4,6 @@ from uuid import UUID
|
|||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
from dramatiq.actor import actor
|
from dramatiq.actor import actor
|
||||||
from dramatiq.composition import group
|
|
||||||
from requests.exceptions import RequestException
|
from requests.exceptions import RequestException
|
||||||
from structlog.stdlib import get_logger
|
from structlog.stdlib import get_logger
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"""Event notification tasks"""
|
"""Event notification tasks"""
|
||||||
|
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from django.db.models.query_utils import Q
|
from django.db.models.query_utils import Q
|
||||||
from dramatiq.actor import actor
|
from dramatiq.actor import actor
|
||||||
from guardian.shortcuts import get_anonymous_user
|
from guardian.shortcuts import get_anonymous_user
|
||||||
|
@ -159,7 +159,7 @@ class AuthenticatorDuoStageViewSet(UsedByMixin, ModelViewSet):
|
|||||||
},
|
},
|
||||||
status=400,
|
status=400,
|
||||||
)
|
)
|
||||||
result = duo_import_devices.send(str(stage.pk)).get_result()
|
result = duo_import_devices.send(stage.pk).get_result()
|
||||||
return Response(data=result, status=200 if result["error"] == "" else 400)
|
return Response(data=result, status=200 if result["error"] == "" else 400)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
"""duo tasks"""
|
"""duo tasks"""
|
||||||
|
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from dramatiq.actor import actor
|
from dramatiq.actor import actor
|
||||||
from structlog.stdlib import get_logger
|
from structlog.stdlib import get_logger
|
||||||
|
|
||||||
@ -10,7 +12,7 @@ LOGGER = get_logger()
|
|||||||
|
|
||||||
|
|
||||||
@actor(store_results=True)
|
@actor(store_results=True)
|
||||||
def duo_import_devices(stage_pk: str):
|
def duo_import_devices(stage_pk: UUID):
|
||||||
"""Import duo devices"""
|
"""Import duo devices"""
|
||||||
created = 0
|
created = 0
|
||||||
stage: AuthenticatorDuoStage = AuthenticatorDuoStage.objects.filter(pk=stage_pk).first()
|
stage: AuthenticatorDuoStage = AuthenticatorDuoStage.objects.filter(pk=stage_pk).first()
|
||||||
|
@ -14,7 +14,6 @@ from authentik.stages.authenticator_webauthn.models import (
|
|||||||
WebAuthnDeviceType,
|
WebAuthnDeviceType,
|
||||||
)
|
)
|
||||||
from authentik.tasks.middleware import CurrentTask
|
from authentik.tasks.middleware import CurrentTask
|
||||||
from authentik.tasks.models import Task, TaskStatus
|
|
||||||
|
|
||||||
CACHE_KEY_MDS_NO = "goauthentik.io/stages/authenticator_webauthn/mds_no"
|
CACHE_KEY_MDS_NO = "goauthentik.io/stages/authenticator_webauthn/mds_no"
|
||||||
AAGUID_BLOB_PATH = Path(__file__).parent / "mds" / "aaguid.json"
|
AAGUID_BLOB_PATH = Path(__file__).parent / "mds" / "aaguid.json"
|
||||||
@ -32,7 +31,7 @@ def mds_ca() -> bytes:
|
|||||||
@actor
|
@actor
|
||||||
def webauthn_mds_import(force=False):
|
def webauthn_mds_import(force=False):
|
||||||
"""Background task to import FIDO Alliance MDS blob and AAGUIDs into database"""
|
"""Background task to import FIDO Alliance MDS blob and AAGUIDs into database"""
|
||||||
self: Task = CurrentTask.get_task()
|
self = CurrentTask.get_task()
|
||||||
with open(MDS_BLOB_PATH, mode="rb") as _raw_blob:
|
with open(MDS_BLOB_PATH, mode="rb") as _raw_blob:
|
||||||
blob = parse_blob(_raw_blob.read(), mds_ca())
|
blob = parse_blob(_raw_blob.read(), mds_ca())
|
||||||
to_create_update = [
|
to_create_update = [
|
||||||
@ -87,7 +86,4 @@ def webauthn_mds_import(force=False):
|
|||||||
unique_fields=["aaguid"],
|
unique_fields=["aaguid"],
|
||||||
)
|
)
|
||||||
|
|
||||||
self.set_status(
|
self.info("Successfully imported FIDO Alliance MDS blobs and AAGUIDs.")
|
||||||
TaskStatus.SUCCESSFUL,
|
|
||||||
"Successfully imported FIDO Alliance MDS blobs and AAGUIDs.",
|
|
||||||
)
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
"""email stage tasks"""
|
"""email stage tasks"""
|
||||||
|
|
||||||
from email.utils import make_msgid
|
from email.utils import make_msgid
|
||||||
from smtplib import SMTPException
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from django.core.mail import EmailMultiAlternatives
|
from django.core.mail import EmailMultiAlternatives
|
||||||
@ -17,7 +16,6 @@ from authentik.stages.authenticator_email.models import AuthenticatorEmailStage
|
|||||||
from authentik.stages.email.models import EmailStage
|
from authentik.stages.email.models import EmailStage
|
||||||
from authentik.stages.email.utils import logo_data
|
from authentik.stages.email.utils import logo_data
|
||||||
from authentik.tasks.middleware import CurrentTask
|
from authentik.tasks.middleware import CurrentTask
|
||||||
from authentik.tasks.models import Task, TaskStatus
|
|
||||||
|
|
||||||
LOGGER = get_logger()
|
LOGGER = get_logger()
|
||||||
|
|
||||||
@ -56,67 +54,54 @@ def send_mail(
|
|||||||
email_stage_pk: str | None = None,
|
email_stage_pk: str | None = None,
|
||||||
):
|
):
|
||||||
"""Send Email for Email Stage. Retries are scheduled automatically."""
|
"""Send Email for Email Stage. Retries are scheduled automatically."""
|
||||||
self: Task = CurrentTask.get_task()
|
self = CurrentTask.get_task()
|
||||||
# TODO: fix me
|
|
||||||
# self.save_on_success = False
|
|
||||||
message_id = make_msgid(domain=DNS_NAME)
|
message_id = make_msgid(domain=DNS_NAME)
|
||||||
self.set_uid(slugify(message_id.replace(".", "_").replace("@", "_")))
|
self.set_uid(slugify(message_id.replace(".", "_").replace("@", "_")))
|
||||||
try:
|
if not stage_class_path or not email_stage_pk:
|
||||||
if not stage_class_path or not email_stage_pk:
|
stage = EmailStage(use_global_settings=True)
|
||||||
stage = EmailStage(use_global_settings=True)
|
else:
|
||||||
else:
|
stage_class = path_to_class(stage_class_path)
|
||||||
stage_class = path_to_class(stage_class_path)
|
stages = stage_class.objects.filter(pk=email_stage_pk)
|
||||||
stages = stage_class.objects.filter(pk=email_stage_pk)
|
if not stages.exists():
|
||||||
if not stages.exists():
|
self.warning("Email stage does not exist anymore. Discarding message.")
|
||||||
self.set_status(
|
|
||||||
TaskStatus.WARNING,
|
|
||||||
"Email stage does not exist anymore. Discarding message.",
|
|
||||||
)
|
|
||||||
return
|
|
||||||
stage: EmailStage | AuthenticatorEmailStage = stages.first()
|
|
||||||
try:
|
|
||||||
backend = stage.backend
|
|
||||||
except ValueError as exc:
|
|
||||||
LOGGER.warning("failed to get email backend", exc=exc)
|
|
||||||
self.set_error(exc)
|
|
||||||
return
|
return
|
||||||
backend.open()
|
stage: EmailStage | AuthenticatorEmailStage = stages.first()
|
||||||
# Since django's EmailMessage objects are not JSON serialisable,
|
try:
|
||||||
# we need to rebuild them from a dict
|
backend = stage.backend
|
||||||
message_object = EmailMultiAlternatives()
|
except ValueError as exc:
|
||||||
for key, value in message.items():
|
LOGGER.warning("failed to get email backend", exc=exc)
|
||||||
setattr(message_object, key, value)
|
self.error(exc)
|
||||||
if not stage.use_global_settings:
|
return
|
||||||
message_object.from_email = stage.from_address
|
backend.open()
|
||||||
# Because we use the Message-ID as UID for the task, manually assign it
|
# Since django's EmailMessage objects are not JSON serialisable,
|
||||||
message_object.extra_headers["Message-ID"] = message_id
|
# we need to rebuild them from a dict
|
||||||
|
message_object = EmailMultiAlternatives()
|
||||||
|
for key, value in message.items():
|
||||||
|
setattr(message_object, key, value)
|
||||||
|
if not stage.use_global_settings:
|
||||||
|
message_object.from_email = stage.from_address
|
||||||
|
# Because we use the Message-ID as UID for the task, manually assign it
|
||||||
|
message_object.extra_headers["Message-ID"] = message_id
|
||||||
|
|
||||||
# Add the logo (we can't add it in the previous message since MIMEImage
|
# Add the logo (we can't add it in the previous message since MIMEImage
|
||||||
# can't be converted to json)
|
# can't be converted to json)
|
||||||
message_object.attach(logo_data())
|
message_object.attach(logo_data())
|
||||||
|
|
||||||
if (
|
if (
|
||||||
message_object.to
|
message_object.to
|
||||||
and isinstance(message_object.to[0], str)
|
and isinstance(message_object.to[0], str)
|
||||||
and "=?utf-8?" in message_object.to[0]
|
and "=?utf-8?" in message_object.to[0]
|
||||||
):
|
):
|
||||||
message_object.to = [message_object.to[0].split("<")[-1].replace(">", "")]
|
message_object.to = [message_object.to[0].split("<")[-1].replace(">", "")]
|
||||||
|
|
||||||
LOGGER.debug("Sending mail", to=message_object.to)
|
LOGGER.debug("Sending mail", to=message_object.to)
|
||||||
backend.send_messages([message_object])
|
backend.send_messages([message_object])
|
||||||
Event.new(
|
Event.new(
|
||||||
EventAction.EMAIL_SENT,
|
EventAction.EMAIL_SENT,
|
||||||
message=f"Email to {', '.join(message_object.to)} sent",
|
message=f"Email to {', '.join(message_object.to)} sent",
|
||||||
subject=message_object.subject,
|
subject=message_object.subject,
|
||||||
body=get_email_body(message_object),
|
body=get_email_body(message_object),
|
||||||
from_email=message_object.from_email,
|
from_email=message_object.from_email,
|
||||||
to_email=message_object.to,
|
to_email=message_object.to,
|
||||||
).save()
|
).save()
|
||||||
self.set_status(
|
self.info("Successfully sent mail.")
|
||||||
TaskStatus.SUCCESSFUL,
|
|
||||||
"Successfully sent Mail.",
|
|
||||||
)
|
|
||||||
except (SMTPException, ConnectionError, OSError) as exc:
|
|
||||||
LOGGER.debug("Error sending email, retrying...", exc=exc)
|
|
||||||
self.set_error(exc)
|
|
||||||
raise exc
|
|
||||||
|
Reference in New Issue
Block a user