95985f3550d2600b818da7bc951f134f5f94fbf5
[flowspy] / flowspec / views.py
1 # -*- coding: utf-8 -*- vim:fileencoding=utf-8:
2 # vim: tabstop=4:shiftwidth=4:softtabstop=4:expandtab
3
4 # Copyright (C) 2010-2014 GRNET S.A.
5 #
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 #
19
20 import urllib2
21 import socket
22 import json
23 from django import forms
24 from django.views.decorators.csrf import csrf_exempt
25 from django.core import urlresolvers
26 from django.core import serializers
27 from django.contrib.auth.decorators import login_required
28 from django.contrib.auth import logout
29 from django.contrib.sites.models import Site
30 from django.contrib.auth.models import User
31 from django.http import HttpResponseRedirect, HttpResponseForbidden, HttpResponse
32 from django.shortcuts import get_object_or_404, render_to_response
33 from django.core.context_processors import request
34 from django.template.context import RequestContext
35 from django.template.loader import get_template, render_to_string
36 from django.utils.translation import ugettext as _
37 from django.core.urlresolvers import reverse
38 from django.contrib import messages
39 from accounts.models import *
40 from ipaddr import *
41
42 from django.contrib.auth import authenticate, login
43
44 from django.forms.models import model_to_dict
45
46 from flowspec.forms import * 
47 from flowspec.models import *
48 from peers.models import *
49
50 from registration.models import RegistrationProfile
51
52 from copy import deepcopy
53 from utils.decorators import shib_required
54
55 from django.views.decorators.cache import never_cache
56 from django.conf import settings
57 from django.core.mail.message import EmailMessage
58 from django.template.defaultfilters import slugify
59 import datetime
60 import os
61
62 LOG_FILENAME = os.path.join(settings.LOG_FILE_LOCATION, 'celery_jobs.log')
63 #FORMAT = '%(asctime)s %(levelname)s: %(message)s'
64 #logging.basicConfig(format=FORMAT)
65 formatter = logging.Formatter('%(asctime)s %(levelname)s %(clientip)s %(user)s: %(message)s')
66
67 logger = logging.getLogger(__name__)
68 logger.setLevel(logging.DEBUG)
69 handler = logging.FileHandler(LOG_FILENAME)
70 handler.setFormatter(formatter)
71 logger.addHandler(handler)
72
73 @login_required
74 def user_routes(request):
75     user_routes = Route.objects.filter(applier=request.user)
76     return render_to_response('user_routes.html', {'routes': user_routes},
77                               context_instance=RequestContext(request))
78
79 def welcome(request):
80     return render_to_response('welcome.html', context_instance=RequestContext(request))
81
82 @login_required
83 @never_cache
84 def dashboard(request):
85     group_routes = []
86     try:
87         peer = request.user.get_profile().peer
88     except UserProfile.DoesNotExist:
89         error = "User <strong>%s</strong> does not belong to any peer or organization. It is not possible to create new firewall rules.<br>Please contact Helpdesk to resolve this issue" % request.user.username
90         return render_to_response('error.html', {'error': error}, context_instance=RequestContext(request))
91     if peer:
92        peer_members = UserProfile.objects.filter(peer=peer)
93        users = [prof.user for prof in peer_members]
94        group_routes = Route.objects.filter(applier__in=users).order_by('-expires')[:10]
95        if request.user.is_superuser:
96            group_routes = Route.objects.all().order_by('-expires')[:10]
97        return render_to_response('dashboard.html', {'routes': group_routes},
98                               context_instance=RequestContext(request))
99
100 @login_required
101 @never_cache
102 def group_routes(request):
103     try:
104         peer = request.user.get_profile().peer
105     except UserProfile.DoesNotExist:
106         error = "User <strong>%s</strong> does not belong to any peer or organization. It is not possible to create new firewall rules.<br>Please contact Helpdesk to resolve this issue" % request.user.username
107         return render_to_response('error.html', {'error': error}, context_instance=RequestContext(request))
108     return render_to_response('user_routes.html', context_instance=RequestContext(request))
109
110 @login_required
111 @never_cache
112 def group_routes_ajax(request):
113     group_routes = []
114     try:
115         peer = request.user.get_profile().peer
116     except UserProfile.DoesNotExist:
117         error = "User <strong>%s</strong> does not belong to any peer or organization. It is not possible to create new firewall rules.<br>Please contact Helpdesk to resolve this issue" % request.user.username
118         return render_to_response('error.html', {'error': error}, context_instance=RequestContext(request))
119     if peer:
120        peer_members = UserProfile.objects.filter(peer=peer)
121        users = [prof.user for prof in peer_members]
122        group_routes = Route.objects.filter(applier__in=users)
123        if request.user.is_superuser:
124            group_routes = Route.objects.all()
125     jresp = {}
126     routes = build_routes_json(group_routes)
127     jresp['aaData'] = routes
128     return HttpResponse(json.dumps(jresp), mimetype='application/json') 
129
130 @login_required
131 @never_cache
132 def overview_routes_ajax(request):
133     group_routes = []
134     try:
135         peer = request.user.get_profile().peer
136     except UserProfile.DoesNotExist:
137         error = "User <strong>%s</strong> does not belong to any peer or organization. It is not possible to create new firewall rules.<br>Please contact Helpdesk to resolve this issue" % request.user.username
138         return render_to_response('error.html', {'error': error}, context_instance=RequestContext(request))
139     if peer:
140        peer_members = UserProfile.objects.filter(peer=peer)
141        users = [prof.user for prof in peer_members]
142        group_routes = Route.objects.filter(applier__in=users)
143        if request.user.is_superuser or request.user.has_perm('accounts.overview'):
144            group_routes = Route.objects.all()
145     jresp = {}
146     routes = build_routes_json(group_routes)
147     jresp['aaData'] = routes
148     return HttpResponse(json.dumps(jresp), mimetype='application/json') 
149
150 def build_routes_json(groutes):
151     routes = []
152     for r in groutes:
153         rd = {}
154         rd['id'] = r.pk
155         rd['name'] = r.name
156         rd['comments'] = r.comments
157         rd['match'] = r.get_match()
158         rd['then'] = r.get_then()
159         rd['status'] = r.status
160         rd['applier'] = r.applier.username
161         try:
162             rd['peer'] = r.applier.get_profile().peer.peer_name
163         except UserProfile.DoesNotExist:
164             rd['peer'] = ''
165         rd['expires'] = "%s" %r.expires
166         rd['response'] = "%s" %r.response
167         routes.append(rd)
168     return routes
169
170 @login_required
171 @never_cache
172 def add_route(request):
173     applier = request.user.pk
174     applier_peer_networks = request.user.get_profile().peer.networks.all()
175     if request.user.is_superuser:
176         applier_peer_networks = PeerRange.objects.all()
177     if not applier_peer_networks:
178          messages.add_message(request, messages.WARNING,
179                              _("Insufficient rights on administrative networks. Cannot add rule. Contact your administrator"))
180          return HttpResponseRedirect(reverse("group-routes"))
181     if request.method == "GET":
182         form = RouteForm(initial={'applier': applier})
183         if not request.user.is_superuser:
184             form.fields['then'] = forms.ModelMultipleChoiceField(queryset=ThenAction.objects.filter(action__in=settings.UI_USER_THEN_ACTIONS).order_by('action'), required=True)
185             form.fields['protocol'] = forms.ModelMultipleChoiceField(queryset=MatchProtocol.objects.filter(protocol__in=settings.UI_USER_PROTOCOLS).order_by('protocol'), required=False)
186         return render_to_response('apply.html', {'form': form, 'applier': applier},
187                                   context_instance=RequestContext(request))
188
189     else:
190         request_data = request.POST.copy()
191         if request.user.is_superuser:
192             request_data['issuperuser'] = request.user.username
193         else:
194             request_data['applier'] = applier
195             try:
196                 del requset_data['issuperuser']
197             except:
198                 pass
199         form = RouteForm(request_data)
200         if form.is_valid():
201             route=form.save(commit=False)
202             if not request.user.is_superuser:
203                 route.applier = request.user
204             route.status = "PENDING"
205             route.response = "Applying"
206             route.source = IPNetwork("%s/%s" %(IPNetwork(route.source).network.compressed, IPNetwork(route.source).prefixlen)).compressed
207             route.destination = IPNetwork("%s/%s" %(IPNetwork(route.destination).network.compressed, IPNetwork(route.destination).prefixlen)).compressed
208             route.save()
209             form.save_m2m()
210             route.commit_add()
211             requesters_address = request.META['HTTP_X_FORWARDED_FOR']
212             fqdn = Site.objects.get_current().domain
213             admin_url = "https://%s%s" % (fqdn, reverse("edit-route", kwargs={'route_slug': route.name }))
214             mail_body = render_to_string("rule_action.txt",
215                                              {"route": route, "address": requesters_address, "action": "creation", "url": admin_url})
216             user_mail = "%s" %route.applier.email
217             user_mail = user_mail.split(';')
218             send_new_mail(settings.EMAIL_SUBJECT_PREFIX + "Rule %s creation request submitted by %s" %(route.name, route.applier.username),
219                               mail_body, settings.SERVER_EMAIL, user_mail,
220                               get_peer_techc_mails(route.applier))
221             d = { 'clientip' : "%s"%requesters_address, 'user' : route.applier.username }
222             logger.info(mail_body, extra=d)
223             return HttpResponseRedirect(reverse("group-routes"))
224         else:
225             if not request.user.is_superuser:
226                 form.fields['then'] = forms.ModelMultipleChoiceField(queryset=ThenAction.objects.filter(action__in=settings.UI_USER_THEN_ACTIONS).order_by('action'), required=True)
227                 form.fields['protocol'] = forms.ModelMultipleChoiceField(queryset=MatchProtocol.objects.filter(protocol__in=settings.UI_USER_PROTOCOLS).order_by('protocol'), required=False)
228             return render_to_response('apply.html', {'form': form, 'applier':applier},
229                                       context_instance=RequestContext(request))
230
231 @login_required
232 @never_cache
233 def edit_route(request, route_slug):
234     applier = request.user.pk
235     applier_peer = request.user.get_profile().peer
236     route_edit = get_object_or_404(Route, name=route_slug)
237     route_edit_applier_peer = route_edit.applier.get_profile().peer
238     if applier_peer != route_edit_applier_peer and (not request.user.is_superuser):
239         messages.add_message(request, messages.WARNING,
240                              _("Insufficient rights to edit rule %s") %(route_slug))
241         return HttpResponseRedirect(reverse("group-routes"))
242 #    if route_edit.status == "ADMININACTIVE" :
243 #        messages.add_message(request, messages.WARNING,
244 #                             "Administrator has disabled editing of rule %s" %(route_slug))
245 #        return HttpResponseRedirect(reverse("group-routes"))
246 #    if route_edit.status == "EXPIRED" :
247 #        messages.add_message(request, messages.WARNING,
248 #                             "Cannot edit the expired rule %s. Contact helpdesk to enable it" %(route_slug))
249 #        return HttpResponseRedirect(reverse("group-routes"))
250     if route_edit.status == "PENDING" :
251         messages.add_message(request, messages.WARNING,
252                              _("Cannot edit a pending rule: %s.") %(route_slug))
253         return HttpResponseRedirect(reverse("group-routes"))
254     route_original = deepcopy(route_edit)
255     if request.POST:
256         request_data = request.POST.copy()
257         if request.user.is_superuser:
258             request_data['issuperuser'] = request.user.username
259         else:
260             request_data['applier'] = applier
261             try:
262                 del request_data['issuperuser']
263             except:
264                 pass
265         form = RouteForm(request_data, instance = route_edit)
266         critical_changed_values = ['source', 'destination', 'sourceport', 'destinationport', 'port', 'protocol', 'then', 'fragmenttype']
267         if form.is_valid():
268             changed_data = form.changed_data
269             route=form.save(commit=False)
270             route.name = route_original.name
271             route.status = route_original.status
272             route.response = route_original.response
273             if not request.user.is_superuser:
274                 route.applier = request.user
275             if bool(set(changed_data) & set(critical_changed_values)) or (not route_original.status == 'ACTIVE'):
276                 route.status = "PENDING"
277                 route.response = "Applying"
278                 route.source = IPNetwork("%s/%s" %(IPNetwork(route.source).network.compressed, IPNetwork(route.source).prefixlen)).compressed
279                 route.destination = IPNetwork("%s/%s" %(IPNetwork(route.destination).network.compressed, IPNetwork(route.destination).prefixlen)).compressed
280             route.save()
281             if bool(set(changed_data) & set(critical_changed_values)) or (not route_original.status == 'ACTIVE'):
282                 form.save_m2m()
283                 route.commit_edit()
284                 requesters_address = request.META['HTTP_X_FORWARDED_FOR']
285                 fqdn = Site.objects.get_current().domain
286                 admin_url = "https://%s%s" % (fqdn, reverse("edit-route", kwargs={'route_slug': route.name }))
287                 mail_body = render_to_string("rule_action.txt",
288                                              {"route": route, "address": requesters_address, "action": "edit", "url": admin_url})
289                 user_mail = "%s" %route.applier.email
290                 user_mail = user_mail.split(';')
291                 send_new_mail(settings.EMAIL_SUBJECT_PREFIX + "Rule %s edit request submitted by %s" %(route.name, route.applier.username),
292                               mail_body, settings.SERVER_EMAIL, user_mail,
293                               get_peer_techc_mails(route.applier))
294                 d = { 'clientip' : requesters_address, 'user' : route.applier.username }
295                 logger.info(mail_body, extra=d)
296             return HttpResponseRedirect(reverse("group-routes"))
297         else:
298             if not request.user.is_superuser:
299                 form.fields['then'] = forms.ModelMultipleChoiceField(queryset=ThenAction.objects.filter(action__in=settings.UI_USER_THEN_ACTIONS).order_by('action'), required=True)
300                 form.fields['protocol'] = forms.ModelMultipleChoiceField(queryset=MatchProtocol.objects.filter(protocol__in=settings.UI_USER_PROTOCOLS).order_by('protocol'), required=False)
301             return render_to_response('apply.html', {'form': form, 'edit':True, 'applier': applier},
302                                       context_instance=RequestContext(request))
303     else:
304         if (not route_original.status == 'ACTIVE'):
305             route_edit.expires = datetime.date.today() + datetime.timedelta(days = settings.EXPIRATION_DAYS_OFFSET)
306         dictionary = model_to_dict(route_edit, fields=[], exclude=[])
307         if request.user.is_superuser:
308             dictionary['issuperuser'] = request.user.username
309         else:
310             try:
311                 del dictionary['issuperuser']
312             except:
313                 pass
314         form = RouteForm(dictionary)
315         if not request.user.is_superuser:
316             form.fields['then'] = forms.ModelMultipleChoiceField(queryset=ThenAction.objects.filter(action__in=settings.UI_USER_THEN_ACTIONS).order_by('action'), required=True)
317             form.fields['protocol'] = forms.ModelMultipleChoiceField(queryset=MatchProtocol.objects.filter(protocol__in=settings.UI_USER_PROTOCOLS).order_by('protocol'), required=False)
318         return render_to_response('apply.html', {'form': form, 'edit':True, 'applier': applier},
319                                   context_instance=RequestContext(request))
320
321 @login_required
322 @never_cache
323 def delete_route(request, route_slug):
324     if request.is_ajax():
325         route = get_object_or_404(Route, name=route_slug)
326         applier_peer = route.applier.get_profile().peer
327         requester_peer = request.user.get_profile().peer
328         if applier_peer == requester_peer or request.user.is_superuser:
329             route.status = "PENDING"
330             route.expires = datetime.date.today()
331             if not request.user.is_superuser:
332                 route.applier = request.user
333             route.response = "Deactivating"
334             route.save()
335             route.commit_delete()
336             requesters_address = request.META['HTTP_X_FORWARDED_FOR']
337             fqdn = Site.objects.get_current().domain
338             admin_url = "https://%s%s" % (fqdn, reverse("edit-route", kwargs={'route_slug': route.name }))
339             mail_body = render_to_string("rule_action.txt",
340                                              {"route": route, "address": requesters_address, "action": "removal", "url": admin_url})
341             user_mail = "%s" %route.applier.email
342             user_mail = user_mail.split(';')
343             send_new_mail(settings.EMAIL_SUBJECT_PREFIX + "Rule %s removal request submitted by %s" %(route.name, route.applier.username), 
344                               mail_body, settings.SERVER_EMAIL, user_mail,
345                              get_peer_techc_mails(route.applier))
346             d = { 'clientip' : requesters_address, 'user' : route.applier.username }
347             logger.info(mail_body, extra=d)
348         html = "<html><body>Done</body></html>"
349         return HttpResponse(html)
350     else:
351         return HttpResponseRedirect(reverse("group-routes"))
352
353 @login_required
354 @never_cache
355 def user_profile(request):
356     user = request.user
357     try:
358         peer = request.user.get_profile().peer
359         peers = Peer.objects.filter(pk=peer.pk)
360         if user.is_superuser:
361             peers = Peer.objects.all()
362     except UserProfile.DoesNotExist:
363         error = "User <strong>%s</strong> does not belong to any peer or organization. It is not possible to create new firewall rules.<br>Please contact Helpdesk to resolve this issue" % user.username
364         return render_to_response('error.html', {'error': error}, context_instance=RequestContext(request))
365     return render_to_response('profile.html', {'user': user, 'peers':peers},
366                                   context_instance=RequestContext(request))
367
368 @never_cache
369 def user_login(request):
370     try:
371         error_username = False
372         error_orgname = False
373         error_entitlement = False
374         error_mail = False
375         has_entitlement = False
376         error = ''
377         username = lookupShibAttr(settings.SHIB_USERNAME, request.META)
378         if not username:
379             error_username = True
380         firstname = lookupShibAttr(settings.SHIB_FIRSTNAME, request.META)
381         lastname = lookupShibAttr(settings.SHIB_LASTNAME, request.META)
382         mail = lookupShibAttr(settings.SHIB_MAIL, request.META)
383         entitlement = lookupShibAttr(settings.SHIB_ENTITLEMENT, request.META)
384         #organization = request.META['HTTP_SHIB_HOMEORGANIZATION']
385         
386         if settings.SHIB_AUTH_ENTITLEMENT in entitlement.split(";"):
387             has_entitlement = True
388         if not has_entitlement:
389             error_entitlement = True
390 #        if not organization:
391 #            error_orgname = True
392         if not mail:
393             error_mail = True
394         if error_username:
395             error = _("Your idP should release the HTTP_EPPN attribute towards this service<br>")
396 #        if error_orgname:
397 #            error = error + _("Your idP should release the HTTP_SHIB_HOMEORGANIZATION attribute towards this service<br>")
398         if error_entitlement:
399             error = error + _("Your idP should release an appropriate HTTP_SHIB_EP_ENTITLEMENT attribute towards this service<br>")
400         if error_mail:
401             error = error + _("Your idP should release the HTTP_SHIB_INETORGPERSON_MAIL attribute towards this service")
402         if error_username or error_orgname or error_entitlement or error_mail:
403             return render_to_response('error.html', {'error': error, "missing_attributes": True},
404                                   context_instance=RequestContext(request))
405         try:
406             if settings.SHIB_SLUGIFY_USERNAME:
407                 username = slugify(username)
408             user = User.objects.get(username__exact=username)
409             user.email = mail
410             user.first_name = firstname
411             user.last_name = lastname
412             user.save()
413             user_exists = True
414         except:
415             user_exists = False
416         user = authenticate(username=username, firstname=firstname, lastname=lastname, mail=mail, authsource='shibboleth')
417         
418         if user is not None:
419             try:
420                 peer = user.get_profile().peer
421 #                peer = Peer.objects.get(domain_name=organization)
422 #                up = UserProfile.objects.get_or_create(user=user,peer=peer)
423             except:
424                 form = UserProfileForm()
425                 form.fields['user'] = forms.ModelChoiceField(queryset=User.objects.filter(pk=user.pk), empty_label=None)
426                 form.fields['peer'] = forms.ModelChoiceField(queryset=Peer.objects.all(), empty_label=None)
427                 return render_to_response('registration/select_institution.html', {'form': form}, context_instance=RequestContext(request))
428             if not user_exists:
429                 user_activation_notify(user)
430             if user.is_active:
431                login(request, user)
432                return HttpResponseRedirect(reverse("dashboard"))
433             else:
434                 error = _("User account <strong>%s</strong> is pending activation. Administrators have been notified and will activate this account within the next days. <br>If this account has remained inactive for a long time contact your technical coordinator or GRNET Helpdesk") %user.username
435                 return render_to_response('error.html', {'error': error, 'inactive': True},
436                                   context_instance=RequestContext(request))
437         else:
438             error = _("Something went wrong during user authentication. Contact your administrator")
439             return render_to_response('error.html', {'error': error,},
440                                   context_instance=RequestContext(request))
441     except User.DoesNotExist as e:
442         error = _("Invalid login procedure. Error: %s" %e)
443         return render_to_response('error.html', {'error': error,},
444                                   context_instance=RequestContext(request))
445         # Return an 'invalid login' error message.
446 #    return HttpResponseRedirect(reverse("user-routes"))
447
448 def user_activation_notify(user):
449     current_site = Site.objects.get_current()
450     peer = user.get_profile().peer
451     
452     
453     # Email subject *must not* contain newlines
454     # TechCs will be notified about new users.
455     # Platform admins will activate the users.
456     subject = render_to_string('registration/activation_email_subject.txt',
457                                    { 'site': current_site })
458     subject = ''.join(subject.splitlines())
459     registration_profile = RegistrationProfile.objects.create_profile(user)
460     message = render_to_string('registration/activation_email.txt',
461                                    { 'activation_key': registration_profile.activation_key,
462                                      'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS,
463                                      'site': current_site,
464                                      'user': user })
465     if settings.NOTIFY_ADMIN_MAILS:
466         admin_mails = settings.NOTIFY_ADMIN_MAILS
467         send_new_mail(settings.EMAIL_SUBJECT_PREFIX + subject, 
468                                   message, settings.SERVER_EMAIL,
469                                  admin_mails, [])
470     
471     # Mail to domain techCs plus platform admins (no activation hash sent)
472     subject = render_to_string('registration/activation_email_peer_notify_subject.txt',
473                                    { 'site': current_site,
474                                      'peer': peer })
475     subject = ''.join(subject.splitlines())
476     message = render_to_string('registration/activation_email_peer_notify.txt',
477                                    { 'user': user,
478                                     'peer': peer })
479     send_new_mail(settings.EMAIL_SUBJECT_PREFIX + subject, 
480                               message, settings.SERVER_EMAIL,
481                              get_peer_techc_mails(user), [])
482
483 @login_required
484 @never_cache
485 def add_rate_limit(request):
486     if request.method == "GET":
487         form = ThenPlainForm()
488         return render_to_response('add_rate_limit.html', {'form': form,},
489                                   context_instance=RequestContext(request))
490
491     else:
492         form = ThenPlainForm(request.POST)
493         if form.is_valid():
494             then=form.save(commit=False)
495             then.action_value = "%sk"%then.action_value
496             then.save()
497             response_data = {}
498             response_data['pk'] = "%s" %then.pk
499             response_data['value'] = "%s:%s" %(then.action, then.action_value)
500             return HttpResponse(json.dumps(response_data), mimetype='application/json')
501         else:
502             return render_to_response('add_rate_limit.html', {'form': form,},
503                                       context_instance=RequestContext(request))
504
505 @login_required
506 @never_cache
507 def add_port(request):
508     if request.method == "GET":
509         form = PortPlainForm()
510         return render_to_response('add_port.html', {'form': form,},
511                                   context_instance=RequestContext(request))
512
513     else:
514         form = PortPlainForm(request.POST)
515         if form.is_valid():
516             port=form.save()
517             response_data = {}
518             response_data['value'] = "%s" %port.pk
519             response_data['text'] = "%s" %port.port
520             return HttpResponse(json.dumps(response_data), mimetype='application/json')
521         else:
522             return render_to_response('add_port.html', {'form': form,},
523                                       context_instance=RequestContext(request))
524
525 @never_cache
526 def selectinst(request):
527     if request.method == 'POST':
528         request_data = request.POST.copy()
529         user = request_data['user']
530         try:
531             existingProfile = UserProfile.objects.get(user=user)
532             error = _("Violation warning: User account is already associated with an institution.The event has been logged and our administrators will be notified about it")
533             return render_to_response('error.html', {'error': error, 'inactive': True},
534                                   context_instance=RequestContext(request))
535         except UserProfile.DoesNotExist:
536             pass
537             
538         form = UserProfileForm(request_data)
539         if form.is_valid():
540             userprofile = form.save()
541             user_activation_notify(userprofile.user)
542             error = _("User account <strong>%s</strong> is pending activation. Administrators have been notified and will activate this account within the next days. <br>If this account has remained inactive for a long time contact your technical coordinator or GRNET Helpdesk") %userprofile.user.username
543             return render_to_response('error.html', {'error': error, 'inactive': True},
544                                   context_instance=RequestContext(request))
545         else:
546             form.fields['user'] = forms.ModelChoiceField(queryset=User.objects.filter(pk=user.pk), empty_label=None)
547             form.fields['institution'] = forms.ModelChoiceField(queryset=Peer.objects.all(), empty_label=None)
548             return render_to_response('registration/select_institution.html', {'form': form}, context_instance=RequestContext(request))
549
550 @never_cache
551 def overview(request):
552     user = request.user
553     if user.is_authenticated():
554         if user.has_perm('accounts.overview'):
555             users = User.objects.all()
556             return render_to_response('overview/index.html', {'users': users},
557                                   context_instance=RequestContext(request))
558         else:
559             violation=True
560             return render_to_response('overview/index.html', {'violation': violation},
561                                   context_instance=RequestContext(request))
562     else:
563         return HttpResponseRedirect(reverse("altlogin"))
564
565 @login_required
566 @never_cache
567 def user_logout(request):
568     logout(request)
569     return HttpResponseRedirect(reverse('group-routes'))
570     
571 @never_cache
572 def load_jscript(request, file):
573     long_polling_timeout = int(settings.POLL_SESSION_UPDATE)*1000 + 10000
574     return render_to_response('%s.js' % file, {'timeout': long_polling_timeout}, context_instance=RequestContext(request), mimetype="text/javascript")
575
576
577 def get_peer_techc_mails(user):
578     mail = []
579     additional_mail = []
580     techmails_list = []
581     user_mail = "%s" %user.email
582     user_mail = user_mail.split(';')
583     techmails = user.get_profile().peer.techc_emails.all()
584     if techmails:
585         for techmail in techmails:
586             techmails_list.append(techmail.email)
587     if settings.NOTIFY_ADMIN_MAILS:
588         additional_mail = settings.NOTIFY_ADMIN_MAILS
589     mail.extend(additional_mail)
590     mail.extend(techmails_list)
591     return mail
592
593 def send_new_mail(subject, message, from_email, recipient_list, bcc_list):
594     return EmailMessage(subject, message, from_email, recipient_list, bcc_list).send()
595
596
597 def lookupShibAttr(attrmap, requestMeta):
598     for attr in attrmap:
599         if (attr in requestMeta.keys()):
600             if len(requestMeta[attr]) > 0:
601                 return requestMeta[attr]
602     return ''