# vim:set sw=4 ts=4 sts=4 ft=perl expandtab: package MightyNetwork; use Mojo::Base 'Mojolicious', -signatures, -async_await; use MightyNetwork::DefaultConfig qw($default_config); use MightyNetwork::DB::User; use Crypt::PBKDF2; =pod =head1 NAME MightyNetwork - Perl implementation of L, a simple L proof of concept. =head1 DESCRIPTION ActivityPub is complex. In order to make it easier to understand for everyone, having a sort of L is needed. Mightynetwork can be this Rosetta stone! =head1 DOCUMENTATION L, the developper of the original mightynetwork wrote a document explaining ActivityPub and its implementation in mightynetwork: L (french). See L for documentation about ActivityPub. =head1 SOFTWARE L is written in L, uses L as framework and L as database. You can get the source code on L. =cut # This method will run once at server start sub startup($self) { # Load configuration from hash returned by "my_app.conf" my $config = $self->plugin('Config' => { default => $default_config }); $self->plugin('MightyNetwork::Plugin::Helpers'); $self->plugin('Authentication' => { autoload_user => 1, session_key => 'MightyNetwork', stash_key => '__authentication__', load_user => sub($c, $uid) { return undef unless defined $uid; return MightyNetwork::DB::User->new(app => $c->app)->get_user_by_id($uid); }, validate_user => sub($c, $username, $password, $extradata) { my $user = MightyNetwork::DB::User->new(app => $c->app)->get_user_by_username($username); if (defined($user->id)) { my $hash = $user->password; my $pbkdf2 = Crypt::PBKDF2->new; if ($pbkdf2->validate($hash, $password)) { return $user->id; } } return undef; } } ); $self->plugin('DebugDumperHelper'); $self->plugin('PODViewer' => { default_module => 'MightyNetwork', layout => 'podviewer', allow_modules => ['^MightyNetwork'] }); $self->plugin('Status') if $self->mode eq 'development'; # Default layout $self->defaults(layout => 'default'); # Allow some redirects for the user agent $self->ua->max_redirects(3); =head1 ROUTES /perldoc * perldoc => leads to this documentation +/:module * module => shows the documentation of a module / GET "index" => index page, shows a form to post a note if logged in / POST "new_note" => post a note, needs to be authenticated /register GET "register" => registering page /register POST "register" => register request /login GET "login" => login page /login POST "login" => login request /logout GET "logout" => logout request, redirects to / /note.json GET "get_note" /notifications GET "notifications" /users * users +/ GET "users" +/ POST +/actors GET actors +/:username GET username +/account/:id GET "account" +/:username/note/:id GET usernamenoteid +/users/:username/outbox GET "u_outbox" +/:username/inbox GET "u_inbox" +/:username GET "get_user" /.well-known/webfinger GET wellknownwebfinger /inbox GET "inbox" =cut # Router my $r = $self->routes; $r->get('/') ->to('Misc#index') ->name('index'); $r->post('/') ->over(authenticated => 1) ->to('Note#new') ->name('new_note'); $r->get('/register' => sub($c) { return $c->render( template => 'register', ); })->name('register'); $r->post('/register') ->to('Auth#register') ->name('register'); $r->get('/login' => sub($c) { return $c->redirect_to('index') if ($c->is_user_authenticated); return $c->render( template => 'login', ); })->name('login'); $r->post('/login') ->to('Auth#login') ->name('login'); $r->get('/logout') ->to('Auth#get_out') ->name('logout'); $r->get('/note.json') ->to('Note#get_note') ->name('get_note'); $r->get('/notifications') ->to('Notification#notifications') ->name('notifications'); my $users = $r->under('/users'); $users->get('/') ->to('Users#get_users') ->name('users'); $users->post('/') ->to('Users#search_users'); $users->get('/actors') ->to('Users#get_actors'); $users->get('/:username') ->to('Users#username'); $users->get('/account/:id') ->to('Users#account') ->name('account'); $users->get('/:username/note/:id') ->to('Users#get_note'); $users->get('/users/:username/outbox') ->to('Users#outbox') ->name('u_outbox'); $users->get('/:username/inbox') ->to('Users#inbox') ->name('u_inbox'); $users->get('/:username') ->to('Users#get_user') ->name('get_user'); $r->get('/.well-known/webfinger') ->to('Users#webfinger'); $r->get('/inbox') ->to('Users#Inbox') ->name('inbox'); } =head1 REFERENCE This is the class hierarchy of L. =over 2 =item L =over 2 =item L =over 2 =item L =over 2 =item L =item L =item L =back =item L =item L =item L =item L =item L =item L =item L =back =item L =over 2 =item L =over 2 =item L =item L =item L =item L =back =item L =item L =item L =back =item L =item L =over 2 =item L =over 2 =item L =over 2 =item L =item L =item L =back =item L =item L =item L =item L =item L =item L =back =item L =item L =item L =item L =item L =back =item L =over 2 =item L =back =back =back =head1 SEE ALSO L =cut 1;