mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2025-07-13 22:40:16 +02:00
parent
df3acccc50
commit
319cba8653
@ -6,7 +6,7 @@ from django.db.models import Q
|
|||||||
from allianceauth.services.hooks import ServicesHook
|
from allianceauth.services.hooks import ServicesHook
|
||||||
from django.db.models.signals import pre_save, post_save, pre_delete, post_delete, m2m_changed
|
from django.db.models.signals import pre_save, post_save, pre_delete, post_delete, m2m_changed
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from allianceauth.authentication.models import State, get_guest_state, CharacterOwnership, UserProfile
|
from allianceauth.authentication.models import State, get_guest_state, CharacterOwnership, UserProfile, OwnershipRecord
|
||||||
from allianceauth.hooks import get_hooks
|
from allianceauth.hooks import get_hooks
|
||||||
from allianceauth.eveonline.models import EveCharacter
|
from allianceauth.eveonline.models import EveCharacter
|
||||||
from django.forms import ModelForm
|
from django.forms import ModelForm
|
||||||
@ -160,12 +160,23 @@ class StateAdmin(admin.ModelAdmin):
|
|||||||
return obj.userprofile_set.all().count()
|
return obj.userprofile_set.all().count()
|
||||||
|
|
||||||
|
|
||||||
@admin.register(CharacterOwnership)
|
class BaseOwnershipAdmin(admin.ModelAdmin):
|
||||||
class CharacterOwnershipAdmin(admin.ModelAdmin):
|
|
||||||
list_display = ('user', 'character')
|
list_display = ('user', 'character')
|
||||||
search_fields = ('user__username', 'character__character_name', 'character__corporation_name', 'character__alliance_name')
|
search_fields = ('user__username', 'character__character_name', 'character__corporation_name', 'character__alliance_name')
|
||||||
readonly_fields = ('owner_hash', 'character')
|
|
||||||
|
|
||||||
|
def get_readonly_fields(self, request, obj=None):
|
||||||
|
if obj and obj.pk:
|
||||||
|
return 'owner_hash', 'character'
|
||||||
|
return tuple()
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(OwnershipRecord)
|
||||||
|
class OwnershipRecordAdmin(BaseOwnershipAdmin):
|
||||||
|
list_display = BaseOwnershipAdmin.list_display + ('created',)
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(CharacterOwnership)
|
||||||
|
class CharacterOwnershipAdmin(BaseOwnershipAdmin):
|
||||||
def has_add_permission(self, request):
|
def has_add_permission(self, request):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ from django.contrib.auth.backends import ModelBackend
|
|||||||
from django.contrib.auth.models import Permission
|
from django.contrib.auth.models import Permission
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
from .models import UserProfile, CharacterOwnership
|
from .models import UserProfile, CharacterOwnership, OwnershipRecord
|
||||||
|
|
||||||
|
|
||||||
class StateBackend(ModelBackend):
|
class StateBackend(ModelBackend):
|
||||||
@ -43,7 +43,18 @@ class StateBackend(ModelBackend):
|
|||||||
CharacterOwnership.objects.create_by_token(token)
|
CharacterOwnership.objects.create_by_token(token)
|
||||||
return profile.user
|
return profile.user
|
||||||
except UserProfile.DoesNotExist:
|
except UserProfile.DoesNotExist:
|
||||||
pass
|
# now we check historical records to see if this is a returning user
|
||||||
|
records = OwnershipRecord.objects.filter(owner_hash=token.character_owner_hash).filter(character__character_id=token.character_id)
|
||||||
|
if records.exists():
|
||||||
|
# we've seen this character owner before. Re-attach to their old user account
|
||||||
|
user = records[0].user
|
||||||
|
token.user = user
|
||||||
|
co = CharacterOwnership.objects.create_by_token(token)
|
||||||
|
if not user.profile.main_character:
|
||||||
|
# set this as their main by default if they have none
|
||||||
|
user.profile.main_character = co.character
|
||||||
|
user.profile.save()
|
||||||
|
return user
|
||||||
return self.create_user(token)
|
return self.create_user(token)
|
||||||
|
|
||||||
def create_user(self, token):
|
def create_user(self, token):
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
# Generated by Django 2.0.4 on 2018-04-14 18:28
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
def create_initial_records(apps, schema_editor):
|
||||||
|
OwnershipRecord = apps.get_model('authentication', 'OwnershipRecord')
|
||||||
|
CharacterOwnership = apps.get_model('authentication', 'CharacterOwnership')
|
||||||
|
|
||||||
|
OwnershipRecord.objects.bulk_create([
|
||||||
|
OwnershipRecord(user=o.user, character=o.character, owner_hash=o.owner_hash) for o in CharacterOwnership.objects.all()
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('eveonline', '0009_on_delete'),
|
||||||
|
('authentication', '0015_user_profiles'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='OwnershipRecord',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('owner_hash', models.CharField(db_index=True, max_length=28)),
|
||||||
|
('created', models.DateTimeField(auto_now=True)),
|
||||||
|
('character', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ownership_records', to='eveonline.EveCharacter')),
|
||||||
|
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ownership_records', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'ordering': ['-created'],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.RunPython(create_initial_records, migrations.RunPython.noop)
|
||||||
|
]
|
@ -96,3 +96,16 @@ class CharacterOwnership(models.Model):
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s: %s" % (self.user, self.character)
|
return "%s: %s" % (self.user, self.character)
|
||||||
|
|
||||||
|
|
||||||
|
class OwnershipRecord(models.Model):
|
||||||
|
character = models.ForeignKey(EveCharacter, on_delete=models.CASCADE, related_name='ownership_records')
|
||||||
|
owner_hash = models.CharField(max_length=28, db_index=True)
|
||||||
|
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='ownership_records')
|
||||||
|
created = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ['-created']
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "%s: %s on %s" % (self.user, self.character, self.created)
|
@ -1,6 +1,6 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from .models import CharacterOwnership, UserProfile, get_guest_state, State
|
from .models import CharacterOwnership, UserProfile, get_guest_state, State, OwnershipRecord
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.db.models.signals import pre_save, post_save, pre_delete, post_delete, m2m_changed
|
from django.db.models.signals import pre_save, post_save, pre_delete, post_delete, m2m_changed
|
||||||
@ -153,3 +153,15 @@ def check_state_on_character_update(sender, instance, *args, **kwargs):
|
|||||||
except UserProfile.DoesNotExist:
|
except UserProfile.DoesNotExist:
|
||||||
logger.debug("Character {0} is not a main character. No state assessment required.".format(instance))
|
logger.debug("Character {0} is not a main character. No state assessment required.".format(instance))
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(post_save, sender=CharacterOwnership)
|
||||||
|
def ownership_record_creation(sender, instance, created, *args, **kwargs):
|
||||||
|
if created:
|
||||||
|
records = OwnershipRecord.objects.filter(owner_hash=instance.owner_hash).filter(character=instance.character)
|
||||||
|
if records.exists():
|
||||||
|
if records[0].user == instance.user: # most recent record is sorted first
|
||||||
|
logger.debug("Already have ownership record of {0} by user {1}".format(instance.character, instance.user))
|
||||||
|
return
|
||||||
|
logger.info("Character {0} has a new owner {1}. Creating ownership record.".format(instance.character, instance.user))
|
||||||
|
OwnershipRecord.objects.create(user=instance.user, character=instance.character, owner_hash=instance.owner_hash)
|
@ -3,7 +3,7 @@ from unittest import mock
|
|||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from allianceauth.tests.auth_utils import AuthUtils
|
from allianceauth.tests.auth_utils import AuthUtils
|
||||||
from .models import CharacterOwnership, UserProfile, State, get_guest_state
|
from .models import CharacterOwnership, UserProfile, State, get_guest_state, OwnershipRecord
|
||||||
from .backends import StateBackend
|
from .backends import StateBackend
|
||||||
from .tasks import check_character_ownership
|
from .tasks import check_character_ownership
|
||||||
from allianceauth.eveonline.models import EveCharacter, EveCorporationInfo, EveAllianceInfo
|
from allianceauth.eveonline.models import EveCharacter, EveCorporationInfo, EveAllianceInfo
|
||||||
@ -90,6 +90,7 @@ class BackendTestCase(TestCase):
|
|||||||
corporation_ticker='CORP',
|
corporation_ticker='CORP',
|
||||||
)
|
)
|
||||||
cls.user = AuthUtils.create_user('test_user', disconnect_signals=True)
|
cls.user = AuthUtils.create_user('test_user', disconnect_signals=True)
|
||||||
|
cls.old_user = AuthUtils.create_user('old_user', disconnect_signals=True)
|
||||||
AuthUtils.disconnect_signals()
|
AuthUtils.disconnect_signals()
|
||||||
CharacterOwnership.objects.create(user=cls.user, character=cls.main_character, owner_hash='1')
|
CharacterOwnership.objects.create(user=cls.user, character=cls.main_character, owner_hash='1')
|
||||||
CharacterOwnership.objects.create(user=cls.user, character=cls.alt_character, owner_hash='2')
|
CharacterOwnership.objects.create(user=cls.user, character=cls.alt_character, owner_hash='2')
|
||||||
@ -113,6 +114,14 @@ class BackendTestCase(TestCase):
|
|||||||
self.assertEqual(user.username, 'Unclaimed_Character')
|
self.assertEqual(user.username, 'Unclaimed_Character')
|
||||||
self.assertEqual(user.profile.main_character, self.unclaimed_character)
|
self.assertEqual(user.profile.main_character, self.unclaimed_character)
|
||||||
|
|
||||||
|
def test_authenticate_character_record(self):
|
||||||
|
t = Token(character_id=self.unclaimed_character.character_id, character_name=self.unclaimed_character.character_name, character_owner_hash='4')
|
||||||
|
record = OwnershipRecord.objects.create(user=self.old_user, character=self.unclaimed_character, owner_hash='4')
|
||||||
|
user = StateBackend().authenticate(t)
|
||||||
|
self.assertEqual(user, self.old_user)
|
||||||
|
self.assertTrue(CharacterOwnership.objects.filter(owner_hash='4', user=self.old_user).exists())
|
||||||
|
self.assertTrue(user.profile.main_character)
|
||||||
|
|
||||||
def test_iterate_username(self):
|
def test_iterate_username(self):
|
||||||
t = Token(character_id=self.unclaimed_character.character_id,
|
t = Token(character_id=self.unclaimed_character.character_id,
|
||||||
character_name=self.unclaimed_character.character_name, character_owner_hash='3')
|
character_name=self.unclaimed_character.character_name, character_owner_hash='3')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user