/index handler added

main
Uriel Fanelli 2025-05-10 21:08:23 +02:00
parent fc4f12900a
commit e3fecc7fd5
6 changed files with 94 additions and 2 deletions

View File

@ -6,6 +6,8 @@
activitypub_server_app,
activitypub_server_sup,
hello_handler,
timeline_db,
user_db,
webfinger_handler
]},
{registered, []},

View File

@ -11,12 +11,17 @@ start(_Type, _Args) ->
%% creiamo un utente di test, solo per vedere se mnesia va
user_db:init(),
timeline_db:init(),
%% aggiungiamo un paio di utenti di esempio.
user_db:add_user(<<"admin">>, #{email => <<"admin@example.com">>}),
user_db:add_user(<<"alice">>, #{email => <<"alice@example.com">>}),
Dispatch = cowboy_router:compile([
{'_', [
{"/", hello_handler, []},
{"/.well-known/webfinger", webfinger_handler, []}
{"/.well-known/webfinger", webfinger_handler, []},
{"/index", index_handler, []} %% per /index del server
]}
]),
{ok, _} = cowboy:start_clear(

View File

@ -10,4 +10,4 @@ init(Req, State) ->
<<"Hello, world!">>,
Req
),
{ok, Resp, State}.
{ok, Resp, State}.

55
src/index_handler.erl Normal file
View File

@ -0,0 +1,55 @@
%% index_handler.erl
-module(index_handler).
-behaviour(cowboy_handler).
-export([init/2]).
init(Req, State) ->
{ok, Body, Req2} = cowboy_req:read_body(Req),
Activity = jsx:decode(Body, [return_maps]),
case validate_activity(Activity) of
false ->
{ok, Resp} = cowboy_req:reply(400, #{}, <<"Invalid ActivityPub message">>, Req2),
{ok, Resp, State};
true ->
io:format("Activity: ~p~n", [Activity]),
To = maps:get(<<"to">>, Activity, []),
io:format("To: ~p~n", [To]),
case has_local_recipient(To) of
true ->
{ok, Resp} = cowboy_req:reply(200, #{}, <<"Delivered to local user">>, Req2),
{ok, Resp, State};
false ->
timeline_db:add_message(Activity),
{ok, Resp} = cowboy_req:reply(202, #{}, <<"Saved to global timeline">>, Req2),
{ok, Resp, State}
end
end.
%% Controlla se un destinatario è un utente locale
is_local_user(Dest) when is_binary(Dest) ->
io:format("Controllo utente locale: ~p~n", [Dest]),
user_db:get_user(Dest) =/= not_found;
is_local_user(_) ->
false.
%% Controlla se almeno uno dei destinatari è locale
has_local_recipient(To) when is_list(To) ->
lists:any(fun is_local_user/1, To);
has_local_recipient(To) when is_binary(To) ->
is_local_user(To);
has_local_recipient(_) ->
false.
%% vediamo di controllare se ci sono i campi obbligatori minimi di ActivityPub:
validate_activity(Activity) when is_map(Activity) ->
maps:is_key(<<"type">>, Activity) andalso
maps:is_key(<<"to">>, Activity) andalso
maps:is_key(<<"actor">>, Activity) andalso
maps:is_key(<<"object">>, Activity) andalso
maps:is_key(<<"content">>, Activity).

28
src/timeline_db.erl Normal file
View File

@ -0,0 +1,28 @@
%% timeline_db.erl
-module(timeline_db).
-export([init/0, add_message/1, all_messages/0]).
-record(global_message, {id, activity, timestamp}).
init() ->
%% Crea la tabella Mnesia se non esiste
mnesia:create_table(global_message, [
{attributes, record_info(fields, global_message)},
{disc_copies, [node()]}
]).
add_message(Activity) ->
%% Crea un ID unico e un timestamp per il messaggio
Id = erlang:unique_integer([monotonic, positive]),
Timestamp = erlang:system_time(microsecond),
F = fun() ->
mnesia:write(#global_message{id=Id, activity=Activity, timestamp=Timestamp})
end,
mnesia:transaction(F).
all_messages() ->
F = fun() ->
mnesia:match_object(#global_message{id = '_', activity = '_', timestamp = '_'})
end,
{atomic, Messages} = mnesia:transaction(F),
Messages.

2
start.sh Executable file
View File

@ -0,0 +1,2 @@
rebar3 compile
rebar3 shell --apps activitypub_server