38.5. Exemplo de gatilho de evento de login no banco de dados #

O gatilho de evento no evento login pode ser útil para registrar logins de usuários, verificar a conexão e atribuir funções conforme as circunstâncias correntes, ou para inicialização de dados da sessão. É muito importante que qualquer gatilho de evento que utilize o evento login verifique se o banco de dados está no modo de recuperação antes de realizar qualquer escrita. Escrever em um servidor em espera tornará o mesmo inacessível.

O exemplo a seguir demonstra estas opções.

-- criar tabelas e funções de banco de dados (roles) de teste
CREATE TABLE user_login_log (
  "user" text,
  "session_start" timestamp with time zone
);
CREATE ROLE day_worker;
CREATE ROLE night_worker;

-- função de gatilho de exemplo
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. Proibir o login entre as 2h e as 4h da manhã.
IF hour BETWEEN 2 AND 4 THEN
  RAISE EXCEPTION 'Login proibido';
END IF;

-- As verificações abaixo não podem ser realizadas em servidores em
-- espera, portanto, certifique-se de que o banco de dados não esteja
-- em modo de recuperação antes de executar qualquer operação.
SELECT pg_is_in_recovery() INTO rec;
IF rec THEN
  RETURN;
END IF;

-- 2. Atribuir algumas funções:
-- Durante o dia, atribuir a função day_worker;
-- caso contrário, atribuir a função 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. Inicializar dados da sessão do usuário
CREATE TEMP TABLE session_storage (x float, y integer);
ALTER TABLE session_storage OWNER TO session_user;

-- 4. Registrar o tempo de conexão.
INSERT INTO public.user_login_log VALUES (session_user, current_timestamp);

END;
$$;

-- definição d0 gatilho
CREATE EVENT TRIGGER init_session
  ON login
  EXECUTE FUNCTION init_session();
ALTER EVENT TRIGGER init_session ENABLE ALWAYS;