Commit | Line | Data |
---|---|---|
588d6b93 | 1 | # -*- encoding: utf-8 -*- |
ae075d2c PP |
2 | import re |
3 | ||
ff753fa4 | 4 | from auf.django.references.models import Etablissement |
fa6a2a07 | 5 | from django.conf import settings |
fa6a2a07 EMS |
6 | from django.contrib.auth import REDIRECT_FIELD_NAME |
7 | from django.contrib.auth import login as auth_login | |
ff753fa4 | 8 | from django.contrib.auth import authenticate |
fdcf5874 | 9 | from django.contrib.auth.decorators import login_required |
ff753fa4 | 10 | from django.contrib.auth.forms import PasswordChangeForm |
fa6a2a07 | 11 | from django.contrib.sites.models import RequestSite, Site |
ff753fa4 EMS |
12 | from django.core.urlresolvers import reverse as url |
13 | from django.core.mail import send_mail | |
2aa2a26c | 14 | from django.http import HttpResponse, Http404 |
ff753fa4 EMS |
15 | from django.shortcuts import render, get_object_or_404, redirect |
16 | from django.template import Context | |
17 | from django.template.loader import get_template | |
219710da | 18 | from django.utils import simplejson |
43ed73e7 | 19 | from django.utils.http import int_to_base36, base36_to_int |
a7b16ec9 | 20 | from django.views.decorators.cache import never_cache |
b0609188 | 21 | from django.views.decorators.csrf import csrf_protect |
ff753fa4 EMS |
22 | |
23 | from chercheurs.decorators import chercheur_required | |
24 | from chercheurs.forms import \ | |
25 | ChercheurSearchForm, SetPasswordForm, ChercheurFormGroup, \ | |
26 | AuthenticationForm, GroupeSearchForm, MessageForm | |
27 | from chercheurs.models import \ | |
28 | Chercheur, Groupe, Message, AdhesionGroupe, AuthLDAP | |
29 | from chercheurs.utils import \ | |
30 | get_django_user_for_email, create_ldap_hash, check_ldap_hash | |
31 | from savoirs.models import PageStatique | |
510b5321 | 32 | |
9aa1d783 | 33 | |
f0692c02 | 34 | def index(request): |
ff753fa4 EMS |
35 | """ |
36 | Répertoire des chercheurs | |
37 | """ | |
fdcf5874 | 38 | search_form = ChercheurSearchForm(request.GET) |
2aa2a26c EMS |
39 | if search_form.is_valid(): |
40 | search = search_form.save(commit=False) | |
41 | else: | |
42 | raise Http404 | |
fdcf5874 | 43 | chercheurs = search.run().select_related('etablissement') |
7020ea3d EMS |
44 | sort = request.GET.get('tri') |
45 | if sort is not None and sort.endswith('_desc'): | |
46 | sort = sort[:-5] | |
47 | direction = '-' | |
48 | else: | |
49 | direction = '' | |
50 | if sort == 'nom': | |
acd5cd8f | 51 | chercheurs = chercheurs.order_by_nom(direction) |
7020ea3d | 52 | elif sort == 'etablissement': |
acd5cd8f | 53 | chercheurs = chercheurs.order_by_etablissement(direction) |
7020ea3d | 54 | elif sort == 'pays': |
acd5cd8f | 55 | chercheurs = chercheurs.order_by_pays(direction) |
7020ea3d EMS |
56 | else: |
57 | chercheurs = chercheurs.order_by('-date_modification') | |
ff753fa4 | 58 | |
f09bc1c6 EMS |
59 | try: |
60 | p = PageStatique.objects.get(id='repertoire') | |
61 | entete = p.contenu | |
62 | except PageStatique.DoesNotExist: | |
63 | entete = u'<h1>Répertoire des chercheurs</h1>' | |
7020ea3d | 64 | |
9f7c169e | 65 | nb_chercheurs = chercheurs.count() |
fdcf5874 | 66 | |
ff753fa4 EMS |
67 | return render(request, "chercheurs/index.html", { |
68 | 'chercheurs': chercheurs, | |
69 | 'nb_chercheurs': nb_chercheurs, | |
70 | 'search_form': search_form, | |
71 | 'entete': entete | |
72 | }) | |
73 | ||
588d6b93 | 74 | |
f0692c02 | 75 | def inscription(request): |
932eef9a | 76 | if request.method == 'POST': |
a7b16ec9 EMS |
77 | forms = ChercheurFormGroup(request.POST) |
78 | if forms.is_valid(): | |
43ed73e7 EMS |
79 | chercheur = forms.save() |
80 | id_base36 = int_to_base36(chercheur.id) | |
81 | token = chercheur.activation_token() | |
82 | template = get_template('chercheurs/activation_email.txt') | |
83 | domain = RequestSite(request).domain | |
ff753fa4 EMS |
84 | message = template.render(Context({ |
85 | 'chercheur': chercheur, | |
86 | 'id_base36': id_base36, | |
87 | 'token': token, | |
88 | 'domain': domain | |
89 | })) | |
90 | send_mail( | |
91 | 'Votre inscription à Savoirs en partage', | |
92 | message, None, [chercheur.courriel] | |
93 | ) | |
94 | return redirect('chercheurs-inscription-faite') | |
932eef9a | 95 | else: |
a7b16ec9 | 96 | forms = ChercheurFormGroup() |
ff753fa4 EMS |
97 | |
98 | return render(request, "chercheurs/inscription.html", { | |
99 | 'forms': forms | |
100 | }) | |
101 | ||
9af73c99 | 102 | |
43ed73e7 EMS |
103 | def activation(request, id_base36, token): |
104 | """Activation d'un chercheur""" | |
105 | id = base36_to_int(id_base36) | |
3e556e66 | 106 | chercheur = get_object_or_404(Chercheur.all_objects, id=id) |
43ed73e7 EMS |
107 | if token == chercheur.activation_token(): |
108 | validlink = True | |
109 | if request.method == 'POST': | |
110 | form = SetPasswordForm(request.POST) | |
111 | if form.is_valid(): | |
112 | password = form.cleaned_data['password'] | |
113 | email = chercheur.courriel | |
114 | chercheur.actif = True | |
695930dd EMS |
115 | user = get_django_user_for_email(email) |
116 | user.set_password(password) | |
117 | user.save() | |
b9b3e6ba PP |
118 | chercheur.user = user |
119 | chercheur.save() | |
43ed73e7 EMS |
120 | |
121 | # Auto-login | |
ff753fa4 EMS |
122 | auth_login( |
123 | request, authenticate(username=email, password=password) | |
124 | ) | |
125 | return redirect('chercheurs.views.perso') | |
43ed73e7 EMS |
126 | else: |
127 | form = SetPasswordForm() | |
128 | else: | |
129 | form = None | |
130 | validlink = False | |
ff753fa4 EMS |
131 | return render(request, 'chercheurs/activation.html', { |
132 | 'form': form, | |
133 | 'validlink': validlink | |
134 | }) | |
135 | ||
43ed73e7 | 136 | |
b0609188 PP |
137 | @csrf_protect |
138 | @login_required | |
ff753fa4 EMS |
139 | def password_change(request, |
140 | template_name='registration/password_change_form.html', | |
141 | post_change_redirect=None, | |
142 | password_change_form=PasswordChangeForm): | |
b0609188 | 143 | if post_change_redirect is None: |
ff753fa4 EMS |
144 | post_change_redirect = url( |
145 | 'django.contrib.auth.views.password_change_done' | |
146 | ) | |
b0609188 PP |
147 | if request.method == "POST": |
148 | form = password_change_form(user=request.user, data=request.POST) | |
149 | if form.is_valid(): | |
150 | form.save() | |
151 | ||
152 | # Mot de passe pour LDAP | |
153 | username = request.user.email | |
ff753fa4 EMS |
154 | authldap, created = \ |
155 | AuthLDAP.objects.get_or_create(username=username) | |
b0609188 | 156 | password = form.cleaned_data.get('new_password1') |
ae075d2c | 157 | authldap.ldap_hash = create_ldap_hash(password) |
b0609188 PP |
158 | authldap.save() |
159 | ||
ff753fa4 | 160 | return redirect(post_change_redirect) |
b0609188 PP |
161 | else: |
162 | form = password_change_form(user=request.user) | |
ff753fa4 | 163 | return render(request, template_name, {'form': form}) |
b0609188 PP |
164 | |
165 | ||
518d0b44 | 166 | @chercheur_required |
8baa2a56 EMS |
167 | def desinscription(request): |
168 | """Désinscription du chercheur""" | |
518d0b44 | 169 | chercheur = request.chercheur |
8baa2a56 EMS |
170 | if request.method == 'POST': |
171 | if request.POST.get('confirmer'): | |
13ec4813 EMS |
172 | chercheur.actif = False |
173 | chercheur.save() | |
ff753fa4 EMS |
174 | request.flash['message'] = \ |
175 | "Vous avez été désinscrit du répertoire des chercheurs." | |
176 | return redirect('django.contrib.auth.views.logout') | |
8baa2a56 EMS |
177 | else: |
178 | request.flash['message'] = "Opération annulée." | |
ff753fa4 EMS |
179 | return redirect('chercheurs.views.perso') |
180 | return render(request, "chercheurs/desinscription.html") | |
181 | ||
8baa2a56 | 182 | |
518d0b44 | 183 | @chercheur_required |
a7b16ec9 | 184 | @never_cache |
f0692c02 | 185 | def edit(request): |
b3e1079e | 186 | """Edition d'un chercheur""" |
518d0b44 | 187 | chercheur = request.chercheur |
b3e1079e | 188 | if request.method == 'POST': |
a7b16ec9 EMS |
189 | forms = ChercheurFormGroup(request.POST, chercheur=chercheur) |
190 | if forms.is_valid(): | |
191 | forms.save() | |
91112855 | 192 | request.flash['message'] = "Votre fiche a bien été enregistrée." |
ff753fa4 | 193 | return redirect('chercheurs.views.perso') |
b3e1079e | 194 | else: |
a7b16ec9 | 195 | forms = ChercheurFormGroup(chercheur=chercheur) |
ff753fa4 EMS |
196 | |
197 | return render(request, "chercheurs/edit.html", { | |
198 | 'forms': forms, | |
199 | 'chercheur': chercheur | |
200 | }) | |
201 | ||
202 | ||
518d0b44 | 203 | @chercheur_required |
f0692c02 | 204 | def perso(request): |
0d9d1c4d | 205 | """Espace chercheur (espace personnel du chercheur)""" |
518d0b44 | 206 | chercheur = request.chercheur |
2a36714f | 207 | modification = request.GET.get('modification') |
ff753fa4 EMS |
208 | return render(request, "chercheurs/perso.html", { |
209 | 'chercheur': chercheur, | |
210 | 'modification': modification | |
211 | }) | |
212 | ||
213 | ||
f0692c02 | 214 | def retrieve(request, id): |
da091176 | 215 | """Fiche du chercheur""" |
3eb00212 | 216 | chercheur = get_object_or_404(Chercheur, id=id) |
ff753fa4 EMS |
217 | return render(request, "chercheurs/retrieve.html", { |
218 | 'chercheur': chercheur | |
219 | }) | |
220 | ||
221 | ||
f0692c02 | 222 | def conversion(request): |
ff753fa4 EMS |
223 | return render(request, "chercheurs/conversion.html") |
224 | ||
8baa2a56 | 225 | |
e836f6f7 | 226 | def etablissements_autocomplete(request, pays=None): |
219710da | 227 | term = request.GET.get('term') |
e76f8899 | 228 | noms = Etablissement.objects.all().filter(membre=True, actif=True) |
e836f6f7 EMS |
229 | for word in term.split(): |
230 | noms = noms.filter(nom__icontains=word) | |
231 | if pays: | |
232 | noms = noms.filter(pays=pays) | |
233 | noms = list(noms.values_list('nom', flat=True)[:20]) | |
219710da EMS |
234 | json = simplejson.dumps(noms) |
235 | return HttpResponse(json, mimetype='application/json') | |
fa6a2a07 | 236 | |
ff753fa4 EMS |
237 | |
238 | def login(request, template_name='registration/login.html', | |
239 | redirect_field_name=REDIRECT_FIELD_NAME): | |
fa6a2a07 EMS |
240 | "The Django login view, but using a custom form." |
241 | redirect_to = request.REQUEST.get(redirect_field_name, '') | |
ff753fa4 | 242 | |
fa6a2a07 EMS |
243 | if request.method == "POST": |
244 | form = AuthenticationForm(data=request.POST) | |
245 | if form.is_valid(): | |
246 | # Light security check -- make sure redirect_to isn't garbage. | |
247 | if not redirect_to or ' ' in redirect_to: | |
248 | redirect_to = settings.LOGIN_REDIRECT_URL | |
ff753fa4 EMS |
249 | |
250 | # Heavier security check -- redirects to http://example.com | |
251 | # should not be allowed, but things like | |
252 | # /view/?param=http://example.com should be allowed. This regex | |
253 | # checks if there is a '//' *before* a question mark. | |
fa6a2a07 EMS |
254 | elif '//' in redirect_to and re.match(r'[^\?]*//', redirect_to): |
255 | redirect_to = settings.LOGIN_REDIRECT_URL | |
ff753fa4 | 256 | |
544dec4f PP |
257 | # Mot de passe pour LDAP |
258 | username = form.cleaned_data.get('username') | |
ae075d2c | 259 | password = form.cleaned_data.get('password') |
ff753fa4 EMS |
260 | authldap, created = \ |
261 | AuthLDAP.objects.get_or_create(username=username) | |
ae075d2c PP |
262 | if created or not check_ldap_hash(authldap.ldap_hash, password): |
263 | authldap.ldap_hash = create_ldap_hash(password) | |
544dec4f PP |
264 | authldap.save() |
265 | ||
fa6a2a07 EMS |
266 | # Okay, security checks complete. Log the user in. |
267 | auth_login(request, form.get_user()) | |
268 | ||
269 | if request.session.test_cookie_worked(): | |
270 | request.session.delete_test_cookie() | |
271 | ||
ff753fa4 | 272 | return redirect(redirect_to) |
fa6a2a07 EMS |
273 | |
274 | else: | |
275 | form = AuthenticationForm(request) | |
276 | request.session.set_test_cookie() | |
ff753fa4 | 277 | |
fa6a2a07 EMS |
278 | if Site._meta.installed: |
279 | current_site = Site.objects.get_current() | |
280 | else: | |
281 | current_site = RequestSite(request) | |
ff753fa4 EMS |
282 | |
283 | return render(request, template_name, { | |
fa6a2a07 EMS |
284 | 'form': form, |
285 | redirect_field_name: redirect_to, | |
286 | 'site': current_site, | |
287 | 'site_name': current_site.name, | |
ff753fa4 | 288 | }) |
fa6a2a07 | 289 | login = never_cache(login) |
cdaadee3 | 290 | |
ff753fa4 | 291 | |
cdaadee3 PP |
292 | # groupes |
293 | def groupe_index(request): | |
294 | search_form = GroupeSearchForm(request.GET) | |
295 | search = search_form.save(commit=False) | |
296 | groupes = search.run() | |
297 | nb_resultats = groupes.count() | |
298 | try: | |
299 | p = PageStatique.objects.get(id='groupes') | |
300 | entete = p.contenu | |
301 | except PageStatique.DoesNotExist: | |
381cc09a PP |
302 | entete = '<h1>Liste des groupes</h1>' |
303 | ||
96316da7 | 304 | est_chercheur, mesgroupes, messages = False, None, None |
381cc09a | 305 | if request.user.is_authenticated(): |
6115dba0 PP |
306 | try: |
307 | chercheur = Chercheur.objects.get(courriel=request.user.email) | |
ff753fa4 EMS |
308 | mesgroupes = chercheur.groupes.filter( |
309 | membership__statut='accepte', groupe_chercheur=True | |
310 | ) | |
96316da7 PP |
311 | messages = Message.objects.all().filter(groupe__in=mesgroupes)[:10] |
312 | est_chercheur = True | |
6115dba0 | 313 | except Chercheur.DoesNotExist: |
96316da7 PP |
314 | pass |
315 | ||
ff753fa4 | 316 | return render(request, "chercheurs/groupe_index.html", { |
96316da7 PP |
317 | 'search_form': search_form, |
318 | 'groupes': groupes.order_by('nom'), | |
319 | 'nb_resultats': nb_resultats, | |
320 | 'entete': entete, | |
321 | 'mesgroupes': mesgroupes, | |
322 | 'messages': messages, | |
323 | 'est_chercheur': est_chercheur, | |
ff753fa4 EMS |
324 | }) |
325 | ||
cdaadee3 | 326 | |
0eb2476e PP |
327 | def groupe_adhesion(request, id): |
328 | try: | |
329 | groupe = get_object_or_404(Groupe, id=id) | |
330 | chercheur = Chercheur.objects.get(courriel=request.user.email) | |
ff753fa4 EMS |
331 | adhesion, created = AdhesionGroupe.objects.get_or_create( |
332 | chercheur=chercheur, groupe=groupe | |
333 | ) | |
0eb2476e | 334 | if created: |
18407f73 PP |
335 | adhesion.actif = 0 |
336 | adhesion.save() | |
0eb2476e PP |
337 | except: |
338 | pass | |
339 | ||
ff753fa4 EMS |
340 | return redirect('groupe_retrieve', id=id) |
341 | ||
0eb2476e | 342 | |
cdaadee3 PP |
343 | def groupe_retrieve(request, id): |
344 | groupe = get_object_or_404(Groupe, id=id) | |
ff753fa4 EMS |
345 | membres = groupe.membership.all() \ |
346 | .filter(statut='accepte').order_by('-date_modification') | |
ddf7e62e PP |
347 | plus_que_20 = True if membres.count() > 20 else False |
348 | membres_20 = membres[:20] | |
fd6352ea | 349 | messages = groupe.message_set.all()[:5] |
0c0d997c | 350 | |
0eb2476e PP |
351 | est_chercheur, est_membre, est_membre_actif = False, False, False |
352 | if request.user.is_authenticated(): | |
353 | try: | |
354 | chercheur = Chercheur.objects.get(courriel=request.user.email) | |
355 | est_chercheur = True | |
356 | est_membre = chercheur in groupe.membres.all() | |
ff753fa4 EMS |
357 | est_membre_actif = bool(len(groupe.membership.filter( |
358 | chercheur=chercheur, statut='accepte' | |
359 | ))) | |
0eb2476e PP |
360 | except Chercheur.DoesNotExist: |
361 | pass | |
362 | ||
ff753fa4 EMS |
363 | return render(request, "chercheurs/groupe_retrieve.html", { |
364 | 'groupe': groupe, | |
365 | 'membres': membres_20, | |
366 | 'plus_que_20': plus_que_20, | |
367 | 'messages': messages, | |
368 | 'est_chercheur': est_chercheur, | |
369 | 'est_membre': est_membre, | |
370 | 'est_membre_actif': est_membre_actif, | |
371 | }) | |
372 | ||
c8d6b979 | 373 | |
ddf7e62e PP |
374 | def groupe_membres(request, id): |
375 | groupe = get_object_or_404(Groupe, id=id) | |
ff753fa4 EMS |
376 | membres = groupe.membership.all() \ |
377 | .filter(statut='accepte').order_by('chercheur__nom') | |
ddf7e62e | 378 | |
ff753fa4 EMS |
379 | return render(request, "chercheurs/groupe_membres.html", { |
380 | 'groupe': groupe, | |
381 | 'membres': membres, | |
382 | }) | |
ddf7e62e | 383 | |
fd6352ea | 384 | |
ff753fa4 | 385 | def groupe_messages(request, id): |
fd6352ea PP |
386 | groupe = get_object_or_404(Groupe, id=id) |
387 | ||
9aa1d783 PP |
388 | est_chercheur, est_membre, est_membre_actif = False, False, False |
389 | if request.user.is_authenticated(): | |
390 | try: | |
391 | chercheur = Chercheur.objects.get(courriel=request.user.email) | |
392 | est_chercheur = True | |
393 | est_membre = chercheur in groupe.membres.all() | |
ff753fa4 EMS |
394 | est_membre_actif = bool(len(groupe.membership.filter( |
395 | chercheur=chercheur, statut='accepte' | |
396 | ))) | |
9aa1d783 PP |
397 | except Chercheur.DoesNotExist: |
398 | pass | |
399 | ||
400 | if est_membre_actif and request.method == 'POST': | |
fd6352ea PP |
401 | form = MessageForm(request.POST) |
402 | if form.is_valid(): | |
fd6352ea PP |
403 | message = form.save(commit=False) |
404 | message.groupe = groupe | |
405 | message.chercheur = chercheur | |
406 | message.save() | |
407 | ||
408 | form = MessageForm() | |
409 | ||
410 | else: | |
411 | form = MessageForm() | |
412 | ||
413 | messages = groupe.message_set.all() | |
414 | ||
ff753fa4 EMS |
415 | return render(request, "chercheurs/groupe_message.html", { |
416 | 'groupe': groupe, | |
417 | 'messages': messages, | |
418 | 'form': form, | |
419 | 'est_chercheur': est_chercheur, | |
420 | 'est_membre': est_membre, | |
421 | 'est_membre_actif': est_membre_actif, | |
422 | }) |