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'); |