Skip to content

Commit 4879c26

Browse files
authored
Merge pull request #199 from maykinmedia/feature/OAF#39-user-email-unique
🐛[maykinmedia/open-api-framework#39] make user emails unique
2 parents 768cb31 + ed48538 commit 4879c26

File tree

4 files changed

+48
-0
lines changed

4 files changed

+48
-0
lines changed

CHANGELOG.rst

+8
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,21 @@ New features:
1111

1212
* Add support for mounting Open Klant on a ``SUBPATH``
1313
* Elastic APM service name can now be configured with ``ELASTIC_APM_SERVICE_NAME`` envvar
14+
* Made user emails unique to prevent two users logging in with the same email, causing an error
1415

1516
.. warning::
1617

1718
The service name for Elastic APM is now configurable via the ``ELASTIC_APM_SERVICE_NAME`` environment variable.
1819
The default value changed from ``Open Klant - <ENVIRONMENT>`` to ``openklant - <ENVIRONMENT>``
1920

21+
.. warning::
22+
User email addresses will now be unique on a database level. The database migration will fail if there are already
23+
two or more users with the same email address. You must ensure this is not the case before upgrading.
24+
25+
26+
2027
Bugfixes/QoL:
28+
2129
* Settings module was refactored to use generic settings provided by Open API Framework
2230

2331

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Generated by Django 4.2.11 on 2024-07-02 14:30
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
("accounts", "0002_auto_20211116_0918"),
10+
]
11+
12+
operations = [
13+
migrations.AddConstraint(
14+
model_name="user",
15+
constraint=models.UniqueConstraint(
16+
condition=models.Q(("email", ""), _negated=True),
17+
fields=("email",),
18+
name="filled_email_unique",
19+
),
20+
),
21+
]

src/openklant/accounts/models.py

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
22
from django.contrib.auth.validators import UnicodeUsernameValidator
33
from django.db import models
4+
from django.db.models import Q
45
from django.utils import timezone
56
from django.utils.translation import gettext_lazy as _
67

@@ -52,6 +53,11 @@ class User(AbstractBaseUser, PermissionsMixin):
5253
class Meta:
5354
verbose_name = _("user")
5455
verbose_name_plural = _("users")
56+
constraints = [
57+
models.UniqueConstraint(
58+
fields=["email"], condition=~Q(email=""), name="filled_email_unique"
59+
)
60+
]
5561

5662
def get_full_name(self):
5763
"""

src/openklant/accounts/tests/test_user_manager.py

+13
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from django.db import IntegrityError
12
from django.test import TestCase
23

34
from ..models import User
@@ -20,3 +21,15 @@ def test_create_user(self):
2021
self.assertFalse(user.is_superuser)
2122
self.assertFalse(user.is_staff)
2223
self.assertFalse(user.has_usable_password())
24+
25+
def test_create_users_with_same_email(self):
26+
User.objects.create(username="AAA", email="aaa@aaa.aaa", password="aaa!")
27+
28+
with self.assertRaises(IntegrityError):
29+
User.objects.create(username="BBB", email="aaa@aaa.aaa", password="bbb!")
30+
31+
def test_create_user_with_blank_emails(self):
32+
User.objects.create(username="AAA", email="", password="aaa!")
33+
User.objects.create(username="BBB", email="", password="bbb!")
34+
35+
self.assertEqual(User.objects.count(), 2)

0 commit comments

Comments
 (0)