Update project
- Make authentic2_pratic.User and authentic2_pratic.Collectivity derive from custom_user.User and a2_rbac.OrganizationalUnit - Merge with RBAC changes from authentic2, refactor forms and views to use those from authentic2.manager - Remove OAuth2 mentions - Implement restriction of authentication to X509 for some services
This commit is contained in:
parent
4a0bbb5098
commit
71b416fab1
13
README
13
README
|
@ -32,22 +32,19 @@ authentic2_pratic.models.Service
|
|||
--------------------------------
|
||||
|
||||
Il décrit un service proposé par le CDG59. Ce service peut
|
||||
éventuellement utiliser l'authentification d'authentic soit via le protocole
|
||||
SAML 2.0 soit via le protocole OAuth 2.0.
|
||||
éventuellement utiliser l'authentification d'authentic via le protocole
|
||||
SAML 2.0.
|
||||
|
||||
Les champs `name`, `slug` et `service_url` sont obgligatoires. Le champs
|
||||
`service_url` indique l'URL de base pour accéder au service, c'est l'URL qui
|
||||
sera affichée aux utilisateurs.
|
||||
|
||||
Dans le cas SAML 2.0 le champ `metadata_url` contiendra l'URL des métadonnées
|
||||
du service. Dans le cas OAuth 2.0 les champs oauth2_url et oauth2_key
|
||||
contiendront respecitive l'URL de retour et la clé secrète pour les échanges
|
||||
OAuth 2.0.
|
||||
du service.
|
||||
|
||||
Le champ booléen `is_global` indique si un service est global, dans ce cas les
|
||||
champs `service_url`, 'metadata_url`, `oauth2_url` et `oauth2_key` des
|
||||
instances de ce service seront ignorés et ceux de la définition du service
|
||||
seront utilisés.
|
||||
champs `service_url` et 'metadata_url` des instances de ce service seront
|
||||
ignorés et ceux de la définition du service seront utilisés.
|
||||
|
||||
authentic2_pratic.models.ServiceInstance
|
||||
----------------------------------------
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import re
|
||||
import uuid
|
||||
import tempfile
|
||||
import subprocess
|
||||
|
||||
|
@ -7,6 +8,8 @@ from django.utils.translation import ugettext_lazy as _, ugettext
|
|||
|
||||
from django.contrib.auth import authenticate
|
||||
|
||||
from authentic2.manager.forms import UserEditForm, UserAddForm
|
||||
|
||||
from . import models, fields
|
||||
|
||||
class BaseForm(forms.ModelForm):
|
||||
|
@ -23,7 +26,8 @@ class CertificateMixin(forms.ModelForm):
|
|||
'the issuer and subject DNs by uploading the certificate'), required=False)
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super(CertificateMixin, self).clean()
|
||||
super(CertificateMixin, self).clean()
|
||||
cleaned_data = self.cleaned_data
|
||||
certificate = cleaned_data.get('certificate')
|
||||
if certificate is not None:
|
||||
with tempfile.NamedTemporaryFile() as certificate_file:
|
||||
|
@ -43,7 +47,7 @@ class CertificateMixin(forms.ModelForm):
|
|||
class CollectivityForm(CertificateMixin, BaseForm):
|
||||
class Meta:
|
||||
model = models.Collectivity
|
||||
fields = '__all__'
|
||||
exclude = ('uuid',)
|
||||
|
||||
class ServiceInstanceForm(BaseForm):
|
||||
class Meta:
|
||||
|
@ -61,7 +65,35 @@ class AccessForm(BaseForm):
|
|||
model = models.Access
|
||||
fields = '__all__'
|
||||
|
||||
class UserForm(CertificateMixin, BaseForm):
|
||||
|
||||
class UserMixin(object):
|
||||
def clean(self):
|
||||
cleaned_data = self.cleaned_data
|
||||
cleaned_data['username'] = str(uuid.uuid1())
|
||||
return super(UserMixin, self).clean()
|
||||
|
||||
|
||||
class UserEditForm(UserMixin, CertificateMixin, UserEditForm):
|
||||
class Meta:
|
||||
model = models.User
|
||||
fields = (
|
||||
'uid',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'email',
|
||||
'is_admin',
|
||||
'direction',
|
||||
'employee_type',
|
||||
'postal_address',
|
||||
'fax',
|
||||
'mobile',
|
||||
'phone',
|
||||
'certificate_issuer_dn',
|
||||
'certificate_subject_dn',
|
||||
'certificate',
|
||||
)
|
||||
|
||||
class UserAddForm(UserMixin, CertificateMixin, UserAddForm):
|
||||
class Meta:
|
||||
model = models.User
|
||||
fields = (
|
||||
|
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: authentic2-pratic 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2014-11-24 11:26+0100\n"
|
||||
"POT-Creation-Date: 2015-05-29 10:31+0200\n"
|
||||
"PO-Revision-Date: 2014-11-24 11:28+0100\n"
|
||||
"Last-Translator: Benjamin Dauvergne <bdauvergne@entrouvert.com>\n"
|
||||
"Language-Team: France <fr@li.org>\n"
|
||||
|
@ -17,33 +17,33 @@ msgstr ""
|
|||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: auth_frontends.py:20 dashboard.py:8
|
||||
#: authentic2_pratic/auth_frontends.py:17 authentic2_pratic/dashboard.py:8
|
||||
msgid "Pr@tic"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:21
|
||||
#: authentic2_pratic/forms.py:25
|
||||
msgid "X509 Certificate"
|
||||
msgstr "Certificat X509 au format PEM"
|
||||
|
||||
#: forms.py:21
|
||||
#: authentic2_pratic/forms.py:25
|
||||
msgid "You can set the issuer and subject DNs by uploading the certificate"
|
||||
msgstr ""
|
||||
"Vous pouvez aussi définir les noms distingués du certificat en le "
|
||||
"téléchargeant."
|
||||
|
||||
#: forms.py:85
|
||||
#: authentic2_pratic/forms.py:121
|
||||
msgid "Collectivity"
|
||||
msgstr "Collectivité"
|
||||
|
||||
#: forms.py:86
|
||||
#: authentic2_pratic/forms.py:122
|
||||
msgid "Username"
|
||||
msgstr "Identifiant"
|
||||
|
||||
#: forms.py:87
|
||||
#: authentic2_pratic/forms.py:123
|
||||
msgid "Password"
|
||||
msgstr "Mot de passe"
|
||||
|
||||
#: forms.py:90
|
||||
#: authentic2_pratic/forms.py:126
|
||||
msgid ""
|
||||
"Please enter a correct username and password. Note that both fields may be "
|
||||
"case-sensitive."
|
||||
|
@ -52,188 +52,192 @@ msgstr ""
|
|||
"chacun de ces champs est sensible à la casse (différenciation des majuscules/"
|
||||
"minuscules)."
|
||||
|
||||
#: forms.py:92
|
||||
#: authentic2_pratic/forms.py:128
|
||||
msgid "This account is inactive."
|
||||
msgstr "Ce compte est inactif"
|
||||
|
||||
#: forms.py:130
|
||||
#: authentic2_pratic/forms.py:166
|
||||
msgid "username"
|
||||
msgstr "identifiant"
|
||||
|
||||
#: models.py:22 models.py:109 tables.py:37 tables.py:50
|
||||
#: authentic2_pratic/models.py:29 authentic2_pratic/tables.py:47
|
||||
msgid "identifier"
|
||||
msgstr "identifiant"
|
||||
|
||||
#: models.py:26 models.py:245 models.py:316
|
||||
#: authentic2_pratic/models.py:34 authentic2_pratic/models.py:248
|
||||
#: authentic2_pratic/models.py:312
|
||||
msgid "collectivity"
|
||||
msgstr "collectivité"
|
||||
|
||||
#: models.py:29
|
||||
#: authentic2_pratic/models.py:38
|
||||
msgid "is admin"
|
||||
msgstr "Administrateur?"
|
||||
|
||||
#: models.py:34 models.py:123 models.py:128
|
||||
#: authentic2_pratic/models.py:43 authentic2_pratic/models.py:126
|
||||
#: authentic2_pratic/models.py:131
|
||||
msgid "SIRH Code"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:39
|
||||
#: authentic2_pratic/models.py:48
|
||||
msgid "direction"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:44
|
||||
#: authentic2_pratic/models.py:53
|
||||
msgid "last connection duration"
|
||||
msgstr "durée de la dernière connexion"
|
||||
|
||||
#: models.py:50
|
||||
#: authentic2_pratic/models.py:59
|
||||
msgid "employee type"
|
||||
msgstr "type de poste"
|
||||
|
||||
#: models.py:55 models.py:146
|
||||
#: authentic2_pratic/models.py:64 authentic2_pratic/models.py:149
|
||||
msgid "postal address"
|
||||
msgstr "Adresse postale"
|
||||
|
||||
#: models.py:59 models.py:206
|
||||
#: authentic2_pratic/models.py:68 authentic2_pratic/models.py:209
|
||||
msgid "fax"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:64
|
||||
#: authentic2_pratic/models.py:73
|
||||
msgid "mobile"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:69 models.py:201
|
||||
#: authentic2_pratic/models.py:78 authentic2_pratic/models.py:204
|
||||
msgid "phone"
|
||||
msgstr "téléphone"
|
||||
|
||||
#: models.py:73 models.py:220
|
||||
#: authentic2_pratic/models.py:82 authentic2_pratic/models.py:223
|
||||
msgid "certificate issuer DN"
|
||||
msgstr "nom distingué de l'émetteur du certificat"
|
||||
|
||||
#: models.py:78 models.py:225
|
||||
#: authentic2_pratic/models.py:87 authentic2_pratic/models.py:228
|
||||
msgid "certificate subject DN"
|
||||
msgstr "nom distingué du sujet du certificat"
|
||||
|
||||
#: models.py:87
|
||||
#: authentic2_pratic/models.py:96
|
||||
msgid "agent"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:88
|
||||
#: authentic2_pratic/models.py:97
|
||||
msgid "agents"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:105 models.py:256 tables.py:11 tables.py:24
|
||||
msgid "collectivity name"
|
||||
msgstr "nom"
|
||||
#: authentic2_pratic/models.py:105
|
||||
msgid "This username is already used"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:113
|
||||
#: authentic2_pratic/models.py:116
|
||||
msgid "is superuser"
|
||||
msgstr "Tous les utilisateurs sont des super-administrateurs?"
|
||||
|
||||
#: models.py:118
|
||||
#: authentic2_pratic/models.py:121
|
||||
msgid "collectivity id"
|
||||
msgstr "identifiant de la collectivité"
|
||||
|
||||
#: models.py:133
|
||||
#: authentic2_pratic/models.py:136
|
||||
msgid "INSEE Code"
|
||||
msgstr "code INSEE"
|
||||
|
||||
#: models.py:138
|
||||
#: authentic2_pratic/models.py:141
|
||||
msgid "SIRET Code"
|
||||
msgstr "code SIRET"
|
||||
|
||||
#: models.py:150
|
||||
#: authentic2_pratic/models.py:153
|
||||
msgid "street number"
|
||||
msgstr "numéro dans la rue"
|
||||
|
||||
#: models.py:155
|
||||
#: authentic2_pratic/models.py:158
|
||||
msgid "street"
|
||||
msgstr "rue"
|
||||
|
||||
#: models.py:160
|
||||
#: authentic2_pratic/models.py:163
|
||||
msgid "postal code"
|
||||
msgstr "code postal"
|
||||
|
||||
#: models.py:165
|
||||
#: authentic2_pratic/models.py:168
|
||||
msgid "complementary address"
|
||||
msgstr "adresse complémentaire"
|
||||
|
||||
#: models.py:170
|
||||
#: authentic2_pratic/models.py:173
|
||||
msgid "address mention"
|
||||
msgstr "adresse (mention complémentaire)"
|
||||
|
||||
#: models.py:175
|
||||
#: authentic2_pratic/models.py:178
|
||||
msgid "arrondissement code"
|
||||
msgstr "code d'arrondissement"
|
||||
|
||||
#: models.py:180
|
||||
#: authentic2_pratic/models.py:183
|
||||
msgid "canton code"
|
||||
msgstr "numéro de canton"
|
||||
|
||||
#: models.py:185
|
||||
#: authentic2_pratic/models.py:188
|
||||
msgid "departement code"
|
||||
msgstr "numéro de département"
|
||||
|
||||
#: models.py:190 models.py:195
|
||||
#: authentic2_pratic/models.py:193 authentic2_pratic/models.py:198
|
||||
msgid "distribution office"
|
||||
msgstr "centre de distribution du courrier"
|
||||
|
||||
#: models.py:211
|
||||
#: authentic2_pratic/models.py:214
|
||||
msgid "email"
|
||||
msgstr "courriel"
|
||||
|
||||
#: models.py:216 models.py:269 models.py:318
|
||||
#: authentic2_pratic/models.py:219 authentic2_pratic/models.py:272
|
||||
#: authentic2_pratic/models.py:314
|
||||
msgid "URL"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:246
|
||||
#: authentic2_pratic/models.py:249
|
||||
msgid "collectivities"
|
||||
msgstr "collectivités"
|
||||
|
||||
#: models.py:265
|
||||
#: authentic2_pratic/models.py:259 authentic2_pratic/tables.py:11
|
||||
#: authentic2_pratic/tables.py:24
|
||||
msgid "name"
|
||||
msgstr "nom"
|
||||
|
||||
#: authentic2_pratic/models.py:268
|
||||
msgid "is global"
|
||||
msgstr "service global?"
|
||||
|
||||
#: models.py:271 models.py:321
|
||||
#: authentic2_pratic/models.py:274 authentic2_pratic/models.py:317
|
||||
msgid "SAML Metadata URL"
|
||||
msgstr "URL des métadonnées SAML"
|
||||
|
||||
#: models.py:274 models.py:324
|
||||
msgid "OAuth2 URL"
|
||||
msgstr "URL du point d'accès OAuth2"
|
||||
|
||||
#: models.py:277 models.py:327
|
||||
msgid "OAuth2 Key"
|
||||
msgstr "Clé OAuth2"
|
||||
|
||||
#: models.py:290 models.py:313
|
||||
#: authentic2_pratic/models.py:286 authentic2_pratic/models.py:309
|
||||
msgid "service"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:291
|
||||
#: authentic2_pratic/models.py:287
|
||||
msgid "services"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:345
|
||||
#: authentic2_pratic/models.py:320
|
||||
msgid "Authentication by certificate only"
|
||||
msgstr "Authentificiation seulement par certificat"
|
||||
|
||||
#: authentic2_pratic/models.py:338
|
||||
msgid "There can be only one instance of a global service by collectivity"
|
||||
msgstr ""
|
||||
"Il ne peut y avoir qu'une seule instance d'un service global par collectivité"
|
||||
|
||||
#: models.py:352
|
||||
#: authentic2_pratic/models.py:343
|
||||
msgid "Service URL field is required"
|
||||
msgstr "L'URL de service est requise pour un service non global"
|
||||
|
||||
#: models.py:355 models.py:376
|
||||
#: authentic2_pratic/models.py:346 authentic2_pratic/models.py:367
|
||||
msgid "service instance"
|
||||
msgstr "instance de service"
|
||||
|
||||
#: models.py:356
|
||||
#: authentic2_pratic/models.py:347
|
||||
msgid "service instances"
|
||||
msgstr "instances de service"
|
||||
|
||||
#: models.py:374
|
||||
#: authentic2_pratic/models.py:365
|
||||
msgid "user"
|
||||
msgstr "agent"
|
||||
|
||||
#: models.py:383
|
||||
#: authentic2_pratic/models.py:374
|
||||
msgid ""
|
||||
"Access can only be created between users and service instances of the same "
|
||||
"collectivity"
|
||||
|
@ -241,233 +245,169 @@ msgstr ""
|
|||
"Les accréditations ne peuvent être créé qu'entre une instance de service et "
|
||||
"un utilisateur de la même collectivité"
|
||||
|
||||
#: models.py:390
|
||||
#: authentic2_pratic/models.py:381
|
||||
msgid "access"
|
||||
msgstr "accréditation"
|
||||
|
||||
#: models.py:391
|
||||
#: authentic2_pratic/models.py:382
|
||||
msgid "accesses"
|
||||
msgstr "accréditations"
|
||||
|
||||
#: models.py:423
|
||||
#: authentic2_pratic/models.py:414
|
||||
msgid "This service requires certificate authentication."
|
||||
msgstr ""
|
||||
|
||||
#: authentic2_pratic/models.py:423
|
||||
msgid ""
|
||||
"You are not authorized to access this service. Please contact your "
|
||||
"administrator"
|
||||
msgstr ""
|
||||
"Vous n'êtes pas autorisé à accéder à ce service. Veuillez prendre "
|
||||
"contact avec votre administrateur."
|
||||
"Vous n'êtes pas autorisé à accéder à ce service. Veuillez prendre contact "
|
||||
"avec votre administrateur."
|
||||
|
||||
#: pratic_attribute_source.py:28
|
||||
msgid "User domain"
|
||||
msgstr "Domaine de l'utilisateur"
|
||||
|
||||
#: pratic_attribute_source.py:29
|
||||
msgid "User identifier"
|
||||
msgstr "Identifiant utilisateur"
|
||||
|
||||
#: tables.py:62
|
||||
#: authentic2_pratic/tables.py:59
|
||||
msgid "Last name"
|
||||
msgstr "Nom"
|
||||
|
||||
#: tables.py:64
|
||||
#: authentic2_pratic/tables.py:61
|
||||
msgid "First name"
|
||||
msgstr "Prénom"
|
||||
|
||||
#: views.py:37
|
||||
msgid "You are not a super-administrator or a collectivity administrator"
|
||||
msgstr ""
|
||||
"Vous n'êtes pas un super-administrateur ou un administrateur de collectivité."
|
||||
|
||||
#: views.py:48
|
||||
msgid "You are not a super-administrator"
|
||||
msgstr "Vous n'êtes pas un super-administrateur."
|
||||
|
||||
#: views.py:65 templates/authentic2_pratic/services.html:10
|
||||
msgid "Add service"
|
||||
msgstr "Ajouter un service"
|
||||
|
||||
#: views.py:67 views.py:93 views.py:152 views.py:186 views.py:225
|
||||
msgid "Add"
|
||||
msgstr "Ajouter"
|
||||
|
||||
#: views.py:72
|
||||
msgid "Edit service"
|
||||
msgstr "Éditer un service"
|
||||
|
||||
#: views.py:79
|
||||
msgid "Delete service"
|
||||
msgstr "Supprimer un service"
|
||||
|
||||
#: views.py:91 templates/authentic2_pratic/collectivities.html:10
|
||||
msgid "Add collectivity"
|
||||
msgstr "Ajouter une collectivité"
|
||||
|
||||
#: views.py:98
|
||||
msgid "Edit collectivity"
|
||||
msgstr "Éditer une collectivité"
|
||||
|
||||
#: views.py:106
|
||||
msgid "Delete collectivity"
|
||||
msgstr "Supprimer une collectivité"
|
||||
|
||||
#: views.py:121
|
||||
#, python-format
|
||||
msgid "You are not a super-administrator or an administrator of %s"
|
||||
msgstr "Vous n'êtes pas un super-administrateur ou un administrateur de %s"
|
||||
|
||||
#: views.py:150 templates/authentic2_pratic/users.html:10
|
||||
msgid "Add agent"
|
||||
msgstr "Ajouter un agent"
|
||||
|
||||
#: views.py:157
|
||||
msgid "Edit agent"
|
||||
msgstr "Éditer un agent"
|
||||
|
||||
#: views.py:162
|
||||
msgid "Reset password"
|
||||
msgstr "Ré-initialiser le mot de passe"
|
||||
|
||||
#: views.py:164
|
||||
msgid "Deactivate"
|
||||
msgstr "Désactiver"
|
||||
|
||||
#: views.py:166
|
||||
msgid "Activate"
|
||||
msgstr "Activer"
|
||||
|
||||
#: views.py:172
|
||||
msgid "Delete agent"
|
||||
msgstr "Supprimer un agent"
|
||||
|
||||
#: views.py:184 views.py:223
|
||||
msgid "Add service instance"
|
||||
msgstr "Ajouter une instance de service"
|
||||
|
||||
#: views.py:192 views.py:231
|
||||
msgid "Edit service instance"
|
||||
msgstr "Éditer une instance de service"
|
||||
|
||||
#: views.py:200 views.py:239
|
||||
msgid "Delete service instance"
|
||||
msgstr "Supprimer une instance de service"
|
||||
|
||||
#: templates/authentic2_pratic/accesses.html:4
|
||||
#: templates/authentic2_pratic/accesses.html:6
|
||||
#: templates/authentic2_pratic/collectivity_edit.html:14
|
||||
#: templates/authentic2_pratic/homepage.html:29
|
||||
#: authentic2_pratic/templates/authentic2_pratic/accesses.html:4
|
||||
#: authentic2_pratic/templates/authentic2_pratic/accesses.html:6
|
||||
#: authentic2_pratic/templates/authentic2_pratic/collectivity_edit.html:10
|
||||
#: authentic2_pratic/templates/authentic2_pratic/homepage.html:29
|
||||
msgid "Accesses management"
|
||||
msgstr "Gestion des accréditations"
|
||||
msgstr "Accréditations"
|
||||
|
||||
#: templates/authentic2_pratic/accesses.html:10
|
||||
#: authentic2_pratic/templates/authentic2_pratic/accesses.html:10
|
||||
msgid "Add access"
|
||||
msgstr "Ajouter une accréditation"
|
||||
|
||||
#: templates/authentic2_pratic/accesses.html:14
|
||||
#: authentic2_pratic/templates/authentic2_pratic/accesses.html:14
|
||||
#, python-format
|
||||
msgid "%(count)s accesses"
|
||||
msgid_plural "%(count)s access"
|
||||
msgstr[0] "%(count)s accréditation"
|
||||
msgstr[1] "%(count)s accréditations"
|
||||
|
||||
#: templates/authentic2_pratic/base.html:4
|
||||
#: templates/authentic2_pratic/base.html:26
|
||||
#: authentic2_pratic/templates/authentic2_pratic/base.html:4
|
||||
#: authentic2_pratic/templates/authentic2_pratic/base.html:26
|
||||
msgid "Management"
|
||||
msgstr "Gestion"
|
||||
|
||||
#: templates/authentic2_pratic/collectivities.html:4
|
||||
#: templates/authentic2_pratic/collectivities.html:6
|
||||
#: templates/authentic2_pratic/collectivity_edit.html:8
|
||||
#: authentic2_pratic/templates/authentic2_pratic/collectivities.html:4
|
||||
#: authentic2_pratic/templates/authentic2_pratic/collectivities.html:6
|
||||
#: authentic2_pratic/templates/authentic2_pratic/collectivities.html:9
|
||||
#: authentic2_pratic/templates/authentic2_pratic/collectivity_edit.html:15
|
||||
#: authentic2_pratic/templates/authentic2_pratic/service_instances.html:10
|
||||
#: authentic2_pratic/templates/authentic2_pratic/user_edit.html:10
|
||||
#: authentic2_pratic/templates/authentic2_pratic/users.html:10
|
||||
msgid "Collectivities management"
|
||||
msgstr "Gestion des collectivités"
|
||||
msgstr "Collectivités"
|
||||
|
||||
#: templates/authentic2_pratic/collectivities.html:15
|
||||
#: templates/authentic2_pratic/collectivities.html:18
|
||||
#: authentic2_pratic/templates/authentic2_pratic/collectivities.html:14
|
||||
#: authentic2_pratic/views.py:95
|
||||
msgid "Add collectivity"
|
||||
msgstr "Ajouter une collectivité"
|
||||
|
||||
#: authentic2_pratic/templates/authentic2_pratic/collectivities.html:19
|
||||
#: authentic2_pratic/templates/authentic2_pratic/collectivities.html:22
|
||||
msgid "Search"
|
||||
msgstr "Recherche"
|
||||
|
||||
#: templates/authentic2_pratic/collectivities.html:21
|
||||
#: authentic2_pratic/templates/authentic2_pratic/collectivities.html:25
|
||||
#, python-format
|
||||
msgid "%(count)s collectivities"
|
||||
msgid_plural "%(count)s collectivity"
|
||||
msgstr[0] "%(count)s collectivité"
|
||||
msgstr[1] "%(count)s collectivités"
|
||||
|
||||
#: templates/authentic2_pratic/collectivity_edit.html:12
|
||||
#: templates/authentic2_pratic/homepage.html:27
|
||||
#: templates/authentic2_pratic/users.html:4
|
||||
#: templates/authentic2_pratic/users.html:6
|
||||
#: authentic2_pratic/templates/authentic2_pratic/collectivity_edit.html:8
|
||||
#: authentic2_pratic/templates/authentic2_pratic/homepage.html:27
|
||||
#: authentic2_pratic/templates/authentic2_pratic/user_edit.html:12
|
||||
#: authentic2_pratic/templates/authentic2_pratic/users.html:4
|
||||
#: authentic2_pratic/templates/authentic2_pratic/users.html:6
|
||||
#: authentic2_pratic/templates/authentic2_pratic/users.html:12
|
||||
msgid "Agents management"
|
||||
msgstr "Gestion des agents"
|
||||
msgstr "Agents"
|
||||
|
||||
#: templates/authentic2_pratic/collectivity_edit.html:13
|
||||
#: templates/authentic2_pratic/homepage.html:28
|
||||
#: templates/authentic2_pratic/service_instances.html:4
|
||||
#: templates/authentic2_pratic/service_instances.html:6
|
||||
#: authentic2_pratic/templates/authentic2_pratic/collectivity_edit.html:9
|
||||
#: authentic2_pratic/templates/authentic2_pratic/homepage.html:28
|
||||
#: authentic2_pratic/templates/authentic2_pratic/service_instances.html:4
|
||||
#: authentic2_pratic/templates/authentic2_pratic/service_instances.html:6
|
||||
#: authentic2_pratic/templates/authentic2_pratic/service_instances.html:12
|
||||
msgid "Service instances management"
|
||||
msgstr "Gestion des instances de service"
|
||||
msgstr "Instances de service"
|
||||
|
||||
#: templates/authentic2_pratic/collectivity_edit.html:24
|
||||
#: templates/authentic2_pratic/form.html:31
|
||||
#: authentic2_pratic/templates/authentic2_pratic/collectivity_edit.html:22
|
||||
msgid "Actions"
|
||||
msgstr ""
|
||||
|
||||
#: templates/authentic2_pratic/collectivity_edit.html:48
|
||||
#: templates/authentic2_pratic/form.html:26
|
||||
#: authentic2_pratic/templates/authentic2_pratic/collectivity_edit.html:48
|
||||
#: authentic2_pratic/templates/authentic2_pratic/form.html:6
|
||||
msgid "Certificate"
|
||||
msgstr "Certificat"
|
||||
|
||||
#: authentic2_pratic/templates/authentic2_pratic/collectivity_edit.html:67
|
||||
msgid "Save"
|
||||
msgstr "Sauvegarder"
|
||||
|
||||
#: templates/authentic2_pratic/collectivity_edit.html:49
|
||||
#: templates/authentic2_pratic/delete.html:28
|
||||
#: templates/authentic2_pratic/form.html:27
|
||||
#: templates/authentic2_pratic/login.html:50
|
||||
#: authentic2_pratic/templates/authentic2_pratic/collectivity_edit.html:68
|
||||
#: authentic2_pratic/templates/authentic2_pratic/delete.html:28
|
||||
#: authentic2_pratic/templates/authentic2_pratic/login.html:50
|
||||
msgid "Cancel"
|
||||
msgstr "Annuler"
|
||||
|
||||
#: templates/authentic2_pratic/delete.html:23
|
||||
#: authentic2_pratic/templates/authentic2_pratic/delete.html:23
|
||||
#, python-format
|
||||
msgid "Do you really want to delete « %(object)s » ?"
|
||||
msgstr "Êtez-vous sûr de vouloir supprimer « %(object)s » ?"
|
||||
|
||||
#: templates/authentic2_pratic/delete.html:27
|
||||
#: authentic2_pratic/templates/authentic2_pratic/delete.html:27
|
||||
msgid "Delete"
|
||||
msgstr "Supprimer"
|
||||
|
||||
#: templates/authentic2_pratic/homepage.html:8
|
||||
#: authentic2_pratic/templates/authentic2_pratic/form.html:9
|
||||
msgid "Passwords"
|
||||
msgstr "Mot de passe"
|
||||
|
||||
#: authentic2_pratic/templates/authentic2_pratic/homepage.html:8
|
||||
msgid "Welcome"
|
||||
msgstr "Bievenue"
|
||||
|
||||
#: templates/authentic2_pratic/homepage.html:15
|
||||
#: authentic2_pratic/templates/authentic2_pratic/homepage.html:15
|
||||
msgid "Password change"
|
||||
msgstr "Changer de mot de passe"
|
||||
|
||||
#: templates/authentic2_pratic/homepage.html:21
|
||||
#: authentic2_pratic/templates/authentic2_pratic/homepage.html:21
|
||||
msgid "Collectivities"
|
||||
msgstr "Collectivités"
|
||||
|
||||
#: templates/authentic2_pratic/homepage.html:22
|
||||
#: authentic2_pratic/templates/authentic2_pratic/homepage.html:22
|
||||
msgid "Services"
|
||||
msgstr ""
|
||||
|
||||
#: templates/authentic2_pratic/homepage.html:25
|
||||
#: authentic2_pratic/templates/authentic2_pratic/homepage.html:25
|
||||
#, python-format
|
||||
msgid "Management of %(collectivity)s"
|
||||
msgstr "Gestion de %(collectivity)s"
|
||||
msgstr "%(collectivity)s"
|
||||
|
||||
#: templates/authentic2_pratic/login.html:20
|
||||
#: authentic2_pratic/templates/authentic2_pratic/login.html:20
|
||||
msgid "You are authenticated with certificate of users :"
|
||||
msgstr "Vous êtez authentifié avec le certificat des utilisateurs :"
|
||||
|
||||
#: templates/authentic2_pratic/login.html:26
|
||||
#: authentic2_pratic/templates/authentic2_pratic/login.html:26
|
||||
#, python-format
|
||||
msgid "<em>%(user)s</em> from <em>%(collectivity)s</em>"
|
||||
msgstr "<em>%(user)s</em> de <em>%(collectivity)s</em>"
|
||||
|
||||
#: templates/authentic2_pratic/login.html:29
|
||||
#: templates/authentic2_pratic/login.html:49
|
||||
#: authentic2_pratic/templates/authentic2_pratic/login.html:29
|
||||
#: authentic2_pratic/templates/authentic2_pratic/login.html:49
|
||||
msgid "Log in"
|
||||
msgstr "Connexion"
|
||||
|
||||
#: templates/authentic2_pratic/login.html:40
|
||||
#: authentic2_pratic/templates/authentic2_pratic/login.html:40
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You are\n"
|
||||
|
@ -478,32 +418,139 @@ msgstr ""
|
|||
"Vous êtez authentifié avec le certificat de la collectivité <em>"
|
||||
"%(collectivity)s</em>. Cette collectivité a été pré-selectionné pour vous."
|
||||
|
||||
#: templates/authentic2_pratic/service_instances.html:10
|
||||
#: authentic2_pratic/templates/authentic2_pratic/service_instances.html:17
|
||||
msgid "Add service-instance"
|
||||
msgstr "Ajouter une instance de service"
|
||||
|
||||
#: templates/authentic2_pratic/service_instances.html:14
|
||||
#: authentic2_pratic/templates/authentic2_pratic/service_instances.html:21
|
||||
#, python-format
|
||||
msgid "%(count)s services instances"
|
||||
msgid_plural "%(count)s service instance"
|
||||
msgstr[0] "%(count)s instance de service"
|
||||
msgstr[1] "%(count)s instances de service"
|
||||
|
||||
#: templates/authentic2_pratic/services.html:4
|
||||
#: templates/authentic2_pratic/services.html:6
|
||||
#: authentic2_pratic/templates/authentic2_pratic/services.html:4
|
||||
#: authentic2_pratic/templates/authentic2_pratic/services.html:6
|
||||
msgid "Services management"
|
||||
msgstr "Gestion des services"
|
||||
msgstr "Services"
|
||||
|
||||
#: templates/authentic2_pratic/services.html:14
|
||||
#: authentic2_pratic/templates/authentic2_pratic/services.html:10
|
||||
#: authentic2_pratic/views.py:68
|
||||
msgid "Add service"
|
||||
msgstr "Ajouter un service"
|
||||
|
||||
#: authentic2_pratic/templates/authentic2_pratic/services.html:14
|
||||
#, python-format
|
||||
msgid "%(count)s services"
|
||||
msgid_plural "%(count)s service"
|
||||
msgstr[0] "%(count)s service"
|
||||
msgstr[1] "%(count)s services"
|
||||
|
||||
#: templates/authentic2_pratic/users.html:14
|
||||
#: authentic2_pratic/templates/authentic2_pratic/user_edit.html:4
|
||||
#: authentic2_pratic/templates/authentic2_pratic/user_edit.html:6
|
||||
msgid "Edit user"
|
||||
msgstr "Éditer un utilisateur"
|
||||
|
||||
#: authentic2_pratic/templates/authentic2_pratic/user_edit.html:22
|
||||
msgid "UUID"
|
||||
msgstr "Identifiant unique"
|
||||
|
||||
#: authentic2_pratic/templates/authentic2_pratic/user_edit.html:29
|
||||
msgid "User must change its password on next access to authentic"
|
||||
msgstr "L'utilisateur devra change de mot de passe à sa prochain connexion."
|
||||
|
||||
#: authentic2_pratic/templates/authentic2_pratic/user_edit.html:30
|
||||
msgid "Cancel this constraint"
|
||||
msgstr "Supprimer cette contrainte"
|
||||
|
||||
#: authentic2_pratic/templates/authentic2_pratic/users.html:17
|
||||
#: authentic2_pratic/views.py:155
|
||||
msgid "Add agent"
|
||||
msgstr "Ajouter un agent"
|
||||
|
||||
#: authentic2_pratic/templates/authentic2_pratic/users.html:21
|
||||
#, python-format
|
||||
msgid "%(count)s agent"
|
||||
msgid_plural "%(count)s agents"
|
||||
msgstr[0] "%(count)s agent"
|
||||
msgstr[1] "%(count)s agents"
|
||||
|
||||
#: authentic2_pratic/views.py:40
|
||||
msgid "You are not a super-administrator or a collectivity administrator"
|
||||
msgstr ""
|
||||
"Vous n'êtes pas un super-administrateur ou un administrateur de collectivité."
|
||||
|
||||
#: authentic2_pratic/views.py:51
|
||||
msgid "You are not a super-administrator"
|
||||
msgstr "Vous n'êtes pas un super-administrateur."
|
||||
|
||||
#: authentic2_pratic/views.py:70 authentic2_pratic/views.py:97
|
||||
#: authentic2_pratic/views.py:156 authentic2_pratic/views.py:232
|
||||
#: authentic2_pratic/views.py:273
|
||||
msgid "Add"
|
||||
msgstr "Ajouter"
|
||||
|
||||
#: authentic2_pratic/views.py:76
|
||||
msgid "Edit service"
|
||||
msgstr "Éditer un service"
|
||||
|
||||
#: authentic2_pratic/views.py:83
|
||||
msgid "Delete service"
|
||||
msgstr "Supprimer un service"
|
||||
|
||||
#: authentic2_pratic/views.py:104
|
||||
msgid "Edit collectivity"
|
||||
msgstr "Éditer une collectivité"
|
||||
|
||||
#: authentic2_pratic/views.py:112
|
||||
msgid "Delete collectivity"
|
||||
msgstr "Supprimer une collectivité"
|
||||
|
||||
#: authentic2_pratic/views.py:127
|
||||
#, python-format
|
||||
msgid "You are not a super-administrator or an administrator of %s"
|
||||
msgstr "Vous n'êtes pas un super-administrateur ou un administrateur de %s"
|
||||
|
||||
#: authentic2_pratic/views.py:182
|
||||
msgid "Edit agent"
|
||||
msgstr "Éditer un agent"
|
||||
|
||||
#: authentic2_pratic/views.py:218
|
||||
msgid "Delete agent"
|
||||
msgstr "Supprimer un agent"
|
||||
|
||||
#: authentic2_pratic/views.py:230 authentic2_pratic/views.py:271
|
||||
msgid "Add service instance"
|
||||
msgstr "Ajouter une instance de service"
|
||||
|
||||
#: authentic2_pratic/views.py:240 authentic2_pratic/views.py:280
|
||||
msgid "Edit service instance"
|
||||
msgstr "Éditer une instance de service"
|
||||
|
||||
#: authentic2_pratic/views.py:248 authentic2_pratic/views.py:288
|
||||
msgid "Delete service instance"
|
||||
msgstr "Supprimer une instance de service"
|
||||
|
||||
#~ msgid "collectivity name"
|
||||
#~ msgstr "nom"
|
||||
|
||||
#~ msgid "OAuth2 URL"
|
||||
#~ msgstr "URL du point d'accès OAuth2"
|
||||
|
||||
#~ msgid "OAuth2 Key"
|
||||
#~ msgstr "Clé OAuth2"
|
||||
|
||||
#~ msgid "User domain"
|
||||
#~ msgstr "Domaine de l'utilisateur"
|
||||
|
||||
#~ msgid "User identifier"
|
||||
#~ msgstr "Identifiant utilisateur"
|
||||
|
||||
#~ msgid "Reset password"
|
||||
#~ msgstr "Ré-initialiser le mot de passe"
|
||||
|
||||
#~ msgid "Deactivate"
|
||||
#~ msgstr "Désactiver"
|
||||
|
||||
#~ msgid "Activate"
|
||||
#~ msgstr "Activer"
|
||||
|
|
|
@ -160,7 +160,7 @@ class PraticLDIFParser(ldif.LDIFParser):
|
|||
last_login_duration = int(entry.get('cdg59lastConnectionDuration', [0])[0])
|
||||
is_admin = entry.get('cdg59isAdmin', ['FALSE'])[0] == 'TRUE'
|
||||
user = User(
|
||||
collectivity=collectivity,
|
||||
ou=collectivity,
|
||||
is_active=is_active,
|
||||
last_login_duration=last_login_duration,
|
||||
is_admin=is_admin,
|
||||
|
|
|
@ -8,7 +8,8 @@ from django.conf import settings
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('custom_user', '0005_auto_20150522_1527'),
|
||||
('a2_rbac', '0005_auto_20150526_1406'),
|
||||
('custom_user', '0006_auto_20150527_1212'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
|
@ -26,9 +27,7 @@ class Migration(migrations.Migration):
|
|||
migrations.CreateModel(
|
||||
name='Collectivity',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('name', models.CharField(unique=True, max_length=128, verbose_name='collectivity name')),
|
||||
('slug', models.SlugField(unique=True, max_length=128, verbose_name='identifier')),
|
||||
('organizationalunit_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to=settings.RBAC_OU_MODEL)),
|
||||
('is_superuser', models.BooleanField(default=False, verbose_name='is superuser')),
|
||||
('collectivity_id', models.CharField(max_length=8, verbose_name='collectivity id', blank=True)),
|
||||
('sirh_code', models.CharField(max_length=8, verbose_name='SIRH Code', blank=True)),
|
||||
|
@ -58,7 +57,7 @@ class Migration(migrations.Migration):
|
|||
'verbose_name': 'collectivity',
|
||||
'verbose_name_plural': 'collectivities',
|
||||
},
|
||||
bases=(models.Model,),
|
||||
bases=('a2_rbac.organizationalunit',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Service',
|
||||
|
@ -69,8 +68,6 @@ class Migration(migrations.Migration):
|
|||
('is_global', models.BooleanField(default=False, verbose_name='is global')),
|
||||
('service_url', models.URLField(verbose_name='URL')),
|
||||
('metadata_url', models.URLField(verbose_name='SAML Metadata URL', blank=True)),
|
||||
('oauth2_url', models.URLField(verbose_name='OAuth2 URL', blank=True)),
|
||||
('oauth2_key', models.CharField(max_length=64, verbose_name='OAuth2 Key', blank=True)),
|
||||
],
|
||||
options={
|
||||
'ordering': ('name',),
|
||||
|
@ -86,8 +83,6 @@ class Migration(migrations.Migration):
|
|||
('slug', models.SlugField(max_length=128, verbose_name=b'identifier')),
|
||||
('service_url', models.URLField(verbose_name='URL', blank=True)),
|
||||
('metadata_url', models.URLField(verbose_name='SAML Metadata URL', blank=True)),
|
||||
('oauth2_url', models.URLField(verbose_name='OAuth2 URL', blank=True)),
|
||||
('oauth2_key', models.CharField(max_length=64, verbose_name='OAuth2 Key', blank=True)),
|
||||
('collectivity', models.ForeignKey(verbose_name='collectivity', to='authentic2_pratic.Collectivity')),
|
||||
('service', models.ForeignKey(verbose_name='service', to='authentic2_pratic.Service')),
|
||||
],
|
||||
|
@ -113,7 +108,7 @@ class Migration(migrations.Migration):
|
|||
('phone', models.CharField(max_length=32, verbose_name='phone', blank=True)),
|
||||
('certificate_issuer_dn', models.CharField(max_length=256, null=True, verbose_name='certificate issuer DN', blank=True)),
|
||||
('certificate_subject_dn', models.CharField(max_length=256, null=True, verbose_name='certificate subject DN', blank=True)),
|
||||
('collectivity', models.ForeignKey(verbose_name='collectivity', to='authentic2_pratic.Collectivity')),
|
||||
('collectivity', models.ForeignKey(related_name='collectivities', verbose_name='collectivity', to='authentic2_pratic.Collectivity')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'agent',
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('authentic2_pratic', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='serviceinstance',
|
||||
name='certificate',
|
||||
field=models.BooleanField(default=False, verbose_name='Authentication by certificate only'),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
|
@ -2,7 +2,6 @@ import logging
|
|||
|
||||
from django.db.models import (Model, TextField, CharField, EmailField,
|
||||
URLField, BooleanField, IntegerField, ForeignKey, SlugField, Manager)
|
||||
from django.contrib.auth.models import User as AuthUser
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.dispatch import receiver
|
||||
|
@ -12,6 +11,9 @@ from django.contrib.auth.models import Group
|
|||
from authentic2 import managers
|
||||
from authentic2.idp.signals import authorize_service
|
||||
from authentic2.custom_user.models import User as BaseUser
|
||||
from authentic2.a2_rbac.models import OrganizationalUnit
|
||||
from authentic2.constants import AUTHENTICATION_EVENTS_SESSION_KEY
|
||||
|
||||
|
||||
class User(BaseUser):
|
||||
# givenName -> first_name
|
||||
|
@ -28,7 +30,9 @@ class User(BaseUser):
|
|||
max_length=128)
|
||||
collectivity = ForeignKey(
|
||||
'Collectivity',
|
||||
related_name='collectivities',
|
||||
verbose_name=_('collectivity'))
|
||||
|
||||
# cdg59isAdmin
|
||||
is_admin = BooleanField(
|
||||
verbose_name=_('is admin'),
|
||||
|
@ -96,24 +100,18 @@ class User(BaseUser):
|
|||
|
||||
def clean(self):
|
||||
# prevent collisions between users from multiple collectivities
|
||||
qs = self.__class__.objects.exclude(pk=self.pk)
|
||||
if qs.filter(uid=self.uid, collectivity=self.collectivity).exists():
|
||||
raise ValidationError(_('This username is already used'))
|
||||
if self.uid and not self.username and self.collectivity:
|
||||
self.username = u'%s@%s' % (self.uid, self.collectivity.slug)
|
||||
if self.collectivity:
|
||||
self.is_superuser = self.collectivity.is_superuser
|
||||
super(User, self).clean()
|
||||
|
||||
# Fields to support
|
||||
class Collectivity(Model):
|
||||
class Collectivity(OrganizationalUnit):
|
||||
# Identifiers
|
||||
# cn = ou
|
||||
name = CharField(
|
||||
verbose_name=_('collectivity name'),
|
||||
max_length=128,
|
||||
unique=True)
|
||||
slug = SlugField(
|
||||
verbose_name=_('identifier'),
|
||||
max_length=128,
|
||||
unique=True)
|
||||
is_superuser = BooleanField(
|
||||
verbose_name=_('is superuser'),
|
||||
default=False,
|
||||
|
@ -275,13 +273,6 @@ class Service(Model):
|
|||
metadata_url = URLField(
|
||||
verbose_name=_('SAML Metadata URL'),
|
||||
blank=True)
|
||||
oauth2_url = URLField(
|
||||
verbose_name=_('OAuth2 URL'),
|
||||
blank=True)
|
||||
oauth2_key = CharField(
|
||||
verbose_name=_('OAuth2 Key'),
|
||||
max_length=64,
|
||||
blank=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
@ -325,13 +316,10 @@ class ServiceInstance(Model):
|
|||
metadata_url = URLField(
|
||||
verbose_name=_('SAML Metadata URL'),
|
||||
blank=True)
|
||||
oauth2_url = URLField(
|
||||
verbose_name=_('OAuth2 URL'),
|
||||
blank=True)
|
||||
oauth2_key = CharField(
|
||||
verbose_name=_('OAuth2 Key'),
|
||||
max_length=64,
|
||||
blank=True)
|
||||
certificate = BooleanField(
|
||||
verbose_name=_('Authentication by certificate only'),
|
||||
default=False,
|
||||
blank=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return unicode(self.service)
|
||||
|
@ -351,8 +339,6 @@ class ServiceInstance(Model):
|
|||
if self.service and self.service.is_global:
|
||||
self.service_url = self.service.service_url
|
||||
self.metadata_url = self.service.metadata_url
|
||||
self.oauth2_url = self.service.oauth2_url
|
||||
self.oauth2_key = self.oauth2_key
|
||||
if not self.service.is_global and not self.service_url:
|
||||
raise ValidationError(_('Service URL field is required'))
|
||||
|
||||
|
@ -422,6 +408,11 @@ def authorize_service_cb(request, user, audience, attributes, **kwargs):
|
|||
logger.warn('unable to find service for audience %r and user %r in collectivity %r',
|
||||
audience, unicode(user), unicode(collectivity))
|
||||
return authz(False, 'service not found')
|
||||
if si.certificate:
|
||||
events = request.session.get(AUTHENTICATION_EVENTS_SESSION_KEY, [])
|
||||
if not any(event['how'] in ('ssl', 'ssl-collectivity') for event in events):
|
||||
return authz(False, _('This service requires certificate authentication.'))
|
||||
|
||||
if Access.objects.filter(service_instance=si, user=user).exists():
|
||||
logger.info('%r of collectivity %r is authorized to connect on %r', unicode(user),
|
||||
unicode(collectivity), audience)
|
||||
|
|
|
@ -32,9 +32,6 @@ class CollectivityTable(tables.Table):
|
|||
fields = ('name', 'insee_code', 'postal_code', 'delete')
|
||||
|
||||
class UserTable(tables.Table):
|
||||
uid = tables.TemplateColumn(
|
||||
'<a rel="popup" href="{% url "a2-pratic-user-edit" collectivity_pk=record.collectivity.pk pk=record.pk %}">{{ record.uid }}</a>',
|
||||
verbose_name=_('identifier'))
|
||||
delete = tables.TemplateColumn(
|
||||
'{% load i18n %}<a rel="popup" href="{% url "a2-pratic-user-delete" collectivity_pk=record.collectivity.pk pk=record.pk %}">{% trans "Delete" %}</a>',
|
||||
verbose_name=mark_safe(' '))
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
{% block page-title %}{{ block.super }} - {% trans "Collectivities management" %}{% endblock %}
|
||||
|
||||
{% block page_title %}{% trans "Collectivities management" %}{% endblock %}
|
||||
{% block more-user-links %}
|
||||
{{ block.super }}
|
||||
<a href="{% url 'a2-pratic-collectivities' %}">{% trans "Collectivities management" %}</a>
|
||||
{% endblock %}
|
||||
|
||||
{% block appbar %}
|
||||
{{ block.super }}
|
||||
|
|
|
@ -4,21 +4,19 @@
|
|||
{% block messages %}
|
||||
{% endblock %}
|
||||
|
||||
{% block page_title %}
|
||||
<a href="{% url "a2-pratic-collectivities" %}">{% trans "Collectivities management" %}</a>
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
<p><a href="users/">{% trans "Agents management" %}</a></p>
|
||||
<p><a href="services/">{% trans "Service instances management" %}</a></p>
|
||||
<p><a href="accesses/">{% trans "Accesses management" %}</a></p>
|
||||
{% endblock %}
|
||||
|
||||
{% block more-user-links %}
|
||||
{{ block.super }}
|
||||
<a href="{% url 'a2-pratic-collectivities' %}">{% trans "Collectivities management" %}</a>
|
||||
<a href="{% url 'a2-pratic-collectivity-edit' collectivity_pk=collectivity.pk %}">{{ collectivity }}</a>
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<div class="content">
|
||||
{% if title %}
|
||||
<div id="appbar"><h2>{{ title }}</h2></div>
|
||||
{% endif %}
|
||||
{% if other_actions %}
|
||||
<div class="other_actions">
|
||||
<strong>{% trans "Actions" %}</strong>
|
||||
|
@ -71,5 +69,4 @@
|
|||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -2,12 +2,4 @@
|
|||
{% load i18n staticfiles django_tables2 %}
|
||||
|
||||
{% block page_title %}
|
||||
{% comment %}
|
||||
Only show link for super-admins, collectivity's admins just go back to the homepag
|
||||
{% endcomment %}
|
||||
{% if user.is_superuser %}
|
||||
<a href="{% url "a2-pratic-collectivity-edit" collectivity_pk=collectivity.pk %}">
|
||||
{{ collectivity }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,65 +1,11 @@
|
|||
{% extends "authentic2_pratic/sidebar.html" %}
|
||||
{% extends "authentic2/manager/form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block messages %}
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<div class="content">
|
||||
{% if title %}
|
||||
<div id="appbar"><h2>{{ title }}</h2></div>
|
||||
{% endif %}
|
||||
<form method="post" {% if form.is_multipart %}enctype="multipart/form-data"{% endif %}>
|
||||
<div class="form-inner-container">
|
||||
{% if messages %}
|
||||
<ul class="messages">
|
||||
{% for message in messages %}
|
||||
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>
|
||||
{{ message }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% csrf_token %}
|
||||
{{ form.non_field_errors}}
|
||||
{% for field in form %}
|
||||
{% block form.before-field %}
|
||||
{% if field.name == 'certificate_issuer_dn' %}
|
||||
<h2>{% trans "Certificate" %}</h2>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
<p id="{{field.id_for_label}}_p"
|
||||
class="
|
||||
{% if field.field.required %}required{% endif %}
|
||||
{% if field.errors %}error{% endif %}">
|
||||
{{ field.label_tag }}
|
||||
{{ field }}
|
||||
{% if field.errors %}
|
||||
<span class="errorlist">
|
||||
{% for error in field.errors %}
|
||||
<span>{{ error }}</span>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</p>
|
||||
{% endfor %}
|
||||
<div class="buttons">
|
||||
<button>{% if action %}{{ action }}{% else %}{% trans "Save" %}{% endif %}</button>
|
||||
<a class="cancel" href="..">{% trans "Cancel" %}</a>
|
||||
</div>
|
||||
{% if other_actions %}
|
||||
<div class="other_actions">
|
||||
<strong>{% trans "Actions" %}</strong>
|
||||
<form method="post">
|
||||
{% for action in other_actions %}
|
||||
<input type="submit" name="{{ action.name }}" value="{{ action.title }}"
|
||||
{% if action.confirm %}data-confirm="{{ action.confirm }}"{% endif %}
|
||||
/>
|
||||
{% endfor %}
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% block beforefield %}
|
||||
{% if field.name == 'certificate_issuer_dn' %}
|
||||
<h2>{% trans "Certificate" %}</h2>
|
||||
{% endif %}
|
||||
{% if field.name == 'generate_password' %}
|
||||
<h2>{% trans "Passwords" %}</h2>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -5,6 +5,13 @@
|
|||
|
||||
{% block page_title %}{{ block.super }}{% trans "Service instances management" %}{% endblock %}
|
||||
|
||||
{% block more-user-links %}
|
||||
{{ block.super }}
|
||||
<a href="{% url 'a2-pratic-collectivities' %}">{% trans "Collectivities management" %}</a>
|
||||
<a href="{% url 'a2-pratic-collectivity-edit' collectivity_pk=collectivity.pk %}">{{ collectivity }}</a>
|
||||
<a href="#">{% trans "Service instances management" %}</a>
|
||||
{% endblock %}
|
||||
|
||||
{% block appbar %}
|
||||
{{ block.super }}
|
||||
<a rel="popup" href="{% url "a2-pratic-service-instance-add" collectivity_pk=collectivity.pk %}" id="add-user-btn">{% trans "Add service-instance" %}</a>
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
{% extends "authentic2_pratic/form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page-title %}{{ block.super }} - {% trans "Edit user" %} {{ object }}{% endblock %}
|
||||
|
||||
{% block page_title %}{% trans "Edit user" %} {{ object }}{% endblock %}
|
||||
|
||||
{% block more-user-links %}
|
||||
{{ block.super }}
|
||||
<a href="{% url 'a2-pratic-collectivities' %}">{% trans "Collectivities management" %}</a>
|
||||
<a href="{% url 'a2-pratic-collectivity-edit' collectivity_pk=collectivity.pk %}">{{ collectivity }}</a>
|
||||
<a href="{% url 'a2-pratic-users' collectivity_pk=collectivity.pk %}">{% trans "Agents management" %}</a>
|
||||
<a href="#">{{ object.get_full_name }}</a>
|
||||
{% endblock %}
|
||||
|
||||
{% block appbar %}
|
||||
<h2>{{ object.get_full_name }}</h2>
|
||||
{% endblock %}
|
||||
|
||||
{% block beforeform %}
|
||||
<p>
|
||||
<label for="id_uuid">{% trans "UUID" %} :</label>
|
||||
<input disabled type="text" id="id_uuid" value="{{ form.instance.uuid }}"/>
|
||||
</p>
|
||||
{% endblock %}
|
||||
|
||||
{% block afterform %}
|
||||
{% if object.passwordreset_set.exists %}
|
||||
<div class="warning-box">{% trans "User must change its password on next access to authentic" %}
|
||||
<input type="submit" name="delete_password_reset" value="{% trans "Cancel this constraint" %}"/>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
|
@ -1,10 +1,17 @@
|
|||
{% extends "authentic2_pratic/collectivity_sidebar.html" %}
|
||||
{% extends "authentic2/manager/sidebar.html" %}
|
||||
{% load i18n staticfiles django_tables2 %}
|
||||
|
||||
{% block page-title %}{{ block.super }} - {% trans "Agents management" %}{% endblock %}
|
||||
|
||||
{% block page_title %}{{ block.super }}{% trans "Agents management" %}{% endblock %}
|
||||
|
||||
{% block more-user-links %}
|
||||
{{ block.super }}
|
||||
<a href="{% url 'a2-pratic-collectivities' %}">{% trans "Collectivities management" %}</a>
|
||||
<a href="{% url 'a2-pratic-collectivity-edit' collectivity_pk=collectivity.pk %}">{{ collectivity }}</a>
|
||||
<a href="#">{% trans "Agents management" %}</a>
|
||||
{% endblock %}
|
||||
|
||||
{% block appbar %}
|
||||
{{ block.super }}
|
||||
<a rel="popup" href="{% url "a2-pratic-user-add" collectivity_pk=collectivity.pk %}" id="add-user-btn">{% trans "Add agent" %}</a>
|
||||
|
@ -15,5 +22,7 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% render_table table "authentic2_pratic/table.html" %}
|
||||
{% with row_link=1 %}
|
||||
{% render_table table "authentic2/manager/table.html" %}
|
||||
{% endwith %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from django.conf.urls import patterns, url, include
|
||||
|
||||
from authentic2.manager import user_views as user_views
|
||||
from . import views
|
||||
|
||||
access_urlpatterns = patterns('',
|
||||
|
@ -20,6 +21,9 @@ service_instance_urlpatterns = patterns('',
|
|||
|
||||
user_urlpatterns = patterns('',
|
||||
url('^$', views.user_edit, name='a2-pratic-user-edit'),
|
||||
url(r'change-password/$',
|
||||
user_views.user_change_password,
|
||||
name='a2-manager-user-change-password'),
|
||||
url('^delete/$', views.user_delete, name='a2-pratic-user-delete'))
|
||||
|
||||
collectivity_urlpatterns = patterns('',
|
||||
|
|
|
@ -106,12 +106,14 @@ def sync_saml_provider(service_or_service_instance):
|
|||
saml_slug = u'siid-%s-%s' % (service_or_service_instance.collectivity.slug,
|
||||
service_or_service_instance.slug)
|
||||
name = service_or_service_instance.service.name
|
||||
ou = service_or_service_instance.collectivity
|
||||
else:
|
||||
# if service is not global, do not create it
|
||||
if not service_or_service_instance.is_global:
|
||||
return
|
||||
saml_slug = u'sid-%s' % service_or_service_instance.slug
|
||||
name = service_or_service_instance.name
|
||||
ou = None
|
||||
# enforce limits of LibertyProvider model
|
||||
name = name[:140]
|
||||
saml_slug = saml_slug[:128]
|
||||
|
@ -137,15 +139,17 @@ def sync_saml_provider(service_or_service_instance):
|
|||
logger.warning('updating of metadata of provider %r failed: %s',
|
||||
saml_slug, e)
|
||||
return False
|
||||
liberty_provider.metadata = response.content
|
||||
print response.headers['Content-Type']
|
||||
liberty_provider.metadata = unicode(response.content, 'utf-8')
|
||||
try:
|
||||
liberty_provider.clean()
|
||||
liberty_provider.full_clean(exclude=('ou', 'entity_id', 'protocol_conformance'))
|
||||
except ValidationError, e:
|
||||
logger.warning('updating of metadata of provider %r failed: %s',
|
||||
saml_slug, e)
|
||||
return False
|
||||
liberty_provider.save()
|
||||
liberty_service_provider, created = LibertyServiceProvider.objects.get_or_create(
|
||||
ou=ou,
|
||||
liberty_provider=liberty_provider,
|
||||
defaults={'enabled': True})
|
||||
return True
|
||||
|
|
|
@ -3,15 +3,16 @@ from django.shortcuts import get_object_or_404, redirect
|
|||
from django.contrib import messages
|
||||
from django.contrib.auth.views import redirect_to_login
|
||||
from django.db.models.query import Q
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from django.views.generic import (TemplateView, UpdateView,
|
||||
CreateView, DeleteView)
|
||||
CreateView, DeleteView)
|
||||
from django_tables2 import SingleTableView
|
||||
|
||||
from authentic2.manager.views import AjaxFormViewMixin, \
|
||||
ActionMixin, OtherActionsMixin, TitleMixin, Action
|
||||
|
||||
from authentic2.manager.user_views import UserEditView
|
||||
from authentic2.manager.user_views import UserEditView, UserAddView
|
||||
|
||||
from . import models, tables, forms
|
||||
|
||||
|
@ -121,8 +122,8 @@ class CollectivityMixin(object):
|
|||
return redirect_to_login(request.get_full_path())
|
||||
|
||||
if not user.is_superuser and \
|
||||
(not hasattr(user, 'is_admin') or
|
||||
not (user.is_admin and user.collectivity == self.collectivity)):
|
||||
(not hasattr(user, 'is_admin') or
|
||||
not (user.is_admin and user.ou == self.collectivity)):
|
||||
messages.warning(request, _('You are not a super-administrator or an administrator of %s') % self.collectivity)
|
||||
return redirect('auth_homepage')
|
||||
return super(CollectivityMixin, self).dispatch(request, *args, **kwargs)
|
||||
|
@ -149,27 +150,66 @@ class UsersView(CollectivityChildMixin, SingleTableView):
|
|||
model = models.User
|
||||
table_class = tables.UserTable
|
||||
|
||||
class UserAddView(CollectivityChildMixin, TitleMixin, ActionMixin,
|
||||
AjaxFormViewMixin, CreateView):
|
||||
class UserAddView(CollectivityChildMixin, UserAddView):
|
||||
model = models.User
|
||||
title = _('Add agent')
|
||||
template_name = 'authentic2_pratic/form.html'
|
||||
action = _('Add')
|
||||
form_class = forms.UserForm
|
||||
form_class = forms.UserAddForm
|
||||
template_name = 'authentic2_pratic/form.html'
|
||||
success_url = '..'
|
||||
fields = (
|
||||
'uid',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'email',
|
||||
'is_admin',
|
||||
'direction',
|
||||
'employee_type',
|
||||
'postal_address',
|
||||
'fax',
|
||||
'mobile',
|
||||
'phone',
|
||||
'certificate_issuer_dn',
|
||||
'certificate_subject_dn',
|
||||
'certificate',
|
||||
)
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('a2-pratic-user-edit', kwargs={'collectivity_pk': self.object.collectivity.pk, 'pk': self.object.pk})
|
||||
|
||||
class UserView(CollectivityChildMixin, UserEditView):
|
||||
model = models.User
|
||||
title = _('Edit agent')
|
||||
template_name = 'authentic2_pratic/form.html'
|
||||
form_class = forms.UserForm
|
||||
form_class = forms.UserEditForm
|
||||
template_name = 'authentic2_pratic/user_edit.html'
|
||||
fields = (
|
||||
'uid',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'email',
|
||||
'is_admin',
|
||||
'direction',
|
||||
'employee_type',
|
||||
'postal_address',
|
||||
'fax',
|
||||
'mobile',
|
||||
'phone',
|
||||
'certificate_issuer_dn',
|
||||
'certificate_subject_dn',
|
||||
'certificate',
|
||||
)
|
||||
|
||||
def get_other_actions(self):
|
||||
yield Action('password_reset', _('Reset password'))
|
||||
if self.object.is_active:
|
||||
yield Action('deactivate', _('Deactivate'))
|
||||
else:
|
||||
yield Action('activate', _('Activate'))
|
||||
actions = list(super(UserView, self).get_other_actions())
|
||||
for action in actions:
|
||||
if action.url_name == 'a2-manager-user-change-password':
|
||||
action.url_name = None
|
||||
action.url = reverse('a2-manager-user-change-password',
|
||||
kwargs={'collectivity_pk':
|
||||
self.object.collectivity.pk,
|
||||
'pk': self.object.pk})
|
||||
return actions
|
||||
|
||||
|
||||
class UserDeleteView(CollectivityChildMixin, TitleMixin, AjaxFormViewMixin,
|
||||
DeleteView):
|
||||
|
@ -191,6 +231,8 @@ class ServiceInstanceAddView(CollectivityChildMixin, TitleMixin, ActionMixin,
|
|||
template_name = 'authentic2_pratic/form.html'
|
||||
action = _('Add')
|
||||
form_class = forms.ServiceInstanceForm
|
||||
success_url = '..'
|
||||
|
||||
|
||||
class ServiceInstanceView(CollectivityChildMixin, TitleMixin,
|
||||
OtherActionsMixin, AjaxFormViewMixin, UpdateView):
|
||||
|
@ -204,7 +246,7 @@ class ServiceInstanceDeleteView(CollectivityChildMixin, TitleMixin,
|
|||
model = models.ServiceInstance
|
||||
template_name = 'authentic2_pratic/delete.html'
|
||||
title = _('Delete service instance')
|
||||
success_url = 'a2-pratic-users'
|
||||
success_url = '../..'
|
||||
|
||||
# accesses
|
||||
class AccessMixin(object):
|
||||
|
@ -230,6 +272,7 @@ class AccessAddView(AccessMixin, CollectivityMixin, TitleMixin, ActionMixin,
|
|||
template_name = 'authentic2_pratic/form.html'
|
||||
action = _('Add')
|
||||
form_class = forms.AccessForm
|
||||
success_url = '..'
|
||||
|
||||
class AccessView(AccessMixin, CollectivityMixin, TitleMixin,
|
||||
OtherActionsMixin, AjaxFormViewMixin, UpdateView):
|
||||
|
@ -244,6 +287,7 @@ class AccessDeleteView(AccessMixin, CollectivityMixin, TitleMixin,
|
|||
template_name = 'authentic2_pratic/delete.html'
|
||||
title = _('Delete service instance')
|
||||
success_url = 'a2-pratic-users'
|
||||
success_url = '../..'
|
||||
|
||||
# general views
|
||||
homepage = HomepageView.as_view()
|
||||
|
|
Reference in New Issue