Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support passing authentication as part of URI #36

Merged
merged 2 commits into from
May 30, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ and probing for the correct protocol to use.
```php
$factory->createClient('localhost')->then(
function (Client $client) {
// client connected
// client connected (and authenticated)
},
function (Exception $e) {
// an error occured while trying to connect client
// an error occured while trying to connect (or authenticate) client
}
);
```
Expand All @@ -90,6 +90,27 @@ if your Quassel IRC core is not using the default TCP/IP port `4242`:
$factory->createClient('quassel://localhost:4242');
```

Quassel supports password-based authentication. If you want to create a "normal"
client connection, you're recommended to pass the authentication details as part
of the URI. You can pass the password `h@llo` URL-encoded (percent-encoded) as
part of the URI like this:

```php
$factory->createClient('quassel://user:h%40llo@localhost')->then(
function (Client $client) {
// client sucessfully connected and authenticated
$client->on('data', function ($data) {
// next message to follow would be "SessionInit"
});
}
);
```

Note that if you do not pass the authentication details as part of the URI, then
this method will resolve with a "bare" `Client` right after connecting without
sending any application messages. This can be useful if you need full control
over the message flow, see below for more details.

> This method uses Quassel IRC's probing mechanism for the correct protocol to
use (newer "datastream" protocol or original "legacy" protocol).
Protocol handling will be abstracted away for you, so you don't have to
Expand Down
46 changes: 9 additions & 37 deletions examples/01-channels.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,57 +5,31 @@
use Clue\React\Quassel\Io\Protocol;

require __DIR__ . '/../vendor/autoload.php';

$host = '127.0.0.1';
$user = array();
if (isset($argv[1])) { $host = $argv[1]; }

echo 'Server: ' . $host . PHP_EOL;

echo 'User name: ';
$user['name'] = trim(fgets(STDIN));
$user = trim(fgets(STDIN));

echo 'Password: ';
$user['password'] = trim(fgets(STDIN));
$pass = trim(fgets(STDIN));

$loop = \React\EventLoop\Factory::create();
$factory = new Factory($loop);

$factory->createClient($host)->then(function (Client $client) use ($loop, $user) {
$uri = rawurlencode($user) . ':' . rawurlencode($pass) . '@' . $host;

$factory->createClient($uri)->then(function (Client $client) {
var_dump('CONNECTED');

$await = array();

$client->on('data', function ($message) use ($client, $user, &$await) {
$type = null;
if (is_array($message) && isset($message['MsgType'])) {
$type = $message['MsgType'];
}

if ($type === 'ClientInitAck') {
if (!$message['Configured']) {
var_dump('core not configured yet');
$client->close();
return;
}
var_dump('core ready, now logging in');
$client->writeClientLogin($user['name'], $user['password']);

return;
}
if ($type === 'ClientLoginReject') {
var_dump('Unable to login', $message['Error']);

var_dump('Now closing connection');
$client->close();

return;
}
if ($type === 'ClientLoginAck') {
var_dump('successfully logged in, now waiting for a SessionInit message');

return;
}
if ($type === 'SessionInit') {
$client->on('data', function ($message) use ($client, &$await) {
// session initialized => initialize all networks
if (isset($message['MsgType']) && $message['MsgType'] === 'SessionInit') {
var_dump('session initialized');

foreach ($message['SessionState']['NetworkIds'] as $nid) {
Expand Down Expand Up @@ -104,8 +78,6 @@
$client->on('close', function () {
echo 'Connection closed' . PHP_EOL;
});

$client->writeClientInit();
})->then(null, function ($e) {
echo $e;
});
Expand Down
52 changes: 12 additions & 40 deletions examples/02-chatbot.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,62 +5,36 @@
use Clue\React\Quassel\Io\Protocol;

require __DIR__ . '/../vendor/autoload.php';

$host = '127.0.0.1';
$user = array();
if (isset($argv[1])) { $host = $argv[1]; }

echo 'Server: ' . $host . PHP_EOL;

echo 'User name: ';
$user['name'] = trim(fgets(STDIN));
$user = trim(fgets(STDIN));

echo 'Password: ';
$user['password'] = trim(fgets(STDIN));
$pass = trim(fgets(STDIN));

echo 'Keyword: ';
$user['keyword'] = trim(fgets(STDIN));
$keyword = trim(fgets(STDIN));

if (strlen($user['keyword']) < 3) {
if (strlen($keyword) < 3) {
die('Keyword MUST contain at least 3 characters to avoid excessive spam');
}

$loop = \React\EventLoop\Factory::create();
$factory = new Factory($loop);

$factory->createClient($host)->then(function (Client $client) use ($loop, $user) {
var_dump('CONNECTED');

$client->on('data', function ($message) use ($client, $user, $loop) {
$type = null;
if (is_array($message) && isset($message['MsgType'])) {
$type = $message['MsgType'];
}

if ($type === 'ClientInitAck') {
if (!$message['Configured']) {
var_dump('core not configured yet');
$client->close();
return;
}
var_dump('core ready, now logging in');
$client->writeClientLogin($user['name'], $user['password']);

return;
}
if ($type === 'ClientLoginReject') {
var_dump('Unable to login', $message['Error']);

var_dump('Now closing connection');
$client->close();
$uri = rawurlencode($user) . ':' . rawurlencode($pass) . '@' . $host;

return;
}
if ($type === 'ClientLoginAck') {
var_dump('successfully logged in, now waiting for a SessionInit message');
$factory->createClient($uri)->then(function (Client $client) use ($loop, $keyword) {
var_dump('CONNECTED');

return;
}
if ($type === 'SessionInit') {
$client->on('data', function ($message) use ($client, $keyword, $loop) {
// session initialized
if (isset($message['MsgType']) && $message['MsgType']=== 'SessionInit') {
var_dump('session initialized, now waiting for incoming messages');

// send heartbeat message every 30s to check dropped connection
Expand All @@ -87,7 +61,7 @@
if (isset($message[0]) && $message[0] === Protocol::REQUEST_RPCCALL && $message[1] === '2displayMsg(Message)') {
$data = $message[2];

if (strpos($data['content'], $user['keyword']) !== false) {
if (strpos($data['content'], $keyword) !== false) {
$client->writeBufferInput($data['bufferInfo'], 'Hello from clue/quassel-react :-)');

echo date('Y-m-d H:i:s') . ' Replied to ' . $data['bufferInfo']['name'] . '/' . explode('!', $data['sender'], 2)[0] . ': "' . $data['content'] . '"' . PHP_EOL;
Expand All @@ -99,8 +73,6 @@
$client->on('close', function () {
echo 'Connection closed' . PHP_EOL;
});

$client->writeClientInit();
})->then(null, function ($e) {
echo $e;
});
Expand Down
46 changes: 9 additions & 37 deletions examples/03-pingbot.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,57 +5,31 @@
use Clue\React\Quassel\Io\Protocol;

require __DIR__ . '/../vendor/autoload.php';

$host = '127.0.0.1';
$user = array();
if (isset($argv[1])) { $host = $argv[1]; }

echo 'Server: ' . $host . PHP_EOL;

echo 'User name: ';
$user['name'] = trim(fgets(STDIN));
$user = trim(fgets(STDIN));

echo 'Password: ';
$user['password'] = trim(fgets(STDIN));
$pass = trim(fgets(STDIN));

$loop = \React\EventLoop\Factory::create();
$factory = new Factory($loop);

$factory->createClient($host)->then(function (Client $client) use ($loop, $user) {
$uri = rawurlencode($user) . ':' . rawurlencode($pass) . '@' . $host;

$factory->createClient($uri)->then(function (Client $client) use ($loop) {
var_dump('CONNECTED');

$nicks = array();

$client->on('data', function ($message) use ($client, $user, &$nicks, $loop) {
$type = null;
if (is_array($message) && isset($message['MsgType'])) {
$type = $message['MsgType'];
}

if ($type === 'ClientInitAck') {
if (!$message['Configured']) {
var_dump('core not configured yet');
$client->close();
return;
}
var_dump('core ready, now logging in');
$client->writeClientLogin($user['name'], $user['password']);

return;
}
if ($type === 'ClientLoginReject') {
var_dump('Unable to login', $message['Error']);

var_dump('Now closing connection');
$client->close();

return;
}
if ($type === 'ClientLoginAck') {
var_dump('successfully logged in, now waiting for a SessionInit message');

return;
}
if ($type === 'SessionInit') {
$client->on('data', function ($message) use ($client, &$nicks, $loop) {
// session initialized => initialize all networks
if (isset($message['MsgType']) && $message['MsgType'] === 'SessionInit') {
var_dump('session initialized, now waiting for incoming messages');

foreach ($message['SessionState']['NetworkIds'] as $nid) {
Expand Down Expand Up @@ -136,8 +110,6 @@
$client->on('close', function () {
echo 'Connection closed' . PHP_EOL;
});

$client->writeClientInit();
})->then(null, function ($e) {
echo $e;
});
Expand Down
69 changes: 8 additions & 61 deletions examples/04-connect.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,79 +6,28 @@

require __DIR__ . '/../vendor/autoload.php';

$debug = false;
$host = '127.0.0.1';
$user = array();
if (isset($argv[1])) { $host = $argv[1]; }

echo 'Server: ' . $host . PHP_EOL;

echo 'User name: ';
$user['name'] = trim(fgets(STDIN));
$user = trim(fgets(STDIN));

echo 'Password: ';
$user['password'] = trim(fgets(STDIN));
$pass = trim(fgets(STDIN));

$loop = \React\EventLoop\Factory::create();
$factory = new Factory($loop);

$factory->createClient($host)->then(function (Client $client) use ($loop, $user, $debug) {
var_dump('CONNECTED');

if ($debug) {
$client->on('data', function ($message) {
var_dump($message);
});
}

$client->on('data', function ($message) use ($client, $user, $loop) {
$type = null;
if (is_array($message) && isset($message['MsgType'])) {
$type = $message['MsgType'];
}

if ($type === 'ClientInitAck') {
if (!$message['Configured']) {
var_dump('core not configured yet, you may want to issue a setup call manually');
print_r($message['StorageBackends']);

echo 'Hit enter to set-up server with defaults, otherwise cancel program now';
fgets(STDIN);

$client->writeCoreSetupData($user['name'], $user['password']);

return;
}
var_dump('core ready, now logging in');
$client->writeClientLogin($user['name'], $user['password']);

return;
}
if ($type === 'CoreSetupAck') {
var_dump('core set-up, now logging in');
$client->writeClientLogin($user['name'], $user['password']);
$uri = rawurlencode($user) . ':' . rawurlencode($pass) . '@' . $host;

return;
}
if ($type === 'CoreSetupReject') {
var_dump('Unable to set-up core', $message['Error']);

return;
}
if ($type === 'ClientLoginReject') {
var_dump('Unable to login', $message['Error']);

var_dump('Now closing connection');
$client->close();

return;
}
if ($type === 'ClientLoginAck') {
var_dump('successfully logged in, now waiting for a SessionInit message');
$factory->createClient($uri)->then(function (Client $client) use ($loop) {
var_dump('CONNECTED');

return;
}
if ($type === 'SessionInit') {
$client->on('data', function ($message) use ($client, $loop) {
// session initialized => initialize all networks and buffers
if (isset($message['MsgType']) && $message['MsgType'] === 'SessionInit') {
var_dump('session initialized');

foreach ($message['SessionState']['NetworkIds'] as $nid) {
Expand Down Expand Up @@ -145,8 +94,6 @@
$client->on('close', function () {
echo 'Connection closed' . PHP_EOL;
});

$client->writeClientInit();
})->then(null, function ($e) {
echo $e;
});
Expand Down
Loading