Знайомство з Erlang [5-2]
Продовжуємо роботу в erlang з postgresql - hstore
Існує така штука як RBAC https://en.wikipedia.org/wiki/Role-based_access_control
І зараз ми реалізуємо цей спосіб в ерлангу, з використанням hstore.
Зберігатимемо наші ключі-значення в полі з іменем security_attributes та типом hstore
(напевно у тій же таблиці, де і id-login-password наших користувачів)
в окремий ерланг-модуль hm.erl додамо функції
(назва не важлива, це скорочення від helping module)
has_access(Security_Attributes2, Page) ->
Not_Banned = not(?MODULE:has_access4(Security_Attributes2, <<"banned">>)),
?MODULE:has_access3(Security_Attributes2, Not_Banned, Page).
has_access2(Security_Attributes) ->
Map1 = #{<<"banned">> => <<"0">>,
<<"is_user">> => <<"0">>,
<<"is_moderator">> => <<"0">>,
<<"is_admin">> => <<"0">>},
maps:merge(Map1,maps:from_list(Security_Attributes)).
%banned
has_access3(_, false, _) -> false;
%not banned
has_access3(Security_Attributes2, _, <<"mypage1">>) ->
?MODULE:has_access4(Security_Attributes2, <<"is_user">>);
has_access3(Security_Attributes2, _, <<"mypage2">>) ->
?MODULE:has_access4(Security_Attributes2, <<"is_moderator">>);
has_access3(Security_Attributes2, _, <<"adminka">>) ->
?MODULE:has_access4(Security_Attributes2, <<"is_admin">>);
has_access3(_,_,_) -> false.
%get value by key and return bool
has_access4(Security_Attributes2, Key) ->
case maps:get(Key, Security_Attributes2, undefined) of
<<"1">> -> true;
_ -> false
end.
- спочатку отримане з бд значення перетворюємо (proplist -> map) та об'єднуємо зі значеннями по-замовчанню,
значення з бд перезаписують значення по-замовчанню
(в тій же функції has_access2 в 1й map ми і дописуємо групи та додаткові права цієї групи,
або ж просто окремі набори прав для кожного нашого користувача, в залежності від потреби)
Security_access2 = hm:has_access2(Security_access),
- перевіряємо чи має користувач доступ до певної сторінки,
далі виводимо користувачу повідомлення про відсутність доступу|переадресовуємо його на іншу сторінку чи показуємо вибрану сторінку
Access = hm:has_access(Security_access2, <<"mypage1">>),
case Access of
false ->
wf:redirect("/login/");
true ->
%show mypage1 here
end.
Деталі функцій -
- has_access2(Security_Attributes) --
отримайний список-proplist з бд перетворюється в map та обєднується зі списком значень по-замовчанню
inputs - отримані з бд Security_Attributes у вигляді proplist
outputs - Security_Attributes2 у вигляді map, включає у себе значення з Security_Attributes та значення по-замовчанню для відсутніх в попередньому списку ключів
- has_access(Security_Attributes2, Page) --
отримуємо відповідь на запитання "чи забанений користувач" та викликаємо функцію перевірки права доступу до даної сторінки
inputs - Security_Attributes2 - map, Page - binary string (цільова сторінка),
outputs - результат роботи функції has_access3/3 - boolean
- has_access3(Security_Attributes2, Not_Banned, Page) --
отримуємо відповідь на запитання "чи має користувач право доступу до цієї сторінки",
якщо користувач забанений - відповідь завжди false
inputs - Security_Attributes2 - map (результат роботи функції has_access2(Security_Attributes) ), Page - binary string (цільова сторінка)
outputs - boolean
- has_access4(Security_Attributes2, Key) --
ця функція просто повертає boolean-значення для даного ключа Key з map Security_Attributes2
(<<"1">> -> true, <<"0">> -> false, undefined -> false)