Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ and this project adheres to

## [Unreleased]

### Added

- ✨(backend) allow to create a new user in a marketing system

### Changed

- ♿(frontend) improve accessibility:
Expand Down
20 changes: 20 additions & 0 deletions src/backend/core/authentication/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from django.conf import settings
from django.core.exceptions import SuspiciousOperation

from lasuite.marketing.tasks import create_or_update_contact
from lasuite.oidc_login.backends import (
OIDCAuthenticationBackend as LaSuiteOIDCAuthenticationBackend,
)
Expand Down Expand Up @@ -57,3 +58,22 @@ def get_existing_user(self, sub, email):
return self.UserModel.objects.get_user_by_sub_or_email(sub, email)
except DuplicateEmailError as err:
raise SuspiciousOperation(err.message) from err

def post_get_or_create_user(self, user, claims, is_new_user):
"""
Post-processing after user creation or retrieval.

Args:
user (User): The user instance.
claims (dict): The claims dictionary.
is_new_user (bool): Indicates if the user was newly created.

Returns:
- None

"""

if is_new_user and settings.SIGNUP_NEW_USER_TO_MARKETING_EMAIL:
create_or_update_contact.delay(
email=user.email, attributes={"DOCS_SOURCE": ["SIGNIN"]}
)
83 changes: 82 additions & 1 deletion src/backend/core/tests/authentication/test_backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@

import random
import re
from unittest import mock

from django.core.exceptions import SuspiciousOperation
from django.test.utils import override_settings

import pytest
import responses
from cryptography.fernet import Fernet
from lasuite.marketing.backends import ContactData
from lasuite.oidc_login.backends import get_oidc_refresh_token

from core import models
from core.authentication.backends import OIDCAuthenticationBackend
from core.authentication.backends import (
OIDCAuthenticationBackend,
create_or_update_contact,
)
from core.factories import UserFactory

pytestmark = pytest.mark.django_db
Expand Down Expand Up @@ -509,3 +514,79 @@ def verify_token_mocked(*args, **kwargs):
assert user is not None
assert request.session["oidc_access_token"] == "test-access-token"
assert get_oidc_refresh_token(request.session) == "test-refresh-token"


def test_authentication_post_get_or_create_user_new_user_to_marketing_email(settings):
"""
New user and SIGNUP_NEW_USER_TO_MARKETING_EMAIL enabled should create a contact
in the marketing backend.
"""

user = UserFactory()
settings.SIGNUP_NEW_USER_TO_MARKETING_EMAIL = True

klass = OIDCAuthenticationBackend()
with mock.patch.object(
create_or_update_contact, "delay"
) as mock_create_or_update_contact:
klass.post_get_or_create_user(user, {}, True)
mock_create_or_update_contact.assert_called_once_with(
email=user.email, attributes={"DOCS_SOURCE": ["SIGNIN"]}
)


def test_authentication_post_get_or_create_user_new_user_to_marketing_email_disabled(
settings,
):
"""
New user and SIGNUP_NEW_USER_TO_MARKETING_EMAIL disabled should not create a contact
in the marketing backend.
"""

user = UserFactory()
settings.SIGNUP_NEW_USER_TO_MARKETING_EMAIL = False

klass = OIDCAuthenticationBackend()
with mock.patch.object(
create_or_update_contact, "delay"
) as mock_create_or_update_contact:
klass.post_get_or_create_user(user, {}, True)
mock_create_or_update_contact.assert_not_called()


def test_authentication_post_get_or_create_user_existing_user_to_marketing_email(
settings,
):
"""
Existing user and SIGNUP_NEW_USER_TO_MARKETING_EMAIL enabled should not create a contact
in the marketing backend.
"""

user = UserFactory()
settings.SIGNUP_NEW_USER_TO_MARKETING_EMAIL = True

klass = OIDCAuthenticationBackend()
with mock.patch.object(
create_or_update_contact, "delay"
) as mock_create_or_update_contact:
klass.post_get_or_create_user(user, {}, False)
mock_create_or_update_contact.assert_not_called()


def test_authentication_post_get_or_create_user_existing_user_to_marketing_email_disabled(
settings,
):
"""
Existing user and SIGNUP_NEW_USER_TO_MARKETING_EMAIL disabled should not create a contact
in the marketing backend.
"""

user = UserFactory()
settings.SIGNUP_NEW_USER_TO_MARKETING_EMAIL = False

klass = OIDCAuthenticationBackend()
with mock.patch.object(
create_or_update_contact, "delay"
) as mock_create_or_update_contact:
klass.post_get_or_create_user(user, {}, False)
mock_create_or_update_contact.assert_not_called()
25 changes: 25 additions & 0 deletions src/backend/impress/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ class Base(Configuration):
# OIDC third party
"mozilla_django_oidc",
"lasuite.malware_detection",
"lasuite.marketing",
"csp",
]

Expand Down Expand Up @@ -808,6 +809,30 @@ class Base(Configuration):
),
}

# Marketing and communication settings
SIGNUP_NEW_USER_TO_MARKETING_EMAIL = values.BooleanValue(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

False,
environ_name="SIGNUP_NEW_USER_TO_MARKETING_EMAIL",
environ_prefix=None,
help_text=(
"When enabled, new users are automatically added to mailing list "
"for product updates, marketing communications, and customized emails. "
),
)

LASUITE_MARKETING = {
"BACKEND": values.Value(
"lasuite.marketing.backends.dummy.DummyBackend",
environ_name="LASUITE_MARKETING_BACKEND",
environ_prefix=None,
),
"PARAMETERS": values.DictValue(
default={},
environ_name="LASUITE_MARKETING_PARAMETERS",
environ_prefix=None,
),
}
Comment on lines +823 to +834
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any references in the tests about LASUITE_MARKETING, should we add a doc about how it is working ?


# pylint: disable=invalid-name
@property
def ENVIRONMENT(self):
Expand Down
2 changes: 1 addition & 1 deletion src/backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ dependencies = [
"django-countries==8.1.0",
"django-csp==4.0",
"django-filter==25.2",
"django-lasuite[all]==0.0.18",
"django-lasuite[all]==0.0.22",
"django-parler==2.3",
"django-redis==6.0.0",
"django-storages[s3]==1.14.6",
Expand Down
Loading