first commit of portail-citoyen2

start a TODO list
This commit is contained in:
Benjamin Dauvergne 2014-02-28 16:08:41 +01:00
parent e286c686ae
commit 68d58bb771
4 changed files with 6 additions and 208 deletions

3
TODO Normal file
View File

@ -0,0 +1,3 @@
- Authentication is handled by authsaml2
- First user created must be superadmin
- User admin must be read-only

View File

@ -1,69 +1,17 @@
import urlparse
import urllib2
import time
import logging
from django.contrib import messages
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from django.utils.html import format_html
from django.core.exceptions import ValidationError
from django.contrib import admin
from django.contrib.auth.models import Group
from authentic2.saml.models import LibertyProvider, LibertyServiceProvider
from . import app_settings
from . import models
logger = logging.getLogger(__name__)
if settings.AUTH_USER_MODEL == 'portail_citoyen.Citoyen':
import forms
from django.contrib.auth.admin import UserAdmin
class CitoyenAdmin(UserAdmin):
list_display = UserAdmin.list_display + ('is_active',)
non_superuser_fieldsets = (
(None, {'fields': ('username', 'password')}),
(_('Personal info'), {'fields': ('first_name', 'last_name',
'email', 'address', 'city', 'postal_code', 'phone',
'mobile')}),
(_('Permissions'), {'fields': ('is_active',
'groups')}),
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
fieldsets = (
(None, {'fields': ('username', 'password')}),
(_('Personal info'), {'fields': ('first_name', 'last_name',
'email', 'address', 'city', 'postal_code', 'phone',
'mobile')}),
(_('Permissions'), {'fields': ('is_active',
'is_superuser', 'groups')}),
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
form = forms.UserChangeForm
add_form = forms.UserCreationForm
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'password1', 'password2', 'first_name', 'last_name', 'email')}
),
)
def get_fieldsets(self, request, obj=None):
if not obj:
return self.add_fieldsets
if not request.user.is_superuser:
return self.non_superuser_fieldsets
return self.fieldsets
admin.site.register(models.Citoyen, CitoyenAdmin)
from django.contrib.auth.admin import GroupAdmin
# XXX: the UserAdmin must be read-only
class GroupPortailCitoyenAdmin(GroupAdmin):
fieldsets = ((None, {'fields': ('name', 'permissions')}),)
default_fieldsets = ((None, {'fields': ('name', )}),)
@ -108,104 +56,3 @@ if hasattr(get_user_model(), 'groups'):
.filter(permissions__isnull=False) \
.exists() or user.is_superuser
user.save(update_fields=['is_staff'])
if 'wcsinst.wcsinst' in settings.INSTALLED_APPS:
from wcsinst.wcsinst.admin import WcsInstanceAdmin
from wcsinst.wcsinst.models import WcsInstance
admin.site.unregister(WcsInstance)
class WcsInstancePortailCitoyenAdmin(WcsInstanceAdmin):
list_display = [ '__unicode__', 'link' ]
fieldsets = (
(None, {'fields': ('title', 'domain', 'link'),}),
('site-options.cfg',
{'fields': ('postgresql', 'backoffice_feed_url' )}
),
('site-options.cfg au-quotidien',
{'fields': ('drupal', 'ezldap', 'strongbox', 'clicrdv', 'domino' )}
),
)
readonly_fields = WcsInstanceAdmin.readonly_fields + ('link',)
def link(self, obj):
url = str(settings.WCSINST_URL_TEMPLATE % { 'domain': obj.domain })
return format_html('<a class="external-link" href="{1}">{0}</a>',
url, url)
link.allow_tags = True
link.short_description = _('URL')
def delete_model(self, request, obj):
title = obj.title
super(WcsInstancePortailCitoyenAdmin, self).delete_model(request, obj)
Group.objects.filter(name__startswith=title+' - ').delete()
def save_related(self, request, form, formsets, change):
instance = form.instance
admin.ModelAdmin.save_related(self, request, form, formsets, change)
for key, value in app_settings.WCSINST_DEFAULT_VARIABLES.iteritems():
if instance.variables.filter(key=key).count() == 0:
instance.variables.create(key=key, value=value)
instance.notify()
# Get and configure metadata
sleep_length = 4
c = 0
done = False
if LibertyProvider.objects.filter(slug=instance.domain).exists():
provider = LibertyProvider.objects.get(slug=instance.domain)
provider.name = instance.title
else:
provider = LibertyProvider(name=instance.title, slug=instance.domain)
while not done:
time.sleep(sleep_length)
url = str(settings.WCSINST_URL_TEMPLATE % { 'domain': instance.domain })
url = urlparse.urljoin(url, 'saml/metadata')
try:
provider.metadata = urllib2.urlopen(url).read().decode('utf-8')
except:
logger.warning("Unable to retrieve SAML 2.0 metadata for %r", instance.title, exc_info=True)
if c >= 3:
messages.error(request, _('Unable to retrieve SAML 2.0 metadatas, please report it to an administrator'))
break
else:
try:
provider.clean()
except ValidationError, v:
provider.delete()
logger.error('Unable to create the SAML 2.0 provider: %r', v)
messages.error(request, _('Unable to create the SAML 2.0 provider: %s') % v)
break
provider.save()
LibertyServiceProvider.objects.get_or_create(liberty_provider=provider, enabled=True)
done = True
c += 1
sleep_length *= 2
def save_model(self, request, obj, form, change):
if change:
old_obj = WcsInstance.objects.get(pk=obj.pk)
super(WcsInstancePortailCitoyenAdmin, self).save_model(request, obj, form, change)
new_prefix = obj.title
new_prefix += ' - '
if change:
# rename old admin group if needed
old_prefix = old_obj.title + ' - '
if old_prefix != new_prefix:
for group in Group.objects.select_for_update() \
.filter(name__startswith=old_prefix):
group.name = new_prefix + group.name[len(old_prefix):]
group.save()
else:
# create first group
admin_group, created = Group.objects.get_or_create(name=new_prefix+'Administrateur')
# make current user admin of the new site
request.user.groups.add(admin_group)
admin.site.register(WcsInstance,
WcsInstancePortailCitoyenAdmin)

