def populate_DB(): """ Peuple la base de données. """ # On ajoute un groupe d'hôtes et un groupe de services. supitemmanagers = SupItemGroup(name=u'managersgroup', parent=None) DBSession.add(supitemmanagers) DBSession.flush() usergroup = UserGroup.by_group_name(u'users_with_access') DBSession.add(DataPermission( group=supitemmanagers, usergroup=usergroup, access=u'r', )) DBSession.flush() # On crée un hôte de test, et on l'ajoute au groupe d'hôtes. managerhost = functions.add_host(u'managerhost') supitemmanagers.supitems.append(managerhost) DBSession.flush() # On crée un services de bas niveau, et on l'ajoute au groupe de services. managerservice = functions.add_lowlevelservice( managerhost, u'managerservice') supitemmanagers.supitems.append(managerservice) DBSession.flush() return (managerhost, managerservice)
def test_search_service_when_allowed_by_service(self): """ Teste la recherche par service avec des droits explicites (droits accordés car l'utilisateur a explicitement les droits sur ce service). """ # On crée un service avec une alerte. # Le service est rattaché à un groupe de services # pour lesquel l'utilisateur a les permissions. servicegroup = insert_deps()[1] usergroup = UserGroup.by_group_name(u'users') DBSession.add(DataPermission( group=servicegroup, usergroup=usergroup, access=u'r', )) DBSession.flush() transaction.commit() # On envoie une requête avec recherche sur le service créé, # on s'attend à recevoir 1 résultat. response = self.app.get('/?service=baz', extra_environ={'REMOTE_USER': '******'}) # Il doit y avoir 1 seule ligne de résultats. rows = response.lxml.xpath('//table[@class="vigitable"]/tbody/tr') print "There are %d rows in the result set" % len(rows) assert_equal(len(rows), 1) # Il doit y avoir plusieurs colonnes dans la ligne de résultats. cols = response.lxml.xpath('//table[@class="vigitable"]/tbody/tr/td') print "There are %d columns in the result set" % len(cols) assert_true(len(cols) > 1)
def populate_DB(): """ Peuple la base de données. """ # On ajoute un groupe d'hôtes et un groupe de services. supitemmanagers = functions.add_supitemgroup(u'managersgroup') usergroup = UserGroup.by_group_name(u'users_with_access') DBSession.add(DataPermission( group=supitemmanagers, usergroup=usergroup, access=u'w', )) DBSession.flush() # On crée un 2 hôtes, et on les ajoute au groupe d'hôtes. host1 = functions.add_host(u'host1') host2 = functions.add_host(u'host2') supitemmanagers.supitems.append(host1) supitemmanagers.supitems.append(host2) DBSession.flush() # On crée 2 services de bas niveau, et on les ajoute au groupe de services. service1 = functions.add_lowlevelservice(host1, u'service1') service2 = functions.add_lowlevelservice(host2, u'service2') supitemmanagers.supitems.append(service1) supitemmanagers.supitems.append(service2) DBSession.flush() return ([host1, host2], [service1, service2])
def insert_deps(): """Insère les dépendances nécessaires aux tests.""" timestamp = datetime.now() host = Host( name=u'bar', description=u'', hosttpl=u'', address=u'127.0.0.1', snmpport=42, snmpcommunity=u'public', snmpversion=u'3', weight=42, ) DBSession.add(host) DBSession.flush() hostgroup = SupItemGroup(name=u'foo', parent=None) hostgroup.supitems.append(host) DBSession.add(hostgroup) DBSession.flush() event = Event( supitem=host, timestamp=timestamp, current_state=StateName.statename_to_value(u'WARNING'), message=u'Hello world', ) DBSession.add(event) DBSession.flush() correvent = CorrEvent( priority=42, trouble_ticket=u'FOO BAR BAZ éçà', ack=CorrEvent.ACK_NONE, occurrence=42, timestamp_active=timestamp, cause=event, ) correvent.events.append(event) DBSession.add(correvent) DBSession.flush() # On donne l'accès aux données. usergroup = UserGroup.by_group_name(u'users') DBSession.add(DataPermission( group=hostgroup, usergroup=usergroup, access=u'r', )) DBSession.flush() return timestamp
def insert_deps(return_service): """ Insère les dépendances nécessaires aux tests. @param return_service: Indique si les événements générés concernent un hôte (False) ou un service de bas niveau (True). @type return_service: C{bool} @return: Renvoie un tuple avec le groupe d'hôte créé, l'identifiant du L{CorrEvent} généré et enfin, l'identifiant de l'L{Event} généré. @rtype: C{tuple} """ timestamp = datetime.now() hostgroup = functions.add_supitemgroup(u'foo') host = functions.add_host(u'bar') hostgroup.supitems.append(host) DBSession.flush() servicegroup = functions.add_supitemgroup(u'bar') service = functions.add_lowlevelservice(host, u'baz') servicegroup.supitems.append(service) DBSession.flush() if return_service: event = functions.add_event(service, u'WARNING', u'', timestamp) else: event = functions.add_event(host, u'WARNING', u'', timestamp) correvent = functions.add_correvent([event], timestamp=timestamp) usergroup = UserGroup.by_group_name(u'users_with_access') DBSession.add(DataPermission( usergroup=usergroup, group=hostgroup, access=u'r', )) DBSession.flush() transaction.commit() correvent = DBSession.query(CorrEvent).first() event = DBSession.query(Event).first() return (correvent.idcorrevent, event.idevent)
def add_metadata(self, environ, identity): """ Cette méthode n'ajoute pas de méta-données à proprement parler. À la place, elle crée un utilisateur dans la base de données si nécessaire, correspondant au contenu de la variable CGI C{REMOTE_USER} transmise par Apache. Dans le cas d'un identifiant Kerberos ("uid@REALM"), seule la partie "uid" est utilisée pour créer le compte. Pour cela, cette méthode effectue une requête à un annuaire LDAP. Elle génère en outre des groupes d'utilisateurs dans Vigilo correspondant aux groupes de l'utilisateur dans LDAP. Ces informations sont synchronisées à chaque requête HTTP ou bien une seule fois par session si un cache est utilisé (pour plus d'information, voir le paramètre C{cache_name} de L{VigiloLdapSync.__init__}). @param environ: Environnement de la requête HTTP en cours de traitement. @type environ: C{dict} @param identity: Identité de l'utilisateur qui tente d'accéder à l'application. @type identity: C{dict} """ remote_user_key = environ.get('repoze.who.remote_user_key') if not remote_user_key: return remote_user = environ.get(remote_user_key) if not remote_user: return remote_user = remote_user.decode(self.http_charset) logger = environ.get('repoze.who.logger') logger and logger.info(_('Remote user: %s'), remote_user) # Une identité Kerberos correspond à un "principal" # de la forme "uid@realm". On ne garde que l'uid. if '@' in remote_user: remote_user = remote_user.split('@', 1)[0] # On corrige l'identité trouvée par repoze.who afin que # les autres mdproviders puissent trouver une correspondance # dans la base de données. identity['repoze.who.userid'] = remote_user remote_user = unicode(remote_user) user = User.by_user_name(remote_user) if self.cache_name is not None: if 'beaker.session' not in environ: logger and logger.warning( _('Beaker must be present in the WSGI middleware ' 'stack for the cache to work')) # L'identité dans le cache doit être la même que celle # pour laquelle on est en train de s'authentifier. elif self.cache_name in environ['beaker.session'] and \ environ['beaker.session'][self.cache_name] == remote_user: return # On récupère les informations concernant l'utilisateur # pour alimenter / mettre à jour notre base de données. try: (user_fullname, user_email, user_groups) = \ self.retrieve_user_ldap_info(environ, remote_user) except: logger and logger.exception(_( 'Exception while contacting LDAP server')) return None if user_fullname is None: user_fullname = remote_user if user_groups is None: user_groups = [] # Création de l'utilisateur si nécessaire. if user is None: user = User( user_name=remote_user, fullname=user_fullname, email=user_email ) try: DBSession.add(user) DBSession.flush() logger and logger.info(_('New user created: %s'), remote_user) except SQLAlchemyError: transaction.abort() logger and logger.exception( _('Exception during user creation')) return None current_user_groups = user.usergroups # Suppression des groupes présents qui ne devraient plus l'être. for group in current_user_groups: if not group.group_name in user_groups: logger and logger.info( _('Removing user "%(user)s" from group "%(group)s"'), { 'user': remote_user, 'group': group.group_name, }) user.usergroups.remove(group) # Ajout des groupes manquants. for group_name in user_groups: try: # Cet appel provoque un flush implicite à la 2ème # itération, d'où le bloc try...except (cf. #909). group = UserGroup.by_group_name(group_name) except SQLAlchemyError: # Si une erreur s'est produite, on effectue un ROLLBACK # pour éviter de bloquer le thread avec l'erreur, mais # on continue tout de même car l'utilisateur a bien été # reconnu. transaction.abort() if 'beaker.session' in environ and self.cache_name is not None: environ['beaker.session'][self.cache_name] = remote_user environ['beaker.session'].save() return # Création des groupes au besoin. if group is None: logger and logger.info( _('Creating group "%s"'), group_name) group = UserGroup(group_name=group_name) DBSession.add(group) elif group in current_user_groups: continue logger and logger.info( _('Adding user "%(user)s" to group "%(group)s"'), { 'user': remote_user, 'group': group_name, }) user.usergroups.append(group) try: DBSession.flush() # Nécessaire afin que les modifications soient sauvegardées # en base de données. Sans cela, le groupe serait supprimé # automatiquement (via un ROLLBACK) en cas d'erreur issue # de l'application (status HTTP != 200). transaction.commit() transaction.begin() except SQLAlchemyError: transaction.abort() logger and logger.exception(_( 'Exception during groups creation')) return None if 'beaker.session' in environ and self.cache_name is not None: environ['beaker.session'][self.cache_name] = remote_user environ['beaker.session'].save() return