views.py 9.32 KB
Newer Older
1 2 3 4
# -*- coding: utf-8 -*-

import datetime
import json
5

6
from django.utils import timezone
7 8 9
from django.shortcuts import render
from django.shortcuts import get_object_or_404
from django.views.decorators.csrf import csrf_exempt
10
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden
11
from django.contrib.auth.decorators import login_required
12
from django.utils.translation import ugettext_lazy as _
13
from django.contrib import messages
14

15
from models import ConfirmAction
16
from forms import DemenagementForm
17
from forms import SearchForm
18

19
import lc_ldap.shortcuts
20
from lc_ldap.attributs import UniquenessError
21
from gestion import secrets_new as secrets
22 23
import gestion.mail as mail_module

24 25
use_ldap_admin = lc_ldap.shortcuts.with_ldap_conn(retries=2, delay=5,
    constructor=lc_ldap.shortcuts.lc_ldap_admin)
26

27
RESPBATS = 'respbats@crans.org'
28 29 30 31 32 33 34 35 36 37

@use_ldap_admin
def upload(request, pk, secret, ldap):
    """
    Validation d'une déconnexion. Reprogramme la fin d'une déconnexion
    pour dans 24h.
    """
    task = get_object_or_404(ConfirmAction, pk=pk, view_name='upload',
        secret=secret)
    data = json.loads(task.data)
38

39 40 41 42 43 44
    with ldap.search(data['dn'], mode='rw')[0] as adh:
        bl = adh['blacklist'][data['blid']].value
        if bl['fin'] == '-' and 'confirm' in request.POST:
            bl['fin'] = bl['debut'] + 24*60*60
            adh.history_add(u'validate', u'blacklist_upload (fin)')
            adh.save()
45
            task.triggered = timezone.now()
46 47 48
            task.save()
        if bl['fin'] != '-':
            fin = datetime.datetime.fromtimestamp(bl['fin'])
49
            return render(request, 'validation/upload_done.html',
50 51 52 53
                {'fin': fin})
        else:
            return render(request, 'validation/upload.html')

54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
@use_ldap_admin
@csrf_exempt
def demenagement(request, pk, secret, ldap):
    """
    Validation d'un déménagement. Propose les alternatives suivantes:
    - Conservation de l'accès Internet (avec nouvelle chambre ou EXT)
    - Suppression de l'accès Internet
    """

    task = get_object_or_404(ConfirmAction, pk=pk, view_name='demenagement',
        secret=secret)
    data = json.loads(task.data)

    f = DemenagementForm(label_suffix="")
    chbre = data['chbre']

    if isinstance(task.triggered, datetime.datetime) \
71
    and task.triggered < timezone.now():
72 73 74
        # L'url a déjà été triggered, on empêche un nouvel accès, mais on
        # remercie d'être passé
        return render(request, 'validation/demenagement_succes.html')
75 76 77 78 79 80 81 82 83 84 85

    if request.method == 'POST':
        # On traite un formulaire de déménagement
        f = DemenagementForm(request.POST, label_suffix="")

        if f.is_valid():
            keep_connection = f.cleaned_data['keep_connection']
            status = f.cleaned_data['status']
            new_chbre = f.cleaned_data['new_chbre']
            adresse_rue = f.cleaned_data['adresse_rue']
            adresse_code = f.cleaned_data['adresse_code']
86
            adresse_code = unicode('%05d' % adresse_code)
87 88
            adresse_ville = f.cleaned_data['adresse_ville']

89 90 91 92
            if keep_connection and status != 'is_crous_cachan':
                adresse_complete = [adresse_rue, adresse_code, adresse_ville, ]
            else:
                adresse_complete = []
93 94 95 96 97 98 99 100 101

            with ldap.search(data['dn'], mode='rw')[0] as adh:
                if not keep_connection:
                    # L'adhérent ne souhaite plus garder sa connexion
                    # On supprime ses machines

                    for machine in adh.machines():
                        machine.delete()

102 103 104
                try:
                    adh['postalAddress'] = adresse_complete
                except ValueError:
105
                    messages.error(request, _(u"Cette adresse est invalide") )
