Skip to content

Commit 29f12ce

Browse files
committed
ensure that username captured from Django is a string (#398)
fixes #397 closes #398
1 parent d4e8388 commit 29f12ce

File tree

4 files changed

+44
-12
lines changed

4 files changed

+44
-12
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
* Moved context.url to context.http.url for requests/urllib3 spans (#393, #394)
77
* Added support for using route as transaction name in Django 2.2+ (#86, #396)
8+
* Fixed an issue with custom user models in Django using non-string usernames (#397, #398)
89

910
## v4.1.0
1011
[Check the diff](https://github.com/elastic/apm-agent-python/compare/v4.0.3...v4.1.0)

elasticapm/contrib/django/client.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,12 @@ def get_user_info(self, request):
8383
if hasattr(user, "id"):
8484
user_info["id"] = encoding.keyword_field(user.id)
8585
if hasattr(user, "get_username"):
86-
user_info["username"] = encoding.keyword_field(user.get_username())
86+
user_info["username"] = encoding.keyword_field(encoding.force_text(user.get_username()))
8787
elif hasattr(user, "username"):
88-
user_info["username"] = encoding.keyword_field(user.username)
88+
user_info["username"] = encoding.keyword_field(encoding.force_text(user.username))
8989

9090
if hasattr(user, "email"):
91-
user_info["email"] = user.email
91+
user_info["email"] = encoding.force_text(user.email)
9292
except DatabaseError:
9393
# If the connection is closed or similar, we'll just skip this
9494
return {}

tests/contrib/django/django_tests.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,28 @@ def test_user_info_with_custom_user(django_elasticapm_client, client):
212212
assert "email" not in user_info
213213

214214

215+
@pytest.mark.django_db
216+
def test_user_info_with_custom_user_non_string_username(django_elasticapm_client, client):
217+
with override_settings(AUTH_USER_MODEL="testapp.MyIntUser"):
218+
from django.contrib.auth import get_user_model
219+
220+
MyIntUser = get_user_model()
221+
user = MyIntUser(my_username=1)
222+
user.set_password("admin")
223+
user.save()
224+
assert client.login(username=1, password="admin")
225+
with pytest.raises(Exception):
226+
client.get(reverse("elasticapm-raise-exc"))
227+
228+
assert len(django_elasticapm_client.events) == 1
229+
event = django_elasticapm_client.events[ERROR][0]
230+
assert "user" in event["context"]
231+
user_info = event["context"]["user"]
232+
assert "username" in user_info
233+
assert isinstance(user_info["username"], compat.text_type)
234+
assert user_info["username"] == "1"
235+
236+
215237
@pytest.mark.skipif(django.VERSION > (1, 9), reason="MIDDLEWARE_CLASSES removed in Django 2.0")
216238
def test_user_info_with_non_django_auth(django_elasticapm_client, client):
217239
with override_settings(
Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
# -*- coding: utf-8 -*-
22
from __future__ import absolute_import
33

4-
from django import VERSION as DJANGO_VERSION
4+
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
55
from django.db import models
66

7-
if DJANGO_VERSION >= (1, 5):
8-
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
97

10-
class MyUser(AbstractBaseUser):
11-
USERNAME_FIELD = "my_username"
12-
my_username = models.CharField(max_length=30)
8+
class MyUser(AbstractBaseUser):
9+
USERNAME_FIELD = "my_username"
10+
my_username = models.CharField(max_length=30)
1311

14-
objects = BaseUserManager()
12+
objects = BaseUserManager()
1513

16-
class Meta:
17-
abstract = False
14+
class Meta:
15+
abstract = False
16+
17+
18+
class MyIntUser(AbstractBaseUser):
19+
USERNAME_FIELD = "my_username"
20+
21+
my_username = models.IntegerField()
22+
23+
objects = BaseUserManager()
24+
25+
class Meta:
26+
abstract = False

0 commit comments

Comments
 (0)