Project

General

Profile

Revision 97f6d842

ID97f6d8420b4ce39b6617ff0d52f2a52bb0934a1a
Parent e2e218d7
Child 8c93d88b

Added by Vincent QUEMENER over 14 years ago

Ajout d'un test visant à empêcher l'utilisateur d'opérer un changement sur un évènement corrélé sans avoir pris connaissance au préalable d'éventuelles modifications intervenues depuis le chargement de la page.

git-svn-id: https://vigilo-dev.si.c-s.fr/svn@1667 b22e2e97-25c9-44ff-b637-2e5ceca36478

View differences:

vigiboard/controllers/root.py
7 7
from tw.forms import validators
8 8
from pylons.i18n import ugettext as _
9 9
from pylons.i18n import lazy_ugettext as l_
10
from tg.i18n import get_lang
11 10
from pylons.controllers.util import abort
12 11
from sqlalchemy import not_, and_, asc
13 12
from sqlalchemy.orm import aliased
13
from sqlalchemy.sql import func
14 14
from datetime import datetime
15
from time import mktime
15 16
import math
16 17
import urllib
17 18

  
......
27 28
from vigilo.models.functions import sql_escape_like
28 29
from vigilo.models.secondary_tables import HOST_GROUP_TABLE, \
29 30
                                            SERVICE_GROUP_TABLE
30
from vigilo.common.conf import settings
31 31
from vigiboard.lib.base import BaseController
32 32

  
33
__all__ = ('RootController', )
33
__all__ = ('RootController', 'get_last_modification_timestamp', 
34
           'date_to_timestamp')
34 35

  
35 36
class RootController(VigiboardRootController):
36 37
    """
......
84 85

  
85 86
        username = request.environ['repoze.who.identity']['repoze.who.userid']
86 87
        user = User.by_user_name(username)
87

  
88
        # TODO: Utiliser le champ "language" du modèle pour cet utilisateur ?
89
        # On récupère la langue du navigateur de l'utilisateur
90
        lang = get_lang()
91
        if not lang:
92
            lang = settings['VIGILO_ALL_DEFAULT_LANGUAGE']
93
        else:
94
            lang = lang[0]
95 88
        
96
        aggregates = VigiboardRequest(user, lang)
89
        aggregates = VigiboardRequest(user)
97 90
        
98 91
        search = {
99 92
            'host': '',
......
408 401
        Cela peut être un changement de ticket ou un changement de statut.
409 402
        
410 403
        @param krgv['id']: Le ou les identifiants des événements à traiter
404
        @param krgv['last_modification']: La date de la dernière modification
405
        dont l'utilisateur est au courant.
411 406
        @param krgv['tt']: Nouveau numéro du ticket associé.
412 407
        @param krgv['status']: Nouveau status de/des événements.
413 408
        """
414
        
415
        # Si l'utilisateur édite plusieurs événements à la fois,
416
        # il nous faut chacun des identifiants
417 409

  
410
        # On vérifie que des identifiants ont bien été transmis via
411
        # le formulaire, et on informe l'utilisateur le cas échéant.
418 412
        if krgv['id'] is None:
419 413
            flash(_('No event has been selected'), 'warning')
420 414
            raise redirect(request.environ.get('HTTP_REFERER', url('/')))
421

  
422 415
        ids = krgv['id'].split(',')
416
        
417
        # Si des changements sont survenus depuis que la 
418
        # page est affichée, on en informe l'utilisateur.
419
        if datetime.fromtimestamp(float(krgv['last_modification'])) \
420
                                        < get_last_modification_timestamp(ids):
421
            flash(_('Changes have occurred since the page was displayed, '
422
                    'please refresh it.'), 'warning')
423
            print "\n\n\n\n ##### ", datetime.fromtimestamp(float(krgv['last_modification'])), " #####"
424
            print "##### ", get_last_modification_timestamp(ids), "\n\n\n\n"
425
            raise redirect(request.environ.get('HTTP_REFERER', url('/')))
426

  
427
        # Si l'utilisateur édite plusieurs événements à la fois,
428
        # il nous faut chacun des identifiants
423 429
       
424 430
        if len(ids) > 1 :
425 431
            ids = ids[:-1]
......
435 441
        
436 442
        # Modification des événements et création d'un historique
437 443
        # pour chacun d'eux.
438
        username = request.environ['repoze.who.identity']['repoze.who.userid']
439

  
440 444
        for req in events.req:
441 445
            if isinstance(req, CorrEvent):
442 446
                event = req
......
457 461
                DBSession.add(history)   
458 462
                event.trouble_ticket = krgv['trouble_ticket']
459 463

  
460
            if krgv['status'] != 'NoChange' :
464
            if krgv['ack'] != 'NoChange' :
461 465
                history = EventHistory(
462 466
                        type_action="Acknowlegement change state",
463 467
                        idevent=event.idcause,
464
                        value=krgv['status'],
468
                        value=krgv['ack'],
465 469
                        text=_("Changed acknowledgement status from '%s' to '%s'") % (
466
                            event.status, krgv['status']
470
                            event.status, krgv['ack']
467 471
                        ),
468 472
                        username=username,
469 473
                        timestamp=datetime.now(),
470 474
                    )
471 475
                DBSession.add(history)
472
                event.status = krgv['status']
476
                event.status = krgv['ack']
473 477

  
474 478
        DBSession.flush()
475 479
        flash(_('Updated successfully'))
......
528 532
        session['theme'] = theme
529 533
        session.save()
530 534
        return dict()
531

  
535
    
