Skip to content

Commit 85700d5

Browse files
committed
✨(backend) allow to create a new user in a marketing system
We want to create a new user in a marketing system to create a dedicated onboarding for each of them. The marketing service is implemented in the django-lasuite library and it is possible to pick the backend we want or implement a new one following the documentation on this library.
1 parent a07ab70 commit 85700d5

File tree

4 files changed

+131
-1
lines changed

4 files changed

+131
-1
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ and this project adheres to
66

77
## [Unreleased]
88

9+
### Added
10+
11+
- ✨(backend) allow to create a new user in a marketing system
12+
913
### Changed
1014

1115
- ♿(frontend) improve accessibility:

src/backend/core/authentication/backends.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from django.conf import settings
77
from django.core.exceptions import SuspiciousOperation
88

9+
from lasuite.marketing.tasks import create_or_update_contact
910
from lasuite.oidc_login.backends import (
1011
OIDCAuthenticationBackend as LaSuiteOIDCAuthenticationBackend,
1112
)
@@ -57,3 +58,22 @@ def get_existing_user(self, sub, email):
5758
return self.UserModel.objects.get_user_by_sub_or_email(sub, email)
5859
except DuplicateEmailError as err:
5960
raise SuspiciousOperation(err.message) from err
61+
62+
def post_get_or_create_user(self, user, claims, is_new_user):
63+
"""
64+
Post-processing after user creation or retrieval.
65+
66+
Args:
67+
user (User): The user instance.
68+
claims (dict): The claims dictionary.
69+
is_new_user (bool): Indicates if the user was newly created.
70+
71+
Returns:
72+
- None
73+
74+
"""
75+
76+
if is_new_user and settings.SIGNUP_NEW_USER_TO_MARKETING_EMAIL:
77+
create_or_update_contact.delay(
78+
email=user.email, attributes={"DOCS_SOURCE": ["SIGNIN"]}
79+
)

src/backend/core/tests/authentication/test_backends.py

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,22 @@
22

33
import random
44
import re
5+
from unittest import mock
56

67
from django.core.exceptions import SuspiciousOperation
78
from django.test.utils import override_settings
89

910
import pytest
1011
import responses
1112
from cryptography.fernet import Fernet
13+
from lasuite.marketing.backends import ContactData
1214
from lasuite.oidc_login.backends import get_oidc_refresh_token
1315

1416
from core import models
15-
from core.authentication.backends import OIDCAuthenticationBackend
17+
from core.authentication.backends import (
18+
OIDCAuthenticationBackend,
19+
create_or_update_contact,
20+
)
1621
from core.factories import UserFactory
1722

1823
pytestmark = pytest.mark.django_db
@@ -509,3 +514,79 @@ def verify_token_mocked(*args, **kwargs):
509514
assert user is not None
510515
assert request.session["oidc_access_token"] == "test-access-token"
511516
assert get_oidc_refresh_token(request.session) == "test-refresh-token"
517+
518+
519+
def test_authentication_post_get_or_create_user_new_user_to_marketing_email(settings):
520+
"""
521+
New user and SIGNUP_NEW_USER_TO_MARKETING_EMAIL enabled should create a contact
522+
in the marketing backend.
523+
"""
524+
525+
user = UserFactory()
526+
settings.SIGNUP_NEW_USER_TO_MARKETING_EMAIL = True
527+
528+
klass = OIDCAuthenticationBackend()
529+
with mock.patch.object(
530+
create_or_update_contact, "delay"
531+
) as mock_create_or_update_contact:
532+
klass.post_get_or_create_user(user, {}, True)
533+
mock_create_or_update_contact.assert_called_once_with(
534+
email=user.email, attributes={"DOCS_SOURCE": ["SIGNIN"]}
535+
)
536+
537+
538+
def test_authentication_post_get_or_create_user_new_user_to_marketing_email_disabled(
539+
settings,
540+
):
541+
"""
542+
New user and SIGNUP_NEW_USER_TO_MARKETING_EMAIL disabled should not create a contact
543+
in the marketing backend.
544+
"""
545+
546+
user = UserFactory()
547+
settings.SIGNUP_NEW_USER_TO_MARKETING_EMAIL = False
548+
549+
klass = OIDCAuthenticationBackend()
550+
with mock.patch.object(
551+
create_or_update_contact, "delay"
552+
) as mock_create_or_update_contact:
553+
klass.post_get_or_create_user(user, {}, True)
554+
mock_create_or_update_contact.assert_not_called()
555+
556+
557+
def test_authentication_post_get_or_create_user_existing_user_to_marketing_email(
558+
settings,
559+
):
560+
"""
561+
Existing user and SIGNUP_NEW_USER_TO_MARKETING_EMAIL enabled should not create a contact
562+
in the marketing backend.
563+
"""
564+
565+
user = UserFactory()
566+
settings.SIGNUP_NEW_USER_TO_MARKETING_EMAIL = True
567+
568+
klass = OIDCAuthenticationBackend()
569+
with mock.patch.object(
570+
create_or_update_contact, "delay"
571+
) as mock_create_or_update_contact:
572+
klass.post_get_or_create_user(user, {}, False)
573+
mock_create_or_update_contact.assert_not_called()
574+
575+
576+
def test_authentication_post_get_or_create_user_existing_user_to_marketing_email_disabled(
577+
settings,
578+
):
579+
"""
580+
Existing user and SIGNUP_NEW_USER_TO_MARKETING_EMAIL disabled should not create a contact
581+
in the marketing backend.
582+
"""
583+
584+
user = UserFactory()
585+
settings.SIGNUP_NEW_USER_TO_MARKETING_EMAIL = False
586+
587+
klass = OIDCAuthenticationBackend()
588+
with mock.patch.object(
589+
create_or_update_contact, "delay"
590+
) as mock_create_or_update_contact:
591+
klass.post_get_or_create_user(user, {}, False)
592+
mock_create_or_update_contact.assert_not_called()

src/backend/impress/settings.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ class Base(Configuration):
328328
# OIDC third party
329329
"mozilla_django_oidc",
330330
"lasuite.malware_detection",
331+
"lasuite.marketing",
331332
"csp",
332333
]
333334

@@ -808,6 +809,30 @@ class Base(Configuration):
808809
),
809810
}
810811

812+
# Marketing and communication settings
813+
SIGNUP_NEW_USER_TO_MARKETING_EMAIL = values.BooleanValue(
814+
False,
815+
environ_name="SIGNUP_NEW_USER_TO_MARKETING_EMAIL",
816+
environ_prefix=None,
817+
help_text=(
818+
"When enabled, new users are automatically added to mailing list "
819+
"for product updates, marketing communications, and customized emails. "
820+
),
821+
)
822+
823+
LASUITE_MARKETING = {
824+
"BACKEND": values.Value(
825+
"lasuite.marketing.backends.dummy.DummyBackend",
826+
environ_name="LASUITE_MARKETING_BACKEND",
827+
environ_prefix=None,
828+
),
829+
"PARAMETERS": values.DictValue(
830+
default={},
831+
environ_name="LASUITE_MARKETING_PARAMETERS",
832+
environ_prefix=None,
833+
),
834+
}
835+
811836
# pylint: disable=invalid-name
812837
@property
813838
def ENVIRONMENT(self):

0 commit comments

Comments
 (0)