finish feature osusertoldap

This commit is contained in:
Jan Dittberner 2014-05-30 17:14:09 +02:00
commit 561b2d64db
7 changed files with 201 additions and 12 deletions

View file

@ -0,0 +1 @@
from gnuviechadmin.celery import app as celery_app

View file

@ -0,0 +1,21 @@
from __future__ import absolute_import
import os
from celery import Celery
from django.conf import settings
os.environ.setdefault('DJANGO_SETTINGS_MODULE',
'gnuviechadmin.settings.production')
app = Celery('gnuviechadmin')
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
@app.task(bind=True)
def debug_task(self):
print('Request: {0!r}'.format(self.request))

View file

@ -279,6 +279,17 @@ SOUTH_TESTS_MIGRATE = False
########## END SOUTH CONFIGURATION ########## END SOUTH CONFIGURATION
########## CELERY CONFIGURATION
BROKER_URL = get_env_variable('GVA_BROKER_URL')
CELERY_RESULT_BACKEND = 'amqp'
CELERY_RESULT_PERSISTENT = True
CELERY_TASK_RESULT_EXPIRES = None
CELERY_ROUTES = (
'osusers.tasks.LdapRouter',
)
########## END CELERY CONFIGURATION
########## CUSTOM APP CONFIGURATION ########## CUSTOM APP CONFIGURATION
OSUSER_MINUID = int(get_env_variable('GVA_MIN_OS_UID')) OSUSER_MINUID = int(get_env_variable('GVA_MIN_OS_UID'))
OSUSER_MINGID = int(get_env_variable('GVA_MIN_OS_GID')) OSUSER_MINGID = int(get_env_variable('GVA_MIN_OS_GID'))

View file

@ -1,3 +1,5 @@
from django import forms
from django.utils.translation import ugettext as _
from django.contrib import admin from django.contrib import admin
from .models import ( from .models import (
@ -7,6 +9,8 @@ from .models import (
User, User,
) )
PASSWORD_MISMATCH_ERROR = _("Passwords don't match")
class AdditionalGroupInline(admin.TabularInline): class AdditionalGroupInline(admin.TabularInline):
model = AdditionalGroup model = AdditionalGroup
@ -18,9 +22,73 @@ class ShadowInline(admin.TabularInline):
can_delete = False 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): class UserAdmin(admin.ModelAdmin):
inlines = [AdditionalGroupInline, ShadowInline] inlines = [AdditionalGroupInline, ShadowInline]
readonly_fields = ['uid'] 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) admin.site.register(Group)

View file