View File

@ -10,7 +10,7 @@ class CustomIndexDashboard(Dashboard):
# append an app list module for "Applications"
self.children.append(modules.ModelList(
_('Users and roles'),
models=('portail_citoyen.models.Citoyen',
models=('django.contrib.auth.models.User',
'portail_citoyen.models.Role'),
))
self.children.append(modules.ModelList(

View File

@ -1,58 +1,6 @@
from django.db import models
from django.core.validators import RegexValidator, MinLengthValidator, \
MaxLengthValidator
from django.utils.translation import ugettext_lazy as _, pgettext_lazy
from django.contrib.auth.models import Group
from authentic2.models import AbstractUser
class Citoyen(AbstractUser):
title = models.CharField(pgettext_lazy('person title', 'title'), max_length=16, blank=True,
choices=tuple((x, x) for x in (_('Mrs'),
_('Mr'))))
first_name = models.CharField(_('first name'), max_length=30, blank=True)
last_name = models.CharField(_('last name'), max_length=30, blank=True)
email = models.EmailField(_('e-mail address'), max_length=128, blank=True)
city = models.CharField(_('city'), max_length=64, blank=True)
address = models.CharField(_('address'), max_length=128, blank=True)
postal_code = models.CharField(_('postal code'), max_length=5, blank=True,
validators=[
RegexValidator(r'^[0-9]*$',
_('Postal code must be five numbers'),
_('Invalid postal code')),
MinLengthValidator(5),
MaxLengthValidator(5)])
phone = models.CharField(verbose_name=_("phone"),
max_length=16, blank=True,
help_text=_('Phone number must start with 01, 02, 03, 04, 05, 08 or 07 and be ten digits long without spaces'),
validators=[
RegexValidator(r'^0[1234589][0-9]{8}$',
_('Phone number must start with 01, 02, 03, 04, 05, 08 or 07 and be ten digits long without spaces'),
_('Invalid mobile phone number')),])
mobile = models.CharField(verbose_name=_("mobile"),
max_length=16, blank=True,
help_text=_('Mobile phone number must start with 06 or 07 and be ten digits long without spaces'),
validators=[
RegexValidator(r'^0[67][0-9]{8}$',
_('Mobile phone number must start with 06 or 07 and be ten digits long without spaces'),
_('Invalid mobile phone number')),])
REQUIRED_FIELDS = ['first_name', 'last_name', 'email']
USERNAME = 'username'
USER_PROFILE = ( 'title', 'username', 'first_name', 'last_name', 'email',
'phone', 'mobile', 'address', 'postal_code', 'city', 'roles')
from authentic2.attribute_aggregator.core import ATTRIBUTE_MAPPING
ATTRIBUTE_MAPPING['l']['profile_field_name'] = 'city'
ATTRIBUTE_MAPPING['personalTitle']['profile_field_name'] = 'title'
ATTRIBUTE_MAPPING['street']['profile_field_name'] = 'address'
ATTRIBUTE_MAPPING['postalCode']['profile_field_name'] = 'postal_code'
ATTRIBUTE_MAPPING['mobile']['profile_field_name'] = 'mobile'
class Role(Group):
class Meta:
proxy = True