Перенести все админские эндпоинты на порт 8445 и добавить отдельную авторизацию для админов. Часть 1

This commit is contained in:
2026-04-27 15:54:48 +03:00
parent 62bc62f990
commit 4ed6a961ab
40 changed files with 3573 additions and 800 deletions
-85
View File
@@ -1,85 +0,0 @@
-module(core_banned_word).
-include("records.hrl").
-export([add/1, remove/1, list_all/0, is_banned/1]).
-export([check_text/1, filter_text/1]).
%% Добавить слово в бан-лист
add(Word) when is_binary(Word) ->
WordLower = string:lowercase(Word),
case is_banned(WordLower) of
true -> {error, already_exists};
false ->
BannedWord = #banned_word{
id = generate_id(),
word = WordLower
},
F = fun() ->
mnesia:write(BannedWord),
{ok, BannedWord}
end,
case mnesia:transaction(F) of
{atomic, Result} -> Result;
{aborted, Reason} -> {error, Reason}
end
end.
%% Удалить слово из бан-листа
remove(Word) when is_binary(Word) ->
WordLower = string:lowercase(Word),
Match = #banned_word{word = WordLower, _ = '_'},
case mnesia:dirty_match_object(Match) of
[] -> {error, not_found};
[BannedWord] ->
F = fun() ->
mnesia:delete_object(BannedWord),
{ok, removed}
end,
case mnesia:transaction(F) of
{atomic, Result} -> Result;
{aborted, Reason} -> {error, Reason}
end
end.
%% Список всех запрещённых слов
list_all() ->
Match = #banned_word{_ = '_'},
Words = mnesia:dirty_match_object(Match),
{ok, [W#banned_word.word || W <- Words]}.
%% Проверить, является ли слово запрещённым
is_banned(Word) when is_binary(Word) ->
WordLower = string:lowercase(Word),
Match = #banned_word{word = WordLower, _ = '_'},
case mnesia:dirty_match_object(Match) of
[] -> false;
_ -> true
end.
%% Проверить текст на наличие запрещённых слов
check_text(Text) when is_binary(Text) ->
TextLower = string:lowercase(Text),
Words = string:split(TextLower, " ", all),
{ok, BannedWords} = list_all(),
lists:any(fun(W) -> lists:member(W, BannedWords) end, Words).
%% Отфильтровать запрещённые слова (заменить на ***)
filter_text(Text) when is_binary(Text) ->
{ok, BannedWords} = list_all(),
Words = binary:split(Text, <<" ">>, [global]),
Filtered = lists:map(fun(W) ->
case lists:member(string:lowercase(W), BannedWords) of
true -> <<"***">>;
false -> W
end
end, Words),
iolist_to_binary(join_binary(Filtered, <<" ">>)).
join_binary([], _) -> [];
join_binary([H], _) -> [H];
join_binary([H|T], Sep) ->
[H, Sep | join_binary(T, Sep)].
%% Внутренние функции
generate_id() ->
base64:encode(crypto:strong_rand_bytes(16), #{mode => urlsafe, padding => false}).
+54
View File
@@ -0,0 +1,54 @@
-module(core_banned_words).
-export([list_banned_words/0,
add_banned_word/2,
remove_banned_word/1,
update_banned_word/2]).
-include("records.hrl").
list_banned_words() ->
mnesia:dirty_match_object(#banned_word{_ = '_'}).
add_banned_word(Word, AddedBy) ->
Id = generate_id(),
Now = calendar:universal_time(),
BW = #banned_word{id = Id, word = Word, added_by = AddedBy, added_at = Now},
case mnesia:transaction(fun() ->
case mnesia:match_object(#banned_word{word = Word, _ = '_'}) of
[] -> mnesia:write(BW), {ok, BW};
_ -> mnesia:abort(already_exists)
end
end) of
{atomic, {ok, BWRec}} -> {ok, BWRec};
{aborted, already_exists} -> {error, already_exists};
{aborted, Reason} -> {error, Reason}
end.
remove_banned_word(Word) ->
case mnesia:transaction(fun() ->
case mnesia:match_object(#banned_word{word = Word, _ = '_'}) of
[Rec] -> mnesia:delete_object(Rec), {ok, deleted};
[] -> mnesia:abort(not_found)
end
end) of
{atomic, {ok, deleted}} -> {ok, deleted};
{aborted, not_found} -> {error, not_found}
end.
update_banned_word(OldWord, NewWord) ->
case mnesia:transaction(fun() ->
case mnesia:match_object(#banned_word{word = OldWord, _ = '_'}) of
[Rec] ->
Updated = Rec#banned_word{word = NewWord},
mnesia:write(Updated),
{ok, Updated};
[] ->
mnesia:abort(not_found)
end
end) of
{atomic, {ok, UpdatedRec}} -> {ok, UpdatedRec};
{aborted, not_found} -> {error, not_found}
end.
generate_id() ->
base64:encode(crypto:strong_rand_bytes(9)).
+17
View File
@@ -4,6 +4,7 @@
-export([create/2, get_by_id/1, get_by_email/1, update/2, delete/1]).
-export([email_exists/1]).
-export([generate_id/0]).
-export([list_users/0]).
%% Создание пользователя
create(Email, Password) ->
@@ -86,6 +87,22 @@ update(Id, Updates) ->
delete(Id) ->
update(Id, [{status, deleted}]).
list_users() ->
Users = mnesia:dirty_match_object(#user{_ = '_'}),
ActiveUsers = [U || U <- Users, U#user.status =/= deleted],
{ok, [user_to_map(U) || U <- ActiveUsers]}.
user_to_map(User) ->
#{
id => User#user.id,
email => User#user.email,
password_hash => User#user.password_hash,
role => User#user.role,
status => User#user.status,
created_at => User#user.created_at,
updated_at => User#user.updated_at
}.
%% Внутренние функции
generate_id() ->
base64:encode(crypto:strong_rand_bytes(16), #{mode => urlsafe, padding => false}).