Skip to content

Commit b6627a9

Browse files
committed
setup ssl configurator
1 parent 4d87af9 commit b6627a9

File tree

5 files changed

+87
-55
lines changed

5 files changed

+87
-55
lines changed

src/Bolt/BoltConnectionPool.php

Lines changed: 5 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@
1717
use Bolt\Bolt;
1818
use Bolt\connection\StreamSocket;
1919
use Exception;
20-
use function explode;
21-
use const FILTER_VALIDATE_IP;
22-
use function filter_var;
2320
use Laudis\Neo4j\Common\BoltConnection;
2421
use Laudis\Neo4j\Contracts\AuthenticateInterface;
2522
use Laudis\Neo4j\Contracts\ConnectionInterface;
@@ -28,7 +25,6 @@
2825
use Laudis\Neo4j\Databags\DriverConfiguration;
2926
use Laudis\Neo4j\Databags\SessionConfiguration;
3027
use Laudis\Neo4j\Enum\ConnectionProtocol;
31-
use Laudis\Neo4j\Enum\SslMode;
3228
use Laudis\Neo4j\Neo4j\RoutingTable;
3329
use Psr\Http\Message\UriInterface;
3430
use Throwable;
@@ -44,13 +40,15 @@ final class BoltConnectionPool implements ConnectionPoolInterface
4440
/** @var array<string, list<BoltConnection>> */
4541
private static array $connectionCache = [];
4642
private DriverConfiguration $driverConfig;
43+
private SslConfigurator $sslConfigurator;
4744

4845
/**
4946
* @psalm-external-mutation-free
5047
*/
51-
public function __construct(DriverConfiguration $driverConfig)
48+
public function __construct(DriverConfiguration $driverConfig, SslConfigurator $sslConfigurator)
5249
{
5350
$this->driverConfig = $driverConfig;
51+
$this->sslConfigurator = $sslConfigurator;
5452
}
5553

