Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 4 additions & 2 deletions src/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class Auth
private string $authcid;
private string $secret;
private string $authzid;
private string $authSource;
private string $gs2Header;
private ?string $cnonce = null;
private string $firstMessageBare;
Expand All @@ -23,6 +24,7 @@ public function __construct(array $options)
$this->authcid = $options['authcid'] ?? '';
$this->secret = $options['secret'] ?? '';
$this->authzid = $options['authzid'] ?? '';
$this->authSource = $options['authSource'] ?? 'admin';
$this->cnonce = base64_encode(random_bytes(32));
}

Expand All @@ -39,7 +41,7 @@ public function start(): array
"autoAuthorize" => 1,
"options" => ["skipEmptyExchange" => true],
],
'admin'
$this->authSource
];
}

Expand All @@ -61,7 +63,7 @@ public function continue($data): array
"conversationId" => $cid,
"payload" => $payload,
],
'admin'
$this->authSource
];
}

Expand Down
9 changes: 7 additions & 2 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ class Client
* @param string $user
* @param string $password
* @param Boolean $useCoroutine
* @param string|null $authSource Database to authenticate against; defaults to 'admin'.
* Set this when the user was created in a database other than admin (e.g. the
* application database itself).
* @throws \Exception
Comment thread
abnegate marked this conversation as resolved.
Resolved
*/
public function __construct(
Expand All @@ -144,7 +147,8 @@ public function __construct(
string $password,
bool $useCoroutine = false,
bool $tls = false,
array $tlsOptions = []
array $tlsOptions = [],
?string $authSource = null
) {
if (empty($database)) {
throw new \InvalidArgumentException('Database name cannot be empty');
Expand Down Expand Up @@ -210,7 +214,8 @@ public function __construct(

$this->auth = new Auth([
'authcid' => $user,
'secret' => Auth::encodeCredentials($user, $password)
'secret' => Auth::encodeCredentials($user, $password),
'authSource' => $authSource ?? 'admin',
]);
}

Expand Down
56 changes: 56 additions & 0 deletions tests/AuthTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

namespace Utopia\Tests;

use PHPUnit\Framework\TestCase;
use Utopia\Mongo\Auth;

class AuthTest extends TestCase
{
public function testStartDefaultsToAdminAuthSource(): void
{
$auth = new Auth([
'authcid' => 'root',
'secret' => Auth::encodeCredentials('root', 'example'),
]);

[$payload, $database] = $auth->start();

$this->assertSame(1, $payload['saslStart']);
$this->assertSame('admin', $database);
}

public function testStartUsesProvidedAuthSource(): void
{
$auth = new Auth([
'authcid' => 'appuser',
'secret' => Auth::encodeCredentials('appuser', 'example'),
'authSource' => 'appdb',
]);

[$payload, $database] = $auth->start();

$this->assertSame(1, $payload['saslStart']);
$this->assertSame('appdb', $database);
}

public function testContinueUsesProvidedAuthSource(): void
{
$auth = new Auth([
'authcid' => 'appuser',
'secret' => Auth::encodeCredentials('appuser', 'example'),
'authSource' => 'appdb',
]);

$auth->start();

$data = new \stdClass();
$data->conversationId = 1;
$data->payload = new \MongoDB\BSON\Binary('r=' . $auth->getCnonce() . 'server,s=' . base64_encode('salt') . ',i=4096', 0);

[$payload, $database] = $auth->continue($data);

$this->assertSame(1, $payload['saslContinue']);
$this->assertSame('appdb', $database);
}
}
Loading