106 107 108 109
                    return render(request, 'validation/demenagement.html', {
                      'chbre' : chbre,
                      'form' : f,
                    })
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
                try:
                    # On modifie la chambre de l'adhérent
                    adh['chbre'] = new_chbre

                except UniquenessError as e:
                    # 1er cas : La chambre est occupée

                    with mail_module.ServerConnection() as smtp:
                        smtp.send_template('demenagement_erreur', {
                            'from': RESPBATS,
                            'to': RESPBATS,
                            'adh': adh,
                            'aid': adh['aid'][0].value,
                            'chbre': chbre,
                            'new_chbre': new_chbre,
                            'type_erreur' : 'UniquenessError',
                            'erreur' : e,
                        })

                    return render(request, 'validation/demenagement_succes.html', {
                        'keep' : keep_connection,
                        'new_chbre' : new_chbre,
                        'ask_respbats' : True,
                        'adresse' : adresse_complete,
                        'why' : 'occupee',
                    })

                except ValueError as e:
                    # 2ème cas : La chambre est invalide

                    # On ajoute une erreur au formulaire et on le renvoie
141 142 143
                    f.add_error('new_chbre', _(u"La chambre %(chbre)s est invalide.") %
                        {'chbre': new_chbre}
                    )
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176

                    return render(request, 'validation/demenagement.html', {
                        'chbre' : chbre,
                        'form' : f,
                    })

                except Exception as e:
                    # 3ème cas : Erreur inconnue

                    with mail_module.ServerConnection() as smtp:
                        smtp.send_template('demenagement_erreur', {
                            'from': RESPBATS,
                            'to': RESPBATS,
                            'adh': adh,
                            'aid': adh['aid'][0].value,
                            'chbre': chbre,
                            'new_chbre': new_chbre,
                            'type_erreur': 'Exception',
                            'erreur': e,
                        })

                    return render(request, 'validation/demenagement_succes.html', {
                        'keep' : keep_connection,
                        'new_chbre' : new_chbre,
                        'ask_respbats' : True,
                        'adresse' : adresse_complete,
                        'why' : 'inconnu',
                    })

                # On oublie pas de sauvegarder les modifications
                adh.history_gen(login=u'validate')
                adh.save()

177
            task.triggered = timezone.now()
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
            task.save()
            return render(request,'validation/demenagement_succes.html', {
                'keep' : keep_connection,
                'ask_respbats' : False,
                'new_chbre' : new_chbre,
                'adresse' : adresse_complete,
            })

        else:
            return render(request, 'validation/demenagement.html', {
                 'form' : f,
                 'chbre' : chbre,
            })

    else:
        # On envoie un formulaire de déménagement
        return render(request, 'validation/demenagement.html', {
              'form' : f,
              'chbre' : chbre,
        })

199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
@csrf_exempt
def register(request, view_name):
    """Enregistre une action à effectuer. Les données d'exécution sont dans
    request.POST['data'].
    Pour être sûr que l'appelant avait le droit de faire cet appel, on vérifie
    le secret partagé dans request.POST['shared_secret'].
    Affiche en réponse une url de callback"""
    if request.POST.get('shared_secret', '') != secrets.get('validation'):
        return HttpResponseForbidden()
    task = ConfirmAction()
    task.data = request.POST.get('data', '')
    task.view_name = view_name
    task.save()
    return HttpResponse(task.get_absolute_url(), content_type="text/plain")

214 215 216 217
@login_required
@use_ldap_admin
def afficher(request, ldap):
    """ Affiche les liens upload pour les cableurs  """
218
    if not request.user.has_perm('auth.crans_cableur'):
219 220
        messages.error(request, _(u"Accès interdit, droits insuffisants") )
        return HttpResponseRedirect("/") # TODO vraie url propre
221 222 223 224 225 226 227 228 229 230 231 232
    if request.method == "POST":
        form = SearchForm(request.POST)
        if form.is_valid():
            links = []
            adh = None
            if 'login' in form.changed_data:
                adh = ldap.search(u'uid=%s' % form.cleaned_data['login'])
            if 'chambre' in form.changed_data:
                adh = ldap.search(u'chbre=%s' % form.cleaned_data['chambre'])
            if adh:
                adh = adh[0]
                aid = adh['aid'][0]
233
                links = ConfirmAction.objects.filter(data__contains='"aid=%s"' % aid)
234 235
            elif 'aid' in form.changed_data:
                aid = form.cleaned_data['aid']
236
                links = ConfirmAction.objects.filter(data__contains='"aid=%s"' % aid)
237 238 239 240
            return render(request, "validation/affichage.html", {
                'form': form,
                'links': links,
            })
241 242 243 244
        else:
           return render(request, "validation/affichage.html", {
                'form': form,
            })
245 246 247 248 249
    else:
        form = SearchForm()
        context = {'form': form}
        return render(request, "validation/affichage.html", context)