From bc5320224e0e5858d2c3245ee3bcbf0b6e512510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrej=20Rama=C5=A1euski?= <andrej@x2.cz> Date: Sun, 3 Jan 2021 01:00:46 +0100 Subject: [PATCH] Lepsi pocitani, prepnuti na Mojo::Pg --- lib/CF/Controller/Websockets.pm | 68 ++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 23 deletions(-) diff --git a/lib/CF/Controller/Websockets.pm b/lib/CF/Controller/Websockets.pm index c2329a2..a1772d4 100644 --- a/lib/CF/Controller/Websockets.pm +++ b/lib/CF/Controller/Websockets.pm @@ -8,13 +8,12 @@ use POSIX qw(ceil); use feature 'signatures'; no warnings qw{ experimental::signatures }; -use constant SOCKET_INACTIVITY_TIMEOUT => 300; +use constant SOCKET_INACTIVITY_TIMEOUT => 180; sub main { my $c = shift; - my $ip = $c->tx->remote_address; - - my $user; + my $ip = $c->tx->remote_address; + my $key = $c->req->headers->header('Sec-WebSocket-Key'); $c->inactivity_timeout(SOCKET_INACTIVITY_TIMEOUT); @@ -25,29 +24,53 @@ sub main { }); $c->on(json => sub( $c, $message ) { - if ( $message->{event} eq 'KEEPALIVE' ) { - if ($message->{payload} =~ /^(\d+)$/) { - # TODO: check signtaure + my $user; + + if ($message->{payload} =~ /^\d+$/) { + + $user = $c->pg->db->select('users', + [qw(id username secret jitsi_allowed roles banned_until)], + { id => $message->{payload}} + )->hash; + } - $user //= $c->schema->resultset('User')->find( - { id => $1 } - ); + if ( $user ) { + my $sig = hmac_sha1_hex($message->{payload}, $user->{secret} ); + if ( $sig ne $message->{sig} ) { + $c->app->log->warn( + "Invalid signature for " . $user->{username} + ); + $user = undef; + } } - $c->schema->resultset('Socket')->update_or_create({ - id => $c->req->headers->header('Sec-WebSocket-Key'), - ip => $ip, - keepalive => \'now()', - user_id => $user ? $user->id : undef, - }, { key => $user ? 'user':'primary'} ); + eval { + my $tx = $c->pg->db->begin; + + $c->pg->db->delete('sockets', [ + {id => $key}, + {user_id => $message->{payload}}, + ]); + + $c->pg->db->insert('sockets', { + id => $key, + ip => $ip, + keepalive => \'now()', + user_id => $user ? $user->{id} : undef, + }); - my $all = $c->schema->resultset('Socket_view')->count(); + $tx->commit; + }; - my $members = $c->schema->resultset('Socket_view')->count( - { is_member => 't' } - ); + my $all = $c->pg->db->query( + 'select count(*) from sockets_view' + )->hash->{count}; + + my $members = $c->pg->db->query( + 'select count(*) from sockets_view where is_member' + )->hash->{count}; my $group_size = $c->_member_group_size($members); @@ -59,15 +82,14 @@ sub main { }}}); if ( $user ) { - my $jitsi = $user->jitsi_allowed || $user->roles =~ /chairman/; + my $jitsi = $user->{jitsi_allowed} || $user->{roles} =~ /chairman|jitsi/; $c->send({json => { event => 'user_status', payload => { jitsi_allowed => $jitsi ? \1:\0, - is_banned => $user->banned_until ? \1:\0, + is_banned => $user->{banned_until} ? \1:\0, }}}); } } - }); $c->on(finish => sub ($c, $code, $reason = undef) { -- GitLab