Compare commits

...

23 Commits

Author SHA1 Message Date
Clemens Schwaighofer
f174e9ec34 DB-IO fix for JSON/JSONB operators when checking for placeholders 2024-07-29 16:32:45 +09:00
Clemens Schwaighofer
928369cff7 Release: v9.13.1 2024-07-29 16:14:37 +09:00
Clemens Schwaighofer
29f4800e1a DB IO Placeholder regex fix for JSON/JSONB placeholders 2024-07-29 16:13:08 +09:00
Clemens Schwaighofer
e706a67427 Shellcheck updates for publish.sh script 2024-07-19 18:39:30 +09:00
Clemens Schwaighofer
672de694ee Readme file update 2024-06-18 10:00:11 +09:00
Clemens Schwaighofer
c69eac3258 Move temp folder for phpstan to local, update github actions
Note: Github actions are not used right now
2024-05-22 18:53:16 +09:00
Clemens Schwaighofer
eca62e53c9 Disabled workflow
For this to work we have to move the smarty-extended package to an official
composer package
2024-05-22 14:21:00 +09:00
Clemens Schwaighofer
62cd3badfe GitHub action update 2024-05-22 14:18:21 +09:00
Clemens Schwaighofer
4bd2568d94 composer.json file update 2024-05-22 14:15:59 +09:00
Clemens Schwaighofer
b3c7947c67 Github actions wrong folder name 2024-05-22 14:13:46 +09:00
Clemens Schwaighofer
6710f44646 GitHub action for PHPstan CI 2024-05-22 14:11:05 +09:00
Clemens Schwaighofer
f89be6bd19 Update composer publish script
check for GITEA_PUBLISH and GITLAB_PUBLISH to trigger actual publish run
2024-05-22 11:11:18 +09:00
Clemens Schwaighofer
9696336abc Release: v9.13.0 2024-05-22 11:10:30 +09:00
Clemens Schwaighofer
fec1c5ad57 Symmetric Encryption class update to standard class and static call type 2024-05-22 11:03:44 +09:00
Clemens Schwaighofer
a6e5e86c9e Remove tools folder from git 2024-05-22 11:02:42 +09:00
Clemens Schwaighofer
1357b98883 phpcs, phpstan, psalm update 2024-05-15 17:05:52 +09:00
Clemens Schwaighofer
fa18a6f422 Merge branch 'master' into development 2024-04-17 10:22:37 +09:00
Clemens Schwaighofer
ada130329f Publish package script fixes 2024-04-17 10:22:25 +09:00
Clemens Schwaighofer
4c489adf9b Release: v9.12.2 2024-04-17 10:21:56 +09:00
Clemens Schwaighofer
c8a2ad4d48 test scripts update 2024-04-17 10:16:56 +09:00
Clemens Schwaighofer
d54a6cbdf5 Remove mb encode mimeheader special code and replace it with default function call 2024-04-17 10:13:32 +09:00
Clemens Schwaighofer
e8f4c82f59 Publish script update with versio file not existing check 2024-04-16 18:27:43 +09:00
Clemens Schwaighofer
24eb2c2bee Release: v9.12.1 2024-03-21 12:47:14 +09:00
25 changed files with 427 additions and 154 deletions

33
.github/workflows-disabled/ci.yml vendored Normal file
View File

@@ -0,0 +1,33 @@
name: CI
run-name: ${{ github.actor}} runs CI
on: [push]
jobs:
phpstan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# - uses: php-actions/composer@v6
# env:
# COMPOSER_ROOT_VERSION: dev-master
- name: "Restore result cache"
uses: actions/cache/restore@v4
with:
path: ./tmp
key: "result-cache-v1-${{ matrix.php-version }}-${{ github.run_id }}"
restore-keys: |
result-cache-v1-${{ matrix.php-version }}-
- name: PHPStan Static Analysis
uses: php-actions/phpstan@v3
with:
path: src/
- name: "Save result cache"
uses: actions/cache/save@v4
if: always()
with:
path: ./tmp
key: "result-cache-v1-${{ matrix.php-version }}-${{ github.run_id }}"
# - name: PHPunit Tests
# run: |
# vendor/bin/phpunit

3
.gitignore vendored
View File

@@ -1,2 +1,3 @@
vendor
vendor/
composer.lock
tools/

