mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2025-07-13 14:30:17 +02:00
Merge branch '1088-qol-improve-name-handling-for-smf' into 'master'
Displayed names for SMF Closes #1088 See merge request allianceauth/allianceauth!1459
This commit is contained in:
commit
273bda173e
@ -38,6 +38,12 @@ class SmfService(ServicesHook):
|
|||||||
if SmfTasks.has_account(user):
|
if SmfTasks.has_account(user):
|
||||||
SmfTasks.update_groups.delay(user.pk)
|
SmfTasks.update_groups.delay(user.pk)
|
||||||
|
|
||||||
|
def sync_nickname(self, user):
|
||||||
|
logger.debug(f"Updating {self.name} displayed name for {user}")
|
||||||
|
|
||||||
|
if SmfTasks.has_account(user):
|
||||||
|
SmfTasks.update_display_name.apply_async(args=[user.pk], countdown=5) # cooldown on this task to ensure DB clean when syncing
|
||||||
|
|
||||||
def update_all_groups(self):
|
def update_all_groups(self):
|
||||||
logger.debug('Update all %s groups called' % self.name)
|
logger.debug('Update all %s groups called' % self.name)
|
||||||
SmfTasks.update_all_groups.delay()
|
SmfTasks.update_all_groups.delay()
|
||||||
|
@ -5,11 +5,14 @@ from datetime import datetime
|
|||||||
import hashlib
|
import hashlib
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
from typing import Tuple
|
||||||
|
|
||||||
from packaging import version
|
from packaging import version
|
||||||
|
|
||||||
from django.db import connections
|
from django.db import connections
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
from allianceauth.eveonline.models import EveCharacter
|
from allianceauth.eveonline.models import EveCharacter
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -37,6 +40,10 @@ class SmfManager:
|
|||||||
|
|
||||||
SQL_DEL_USER = r"DELETE FROM %smembers where member_name = %%s" % TABLE_PREFIX
|
SQL_DEL_USER = r"DELETE FROM %smembers where member_name = %%s" % TABLE_PREFIX
|
||||||
|
|
||||||
|
SQL_UPD_USER = r"UPDATE %smembers SET email_address = %%s, passwd = %%s, real_name = %%s WHERE member_name = %%s" % TABLE_PREFIX
|
||||||
|
|
||||||
|
SQL_UPD_DISPLAY_NAME = r"UPDATE %smembers SET real_name = %%s WHERE member_name = %%s" % TABLE_PREFIX
|
||||||
|
|
||||||
SQL_DIS_USER = r"UPDATE %smembers SET email_address = %%s, passwd = %%s WHERE member_name = %%s" % TABLE_PREFIX
|
SQL_DIS_USER = r"UPDATE %smembers SET email_address = %%s, passwd = %%s WHERE member_name = %%s" % TABLE_PREFIX
|
||||||
|
|
||||||
SQL_USER_ID_FROM_USERNAME = r"SELECT id_member from %smembers WHERE member_name = %%s" % TABLE_PREFIX
|
SQL_USER_ID_FROM_USERNAME = r"SELECT id_member from %smembers WHERE member_name = %%s" % TABLE_PREFIX
|
||||||
@ -174,50 +181,75 @@ class SmfManager:
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def add_user(cls, username, email_address, groups, characterid):
|
def add_user(cls, username, email_address, groups, main_character: EveCharacter) -> Tuple:
|
||||||
|
"""
|
||||||
|
Add a user to SMF
|
||||||
|
:param username:
|
||||||
|
:param email_address:
|
||||||
|
:param groups:
|
||||||
|
:param main_character:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
|
||||||
|
main_character_id = main_character.character_id
|
||||||
|
main_character_name = main_character.character_name
|
||||||
|
|
||||||
logger.debug(
|
logger.debug(
|
||||||
f"Adding smf user with member_name {username}, "
|
f"Adding smf user with member_name: {username}, "
|
||||||
f"email_address {email_address}, "
|
f"email_address: {email_address}, "
|
||||||
f"characterid {characterid}"
|
f"characterid: {main_character_id}, "
|
||||||
|
f"main character: {main_character_name}"
|
||||||
)
|
)
|
||||||
|
|
||||||
cursor = connections['smf'].cursor()
|
cursor = connections['smf'].cursor()
|
||||||
username_clean = cls.santatize_username(username)
|
username_clean = cls.santatize_username(username)
|
||||||
passwd = cls.generate_random_pass()
|
passwd = cls.generate_random_pass()
|
||||||
pwhash = cls.gen_hash(username_clean, passwd)
|
pwhash = cls.gen_hash(username_clean, passwd)
|
||||||
logger.debug(f"Proceeding to add smf user {username} and pwhash starting with {pwhash[0:5]}")
|
|
||||||
register_date = cls.get_current_utc_date()
|
register_date = cls.get_current_utc_date()
|
||||||
|
|
||||||
|
logger.debug(f"Proceeding to add smf user {username} and pwhash starting with {pwhash[0:5]}")
|
||||||
|
|
||||||
# check if the username was simply revoked
|
# check if the username was simply revoked
|
||||||
if cls.check_user(username) is True:
|
if cls.check_user(username) is True:
|
||||||
logger.warning(f"Unable to add smf user with username {username} - already exists. Updating user instead.")
|
logger.warning(
|
||||||
cls.__update_user_info(username_clean, email_address, pwhash)
|
f"Unable to add smf user with username {username} - "
|
||||||
|
f"already exists. Updating user instead."
|
||||||
|
)
|
||||||
|
|
||||||
|
cls.__update_user_info(
|
||||||
|
username_clean, email_address, pwhash, main_character_name
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
smf_version = cls._get_current_smf_version()
|
smf_version = cls._get_current_smf_version()
|
||||||
|
sql_add_user_arguments = [
|
||||||
|
username_clean,
|
||||||
|
pwhash,
|
||||||
|
email_address,
|
||||||
|
register_date,
|
||||||
|
main_character_name,
|
||||||
|
]
|
||||||
|
|
||||||
if version.parse(smf_version) < version.parse("2.1"):
|
if version.parse(smf_version) < version.parse("2.1"):
|
||||||
logger.debug("SMF compatibility: < 2.1")
|
logger.debug("SMF compatibility: < 2.1")
|
||||||
|
|
||||||
cursor.execute(
|
cursor.execute(cls.SQL_ADD_USER_SMF_20, sql_add_user_arguments)
|
||||||
cls.SQL_ADD_USER_SMF_20,
|
|
||||||
[username_clean, pwhash, email_address, register_date, username_clean]
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
logger.debug("SMF compatibility: >= 2.1")
|
logger.debug("SMF compatibility: >= 2.1")
|
||||||
|
|
||||||
cursor.execute(
|
cursor.execute(cls.SQL_ADD_USER_SMF_21, sql_add_user_arguments)
|
||||||
cls.SQL_ADD_USER_SMF_21,
|
|
||||||
[username_clean, pwhash, email_address, register_date, username_clean]
|
cls.add_avatar(username_clean, main_character_id)
|
||||||
)
|
|
||||||
cls.add_avatar(username_clean, characterid)
|
|
||||||
logger.info(f"Added smf member_name {username_clean}")
|
logger.info(f"Added smf member_name {username_clean}")
|
||||||
cls.update_groups(username_clean, groups)
|
cls.update_groups(username_clean, groups)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"Unable to add smf user {username_clean}: {e}")
|
logger.warning(f"Unable to add smf user {username_clean}: {e}")
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return username_clean, passwd
|
return username_clean, passwd
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __update_user_info(cls, username, email_address, passwd):
|
def __update_user_info(cls, username, email_address, passwd, main_character_name):
|
||||||
logger.debug(
|
logger.debug(
|
||||||
f"Updating smf user {username} info: "
|
f"Updating smf user {username} info: "
|
||||||
f"username {email_address} "
|
f"username {email_address} "
|
||||||
@ -225,7 +257,9 @@ class SmfManager:
|
|||||||
)
|
)
|
||||||
cursor = connections['smf'].cursor()
|
cursor = connections['smf'].cursor()
|
||||||
try:
|
try:
|
||||||
cursor.execute(cls.SQL_DIS_USER, [email_address, passwd, username])
|
cursor.execute(
|
||||||
|
cls.SQL_UPD_USER, [email_address, passwd, main_character_name, username]
|
||||||
|
)
|
||||||
logger.info(f"Updated smf user {username} info")
|
logger.info(f"Updated smf user {username} info")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception(f"Unable to update smf user {username} info. ({e})")
|
logger.exception(f"Unable to update smf user {username} info. ({e})")
|
||||||
@ -243,6 +277,27 @@ class SmfManager:
|
|||||||
logger.error(f"Unable to delete smf user {username} - user not found on smf.")
|
logger.error(f"Unable to delete smf user {username} - user not found on smf.")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def update_display_name(cls, user: User):
|
||||||
|
logger.debug(f"Updating SMF displayed name for user {user}")
|
||||||
|
cursor = connections['smf'].cursor()
|
||||||
|
smf_username = user.smf.username
|
||||||
|
|
||||||
|
try:
|
||||||
|
display_name = user.profile.main_character.character_name
|
||||||
|
except Exception as exc:
|
||||||
|
logger.exception(
|
||||||
|
f"Unable to find a main character name for {user}, skipping... ({exc})"
|
||||||
|
)
|
||||||
|
display_name = smf_username
|
||||||
|
|
||||||
|
if cls.check_user(smf_username):
|
||||||
|
cursor.execute(cls.SQL_UPD_DISPLAY_NAME, [display_name, smf_username])
|
||||||
|
logger.info(f"Updated displayed name for smf user {smf_username}")
|
||||||
|
return True
|
||||||
|
logger.error(f"Unable to update smf user {smf_username} - user not found on smf.")
|
||||||
|
return False
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def update_groups(cls, username, groups):
|
def update_groups(cls, username, groups):
|
||||||
userid = cls.get_user_id(username)
|
userid = cls.get_user_id(username)
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
from django.db import migrations
|
||||||
|
from ..manager import SmfManager
|
||||||
|
|
||||||
|
def on_migrate(apps, schema_editor):
|
||||||
|
SmfUser = apps.get_model("smf", "SmfUser")
|
||||||
|
db_alias = schema_editor.connection.alias
|
||||||
|
all_smf_users = SmfUser.objects.using(db_alias).all()
|
||||||
|
|
||||||
|
for smf_user in all_smf_users:
|
||||||
|
try:
|
||||||
|
auth_user = smf_user.user
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
SmfManager.update_display_name(auth_user)
|
||||||
|
|
||||||
|
def on_migrate_zero(apps, schema_editor):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('smf', '0002_service_permissions'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RunPython(on_migrate, on_migrate_zero),
|
||||||
|
]
|
@ -57,6 +57,40 @@ class SmfTasks:
|
|||||||
else:
|
else:
|
||||||
logger.debug("User does not have an smf account")
|
logger.debug("User does not have an smf account")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@shared_task(bind=True, name="smf.update_display_name", base=QueueOnce)
|
||||||
|
def update_display_name(self, pk):
|
||||||
|
user = User.objects.get(pk=pk)
|
||||||
|
logger.debug(f"Updating SMF displayed name user {user}")
|
||||||
|
|
||||||
|
if SmfTasks.has_account(user):
|
||||||
|
try:
|
||||||
|
if not SmfManager.update_display_name(user):
|
||||||
|
raise Exception("SMF Displayed Name Sync failed")
|
||||||
|
logger.debug(f"Updated user {user} SMF displayed name.")
|
||||||
|
return True
|
||||||
|
except SmfUser.DoesNotExist:
|
||||||
|
logger.info(
|
||||||
|
f"SMF displayed name sync failed for {user}, "
|
||||||
|
"user does not have a SMF account"
|
||||||
|
)
|
||||||
|
except:
|
||||||
|
logger.exception(
|
||||||
|
f"SMF displayed name sync failed for {user}, retrying in 10 mins"
|
||||||
|
)
|
||||||
|
raise self.retry(countdown=60 * 10)
|
||||||
|
else:
|
||||||
|
logger.debug(f"User {user} does not have a SMF account, skipping")
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@shared_task(name="smf.update_all_display_names")
|
||||||
|
def update_all_display_names():
|
||||||
|
logger.debug("Updating ALL SMF display names")
|
||||||
|
for smf_user in SmfUser.objects.exclude(username__exact=''):
|
||||||
|
SmfTasks.update_display_name.delay(smf_user)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@shared_task(name="smf.update_all_groups")
|
@shared_task(name="smf.update_all_groups")
|
||||||
def update_all_groups():
|
def update_all_groups():
|
||||||
|
@ -19,26 +19,51 @@ ACCESS_PERM = 'smf.access_smf'
|
|||||||
@login_required
|
@login_required
|
||||||
@permission_required(ACCESS_PERM)
|
@permission_required(ACCESS_PERM)
|
||||||
def activate_smf(request):
|
def activate_smf(request):
|
||||||
logger.debug("activate_smf called by user %s" % request.user)
|
logger.debug(f"activate_smf called by user {request.user}")
|
||||||
# Valid now we get the main characters
|
# Valid now we get the main characters
|
||||||
character = request.user.profile.main_character
|
main_character = request.user.profile.main_character
|
||||||
logger.debug(f"Adding smf user for user {request.user} with main character {character}")
|
|
||||||
result = SmfManager.add_user(SmfTasks.get_username(request.user), request.user.email, ['Member'], character.character_id)
|
logger.debug(
|
||||||
|
f"Adding smf user for user {request.user} with main character {main_character}"
|
||||||
|
)
|
||||||
|
|
||||||
|
result = SmfManager.add_user(
|
||||||
|
SmfTasks.get_username(request.user),
|
||||||
|
request.user.email,
|
||||||
|
['Member'],
|
||||||
|
main_character,
|
||||||
|
)
|
||||||
|
|
||||||
# if empty we failed
|
# if empty we failed
|
||||||
if result[0] != "":
|
if result[0] != "":
|
||||||
SmfUser.objects.update_or_create(user=request.user, defaults={'username': result[0]})
|
SmfUser.objects.update_or_create(
|
||||||
logger.debug("Updated authserviceinfo for user %s with smf credentials. Updating groups." % request.user)
|
user=request.user, defaults={'username': result[0]}
|
||||||
|
)
|
||||||
|
|
||||||
|
logger.debug(
|
||||||
|
f"Updated authserviceinfo for user {request.user} "
|
||||||
|
f"with smf credentials. Updating groups."
|
||||||
|
)
|
||||||
|
|
||||||
SmfTasks.update_groups.delay(request.user.pk)
|
SmfTasks.update_groups.delay(request.user.pk)
|
||||||
logger.info("Successfully activated smf for user %s" % request.user)
|
|
||||||
|
logger.info(f"Successfully activated smf for user {request.user}")
|
||||||
|
|
||||||
messages.success(request, _('Activated SMF account.'))
|
messages.success(request, _('Activated SMF account.'))
|
||||||
credentials = {
|
credentials = {
|
||||||
'username': result[0],
|
'username': result[0],
|
||||||
'password': result[1],
|
'password': result[1],
|
||||||
}
|
}
|
||||||
return render(request, 'services/service_credentials.html', context={'credentials': credentials, 'service': 'SMF'})
|
|
||||||
else:
|
return render(
|
||||||
logger.error("Unsuccessful attempt to activate smf for user %s" % request.user)
|
request,
|
||||||
messages.error(request, _('An error occurred while processing your SMF account.'))
|
'services/service_credentials.html',
|
||||||
|
context={'credentials': credentials, 'service': 'SMF'},
|
||||||
|
)
|
||||||
|
|
||||||
|
logger.error(f"Unsuccessful attempt to activate smf for user {request.user}")
|
||||||
|
messages.error(request, _('An error occurred while processing your SMF account.'))
|
||||||
|
|
||||||
return redirect("services:services")
|
return redirect("services:services")
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user