mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2025-07-09 12:30:15 +02:00
157 lines
5.4 KiB
Python
157 lines
5.4 KiB
Python
import random
|
|
import string
|
|
from passlib.hash import bcrypt_sha256
|
|
|
|
from django.db import models
|
|
from django.contrib.auth.models import Group
|
|
from allianceauth.services.hooks import NameFormatter
|
|
from allianceauth.services.abstract import AbstractServiceModel
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class MumbleManager(models.Manager):
|
|
HASH_FN = 'bcrypt-sha256'
|
|
|
|
@staticmethod
|
|
def get_display_name(user):
|
|
from .auth_hooks import MumbleService
|
|
return NameFormatter(MumbleService(), user).format_name()
|
|
|
|
@staticmethod
|
|
def get_username(user):
|
|
return user.profile.main_character.character_name # main character as the user.username may be incorect
|
|
|
|
@staticmethod
|
|
def sanitise_username(username):
|
|
return username.replace(" ", "_")
|
|
|
|
@staticmethod
|
|
def generate_random_pass():
|
|
return ''.join([random.choice(string.ascii_letters + string.digits) for n in range(16)])
|
|
|
|
@staticmethod
|
|
def gen_pwhash(password):
|
|
return bcrypt_sha256.encrypt(password.encode('utf-8'))
|
|
|
|
def create(self, user):
|
|
try:
|
|
username = self.get_username(user)
|
|
logger.debug("Creating mumble user with username {}".format(username))
|
|
username_clean = self.sanitise_username(username)
|
|
display_name = self.get_display_name(user)
|
|
password = self.generate_random_pass()
|
|
pwhash = self.gen_pwhash(password)
|
|
logger.debug("Proceeding with mumble user creation: clean username {}, pwhash starts with {}".format(
|
|
username_clean, pwhash[0:5]))
|
|
logger.info("Creating mumble user {}".format(username_clean))
|
|
|
|
result = super(MumbleManager, self).create(user=user, username=username_clean,
|
|
pwhash=pwhash, hashfn=self.HASH_FN,
|
|
display_name=display_name)
|
|
result.update_groups()
|
|
result.credentials.update({'username': result.username, 'password': password})
|
|
return result
|
|
except AttributeError: # No Main or similar errors
|
|
return False
|
|
return False
|
|
|
|
def user_exists(self, username):
|
|
return self.filter(username=username).exists()
|
|
|
|
|
|
class MumbleUser(AbstractServiceModel):
|
|
username = models.CharField(max_length=254, unique=True)
|
|
pwhash = models.CharField(max_length=90)
|
|
hashfn = models.CharField(max_length=20, default='sha1')
|
|
groups = models.TextField(blank=True, null=True)
|
|
certhash = models.CharField(
|
|
verbose_name="Certificate Hash",
|
|
max_length=254,
|
|
blank=True,
|
|
null=True,
|
|
editable=False,
|
|
help_text="Hash of Mumble client certificate as presented when user authenticates"
|
|
)
|
|
display_name = models.CharField(
|
|
max_length=254,
|
|
unique=True
|
|
)
|
|
release = models.TextField(
|
|
verbose_name="Mumble Release",
|
|
max_length=254,
|
|
blank=True,
|
|
null=True,
|
|
editable=False,
|
|
help_text="The Mumble Release the user last authenticated with"
|
|
)
|
|
version = models.IntegerField(
|
|
verbose_name="Mumble Version",
|
|
blank=True,
|
|
null=True,
|
|
editable=False,
|
|
help_text="Client version. Major version in upper 16 bits, followed by 8 bits of minor version and 8 bits of patchlevel. Version 1.2.3 = 0x010203."
|
|
)
|
|
last_connect = models.DateTimeField(
|
|
verbose_name="Last Connection",
|
|
max_length=254,
|
|
blank=True,
|
|
null=True,
|
|
editable=False,
|
|
help_text="Timestamp of the users Last Connection to Mumble"
|
|
)
|
|
last_disconnect = models.DateTimeField(
|
|
verbose_name="Last Disconnection",
|
|
max_length=254,
|
|
blank=True,
|
|
null=True,
|
|
editable=False,
|
|
help_text="Timestamp of the users Last Disconnection to Mumble"
|
|
)
|
|
|
|
objects = MumbleManager()
|
|
|
|
def __str__(self):
|
|
return self.username
|
|
|
|
def update_password(self, password=None):
|
|
init_password = password
|
|
logger.debug("Updating mumble user %s password.".format(self.user))
|
|
if not password:
|
|
password = MumbleManager.generate_random_pass()
|
|
pwhash = MumbleManager.gen_pwhash(password)
|
|
logger.debug("Proceeding with mumble user {} password update - pwhash starts with {}".format(
|
|
self.user, pwhash[0:5]))
|
|
self.pwhash = pwhash
|
|
self.hashfn = MumbleManager.HASH_FN
|
|
self.save()
|
|
if init_password is None:
|
|
self.credentials.update({'username': self.username, 'password': password})
|
|
|
|
def reset_password(self):
|
|
self.update_password()
|
|
|
|
def update_groups(self, groups: Group=None):
|
|
if groups is None:
|
|
groups = self.user.groups.all()
|
|
groups_str = [self.user.profile.state.name]
|
|
for group in groups:
|
|
groups_str.append(str(group.name))
|
|
safe_groups = ','.join(set([g.replace(' ', '-') for g in groups_str]))
|
|
logger.info("Updating mumble user {} groups to {}".format(self.user, safe_groups))
|
|
self.groups = safe_groups
|
|
self.save()
|
|
return True
|
|
|
|
def update_display_name(self):
|
|
logger.info("Updating mumble user {} display name".format(self.user))
|
|
self.display_name = MumbleManager.get_display_name(self.user)
|
|
self.save()
|
|
return True
|
|
|
|
class Meta:
|
|
permissions = (
|
|
("access_mumble", u"Can access the Mumble service"),
|
|
)
|