Ejemplo n.º 1
0
    def test_get_supitemgroups(self):
        """Récupération des groupes d'éléments supervisés accessibles."""
        user = User(user_name=u'manager', email=u'', fullname=u'')
        DBSession.flush()

        usergroup = UserGroup(group_name=u'managers')
        usergroup.users.append(user)
        DBSession.flush()

        root = SupItemGroup(name=u'root', parent=None)
        DBSession.add(root)
        sub1 = SupItemGroup(name=u'sub1', parent=root)
        DBSession.add(sub1)
        sub2 = SupItemGroup(name=u'sub2', parent=root)
        DBSession.add(sub2)
        sub21 = SupItemGroup(name=u'sub21', parent=sub2)
        DBSession.add(sub21)
        DBSession.flush()

        dataperm = DataPermission(
            usergroup=usergroup,
            group=sub2,
            access=u'r',
        )
        DBSession.add(dataperm)
        DBSession.flush()

        eq_([
                (root.idgroup, False),
                (sub2.idgroup, True),
                (sub21.idgroup, True),
            ], user.supitemgroups())
Ejemplo n.º 2
0
def get_current_user():
    """
    Renvoie l'instance de l'utilisateur actuellement connecté.

    @return: Instance correspondant à l'utilisateur actuellement connecté
        ou None s'il n'est pas identifié.
    @rtype: L{User} ou None
    """

    # Le plugin de méta-données SQLAlchemy (repoze.who.plugins.sa)
    # stocke directement l'instance de l'utilisateur dans l'identité.
    # Ce bout de code permet d'éviter une requête SQL supplémentaire.
    identity = request.environ.get('repoze.who.identity')
    if identity:
        user = identity.get('user')
        if user:
            return user

    # Pour les autres plugins.
    if request.identity is None:
        return None
    userid = request.identity.get('repoze.who.userid', None)
    if userid is None:
        return None
    return User.by_user_name(userid)
Ejemplo n.º 3
0
    def test_mapgroups(self):
        """Récupération des groupes de cartes accessibles"""
        user = User(user_name=u'manager', email=u'', fullname=u'')
        DBSession.flush()

        usergroup = UserGroup(group_name=u'managers')
        usergroup.users.append(user)
        DBSession.flush()

        g1 = MapGroup(name=u'groupe 1', parent=None)
        DBSession.add(g1)
        g11 = MapGroup(name=u'groupe 1.1', parent=g1)
        DBSession.add(g11)
        g111 = MapGroup(name=u'groupe 1.1.1', parent=g11)
        DBSession.add(g111)
        g1111 = MapGroup(name=u'groupe 1.1.1.1', parent=g111)
        DBSession.add(g1111)
        DBSession.flush()

        perm = Permission(permission_name=u'manage')
        DBSession.add(perm)
        perm.usergroups.append(usergroup)
        DBSession.flush()

        dataperm = DataPermission(
            idusergroup=usergroup.idgroup,
            idgroup=g111.idgroup,
            access=u'r',
        )
        DBSession.add(dataperm)
        DBSession.flush()

        # g1111 est considéré comme un groupe direct par mapgroups()
        # car l'accès est autorisé récursivement.
        expected = sorted([
            g1.idgroup,
            g11.idgroup,
            g111.idgroup,
            g1111.idgroup,
        ])
        received = sorted(user.mapgroups(True))
        eq_(expected, received)

        expected = sorted([g111, g1111])
        received = sorted(user.mapgroups(False, True))
        eq_(expected, received)
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
 def test_getting_by_user_name(self):
     """Users should be fetcheable by their username"""
     him = User.by_user_name(u"foobar")
     eq_(him, self.obj)
Ejemplo n.º 6
0
 def test_getting_by_email(self):
     """Users should be fetcheable by their email"""
     him = User.by_email_address(u"*****@*****.**")
     eq_(him, self.obj)