View File

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<phive xmlns="https://phar.io/phive">
<phar name="phpunit" version="^9.6" installed="9.6.17" location="./tools/phpunit" copy="false"/>
<phar name="phpcs" version="^3.7.2" installed="3.9.0" location="./tools/phpcs" copy="false"/>
<phar name="phpcbf" version="^3.7.2" installed="3.9.0" location="./tools/phpcbf" copy="false"/>
<phar name="psalm" version="^5.15.0" installed="5.23.1" location="./tools/psalm" copy="false"/>
<phar name="phpstan" version="^1.10.37" installed="1.10.63" location="./tools/phpstan" copy="false"/>
<phar name="phpunit" version="^9.6" installed="9.6.19" location="./tools/phpunit" copy="false"/>
<phar name="phpcs" version="^3.7.2" installed="3.10.0" location="./tools/phpcs" copy="false"/>
<phar name="phpcbf" version="^3.7.2" installed="3.10.0" location="./tools/phpcbf" copy="false"/>
<phar name="psalm" version="^5.15.0" installed="5.24.0" location="./tools/psalm" copy="false"/>
<phar name="phpstan" version="^1.10.37" installed="1.11.1" location="./tools/phpstan" copy="false"/>
<phar name="phan" version="^5.4.2" installed="5.4.3" location="./tools/phan" copy="false"/>
</phive>

2
.shellcheckrc Normal file
View File

@@ -0,0 +1,2 @@
shell=bash
external-sources=true

View File

@@ -9,16 +9,41 @@ For local install only
- Template\SmartyExtended
- Admin\EditBase
## Setup from central composer
## Publish to gitea or gitlab server
Setup from gitea internal servers
Currently there are only gitea and gitlab supported, github does not have support for composer packages
```sh
composer config repositories.git.egplusww.jp.Composer composer https://git.egplusww.jp/api/packages/Composer/composer
`publish\publish.sh go` will run the publish script
All the configuration is done in the `publish\.env.deploy` file
```ini
# downlaod file name is "Repository name" "-" "version" where
# version is "vN.N.N"
GITEA_PUBLISH=1
GITEA_UPLOAD_FILENAME="Upload-File-Name";
GITEA_USER=gitea-user
GITEA_TOKEN=gitea-tokek
GITEA_URL_DL=https://[gitea.hostname]/[to/package/folder]/archive
GITEA_URL_PUSH=https://[gitea.hostname]/api/packages/[organization]/composer
GITLAB_PUBLISH=1
GITLAB_URL=gitlab URl to repository
GITLAB_DEPLOY_TOKEN=gitlab-token
```
Alternative setup composer local zip file repot:
`composer config repositories.composer.egplusww.jp composer http://composer.egplusww.jp`
At the moment there is only one gitea or gitlab target setable
## Setup from central composer
Setup from gitea servers
[hostname] is the hostname for your gitea server (or wherever this is published)
[OrgName] is the organization name where the composer packages are hosted
```sh
composer config repositories.[hostname].Composer composer https://[hostname]/api/packages/[OrgName]/composer
```
## Install package

View File