@ -1,7 +1,7 @@
from datetime import date from datetime import date
import os import os
from django.db import models, transaction from django.db import models
from django.conf import settings 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 import timezone
@ -13,6 +13,15 @@ from model_utils.models import TimeStampedModel
from passlib.hash import sha512_crypt from passlib.hash import sha512_crypt
from passlib.utils import generate_password from passlib.utils import generate_password
from .tasks import (
add_ldap_user_to_group,
create_ldap_group,
create_ldap_user,
delete_ldap_group_if_empty,
delete_ldap_user,
remove_ldap_user_from_group,
)
class GroupManager(models.Manager): class GroupManager(models.Manager):
@ -42,6 +51,15 @@ class Group(TimeStampedModel, models.Model):
def __str__(self): def __str__(self):
return '{0} ({1})'.format(self.groupname, self.gid) return '{0} ({1})'.format(self.groupname, self.gid)
def save(self, *args, **kwargs):
super(Group, self).save(*args, **kwargs)
create_ldap_group.delay(self)
return self
def delete(self, *args, **kwargs):
delete_ldap_group_if_empty.delay(self)
super(Group, self).delete(*args, **kwargs)
class UserManager(models.Manager): class UserManager(models.Manager):
@ -59,7 +77,7 @@ class UserManager(models.Manager):
for user in self.values('username').filter( for user in self.values('username').filter(
username__startswith=settings.OSUSER_USERNAME_PREFIX).order_by( username__startswith=settings.OSUSER_USERNAME_PREFIX).order_by(
'username'): 'username'):
if user == nextuser: if user['username'] == nextuser:
count += 1 count += 1
nextuser = usernameformat.format( nextuser = usernameformat.format(
settings.OSUSER_USERNAME_PREFIX, count) settings.OSUSER_USERNAME_PREFIX, count)
@ -67,7 +85,7 @@ class UserManager(models.Manager):
break break
return nextuser 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() uid = self.get_next_uid()
gid = Group.objects.get_next_gid() gid = Group.objects.get_next_gid()
if username is None: if username is None:
@ -75,19 +93,15 @@ class UserManager(models.Manager):
if password is None: if password is None:
password = generate_password() password = generate_password()
homedir = os.path.join(settings.OSUSER_HOME_BASEPATH, username) 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) group = Group.objects.create(groupname=username, gid=gid)
create_ldap_group.delay(group)
user = self.create(username=username, group=group, uid=uid, user = self.create(username=username, group=group, uid=uid,
homedir=homedir, homedir=homedir,
shell=settings.OSUSER_DEFAULT_SHELL) shell=settings.OSUSER_DEFAULT_SHELL)
shadow = Shadow.objects.create_shadow(user=user, password=password) Shadow.objects.create_shadow(user=user, password=password)
user.save() user.set_password(password)
shadow.save() if commit:
transaction.commit() user.save()
if autocommit:
transaction.set_autocommit(True)
return user return user
@ -111,6 +125,23 @@ class User(TimeStampedModel, models.Model):
def __str__(self): def __str__(self):
return '{0} ({1})'.format(self.username, self.uid) return '{0} ({1})'.format(self.username, self.uid)
def set_password(self, password):
create_ldap_user.delay(self, password)
def save(self, *args, **kwargs):
create_ldap_user.delay(self, password=None)
return super(User, self).save(*args, **kwargs)
def delete(self, *args, **kwargs):
for group in [
ag.group for ag in AdditionalGroup.objects.filter(user=self)
]:
remove_ldap_user_from_group.delay(self.username, group.groupname)
delete_ldap_user.delay(self)
delete_ldap_group_if_empty.delay(self.group)
self.group.delete()
super(User, self).delete(*args, **kwargs)
class ShadowManager(models.Manager): class ShadowManager(models.Manager):
@ -185,5 +216,15 @@ class AdditionalGroup(TimeStampedModel, models.Model):
raise ValidationError(_( raise ValidationError(_(
"You can not use a user's primary group.")) "You can not use a user's primary group."))
def save(self, *args, **kwargs):
add_ldap_user_to_group.delay(
self.user.username, self.group.groupname)
super(AdditionalGroup, self).save(*args, **kwargs)
def delete(self, *args, **kwargs):
remove_ldap_user_from_group.delay(
self.user.username, self.group.groupname)
super(AdditionalGroup, self).delete(*args, **kwargs)
def __str__(self): def __str__(self):
return '{0} in {1}'.format(self.user, self.group) return '{0} in {1}'.format(self.user, self.group)

View file

@ -0,0 +1,43 @@
from __future__ import absolute_import
from celery import shared_task
class LdapRouter(object):
def route_for_task(self, task, args=None, kwargs=None):
if 'ldap' in task:
return {'exchange': 'ldap',
'exchange_type': 'direct',
'queue': 'ldap'}
return None
@shared_task
def create_ldap_group(group):
return group.groupname
@shared_task
def create_ldap_user(user, password):
return user.username
@shared_task
def add_ldap_user_to_group(username, groupname):
pass
@shared_task
def remove_ldap_user_from_group(username, groupname):
pass
@shared_task
def delete_ldap_user(user):
pass
@shared_task
def delete_ldap_group_if_empty(group):
pass

View file

@ -6,3 +6,7 @@ logutils==0.3.3
South==0.8.4 South==0.8.4
psycopg2==2.5.3 psycopg2==2.5.3
passlib==1.6.2 passlib==1.6.2
celery==3.1.11
billiard==3.3.0.17
kombu==3.0.16
pytz==2014.3