38.6. ÐÑÐ¸Ð¼ÐµÑ ÑобÑÑийного ÑÑиггеÑа, обÑабаÑÑваÑÑего Ð²Ñ Ð¾Ð´ в Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ #
ТÑÐ¸Ð³Ð³ÐµÑ ÑобÑÑÐ¸Ñ login Ð¼Ð¾Ð¶ÐµÑ Ð¸ÑполÑзоваÑÑÑÑ Ð´Ð»Ñ ÑегиÑÑÑаÑии вÑ
ода полÑзоваÑелей в ÑиÑÑемÑ, Ð´Ð»Ñ Ð¿ÑовеÑки подклÑÑÐµÐ½Ð¸Ñ Ð¸ назнаÑÐµÐ½Ð¸Ñ Ñолей в завиÑимоÑÑи Ð¾Ñ Ð¾Ð±ÑÑоÑÑелÑÑÑв или Ð´Ð»Ñ Ð¸Ð½Ð¸ÑиализаÑии даннÑÑ
ÑеанÑа. ÐÑÐµÐ½Ñ Ð²Ð°Ð¶Ð½Ð¾, ÑÑÐ¾Ð±Ñ Ð»Ñбой ÑобÑÑийнÑй ÑÑиггеÑ, иÑполÑзÑÑÑий ÑобÑÑие login, пÑовеÑÑл, не наÑ
одиÑÑÑ Ð»Ð¸ база даннÑÑ
в ÑоÑÑоÑнии воÑÑÑÐ°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿ÐµÑед вÑполнением какиÑ
-либо опеÑаÑий запиÑи. ÐопÑÑка вÑполниÑÑ Ð·Ð°Ð¿Ð¸ÑÑ Ð½Ð° ÑезеÑвном ÑеÑвеÑе вÑÐ·Ð¾Ð²ÐµÑ Ð¾ÑибкÑ, ÑÑо не Ð¿Ð¾Ð·Ð²Ð¾Ð»Ð¸Ñ Ð¿Ð¾Ð´ÐºÐ»ÑÑиÑÑÑÑ Ðº немÑ.
СледÑÑÑий пÑÐ¸Ð¼ÐµÑ Ð´ÐµÐ¼Ð¾Ð½ÑÑÑиÑÑÐµÑ ÑÑи возможноÑÑи.
-- Ñоздание ÑеÑÑовÑÑ
ÑÐ°Ð±Ð»Ð¸Ñ Ð¸ Ñолей
CREATE TABLE user_login_log (
"user" text,
"session_start" timestamp with time zone
);
CREATE ROLE day_worker;
CREATE ROLE night_worker;
-- пÑÐ¸Ð¼ÐµÑ ÑÑиггеÑной ÑÑнкÑии
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. ÐапÑÐµÑ Ð½Ð° вÑ
од Ñ 2 до 4 ÑаÑов ноÑи
IF hour BETWEEN 2 AND 4 THEN
RAISE EXCEPTION 'Login forbidden';
END IF;
-- СледÑÑÑие пÑовеÑки могÑÑ Ð½Ðµ вÑполнÑÑÑÑÑ Ð½Ð° ÑезеÑвнÑÑ
ÑеÑвеÑаÑ
, поÑÑомÑ
-- до вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÐºÐ°ÐºÐ¸Ñ
-либо дейÑÑвий нÑжно пÑовеÑиÑÑ, не наÑ
одиÑÑÑ Ð»Ð¸
-- база даннÑÑ
в Ñежиме воÑÑÑановлениÑ.
SELECT pg_is_in_recovery() INTO rec;
IF rec THEN
RETURN;
END IF
-- 2. ÐазнаÑение Ñолей. Рдневное вÑÐµÐ¼Ñ Ð½Ð°Ð·Ð½Ð°ÑаеÑÑÑ ÑÐ¾Ð»Ñ day_worker,
-- в ноÑное â 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. ÐниÑиализаÑÐ¸Ñ Ð´Ð°Ð½Ð½ÑÑ
ÑеанÑа полÑзоваÑелÑ
CREATE TEMP TABLE session_storage (x float, y integer);
ALTER TABLE session_storage OWNER TO session_user;
-- 4. ÐÑоÑоколиÑование вÑемени ÑоединениÑ
INSERT INTO user_login_log VALUES (session_user, current_timestamp);
END;
$$;
-- опÑеделение ÑÑиггеÑа
CREATE EVENT TRIGGER init_session
ON login
EXECUTE FUNCTION init_session();
ALTER EVENT TRIGGER init_session ENABLE ALWAYS;