94 lines
2.6 KiB
PL/PgSQL
94 lines
2.6 KiB
PL/PgSQL
|
|
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
CREATE TABLE person_account(
|
|||
|
|
person_id int NOT NULL UNIQUE REFERENCES person,
|
|||
|
|
login varchar(60) NOT NULL,
|
|||
|
|
password varchar NOT NULL,
|
|||
|
|
CONSTRAINT empty_login CHECK (trim(login) <> '')
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
CREATE OR REPLACE FUNCTION check_password(_password varchar(60))
|
|||
|
|
RETURNS void AS
|
|||
|
|
$BODY$
|
|||
|
|
BEGIN
|
|||
|
|
IF (trim(_password) = '')
|
|||
|
|
THEN
|
|||
|
|
RAISE EXCEPTION 'Пароль не может быть пустым!';
|
|||
|
|
END IF;
|
|||
|
|
|
|||
|
|
IF (trim(_password) <> _password)
|
|||
|
|
THEN
|
|||
|
|
RAISE EXCEPTION 'Пароль должен быть без пробелов!';
|
|||
|
|
END IF;
|
|||
|
|
|
|||
|
|
IF (length(_password) < 8)
|
|||
|
|
THEN
|
|||
|
|
RAISE EXCEPTION 'Пароль должен иметь больше 8 знаков!';
|
|||
|
|
END IF;
|
|||
|
|
|
|||
|
|
IF (lower(_password) = _password OR _password !~ '[0-9]')
|
|||
|
|
THEN
|
|||
|
|
RAISE EXCEPTION 'Пароль должен иметь прописные и заглавные буквы, а также цифры!';
|
|||
|
|
END IF;
|
|||
|
|
|
|||
|
|
IF ((SELECT COUNT(*) AS letter_count
|
|||
|
|
FROM ( SELECT regexp_split_to_table(_password, '') AS letter) AS letters
|
|||
|
|
GROUP BY letter
|
|||
|
|
ORDER BY letter
|
|||
|
|
LIMIT 1) >= length(_password)/2)
|
|||
|
|
THEN
|
|||
|
|
RAISE EXCEPTION 'Пароль не должен иметь больше половины одинаковых символов!';
|
|||
|
|
END IF;
|
|||
|
|
END
|
|||
|
|
$BODY$
|
|||
|
|
LANGUAGE plpgsql VOLATILE;
|
|||
|
|
|
|||
|
|
CREATE OR REPLACE FUNCTION create_person_account()
|
|||
|
|
RETURNS TRIGGER AS $$
|
|||
|
|
DECLARE
|
|||
|
|
role int;
|
|||
|
|
BEGIN
|
|||
|
|
PERFORM check_password(NEW.password);
|
|||
|
|
NEW.password := crypt(NEW.password, gen_salt('bf'));
|
|||
|
|
|
|||
|
|
RETURN NEW;
|
|||
|
|
END;
|
|||
|
|
$$ LANGUAGE plpgsql;
|
|||
|
|
|
|||
|
|
-- Создаем триггер
|
|||
|
|
CREATE TRIGGER trigger_create_account
|
|||
|
|
BEFORE INSERT ON person_account
|
|||
|
|
FOR EACH ROW
|
|||
|
|
EXECUTE FUNCTION create_person_account();
|
|||
|
|
|
|||
|
|
CREATE OR REPLACE FUNCTION check_enter_in_person_account(_login varchar, _password varchar)
|
|||
|
|
RETURNS int AS $$
|
|||
|
|
DECLARE
|
|||
|
|
_hash_password varchar := null;
|
|||
|
|
_person_id int;
|
|||
|
|
BEGIN
|
|||
|
|
-- Получаем person_id и проверяем авторизацию
|
|||
|
|
SELECT pa.person_id, pa.password
|
|||
|
|
INTO _person_id, _hash_password
|
|||
|
|
FROM person_account pa
|
|||
|
|
WHERE pa.login = _login
|
|||
|
|
AND pa.password = crypt(_password, pa.password);
|
|||
|
|
|
|||
|
|
-- Если запись не найдена
|
|||
|
|
IF _person_id IS NULL THEN
|
|||
|
|
RAISE EXCEPTION 'Неверный логин или пароль!';
|
|||
|
|
END IF;
|
|||
|
|
|
|||
|
|
RETURN _person_id;
|
|||
|
|
END;
|
|||
|
|
$$ LANGUAGE plpgsql;
|
|||
|
|
|
|||
|
|
INSERT INTO person_account (person_id, login, password)
|
|||
|
|
VALUES (1, 'Иванов Н.В.', 'Иванов123'),
|
|||
|
|
(2, 'Сидоров В.А.', 'Сидоров123'),
|
|||
|
|
(3, 'Кузнецов П.С.', 'Кузнецов123'),
|
|||
|
|
(4, 'Петров И.В.', 'Петров123'),
|
|||
|
|
(5, 'Иванов Н.А.', 'Иванов123'),
|
|||
|
|
(6, 'Иванов Е.С.', 'Иванов123');
|