Le trigger sur événement login peut être utile pour
tracer les connexions d'utilisateur, pour vérifier la connexion et les
rôles affectés d'après les circonstances actuelles, ou pour une
initialisation des données de la session. Il est très important que tout
trigger sur événement utilisant l'événement login
vérifie si la base est en mode restauration avant de réaliser des
écritures. Écrire sur un serveur secondaire rendra impossible toute
connexion.
L'exemple suivant montre ces options.
-- créer les tables et les rôles pour ce test
CREATE TABLE user_login_log (
"user" text,
"session_start" timestamp with time zone
);
CREATE ROLE day_worker;
CREATE ROLE night_worker;
-- la fonction trigger d'exemple
CREATE OR REPLACE FUNCTION init_session()
RETURNS event_trigger SECURITY DEFINER
LANGUAGE plpgsql AS
$$
DECLARE
hour integer = EXTRACT('hour' FROM current_time at time zone 'utc');
rec boolean;
BEGIN
-- 1. Interdire les connexions entre 2 et 4 heures du matin
IF hour BETWEEN 2 AND 4 THEN
RAISE EXCEPTION 'Login forbidden';
END IF;
-- Les vérifications ci-dessous ne peuvent pas être réalisées sur des
-- secondaires, donc on s'assure que la base n'est pas en restauration
-- avant de continuer.
SELECT pg_is_in_recovery() INTO rec;
IF rec THEN
RETURN;
END IF;
-- 2. Affecte certains rôles. Le jour, on donne le rôle day_worker role,
-- et sinon le rôle night_worker.
IF hour BETWEEN 8 AND 20 THEN
EXECUTE 'REVOKE night_worker FROM ' || quote_ident(session_user);
EXECUTE 'GRANT day_worker TO ' || quote_ident(session_user);
ELSE
EXECUTE 'REVOKE day_worker FROM ' || quote_ident(session_user);
EXECUTE 'GRANT night_worker TO ' || quote_ident(session_user);
END IF;
-- 3. Initialise les données de session de l'utilisateur
CREATE TEMP TABLE session_storage (x float, y integer);
ALTER TABLE session_storage OWNER TO session_user;
-- 4. Trace le moment de la connexion
INSERT INTO public.user_login_log VALUES (session_user, current_timestamp);
END;
$$;
-- définition du trigger
CREATE EVENT TRIGGER init_session
ON login
EXECUTE FUNCTION init_session();
ALTER EVENT TRIGGER init_session ENABLE ALWAYS;