Skip to content

Commit 8091cbc

Browse files
authored
✨(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 12cc79b commit 8091cbc

File tree

6 files changed

+228
-99
lines changed

6 files changed

+228
-99
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ and this project adheres to
1111
### Added
1212

1313
- ⚡️(frontend) export html #1669
14+
- ✨(backend) allow to create a new user in a marketing system
1415

1516
### Changed
1617

docs/env.md

Lines changed: 100 additions & 97 deletions
Large diffs are not rendered by default.

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: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
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
@@ -12,7 +13,10 @@
1213
from lasuite.oidc_login.backends import get_oidc_refresh_token
1314

1415
from core import models
15-
from core.authentication.backends import OIDCAuthenticationBackend
16+
from core.authentication.backends import (
17+
OIDCAuthenticationBackend,
18+
create_or_update_contact,
19+
)
1620
from core.factories import UserFactory
1721

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

src/backend/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ dependencies = [
3434
"django-countries==8.1.0",
3535
"django-csp==4.0",
3636
"django-filter==25.2",
37-
"django-lasuite[all]==0.0.18",
37+
"django-lasuite[all]==0.0.22",
3838
"django-parler==2.3",
3939
"django-redis==6.0.0",
4040
"django-storages[s3]==1.14.6",

0 commit comments

Comments
 (0)