Skip to content

Commit 3a2a059

Browse files
committed
modified Login logic
1 parent b615899 commit 3a2a059

File tree

6 files changed

+175
-9
lines changed

6 files changed

+175
-9
lines changed

src/Neo4jQueryAPI.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
use Exception;
66
use GuzzleHttp\Client;
7+
use Neo4j\QueryAPI\Objects\Auth;
8+
use Neo4j\QueryAPI\Objects\Authentication;
79
use Neo4j\QueryAPI\Objects\ProfiledQueryPlanArguments;
810
use Neo4j\QueryAPI\Objects\ResultCounters;
911
use Neo4j\QueryAPI\Objects\ProfiledQueryPlan;
@@ -24,13 +26,13 @@ public function __construct(Client $client)
2426
$this->client = $client;
2527
}
2628

27-
public static function login(string $address, string $username, string $password): self
29+
public static function login(string $address, Authentication $auth): self
2830
{
2931
$client = new Client([
3032
'base_uri' => rtrim($address, '/'),
3133
'timeout' => 10.0,
3234
'headers' => [
33-
'Authorization' => 'Basic ' . base64_encode("$username:$password"),
35+
'Authorization' => $auth->getHeader(),
3436
'Content-Type' => 'application/vnd.neo4j.query',
3537
'Accept' => 'application/vnd.neo4j.query',
3638
],
@@ -39,6 +41,7 @@ public static function login(string $address, string $username, string $password
3941
return new self($client);
4042
}
4143

44+
4245
/**
4346
* @throws Neo4jException
4447
* @throws RequestExceptionInterface

src/Objects/Authentication.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
namespace Neo4j\QueryAPI\Objects;
4+
5+
use InvalidArgumentException;
6+
7+
class Authentication
8+
{
9+
private string $header;
10+
private string $type;
11+
12+
private function __construct(string $header, string $type)
13+
{
14+
$this->header = $header;
15+
$this->type = $type;
16+
}
17+
18+
public static function request(string $username = null, string $password = null, string $token = null): self
19+
{
20+
if ($token !== null) {
21+
return self::bearer($token);
22+
}
23+
if ($username === null) {
24+
$username = getenv('NEO4J_USERNAME');
25+
}
26+
27+
if ($password === null) {
28+
$password = getenv('NEO4J_PASSWORD');
29+
}
30+
if ($username !== null && $password !== null) {
31+
return self::basic($username, $password);
32+
}
33+
34+
throw new InvalidArgumentException("Both username and password cannot be null.");
35+
}
36+
37+
private static function basic(string $username, string $password): self
38+
{
39+
return new self("Basic " . base64_encode("$username:$password"), 'Basic');
40+
}
41+
42+
private static function bearer(string $token): self
43+
{
44+
return new self("Bearer $token", 'Bearer');
45+
}
46+
47+
public function getHeader(): string
48+
{
49+
return $this->header; // Return the header string directly
50+
}
51+
52+
public function getType(): string
53+
{
54+
return $this->type;
55+
}
56+
}

src/Objects/php your-script.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
use Neo4j\QueryAPI\Objects\Authentication;
4+
require_once 'Authentication.php'; // Assuming your Authentication class is in Authentication.php
5+
6+
// Using Bearer Token Authentication
7+
$authBearer = Authentication::create([
8+
'token' => 'yourBearerToken'
9+
]);
10+
11+
print_r($authBearer->getHeader());
12+
13+
// Using Basic Authentication
14+
$authBasic = Authentication::create([
15+
'username' => '',
16+
'password' => ''
17+
]);
18+
19+
print_r($authBasic->getHeader());

tests/Integration/Neo4jQueryAPIIntegrationTest.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use GuzzleHttp\Psr7\Response;
1010
use Neo4j\QueryAPI\Exception\Neo4jException;
1111
use Neo4j\QueryAPI\Neo4jQueryAPI;
12+
use Neo4j\QueryAPI\Objects\Authentication;
1213
use Neo4j\QueryAPI\Objects\ProfiledQueryPlan;
1314
use Neo4j\QueryAPI\Objects\Bookmarks;
1415
use Neo4j\QueryAPI\Objects\ResultCounters;
@@ -37,20 +38,26 @@ public function setUp(): void
3738

3839
private function initializeApi(): Neo4jQueryAPI
3940
{
41+
$auth = Authentication::request(); // Automatically determines basic or bearer
4042
return Neo4jQueryAPI::login(
4143
getenv('NEO4J_ADDRESS'),
42-
getenv('NEO4J_USERNAME'),
43-
getenv('NEO4J_PASSWORD')
44+
$auth
4445
);
4546
}
4647

48+
49+
4750
public function testCounters(): void
4851
{
4952
$result = $this->api->run('CREATE (x:Node {hello: "world"})');
5053

5154
$this->assertEquals(1, $result->getQueryCounters()->getNodesCreated());
5255
}
5356

57+
/**
58+
* @throws Neo4jException
59+
* @throws RequestExceptionInterface
60+
*/
5461
public function testCreateBookmarks(): void
5562
{
5663
$result = $this->api->run(cypher: 'CREATE (x:Node {hello: "world"})');

tests/Unit/AuthenticationTest.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
namespace Neo4j\QueryAPI\Tests\Unit;
4+
5+
use Neo4j\QueryAPI\Objects\Authentication;
6+
use PHPUnit\Framework\TestCase;
7+
use InvalidArgumentException;
8+
9+
class AuthenticationTest extends TestCase
10+
{
11+
public function testBearerToken(): void
12+
{
13+
// Mock a bearer token
14+
$mockToken = 'mocked_bearer_token';
15+
16+
// Create an Authentication instance with the bearer token
17+
$auth = Authentication::request(token: $mockToken);
18+
19+
// Assert that the Authorization header is correct
20+
$this->assertEquals("Bearer $mockToken", $auth->getHeader(), 'Bearer token mismatch.');
21+
$this->assertEquals('Bearer', $auth->getType(), 'Type should be Bearer.');
22+
}
23+
24+
public function testBasicAuthentication(): void
25+
{
26+
// Mock username and password
27+
$mockUsername = 'mockUser';
28+
$mockPassword = 'mockPass';
29+
30+
// Create an Authentication instance with username and password
31+
$auth = Authentication::request($mockUsername, $mockPassword);
32+
33+
// Assert that the Authorization header is correct
34+
$expectedHeader = 'Basic ' . base64_encode("$mockUsername:$mockPassword");
35+
$this->assertEquals($expectedHeader, $auth->getHeader(), 'Basic authentication header mismatch.');
36+
$this->assertEquals('Basic', $auth->getType(), 'Type should be Basic.');
37+
}
38+
39+
public function testFallbackToEnvironmentVariables(): void
40+
{
41+
// Mock environment variables
42+
putenv('NEO4J_USERNAME=mockEnvUser');
43+
putenv('NEO4J_PASSWORD=mockEnvPass');
44+
45+
// Create an Authentication instance with environment variables
46+
$auth = Authentication::request();
47+
48+
// Assert that the Authorization header is correct
49+
$expectedHeader = 'Basic ' . base64_encode("mockEnvUser:mockEnvPass");
50+
$this->assertEquals($expectedHeader, $auth->getHeader(), 'Basic authentication with environment variables mismatch.');
51+
$this->assertEquals('Basic', $auth->getType(), 'Type should be Basic.');
52+
53+
// Cleanup the environment variables
54+
putenv('NEO4J_USERNAME');
55+
putenv('NEO4J_PASSWORD');
56+
}
57+
58+
public function testInvalidArguments(): void
59+
{
60+
// Expect an exception when both username and password are null
61+
$this->expectException(InvalidArgumentException::class);
62+
$this->expectExceptionMessage('Both username and password cannot be null.');
63+
64+
// Attempt to create an Authentication instance without credentials
65+
Authentication::request(null, null, null);
66+
}
67+
}

tests/Unit/Neo4jQueryAPIUnitTest.php

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use GuzzleHttp\HandlerStack;
99
use GuzzleHttp\Psr7\Response;
1010
use Neo4j\QueryAPI\Neo4jQueryAPI;
11+
use Neo4j\QueryAPI\Objects\Authentication;
1112
use Neo4j\QueryAPI\Objects\Bookmarks;
1213
use Neo4j\QueryAPI\Objects\ResultCounters;
1314
use Neo4j\QueryAPI\Results\ResultRow;
@@ -24,34 +25,47 @@ protected function setUp(): void
2425
{
2526
parent::setUp();
2627

27-
$this->address = getenv('NEO4J_ADDRESS');
28-
$this->username = getenv('NEO4J_USERNAME');
29-
$this->password = getenv('NEO4J_PASSWORD');
28+
$this->address = getenv('NEO4J_ADDRESS') ;
29+
$this->username = getenv('NEO4J_USERNAME') ;
30+
$this->password = getenv('NEO4J_PASSWORD') ;
3031
}
3132

3233
public function testCorrectClientSetup(): void
3334
{
34-
$neo4jQueryAPI = Neo4jQueryAPI::login($this->address, $this->username, $this->password);
35+
// Verify Authentication object creation
36+
$authentication = Authentication::request($this->username, $this->password);
37+
$expectedAuthHeader = 'Basic ' . base64_encode("{$this->username}:{$this->password}");
38+
$this->assertEquals($expectedAuthHeader, $authentication->getHeader(), 'Authentication header mismatch.');
39+
40+
// Use the updated login method
41+
$neo4jQueryAPI = Neo4jQueryAPI::login($this->address, $authentication);
3542

3643
$this->assertInstanceOf(Neo4jQueryAPI::class, $neo4jQueryAPI);
3744

45+
// Use reflection to access private `client` property
3846
$clientReflection = new \ReflectionClass(Neo4jQueryAPI::class);
3947
$clientProperty = $clientReflection->getProperty('client');
48+
// Ensure we can access private properties
4049
$client = $clientProperty->getValue($neo4jQueryAPI);
4150

4251
$this->assertInstanceOf(Client::class, $client);
4352

53+
// Get the client's configuration and check headers
4454
$config = $client->getConfig();
4555
$this->assertEquals(rtrim($this->address, '/'), $config['base_uri']);
46-
$this->assertEquals('Basic ' . base64_encode("{$this->username}:{$this->password}"), $config['headers']['Authorization']);
56+
$this->assertArrayHasKey('Authorization', $config['headers'], 'Authorization header missing.');
57+
$this->assertEquals($expectedAuthHeader, $config['headers']['Authorization'], 'Authorization header value mismatch.');
4758
$this->assertEquals('application/vnd.neo4j.query', $config['headers']['Content-Type']);
59+
$this->assertEquals('application/vnd.neo4j.query', $config['headers']['Accept']);
4860
}
4961

62+
5063
/**
5164
* @throws GuzzleException
5265
*/
5366
public function testRunSuccess(): void
5467
{
68+
// Mock response for a successful query
5569
$mock = new MockHandler([
5670
new Response(200, ['X-Foo' => 'Bar'], '{"data": {"fields": ["hello"], "values": [[{"$type": "String", "_value": "world"}]]}}'),
5771
]);

0 commit comments

Comments
 (0)