@@ -21,7 +21,8 @@
},
"require-dev": {
"egrajp/smarty-extended": "^4.3",
"gullevek/dotenv": "dev-master"
"gullevek/dotenv": "dev-master",
"phpunit/phpunit": "^9"
},
"repositories": {
"git.egplusww.jp.Composer": {

View File

@@ -2,7 +2,7 @@
includes:
- phpstan-conditional.php
parameters:
tmpDir: /tmp/phpstan-corelibs-composer
tmpDir: %currentWorkingDirectory%/tmp/phpstan-corelibs-composer
level: 8 # max is now 9
checkMissingCallableSignature: true
treatPhpDocTypesAsCertain: false

View File

@@ -1 +1 @@
9.12.0
9.13.1

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash
BASE_FOLDER=$(dirname $(readlink -f $0))"/";
BASE_FOLDER=$(dirname "$(readlink -f "$0")")"/";
PACKAGE_DOWNLOAD="${BASE_FOLDER}package-download/";
if [ ! -d "${PACKAGE_DOWNLOAD}" ]; then
mkdir "${PACKAGE_DOWNLOAD}";
@@ -15,30 +15,35 @@ if [ -z "${VERSION}" ]; then
fi;
# compare version, if different or newer, deploy
if [ -f "${file_last_published}" ]; then
LAST_PUBLISHED_VERSION=$(cat ${file_last_published});
if $(dpkg --compare-versions "${VERSION}" le "${LAST_PUBLISHED_VERSION}"); then
LAST_PUBLISHED_VERSION=$(cat "${file_last_published}");
if dpkg --compare-versions "${VERSION}" le "${LAST_PUBLISHED_VERSION}"; then
echo "git tag version ${VERSION} is not newer than previous published version ${LAST_PUBLISHED_VERSION}";
exit;
fi;
fi;
# read in the .env.deploy file and we must have
# for gitea
# GITEA_PUBLISH: must be set with a value to trigger publish run
# GITEA_UPLOAD_FILENAME
# GITLAB_USER
# GITLAB_TOKEN
# GITLAB_URL
# GITEA_USER
# GITEA_DEPLOY_TOKEN
# GITEA_URL_DL
# GITEA_URL_PUSH
# for gitlab
# GITLAB_PUBLISH: must be set with a value to trigger publish run
# GITLAB_USER
# GITLAB_TOKEN
# GITLAB_URL
if [ ! -f "${BASE_FOLDER}.env.deploy" ]; then
echo "Deploy enviroment file .env.deploy is missing";
exit;
fi;
set -o allexport;
cd ${BASE_FOLDER};
cd "${BASE_FOLDER}" || exit;
# shellcheck source=.env.deploy
source .env.deploy;
cd -;
cd - || exit;
set +o allexport;
if [ "${go_flag}" != "go" ]; then
@@ -50,31 +55,42 @@ fi;
echo "[START]";
# gitea
if [ ! -z "${GITEA_UPLOAD_FILENAME}" ] &&
[ ! -z "${GITEA_URL_DL}" ] && [ ! -z "${GITEA_URL_PUSH}" ] &&
[ ! -z "${GITEA_USER}" ] && [ ! -z "${GITEA_TOKEN}" ]; then
curl -LJO \
--output-dir "${PACKAGE_DOWNLOAD}" \
${GITEA_URL_DL}/v${VERSION}.zip;
curl --user ${GITEA_USER}:${GITEA_TOKEN} \
--upload-file "${PACKAGE_DOWNLOAD}${GITEA_UPLOAD_FILENAME}-v${VERSION}.zip" \
${GITEA_URL_PUSH}?version=${VERSION};
echo "${VERSION}" > "${file_last_published}";
else
echo "Missing either GITEA_UPLOAD_FILENAME, GITEA_URL_DL, GITEA_URL_PUSH, GITEA_USER or GITEA_TOKEN environment variable";
# skip iof
if [ -n "${GITEA_PUBLISH}" ]; then
if [ -n "${GITEA_UPLOAD_FILENAME}" ] &&
[ -n "${GITEA_URL_DL}" ] && [ -n "${GITEA_URL_PUSH}" ] &&
[ -n "${GITEA_USER}" ] && [ -n "${GITEA_TOKEN}" ]; then
if [ ! -f "${PACKAGE_DOWNLOAD}${GITEA_UPLOAD_FILENAME}-v${VERSION}.zip" ]; then
curl -LJO \
--output-dir "${PACKAGE_DOWNLOAD}" \
"${GITEA_URL_DL}"/v"${VERSION}".zip;
fi;
if [ ! -f "${PACKAGE_DOWNLOAD}${GITEA_UPLOAD_FILENAME}-v${VERSION}.zip" ]; then
echo "Version file does not exist for ${VERSION}";
else
curl --user "${GITEA_USER}":"${GITEA_TOKEN}" \
--upload-file "${PACKAGE_DOWNLOAD}${GITEA_UPLOAD_FILENAME}-v${VERSION}.zip" \
"${GITEA_URL_PUSH}"?version="${VERSION}";
echo "${VERSION}" > "${file_last_published}";
fi;
else
echo "Missing either GITEA_UPLOAD_FILENAME, GITEA_URL_DL, GITEA_URL_PUSH, GITEA_USER or GITEA_TOKEN environment variable";
fi;
fi;
# gitlab
if [ ! -z "${GITLAB_URL}" ] && [ ! -z "${GITLAB_DEPLOY_TOKEN}" ]; then
curl --data tag=v${VERSION} \
--header "Deploy-Token: ${GITLAB_DEPLOY_TOKEN}" \
"${GITLAB_URL}";
curl --data branch=master \
--header "Deploy-Token: ${GITLAB_DEPLOY_TOKEN}" \
"${GITLAB_URL}";
echo "${VERSION}" > "${file_last_published}";
else
echo "Missing GITLAB_DEPLOY_TOKEN environment variable";
if [ -n "${GITLAB_PUBLISH}" ]; then
if [ -n "${GITLAB_URL}" ] && [ -n "${GITLAB_DEPLOY_TOKEN}" ]; then
curl --data tag=v"${VERSION}" \
--header "Deploy-Token: ${GITLAB_DEPLOY_TOKEN}" \
"${GITLAB_URL}";
curl --data branch=master \
--header "Deploy-Token: ${GITLAB_DEPLOY_TOKEN}" \
"${GITLAB_URL}";
echo "${VERSION}" > "${file_last_published}";
else
echo "Missing GITLAB_URL or GITLAB_DEPLOY_TOKEN environment variable";
fi;
fi;
echo "";
echo "[DONE]";

View File

@@ -15,6 +15,7 @@ class MimeEncode
/**
* wrapper function for mb mime convert
* for correct conversion with long strings
* NOTE: This is only a wrapper for mb_encode_mimeheader to stay compatible
*
* @param string $string string to encode
* @param string $encoding target encoding
@@ -29,38 +30,9 @@ class MimeEncode
$current_internal_encoding = mb_internal_encoding();
// set internal encoding, so the mimeheader encode works correctly
mb_internal_encoding($encoding);
// if a subject, make a work around for the broken mb_mimencode
$pos = 0;
// after 36 single bytes characters,
// if then comes MB, it is broken
// has to 2 x 36 < 74 so the mb_encode_mimeheader
// 74 hardcoded split does not get triggered
$split = 36;
$_string = '';
while ($pos < mb_strlen($string, $encoding)) {
$output = mb_strimwidth($string, $pos, $split, "", $encoding);
$pos += mb_strlen($output, $encoding);
// if the strinlen is 0 here, get out of the loop
if (!mb_strlen($output, $encoding)) {
$pos += mb_strlen($string, $encoding);
}
$_string_encoded = mb_encode_mimeheader($output, $encoding);
// only make linebreaks if we have mime encoded code inside
// the space only belongs in the second line
if ($_string && preg_match("/^=\?/", $_string_encoded)) {
$_string .= $line_break . " ";
} elseif (
// hack for plain text with space at the end
mb_strlen($output, $encoding) == $split &&
mb_substr($output, -1, 1, $encoding) == " "
) {
// if output ends with space, add one more
$_string_encoded .= " ";
}
$_string .= $_string_encoded;
}
// strip out any spaces BEFORE a line break
$string = str_replace(" " . $line_break, $line_break, $_string);
// use the internal convert to mime header
// it works from PHP 8.2 on
$string = mb_encode_mimeheader($string, $encoding, 'B', $line_break);
// before we end, reset internal encoding
mb_internal_encoding($current_internal_encoding);
// return mime encoded string

View File

@@ -1324,8 +1324,12 @@ class IO
// /s for matching new line in . list
// [disabled, we don't used ^ or $] /m for multi line match
// Matches in 1:, must be array_filtered to remove empty, count with array_unique
$query_split = '[(=,?-]|->|->>|#>|#>>|@>|<@|\?\|\?\&|\|\||#-';
preg_match_all(
'/(?:\'.*?\')?\s*(?:\?\?|<>|[(=,])\s*(?:\d+|(?:\'.*?\')|(\$[1-9]{1}(?:[0-9]{1,})?))/s',
'/'
. '(?:\'.*?\')?\s*(?:\?\?|<>|' . $query_split . ')\s*'
. '(?:\d+|(?:\'.*?\')|(\$[1-9]{1}(?:[0-9]{1,})?))'
. '/s',
$query,
$match
);

View File

@@ -39,9 +39,11 @@ class ConvertPlaceholder
): array {
$convert_to = strtolower($convert_to);
$matches = [];
$query_split = '[(=,?-]|->|->>|#>|#>>|@>|<@|\?\|\?\&|\|\||#-';
$pattern = '/'
// prefix string part, must match towards
. '(?:\'.*?\')?\s*(?:\?\?|[(=,])\s*'
// seperator for ( = , ? - [and json/jsonb in pg doc section 9.15]
. '(?:\'.*?\')?\s*(?:\?\?|' . $query_split . ')\s*'
// match for replace part
. '(?:'
// digit -> ignore
@@ -96,7 +98,10 @@ class ConvertPlaceholder
$type = 'named';
$matches_return = $named_matches;
// only check for :named
$pattern_replace = '/((?:\'.*?\')?\s*(?:\?\?|[(=,])\s*)(\d+|(?:\'.*?\')|(:\w+))/s';
$pattern_replace = '/'
. '((?:\'.*?\')?\s*(?:\?\?|' . $query_split . ')\s*)'
. '(\d+|(?:\'.*?\')|(:\w+))'
. '/s';
// 0: full
// 1: pre part
// 2: keep part UNLESS '3' is set
@@ -134,7 +139,10 @@ class ConvertPlaceholder
// order and data stays the same
$params_new = $params;
// only check for ?
$pattern_replace = '/((?:\'.*?\')?\s*(?:\?\?|[(=,])\s*)(\d+|(?:\'.*?\')|(?:(?:\?\?)?\s*(\?{1})))/s';
$pattern_replace = '/'
. '((?:\'.*?\')?\s*(?:\?\?|' . $query_split . ')\s*)'
. '(\d+|(?:\'.*?\')|(?:(?:\?\?)?\s*(\?{1})))'
. '/s';
// 0: full
// 1: pre part
// 2: keep part UNLESS '3' is set
@@ -163,7 +171,10 @@ class ConvertPlaceholder
$type = 'numbered';
$matches_return = $numbered_matches;
// only check for $n
$pattern_replace = '/((?:\'.*?\')?\s*(?:\?\?|[(=,])\s*)(\d+|(?:\'.*?\')|(\$[1-9]{1}(?:[0-9]{1,})?))/s';
$pattern_replace = '/'
. '((?:\'.*?\')?\s*(?:\?\?|' . $query_split . ')\s*)'
. '(\d+|(?:\'.*?\')|(\$[1-9]{1}(?:[0-9]{1,})?))'
. '/s';
// 0: full
// 1: pre part
// 2: keep part UNLESS '3' is set

View File

@@ -46,7 +46,7 @@ class CachedFileReader extends \CoreLibs\Language\Core\StringReader
if (!is_resource($fd)) {
$this->error = 3; // Cannot read file, probably permissions
} else {
$this->fd_str = fread($fd, filesize($filename) ?: 0) ?: '';
$this->fd_str = fread($fd, filesize($filename) ?: 1) ?: '';
fclose($fd);
}
} else {

View File

@@ -21,58 +21,82 @@ use SodiumException;
class SymmetricEncryption
{
/** @var SymmetricEncryption self instance */
private static SymmetricEncryption $instance;
/** @var string bin hex key */
private string $key = '';
/**
* Encrypt a message
* init class
* if key not passed, key must be set with createKey
*
* @param string $message Message to encrypt
* @param string $key Encryption key (as hex string)
* @return string
* @throws \Exception
* @throws \RangeException
* @param string|null|null $key
*/
public static function encrypt(string $message, string $key): string
public function __construct(
string|null $key = null
) {
if ($key != null) {
$this->setKey($key);
}
}
/**
* Returns the singleton self object.
* For function wrapper use
*
* @return SymmetricEncryption object
*/
public static function getInstance(string|null $key = null): self
{
if (empty(self::$instance)) {
self::$instance = new self($key);
}
return self::$instance;
}
/* ************************************************************************
* MARK: PRIVATE
* *************************************************************************/
/**
* create key and check validity
*
* @param string $key The key from which the binary key will be created
* @return string Binary key string
*/
private function createKey(string $key): string
{
try {
$key = CreateKey::hex2bin($key);
} catch (SodiumException $e) {
throw new \UnexpectedValueException('Invalid hex key');
throw new \UnexpectedValueException('Invalid hex key: ' . $e->getMessage());
}
if (mb_strlen($key, '8bit') !== SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
throw new \RangeException(
'Key is not the correct size (must be '
. 'SODIUM_CRYPTO_SECRETBOX_KEYBYTES bytes long).'
. SODIUM_CRYPTO_SECRETBOX_KEYBYTES . ' bytes long).'
);
}
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$cipher = base64_encode(
$nonce
. sodium_crypto_secretbox(
$message,
$nonce,
$key
)
);
sodium_memzero($message);
sodium_memzero($key);
return $cipher;
return $key;
}
/**
* Decrypt a message
* Decryption call
*
* @param string $encrypted Message encrypted with safeEncrypt()
* @param string $key Encryption key (as hex string)
* @return string
* @throws \Exception
* @param string $encrypted Text to decrypt
* @param ?string $key Mandatory encryption key, will throw exception if empty
* @return string Plain text
* @throws \RangeException
* @throws \UnexpectedValueException
* @throws \UnexpectedValueException
*/
public static function decrypt(string $encrypted, string $key): string
private function decryptData(string $encrypted, ?string $key): string
{
try {
$key = CreateKey::hex2bin($key);
} catch (SodiumException $e) {
throw new \Exception('Invalid hex key');
if (empty($key)) {
throw new \UnexpectedValueException('Key not set');
}
$key = $this->createKey($key);
$decoded = base64_decode($encrypted);
$nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
$ciphertext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
@@ -85,7 +109,7 @@ class SymmetricEncryption
$key
);
} catch (SodiumException $e) {
throw new \UnexpectedValueException('Invalid ciphertext (too short)');
throw new \UnexpectedValueException('Decipher message failed: ' . $e->getMessage());
}
if (!is_string($plain)) {
throw new \UnexpectedValueException('Invalid Key');
@@ -94,6 +118,117 @@ class SymmetricEncryption
sodium_memzero($key);
return $plain;
}
/**
* Encrypt a message
*
* @param string $message Message to encrypt
* @param ?string $key Mandatory encryption key, will throw exception if empty
* @return string
* @throws \Exception
* @throws \RangeException
*/
private function encryptData(string $message, ?string $key): string
{
if (empty($this->key) || $key === null) {
throw new \UnexpectedValueException('Key not set');
}
$key = $this->createKey($key);
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
try {
$cipher = base64_encode(
$nonce
. sodium_crypto_secretbox(
$message,
$nonce,
$key,
)
);
} catch (SodiumException $e) {
throw new \UnexpectedValueException("Create encrypted message failed: " . $e->getMessage());
}
sodium_memzero($message);
sodium_memzero($key);
return $cipher;
}
/* ************************************************************************
* MARK: PUBLIC
* *************************************************************************/
/**
* set a new key for encryption
*
* @param string $key
* @return void
*/
public function setKey(string $key)
{
if (empty($key)) {
throw new \UnexpectedValueException('Key cannot be empty');
}
$this->key = $key;
}
/**
* Decrypt a message
* static version
*
* @param string $encrypted Message encrypted with safeEncrypt()
* @param string $key Encryption key (as hex string)
* @return string
* @throws \Exception
* @throws \RangeException
* @throws \UnexpectedValueException
* @throws \UnexpectedValueException
*/
public static function decryptKey(string $encrypted, string $key): string
{
return self::getInstance()->decryptData($encrypted, $key);
}
/**
* Decrypt a message
*
* @param string $encrypted Message encrypted with safeEncrypt()
* @return string
* @throws \RangeException
* @throws \UnexpectedValueException
* @throws \UnexpectedValueException
*/
public function decrypt(string $encrypted): string
{
return $this->decryptData($encrypted, $this->key);
}
/**
* Encrypt a message
* static version
*
* @param string $message Message to encrypt
* @param string $key Encryption key (as hex string)
* @return string
* @throws \Exception
* @throws \RangeException
*/
public static function encryptKey(string $message, string $key): string
{
return self::getInstance()->encryptData($message, $key);
}
/**
* Encrypt a message
*
* @param string $message Message to encrypt
* @return string
* @throws \Exception
* @throws \RangeException
*/
public function encrypt(string $message): string
{
return $this->encryptData($message, $this->key);
}
}
// __END__

View File

@@ -185,7 +185,7 @@ class SmartyExtend extends \Smarty
// call basic smarty
// or Smarty::__construct();
parent::__construct();
// iinit lang
// init lang
$this->l10n = $l10n;
// parse and read, legacy stuff
$locale = $this->l10n->getLocaleAsArray();

View File

@@ -15,20 +15,22 @@ php_bin="";
if [ ! -z "${1}" ]; then
case "${1}" in
# "7.3") php_bin="/usr/bin/php7.3 "; ;;
"7.4") php_bin="/usr/bin/php7.4 "; ;;
"8.0") php_bin="/usr/bin/php8.0 "; ;;
"8.1") php_bin="/usr/bin/php8.1 "; ;;
#"7.4") php_bin="/usr/bin/php7.4 "; ;;
#"8.0") php_bin="/usr/bin/php8.0 "; ;;
#"8.1") php_bin="/usr/bin/php8.1 "; ;;
"8.2") php_bin="/usr/bin/php8.2 "; ;;
"8.3") php_bin="/usr/bin/php8.3 "; ;;
*) echo "Not support PHP: ${1}"; exit; ;;
esac;
fi;
if [ ! -z "${2}" ] && [ -z "${php_bin}" ]; then
case "${2}" in
# "7.3") php_bin="/usr/bin/php7.3 "; ;;
"7.4") php_bin="/usr/bin/php7.4 "; ;;
"8.0") php_bin="/usr/bin/php8.0 "; ;;
"8.1") php_bin="/usr/bin/php8.1 "; ;;
#"7.4") php_bin="/usr/bin/php7.4 "; ;;
#"8.0") php_bin="/usr/bin/php8.0 "; ;;
#"8.1") php_bin="/usr/bin/php8.1 "; ;;
"8.2") php_bin="/usr/bin/php8.2 "; ;;
"8.3") php_bin="/usr/bin/php8.3 "; ;;
*) echo "Not support PHP: ${1}"; exit; ;;
esac;
fi;

