Merge pull request #5 from bjornvoesten/development
Added nullable attributes
This commit is contained in:
commit
5fdadf1b46
|
|
@ -13,10 +13,10 @@ class Encrypted implements CastsAttributes
|
|||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
* @return string|null
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function get($model, string $key, $value, array $attributes)
|
||||
public function get($model, string $key, $value, array $attributes): ?string
|
||||
{
|
||||
return $model->decrypt($key);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,23 +108,23 @@ class CipherSweetService
|
|||
$field = new EncryptedField(
|
||||
$this->engine,
|
||||
$table = $model->getTable(),
|
||||
$attribute->column,
|
||||
$attribute->column
|
||||
);
|
||||
|
||||
// Map and add the indexes to the encrypted
|
||||
// field instance.
|
||||
collect($attribute->indexes)
|
||||
->map(function (Index $index) {
|
||||
return $index = new BlindIndex(
|
||||
->map(static function (Index $index) {
|
||||
return new BlindIndex(
|
||||
$index->column,
|
||||
$index->transformers,
|
||||
$index->bits,
|
||||
$index->fast,
|
||||
$index->fast
|
||||
);
|
||||
})
|
||||
->each(
|
||||
fn($index) => $field->addBlindIndex($index)
|
||||
);
|
||||
->each(static function ($index) use ($field) {
|
||||
return $field->addBlindIndex($index);
|
||||
});
|
||||
|
||||
return $field;
|
||||
}
|
||||
|
|
@ -134,18 +134,24 @@ class CipherSweetService
|
|||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model|\BjornVoesten\CipherSweet\Concerns\WithAttributeEncryption $model
|
||||
* @param string $attribute
|
||||
* @param string|int|boolean $value
|
||||
* @param string|int|boolean|null $value
|
||||
* @return array
|
||||
* @throws \ParagonIE\CipherSweet\Exception\BlindIndexNameCollisionException
|
||||
* @throws \ParagonIE\CipherSweet\Exception\BlindIndexNotFoundException
|
||||
* @throws \ParagonIE\CipherSweet\Exception\CryptoOperationException
|
||||
* @throws \SodiumException
|
||||
*/
|
||||
public function encrypt(Model $model, string $attribute, $value)
|
||||
public function encrypt(Model $model, string $attribute, $value): array
|
||||
{
|
||||
return $this
|
||||
->field($model, $attribute)
|
||||
->prepareForStorage($value);
|
||||
$field = $this->field($model, $attribute);
|
||||
|
||||
if (is_null($value)) {
|
||||
return [null, array_map(static function () {
|
||||
return null;
|
||||
}, $field->getAllBlindIndexes(''))];
|
||||
}
|
||||
|
||||
return $field->prepareForStorage($value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -158,8 +164,12 @@ class CipherSweetService
|
|||
* @throws \ParagonIE\CipherSweet\Exception\BlindIndexNameCollisionException
|
||||
* @throws \ParagonIE\CipherSweet\Exception\CryptoOperationException
|
||||
*/
|
||||
public function decrypt(Model $model, string $attribute, $value)
|
||||
public function decrypt(Model $model, string $attribute, $value): ?string
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this
|
||||
->field($model, $attribute)
|
||||
->decryptValue($value);
|
||||
|
|
|
|||
|
|
@ -35,12 +35,12 @@ trait WithAttributeEncryption
|
|||
* Encrypt the attribute.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @return string
|
||||
* @return string|null
|
||||
*/
|
||||
public function decrypt(string $attribute): string
|
||||
public function decrypt(string $attribute): ?string
|
||||
{
|
||||
return app('ciphersweet')->decrypt(
|
||||
$this, $attribute, $this->attributes[$attribute]
|
||||
$this, $attribute, $this->attributes[$attribute] ?? null
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ trait CreateUsersTable
|
|||
protected function createUsersTable(): void
|
||||
{
|
||||
Schema::create('users', function (Blueprint $table) {
|
||||
$table->id('id');
|
||||
$table->string('social_security_number');
|
||||
$table->id();
|
||||
$table->string('social_security_number')->nullable();
|
||||
$table->string('social_security_number_index')->nullable();
|
||||
$table->string('custom_index')->nullable();
|
||||
$table->timestamps();
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ trait CreatesUsers
|
|||
/**
|
||||
* Create a new user instance.
|
||||
*
|
||||
* @param string $socialSecurityNumber
|
||||
* @param string|null $socialSecurityNumber
|
||||
* @return \Tests\Mocks\User|\Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
protected function user(string $socialSecurityNumber): User
|
||||
protected function user(?string $socialSecurityNumber): User
|
||||
{
|
||||
return User::query()->create([
|
||||
'social_security_number' => $socialSecurityNumber,
|
||||
|
|
|
|||
|
|
@ -27,12 +27,12 @@ class EncryptionTest extends TestCase
|
|||
'social_security_number' => '123-456-789',
|
||||
]);
|
||||
|
||||
$this->assertSame(
|
||||
static::assertSame(
|
||||
'123-456-789',
|
||||
$user->social_security_number
|
||||
);
|
||||
|
||||
$this->assertNotEmpty(
|
||||
static::assertNotEmpty(
|
||||
$user->social_security_number_index
|
||||
);
|
||||
}
|
||||
|
|
@ -41,12 +41,12 @@ class EncryptionTest extends TestCase
|
|||
{
|
||||
$user = $this->user('123-456-789');
|
||||
|
||||
$this->assertNotSame(
|
||||
static::assertNotSame(
|
||||
'123-456-789',
|
||||
$user->getRawOriginal('social_security_number')
|
||||
);
|
||||
|
||||
$this->assertNotEmpty(
|
||||
static::assertNotEmpty(
|
||||
$user->social_security_number_index
|
||||
);
|
||||
|
||||
|
|
@ -78,12 +78,12 @@ class EncryptionTest extends TestCase
|
|||
])
|
||||
->save();
|
||||
|
||||
$this->assertNotSame(
|
||||
static::assertNotSame(
|
||||
'123-456-789',
|
||||
$user->getRawOriginal('social_security_number')
|
||||
);
|
||||
|
||||
$this->assertNotEmpty(
|
||||
static::assertNotEmpty(
|
||||
$user->getAttribute('custom_index')
|
||||
);
|
||||
|
||||
|
|
@ -100,9 +100,29 @@ class EncryptionTest extends TestCase
|
|||
{
|
||||
$user = $this->user('123-456-789');
|
||||
|
||||
$this->assertSame(
|
||||
static::assertSame(
|
||||
'123-456-789',
|
||||
$user->getAttribute('social_security_number')
|
||||
);
|
||||
}
|
||||
|
||||
public function testAttributesCanBeMadeNull(): void
|
||||
{
|
||||
$user = $this->user('123-456-789');
|
||||
|
||||
static::assertSame(
|
||||
'123-456-789',
|
||||
$user->social_security_number
|
||||
);
|
||||
|
||||
$user->social_security_number = null;
|
||||
|
||||
static::assertNull(
|
||||
$user->social_security_number
|
||||
);
|
||||
|
||||
static::assertNull(
|
||||
$user->social_security_number_index
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ class QueryTest extends TestCase
|
|||
->get()
|
||||
->modelKeys();
|
||||
|
||||
$this->assertContains($userOne->id, $keys);
|
||||
$this->assertNotContains($userTwo->id, $keys);
|
||||
static::assertContains($userOne->id, $keys);
|
||||
static::assertNotContains($userTwo->id, $keys);
|
||||
|
||||
// Assert success using provided index.
|
||||
/** @var \Illuminate\Database\Eloquent\Collection $keys */
|
||||
|
|
@ -44,8 +44,8 @@ class QueryTest extends TestCase
|
|||
->get()
|
||||
->modelKeys();
|
||||
|
||||
$this->assertContains($userOne->id, $keys);
|
||||
$this->assertNotContains($userTwo->id, $keys);
|
||||
static::assertContains($userOne->id, $keys);
|
||||
static::assertNotContains($userTwo->id, $keys);
|
||||
|
||||
// Assert undefined index exception.
|
||||
$this->expectException(Exception::class);
|
||||
|
|
@ -57,6 +57,22 @@ class QueryTest extends TestCase
|
|||
->get();
|
||||
}
|
||||
|
||||
public function testCanQueryNullableAttributes(): void
|
||||
{
|
||||
$userOne = $this->user('123-456-789');
|
||||
$userTwo = $this->user(null);
|
||||
|
||||
// Assert success.
|
||||
/** @var \Illuminate\Database\Eloquent\Collection $keys */
|
||||
$keys = User::query()
|
||||
->whereEncrypted('social_security_number', '=', '123-456-789')
|
||||
->get()
|
||||
->modelKeys();
|
||||
|
||||
static::assertContains($userOne->id, $keys);
|
||||
static::assertNotContains($userTwo->id, $keys);
|
||||
}
|
||||
|
||||
public function testCanQueryEncryptedAttributeWithOrWhereClause(): void
|
||||
{
|
||||
$userOne = $this->user('123-456-789');
|
||||
|
|
@ -71,9 +87,9 @@ class QueryTest extends TestCase
|
|||
->get()
|
||||
->modelKeys();
|
||||
|
||||
$this->assertContains($userOne->id, $keys);
|
||||
$this->assertNotContains($userTwo->id, $keys);
|
||||
$this->assertContains($userThree->id, $keys);
|
||||
static::assertContains($userOne->id, $keys);
|
||||
static::assertNotContains($userTwo->id, $keys);
|
||||
static::assertContains($userThree->id, $keys);
|
||||
|
||||
// Assert success using provided index.
|
||||
/** @var \Illuminate\Database\Eloquent\Collection $keys */
|
||||
|
|
@ -85,9 +101,9 @@ class QueryTest extends TestCase
|
|||
->get()
|
||||
->modelKeys();
|
||||
|
||||
$this->assertContains($userOne->id, $keys);
|
||||
$this->assertNotContains($userTwo->id, $keys);
|
||||
$this->assertContains($userThree->id, $keys);
|
||||
static::assertContains($userOne->id, $keys);
|
||||
static::assertNotContains($userTwo->id, $keys);
|
||||
static::assertContains($userThree->id, $keys);
|
||||
|
||||
// Assert undefined index exception.
|
||||
$this->expectException(Exception::class);
|
||||
|
|
@ -118,9 +134,9 @@ class QueryTest extends TestCase
|
|||
->get()
|
||||
->modelKeys();
|
||||
|
||||
$this->assertContains($userOne->id, $keys);
|
||||
$this->assertContains($userTwo->id, $keys);
|
||||
$this->assertNotContains($userThree->id, $keys);
|
||||
static::assertContains($userOne->id, $keys);
|
||||
static::assertContains($userTwo->id, $keys);
|
||||
static::assertNotContains($userThree->id, $keys);
|
||||
|
||||
// Assert success using provided index.
|
||||
/** @var \Illuminate\Database\Eloquent\Collection $keys */
|
||||
|
|
@ -136,9 +152,9 @@ class QueryTest extends TestCase
|
|||
->get()
|
||||
->modelKeys();
|
||||
|
||||
$this->assertContains($userOne->id, $keys);
|
||||
$this->assertContains($userTwo->id, $keys);
|
||||
$this->assertNotContains($userThree->id, $keys);
|
||||
static::assertContains($userOne->id, $keys);
|
||||
static::assertContains($userTwo->id, $keys);
|
||||
static::assertNotContains($userThree->id, $keys);
|
||||
|
||||
$keys = User::query()
|
||||
->whereInEncrypted(
|
||||
|
|
@ -149,7 +165,7 @@ class QueryTest extends TestCase
|
|||
->get()
|
||||
->modelKeys();
|
||||
|
||||
$this->assertEmpty($keys);
|
||||
static::assertEmpty($keys);
|
||||
}
|
||||
|
||||
public function testCanQueryEncryptedAttributeWithOrWhereInClause(): void
|
||||
|
|
@ -172,9 +188,9 @@ class QueryTest extends TestCase
|
|||
->get()
|
||||
->modelKeys();
|
||||
|
||||
$this->assertContains($userOne->id, $keys);
|
||||
$this->assertContains($userTwo->id, $keys);
|
||||
$this->assertNotContains($userThree->id, $keys);
|
||||
static::assertContains($userOne->id, $keys);
|
||||
static::assertContains($userTwo->id, $keys);
|
||||
static::assertNotContains($userThree->id, $keys);
|
||||
|
||||
// Assert success using provided index.
|
||||
/** @var \Illuminate\Database\Eloquent\Collection $keys */
|
||||
|
|
@ -192,9 +208,9 @@ class QueryTest extends TestCase
|
|||
->get()
|
||||
->modelKeys();
|
||||
|
||||
$this->assertContains($userOne->id, $keys);
|
||||
$this->assertContains($userTwo->id, $keys);
|
||||
$this->assertNotContains($userThree->id, $keys);
|
||||
static::assertContains($userOne->id, $keys);
|
||||
static::assertContains($userTwo->id, $keys);
|
||||
static::assertNotContains($userThree->id, $keys);
|
||||
|
||||
$keys = User::query()
|
||||
->whereInEncrypted(
|
||||
|
|
@ -210,6 +226,6 @@ class QueryTest extends TestCase
|
|||
->get()
|
||||
->modelKeys();
|
||||
|
||||
$this->assertEmpty($keys);
|
||||
static::assertEmpty($keys);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue