Frontend: Implement channel adding support
This commit is contained in:
parent
d594c53e50
commit
61ea7c8eec
@ -21,6 +21,7 @@ use frontend_session;
|
|||||||
use logger;
|
use logger;
|
||||||
|
|
||||||
use Digest::SHA;
|
use Digest::SHA;
|
||||||
|
use threads::shared;
|
||||||
|
|
||||||
use feature qw(switch);
|
use feature qw(switch);
|
||||||
use strict;
|
use strict;
|
||||||
@ -368,6 +369,73 @@ sub handlePath {
|
|||||||
logger::createLogger($parameters{"name"}, $parameters{"address"}, $port, ());
|
logger::createLogger($parameters{"name"}, $parameters{"address"}, $port, ());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
when("/manage_channel_action") {
|
||||||
|
if(!defined($aRequest->{"cookies"}{"session"}) || !frontend_session::isValidSession($aRequest->{"cookies"}{"session"})) {
|
||||||
|
frontend::redirect($aClient, "/");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(defined($aRequest->{"headers"}{"Content-Type"}) && $aRequest->{"headers"}{"Content-Type"} ne "application/x-www-form-urlencoded") {
|
||||||
|
frontend::sendBadRequest($aClient, "Unsupported form Content-Type (application/x-www-form-urlencoded required)");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(!defined($aRequest->{"content"})) {
|
||||||
|
frontend::sendBadRequest($aClient, "Request content required");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
my $session = $frontend_session::sessions{$aRequest->{"cookies"}{"session"}};
|
||||||
|
|
||||||
|
my $query = $aConnection->prepare(qq(select privileges from users where name=?;));
|
||||||
|
$query->execute($session->{"username"});
|
||||||
|
my @row = $query->fetchrow_array();
|
||||||
|
if($row[0]<2) {
|
||||||
|
frontend::sendForbidden($aClient, "Insufficient permissions to perform this operation");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
my %parameters = frontend::parsePathParameters($aRequest->{"content"});
|
||||||
|
if(!defined($parameters{"channel"})) {
|
||||||
|
frontend::sendBadRequest($aClient, "Channel name required");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(!defined($parameters{"server"})) {
|
||||||
|
frontend::sendBadRequest($aClient, "Server ID required");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = $aConnection->prepare(qq(select name from servers where id=?;));
|
||||||
|
$query->execute($parameters{"server"});
|
||||||
|
@row = $query->fetchrow_array();
|
||||||
|
if(scalar(@row)==0) {
|
||||||
|
frontend::sendBadRequest($aClient, "Invalid server ID");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
my $serverName = $row[0];
|
||||||
|
|
||||||
|
$query = $aConnection->prepare(qq(select id from channels where name=? and server_id=?;));
|
||||||
|
$query->execute($parameters{"channel"}, $parameters{"server"});
|
||||||
|
@row = $query->fetchrow_array();
|
||||||
|
$parameters{"channel"}=~s/%23/#/;
|
||||||
|
if(scalar(@row)>0) {
|
||||||
|
frontend::sendConflict($aClient, "Channel $parameters{'channel'} already exists on server $serverName");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = $aConnection->prepare(qq(select id from channels order by rowid desc limit 1;));
|
||||||
|
$query->execute();
|
||||||
|
@row = $query->fetchrow_array();
|
||||||
|
my $lastID = 0;
|
||||||
|
if(scalar(@row)>0) {
|
||||||
|
$lastID = $row[0]+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = $aConnection->prepare(qq(insert into channels values($lastID, ?, ?, 1);));
|
||||||
|
$query->execute($parameters{"server"}, $parameters{"channel"});
|
||||||
|
my $actionQueue = logger::getActionQueueByServerName($serverName);
|
||||||
|
push(@$actionQueue, "JOIN", $parameters{"channel"});
|
||||||
|
|
||||||
|
frontend::redirect($aClient, "/channel_added.html");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
when("/view_logs") {
|
when("/view_logs") {
|
||||||
my $channelID = $aRequest->{"path"}{"parameters"}{"channel"};
|
my $channelID = $aRequest->{"path"}{"parameters"}{"channel"};
|
||||||
if(!defined($channelID)) {
|
if(!defined($channelID)) {
|
||||||
|
92
logger.pm
92
logger.pm
@ -17,10 +17,12 @@
|
|||||||
package logger;
|
package logger;
|
||||||
|
|
||||||
use IO::Socket;
|
use IO::Socket;
|
||||||
|
use IO::Select;
|
||||||
use List::Util;
|
use List::Util;
|
||||||
use Time::Piece;
|
use Time::Piece;
|
||||||
use File::Path;
|
use File::Path;
|
||||||
use threads;
|
use threads;
|
||||||
|
use threads::shared;
|
||||||
|
|
||||||
use lib ".";
|
use lib ".";
|
||||||
use configuration;
|
use configuration;
|
||||||
@ -34,13 +36,35 @@ sub connectToServer {
|
|||||||
my $aPort = $_[1];
|
my $aPort = $_[1];
|
||||||
my $aServerName = $_[2];
|
my $aServerName = $_[2];
|
||||||
|
|
||||||
my $socket = new IO::Socket::INET(PeerAddr=>$aServer, PeerPort=>$aPort, Proto=>"tcp");
|
my $socket = IO::Socket::INET->new(PeerAddr=>$aServer, PeerPort=>$aPort, Proto=>"tcp");
|
||||||
$socket->send(sprintf("PASS %s\r\n", $configuration::botPassword));
|
$socket->send(sprintf("PASS %s\r\n", $configuration::botPassword));
|
||||||
$socket->send(sprintf("NICK %s\r\n", $configuration::botNick));
|
$socket->send(sprintf("NICK %s\r\n", $configuration::botNick));
|
||||||
$socket->send(sprintf("USER %s %s %s :%s\r\n", $configuration::botUsername, $configuration::botHostname, $aServerName, $configuration::botName));
|
$socket->send(sprintf("USER %s %s %s :%s\r\n", $configuration::botUsername, $configuration::botHostname, $aServerName, $configuration::botName));
|
||||||
return $socket;
|
return $socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub readLineFromBuffer {
|
||||||
|
my $aBuffer = $_[0];
|
||||||
|
|
||||||
|
my $output = "";
|
||||||
|
my $bufferLength = length($aBuffer);
|
||||||
|
foreach my $i (0..$bufferLength-1) {
|
||||||
|
my $char = substr($aBuffer, $i, 1);
|
||||||
|
if($char eq "\n" || ($char eq "\r" && $i+1<$bufferLength && substr($aBuffer, $i+1, 1) eq "\n")) {
|
||||||
|
my $outputLength = length($output);
|
||||||
|
if($char eq "\r" && $i+1<$bufferLength && substr($aBuffer, $i+1, 1) eq "\n") {
|
||||||
|
$outputLength+=2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$outputLength++;
|
||||||
|
}
|
||||||
|
return ($output, substr($aBuffer, $outputLength, $bufferLength-$outputLength));
|
||||||
|
}
|
||||||
|
$output.=$char;
|
||||||
|
}
|
||||||
|
return ("", $aBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
sub stripPrefix {
|
sub stripPrefix {
|
||||||
my $aLine = $_[0];
|
my $aLine = $_[0];
|
||||||
|
|
||||||
@ -257,43 +281,75 @@ sub joinChannels {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
our @connections :shared;
|
||||||
|
|
||||||
sub connectionWorker {
|
sub connectionWorker {
|
||||||
my $aHost = $_[0];
|
my $aHost = $_[0];
|
||||||
my $aPort = $_[1];
|
my $aPort = $_[1];
|
||||||
my $aServerName = $_[2];
|
my $aServerName = $_[2];
|
||||||
my $aChannels = $_[3];
|
my $aChannels = $_[3];
|
||||||
my $aConnection = $_[4];
|
|
||||||
|
|
||||||
my %logFiles;
|
my %logFiles;
|
||||||
my $stream = connectToServer($aHost, $aPort, $aServerName);
|
my $stream = connectToServer($aHost, $aPort, $aServerName);
|
||||||
while(!eof($stream) && $aConnection->[1]) {
|
my $streamSelect = IO::Select->new($stream);
|
||||||
my $line = readline($stream);
|
my $buffer = "";
|
||||||
my @command = parseIRCCommand($line);
|
my @actionQueue :shared;
|
||||||
printf(":: Server -> %s", $line);
|
my @connection :shared = ($aServerName, \@actionQueue);
|
||||||
|
push(@connections, \@connection);
|
||||||
|
while(!eof($stream)) {
|
||||||
|
if(scalar(@actionQueue)>0) {
|
||||||
|
given($actionQueue[0]) {
|
||||||
|
when("JOIN") {
|
||||||
|
joinChannel($stream, $actionQueue[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@actionQueue = ();
|
||||||
|
}
|
||||||
|
|
||||||
given($command[0]) {
|
my @canRead = $streamSelect->can_read(0);
|
||||||
when("PING") { handlePing($stream, \@command); }
|
if(scalar(@canRead)==0) {
|
||||||
when("PRIVMSG") { handlePrivMsg($stream, \@command, $aServerName, $aChannels, \%logFiles); }
|
next;
|
||||||
when("JOIN") { handleJoin(\@command, $aServerName, \%logFiles); }
|
}
|
||||||
when("QUIT") { handleQuit(\@command, $aServerName, $aChannels, \%logFiles); }
|
my $tempBuffer;
|
||||||
when("PART") { handlePart(\@command, $aServerName, \%logFiles); }
|
$stream->recv($tempBuffer, 512);
|
||||||
when("376") { joinChannels($stream, $aChannels); } # end of MOTD
|
$buffer.=$tempBuffer;
|
||||||
|
my ($line, $remaining) = readLineFromBuffer($buffer);
|
||||||
|
$buffer = $remaining;
|
||||||
|
while(length($line)>0) {
|
||||||
|
my @command = parseIRCCommand($line);
|
||||||
|
#printf(":: Server -> %s\n", $line);
|
||||||
|
given($command[0]) {
|
||||||
|
when("PING") { handlePing($stream, \@command); }
|
||||||
|
when("PRIVMSG") { handlePrivMsg($stream, \@command, $aServerName, $aChannels, \%logFiles); }
|
||||||
|
when("JOIN") { handleJoin(\@command, $aServerName, \%logFiles); }
|
||||||
|
when("QUIT") { handleQuit(\@command, $aServerName, $aChannels, \%logFiles); }
|
||||||
|
when("PART") { handlePart(\@command, $aServerName, \%logFiles); }
|
||||||
|
when("376") { joinChannels($stream, $aChannels); } # end of MOTD
|
||||||
|
}
|
||||||
|
($line, $remaining) = readLineFromBuffer($buffer);
|
||||||
|
$buffer = $remaining;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close($stream);
|
close($stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
our @connections;
|
|
||||||
|
|
||||||
sub createLogger {
|
sub createLogger {
|
||||||
my $aName = $_[0];
|
my $aName = $_[0];
|
||||||
my $aHost = $_[1];
|
my $aHost = $_[1];
|
||||||
my $aPort = $_[2];
|
my $aPort = $_[2];
|
||||||
my $aChannels = $_[3];
|
my $aChannels = $_[3];
|
||||||
|
|
||||||
my @connection = ($aName, 1);
|
threads->create("connectionWorker", $aHost, $aPort, $aName, $aChannels);
|
||||||
push(@connection, threads->create("connectionWorker", $aHost, $aPort, $aName, $aChannels, \@connection));
|
}
|
||||||
push(@connections, @connection);
|
|
||||||
|
sub getActionQueueByServerName {
|
||||||
|
my $aServerName = $_[0];
|
||||||
|
|
||||||
|
foreach my $connection (@connections) {
|
||||||
|
if($connection->[0] eq $aServerName) {
|
||||||
|
return $connection->[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
my $db = DBI->connect("DBI:SQLite:dbname=$configuration::database", "", "", {RaiseError=>1});
|
my $db = DBI->connect("DBI:SQLite:dbname=$configuration::database", "", "", {RaiseError=>1});
|
||||||
|
10
static/channel_added.html
Normal file
10
static/channel_added.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Channel added</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>Channel successfully added</p>
|
||||||
|
<a href="/panel">Return to user panel</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
x
Reference in New Issue
Block a user