View File

@@ -33,15 +33,14 @@ final class CoreLibsConvertMimeEncodeTest extends TestCase
'The quick brown fox jumps over the lazy sheep that sleeps in the ravine '
. 'and has no idea what is going on here',
'UTF-8',
'The quick brown fox jumps over the lazy sheep that sleeps in the ravine '
. 'and has no idea what is going on here'
"The quick brown fox jumps over the lazy sheep that sleeps in the ravine and\r\n"
. ' has no idea what is going on here'
],
'standard with special chars UTF-8' => [
'This is ümläßtと漢字もカタカナ!^$%&',
'UTF-8',
'This is =?UTF-8?B?w7xtbMOkw59044Go5ryi5a2X44KC44Kr44K/44Kr44OK77yBIV4k?='
. "\r\n"
. ' =?UTF-8?B?JQ==?=&'
"This is =?UTF-8?B?w7xtbMOkw59044Go5ryi5a2X44KC44Kr44K/44Kr44OK77yBIV4k?=\r\n"
. ' =?UTF-8?B?JSY=?='
],
'35 chars and space at the end UTF-8' => [
'12345678901234567890123456789012345 '
@@ -62,9 +61,8 @@ final class CoreLibsConvertMimeEncodeTest extends TestCase
. 'is there a space?',
'UTF-8',
"=?UTF-8?B?44Kr44K/44Kr44OK44Kr44K/44Kr44OK44GL44Gq44Kr44K/44Kr44OK44Kr?=\r\n"
. " =?UTF-8?B?44K/44Kr44OK?=\r\n"
. " =?UTF-8?B?44GL44Gq44Kr44K/44Kr44OK44Kr44K/44Kr44OK44GL44Gq44Kr44K/44Kr?=\r\n"
. " =?UTF-8?B?44OK44Kr44K/?= is there a =?UTF-8?B?c3BhY2U/?="
. " =?UTF-8?B?44K/44Kr44OK44GL44Gq44Kr44K/44Kr44OK44Kr44K/44Kr44OK44GL44Gq?=\r\n"
. " =?UTF-8?B?44Kr44K/44Kr44OK44Kr44K/IGlzIHRoZXJlIGEgc3BhY2U/?="
]
];
}
@@ -85,16 +83,28 @@ final class CoreLibsConvertMimeEncodeTest extends TestCase
// print "MIME: -" . $encoded . "-\n";
$this->assertEquals(
$expected,
$encoded
$encoded,
"__mbMimeEncode"
);
$decoded = mb_decode_mimeheader($encoded);
// print "INPUT : " . $input . "\n";
// print "DECODED: " . $decoded . "\n";
// print "ENCODED: " . $encoded . "\n";
// print "INPUT : " . $input . " | " . mb_strlen($input) . "\n";
// print "DECODED: " . $decoded . " | " . mb_strlen($decoded) . "\n";
// $test_enc = mb_encode_mimeheader($input, $encoding);
// $test_dec = mb_decode_mimeheader($test_enc);
// print "TEST ENC: " . $test_enc . "\n";
// back compare decoded
$this->assertEquals(
$input,
$decoded
$decoded,
"mb_decode_mimeheader"
);
// $this->assertEquals(
// $input,
// $test_dec,
// 'mb_encode_to_decode'
// );
}
}

