Skip to content
Open
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
16 changes: 16 additions & 0 deletions src/Models/Attributes/Password.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,22 @@ public static function md5(string $password): string
return '{MD5}'.static::makeHash($password, 'md5');
}

/**
* Make an argon2i password.
*/
public static function argon2i(string $password): string
{
return '{ARGON2I}'.password_hash($password, PASSWORD_ARGON2I);
}

/**
* Make an argon2id password.
*/
public static function argon2id(string $password): string
{
return '{ARGON2ID}'.password_hash($password, PASSWORD_ARGON2ID);
}

/**
* Make a non-salted NThash password.
*/
Expand Down
6 changes: 6 additions & 0 deletions src/Models/Concerns/HasPassword.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ public function setPasswordAttribute(array|string $password): void
// If the password given is an array, we can assume we
// are changing the password for the current user.
if (is_array($password)) {
if (in_array(strtolower($method), ['argon2i', 'argon2id'])) {
throw new LdapRecordException(
"Argon2 passwords cannot be changed using this method. Use the LDAP Password Modify extended operation instead."
);
}

$this->setChangedPassword(
$this->getHashedPassword($method, $password[0], $this->getPasswordSalt($method)),
$this->getHashedPassword($method, $password[1]),
Expand Down
16 changes: 16 additions & 0 deletions tests/Unit/Models/Attributes/PasswordTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,22 @@ public function test_sha512crypt()
$this->assertEquals($password, Password::sha512crypt('password', Password::getSalt($password)));
}

public function test_argon2i()
{
$password = Password::argon2i('password');

$this->assertStringStartsWith('{ARGON2I}$argon2i$', $password);
$this->assertNotEquals($password, Password::argon2i('password'));
}

public function test_argon2id()
{
$password = Password::argon2id('password');

$this->assertStringStartsWith('{ARGON2ID}$argon2id$', $password);
$this->assertNotEquals($password, Password::argon2id('password'));
}

// Unsalted Hash Tests. //

public function test_sha()
Expand Down
15 changes: 15 additions & 0 deletions tests/Unit/Models/OpenLDAP/UserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use LdapRecord\Connection;
use LdapRecord\Container;
use LdapRecord\LdapRecordException;
use LdapRecord\Models\Attributes\Password;
use LdapRecord\Models\OpenLDAP\User;
use LdapRecord\Tests\TestCase;
Expand Down Expand Up @@ -75,6 +76,20 @@ public function test_algo_and_salt_is_automatically_detected_when_changing_a_use
$this->assertEquals(Password::CRYPT_SALT_TYPE_SHA512, $newAlgo);
}

public function test_changing_argon2_password_throws_exception()
{
$this->expectException(LdapRecordException::class);
$this->expectExceptionMessage('Argon2 passwords cannot be changed using this method.');

$user = (new OpenLDAPUserTestStub)->setRawAttributes([
'userpassword' => [
Password::argon2id('secret'),
],
]);

$user->password = ['secret', 'new-secret'];
}

public function test_correct_auth_identifier_is_returned()
{
$entryUuid = 'foo';
Expand Down
Loading