From caab322bebf68a61e8cf2dbaa1db84d777fafe04 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Sun, 25 May 2014 23:35:14 +0200 Subject: [PATCH] implement user creation in osusers.admin - add osusers.admin.UserCreationForm - add dummy osusers.tasks implementation with create_ldap_group and create_ldap_user - fix UserManager.get_next_username - add proper transaction handling in UserManager.create_user - add calls to create_ldap_user and create_ldap_group to UserManager.create_user --- gnuviechadmin/osusers/admin.py | 68 +++++++++++++++++++++++++++++++++ gnuviechadmin/osusers/models.py | 24 ++++++------ gnuviechadmin/osusers/tasks.py | 13 +++++++ 3 files changed, 94 insertions(+), 11 deletions(-) create mode 100644 gnuviechadmin/osusers/tasks.py diff --git a/gnuviechadmin/osusers/admin.py b/gnuviechadmin/osusers/admin.py index e0e9adc..62928fc 100644 --- a/gnuviechadmin/osusers/admin.py +++ b/gnuviechadmin/osusers/admin.py @@ -1,3 +1,5 @@ +from django import forms +from django.utils.translation import ugettext as _ from django.contrib import admin from .models import ( @@ -7,6 +9,8 @@ from .models import ( User, ) +PASSWORD_MISMATCH_ERROR = _("Passwords don't match") + class AdditionalGroupInline(admin.TabularInline): model = AdditionalGroup @@ -18,9 +22,73 @@ class ShadowInline(admin.TabularInline): can_delete = False +class UserCreationForm(forms.ModelForm): + """ + A form for creating system users. + + """ + password1 = forms.CharField(label=_('Password'), + widget=forms.PasswordInput) + password2 = forms.CharField(label=_('Password (again)'), + widget=forms.PasswordInput) + + class Meta: + model = User + fields = [] + + def clean_password2(self): + """ + Check that the two password entries match. + + """ + password1 = self.cleaned_data.get('password1') + password2 = self.cleaned_data.get('password2') + if password1 and password2 and password1 != password2: + raise forms.ValidationError(PASSWORD_MISMATCH_ERROR) + return password2 + + def save(self, commit=True): + """ + Save the provided password in hashed format. + + """ + user = User.objects.create_user( + password=self.cleaned_data['password1'], commit=commit) + return user + + def save_m2m(self): + pass + + class UserAdmin(admin.ModelAdmin): inlines = [AdditionalGroupInline, ShadowInline] readonly_fields = ['uid'] + add_form = UserCreationForm + + add_fieldsets = ( + (None, { + 'classes': ('wide',), + 'fields': ('password1', 'password2')}), + ) + + def get_form(self, request, obj=None, **kwargs): + """ + Use special form during user creation. + + """ + defaults = {} + if obj is None: + defaults.update({ + 'form': self.add_form, + 'fields': admin.util.flatten_fieldsets(self.add_fieldsets), + }) + defaults.update(kwargs) + return super(UserAdmin, self).get_form(request, obj, **defaults) + + def get_inline_instances(self, request, obj=None): + if obj is None: + return [] + return super(UserAdmin, self).get_inline_instances(request, obj) admin.site.register(Group) diff --git a/gnuviechadmin/osusers/models.py b/gnuviechadmin/osusers/models.py index ecb9beb..1ecf82c 100644 --- a/gnuviechadmin/osusers/models.py +++ b/gnuviechadmin/osusers/models.py @@ -1,7 +1,7 @@ from datetime import date import os -from django.db import models, transaction +from django.db import models from django.conf import settings from django.core.exceptions import ValidationError from django.utils import timezone @@ -13,6 +13,11 @@ from model_utils.models import TimeStampedModel from passlib.hash import sha512_crypt from passlib.utils import generate_password +from .tasks import ( + create_ldap_group, + create_ldap_user, +) + class GroupManager(models.Manager): @@ -59,7 +64,7 @@ class UserManager(models.Manager): for user in self.values('username').filter( username__startswith=settings.OSUSER_USERNAME_PREFIX).order_by( 'username'): - if user == nextuser: + if user['username'] == nextuser: count += 1 nextuser = usernameformat.format( settings.OSUSER_USERNAME_PREFIX, count) @@ -67,7 +72,7 @@ class UserManager(models.Manager): break return nextuser - def create_user(self, username=None, password=None): + def create_user(self, username=None, password=None, commit=False): uid = self.get_next_uid() gid = Group.objects.get_next_gid() if username is None: @@ -75,19 +80,16 @@ class UserManager(models.Manager): 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) + create_ldap_group.delay(group) user = self.create(username=username, group=group, uid=uid, homedir=homedir, shell=settings.OSUSER_DEFAULT_SHELL) + create_ldap_user.delay(user, password) shadow = Shadow.objects.create_shadow(user=user, password=password) - user.save() - shadow.save() - transaction.commit() - if autocommit: - transaction.set_autocommit(True) + if commit: + user.save() + shadow.save() return user diff --git a/gnuviechadmin/osusers/tasks.py b/gnuviechadmin/osusers/tasks.py new file mode 100644 index 0000000..7382c99 --- /dev/null +++ b/gnuviechadmin/osusers/tasks.py @@ -0,0 +1,13 @@ +from __future__ import absolute_import + +from celery import shared_task + + +@shared_task +def create_ldap_group(group): + return group + + +@shared_task +def create_ldap_user(user, password): + return user, password