Skip to content

Commit

Permalink
Implemented ban list
Browse files Browse the repository at this point in the history
  • Loading branch information
PeeHaa committed Mar 19, 2016
1 parent b371d6b commit 1ab47bd
Show file tree
Hide file tree
Showing 15 changed files with 241 additions and 14 deletions.
10 changes: 8 additions & 2 deletions cli/run.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Auryn\Injector;
use Room11\Jeeves\Chat\Command\Factory as CommandFactory;
use Room11\Jeeves\Chat\Plugin\Admin as AdminPlugin;
use Room11\Jeeves\Chat\Plugin\Ban as BanPlugin;
use Room11\Jeeves\Chat\Plugin\CodeFormat as CodeFormatPlugin;
use Room11\Jeeves\Chat\Plugin\Collection as PluginCollection;
use Room11\Jeeves\Chat\Plugin\Canon as CanonPlugin;
Expand All @@ -32,6 +33,7 @@
use Room11\Jeeves\OpenId\Client;
use Room11\Jeeves\OpenId\EmailAddress;
use Room11\Jeeves\OpenId\Password;
use Room11\Jeeves\Storage\Ban;
use Room11\Jeeves\WebSocket\Handler;
use Symfony\Component\Yaml\Yaml;

Expand Down Expand Up @@ -80,11 +82,16 @@
});

