Name generator/formatter (#897)

* Squash services migrations

* Add name to example service to allow it to be used in tests

* Add name formatter to services

* Add documentation
This commit is contained in:
Basraah
2017-10-11 12:34:31 +10:00
committed by GitHub
parent b95bb9aa6a
commit ef37cb3ea5
45 changed files with 518 additions and 33 deletions

View File

@@ -18,6 +18,7 @@ class DiscordService(ServicesHook):
self.name = 'discord'
self.service_ctrl_template = 'services/discord/discord_service_ctrl.html'
self.access_perm = 'discord.access_discord'
self.name_format = '{character_name}'
def delete_user(self, user, notify_user=False):
logger.debug('Deleting user %s %s account' % (user, self.name))

View File

@@ -6,6 +6,7 @@ from django.core.exceptions import ObjectDoesNotExist
from allianceauth.notifications import notify
from allianceauth.celery import app
from allianceauth.services.hooks import NameFormatter
from .manager import DiscordOAuthManager, DiscordApiBackoff
from .models import DiscordUser
@@ -102,7 +103,7 @@ class DiscordTasks:
character = user.profile.main_character
logger.debug("Updating user %s discord nickname to %s" % (user, character.character_name))
try:
DiscordOAuthManager.update_nickname(user.discord.uid, character.character_name)
DiscordOAuthManager.update_nickname(user.discord.uid, DiscordTasks.get_nickname(user))
except Exception as e:
if self:
logger.exception("Discord nickname sync failed for %s, retrying in 10 mins" % user)
@@ -126,3 +127,8 @@ class DiscordTasks:
@classmethod
def disable(cls):
DiscordUser.objects.all().delete()
@staticmethod
def get_nickname(user):
from .auth_hooks import DiscordService
return NameFormatter(DiscordService(), user).format_name()

View File

@@ -18,6 +18,7 @@ class DiscourseService(ServicesHook):
self.name = 'discourse'
self.service_ctrl_template = 'services/discourse/discourse_service_ctrl.html'
self.access_perm = 'discourse.access_discourse'
self.name_format = '{character_name}'
def delete_user(self, user, notify_user=False):
logger.debug('Deleting user %s %s account' % (user, self.name))

View File

@@ -5,6 +5,7 @@ from django.core.exceptions import ObjectDoesNotExist
from allianceauth.celery import app
from allianceauth.notifications import notify
from allianceauth.services.hooks import NameFormatter
from .manager import DiscourseManager
from .models import DiscourseUser
@@ -56,3 +57,8 @@ class DiscourseTasks:
logger.debug("Updating ALL discourse groups")
for discourse_user in DiscourseUser.objects.filter(enabled=True):
DiscourseTasks.update_groups.delay(discourse_user.user.pk)
@staticmethod
def get_username(user):
from .auth_hooks import DiscourseService
return NameFormatter(DiscourseService(), user).format_name()

View File

@@ -71,7 +71,7 @@ def discourse_sso(request):
## Build the return payload
username = DiscourseManager._sanitize_username(main_char.character_name)
username = DiscourseManager._sanitize_username(DiscourseTasks.get_username(request.user))
qs = parse_qs(decoded)
params = {

View File

@@ -10,6 +10,7 @@ class ExampleService(ServicesHook):
ServicesHook.__init__(self)
self.urlpatterns = urlpatterns
self.service_url = 'http://exampleservice.example.com'
self.name = 'example'
"""
Overload base methods here to implement functionality

View File

@@ -14,6 +14,7 @@ class Ips4Service(ServicesHook):
self.urlpatterns = urlpatterns
self.service_url = settings.IPS4_URL
self.access_perm = 'ips4.access_ips4'
self.name_format = '{character_name}'
@property
def title(self):

View File

@@ -1,6 +1,7 @@
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from allianceauth.services.hooks import NameFormatter
from .manager import Ips4Manager
from .models import Ips4User
@@ -33,3 +34,8 @@ class Ips4Tasks:
def disable():
logging.debug("Deleting all IPS4 users")
Ips4User.objects.all().delete()
@staticmethod
def get_username(user):
from .auth_hooks import Ips4Service
return NameFormatter(Ips4Service(), user).format_name()

View File

@@ -20,7 +20,7 @@ def activate_ips4(request):
logger.debug("activate_ips4 called by user %s" % request.user)
character = request.user.profile.main_character
logger.debug("Adding IPS4 user for user %s with main character %s" % (request.user, character))
result = Ips4Manager.add_user(character.character_name, request.user.email)
result = Ips4Manager.add_user(Ips4Tasks.get_username(request.user), request.user.email)
# if empty we failed
if result[0] != "" and not Ips4Tasks.has_account(request.user):
ips_user = Ips4User.objects.create(user=request.user, id=result[2], username=result[0])

View File

@@ -21,6 +21,7 @@ class MumbleService(ServicesHook):
self.service_url = settings.MUMBLE_URL
self.access_perm = 'mumble.access_mumble'
self.service_ctrl_template = 'services/mumble/mumble_service_ctrl.html'
self.name_format = '[{corp_ticker}]{character_name}'
def delete_user(self, user, notify_user=False):
logging.debug("Deleting user %s %s account" % (user, self.name))

View File

@@ -26,25 +26,14 @@ class MumbleManager:
def __generate_random_pass():
return ''.join([random.choice(string.ascii_letters + string.digits) for n in range(16)])
@staticmethod
def __generate_username(username, corp_ticker):
return "[" + corp_ticker + "]" + username
@staticmethod
def __generate_username_blue(username, corp_ticker):
return "[BLUE][" + corp_ticker + "]" + username
@classmethod
def _gen_pwhash(cls, password):
return bcrypt_sha256.encrypt(password.encode('utf-8'))
@classmethod
def create_user(cls, user, corp_ticker, username, blue=False):
logger.debug("Creating%s mumble user with username %s and ticker %s" % (' blue' if blue else '',
username, corp_ticker))
username_clean = cls.__santatize_username(
cls.__generate_username_blue(username, corp_ticker) if blue else
cls.__generate_username(username, corp_ticker))
def create_user(cls, user, username):
logger.debug("Creating mumble user with username %s" % (username))
username_clean = cls.__santatize_username(username)
password = cls.__generate_random_pass()
pwhash = cls._gen_pwhash(password)
logger.debug("Proceeding with mumble user creation: clean username %s, pwhash starts with %s" % (

View File

@@ -2,6 +2,7 @@ import logging
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist
from allianceauth.services.hooks import NameFormatter
from allianceauth.celery import app
from .manager import MumbleManager
@@ -26,6 +27,11 @@ class MumbleTasks:
logger.info("Deleting all MumbleUser models")
MumbleUser.objects.all().delete()
@staticmethod
def get_username(user):
from .auth_hooks import MumbleService
return NameFormatter(MumbleService(), user).format_name()
@staticmethod
@app.task(bind=True, name="mumble.update_groups")
def update_groups(self, pk):

View File

@@ -18,10 +18,9 @@ ACCESS_PERM = 'mumble.access_mumble'
def activate_mumble(request):
logger.debug("activate_mumble called by user %s" % request.user)
character = request.user.profile.main_character
ticker = character.corporation_ticker
logger.debug("Adding mumble user for %s with main character %s" % (request.user, character))
result = MumbleManager.create_user(request.user, ticker, character.character_name)
result = MumbleManager.create_user(request.user, MumbleTasks.get_username(request.user))
if result:
logger.debug("Updated authserviceinfo for user %s with mumble credentials. Updating groups." % request.user)

View File

@@ -18,6 +18,7 @@ class OpenfireService(ServicesHook):
self.urlpatterns = urlpatterns
self.service_url = settings.JABBER_URL
self.access_perm = 'openfire.access_openfire'
self.name_format = '{character_name}'
@property
def title(self):

View File

@@ -6,6 +6,7 @@ from allianceauth.notifications import notify
from allianceauth.celery import app
from allianceauth.services.modules.openfire.manager import OpenfireManager
from allianceauth.services.hooks import NameFormatter
from .models import OpenfireUser
logger = logging.getLogger(__name__)
@@ -65,3 +66,8 @@ class OpenfireTasks:
logger.debug("Updating ALL jabber groups")
for openfire_user in OpenfireUser.objects.exclude(username__exact=''):
OpenfireTasks.update_groups.delay(openfire_user.user.pk)
@staticmethod
def get_username(user):
from .auth_hooks import OpenfireService
return NameFormatter(OpenfireService(), user).format_name()

View File

@@ -23,7 +23,7 @@ def activate_jabber(request):
logger.debug("activate_jabber called by user %s" % request.user)
character = request.user.profile.main_character
logger.debug("Adding jabber user for user %s with main character %s" % (request.user, character))
info = OpenfireManager.add_user(character.character_name)
info = OpenfireManager.add_user(OpenfireTasks.get_username(request.user))
# If our username is blank means we already had a user
if info[0] is not "":
OpenfireUser.objects.update_or_create(user=request.user, defaults={'username': info[0]})

View File

@@ -18,6 +18,7 @@ class Phpbb3Service(ServicesHook):
self.urlpatterns = urlpatterns
self.service_url = settings.PHPBB3_URL
self.access_perm = 'phpbb3.access_phpbb3'
self.name_format = '{character_name}'
@property
def title(self):

View File

@@ -5,6 +5,7 @@ from django.core.exceptions import ObjectDoesNotExist
from allianceauth.celery import app
from allianceauth.notifications import notify
from allianceauth.services.hooks import NameFormatter
from .manager import Phpbb3Manager
from .models import Phpbb3User
@@ -64,3 +65,8 @@ class Phpbb3Tasks:
@staticmethod
def disable():
Phpbb3User.objects.all().delete()
@staticmethod
def get_username(user):
from .auth_hooks import Phpbb3Service
return NameFormatter(Phpbb3Service(), user).format_name()

View File

@@ -21,7 +21,7 @@ def activate_forum(request):
# Valid now we get the main characters
character = request.user.profile.main_character
logger.debug("Adding phpbb user for user %s with main character %s" % (request.user, character))
result = Phpbb3Manager.add_user(character.character_name, request.user.email, ['REGISTERED'],
result = Phpbb3Manager.add_user(Phpbb3Tasks.get_username(request.user), request.user.email, ['REGISTERED'],
character.character_id)
# if empty we failed
if result[0] != "":

View File

@@ -18,6 +18,7 @@ class SeatService(ServicesHook):
self.name = 'seat'
self.service_url = settings.SEAT_URL
self.access_perm = 'seat.access_seat'
self.name_format = '{character_name}'
@property
def title(self):

View File

@@ -5,6 +5,7 @@ from django.core.exceptions import ObjectDoesNotExist
from allianceauth.celery import app
from allianceauth.notifications import notify
from allianceauth.services.hooks import NameFormatter
from .manager import SeatManager
from .models import SeatUser
@@ -64,3 +65,8 @@ class SeatTasks:
@staticmethod
def deactivate():
SeatUser.objects.all().delete()
@staticmethod
def get_username(user):
from .auth_hooks import SeatService
return NameFormatter(SeatService(), user).format_name()

View File

@@ -25,7 +25,7 @@ def activate_seat(request):
stat = SeatManager.check_user_status(character.character_name)
if stat == {}:
logger.debug("User not found, adding SeAT user for user %s with main character %s" % (request.user, character))
result = SeatManager.add_user(character.character_name, request.user.email)
result = SeatManager.add_user(SeatTasks.get_username(request.user), request.user.email)
else:
logger.debug("User found, resetting password")
username = SeatManager.enable_user(stat["name"])

View File

@@ -18,6 +18,7 @@ class SmfService(ServicesHook):
self.urlpatterns = urlpatterns
self.service_url = settings.SMF_URL
self.access_perm = 'smf.access_smf'
self.name_format = '{character_name}'
@property
def title(self):

View File

@@ -5,6 +5,7 @@ from django.core.exceptions import ObjectDoesNotExist
from allianceauth.celery import app
from allianceauth.notifications import notify
from allianceauth.services.hooks import NameFormatter
from .manager import SmfManager
from .models import SmfUser
@@ -64,3 +65,8 @@ class SmfTasks:
logger.debug("Updating ALL smf groups")
for user in SmfUser.objects.exclude(username__exact=''):
SmfTasks.update_groups.delay(user.user_id)
@staticmethod
def get_username(user):
from .auth_hooks import SmfService
return NameFormatter(SmfService(), user).format_name()

View File

@@ -21,7 +21,8 @@ def activate_smf(request):
# Valid now we get the main characters
character = request.user.profile.main_character
logger.debug("Adding smf user for user %s with main character %s" % (request.user, character))
result = SmfManager.add_user(character.character_name, request.user.email, ['Member'], character.character_id)
result = SmfManager.add_user(SmfTasks.get_username(request.user), request.user.email, ['Member'],
character.character_id)
# if empty we failed
if result[0] != "":
SmfUser.objects.update_or_create(user=request.user, defaults={'username': result[0]})

View File

@@ -18,6 +18,7 @@ class Teamspeak3Service(ServicesHook):
self.urlpatterns = urlpatterns
self.service_ctrl_template = 'services/teamspeak3/teamspeak3_service_ctrl.html'
self.access_perm = 'teamspeak3.access_teamspeak3'
self.name_format = '[{corp_ticker}]{character_name}'
def delete_user(self, user, notify_user=False):
logger.debug('Deleting user %s %s account' % (user, self.name))

View File

@@ -50,11 +50,6 @@ class Teamspeak3Manager:
sanatized = sanatized.replace("'", "-")
return sanatized
@staticmethod
def __generate_username(username, corp_ticker):
sanatized = "[" + corp_ticker + "]" + username
return sanatized[:30]
def _get_userid(self, uid):
logger.debug("Looking for uid %s on TS3 server." % uid)
try:
@@ -184,8 +179,8 @@ class Teamspeak3Manager:
except:
logger.exception("An unhandled exception has occured while syncing TS groups.")
def add_user(self, username, corp_ticker):
username_clean = self.__santatize_username(self.__generate_username(username, corp_ticker))
def add_user(self, username):
username_clean = self.__santatize_username(username[:30])
logger.debug("Adding user to TS3 server with cleaned username %s" % username_clean)
server_groups = self._group_list()

View File

@@ -5,6 +5,7 @@ from django.core.exceptions import ObjectDoesNotExist
from allianceauth.celery import app
from allianceauth.notifications import notify
from allianceauth.services.hooks import NameFormatter
from .manager import Teamspeak3Manager
from .models import AuthTS, TSgroup, UserTSgroup, Teamspeak3User
from .util.ts3 import TeamspeakError
@@ -85,3 +86,8 @@ class Teamspeak3Tasks:
logger.debug("Updating ALL teamspeak3 groups")
for user in Teamspeak3User.objects.exclude(uid__exact=''):
Teamspeak3Tasks.update_groups.delay(user.user_id)
@staticmethod
def get_username(user):
from .auth_hooks import Teamspeak3Service
return NameFormatter(Teamspeak3Service(), user).format_name()

View File

@@ -23,7 +23,7 @@ def activate_teamspeak3(request):
ticker = character.corporation_ticker
with Teamspeak3Manager() as ts3man:
logger.debug("Adding TS3 user for user %s with main character %s" % (request.user, character))
result = ts3man.add_user(character.character_name, ticker)
result = ts3man.add_user(Teamspeak3Tasks.get_username(request.user))
# if its empty we failed
if result[0] is not "":

View File

@@ -16,6 +16,7 @@ class XenforoService(ServicesHook):
self.name = 'xenforo'
self.urlpatterns = urlpatterns
self.access_perm = 'xenforo.access_xenforo'
self.name_format = '{character_name}'
@property
def title(self):

View File

@@ -3,6 +3,7 @@ import logging
from django.core.exceptions import ObjectDoesNotExist
from allianceauth.notifications import notify
from allianceauth.services.hooks import NameFormatter
from .manager import XenForoManager
from .models import XenforoUser
@@ -35,3 +36,8 @@ class XenforoTasks:
def disable(cls):
logger.debug("Deleting ALL XenForo users")
XenforoUser.objects.all().delete()
@staticmethod
def get_username(user):
from .auth_hooks import XenforoService
return NameFormatter(XenforoService(), user).format_name()

View File

@@ -20,7 +20,7 @@ def activate_xenforo_forum(request):
logger.debug("activate_xenforo_forum called by user %s" % request.user)
character = request.user.profile.main_character
logger.debug("Adding XenForo user for user %s with main character %s" % (request.user, character))
result = XenForoManager.add_user(character.character_name, request.user.email)
result = XenForoManager.add_user(XenforoTasks.get_username(request.user), request.user.email)
# Based on XenAPI's response codes
if result['response']['status_code'] == 200:
XenforoUser.objects.update_or_create(user=request.user, defaults={'username': result['username']})