536
def get_last_modification_timestamp(event_id_list):
537
    """
538
    Récupère le timestamp de la dernière modification 
539
    opérée sur l'un des événements dont l'identifiant
540
    fait partie de la liste passée en paramètre.
541
    """
542
    last_modification_timestamp = DBSession.query(
543
                                func.max(EventHistory.timestamp),
544
                         ).filter(EventHistory.idevent.in_(event_id_list)
545
                         ).scalar()
546
    
547
    return last_modification_timestamp
548
    
549
def date_to_timestamp(date):
550
    """
551
    Convertit une date en timestamp (décimal)
552
    """
553
    return mktime(date.timetuple()) + date.microsecond / 1000000.0
vigiboard/controllers/vigiboardrequest.py
15 15
from vigiboard.widgets.edit_event import EditEventForm
16 16
from vigiboard.widgets.search_form import SearchForm
17 17
from vigiboard.controllers.vigiboard_plugin import VigiboardRequestPlugin
18
from vigilo.common.conf import settings
19
from tg.i18n import get_lang
18 20
from pylons.i18n import ugettext as _
19 21

  
20 22
class VigiboardRequest():
......
29 31
        'AAClosed': '_Ack',
30 32
    }
31 33

  
32
    def __init__(self, user, lang):
34
    def __init__(self, user):
33 35
        """
34 36
        Initialisation de toutes les variables nécessaires :
35 37
        - la liste des groupes de l'utilisateur,
......
38 40
        - la liste des plugins à appliquer.
39 41
        """
40 42

  
43
        # TODO: Utiliser le champ "language" du modèle pour cet utilisateur ?
44
        # On récupère la langue du navigateur de l'utilisateur
45
        lang = get_lang()
46
        if not lang:
47
            lang = settings['VIGILO_ALL_DEFAULT_LANGUAGE']
48
        else:
49
            lang = lang[0]
50

  
41 51
        self.user_groups = user.groups
42 52
        self.lang = lang
43 53
        self.generaterq = False
......
443 453
        formulaires nécessaire au fonctionnement de Vigiboard
444 454
        """
445 455

  
456
        from vigiboard.controllers.root import get_last_modification_timestamp
457
        from vigiboard.controllers.root import date_to_timestamp
458
        
446 459
        # Dialogue d'édition
447 460
        tmpl_context.edit_event_form = EditEventForm('edit_event_form',
448
                action=url('/update'))
461
            last_modification=date_to_timestamp(
462
                            get_last_modification_timestamp(self.idevents)),
463
            action=url('/update'), 
464
            )
449 465
    
450 466
        # Dialogue de recherche
451 467
        tmpl_context.search_form = SearchForm('search_form', lang=self.lang,
vigiboard/widgets/edit_event.py
3 3
"""Le formulaire d'édition d'un événement."""
4 4

  
5 5
from pylons.i18n import lazy_ugettext as l_
6
from tw.forms import TableForm, SingleSelectField, TextField, HiddenField
6
from tw.forms import TableForm, SingleSelectField, TextField, \
7
                        HiddenField, SubmitButton
7 8
from tw.api import WidgetsList
8 9

  
9 10
__all__ = ('EditEventForm', 'edit_event_status_options')
......
22 23
    Affiche une zone de texte pour le Trouble Ticket et une
23 24
    liste déroulante pour le nouveau status
24 25
    """
25
    class fields(WidgetsList):
26
        id = HiddenField()
27
        trouble_ticket = TextField(label_text=l_('Trouble Ticket'))
28
        ack = SingleSelectField(label_text=l_('Status'),
29
                    options=edit_event_status_options)
26
    
27
#    class fields(WidgetsList):
28
#        id = HiddenField()
29
#        trouble_ticket = TextField(label_text=l_('Trouble Ticket'))
30
#        ack = SingleSelectField(label_text=l_('Status'),
31
#                    options=edit_event_status_options)
32
#
33
#    submit_text = l_('Apply')
30 34

  
31
    submit_text = l_('Apply')
35
    submit_text = None
36
    fields = [
37
        HiddenField('id'),
38
        TextField('trouble_ticket', label_text=l_('Trouble Ticket')),
39
        SingleSelectField('ack', label_text=l_('Status'), 
40
                                            options=edit_event_status_options)
41
    ]
42
    
43
    def __init__(self, id, last_modification, *args, **kwargs):
44
        super(TableForm, self).__init__(id, *args, **kwargs)
45

  
46
        self.children.append(HiddenField('last_modification',
47
                                         attrs={'value':last_modification}))
48
        self.children.append(SubmitButton('submit', 
49
                                          attrs={'value':l_('Apply')}))
32 50

  
vigiboard/widgets/search_form.py
36 36

  
37 37
        self.children.append(CalendarDateTimePicker(id + '_from_date', 
38 38
                                name = 'from_date',
39
                                label_text = l_('From:'),
39
                                label_text = l_('From'),
40 40
                                button_text = l_("Choose"),
41 41
                                date_format = date_format, 
42 42
                                not_empty = False,
......
44 44
        
45 45
        self.children.append(CalendarDateTimePicker(id + '_to_date',
46 46
                                name = 'to_date',
47
                                label_text = l_('To:'),
47
                                label_text = l_('To'),
48 48
                                button_text = l_("Choose"),
49 49
                                date_format = date_format, 
50 50
                                not_empty = False,
51 51
                                calendar_lang=lang))
52 52

  
53
        self.children.append(SubmitButton('search', value=l_('Search')))
53
        self.children.append(SubmitButton('search',
54
                                          attrs={'value':l_('Search')}))
54 55

  

Also available in: Unified diff