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.
SOUTH_TESTS_MIGRATE = False
########## 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.utils import timezone
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext as _
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
class Group(TimeStampedModel, models.Model):
@ -16,6 +31,8 @@ class Group(TimeStampedModel, models.Model):
passwd = models.CharField(
_('Group password'), max_length=128, blank=True)
objects = GroupManager()
class Meta:
verbose_name = _('Group')
verbose_name_plural = _('Groups')
@ -24,6 +41,52 @@ class Group(TimeStampedModel, models.Model):
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
class User(TimeStampedModel, models.Model):
username = models.CharField(
@ -35,6 +98,8 @@ class User(TimeStampedModel, models.Model):
homedir = models.CharField(_('Home directory'), max_length=256)
shell = models.CharField(_('Login shell'), max_length=64)
objects = UserManager()
class Meta:
verbose_name = _('User')
verbose_name_plural = _('Users')
@ -43,6 +108,20 @@ class User(TimeStampedModel, models.Model):
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
class Shadow(TimeStampedModel, models.Model):
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'),
blank=True, null=True, default=None)
objects = ShadowManager()
class Meta:
verbose_name = _('Shadow password')
verbose_name_plural = _('Shadow passwords')