Skip to content

Commit 09f227e

Browse files
authored
Merge pull request #315 from Mosquito-Alert/fix_device_active
Fix Device.active when logged_in + rename is_logged_in to active_session
2 parents 0101335 + acf27ef commit 09f227e

File tree

9 files changed

+71
-42
lines changed

9 files changed

+71
-42
lines changed

api/auth/serializers.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,10 @@ def validate(self, attrs):
7878
data["refresh"] = str(refresh)
7979
data["access"] = str(refresh.access_token)
8080

81-
self.device.is_logged_in = True
82-
_update_fields=["is_logged_in"]
81+
self.device.active_session = True
82+
# NOTE: adding 'active' in the update_fields is important.
83+
# The save() method will trigger active = False depending on the value of active_session.
84+
_update_fields=["active_session", "active"]
8385
# Update last_login device
8486
if api_settings.UPDATE_LAST_LOGIN:
8587
self.device.last_login = timezone.now()

api/serializers.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,6 +1463,7 @@ def validate(self, data):
14631463

14641464
return data
14651465

1466+
@transaction.atomic
14661467
def create(self, validated_data):
14671468
# Extract the user and model from the data
14681469
user = validated_data.get('user')

api/tests/test_views.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -539,8 +539,9 @@ def test_device_is_set_to_logged_in_on_login_if_not_logged(self, app_user, user_
539539
user=app_user,
540540
device_id='unique_id_for_device',
541541
registration_id='fcm_token',
542-
is_logged_in=False
542+
active_session=False
543543
)
544+
assert not device.active
544545
response = client.post(
545546
self.endpoint,
546547
data={
@@ -552,16 +553,18 @@ def test_device_is_set_to_logged_in_on_login_if_not_logged(self, app_user, user_
552553
assert response.status_code == status.HTTP_200_OK
553554

554555
device.refresh_from_db()
555-
assert device.is_logged_in
556+
assert device.active_session
557+
assert device.active
556558

557559
def test_device_is_set_to_not_logged_in_if_login_with_duplicated_device_id(self, app_user, user_password, client):
558560
dummy_user = TigaUser.objects.create()
559561
device = Device.objects.create(
560562
user=dummy_user,
561563
device_id='unique_id_for_device',
562564
registration_id='fcm_token',
563-
is_logged_in=True
565+
active_session=True
564566
)
567+
assert device.active
565568
# Login with same device_id but different user.
566569
response = client.post(
567570
self.endpoint,
@@ -574,7 +577,8 @@ def test_device_is_set_to_not_logged_in_if_login_with_duplicated_device_id(self,
574577
assert response.status_code == status.HTTP_200_OK
575578

576579
device.refresh_from_db()
577-
assert not device.is_logged_in
580+
assert not device.active_session
581+
assert not device.active
578582

579583
@pytest.mark.parametrize(
580584
"token_field",
@@ -654,7 +658,7 @@ def test_inactive_device_is_set_to_active_on_registration_id_change(self, app_us
654658
os_name='android',
655659
os_version='32',
656660
active=False,
657-
is_logged_in=True
661+
active_session=True
658662
)
659663
response = app_api_client.patch(
660664
self.endpoint + f"{device.device_id}/",

tigaserver_app/admin.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class MobileAppAdmin(admin.ModelAdmin):
6969
class DeviceInline(admin.StackedInline):
7070
model = Device
7171
fields = (
72-
('device_id', 'is_logged_in', 'last_login'),
72+
('device_id', 'active_session', 'last_login'),
7373
('registration_id', 'active'),
7474
'type',
7575
'mobile_app',
@@ -81,7 +81,7 @@ class DeviceInline(admin.StackedInline):
8181
readonly_fields = (
8282
'date_created',
8383
'updated_at',
84-
'is_logged_in',
84+
'active_session',
8585
'last_login'
8686
)
8787
extra = 0

tigaserver_app/managers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ class DeviceQuerySet(FCMDeviceQuerySet):
125125
def deactivate_devices_with_error_results(self, *args, **kwargs):
126126
deactivated_ids = super().deactivate_devices_with_error_results(*args, **kwargs)
127127

128-
self.filter(registration_id__in=deactivated_ids).update(is_logged_in=False)
128+
self.filter(registration_id__in=deactivated_ids).update(active_session=False)
129129

130130
return deactivated_ids
131131

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Generated by Django 3.2.25 on 2025-08-22 12:14
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('tigaserver_app', '0084_alter_mobileapp_package_version'),
10+
]
11+
12+
operations = [
13+
migrations.RemoveConstraint(
14+
model_name='device',
15+
name='unique_is_logged_in_device_id',
16+
),
17+
migrations.RenameField(
18+
model_name='device',
19+
old_name='is_logged_in',
20+
new_name='active_session',
21+
),
22+
migrations.AddConstraint(
23+
model_name='device',
24+
constraint=models.UniqueConstraint(condition=models.Q(('active_session', True), ('device_id__isnull', False), models.Q(('device_id__exact', ''), _negated=True)), fields=('active_session', 'device_id'), name='unique_active_session_device_id'),
25+
),
26+
]

tigaserver_app/models.py

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -364,9 +364,9 @@ def __str__(self):
364364

365365
class Device(AbstractFCMDevice):
366366
# NOTE: self.active : If the FCM TOKEN is active
367-
# self.is_logged_in : If the Device is is_logged_in for the user
367+
# self.active_session : If the Device has and active logged session for the user
368368

369-
# NOTE: if ever work on a logout method, set is_logged_in/active to False on logout.
369+
# NOTE: if ever work on a logout method, set active_session/active to False on logout.
370370
# Override user to make FK to TigaUser instead of User
371371
user = models.ForeignKey(
372372
TigaUser,
@@ -376,7 +376,7 @@ class Device(AbstractFCMDevice):
376376
)
377377

378378
mobile_app = models.ForeignKey(MobileApp, null=True, on_delete=models.PROTECT)
379-
is_logged_in = models.BooleanField(default=False)
379+
active_session = models.BooleanField(default=False)
380380

381381
registration_id = models.TextField(null=True, db_index=True, verbose_name='Registration token')
382382

@@ -422,7 +422,7 @@ class Device(AbstractFCMDevice):
422422
'name',
423423
'date_created',
424424
'updated_at',
425-
'is_logged_in',
425+
'active_session',
426426
'last_login',
427427
'user'
428428
],
@@ -462,12 +462,7 @@ def save(self, *args, **kwargs):
462462
if self.os_locale:
463463
self.os_locale = standarize_language_tag(self.os_locale)
464464

465-
_fields_with_changes = self.__get_changed_fields(update_fields=kwargs.get('update_fields'))
466-
if self.registration_id and 'registration_id' in _fields_with_changes:
467-
self.active = True
468-
469-
if not self.registration_id or not self.is_logged_in:
470-
self.active = False
465+
self.active = bool(self.registration_id and self.active_session)
471466

472467
if self.active and self.registration_id:
473468
update_device_qs = Device.objects.filter(active=True, registration_id=self.registration_id)
@@ -480,19 +475,20 @@ def save(self, *args, **kwargs):
480475
device._change_reason = 'Another user has created/update a device with the same registration_id'
481476
device.save()
482477

483-
if self.is_logged_in and self.device_id:
484-
update_device_qs = Device.objects.filter(is_logged_in=True, device_id=self.device_id)
478+
if self.active_session and self.device_id:
479+
update_device_qs = Device.objects.filter(active_session=True, device_id=self.device_id)
485480
if self.pk:
486481
update_device_qs = update_device_qs.exclude(pk=self.pk)
487482

488483
for device in update_device_qs.iterator():
489-
device.is_logged_in = False
484+
device.active_session = False
490485
# For simple history
491486
device._change_reason = 'Another user has created/update a device with the same device_id'
492487
device.save()
493488

494489
if self.pk:
495490
_tracked_fields = [field.name for field in self.__class__.history.model._meta.get_fields()]
491+
_fields_with_changes = self.__get_changed_fields(update_fields=kwargs.get('update_fields'))
496492
if not any(element in _tracked_fields for element in _fields_with_changes):
497493
# Only will create history if at least one tracked field has changed.
498494
self.skip_history_when_saving = True
@@ -524,9 +520,9 @@ class Meta(AbstractFCMDevice.Meta):
524520
condition=models.Q(active=True, registration_id__isnull=False) & ~models.Q(registration_id__exact=''),
525521
),
526522
models.UniqueConstraint(
527-
fields=['is_logged_in', 'device_id'],
528-
name='unique_is_logged_in_device_id',
529-
condition=models.Q(is_logged_in=True, device_id__isnull=False) & ~models.Q(device_id__exact=''),
523+
fields=['active_session', 'device_id'],
524+
name='unique_active_session_device_id',
525+
condition=models.Q(active_session=True, device_id__isnull=False) & ~models.Q(device_id__exact=''),
530526
),
531527
models.UniqueConstraint(
532528
fields=['user', 'device_id'],
@@ -1995,7 +1991,7 @@ def save(self, *args, **kwargs):
19951991
).select_for_update().order_by('-last_login').first() or Device.objects.filter(
19961992
user=self.user,
19971993
model__isnull=True,
1998-
is_logged_in=True,
1994+
active_session=True,
19991995
pk__in=models.Subquery(
20001996
Device.objects.filter(
20011997
user=models.OuterRef('user'),
@@ -2035,7 +2031,7 @@ def save(self, *args, **kwargs):
20352031
device.os_version = self.os_version
20362032
device.os_locale = self.os_language
20372033
device.mobile_app = self.mobile_app
2038-
device.is_logged_in = True
2034+
device.active_session = True
20392035
device.active = True
20402036
device.last_login = timezone.now()
20412037

tigaserver_app/tests/tests.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def setUp(self):
107107
Device.objects.create(
108108
user=t,
109109
active=True,
110-
is_logged_in=True,
110+
active_session=True,
111111
registration_id="caM8sSvLQKmX4Iai1xGb9w:APA91bGhzu3DYeYLTh-M9elzrhK492V0J3wDrsFsUDaw13v3Wxzb_9YbemsnMTb3N7_GilKwtS73NtbywSloNRo2alfpIMu29FKszZYr6WxoNdGao6PGNRf4kS1tKCiEAZgFvMkdLkgT"
112112
)
113113

@@ -615,7 +615,7 @@ def test_device_is_created_if_not_exist_on_new_report(self):
615615
self.assertEqual(device.os_version, "testVersion")
616616
self.assertEqual(device.os_locale, "es-ES")
617617
self.assertEqual(device.mobile_app, report.mobile_app)
618-
self.assertEqual(device.is_logged_in, True)
618+
self.assertEqual(device.active_session, True)
619619
self.assertEqual(device.last_login, timezone.now())
620620

621621
self.assertIsNone(device.registration_id)
@@ -631,7 +631,7 @@ def test_device_with_model_null_is_updated_on_new_report(self):
631631
user=user,
632632
model=None,
633633
active=True,
634-
is_logged_in=True,
634+
active_session=True,
635635
last_login=timezone.now()-timedelta(days=1)
636636
)
637637
self.assertIsNone(device.model)
@@ -663,7 +663,7 @@ def test_device_with_model_null_is_updated_on_new_report(self):
663663
self.assertEqual(device.os_version, "testVersion")
664664
self.assertEqual(device.os_locale, "es-ES")
665665
self.assertEqual(device.mobile_app, mobile_app)
666-
self.assertTrue(device.is_logged_in)
666+
self.assertTrue(device.active_session)
667667
self.assertTrue(device.active)
668668
self.assertEqual(device.last_login, timezone.now())
669669
self.assertEqual(device.registration_id, fcm_token)
@@ -676,7 +676,7 @@ def test_device_with_model_is_updated_on_new_report(self):
676676
user=user,
677677
model="test_model",
678678
active=True,
679-
is_logged_in=True,
679+
active_session=True,
680680
last_login=timezone.now()-timedelta(days=1)
681681
)
682682
self.assertIsNone(device.type)
@@ -708,7 +708,7 @@ def test_device_with_model_is_updated_on_new_report(self):
708708
self.assertEqual(device.os_version, "testVersion")
709709
self.assertEqual(device.os_locale, "es-ES")
710710
self.assertEqual(device.mobile_app, mobile_app)
711-
self.assertEqual(device.is_logged_in, True)
711+
self.assertEqual(device.active_session, True)
712712
self.assertEqual(device.last_login, timezone.now())
713713

714714
def test_POST_with_not_valid_version_number_raise_400(self):
@@ -977,7 +977,7 @@ def setUp(self):
977977
Device.objects.create(
978978
user=t,
979979
active=True,
980-
is_logged_in=True,
980+
active_session=True,
981981
registration_id='caM8sSvLQKmX4Iai1xGb9w:APA91bGhzu3DYeYLTh-M9elzrhK492V0J3wDrsFsUDaw13v3Wxzb_9YbemsnMTb3N7_GilKwtS73NtbywSloNRo2alfpIMu29FKszZYr6WxoNdGao6PGNRf4kS1tKCiEAZgFvMkdLkgT'
982982
)
983983

@@ -1943,7 +1943,7 @@ def test_device_is_updated_if_previous_model_exist_and_new_model_None_also(self)
19431943
model="test_model",
19441944
registration_id="fcm_token",
19451945
active=True,
1946-
is_logged_in=True,
1946+
active_session=True,
19471947
last_login=timezone.now() - timedelta(days=1)
19481948
)
19491949
_ = Report.objects.create(
@@ -1975,7 +1975,7 @@ def test_device_is_updated_if_previous_model_exist_and_new_model_None_also(self)
19751975
model=None,
19761976
registration_id="new_fcm_token",
19771977
active=True,
1978-
is_logged_in=True,
1978+
active_session=True,
19791979
last_login=timezone.now() - timedelta(minutes=1)
19801980
)
19811981

@@ -1984,7 +1984,7 @@ def test_device_is_updated_if_previous_model_exist_and_new_model_None_also(self)
19841984
model=None,
19851985
registration_id="new_fcm_token2",
19861986
active=True,
1987-
is_logged_in=True,
1987+
active_session=True,
19881988
last_login=timezone.now()
19891989
)
19901990

@@ -2376,7 +2376,7 @@ def test_post_fcm_token_creates_new_device_if_no_device_exist(self):
23762376
registration_id=fcm_token
23772377
)
23782378
self.assertTrue(device.active)
2379-
self.assertTrue(device.is_logged_in)
2379+
self.assertTrue(device.active_session)
23802380
self.assertEqual(device.last_login, timezone.now())
23812381
self.assertIsNone(device.model)
23822382

@@ -2390,7 +2390,7 @@ def test_post_fcm_token_updates_device_with_same_registration_id(self):
23902390
user=self.tiga_user,
23912391
registration_id=fcm_token,
23922392
active=True,
2393-
is_logged_in=True,
2393+
active_session=True,
23942394
last_login=timezone.now() - timedelta(days=1)
23952395
)
23962396

@@ -2411,7 +2411,7 @@ def test_post_fcm_token_updates_device_with_same_registration_id(self):
24112411

24122412
self.assertEqual(device.registration_id, fcm_token)
24132413
self.assertTrue(device.active)
2414-
self.assertTrue(device.is_logged_in)
2414+
self.assertTrue(device.active_session)
24152415
self.assertEqual(device.last_login, timezone.now())
24162416

24172417

tigaserver_app/views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,7 @@ def token(request):
10511051
registration_id=token,
10521052
defaults={
10531053
'active': True,
1054-
'is_logged_in': True,
1054+
'active_session': True,
10551055
'last_login': timezone.now()
10561056
}
10571057
)

0 commit comments

Comments
 (0)