Files
EventHubBack/src/core/core_user.erl

139 lines
3.8 KiB
Erlang

-module(core_user).
-include("records.hrl").
-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]).
-export([block/1, unblock/1]).
%% Создание пользователя
create(Email, Password) ->
% Проверяем, существует ли email
case email_exists(Email) of
true ->
{error, email_exists};
false ->
Id = generate_id(),
{ok, PasswordHash} = logic_auth:hash_password(Password),
% Определяем роль: первый пользователь становится админом
Role = case mnesia:dirty_match_object(#user{_ = '_'}) of
[] -> admin;
_ -> user
end,
User = #user{
id = Id,
email = Email,
password_hash = PasswordHash,
role = Role,
status = active,
created_at = calendar:universal_time(),
updated_at = calendar:universal_time()
},
F = fun() ->
mnesia:write(User),
{ok, User}
end,
case mnesia:transaction(F) of
{atomic, Result} -> Result;
{aborted, Reason} -> {error, Reason}
end
end.
%% Получение пользователя по ID
get_by_id(Id) ->
case mnesia:dirty_read(user, Id) of
[] -> {error, not_found};
[User] -> {ok, User}
end.
%% Получение пользователя по email
get_by_email(Email) ->
Match = #user{email = Email, _ = '_'},
case mnesia:dirty_match_object(Match) of
[] -> {error, not_found};
[User] -> {ok, User}
end.
%% Проверка существования email
email_exists(Email) ->
case get_by_email(Email) of
{ok, _} -> true;
{error, _} -> false
end.
%% Обновление пользователя
update(Id, Updates) ->
F = fun() ->
case mnesia:read(user, Id) of
[] ->
{error, not_found};
[User] ->
UpdatedUser = apply_updates(User, Updates),
mnesia:write(UpdatedUser),
{ok, UpdatedUser}
end
end,
case mnesia:transaction(F) of
{atomic, Result} -> Result;
{aborted, Reason} -> {error, Reason}
end.
%% Удаление пользователя (soft delete)
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
}.
block(Id) ->
case get_by_id(Id) of
{ok, User} ->
Updated = User#user{status = blocked, updated_at = calendar:universal_time()},
mnesia:dirty_write(Updated),
{ok, Updated};
Error -> Error
end.
unblock(Id) ->
case get_by_id(Id) of
{ok, User} ->
Updated = User#user{status = active, updated_at = calendar:universal_time()},
mnesia:dirty_write(Updated),
{ok, Updated};
Error -> Error
end.
%% Внутренние функции
generate_id() ->
base64:encode(crypto:strong_rand_bytes(16), #{mode => urlsafe, padding => false}).
apply_updates(User, Updates) ->
Updated = lists:foldl(fun({Field, Value}, U) ->
set_field(Field, Value, U)
end, User, Updates),
Updated#user{updated_at = calendar:universal_time()}.
set_field(email, Value, U) -> U#user{email = Value};
set_field(password_hash, Value, U) -> U#user{password_hash = Value};
set_field(role, Value, U) when Value =:= user; Value =:= admin -> U#user{role = Value};
set_field(status, Value, U) when Value =:= active; Value =:= frozen; Value =:= deleted -> U#user{status = Value};
set_field(_, _, U) -> U.