parent
e286c686ae
commit
68d58bb771
|
@ -0,0 +1,3 @@
|
|||
- Authentication is handled by authsaml2
|
||||
- First user created must be superadmin
|
||||
- User admin must be read-only
|
|
@ -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)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
Reference in New Issue