Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixing json field data with ciphersweet issue #82

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
107 changes: 98 additions & 9 deletions src/EncryptedRow.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
};
use ParagonIE\ConstantTime\Hex;
use SodiumException;
use TypeError;

/**
* Class EncryptedRow
Expand Down Expand Up @@ -232,6 +233,34 @@ public function createCompoundIndex(
return $index;
}

/**
* Create a fast compound blind index then add it to this EncryptedRow object.
*
* @param string $name
* @param array<int, string> $columns
* @param int $filterBits
* @param array $hashConfig
* @return CompoundIndex
*
* @throws CipherSweetException
*/
public function createFastCompoundIndex(
string $name,
array $columns = [],
int $filterBits = 256,
array $hashConfig = []
): CompoundIndex {
$index = new FastCompoundIndex(
$name,
$columns,
$filterBits,
true,
$hashConfig
);
$this->addCompoundIndex($index);
return $index;
}

/**
* Calculate a blind index (or compound blind index) output for this row.
*
Expand Down Expand Up @@ -422,10 +451,10 @@ public function decryptRow(
}
if (
!empty($this->aadSourceField[$field])
&&
&&
\array_key_exists($this->aadSourceField[$field], $row)
) {
$aad = (string) $row[$this->aadSourceField[$field]];
$aad = $this->coaxAadToString($row[$this->aadSourceField[$field]]);
} else {
$aad = '';
}
Expand Down Expand Up @@ -453,7 +482,7 @@ public function decryptRow(
* If any columns are defined in this object to be encrypted, the value
* will be encrypted in-place in the returned array.
*
* @param array<string, string|int|float|bool|null> $row
* @param array<string, scalar|scalar[]|null> $row
* @return array<string, string>
*
* @throws ArrayKeyException
Expand All @@ -463,7 +492,8 @@ public function decryptRow(
*/
public function encryptRow(
#[\SensitiveParameter]
array $row
array $row,
bool $decode_json = false,
): array {
/** @var array<string, string|int|float|bool|null|scalar[]> $return */
$return = $row;
Expand All @@ -472,7 +502,7 @@ public function encryptRow(
if (!\array_key_exists($field, $row)) {
throw new ArrayKeyException(
'Expected value for column ' .
$field .
$field .
' on array, nothing given.'
);
}
Expand All @@ -482,25 +512,32 @@ public function encryptRow(
);
if (
!empty($this->aadSourceField[$field])
&&
&&
\array_key_exists($this->aadSourceField[$field], $row)
) {
$aad = (string) $row[$this->aadSourceField[$field]];
$aad = $this->coaxAadToString($row[$this->aadSourceField[$field]]);
} else {
$aad = '';
}
if ($type === Constants::TYPE_JSON && !empty($this->jsonMaps[$field])) {
$return[$field] = $row[$field];
// checks decode json option
if ($decode_json) {
$row[$field] = $this->formatJson($row[$field]);
}
// JSON is a special case
$jsonEncryptor = new EncryptedJsonField(
$backend,
$key,
$this->jsonMaps[$field],
$this->jsonStrict[$field]
);
/** @psalm-suppress InvalidArgument */
$return[$field] = $jsonEncryptor->encryptJson($row[$field], $aad);
$return[$field] = $jsonEncryptor->encryptJson($this->coaxToArray($row[$field]), $aad);
continue;
}
if (!is_scalar($row[$field])) {
throw new TypeError('Invalid type for ' . $field);
}
$plaintext = $this->convertToString($row[$field], $type);
$return[$field] = $backend->encrypt($plaintext, $key, $aad);
}
Expand All @@ -511,6 +548,20 @@ public function encryptRow(
return $return;
}

/**
* Decoding json field
*
* @param array<array-key, mixed>|mixed|null $field
* @return array<array-key, mixed>
*/
public function formatJson(
$field
): array {
//decode json field then to take key from it to encrypt it
$field = isset($field) ? (is_string($field) ? (array)json_decode($field) : $field) : [];
return $field;
}

/**
* Process an entire row, which means:
*
Expand Down Expand Up @@ -848,4 +899,42 @@ public function setTypedIndexes(bool $bool): static
$this->typedIndexes = $bool;
return $this;
}

/**
* @param mixed $input
* @return array
*/
protected function coaxToArray(mixed $input): array
{
if (is_array($input)) {
return $input;
}
if (is_null($input)) {
return [];
}
if (is_object($input)) {
/** psalm-suppress PossiblyInvalidCast */
return (array) $input;
}
if (is_string($input)) {
return json_decode($input, true);
}
throw new TypeError("Cannot coax to array: " . gettype($input));
}

/**
* @param mixed $input
* @return string
*/
protected function coaxAadToString(mixed $input): string
{
if (is_string($input)) {
return $input;
}
if (is_numeric($input)) {
return '' . $input;
}
/** psalm-suppress PossiblyInvalidCast */
return (string) $input;
}
}
38 changes: 38 additions & 0 deletions src/FastCompoundIndex.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace ParagonIE\CipherSweet;

use ParagonIE\CipherSweet\Exception\CipherSweetException;

class FastCompoundIndex extends CompoundIndex
{
/**
* FastCompoundIndex constructor.
*
* @param string $name
* @param array<int, string> $columns
* @param int $filterBits
* @param bool $fastHash
* @param array $hashConfig
*
* @throws CipherSweetException
*/
public function __construct(
string $name,
array $columns = [],
int $filterBits = 256,
bool $fastHash = true,
array $hashConfig = []
) {
if (!$fastHash) {
throw new CipherSweetException("FastCompoundIndex cannot be turned slow");
}
return parent::__construct(
$name,
$columns,
$filterBits,
$fastHash,
$hashConfig
);
}
}