5654
/**
@@ -100,56 +98,12 @@ public function acquire(
10098
return $connection;
10199
}
102100

103-
private function configureSsl(UriInterface $uri, UriInterface $server, StreamSocket $socket, ?RoutingTable $table): void
104-
{
105-
$sslMode = $this->driverConfig->getSslConfiguration()->getMode();
106-
$sslConfig = '';
107-
if ($sslMode === SslMode::FROM_URL()) {
108-
$scheme = $uri->getScheme();
109-
$explosion = explode('+', $scheme, 2);
110-
$sslConfig = $explosion[1] ?? '';
111-
} elseif ($sslMode === SslMode::ENABLE()) {
112-
$sslConfig = 's';
113-
} elseif ($sslMode === SslMode::ENABLE_WITH_SELF_SIGNED()) {
114-
$sslConfig = 'ssc';
115-
}
116-
117-
if (str_starts_with($sslConfig, 's')) {
118-
// We have to pass a different host when working with ssl on aura.
119-
// There is a strange behaviour where if we pass the uri host on a single
120-
// instance aura deployment, we need to pass the original uri for the
121-
// ssl configuration to be valid.
122-
if ($table && count($table->getWithRole()) > 1) {
123-
$this->enableSsl($server->getHost(), $sslConfig, $socket);
124-
} else {
125-
$this->enableSsl($uri->getHost(), $sslConfig, $socket);
126-
}
127-
}
128-
}
129-
130-
private function enableSsl(string $host, string $sslConfig, StreamSocket $sock): void
131-
{
132-
$options = [
133-
'verify_peer' => $this->driverConfig->getSslConfiguration()->isVerifyPeer(),
134-
'peer_name' => $host,
135-
];
136-
if (!filter_var($host, FILTER_VALIDATE_IP)) {
137-
$options['SNI_enabled'] = true;
138-
}
139-
if ($sslConfig === 's') {
140-
$sock->setSslContextOptions($options);
141-
} elseif ($sslConfig === 'ssc') {
142-
$options['allow_self_signed'] = true;
143-
$sock->setSslContextOptions($options);
144-
}
145-
}
146-
147101
public function canConnect(UriInterface $uri, AuthenticateInterface $authenticate, ?RoutingTable $table = null, ?UriInterface $server = null): bool
148102
{
149103
$connectingTo = $server ?? $uri;
150104
$socket = new StreamSocket($uri->getHost(), $connectingTo->getPort() ?? 7687);
151105

152-
$this->configureSsl($uri, $connectingTo, $socket, $table);
106+
$this->sslConfigurator->configure($uri, $connectingTo, $socket, $table, $this->driverConfig);
153107

154108
try {
155109
$bolt = new Bolt($socket);
@@ -172,7 +126,7 @@ private function openConnection(
172126
): BoltConnection {
173127
$socket = new StreamSocket($connectingTo->getHost(), $connectingTo->getPort() ?? 7687, $socketTimeout);
174128

175-
$this->configureSsl($uri, $connectingTo, $socket, $table);
129+
$this->sslConfigurator->configure($uri, $connectingTo, $socket, $table, $this->driverConfig);
176130

177131
$bolt = new Bolt($socket);
178132
$authenticate->authenticateBolt($bolt, $connectingTo, $userAgent);

src/Bolt/BoltDriver.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public static function create($uri, ?DriverConfiguration $configuration = null,
9797
return new self(
9898
$uri,
9999
$authenticate ?? Authenticate::fromUrl(),
100-
new BoltConnectionPool($configuration),
100+
new BoltConnectionPool($configuration, new SslConfigurator()),
101101
$configuration,
102102
$formatter,
103103
$socketTimeout
@@ -107,7 +107,7 @@ public static function create($uri, ?DriverConfiguration $configuration = null,
107107
return new self(
108108
$uri,
109109
$authenticate ?? Authenticate::fromUrl(),
110-
new BoltConnectionPool($configuration),
110+
new BoltConnectionPool($configuration, new SslConfigurator()),
111111
$configuration,
112112
OGMFormatter::create(),
113113
$socketTimeout

src/Bolt/SslConfigurator.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Laudis Neo4j package.
5+
*
6+
* (c) Laudis technologies <http://laudis.tech>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Laudis\Neo4j\Bolt;
13+
14+
use Bolt\connection\StreamSocket;
15+
use function count;
16+
use function explode;
17+
use const FILTER_VALIDATE_IP;
18+
use function filter_var;
19+
use Laudis\Neo4j\Databags\DriverConfiguration;
20+
use Laudis\Neo4j\Enum\SslMode;
21+
use Laudis\Neo4j\Neo4j\RoutingTable;
22+
use Psr\Http\Message\UriInterface;
23+
24+
final class SslConfigurator
25+
{
26+
public function configure(UriInterface $uri, UriInterface $server, StreamSocket $socket, ?RoutingTable $table, DriverConfiguration $config): void
27+
{
28+
$sslMode = $config->getSslConfiguration()->getMode();
29+
$sslConfig = '';
30+
if ($sslMode === SslMode::FROM_URL()) {
31+
$scheme = $uri->getScheme();
32+
$explosion = explode('+', $scheme, 2);
33+
$sslConfig = $explosion[1] ?? '';
34+
} elseif ($sslMode === SslMode::ENABLE()) {
35+
$sslConfig = 's';
36+
} elseif ($sslMode === SslMode::ENABLE_WITH_SELF_SIGNED()) {
37+
$sslConfig = 'ssc';
38+
}
39+
40+
if (str_starts_with($sslConfig, 's')) {
41+
// We have to pass a different host when working with ssl on aura.
42+
// There is a strange behaviour where if we pass the uri host on a single
43+
// instance aura deployment, we need to pass the original uri for the
44+
// ssl configuration to be valid.
45+
if ($table && count($table->getWithRole()) > 1) {
46+
$this->enableSsl($server->getHost(), $sslConfig, $socket, $config);
47+
} else {
48+
$this->enableSsl($uri->getHost(), $sslConfig, $socket, $config);
49+
}
50+
}
51+
}
52+
53+
private function enableSsl(string $host, string $sslConfig, StreamSocket $sock, DriverConfiguration $config): void
54+
{
55+
$options = [
56+
'verify_peer' => $config->getSslConfiguration()->isVerifyPeer(),
57+
'peer_name' => $host,
58+
];
59+
if (!filter_var($host, FILTER_VALIDATE_IP)) {
60+
$options['SNI_enabled'] = true;
61+
}
62+
if ($sslConfig === 's') {
63+
$sock->setSslContextOptions($options);
64+
} elseif ($sslConfig === 'ssc') {
65+
$options['allow_self_signed'] = true;
66+
$sock->setSslContextOptions($options);
67+
}
68+
}
69+
}

src/Neo4j/Neo4jDriver.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Laudis\Neo4j\Authentication\Authenticate;
2020
use Laudis\Neo4j\Bolt\BoltConnectionPool;
2121
use Laudis\Neo4j\Bolt\Session;
22+
use Laudis\Neo4j\Bolt\SslConfigurator;
2223
use Laudis\Neo4j\Common\Uri;
2324
use Laudis\Neo4j\Contracts\AuthenticateInterface;
2425
use Laudis\Neo4j\Contracts\ConnectionPoolInterface;
@@ -98,7 +99,7 @@ public static function create($uri, ?DriverConfiguration $configuration = null,
9899
return new self(
99100
$uri,
100101
$authenticate ?? Authenticate::fromUrl(),
101-
new Neo4jConnectionPool(new BoltConnectionPool($configuration)),
102+
new Neo4jConnectionPool(new BoltConnectionPool($configuration, new SslConfigurator())),
102103
$configuration,
103104
$formatter,
104105
$socketTimeout
@@ -108,7 +109,7 @@ public static function create($uri, ?DriverConfiguration $configuration = null,
108109
return new self(
109110
$uri,
110111
$authenticate ?? Authenticate::fromUrl(),
111-
new Neo4jConnectionPool(new BoltConnectionPool($configuration)),
112+
new Neo4jConnectionPool(new BoltConnectionPool($configuration, new SslConfigurator())),
112113
$configuration,
113114
OGMFormatter::create(),
114115
$socketTimeout

tests/Unit/SslConfiguratorTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Laudis\Neo4j\Tests\Unit;
4+
5+
class SslConfiguratorTest
6+
{
7+
8+
}

0 commit comments

Comments
 (0)