add user creation manager code

- add OSUSER_* settings
- add UserManager, GroupManager and ShadowManager for user creation
This commit is contained in:
Jan Dittberner 2014-05-25 00:55:02 +02:00
parent a85ad4e420
commit e132c9a56c
2 changed files with 91 additions and 1 deletions

View file

@ -276,3 +276,12 @@ INSTALLED_APPS += (
# Don't need to use South when setting up a test database. # Don't need to use South when setting up a test database.
SOUTH_TESTS_MIGRATE = False SOUTH_TESTS_MIGRATE = False
########## END SOUTH CONFIGURATION ########## END SOUTH CONFIGURATION
########## CUSTOM APP CONFIGURATION
OSUSER_MINUID = int(get_env_variable('GVA_MIN_OS_UID'))
OSUSER_MINGID = int(get_env_variable('GVA_MIN_OS_GID'))
OSUSER_USERNAME_PREFIX = get_env_variable('GVA_OSUSER_PREFIX')
OSUSER_HOME_BASEPATH = get_env_variable('GVA_OSUSER_HOME_BASEPATH')
OSUSER_DEFAULT_SHELL = get_env_variable('GVA_OSUSER_DEFAULT_SHELL')
########## END CUSTOM APP CONFIGURATION

View file

@ -1,10 +1,25 @@
from django.db import models from datetime import date
import os
from django.db import models, transaction
from django.conf import settings
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.utils import timezone
from django.utils.encoding import python_2_unicode_compatible from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from model_utils.models import TimeStampedModel from model_utils.models import TimeStampedModel
from passlib.hash import sha512_crypt
from passlib.utils import generate_password
class GroupManager(models.Manager):
def get_next_gid(self):
q = self.aggregate(models.Max('gid'))
return max(settings.OSUSER_MINGID, q['gid__max'] + 1)
@python_2_unicode_compatible @python_2_unicode_compatible
class Group(TimeStampedModel, models.Model): class Group(TimeStampedModel, models.Model):
@ -16,6 +31,8 @@ class Group(TimeStampedModel, models.Model):
passwd = models.CharField( passwd = models.CharField(
_('Group password'), max_length=128, blank=True) _('Group password'), max_length=128, blank=True)
objects = GroupManager()
class Meta: class Meta:
verbose_name = _('Group') verbose_name = _('Group')
verbose_name_plural = _('Groups') verbose_name_plural = _('Groups')
@ -24,6 +41,52 @@ class Group(TimeStampedModel, models.Model):
return '{0} ({1})'.format(self.groupname, self.gid) return '{0} ({1})'.format(self.groupname, self.gid)
class UserManager(models.Manager):
def get_next_uid(self):
q = self.aggregate(models.Max('uid'))
return max(settings.OSUSER_MINUID, q['uid__max'] + 1)
def get_next_username(self):
count = 1
usernameformat = "{0}{1:02d}"
nextuser = usernameformat.format(settings.OSUSER_USERNAME_PREFIX,
count)
for user in self.values('username').filter(
username__startswith=settings.OSUSER_USERNAME_PREFIX).order_by(
'username'):
if user == nextuser:
count += 1
nextuser = usernameformat.format(
settings.OSUSER_USERNAME_PREFIX, count)
else:
break
return nextuser
def create_user(self, username=None, password=None):
uid = self.get_next_uid()
gid = Group.objects.get_next_gid()
if username is None:
username = self.get_next_username()
if password is None:
password = generate_password()
homedir = os.path.join(settings.OSUSER_HOME_BASEPATH, username)
autocommit = transaction.get_autocommit()
if autocommit:
transaction.set_autocommit(False)
group = Group.objects.create(groupname=username, gid=gid)
user = self.create(username=username, group=group, uid=uid,
homedir=homedir,
shell=settings.OSUSER_DEFAULT_SHELL)
shadow = Shadow.objects.create_shadow(user=user, password=password)
user.save()
shadow.save()
transaction.commit()
if autocommit:
transaction.set_autocommit(True)
return user
@python_2_unicode_compatible @python_2_unicode_compatible
class User(TimeStampedModel, models.Model): class User(TimeStampedModel, models.Model):
username = models.CharField( username = models.CharField(
@ -35,6 +98,8 @@ class User(TimeStampedModel, models.Model):
homedir = models.CharField(_('Home directory'), max_length=256) homedir = models.CharField(_('Home directory'), max_length=256)
shell = models.CharField(_('Login shell'), max_length=64) shell = models.CharField(_('Login shell'), max_length=64)
objects = UserManager()
class Meta: class Meta:
verbose_name = _('User') verbose_name = _('User')
verbose_name_plural = _('Users') verbose_name_plural = _('Users')
@ -43,6 +108,20 @@ class User(TimeStampedModel, models.Model):
return '{0} ({1})'.format(self.username, self.uid) return '{0} ({1})'.format(self.username, self.uid)
class ShadowManager(models.Manager):
def create_shadow(self, user, password):
changedays = (timezone.now().date() - date(1970, 1, 1)).days
pwhash = sha512_crypt.encrypt(password)
shadow = self.create(
user=user, changedays=changedays,
minage=0, maxage=None, gracedays=7,
inactdays=30, expiredays=None, passwd=pwhash
)
shadow.save()
return shadow
@python_2_unicode_compatible @python_2_unicode_compatible
class Shadow(TimeStampedModel, models.Model): class Shadow(TimeStampedModel, models.Model):
user = models.OneToOneField(User, primary_key=True, verbose_name=_('User')) user = models.OneToOneField(User, primary_key=True, verbose_name=_('User'))
@ -77,6 +156,8 @@ class Shadow(TimeStampedModel, models.Model):
' number of days since Jan 1, 1970'), ' number of days since Jan 1, 1970'),
blank=True, null=True, default=None) blank=True, null=True, default=None)
objects = ShadowManager()
class Meta: class Meta:
verbose_name = _('Shadow password') verbose_name = _('Shadow password')
verbose_name_plural = _('Shadow passwords') verbose_name_plural = _('Shadow passwords')