Skip to content

Commit a5d7a8e

Browse files
Merge pull request #64 from neo4j-php/auth_options
Implementing auth options
2 parents 5e1354a + 0c1b003 commit a5d7a8e

File tree

12 files changed

+171
-122
lines changed

12 files changed

+171
-122
lines changed

phpunit.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<directory suffix=".php">src/connection</directory>
1414
<directory suffix=".php">src/PackStream</directory>
1515
<directory suffix=".php">src/protocol</directory>
16+
<directory suffix=".php">src/helpers</directory>
1617
<file>src/Bolt.php</file>
1718
</whitelist>
1819
</filter>

src/Bolt.php

Lines changed: 64 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Bolt;
44

5+
use Bolt\helpers\Auth;
56
use Bolt\error\{
67
ConnectException,
78
PackException,
@@ -26,7 +27,7 @@ final class Bolt
2627
* @var IPacker
2728
*/
2829
private $packer;
29-
30+
3031
/**
3132
* @var IUnpacker
3233
*/
@@ -52,14 +53,9 @@ final class Bolt
5253
*/
5354
private $version;
5455

55-
/**
56-
* @var string
57-
*/
58-
private $scheme = 'basic';
59-
6056
/**
6157
* Print debug info
62-
* @var bool
58+
* @var bool
6359
*/
6460
public static $debug = false;
6561

@@ -89,7 +85,7 @@ public function setProtocolVersions(...$v): Bolt
8985
* @return Bolt
9086
* @throws Exception
9187
*/
92-
public function setPackStreamVersion(int $version = 1)
88+
public function setPackStreamVersion(int $version = 1): Bolt
9389
{
9490
$packerClass = "\\Bolt\\PackStream\\v" . $version . "\\Packer";
9591
if (!class_exists($packerClass)) {
@@ -107,17 +103,7 @@ public function setPackStreamVersion(int $version = 1)
107103
}
108104

109105
/**
110-
* @param string $scheme
111-
* @return Bolt
112-
*/
113-
public function setScheme(string $scheme = 'basic')
114-
{
115-
if (in_array($scheme, ['none', 'basic', 'kerberos']))
116-
$this->scheme = $scheme;
117-
return $this;
118-
}
119-
120-
/**
106+
* Version is available after successful connection with init/hello message
121107
* @return float
122108
*/
123109
public function getProtocolVersion(): float
@@ -195,67 +181,73 @@ private function packProtocolVersions(): string
195181

196182
/**
197183
* Send INIT message
198-
* @version <3
199-
* @param string $name should conform to "Name/Version" https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent
200-
* @param string $user
201-
* @param string $password
202-
* @param array $routing routing::Dictionary(address::String)
203-
<pre>null - the server should not carry out routing
204-
[] - the server should carry out routing
205-
['address' => 'ip:port'] - the server should carry out routing according to the given routing context</pre>
206-
* @param array $metadata Server success response metadata
184+
*
185+
* @param array|string $userAgentOrExtra You can use helpers\Auth to generate required array or use the deprecated approach to fill in $name, $user and $password
186+
* @param string|null $user
187+
* @param string|null $password
188+
* @param array|null|bool $routing
189+
* @param array $metadata
190+
*
207191
* @return bool
208192
* @throws Exception
193+
* @deprecated The usage of $user, $password, $routing and $metadata is deprecated. Please use helpers\Auth to generate an authentication strategy as an array.
194+
*
195+
* @version <3
209196
*/
210-
public function init(string $name, string $user, string $password, array $routing = null, array &$metadata = []): bool
197+
public function init($userAgentOrExtra, string $user = '', string $password = '', $routing = false, array &$metadata = []): bool
211198
{
212-
if (!$this->connection->connect())
213-
return false;
214-
215-
if (!$this->handshake())
216-
return false;
199+
if (is_string($userAgentOrExtra)) {
200+
Auth::$userAgent = $userAgentOrExtra;
201+
$userAgentOrExtra = Auth::basic($user, $password);
202+
if ($routing !== false)
203+
$userAgentOrExtra['routing'] = $routing;
204+
}
217205

218-
if (self::$debug)
219-
echo 'INIT';
206+
if ($this->connection->connect() && $this->handshake()) {
207+
if (self::$debug)
208+
echo 'INIT';
209+
$metadata = $this->protocol->init($userAgentOrExtra);
210+
return true;
211+
}
220212

221-
$metadata = $this->protocol->init($name, $this->scheme, $user, $password, $routing);
222-
return !empty($metadata);
213+
// I don't think it will reach this point, but otherwise I've to end method with return
214+
throw new Exception('INIT message failed');
223215
}
224216

225217
/**
226218
* Send HELLO message
227-
* @internal INIT alias
228-
* @version >=3
229-
* @param string $name
219+
*
220+
* @param array|string $userAgentOrExtra You can use helpers\Auth to generate required array or use the deprecated approach to fill in $name, $user and $password
230221
* @param string $user
231222
* @param string $password
232-
* @param array $routing routing::Dictionary(address::String)
233-
<pre>null - the server should not carry out routing
234-
[] - the server should carry out routing
235-
['address' => 'ip:port'] - the server should carry out routing according to the given routing context</pre>
236-
* @param array $metadata Server success response metadata
223+
* @param array|null|bool $routing
224+
* @param array $metadata
225+
*
237226
* @return bool
238227
* @throws Exception
228+
* @deprecated The usage of $user, $password, $routing and $metadata is deprecated. Please use helpers\Auth to generate an authentication strategy as an array.
229+
*
230+
* @version >=3
239231
*/
240-
public function hello(string $name, string $user, string $password, array $routing = null, array &$metadata = []): bool
232+
public function hello($userAgentOrExtra, string $user = '', string $password = '', $routing = false, array &$metadata = []): bool
241233
{
242-
return $this->init($name, $user, $password, $routing, $metadata);
234+
return $this->init($userAgentOrExtra, $user, $password, $routing, $metadata);
243235
}
244236

245237
/**
246238
* Send RUN message
247239
* @param string $statement
248240
* @param array $parameters
249241
* @param array $extra extra::Dictionary(bookmarks::List<String>, tx_timeout::Integer, tx_metadata::Dictionary, mode::String, db:String)
250-
<pre>The bookmarks is a list of strings containg some kind of bookmark identification e.g [“neo4j-bookmark-transaction:1”, “neo4j-bookmark-transaction:2”]
251-
The tx_timeout is an integer in that specifies a transaction timeout in ms.
252-
The tx_metadata is a dictionary that can contain some metadata information, mainly used for logging.
253-
The mode specifies what kind of server the RUN message is targeting. For write access use "w" and for read access use "r". Defaults to write access if no mode is sent.
254-
The db specifies the database name for multi-database to select where the transaction takes place. If no db is sent or empty string it implies that it is the default database.</pre>
242+
* <pre>The bookmarks is a list of strings containg some kind of bookmark identification e.g [“neo4j-bookmark-transaction:1”, “neo4j-bookmark-transaction:2”]
243+
* The tx_timeout is an integer in that specifies a transaction timeout in ms.
244+
* The tx_metadata is a dictionary that can contain some metadata information, mainly used for logging.
245+
* The mode specifies what kind of server the RUN message is targeting. For write access use "w" and for read access use "r". Defaults to write access if no mode is sent.
246+
* The db specifies the database name for multi-database to select where the transaction takes place. If no db is sent or empty string it implies that it is the default database.</pre>
255247
* @return array
256248
* @throws Exception
257249
*/
258-
public function run(string $statement, array $parameters = [], array $extra = [])
250+
public function run(string $statement, array $parameters = [], array $extra = []): array
259251
{
260252
if (self::$debug)
261253
echo 'RUN: ' . $statement;
@@ -264,13 +256,13 @@ public function run(string $statement, array $parameters = [], array $extra = []
264256

265257
/**
266258
* Send PULL_ALL message
267-
* @version <4
268259
* @param int $n The n specifies how many records to fetch. n=-1 will fetch all records.
269260
* @param int $qid The qid (query identification) specifies the result of which statement the operation should be carried out. (Explicit Transaction only). qid=-1 can be used to denote the last executed statement and if no ``.
270261
* @return array
271262
* @throws Exception
263+
* @version <4
272264
*/
273-
public function pullAll(int $n = -1, int $qid = -1)
265+
public function pullAll(int $n = -1, int $qid = -1): array
274266
{
275267
if (self::$debug)
276268
echo 'PULL';
@@ -279,27 +271,27 @@ public function pullAll(int $n = -1, int $qid = -1)
279271

280272
/**
281273
* Send PULL message
282-
* @version >=4
283-
* @internal PULL_ALL alias
284274
* @param int $n The n specifies how many records to fetch. n=-1 will fetch all records.
285275
* @param int $qid The qid (query identification) specifies the result of which statement the operation should be carried out. (Explicit Transaction only). qid=-1 can be used to denote the last executed statement and if no ``.
286276
* @return array Array of records. Last array element is success message.
287277
* @throws Exception
278+
* @version >=4
279+
* @internal PULL_ALL alias
288280
*/
289-
public function pull(int $n = -1, int $qid = -1)
281+
public function pull(int $n = -1, int $qid = -1): array
290282
{
291283
return $this->pullAll($n, $qid);
292284
}
293285

294286
/**
295287
* Send DISCARD_ALL message
296-
* @version <4
297288
* @param int $n The n specifies how many records to throw away. n=-1 will throw away all records.
298289
* @param int $qid The qid (query identification) specifies the result of which statement the operation should be carried out. (Explicit Transaction only). qid=-1 can be used to denote the last executed statement and if no ``.
299290
* @return bool
300291
* @throws Exception
292+
* @version <4
301293
*/
302-
public function discardAll(int $n = -1, int $qid = -1)
294+
public function discardAll(int $n = -1, int $qid = -1): bool
303295
{
304296
if (self::$debug)
305297
echo 'DISCARD';
@@ -308,12 +300,12 @@ public function discardAll(int $n = -1, int $qid = -1)
308300

309301
/**
310302
* Send DISCARD message
311-
* @version >=4
312-
* @internal DISCARD_ALL alias
313303
* @param int $n The n specifies how many records to throw away. n=-1 will throw away all records.
314304
* @param int $qid The qid (query identification) specifies the result of which statement the operation should be carried out. (Explicit Transaction only). qid=-1 can be used to denote the last executed statement and if no ``.
315305
* @return bool
316306
* @throws Exception
307+
* @version >=4
308+
* @internal DISCARD_ALL alias
317309
*/
318310
public function discard(int $n = -1, int $qid = -1): bool
319311
{
@@ -322,15 +314,15 @@ public function discard(int $n = -1, int $qid = -1): bool
322314

323315
/**
324316
* Send BEGIN message
325-
* @version >=3
326317
* @param array $extra extra::Dictionary(bookmarks::List<String>, tx_timeout::Integer, tx_metadata::Dictionary, mode::String, db:String)
327-
<pre>The bookmarks is a list of strings containg some kind of bookmark identification e.g [“neo4j-bookmark-transaction:1”, “neo4j-bookmark-transaction:2”]
328-
The tx_timeout is an integer in that specifies a transaction timeout in ms.
329-
The tx_metadata is a dictionary that can contain some metadata information, mainly used for logging.
330-
The mode specifies what kind of server the RUN message is targeting. For write access use "w" and for read access use "r". Defaults to write access if no mode is sent.
331-
The db specifies the database name for multi-database to select where the transaction takes place. If no db is sent or empty string it implies that it is the default database.</pre>
318+
* <pre>The bookmarks is a list of strings containg some kind of bookmark identification e.g [“neo4j-bookmark-transaction:1”, “neo4j-bookmark-transaction:2”]
319+
* The tx_timeout is an integer in that specifies a transaction timeout in ms.
320+
* The tx_metadata is a dictionary that can contain some metadata information, mainly used for logging.
321+
* The mode specifies what kind of server the RUN message is targeting. For write access use "w" and for read access use "r". Defaults to write access if no mode is sent.
322+
* The db specifies the database name for multi-database to select where the transaction takes place. If no db is sent or empty string it implies that it is the default database.</pre>
332323
* @return bool
333324
* @throws Exception
325+
* @version >=3
334326
*/
335327
public function begin(array $extra = []): bool
336328
{
@@ -341,9 +333,9 @@ public function begin(array $extra = []): bool
341333

342334
/**
343335
* Send COMMIT message
344-
* @version >=3
345336
* @return bool
346337
* @throws Exception
338+
* @version >=3
347339
*/
348340
public function commit(): bool
349341
{
@@ -354,9 +346,9 @@ public function commit(): bool
354346

355347
/**
356348
* Send ROLLBACK message
357-
* @version >=3
358349
* @return bool
359350
* @throws Exception
351+
* @version >=3
360352
*/
361353
public function rollback(): bool
362354
{
@@ -379,11 +371,11 @@ public function reset(): bool
379371

380372
/**
381373
* Send ROUTE message to instruct the server to return the current routing table.
382-
* @version >=4.3 In previous versions there was no explicit message for this and a procedure had to be invoked using Cypher through the RUN and PULL messages.
383374
* @param array|null $routing
384375
* @param array $bookmarks
385376
* @param array|string|null $extra
386377
* @return array|null
378+
* @version >=4.3 In previous versions there was no explicit message for this and a procedure had to be invoked using Cypher through the RUN and PULL messages.
387379
*/
388380
public function route(?array $routing = null, array $bookmarks = [], $extra = null): ?array
389381
{

src/helpers/Auth.php

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
namespace Bolt\helpers;
4+
5+
/**
6+
* Class Auth
7+
* Helper to generate array of extra parameters for INIT/HELLO message
8+
*
9+
* @author Michal Stefanak
10+
* @link https://github.com/neo4j-php/Bolt
11+
* @package Bolt\helpers
12+
*/
13+
class Auth
14+
{
15+
/**
16+
* @var string
17+
*/
18+
public static $userAgent = 'bolt-php';
19+
20+
/**
21+
* None authorization
22+
* @return array
23+
*/
24+
public static function none(): array
25+
{
26+
return [
27+
'user_agent' => self::$userAgent,
28+
'scheme' => 'none'
29+
];
30+
}
31+
32+
/**
33+
* Basic authorization with username and password
34+
* @param string $username
35+
* @param string $password
36+
* @return array
37+
*/
38+
public static function basic(string $username, string $password): array
39+
{
40+
return [
41+
'user_agent' => self::$userAgent,
42+
'scheme' => 'basic',
43+
'principal' => $username,
44+
'credentials' => $password
45+
];
46+
}
47+
48+
/**
49+
* OIDC authorization with token
50+
* @param string $token
51+
* @return array
52+
*/
53+
public static function bearer(string $token): array
54+
{
55+
return [
56+
'user_agent' => self::$userAgent,
57+
'scheme' => 'bearer',
58+
'credentials' => $token
59+
];
60+
}
61+
}

0 commit comments

Comments
 (0)