mirror of
https://gitee.com/hyperf/hyperf.git
synced 2024-12-02 03:37:44 +08:00
Merge branch 'master' into 2.1-merge
This commit is contained in:
commit
c405f177a7
@ -3,6 +3,13 @@
|
||||
## Added
|
||||
|
||||
- [#2857](https://github.com/hyperf/hyperf/pull/2857) Support Consul ACL Token for Service Governance.
|
||||
- [#2870](https://github.com/hyperf/hyperf/pull/2870) The publish option of `ConfigProvider` allows publish directory.
|
||||
- [#2875](https://github.com/hyperf/hyperf/pull/2875) Added option `no-restart` for watcher.
|
||||
|
||||
## Fixed
|
||||
|
||||
- [#2874](https://github.com/hyperf/hyperf/pull/2874) Fixed `scan.ignore_annotations` does not works when using watcher.
|
||||
- [#2878](https://github.com/hyperf/hyperf/pull/2878) Fixed config of nsqd does not works.
|
||||
|
||||
## Changed
|
||||
|
||||
@ -10,6 +17,7 @@
|
||||
|
||||
## Optimized
|
||||
|
||||
- [#2785](https://github.com/hyperf/hyperf/pull/2785) Optimized code for watcher.
|
||||
- [#2861](https://github.com/hyperf/hyperf/pull/2861) Optimized guzzle coroutine handler which throw exception when the status code below zero.
|
||||
- [#2868](https://github.com/hyperf/hyperf/pull/2868) Optimized code for guzzle sink, which support resource not only string.
|
||||
|
||||
|
@ -104,7 +104,6 @@
|
||||
"hyperf/di": "self.version",
|
||||
"hyperf/dispatcher": "self.version",
|
||||
"hyperf/elasticsearch": "self.version",
|
||||
"hyperf/encryption": "self.version",
|
||||
"hyperf/etcd": "self.version",
|
||||
"hyperf/event": "self.version",
|
||||
"hyperf/exception-handler": "self.version",
|
||||
@ -181,7 +180,6 @@
|
||||
"Hyperf\\Di\\": "src/di/src/",
|
||||
"Hyperf\\Dispatcher\\": "src/dispatcher/src/",
|
||||
"Hyperf\\Elasticsearch\\": "src/elasticsearch/src/",
|
||||
"Hyperf\\Encryption\\": "src/encryption/src/",
|
||||
"Hyperf\\Etcd\\": "src/etcd/src/",
|
||||
"Hyperf\\Event\\": "src/event/src/",
|
||||
"Hyperf\\ExceptionHandler\\": "src/exception-handler/src/",
|
||||
@ -264,7 +262,6 @@
|
||||
"HyperfTest\\Di\\": "src/di/tests/",
|
||||
"HyperfTest\\Dispatcher\\": "src/dispatcher/tests/",
|
||||
"HyperfTest\\Elasticsearch\\": "src/elasticsearch/tests/",
|
||||
"HyperfTest\\Encryption\\": "src/encryption/tests/",
|
||||
"HyperfTest\\Etcd\\": "src/etcd/tests/",
|
||||
"HyperfTest\\Event\\": "src/event/tests/",
|
||||
"HyperfTest\\ExceptionHandler\\": "src/exception-handler/tests/",
|
||||
@ -341,7 +338,6 @@
|
||||
"Hyperf\\Devtool\\ConfigProvider",
|
||||
"Hyperf\\Di\\ConfigProvider",
|
||||
"Hyperf\\Dispatcher\\ConfigProvider",
|
||||
"Hyperf\\Encryption\\ConfigProvider",
|
||||
"Hyperf\\Etcd\\ConfigProvider",
|
||||
"Hyperf\\Event\\ConfigProvider",
|
||||
"Hyperf\\ExceptionHandler\\ConfigProvider",
|
||||
|
@ -351,6 +351,7 @@ try{
|
||||
<?php
|
||||
|
||||
use Hyperf\DbConnection\Db;
|
||||
use Hyperf\Utils\Arr;
|
||||
use App\Model\Book;
|
||||
|
||||
// 启用 SQL 数据记录功能
|
||||
|
@ -1,37 +0,0 @@
|
||||
# 加密解密
|
||||
|
||||
[hyperf/encryption](https://github.com/hyperf/encryption) 借鉴于 `Laravel Encryption` 组件,十分感谢 `Laravel` 开发组对 `PHP` 社区的贡献。
|
||||
|
||||
## 简介
|
||||
|
||||
`Encryption` 是基于 `OpenSSL` 实现加密解密组件。
|
||||
|
||||
## 配置
|
||||
|
||||
加密器可以根据实际情况,配置多组 `key` 和 `cipher`。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
return [
|
||||
'default' => [
|
||||
'key' => 'Hyperf',
|
||||
'cipher' => 'AES-128-CBC',
|
||||
],
|
||||
];
|
||||
|
||||
```
|
||||
|
||||
## 使用
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Hyperf\Utils\ApplicationContext;
|
||||
use Hyperf\Encryption\Contract\EncrypterInterface;
|
||||
|
||||
$input = 'Hello Word.';
|
||||
$container = ApplicationContext::getContainer();
|
||||
$encrypter = $container->get(EncrypterInterface::class);
|
||||
$encrypt = $encrypter->encrypt($input);
|
||||
$raw = $encrypter->decrypt($encrypt);
|
||||
```
|
@ -4,8 +4,10 @@
|
||||
|
||||
| 版本 | 状态 | 积极支持截止时间 | 安全维护截止时间 | 发布或预计发布时间 |
|
||||
| ---- | -------- | ---------------- | ---------------- | ------------------ |
|
||||
| 2.0 | 积极支持中 | / | / | 2020-06-22 |
|
||||
| 1.1 | 安全维护中 | 2020-06-23 | 2020-12-31 | |
|
||||
| 3.0 | 研发中 | / | / | 2021-06-20 |
|
||||
| 2.1 | Beta版试用中 | / | / | 2020-12-31 |
|
||||
| 2.0 | 积极支持中 | 2020-12-31 | 2021-06-30 | 2020-06-22 |
|
||||
| 1.1 | 安全维护中 | 2020-06-23 | 2020-12-31 | 2019-10-08 |
|
||||
| 1.0 | 停止维护 | 2019-10-08 | 2019-12-31 | 2019-06-20 |
|
||||
|
||||
* 积极支持将包含常规迭代周期的 BUG 修复、安全问题修复、功能迭代和功能新增;
|
||||
|
@ -116,7 +116,6 @@
|
||||
* [Watcher](zh-cn/watcher.md)
|
||||
* [开发者工具](zh-cn/devtool.md)
|
||||
* [Swoole Tracker](zh-cn/swoole-tracker.md)
|
||||
* [加密解密](zh-cn/encryption.md)
|
||||
|
||||
* 应用部署
|
||||
|
||||
|
@ -25,7 +25,6 @@
|
||||
<directory suffix="Test.php">./src/di/tests</directory>
|
||||
<directory suffix="Test.php">./src/dispatcher/tests</directory>
|
||||
<directory suffix="Test.php">./src/elasticsearch/tests</directory>
|
||||
<directory suffix="Test.php">./src/encryption/tests</directory>
|
||||
<directory suffix="Test.php">./src/etcd/tests</directory>
|
||||
<directory suffix="Test.php">./src/event/tests</directory>
|
||||
<directory suffix="Test.php">./src/exception-handler/tests</directory>
|
||||
@ -39,6 +38,7 @@
|
||||
<directory suffix="Test.php">./src/logger/tests</directory>
|
||||
<directory suffix="Test.php">./src/metric/tests</directory>
|
||||
<directory suffix="Test.php">./src/model-cache/tests</directory>
|
||||
<directory suffix="Test.php">./src/nsq/tests</directory>
|
||||
<directory suffix="Test.php">./src/paginator/tests</directory>
|
||||
<directory suffix="Test.php">./src/pool/tests</directory>
|
||||
<directory suffix="Test.php">./src/process/tests</directory>
|
||||
@ -81,7 +81,6 @@
|
||||
<directory suffix=".php">./src/di/src</directory>
|
||||
<directory suffix=".php">./src/dispatcher/src</directory>
|
||||
<directory suffix=".php">./src/elasticsearch/src</directory>
|
||||
<directory suffix=".php">./src/encryption/src</directory>
|
||||
<directory suffix=".php">./src/event/src</directory>
|
||||
<directory suffix=".php">./src/grpc-client/src</directory>
|
||||
<directory suffix=".php">./src/guzzle/src</directory>
|
||||
|
@ -14,6 +14,7 @@ namespace Hyperf\Devtool;
|
||||
use Hyperf\Command\Annotation\Command;
|
||||
use Hyperf\Utils\Arr;
|
||||
use Hyperf\Utils\Composer;
|
||||
use Hyperf\Utils\Filesystem\Filesystem;
|
||||
use Symfony\Component\Console\Command\Command as SymfonyCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
@ -35,9 +36,15 @@ class VendorPublishCommand extends SymfonyCommand
|
||||
*/
|
||||
protected $force = false;
|
||||
|
||||
public function __construct()
|
||||
/**
|
||||
* @var Filesystem
|
||||
*/
|
||||
protected $filesystem;
|
||||
|
||||
public function __construct(Filesystem $filesystem)
|
||||
{
|
||||
parent::__construct('vendor:publish');
|
||||
$this->filesystem = $filesystem;
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
@ -110,15 +117,20 @@ class VendorPublishCommand extends SymfonyCommand
|
||||
$source = $item['source'];
|
||||
$destination = $item['destination'];
|
||||
|
||||
if (! $this->force && file_exists($destination)) {
|
||||
if (! $this->force && $this->filesystem->exists($destination)) {
|
||||
$this->output->writeln(sprintf('<fg=red>[%s] already exists.</>', $destination));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! file_exists(dirname($destination))) {
|
||||
mkdir(dirname($destination), 0755, true);
|
||||
if (! $this->filesystem->exists($dirname = dirname($destination))) {
|
||||
$this->filesystem->makeDirectory($dirname, 0755, true);
|
||||
}
|
||||
|
||||
if ($this->filesystem->isDirectory($source)) {
|
||||
$this->filesystem->copyDirectory($source, $destination);
|
||||
} else {
|
||||
$this->filesystem->copy($source, $destination);
|
||||
}
|
||||
copy($source, $destination);
|
||||
|
||||
$this->output->writeln(sprintf('<fg=green>[%s] publishes [%s] successfully.</>', $package, $id));
|
||||
}
|
||||
|
2
src/encryption/.gitattributes
vendored
2
src/encryption/.gitattributes
vendored
@ -1,2 +0,0 @@
|
||||
/tests export-ignore
|
||||
/.github export-ignore
|
25
src/encryption/.github/workflows/release.yml
vendored
25
src/encryption/.github/workflows/release.yml
vendored
@ -1,25 +0,0 @@
|
||||
on:
|
||||
push:
|
||||
# Sequence of patterns matched against refs/tags
|
||||
tags:
|
||||
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
|
||||
|
||||
name: Release
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: Release ${{ github.ref }}
|
||||
draft: false
|
||||
prerelease: false
|
@ -1,22 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Taylor Otwell
|
||||
Copyright (c) Hyperf
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -1,36 +0,0 @@
|
||||
{
|
||||
"name": "hyperf/encryption",
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"php",
|
||||
"hyperf",
|
||||
"encryption"
|
||||
],
|
||||
"description": "",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Hyperf\\Encryption\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"HyperfTest\\Encryption\\": "tests/"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"ext-json": "*",
|
||||
"ext-openssl": "*",
|
||||
"hyperf/contract": "~2.0.0",
|
||||
"psr/container": "^1.0"
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
},
|
||||
"extra": {
|
||||
"hyperf": {
|
||||
"config": "Hyperf\\Encryption\\ConfigProvider"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
return [
|
||||
'default' => [
|
||||
'key' => 'Hyperf',
|
||||
'cipher' => 'AES-128-CBC',
|
||||
],
|
||||
];
|
@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Encryption;
|
||||
|
||||
use Hyperf\Encryption\Contract\EncrypterInterface;
|
||||
|
||||
class ConfigProvider
|
||||
{
|
||||
public function __invoke(): array
|
||||
{
|
||||
return [
|
||||
'dependencies' => [
|
||||
EncrypterInterface::class => EncrypterInvoker::class,
|
||||
],
|
||||
'publish' => [
|
||||
[
|
||||
'id' => 'config',
|
||||
'description' => 'The config for encryption.',
|
||||
'source' => __DIR__ . '/../publish/encryption.php',
|
||||
'destination' => BASE_PATH . '/config/autoload/encryption.php',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Encryption\Contract;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
interface EncrypterInterface
|
||||
{
|
||||
/**
|
||||
* Encrypt the given value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function encrypt($value, bool $serialize = true): string;
|
||||
|
||||
/**
|
||||
* Decrypt the given value.
|
||||
*
|
||||
* @throws RuntimeException
|
||||
* @return mixed
|
||||
*/
|
||||
public function decrypt(string $payload, bool $unserialize = true);
|
||||
}
|
@ -1,229 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Encryption;
|
||||
|
||||
use Hyperf\Encryption\Contract\EncrypterInterface;
|
||||
use Hyperf\Encryption\Exception\DecryptException;
|
||||
use Hyperf\Encryption\Exception\EncryptException;
|
||||
use Hyperf\Encryption\Exception\InvalidArgumentException;
|
||||
|
||||
class Encrypter implements EncrypterInterface
|
||||
{
|
||||
/**
|
||||
* The encryption key.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $key;
|
||||
|
||||
/**
|
||||
* The algorithm used for encryption.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $cipher;
|
||||
|
||||
public function __construct(string $key, string $cipher = 'AES-128-CBC')
|
||||
{
|
||||
if (empty($key)) {
|
||||
throw new InvalidArgumentException('Encrypter key Not Set');
|
||||
}
|
||||
|
||||
if (! in_array(strtolower($cipher), openssl_get_cipher_methods())) {
|
||||
throw new InvalidArgumentException('Encrypter ciphers Not supported');
|
||||
}
|
||||
|
||||
$this->key = $key;
|
||||
$this->cipher = $cipher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt the given value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function encrypt($value, bool $serialize = true): string
|
||||
{
|
||||
$iv = random_bytes(openssl_cipher_iv_length($this->cipher));
|
||||
|
||||
// First we will encrypt the value using OpenSSL. After this is encrypted we
|
||||
// will proceed to calculating a MAC for the encrypted value so that this
|
||||
// value can be verified later as not having been changed by the users.
|
||||
$value = \openssl_encrypt(
|
||||
$serialize ? serialize($value) : $value,
|
||||
$this->cipher,
|
||||
$this->key,
|
||||
0,
|
||||
$iv
|
||||
);
|
||||
|
||||
if ($value === false) {
|
||||
throw new EncryptException('Could not encrypt the data.');
|
||||
}
|
||||
|
||||
// Once we get the encrypted value we'll go ahead and base64_encode the input
|
||||
// vector and create the MAC for the encrypted value so we can then verify
|
||||
// its authenticity. Then, we'll JSON the data into the "payload" array.
|
||||
$mac = $this->hash($iv = base64_encode($iv), $value);
|
||||
|
||||
$json = json_encode(compact('iv', 'value', 'mac'), JSON_UNESCAPED_SLASHES);
|
||||
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
throw new EncryptException('Could not encrypt the data.');
|
||||
}
|
||||
|
||||
return base64_encode($json);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt a string without serialization.
|
||||
*
|
||||
* @param string $value
|
||||
* @throws \Exception
|
||||
* @return string
|
||||
*/
|
||||
public function encryptString($value)
|
||||
{
|
||||
return $this->encrypt($value, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt the given value.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function decrypt(string $payload, bool $unserialize = true)
|
||||
{
|
||||
$payload = $this->getJsonPayload($payload);
|
||||
|
||||
$iv = base64_decode($payload['iv']);
|
||||
|
||||
// Here we will decrypt the value. If we are able to successfully decrypt it
|
||||
// we will then unserialize it and return it out to the caller. If we are
|
||||
// unable to decrypt this value we will throw out an exception message.
|
||||
$decrypted = \openssl_decrypt(
|
||||
$payload['value'],
|
||||
$this->cipher,
|
||||
$this->key,
|
||||
0,
|
||||
$iv
|
||||
);
|
||||
|
||||
if ($decrypted === false) {
|
||||
throw new DecryptException('Could not decrypt the data.');
|
||||
}
|
||||
|
||||
return $unserialize ? unserialize($decrypted) : $decrypted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt the given string without unserialization.
|
||||
*
|
||||
* @param string $payload
|
||||
* @return string
|
||||
*/
|
||||
public function decryptString($payload)
|
||||
{
|
||||
return $this->decrypt($payload, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the encryption key.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getKey()
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a MAC for the given value.
|
||||
*
|
||||
* @param string $iv
|
||||
* @param mixed $value
|
||||
* @return string
|
||||
*/
|
||||
protected function hash($iv, $value)
|
||||
{
|
||||
return hash_hmac('sha256', $iv . $value, $this->key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the JSON array from the given payload.
|
||||
*
|
||||
* @param string $payload
|
||||
* @return array
|
||||
*/
|
||||
protected function getJsonPayload($payload)
|
||||
{
|
||||
$payload = json_decode(base64_decode($payload), true);
|
||||
|
||||
// If the payload is not valid JSON or does not have the proper keys set we will
|
||||
// assume it is invalid and bail out of the routine since we will not be able
|
||||
// to decrypt the given value. We'll also check the MAC for this encryption.
|
||||
if (! $this->validPayload($payload)) {
|
||||
throw new DecryptException('The payload is invalid.');
|
||||
}
|
||||
|
||||
if (! $this->validMac($payload)) {
|
||||
throw new DecryptException('The MAC is invalid.');
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that the encryption payload is valid.
|
||||
*
|
||||
* @param mixed $payload
|
||||
* @return bool
|
||||
*/
|
||||
protected function validPayload($payload)
|
||||
{
|
||||
return is_array($payload) && isset($payload['iv'], $payload['value'], $payload['mac']) &&
|
||||
strlen(base64_decode($payload['iv'], true)) === openssl_cipher_iv_length($this->cipher);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the MAC for the given payload is valid.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validMac(array $payload)
|
||||
{
|
||||
$calculated = $this->calculateMac($payload, $bytes = random_bytes(16));
|
||||
|
||||
return hash_equals(
|
||||
hash_hmac('sha256', $payload['mac'], $bytes, true),
|
||||
$calculated
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the hash of the given payload.
|
||||
*
|
||||
* @param array $payload
|
||||
* @param string $bytes
|
||||
* @return string
|
||||
*/
|
||||
protected function calculateMac($payload, $bytes)
|
||||
{
|
||||
return hash_hmac(
|
||||
'sha256',
|
||||
$this->hash($payload['iv'], $payload['value']),
|
||||
$bytes,
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Encryption;
|
||||
|
||||
use Hyperf\Contract\ConfigInterface;
|
||||
use Hyperf\Encryption\Contract\EncrypterInterface;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
class EncrypterFactory
|
||||
{
|
||||
/**
|
||||
* @var ConfigInterface
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->config = $container->get(ConfigInterface::class);
|
||||
}
|
||||
|
||||
public function get(string $name): EncrypterInterface
|
||||
{
|
||||
$encryption = $this->config->get('encryption.' . $name, []);
|
||||
$key = $encryption['key'] ?? '';
|
||||
$cipher = $encryption['cipher'] ?? 'AES-128-CBC';
|
||||
|
||||
return new Encrypter($key, $cipher);
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Encryption;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
class EncrypterInvoker
|
||||
{
|
||||
public function __invoke(ContainerInterface $container)
|
||||
{
|
||||
$factory = $container->get(EncrypterFactory::class);
|
||||
|
||||
return $factory->get('default');
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Encryption\Exception;
|
||||
|
||||
class DecryptException extends \RuntimeException
|
||||
{
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Encryption\Exception;
|
||||
|
||||
class EncryptException extends \RuntimeException
|
||||
{
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Encryption\Exception;
|
||||
|
||||
class InvalidArgumentException extends \InvalidArgumentException
|
||||
{
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace HyperfTest\Encryption;
|
||||
|
||||
use Hyperf\Config\Config;
|
||||
use Hyperf\Contract\ConfigInterface;
|
||||
use Hyperf\Encryption\Contract\EncrypterInterface;
|
||||
use Hyperf\Encryption\EncrypterFactory;
|
||||
use Hyperf\Encryption\EncrypterInvoker;
|
||||
use Hyperf\Utils\ApplicationContext;
|
||||
use Mockery;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @coversNothing
|
||||
*/
|
||||
class EncrypterTest extends TestCase
|
||||
{
|
||||
protected function tearDown(): void
|
||||
{
|
||||
Mockery::close();
|
||||
}
|
||||
|
||||
public function mockContainer(): ContainerInterface
|
||||
{
|
||||
$container = Mockery::mock(ContainerInterface::class);
|
||||
ApplicationContext::setContainer($container);
|
||||
$config = new Config([
|
||||
'encryption' => [
|
||||
'default' => [
|
||||
'key' => '123456',
|
||||
'cipher' => 'AES-256-CBC',
|
||||
],
|
||||
],
|
||||
]);
|
||||
$container->shouldReceive('get')->with(ConfigInterface::class)->andReturn($config);
|
||||
$container->shouldReceive('get')->with(EncrypterFactory::class)->andReturnUsing(function () use ($container) {
|
||||
return new EncrypterFactory($container);
|
||||
});
|
||||
$container->shouldReceive('get')->with(EncrypterInterface::class)->andReturnUsing(function () use ($container) {
|
||||
return (new EncrypterInvoker())($container);
|
||||
});
|
||||
return $container;
|
||||
}
|
||||
|
||||
public function testEncodeString()
|
||||
{
|
||||
$input = 'Hello Word.';
|
||||
$container = $this->mockContainer();
|
||||
$encrypter = $container->get(EncrypterInterface::class);
|
||||
$encrypt = $encrypter->encryptString($input);
|
||||
$this->assertSame($input, $encrypter->decryptString($encrypt));
|
||||
}
|
||||
|
||||
public function testEncodeObject()
|
||||
{
|
||||
$input = range(1, 3);
|
||||
$container = $this->mockContainer();
|
||||
$encrypter = $container->get(EncrypterInterface::class);
|
||||
$encrypt = $encrypter->encrypt($input);
|
||||
$this->assertSame($input, $encrypter->decrypt($encrypt));
|
||||
}
|
||||
}
|
@ -22,9 +22,9 @@ class Client implements ClientInterface
|
||||
*/
|
||||
protected $options = [];
|
||||
|
||||
public function __construct(ConfigInterface $config)
|
||||
public function __construct(ConfigInterface $config, string $pool = 'default')
|
||||
{
|
||||
$nsq = $config->get('nsq', []);
|
||||
$nsq = $config->get('nsq.' . $pool, []);
|
||||
$options = $nsq['nsqd']['options'] ?? [];
|
||||
if (! isset($options['base_uri'])) {
|
||||
$options['base_uri'] = sprintf('http://%s:%s', $nsq['host'] ?? '127.0.0.1', $nsq['nsqd']['port'] ?? 4151);
|
||||
|
@ -61,7 +61,7 @@ class ConsumerManagerTest extends TestCase
|
||||
$hasRegistered = true;
|
||||
/** @var AbstractConsumer $consumer */
|
||||
$consumer = $item->getConsumer();
|
||||
$this->assertTrue($item->isEnable());
|
||||
$this->assertTrue($item->isEnable(new \stdClass()));
|
||||
$this->assertSame($name, $consumer->getName());
|
||||
$this->assertSame($channel, $consumer->getChannel());
|
||||
$this->assertSame($topic, $consumer->getTopic());
|
||||
@ -96,7 +96,7 @@ class ConsumerManagerTest extends TestCase
|
||||
foreach (ProcessManager::all() as $item) {
|
||||
if (method_exists($item, 'getConsumer')) {
|
||||
/* @var AbstractConsumer $consumer */
|
||||
$this->assertFalse($item->isEnable());
|
||||
$this->assertFalse($item->isEnable(new \stdClass()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -123,7 +123,7 @@ class ConsumerManagerTest extends TestCase
|
||||
$manager->run();
|
||||
foreach (ProcessManager::all() as $item) {
|
||||
if (method_exists($item, 'getConsumer') && ($item->getConsumer() instanceof DisabledDemoConsumer)) {
|
||||
$this->assertFalse($item->isEnable());
|
||||
$this->assertFalse($item->isEnable(new \stdClass()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ declare(strict_types=1);
|
||||
*/
|
||||
namespace HyperfTest\Nsq;
|
||||
|
||||
use Hyperf\Contract\ConfigInterface;
|
||||
use Hyperf\Config\Config;
|
||||
use Hyperf\Guzzle\CoroutineHandler;
|
||||
use Hyperf\Nsq\Nsqd\Client;
|
||||
use HyperfTest\Nsq\Stub\CoroutineHandlerStub;
|
||||
@ -31,9 +31,7 @@ class HttpClientTest extends TestCase
|
||||
|
||||
public function testHttpClientWithEmptyConfig()
|
||||
{
|
||||
$config = Mockery::mock(ConfigInterface::class);
|
||||
$config->shouldReceive('get')->with('nsq', [])->andReturn([]);
|
||||
|
||||
$config = new Config([]);
|
||||
$client = new Client($config);
|
||||
$this->assertSame('http://127.0.0.1:4151', $client->getOptions()['base_uri']);
|
||||
$this->assertInstanceOf(CoroutineHandler::class, $client->getOptions()['handler']);
|
||||
@ -41,11 +39,14 @@ class HttpClientTest extends TestCase
|
||||
|
||||
public function testHttpClientWithHost()
|
||||
{
|
||||
$config = Mockery::mock(ConfigInterface::class);
|
||||
$config->shouldReceive('get')->with('nsq', [])->andReturn([
|
||||
'host' => '192.168.1.1',
|
||||
'nsqd' => [
|
||||
'port' => 14151,
|
||||
$config = new Config([
|
||||
'nsq' => [
|
||||
'default' => [
|
||||
'host' => '192.168.1.1',
|
||||
'nsqd' => [
|
||||
'port' => 14151,
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
@ -56,12 +57,15 @@ class HttpClientTest extends TestCase
|
||||
|
||||
public function testHttpClientWithOptions()
|
||||
{
|
||||
$config = Mockery::mock(ConfigInterface::class);
|
||||
$config->shouldReceive('get')->with('nsq', [])->andReturn([
|
||||
'nsqd' => [
|
||||
'options' => [
|
||||
'base_uri' => 'https://nsq.hyperf.io',
|
||||
'handler' => new CoroutineHandlerStub(),
|
||||
$config = new Config([
|
||||
'nsq' => [
|
||||
'default' => [
|
||||
'nsqd' => [
|
||||
'options' => [
|
||||
'base_uri' => 'https://nsq.hyperf.io',
|
||||
'handler' => new CoroutineHandlerStub(),
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
@ -435,7 +435,7 @@ class Filesystem
|
||||
// As we spin through items, we will check to see if the current file is actually
|
||||
// a directory or a file. When it is actually a directory we will need to call
|
||||
// back into this function recursively to keep copying these nested folders.
|
||||
$target = $destination . '/' . $item->getBasename();
|
||||
$target = $destination . DIRECTORY_SEPARATOR . $item->getBasename();
|
||||
|
||||
if ($item->isDir()) {
|
||||
$path = $item->getPathname();
|
||||
|
@ -29,6 +29,7 @@ class WatchCommand extends Command
|
||||
$this->setDescription('watch command');
|
||||
$this->addOption('file', 'F', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, '', []);
|
||||
$this->addOption('dir', 'D', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, '', []);
|
||||
$this->addOption('no-restart', 'N', InputOption::VALUE_NONE, 'Whether no need to restart server');
|
||||
}
|
||||
|
||||
public function handle()
|
||||
@ -36,6 +37,7 @@ class WatchCommand extends Command
|
||||
$option = make(Option::class, [
|
||||
'dir' => $this->input->getOption('dir'),
|
||||
'file' => $this->input->getOption('file'),
|
||||
'restart' => ! $this->input->getOption('no-restart'),
|
||||
]);
|
||||
|
||||
$watcher = make(Watcher::class, [
|
||||
|
@ -92,12 +92,12 @@ class FindDriver implements DriverInterface
|
||||
$dest = implode(' ', $targets);
|
||||
$ret = System::exec($this->getBin() . ' ' . $dest . ' -mmin ' . $minutes . ' -type f -print');
|
||||
if ($ret['code'] === 0 && strlen($ret['output'])) {
|
||||
$stdout = $ret['output'];
|
||||
$stdout = trim($ret['output']);
|
||||
|
||||
$lineArr = explode(PHP_EOL, $stdout);
|
||||
foreach ($lineArr as $line) {
|
||||
$pathName = $line;
|
||||
$modifyTime = fileatime($pathName);
|
||||
$modifyTime = filemtime($pathName);
|
||||
// modifyTime less than or equal to startTime continue
|
||||
if ($modifyTime <= $this->startTime) {
|
||||
continue;
|
||||
|
@ -69,7 +69,9 @@ class FswatchDriver implements DriverInterface
|
||||
|
||||
$cmd = 'fswatch ';
|
||||
if (! $this->isDarwin) {
|
||||
$cmd .= '-m inotify_monitor ';
|
||||
$cmd .= ' -m inotify_monitor';
|
||||
$cmd .= " -E --format '%p' -r ";
|
||||
$cmd .= ' --event Created --event Updated --event Removed --event Renamed ';
|
||||
}
|
||||
|
||||
return $cmd . implode(' ', $dir) . ' ' . implode(' ', $file);
|
||||
|
@ -46,7 +46,12 @@ class Option
|
||||
*/
|
||||
protected $scanInterval = 2000;
|
||||
|
||||
public function __construct(ConfigInterface $config, array $dir, array $file)
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $restart = true;
|
||||
|
||||
public function __construct(ConfigInterface $config, array $dir, array $file, bool $restart = true)
|
||||
{
|
||||
$options = $config->get('watcher', []);
|
||||
|
||||
@ -59,6 +64,7 @@ class Option
|
||||
|
||||
$this->watchDir = array_unique(array_merge($this->watchDir, $dir));
|
||||
$this->watchFile = array_unique(array_merge($this->watchFile, $file));
|
||||
$this->restart = $restart;
|
||||
}
|
||||
|
||||
public function getDriver(): string
|
||||
@ -90,4 +96,9 @@ class Option
|
||||
{
|
||||
return $this->scanInterval > 0 ? $this->scanInterval : 2000;
|
||||
}
|
||||
|
||||
public function isRestart(): bool
|
||||
{
|
||||
return $this->restart;
|
||||
}
|
||||
}
|
||||
|
@ -68,8 +68,8 @@ class Process
|
||||
$this->file = $file;
|
||||
$this->ast = new Ast();
|
||||
$this->reflection = new BetterReflection();
|
||||
$this->config = $this->initScanConfig();
|
||||
$this->reader = new AnnotationReader();
|
||||
$this->config = ScanConfig::instance('/');
|
||||
$this->filesystem = new Filesystem();
|
||||
}
|
||||
|
||||
@ -177,4 +177,16 @@ class Process
|
||||
}
|
||||
return $meta;
|
||||
}
|
||||
|
||||
protected function initScanConfig(): ScanConfig
|
||||
{
|
||||
$config = ScanConfig::instance(BASE_PATH . '/config/');
|
||||
foreach ($config->getIgnoreAnnotations() as $annotation) {
|
||||
AnnotationReader::addGlobalIgnoredName($annotation);
|
||||
}
|
||||
foreach ($config->getGlobalImports() as $alias => $annotation) {
|
||||
AnnotationReader::addGlobalImports($alias, $annotation);
|
||||
}
|
||||
return $config;
|
||||
}
|
||||
}
|
||||
|
@ -133,6 +133,9 @@ class Watcher
|
||||
$ret = System::exec($this->option->getBin() . ' vendor/hyperf/watcher/collector-reload.php ' . $file);
|
||||
if ($ret['code'] === 0) {
|
||||
$this->output->writeln('Class reload success.');
|
||||
} else {
|
||||
$this->output->writeln('Class reload failed.');
|
||||
$this->output->writeln($ret['output'] ?? '');
|
||||
}
|
||||
$result[] = $file;
|
||||
}
|
||||
@ -147,6 +150,9 @@ class Watcher
|
||||
|
||||
public function restart($isStart = true)
|
||||
{
|
||||
if (! $this->option->isRestart()) {
|
||||
return;
|
||||
}
|
||||
$file = $this->config->get('server.settings.pid_file');
|
||||
if (empty($file)) {
|
||||
throw new FileNotFoundException('The config of pid_file is not found.');
|
||||
|
Loading…
Reference in New Issue
Block a user