Compare commits
10 Commits
c41173c06f
...
1a9299bc9c
Author | SHA1 | Date | |
---|---|---|---|
1a9299bc9c | |||
01624c6c14 | |||
cf3fe30e4e | |||
e6085c6e0b | |||
8d60bb55bc | |||
e5e82db490 | |||
6c2bf4aacf | |||
549c84c6ef | |||
251962ae0f | |||
bfa355e846 |
@ -2,7 +2,7 @@
|
||||
irclogger_web is a highly configurable IRC logger with web frontend. It's written in Perl.
|
||||
|
||||
## Installation
|
||||
1. You need to have Perl and SQLite3 interpreter installed.
|
||||
1. You need to have Perl interpreter and SQLite3 installed.
|
||||
2. Following Perl packages have to be installed: [DBI](https://metacpan.org/pod/DBI), [DBD::SQLite](https://metacpan.org/pod/DBD::SQLite).
|
||||
3. Run `./prepare_database.sh` to create SQLite3 database for storing users, servers and logged channels.
|
||||
4. See `configuration.pm` and adjust it to your needs.
|
||||
|
@ -1,7 +1,8 @@
|
||||
create table channels(id int primary key not null,
|
||||
server_id int not null, -- foreign key in servers table
|
||||
name text not null,
|
||||
public int not null
|
||||
public int not null,
|
||||
enabled int not null
|
||||
);
|
||||
|
||||
create table users(id int primary key not null,
|
||||
@ -13,7 +14,8 @@ create table users(id int primary key not null,
|
||||
create table servers(id int primary key not null,
|
||||
name text not null,
|
||||
host text not null,
|
||||
port int not null
|
||||
port int not null,
|
||||
enabled int not null
|
||||
);
|
||||
|
||||
create table accessors(user_id int not null, -- foreign key in users table
|
||||
|
10
frontend.pm
10
frontend.pm
@ -495,6 +495,16 @@ sub createUser {
|
||||
$query->execute($aName, $password, $aPrivileges);
|
||||
}
|
||||
|
||||
sub deleteUser {
|
||||
my $aID = $_[0];
|
||||
my $aConnection = $_[1];
|
||||
|
||||
my $query = $aConnection->prepare(qq(delete from users where id=?;));
|
||||
$query->execute($aID);
|
||||
$query = $aConnection->prepare(qq(delete from accessors where user_id=?;));
|
||||
$query->execute($aID);
|
||||
}
|
||||
|
||||
sub httpServerWorker {
|
||||
my $db = DBI->connect("DBI:SQLite:dbname=$configuration::database", "", "", {RaiseError=>1});
|
||||
my $query = $db->prepare(qq(select id from users;));
|
||||
|
@ -86,6 +86,21 @@ sub verifyChannelAccess {
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub enumerateServers {
|
||||
my $aConnection = $_[0];
|
||||
|
||||
my $output = "<select name=\"server\">";
|
||||
my $query = $aConnection->prepare(qq(select id, name from servers;));
|
||||
$query->execute();
|
||||
while(my @row = $query->fetchrow_array()) {
|
||||
my $serverID = $row[0];
|
||||
my $server = $row[1];
|
||||
$output.="<option value=\"$serverID\">$server</option>";
|
||||
}
|
||||
$output.="</select>";
|
||||
return $output;
|
||||
}
|
||||
|
||||
sub enumerateChannels {
|
||||
my $aConnection = $_[0];
|
||||
|
||||
@ -102,6 +117,25 @@ sub enumerateChannels {
|
||||
return $output;
|
||||
}
|
||||
|
||||
sub enumerateUsers {
|
||||
my $aConnection = $_[0];
|
||||
my $aSession = $_[1];
|
||||
|
||||
my $output = "<select name=\"user\">";
|
||||
my $query = $aConnection->prepare(qq(select id, name from users;));
|
||||
$query->execute();
|
||||
while(my @row = $query->fetchrow_array()) {
|
||||
my $id = $row[0];
|
||||
my $name = $row[1];
|
||||
if($name eq $aSession->{"username"}) {
|
||||
next;
|
||||
}
|
||||
$output.="<option value=\"$id\">$name</option>";
|
||||
}
|
||||
$output.="</select>";
|
||||
return $output;
|
||||
}
|
||||
|
||||
sub handlePath {
|
||||
my $aClient = $_[0];
|
||||
my $aPath = $_[1];
|
||||
@ -129,16 +163,17 @@ sub handlePath {
|
||||
$userbar.="</form>";
|
||||
}
|
||||
|
||||
my $query = $aConnection->prepare(qq(select channels.id, channels.name, servers.name from channels inner join servers on channels.server_id=servers.id where channels.public=1;));
|
||||
my $query = $aConnection->prepare(qq(select channels.id, channels.name, channels.enabled, servers.name, servers.enabled from channels inner join servers on channels.server_id=servers.id where channels.public=1;));
|
||||
$query->execute();
|
||||
my $table = "";
|
||||
while(my @row = $query->fetchrow_array()) {
|
||||
my $channelID = $row[0];
|
||||
my $channelName = $row[1];
|
||||
my $serverName = $row[2];
|
||||
my $channelEnabled = $row[2] && $row[4];
|
||||
my $serverName = $row[3];
|
||||
$channelName =~ s/%23/#/;
|
||||
|
||||
$table.="<tr><td><a href=\"view_logs?channel=$channelID\">$channelName</a></td><td>$serverName</td></tr>";
|
||||
my $status = $channelEnabled?"<span style=\"color:green\">Enabled</span>":"<span style=\"color:gray\">Disabled</span>";
|
||||
$table.="<tr><td><a href=\"view_logs?channel=$channelID\">$channelName</a></td><td>$serverName</td><td>$status</td></tr>";
|
||||
}
|
||||
|
||||
my $privateChannels = "";
|
||||
@ -146,6 +181,10 @@ sub handlePath {
|
||||
$query = $aConnection->prepare(qq(select id, privileges from users where name=?;));
|
||||
$query->execute($frontend_session::sessions{$aRequest->{"cookies"}{"session"}}{"username"});
|
||||
my @row = $query->fetchrow_array();
|
||||
if(scalar(@row)==0) {
|
||||
frontend::redirect($aClient, "/");
|
||||
return 1;
|
||||
}
|
||||
my $id = $row[0];
|
||||
my $privileges = $row[1];
|
||||
if($privileges>0) {
|
||||
@ -158,13 +197,15 @@ sub handlePath {
|
||||
}
|
||||
while(@row = $query->fetchrow_array()) {
|
||||
my $channelID = $row[0];
|
||||
my $channelQuery = $aConnection->prepare(qq(select channels.name, servers.name from channels inner join servers on channels.server_id=servers.id where channels.id=$channelID;));
|
||||
my $channelQuery = $aConnection->prepare(qq(select channels.name, channels.enabled, servers.name, servers.enabled from channels inner join servers on channels.server_id=servers.id where channels.id=$channelID;));
|
||||
$channelQuery->execute();
|
||||
@row = $channelQuery->fetchrow_array();
|
||||
my $channelName = $row[0];
|
||||
$channelName =~ s/%23/#/;
|
||||
my $serverName = $row[1];
|
||||
$privateChannels.="<tr><td><a href=\"view_logs?channel=$channelID\">$channelName</a></td><td>$serverName</td></tr>";
|
||||
my $channelEnabled = $row[1] && $row[3];
|
||||
my $serverName = $row[2];
|
||||
my $status = $channelEnabled?"<span style=\"color:green\">Enabled</span>":"<span style=\"color:gray\">Disabled</span>";
|
||||
$privateChannels.="<tr><td><a href=\"view_logs?channel=$channelID\">$channelName</a></td><td>$serverName</td><td>$status</td></tr>";
|
||||
}
|
||||
}
|
||||
|
||||
@ -216,7 +257,7 @@ sub handlePath {
|
||||
my $response = frontend::getBaseResponse(301, "OK");
|
||||
$response.="Location: /\r\n";
|
||||
$response.="Content-Length: 0\r\n";
|
||||
$response.="Set-Cookie: session=$token\r\n\r\n";
|
||||
$response.="Set-Cookie: session=$token;expires=".localtime(time()+7*24*3600)."\r\n\r\n";
|
||||
$aClient->send($response);
|
||||
return 1;
|
||||
}
|
||||
@ -236,25 +277,19 @@ sub handlePath {
|
||||
my $query = $aConnection->prepare(qq(select privileges from users where name=?;));
|
||||
$query->execute($session->{"username"});
|
||||
my @row = $query->fetchrow_array();
|
||||
if(scalar(@row)==0) {
|
||||
frontend::redirect($aClient, "/");
|
||||
return 1;
|
||||
}
|
||||
my $privileges = $row[0];
|
||||
|
||||
my $manageChannelAccess = "";
|
||||
my $addUser = "";
|
||||
my $updateUser = "";
|
||||
if($privileges>=1) { # moderator
|
||||
$manageChannelAccess.="<h3>Manage channel access</h3>";
|
||||
$manageChannelAccess.="<form action=\"manage_access_action\" method=\"POST\">";
|
||||
$manageChannelAccess.="<select name=\"user\">";
|
||||
$query = $aConnection->prepare(qq(select id, name from users;));
|
||||
$query->execute();
|
||||
while(@row = $query->fetchrow_array()) {
|
||||
my $id = $row[0];
|
||||
my $name = $row[1];
|
||||
if($name eq $session->{"username"}) {
|
||||
next;
|
||||
}
|
||||
$manageChannelAccess.="<option value=\"$id\">$name</option>";
|
||||
}
|
||||
$manageChannelAccess.="</select>";
|
||||
$manageChannelAccess.=enumerateUsers($aConnection, $session)." ";
|
||||
$manageChannelAccess.=enumerateChannels($aConnection)."<br />";
|
||||
$manageChannelAccess.="<input name=\"grant\" type=\"submit\" value=\"Grant access\" /> ";
|
||||
$manageChannelAccess.="<input name=\"revoke\" type=\"submit\" value=\"Revoke access\" />";
|
||||
@ -268,9 +303,18 @@ sub handlePath {
|
||||
$addUser.="<input name=\"operator\" type=\"checkbox\" />Operator<br />";
|
||||
$addUser.="<input type=\"submit\" value=\"Add\" />";
|
||||
$addUser.="</form>";
|
||||
|
||||
$updateUser.="<h3>Update user</h3>";
|
||||
$updateUser.="<form action=\"update_user_action\" method=\"POST\">";
|
||||
$updateUser.=enumerateUsers($aConnection, $session)."<br />";
|
||||
$updateUser.="<input name=\"operator\" type=\"checkbox\" />Operator<br />";
|
||||
$updateUser.="<input name=\"update\" type=\"submit\" value=\"Update\" /> ";
|
||||
$updateUser.="<input name=\"delete\" type=\"submit\" value=\"Delete\" />";
|
||||
$updateUser.="</form>";
|
||||
}
|
||||
|
||||
my $addServer = "";
|
||||
my $updateServer = "";
|
||||
if($privileges==2) {
|
||||
$addServer.="<h3>Add server</h3>";
|
||||
$addServer.="<form action=\"add_server_action\" method=\"POST\">";
|
||||
@ -279,6 +323,12 @@ sub handlePath {
|
||||
$addServer.="<input name=\"port\" type=\"number\" placeholder=\"Server port (optional)\" /><br />";
|
||||
$addServer.="<input type=\"submit\" value=\"Add\" />";
|
||||
$addServer.="</form>";
|
||||
$updateServer.="<h3>Update server</h3>";
|
||||
$updateServer.="<form action=\"update_server_action\" method=\"POST\">";
|
||||
$updateServer.=enumerateServers($aConnection)."<br />";
|
||||
$updateServer.="<input name=\"enabled\" type=\"checkbox\" checked=\"true\" />Enabled<br />";
|
||||
$updateServer.="<input type=\"submit\" value=\"Update\" />";
|
||||
$updateServer.="</form>";
|
||||
}
|
||||
|
||||
my $addChannel = "";
|
||||
@ -304,11 +354,21 @@ sub handlePath {
|
||||
$updateChannel.="<form action=\"update_channel_action\" method=\"POST\">";
|
||||
$updateChannel.=enumerateChannels($aConnection)."<br />";
|
||||
$updateChannel.="<input name=\"public\" type=\"checkbox\" />Public<br />";
|
||||
$updateChannel.="<input name=\"enabled\" type=\"checkbox\" checked=\"true\" />Enabled<br />";
|
||||
$updateChannel.="<input type=\"submit\" value=\"Update\" />";
|
||||
$updateChannel.="</form>";
|
||||
}
|
||||
|
||||
frontend::sendTemplate("templates/panel.html", $aClient, {"username"=>$session->{"username"}, "manageChannelAccess"=>$manageChannelAccess, "addUser"=>$addUser, "addServer"=>$addServer, "addChannel"=>$addChannel, "updateChannel"=>$updateChannel});
|
||||
frontend::sendTemplate("templates/panel.html", $aClient, {
|
||||
"username"=>$session->{"username"},
|
||||
"manageChannelAccess"=>$manageChannelAccess,
|
||||
"addUser"=>$addUser,
|
||||
"updateUser"=>$updateUser,
|
||||
"addServer"=>$addServer,
|
||||
"updateServer"=>$updateServer,
|
||||
"addChannel"=>$addChannel,
|
||||
"updateChannel"=>$updateChannel
|
||||
});
|
||||
return 1;
|
||||
}
|
||||
when("/change_password_action") {
|
||||
@ -355,6 +415,35 @@ sub handlePath {
|
||||
|
||||
return 1;
|
||||
}
|
||||
when("/delete_account_action") {
|
||||
if(!defined($aRequest->{"cookies"}{"session"}) || !frontend_session::isValidSession($aRequest->{"cookies"}{"session"})) {
|
||||
frontend::redirect($aClient, "/");
|
||||
return 1;
|
||||
}
|
||||
my $session = $frontend_session::sessions{$aRequest->{"cookies"}{"session"}};
|
||||
my %parameters = frontend::parsePathParameters($aRequest->{"content"});
|
||||
if(!defined($parameters{"password"})) {
|
||||
frontend::sendBadRequest($aClient, "Password parameter required");
|
||||
return 1;
|
||||
}
|
||||
my $query = $aConnection->prepare(qq(select id, password from users where name=?;));
|
||||
$query->execute($session->{"username"});
|
||||
my @row = $query->fetchrow_array();
|
||||
my $id = $row[0];
|
||||
my $password = $row[1];
|
||||
if($id==0) {
|
||||
frontend::sendBadRequest($aClient, "Cannot delete user with ID 0 (admin)");
|
||||
return 1;
|
||||
}
|
||||
if($password ne Digest::SHA::sha256_hex($parameters{"password"})) {
|
||||
frontend::sendBadRequest($aClient, "Wrong password");
|
||||
return 1;
|
||||
}
|
||||
frontend::deleteUser($id, $aConnection);
|
||||
frontend_session::deleteSession($aRequest->{"cookies"}{"session"});
|
||||
frontend::redirect($aClient, "/account_deleted.html");
|
||||
return 1;
|
||||
}
|
||||
when("/manage_access_action") {
|
||||
if(!verifyRequestPrivileges($aRequest, $aClient, 1, $aConnection)) {
|
||||
return 1;
|
||||
@ -461,6 +550,39 @@ sub handlePath {
|
||||
frontend::redirect($aClient, "/user_added.html");
|
||||
return 1;
|
||||
}
|
||||
when("/update_user_action") {
|
||||
if(!verifyRequestPrivileges($aRequest, $aClient, 1, $aConnection)) {
|
||||
return 1;
|
||||
}
|
||||
my %parameters = frontend::parsePathParameters($aRequest->{"content"});
|
||||
if(!defined($parameters{"user"}) || length($parameters{"user"})==0) {
|
||||
frontend::sendBadRequest($aClient, "User required");
|
||||
return 1;
|
||||
}
|
||||
my $query = $aConnection->prepare(qq(select privileges from users where id=?;));
|
||||
$query->execute($parameters{"user"});
|
||||
my @row = $query->fetchrow_array();
|
||||
if(scalar(@row)==0) {
|
||||
frontend::sendBadRequest($aClient, "User with ID $parameters{'user'} doesn't exist");
|
||||
return 1;
|
||||
}
|
||||
if($row[0]>1 && !verifyRequestPrivileges($aRequest, $aClient, 2, $aConnection)) {
|
||||
return 1;
|
||||
}
|
||||
if(defined($parameters{"update"})) {
|
||||
$query = $aConnection->prepare(qq(update users set privileges=? where id=?;));
|
||||
$query->execute(defined($parameters{"operator"})?1:0, $parameters{"user"});
|
||||
}
|
||||
elsif(defined($parameters{"delete"})) {
|
||||
frontend::deleteUser($parameters{"user"}, $aConnection);
|
||||
}
|
||||
else {
|
||||
frontend::sendBadRequest($aClient, "Action (update or delete) required");
|
||||
return 1;
|
||||
}
|
||||
frontend::redirect($aClient, "/user_updated.html");
|
||||
return 1;
|
||||
}
|
||||
when("/add_server_action") {
|
||||
if(!verifyRequestPrivileges($aRequest, $aClient, 2, $aConnection)) {
|
||||
return 1;
|
||||
@ -495,12 +617,53 @@ sub handlePath {
|
||||
$lastID = $row[0]+1;
|
||||
}
|
||||
|
||||
$query = $aConnection->prepare(qq(insert into servers values($lastID, ?, ?, ?);));
|
||||
$query = $aConnection->prepare(qq(insert into servers values($lastID, ?, ?, ?, 1);));
|
||||
$query->execute($parameters{"name"}, $parameters{"address"}, $port);
|
||||
frontend::redirect($aClient, "/server_added.html");
|
||||
logger::createLogger($parameters{"name"}, $parameters{"address"}, $port, ());
|
||||
return 1;
|
||||
}
|
||||
when("/update_server_action") {
|
||||
if(!verifyRequestPrivileges($aRequest, $aClient, 2, $aConnection)) {
|
||||
return 1;
|
||||
}
|
||||
my %parameters = frontend::parsePathParameters($aRequest->{"content"});
|
||||
if(!defined($parameters{"server"}) || length($parameters{"server"})==0) {
|
||||
frontend::sendBadRequest($aClient, "Server required");
|
||||
return 1;
|
||||
}
|
||||
my $query = $aConnection->prepare(qq(select name, host, port, enabled from servers where id=?;));
|
||||
$query->execute($parameters{"server"});
|
||||
my @row = $query->fetchrow_array();
|
||||
if(scalar(@row)==0) {
|
||||
frontend::sendBadRequest($aClient, "Server with ID $parameters{'server'} doesn't exist");
|
||||
return 1;
|
||||
}
|
||||
my $server = $row[0];
|
||||
my $serverEnabled = $row[3];
|
||||
if(defined($parameters{"enabled"}) && !$serverEnabled) {
|
||||
my $host = $row[1];
|
||||
my $port = $row[2];
|
||||
$query = $aConnection->prepare(qq(select name, enabled from channels where server_id=?;));
|
||||
$query->execute($parameters{"server"});
|
||||
my @channels;
|
||||
while(@row = $query->fetchrow_array()) {
|
||||
if(!$row[1]) {
|
||||
next;
|
||||
}
|
||||
push(@channels, $row[0]);
|
||||
}
|
||||
logger::createLogger($server, $host, $port, \@channels);
|
||||
}
|
||||
elsif($serverEnabled) {
|
||||
my $actionQueue = logger::getActionQueueByServerName($server);
|
||||
push(@$actionQueue, "QUIT");
|
||||
}
|
||||
$query = $aConnection->prepare(qq(update servers set enabled=? where id=?;));
|
||||
$query->execute(defined($parameters{"enabled"})?1:0, $parameters{"server"});
|
||||
frontend::redirect($aClient, "/server_updated.html");
|
||||
return 1;
|
||||
}
|
||||
when("/add_channel_action") {
|
||||
if(!verifyRequestPrivileges($aRequest, $aClient, 2, $aConnection)) {
|
||||
return 1;
|
||||
@ -541,7 +704,7 @@ sub handlePath {
|
||||
$lastID = $row[0]+1;
|
||||
}
|
||||
|
||||
$query = $aConnection->prepare(qq(insert into channels values($lastID, ?, ?, ?);));
|
||||
$query = $aConnection->prepare(qq(insert into channels values($lastID, ?, ?, ?, 1);));
|
||||
$query->execute($parameters{"server"}, $parameters{"channel"}, defined($parameters{"public"})?1:0);
|
||||
my $actionQueue = logger::getActionQueueByServerName($serverName);
|
||||
push(@$actionQueue, "JOIN", $parameters{"channel"});
|
||||
@ -558,15 +721,27 @@ sub handlePath {
|
||||
frontend::sendBadRequest($aClient, "Channel required");
|
||||
return 1;
|
||||
}
|
||||
my $query = $aConnection->prepare(qq(select id from channels where id=?;));
|
||||
my $query = $aConnection->prepare(qq(select name, server_id, enabled from channels where id=?;));
|
||||
$query->execute($parameters{"channel"});
|
||||
my @row = $query->fetchrow_array();
|
||||
if(scalar(@row)==0) {
|
||||
frontend::sendBadRequest($aClient, "Channel with ID $parameters{'channel'} doesn't exist");
|
||||
return 1;
|
||||
}
|
||||
$query = $aConnection->prepare(qq(update channels set public=? where id=?;));
|
||||
$query->execute(defined($parameters{"public"})?1:0, $parameters{"channel"});
|
||||
my $channel = $row[0];
|
||||
my $channelEnabled = $row[2];
|
||||
$query = $aConnection->prepare(qq(select name from servers where id=?;));
|
||||
$query->execute($row[1]);
|
||||
@row = $query->fetchrow_array();
|
||||
my $actionQueue = logger::getActionQueueByServerName($row[0]);
|
||||
if(defined($parameters{"enabled"}) && !$channelEnabled) {
|
||||
push(@$actionQueue, "JOIN", $channel);
|
||||
}
|
||||
elsif($channelEnabled) {
|
||||
push(@$actionQueue, "PART", $channel);
|
||||
}
|
||||
$query = $aConnection->prepare(qq(update channels set public=?, enabled=? where id=?;));
|
||||
$query->execute(defined($parameters{"public"})?1:0, defined($parameters{"enabled"})?1:0, $parameters{"channel"});
|
||||
frontend::redirect($aClient, "/channel_updated.html");
|
||||
return 1;
|
||||
}
|
||||
|
@ -22,9 +22,12 @@ use strict;
|
||||
use warnings;
|
||||
|
||||
our %sessions;
|
||||
my %sessionAccess;
|
||||
|
||||
sub newSessionToken {
|
||||
return Digest::SHA::sha256_hex(sprintf("%x", rand(0xFFFFFFFF)));
|
||||
my $session = Digest::SHA::sha256_hex(sprintf("%x", rand(0xFFFFFFFF)));
|
||||
$sessionAccess{$session} = time();
|
||||
return $session;
|
||||
}
|
||||
|
||||
sub deleteSession {
|
||||
@ -32,13 +35,23 @@ sub deleteSession {
|
||||
|
||||
if(isValidSession($aSession)) {
|
||||
delete $sessions{$aSession};
|
||||
delete $sessionAccess{$aSession};
|
||||
}
|
||||
}
|
||||
|
||||
sub isValidSession {
|
||||
my $aSession = $_[0];
|
||||
|
||||
return defined($sessions{$aSession});
|
||||
foreach my $key (keys(%sessionAccess)) {
|
||||
if(time()-$sessionAccess{$key}>7*24*3600) {
|
||||
deleteSession($key);
|
||||
}
|
||||
}
|
||||
if(defined($sessions{$aSession})) {
|
||||
$sessionAccess{$aSession} = time();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
1;
|
||||
|
100
logger.pm
100
logger.pm
@ -308,6 +308,36 @@ sub handlePart {
|
||||
$aLogFiles->{$aCommand->[1]}{"file"}->flush();
|
||||
}
|
||||
|
||||
sub handleNick {
|
||||
my $aCommand = $_[0];
|
||||
my $aServerName = $_[1];
|
||||
my $aLogFiles = $_[2];
|
||||
|
||||
my $aCommandLength = scalar(@$aCommand);
|
||||
if($aCommandLength!=3) {
|
||||
print("[error] Encountered invalid NICK command (3 arguments expected, $aCommandLength provided)\n");
|
||||
return;
|
||||
}
|
||||
my $username = getUsernameFromHost($aCommand->[2]);
|
||||
foreach my $channel (keys(%$aLogFiles)) {
|
||||
my $found = 0;
|
||||
my $i = 0;
|
||||
foreach $i (0..scalar(@{$aLogFiles->{$channel}{"names"}})-1) {
|
||||
my $name = \$aLogFiles->{$channel}{"names"}[$i];
|
||||
if($$name eq $username) {
|
||||
$found = 1;
|
||||
$$name = $aCommand->[1];
|
||||
last;
|
||||
}
|
||||
}
|
||||
if(!$found || !prepareLogFile($aLogFiles, $aServerName, $channel)) {
|
||||
next;
|
||||
}
|
||||
$aLogFiles->{$channel}{"file"}->print(sprintf("(%s) %s is now known as %s\n", localtime->strftime("%H:%M:%S"), $username, $aCommand->[1]));
|
||||
$aLogFiles->{$channel}{"file"}->flush();
|
||||
}
|
||||
}
|
||||
|
||||
sub joinChannel {
|
||||
my $aStream = $_[0];
|
||||
my $aChannel = $_[1];
|
||||
@ -324,6 +354,19 @@ sub joinChannels {
|
||||
}
|
||||
}
|
||||
|
||||
sub partChannel {
|
||||
my $aStream = $_[0];
|
||||
my $aChannel = $_[1];
|
||||
|
||||
$aStream->send(sprintf("PART %s\r\n", $aChannel));
|
||||
}
|
||||
|
||||
sub quitFromServer {
|
||||
my $aStream = $_[0];
|
||||
|
||||
$aStream->send("QUIT\r\n");
|
||||
}
|
||||
|
||||
sub handleNames {
|
||||
my $aCommand = $_[0];
|
||||
my $aChannels = $_[1];
|
||||
@ -341,6 +384,30 @@ sub handleNames {
|
||||
push(@{$aLogFiles->{$aCommand->[3]}{"names"}}, @names);
|
||||
}
|
||||
|
||||
sub handleTopic {
|
||||
my $aCommand = $_[0];
|
||||
my $aServerName = $_[1];
|
||||
my $aLogFiles = $_[2];
|
||||
my $aChangedByUser = $_[3];
|
||||
|
||||
my $aCommandLength = scalar(@$aCommand);
|
||||
if($aCommandLength!=5) {
|
||||
print("[error] Encountered invalid TOPIC command (5 arguments expected, $aCommandLength provided)\n");
|
||||
return;
|
||||
}
|
||||
if(!prepareLogFile($aLogFiles, $aServerName, $aCommand->[2])) {
|
||||
return;
|
||||
}
|
||||
if($aChangedByUser) {
|
||||
my $username = getUsernameFromHost($aCommand->[4]);
|
||||
$aLogFiles->{$aCommand->[2]}{"file"}->print(sprintf("(%s) %s changed topic for channel %s to: %s\n", localtime->strftime("%H:%M:%S"), $username, $aCommand->[2], $aCommand->[3]));
|
||||
}
|
||||
else {
|
||||
$aLogFiles->{$aCommand->[2]}{"file"}->print(sprintf("(%s) Topic for channel %s: %s\n", localtime->strftime("%H:%M:%S"), $aCommand->[2], $aCommand->[3]));
|
||||
}
|
||||
$aLogFiles->{$aCommand->[2]}{"file"}->flush();
|
||||
}
|
||||
|
||||
our @connections :shared;
|
||||
our $running :shared = 1;
|
||||
|
||||
@ -352,17 +419,21 @@ sub connectionWorker {
|
||||
|
||||
my $buffer = "";
|
||||
my @actionQueue :shared;
|
||||
my $running = 1;
|
||||
my @connection :shared = ($aServerName, \@actionQueue);
|
||||
push(@connections, \@connection);
|
||||
my %logFiles;
|
||||
while($running) {
|
||||
my $stream = connectToServer($aHost, $aPort, $aServerName);
|
||||
my $streamSelect = IO::Select->new($stream);
|
||||
while(!eof($stream)) {
|
||||
while(!eof($stream) && $running) {
|
||||
if(scalar(@actionQueue)>0) {
|
||||
given($actionQueue[0]) {
|
||||
when("JOIN") {
|
||||
joinChannel($stream, $actionQueue[1]);
|
||||
when("JOIN") { joinChannel($stream, $actionQueue[1]); }
|
||||
when("PART") { partChannel($stream, $actionQueue[1]); }
|
||||
when("QUIT") {
|
||||
quitFromServer($stream);
|
||||
$running = 0;
|
||||
}
|
||||
}
|
||||
@actionQueue = ();
|
||||
@ -388,8 +459,11 @@ sub connectionWorker {
|
||||
when("JOIN") { handleJoin(\@command, $aServerName, \%logFiles); }
|
||||
when("QUIT") { handleQuit(\@command, $aServerName, \%logFiles); }
|
||||
when("PART") { handlePart(\@command, $aServerName, \%logFiles); }
|
||||
when("NICK") { handleNick(\@command, $aServerName, \%logFiles); }
|
||||
when("TOPIC") { handleTopic(\@command, $aServerName, \%logFiles, 1); }
|
||||
when("376") { joinChannels($stream, $aChannels); } # end of MOTD
|
||||
when("353") { handleNames(\@command, $aChannels, \%logFiles); } # NAMES reply
|
||||
when("332") { handleTopic(\@command, $aServerName, \%logFiles, 0); } # TOPIC reply
|
||||
}
|
||||
($line, $remaining) = readLineFromBuffer($buffer);
|
||||
$buffer = $remaining;
|
||||
@ -397,6 +471,12 @@ sub connectionWorker {
|
||||
}
|
||||
close($stream);
|
||||
}
|
||||
foreach my $i (0..scalar(@connections)-1) {
|
||||
if($connections[$i][0] eq $aServerName) {
|
||||
$connections[$i][0] = "";
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub createLogger {
|
||||
@ -426,12 +506,20 @@ while(my @row = $query->fetchrow_array()) {
|
||||
my $name = $row[1];
|
||||
my $host = $row[2];
|
||||
my $port = $row[3];
|
||||
my $enabled = $row[4];
|
||||
|
||||
$query = $db->prepare(qq(select name from channels where server_id=$id;));
|
||||
$query->execute();
|
||||
if(!$enabled) {
|
||||
next;
|
||||
}
|
||||
my $channelQuery = $db->prepare(qq(select name, enabled from channels where server_id=$id;));
|
||||
$channelQuery->execute();
|
||||
my @channels;
|
||||
while(my @channelsRow = $query->fetchrow_array()) {
|
||||
while(my @channelsRow = $channelQuery->fetchrow_array()) {
|
||||
my $name = $channelsRow[0];
|
||||
my $enabled = $channelsRow[1];
|
||||
if(!$enabled) {
|
||||
next;
|
||||
}
|
||||
push(@channels, $name);
|
||||
}
|
||||
createLogger($name, $host, $port, \@channels);
|
||||
|
10
static/account_deleted.html
Normal file
10
static/account_deleted.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Account deleted</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Your account successfully deleted</p>
|
||||
<a href="/">Return to index</a>
|
||||
</body>
|
||||
</html>
|
10
static/server_updated.html
Normal file
10
static/server_updated.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Server updated</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Server successfully updated</p>
|
||||
<a href="/panel">Return to user panel</a>
|
||||
</body>
|
||||
</html>
|
10
static/user_updated.html
Normal file
10
static/user_updated.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>User updated</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>User successfully updated</p>
|
||||
<a href="/panel">Return to user panel</a>
|
||||
</body>
|
||||
</html>
|
@ -7,7 +7,7 @@
|
||||
{{userbar}}
|
||||
<h2>Channel list</h2>
|
||||
<table border>
|
||||
<tr><th>Channel</th><th>Network</th></tr>
|
||||
<tr><th>Channel</th><th>Network</th><th>Status</th></tr>
|
||||
{{publicChannels}}
|
||||
{{privateChannels}}
|
||||
</table>
|
||||
|
@ -12,9 +12,16 @@
|
||||
<input name="newPassword" type="password" placeholder="New password"><br />
|
||||
<input type="submit" value="Change" />
|
||||
</form>
|
||||
<h3>Delete this account</h3>
|
||||
<form action="delete_account_action" method="POST">
|
||||
<input name="password" type="password" placeholder="Password" /><br />
|
||||
<input type="submit" value="Delete (this operation cannot be reverted!)" />
|
||||
</form>
|
||||
{{manageChannelAccess}}
|
||||
{{addUser}}
|
||||
{{updateUser}}
|
||||
{{addServer}}
|
||||
{{updateServer}}
|
||||
{{addChannel}}
|
||||
{{updateChannel}}
|
||||
</body>
|
||||
|
Loading…
x
Reference in New Issue
Block a user