$injector->alias("Room11\Jeeves\Storage\Admin", $config["storage"]["admin"]);
$injector->alias("Room11\Jeeves\Storage\Ban", $config["storage"]["ban"]);
//$injector->share($config["storage"]["admin"]);
$injector->define("Room11\Jeeves\Storage\Admin", [":dataFile" => __DIR__ . "/../data/admins.json"]);
$injector->define("Room11\Jeeves\Storage\Ban", [":dataFile" => __DIR__ . "/../data/bans.json"]);
$injector->delegate(PluginCollection::class, function () use ($injector) {
$collection = new PluginCollection($injector->make(CommandFactory::class));
$collection = new PluginCollection($injector->make(CommandFactory::class), $injector->make(Ban::class));

$plugins = [
AdminPlugin::class,
BanPlugin::class,
VersionPlugin::class,
UrbanPlugin::class,
WikipediaPlugin::class,
Expand All @@ -98,7 +105,6 @@
CanonPlugin::class,
ManPlugin::class,
RegexPlugin::class,
AdminPlugin::class,
];

foreach ($plugins as $plugin) {
Expand Down
1 change: 1 addition & 0 deletions config/config.sample.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ logging:

storage:
admin: Room11\Jeeves\Storage\File\Admin
ban: Room11\Jeeves\Storage\File\Ban
2 changes: 1 addition & 1 deletion src/Chat/Message/DeleteMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Room11\Jeeves\Chat\Message;

class DeleteMessage implements Message
class DeleteMessage implements Message, UserMessage
{
private $id;

Expand Down
2 changes: 1 addition & 1 deletion src/Chat/Message/EditMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Room11\Jeeves\Chat\Message;

class EditMessage implements Message
class EditMessage implements Message, UserMessage
{
private $id;

Expand Down
2 changes: 1 addition & 1 deletion src/Chat/Message/MentionMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Room11\Jeeves\Chat\Message;

class MentionMessage implements Message
class MentionMessage implements Message, UserMessage
{
private $id;

Expand Down
2 changes: 1 addition & 1 deletion src/Chat/Message/NewMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Room11\Jeeves\Chat\Message;

class NewMessage implements Message
class NewMessage implements Message, UserMessage
{
private $id;

Expand Down
2 changes: 1 addition & 1 deletion src/Chat/Message/RoomEdit.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Room11\Jeeves\Chat\Message;

class RoomEdit implements Message
class RoomEdit implements Message, UserMessage
{
private $actionId;

Expand Down
2 changes: 1 addition & 1 deletion src/Chat/Message/UserEnter.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Room11\Jeeves\Chat\Message;

class UserEnter implements Message
class UserEnter implements Message, UserMessage
{
private $actionId;

Expand Down
2 changes: 1 addition & 1 deletion src/Chat/Message/UserLeave.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Room11\Jeeves\Chat\Message;

class UserLeave implements Message
class UserLeave implements Message, UserMessage
{
private $actionId;

Expand Down
7 changes: 7 additions & 0 deletions src/Chat/Message/UserMessage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php declare(strict_types=1);

namespace Room11\Jeeves\Chat\Message;

interface UserMessage {
public function getUserId(): int;
}
11 changes: 7 additions & 4 deletions src/Chat/Plugin/Admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,14 @@ private function getList(): \Generator {
return;
}

$userData = yield from $this->getUserData($userIds);
$list = implode(", ", array_map(function($profile) {
return $profile["username"];
}, yield from $this->getUserData($userIds)));

yield from $this->chatClient->postMessage(implode(", ", array_map(function($profile) {
return sprintf("[%s](%s)", $profile["username"], $profile["profile"]);
}, $userData)));
yield from $this->chatClient->postMessage($list);

// max length is 500
//yield new Pause(2000);
}

private function add(int $userId): \Generator {
Expand Down
86 changes: 86 additions & 0 deletions src/Chat/Plugin/Ban.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php declare(strict_types=1);

namespace Room11\Jeeves\Chat\Plugin;

use Room11\Jeeves\Chat\Client\ChatClient;
use Room11\Jeeves\Storage\Admin as AdminStorage;
use Room11\Jeeves\Storage\Ban as Storage;
use Room11\Jeeves\Chat\Command\Command;
use Room11\Jeeves\Chat\Command\Message;

class Ban implements Plugin
{
const COMMANDS = ["ban", "unban"];

private $chatClient;

private $admin;

private $storage;

public function __construct(ChatClient $chatClient, AdminStorage $admin, Storage $storage) {
$this->chatClient = $chatClient;
$this->admin = $admin;
$this->storage = $storage;
}

public function handle(Message $message): \Generator {
if (!$this->validMessage($message)) {
return;
}

yield from $this->execute($message);
}

private function validMessage(Message $message): bool {
return $message instanceof Command
&& in_array($message->getCommand(), self::COMMANDS, true)
&& $message->getParameters();
}

private function execute(Message $message): \Generator {
if (!yield from $this->admin->isAdmin($message->getMessage()->getUserId())) {
yield from $this->chatClient->postMessage(
sprintf(":%d I'm sorry Dave, I'm afraid I can't do that", $message->getOrigin())
);

return;
}

if ($message->getCommand() === "ban" && $message->getParameters()[0] === 'list') {
yield from $this->list();
} elseif ($message->getCommand() === "ban") {
yield from $this->add((int)$message->getParameters()[0], $message->getParameters()[1]);
} elseif ($message->getCommand() === "unban") {
yield from $this->remove((int) $message->getParameters()[0]);
}
}

private function list(): \Generator
{
$bans = yield from $this->storage->getAll();

if (!$bans) {
yield from $this->chatClient->postMessage("No users are currently on the naughty list.");
return;
}

$list = implode(", ", array_map(function($expiration, $userId) {
return sprintf("%s (%s)", $userId, $expiration);
}, $bans, array_keys($bans)));

yield from $this->chatClient->postMessage($list);
}

private function add(int $userId, string $duration): \Generator {
yield from $this->storage->add($userId, $duration);

yield from $this->chatClient->postMessage("User is banned.");
}

private function remove(int $userId): \Generator {
yield from $this->storage->remove($userId);

yield from $this->chatClient->postMessage("User is unbanned.");
}
}
14 changes: 13 additions & 1 deletion src/Chat/Plugin/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,22 @@
namespace Room11\Jeeves\Chat\Plugin;

use Room11\Jeeves\Chat\Command\Factory as CommandFactory;
use Room11\Jeeves\Storage\Ban as BanList;
use Room11\Jeeves\Chat\Message\Message;
use Room11\Jeeves\Chat\Message\UserMessage;

class Collection
{
private $commandFactory;

private $banList;

private $plugins = [];

public function __construct(CommandFactory $commandFactory)
public function __construct(CommandFactory $commandFactory, BanList $banList)
{
$this->commandFactory = $commandFactory;
$this->banList = $banList;
}

public function register(Plugin $plugin): Collection
Expand All @@ -27,6 +32,13 @@ public function handle(Message $message): \Generator
{
$command = $this->commandFactory->build($message);

if ($message instanceof UserMessage) {
if (yield from $this->banList->isBanned($message->getUserId())) {
var_dump('user is banned');
return;
}
}

foreach ($this->plugins as $plugin) {
yield from $plugin->handle($command);
}
Expand Down
14 changes: 14 additions & 0 deletions src/Storage/Ban.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php declare(strict_types=1);

namespace Room11\Jeeves\Storage;

interface Ban
{
public function getAll(): \Generator;

public function isBanned(int $userId): \Generator;

public function add(int $userId, string $duration): \Generator;

public function remove(int $userId): \Generator;
}
98 changes: 98 additions & 0 deletions src/Storage/File/Ban.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php declare(strict_types=1);

namespace Room11\Jeeves\Storage\File;

use Room11\Jeeves\Storage\Ban as BanList;
use function Amp\File\exists;
use function Amp\File\get;
use function Amp\File\put;

class Ban implements BanList
{
private $dataFile;

public function __construct(string $dataFile) {
$this->dataFile = $dataFile;
}

public function getAll(): \Generator {
if (!yield exists($this->dataFile)) {
return [];
}

$banned = yield get($this->dataFile);

return json_decode($banned, true);
}

public function isBanned(int $userId): \Generator {
// inb4 people "testing" banning me
if ($userId === 508666) {
//return false;
}

$banned = yield from $this->getAll();

return array_key_exists($userId, $banned) && $banned[$userId] > (new \DateTime())->format('Y-m-d H:i:s');
}

public function add(int $userId, string $duration): \Generator {
$banned = yield from $this->getAll();

$banned[$userId] = $this->getExpiration($duration)->format('Y-m-d H:i:s');

yield put($this->dataFile, json_encode($banned));
}

// duration string should be in the format of [nd(ays)][nh(ours)][nm(inutes)][ns(econds)]
private function getExpiration(string $duration): \DateTimeImmutable {
$expiration = new \DateTimeImmutable();

if (!preg_match('/^((?P<days>\d+)d)?((?P<hours>\d+)h)?((?P<minutes>\d+)m)?((?P<seconds>\d+)s)?$/', $duration, $matches)) {
return $expiration;
}

$dateInterval = 'P';
$timeDelimiter = 'T';

if (!empty($matches['days'])) {
$dateInterval .= $matches['days'] . 'D';
}

if (!empty($matches['hours'])) {
$dateInterval .= $timeDelimiter . $matches['hours'] . 'D';

$timeDelimiter = '';
}

if (!empty($matches['hours'])) {
$dateInterval .= $timeDelimiter . $matches['hours'] . 'H';

$timeDelimiter = '';
}

if (!empty($matches['minutes'])) {
$dateInterval .= $timeDelimiter . $matches['minutes'] . 'M';

$timeDelimiter = '';
}

if (!empty($matches['seconds'])) {
$dateInterval .= $timeDelimiter . $matches['seconds'] . 'S';
}

return $expiration->add(new \DateInterval($dateInterval));
}

public function remove(int $userId): \Generator {
if (!yield from $this->isBanned($userId)) {
return;
}

$banned = yield from $this->getAll();

unset($banned[$userId]);

yield put($this->dataFile, json_encode($banned));
}
}

0 comments on commit 1ab47bd

Please sign in to comment.