View File

@@ -46,12 +46,34 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
public function testEncryptDecryptSuccess(string $input, string $expected): void
{
$key = CreateKey::generateRandomKey();
$encrypted = SymmetricEncryption::encrypt($input, $key);
$decrypted = SymmetricEncryption::decrypt($encrypted, $key);
// test class
$crypt = new SymmetricEncryption($key);
$encrypted = $crypt->encrypt($input);
$decrypted = $crypt->decrypt($encrypted);
$this->assertEquals(
$expected,
$decrypted,
'Class call',
);
// test indirect
$encrypted = SymmetricEncryption::getInstance($key)->encrypt($input);
$decrypted = SymmetricEncryption::getInstance($key)->decrypt($encrypted);
$this->assertEquals(
$expected,
$decrypted,
'Class Instance call',
);
// test static
$encrypted = SymmetricEncryption::encryptKey($input, $key);
$decrypted = SymmetricEncryption::decryptKey($encrypted, $key);
$this->assertEquals(
$expected,
$decrypted
$decrypted,
'Static call',
);
}
@@ -86,10 +108,24 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
public function testEncryptFailed(string $input, string $exception_message): void
{
$key = CreateKey::generateRandomKey();
$encrypted = SymmetricEncryption::encrypt($input, $key);
$wrong_key = CreateKey::generateRandomKey();
// wrong key in class call
$crypt = new SymmetricEncryption($key);
$encrypted = $crypt->encrypt($input);
$this->expectExceptionMessage($exception_message);
SymmetricEncryption::decrypt($encrypted, $wrong_key);
$crypt->setKey($key);
$crypt->decrypt($encrypted);
// class instance
$encrypted = SymmetricEncryption::getInstance($key)->encrypt($input);
$this->expectExceptionMessage($exception_message);
SymmetricEncryption::getInstance($wrong_key)->decrypt($encrypted);
// class static
$encrypted = SymmetricEncryption::encryptKey($input, $key);
$this->expectExceptionMessage($exception_message);
SymmetricEncryption::decryptKey($encrypted, $wrong_key);
}
/**
@@ -107,7 +143,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
'too short hex key' => [
'key' => '1cabd5cba9e042f12522f4ff2de5c31d233b',
'excpetion_message' => 'Key is not the correct size (must be '
. 'SODIUM_CRYPTO_SECRETBOX_KEYBYTES bytes long).'
],
];
}
@@ -126,13 +161,33 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
*/
public function testWrongKey(string $key, string $exception_message): void
{
$this->expectExceptionMessage($exception_message);
SymmetricEncryption::encrypt('test', $key);
// we must encrypt valid thing first so we can fail with the wrong kjey
$enc_key = CreateKey::generateRandomKey();
$encrypted = SymmetricEncryption::encrypt('test', $enc_key);
// class
$crypt = new SymmetricEncryption($key);
$this->expectExceptionMessage($exception_message);
SymmetricEncryption::decrypt($encrypted, $key);
$crypt->encrypt('test');
$crypt->setKey($enc_key);
$encrypted = $crypt->encrypt('test');
$this->expectExceptionMessage($exception_message);
$crypt->setKey($key);
$crypt->decrypt($encrypted);
// class instance
$this->expectExceptionMessage($exception_message);
SymmetricEncryption::getInstance($key)->encrypt('test');
// we must encrypt valid thing first so we can fail with the wrong key
$encrypted = SymmetricEncryption::getInstance($enc_key)->encrypt('test');
$this->expectExceptionMessage($exception_message);
SymmetricEncryption::getInstance($key)->decrypt($encrypted);
// class static
$this->expectExceptionMessage($exception_message);
SymmetricEncryption::encryptKey('test', $key);
// we must encrypt valid thing first so we can fail with the wrong key
$encrypted = SymmetricEncryption::encryptKey('test', $enc_key);
$this->expectExceptionMessage($exception_message);
SymmetricEncryption::decryptKey($encrypted, $key);
}
/**
@@ -145,7 +200,7 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
return [
'too short ciphertext' => [
'input' => 'short',
'exception_message' => 'Invalid ciphertext (too short)'
'exception_message' => 'Decipher message failed: '
],
];
}
@@ -164,8 +219,18 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
public function testWrongCiphertext(string $input, string $exception_message): void
{
$key = CreateKey::generateRandomKey();
// class
$crypt = new SymmetricEncryption($key);
$this->expectExceptionMessage($exception_message);
SymmetricEncryption::decrypt($input, $key);
$crypt->decrypt($input);
// class instance
$this->expectExceptionMessage($exception_message);
SymmetricEncryption::getInstance($key)->decrypt($input);
// class static
$this->expectExceptionMessage($exception_message);
SymmetricEncryption::decryptKey($input, $key);
}
}

2
tmp/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*
!.gitignore

View File

@@ -1 +0,0 @@
/home/clemens/.phive/phars/phan-5.4.3.phar

View File

@@ -1 +0,0 @@
/home/clemens/.phive/phars/phpcbf-3.9.0.phar

View File

@@ -1 +0,0 @@
/home/clemens/.phive/phars/phpcs-3.9.0.phar

View File

@@ -1 +0,0 @@
/home/clemens/.phive/phars/phpstan-1.10.63.phar

View File

@@ -1 +0,0 @@
/home/clemens/.phive/phars/phpunit-9.6.17.phar

View File

@@ -1 +0,0 @@
/home/clemens/.phive/phars/psalm-5.23.1.phar