diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 35d51f04..964b63a2 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: Create Release
id: create_release
uses: actions/create-release@v1
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index e2edafc0..ab13a512 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -20,7 +20,7 @@ jobs:
swoole: [ 'swoole' ]
steps:
- name: Checkout
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
diff --git a/composer.json b/composer.json
index b292af6e..2923d686 100644
--- a/composer.json
+++ b/composer.json
@@ -92,9 +92,6 @@
"mineadmin/app-store": "*",
"mineadmin/crontab": "*",
"mineadmin/http-server": "*",
- "mineadmin/security-access": "*",
- "mineadmin/security-bundle": "*",
- "mineadmin/security-http": "*",
"mineadmin/support": "*"
},
"minimum-stability": "dev",
@@ -110,9 +107,6 @@
"Mine\\Helper\\": "src/mine-helpers/src/",
"Mine\\HttpServer\\": "src/HttpServer/src/",
"Mine\\Office\\": "src/office/src/",
- "Mine\\SecurityBundle\\": "src/SecurityBundle/src/",
- "Mine\\Security\\Access\\": "src/SecurityAccess/src/",
- "Mine\\Security\\Http\\": "src/SecurityHttp/src/",
"Mine\\Support\\": "src/Support/src/",
"Mine\\Translatable\\": "src/translatable/src/",
"Xmo\\JWTAuth\\": "src/jwt-auth/src/"
@@ -126,9 +120,6 @@
"psr-4": {
"Mine\\Crontab\\Tests\\": "src/Crontab/tests/",
"Mine\\HttpServer\\Tests\\": "src/HttpServer/tests/",
- "Mine\\SecurityBundle\\Tests\\": "src/SecurityBundle/tests/",
- "Mine\\Security\\Access\\Tests\\": "src/SecurityAccess/tests/",
- "Mine\\Security\\Http\\Tests\\": "src/SecurityHttp/tests/",
"Mine\\Support\\Tests\\": "src/Support/tests/",
"Mine\\Tests\\": "tests/",
"Mine\\Translatable\\": "src/translatable/tests/"
@@ -152,8 +143,6 @@
"Mine\\Generator\\GeneratorConfigProvider",
"Mine\\Generator\\GeneratorConfigProvider",
"Mine\\HttpServer\\ConfigProvider",
- "Mine\\SecurityBundle\\ConfigProvider",
- "Mine\\Security\\Http\\ConfigProvider",
"Mine\\Support\\ConfigProvider",
"Mine\\Translatable\\ConfigProvider",
"Xmo\\JWTAuth\\ConfigProvider"
diff --git a/src/SecurityAccess/.gitattributes b/src/SecurityAccess/.gitattributes
deleted file mode 100644
index ce244ab1..00000000
--- a/src/SecurityAccess/.gitattributes
+++ /dev/null
@@ -1,2 +0,0 @@
-/tests export-ignore
-/.github export-ignore
\ No newline at end of file
diff --git a/src/SecurityAccess/.github/workflows/close-pull-request.yml b/src/SecurityAccess/.github/workflows/close-pull-request.yml
deleted file mode 100644
index c8182b84..00000000
--- a/src/SecurityAccess/.github/workflows/close-pull-request.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-name: Close Pull Request
-
-on:
- pull_request_target:
- types: [ opened ]
-
-jobs:
- run:
- runs-on: ubuntu-latest
- steps:
- - uses: superbrothers/close-pull-request@v3
- with:
- comment: "Hi, this is a READ-ONLY repository, please submit your PR on the https://github.com/mineadmin/components repository.
This Pull Request will close automatically.
Thanks! "
\ No newline at end of file
diff --git a/src/SecurityAccess/.github/workflows/release.yml b/src/SecurityAccess/.github/workflows/release.yml
deleted file mode 100644
index 2fc8404b..00000000
--- a/src/SecurityAccess/.github/workflows/release.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-on:
- push:
- 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@v4
- - 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
\ No newline at end of file
diff --git a/src/SecurityAccess/LICENSE b/src/SecurityAccess/LICENSE
deleted file mode 100644
index c5722457..00000000
--- a/src/SecurityAccess/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2024 MineAdmin
-
-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.
\ No newline at end of file
diff --git a/src/SecurityAccess/README.md b/src/SecurityAccess/README.md
deleted file mode 100644
index 307e2a5a..00000000
--- a/src/SecurityAccess/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# 基于 mineadmin/security-bundle 提供安全访问控制
\ No newline at end of file
diff --git a/src/SecurityAccess/composer.json b/src/SecurityAccess/composer.json
deleted file mode 100644
index ca6c9968..00000000
--- a/src/SecurityAccess/composer.json
+++ /dev/null
@@ -1,39 +0,0 @@
-{
- "name": "mineadmin/security-access",
- "description": "Security Access Component",
- "license": "MIT",
- "type": "library",
- "authors": [
- {
- "name": "xmo",
- "email": "root@imoi.cn",
- "role": "Developer"
- },
- {
- "name": "zds",
- "email": "2771717608@qq.com",
- "role": "Developer"
- }
- ],
- "require": {
- "php": ">=8.1",
- "casbin/casbin": "^3.21",
- "friendsofhyperf/facade": "^3.1",
- "mineadmin/security-bundle": "2.0.x-dev"
- },
- "autoload": {
- "psr-4": {
- "Mine\\Security\\Access\\": "src/"
- }
- },
- "autoload-dev": {
- "psr-4": {
- "Mine\\Security\\Access\\Tests\\": "tests/"
- }
- },
- "extra": {
- "config": {
- "hyperf": "Mine\\Security\\Access\\ConfigProvider"
- }
- }
-}
\ No newline at end of file
diff --git a/src/SecurityAccess/publish/access.php b/src/SecurityAccess/publish/access.php
deleted file mode 100644
index 74b12829..00000000
--- a/src/SecurityAccess/publish/access.php
+++ /dev/null
@@ -1,25 +0,0 @@
- 'rbac',
- 'component' => [
- 'rbac' => [
- 'construct' => [
- __DIR__ . '/rbac_model.conf',
- __DIR__ . '/rbac_policy.csv',
- ],
- 'enforcer' => Enforcer::class,
- ],
- ],
-];
diff --git a/src/SecurityAccess/publish/rbac_model.conf b/src/SecurityAccess/publish/rbac_model.conf
deleted file mode 100644
index 71159e38..00000000
--- a/src/SecurityAccess/publish/rbac_model.conf
+++ /dev/null
@@ -1,14 +0,0 @@
-[request_definition]
-r = sub, obj, act
-
-[policy_definition]
-p = sub, obj, act
-
-[role_definition]
-g = _, _
-
-[policy_effect]
-e = some(where (p.eft == allow))
-
-[matchers]
-m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
\ No newline at end of file
diff --git a/src/SecurityAccess/publish/rbac_policy.csv b/src/SecurityAccess/publish/rbac_policy.csv
deleted file mode 100644
index e69de29b..00000000
diff --git a/src/SecurityAccess/src/ConfigProvider.php b/src/SecurityAccess/src/ConfigProvider.php
deleted file mode 100644
index a93c4730..00000000
--- a/src/SecurityAccess/src/ConfigProvider.php
+++ /dev/null
@@ -1,47 +0,0 @@
- [
- Access::class => Manager::class,
- ],
- 'publish' => [
- [
- 'id' => 'access rbac conf',
- 'description' => 'Access Rbac Conf',
- 'source' => __DIR__ . '/../publish/access.php',
- 'destination' => BASE_PATH . '/config/autoload/access.php',
- ],
- [
- 'id' => 'access rbac model conf',
- 'description' => 'Access Rbac Model Conf',
- 'source' => __DIR__ . '/../publish/rbac_model.conf',
- 'destination' => BASE_PATH . '/config/autoload/rbac_model.conf',
- ],
- [
- 'id' => 'access rbac policy csv',
- 'description' => 'Access Rbac Policy csv',
- 'source' => __DIR__ . '/../publish/rbac_policy.csv',
- 'destination' => BASE_PATH . '/config/autoload/rbac_policy.csv',
- ],
- ],
- ];
- }
-}
diff --git a/src/SecurityAccess/src/Contract/Access.php b/src/SecurityAccess/src/Contract/Access.php
deleted file mode 100644
index c279ffe5..00000000
--- a/src/SecurityAccess/src/Contract/Access.php
+++ /dev/null
@@ -1,24 +0,0 @@
-getConfig('default');
- }
- return $this->getAdapter($name);
- }
-
- protected function getConfig(string $key, mixed $default = null): mixed
- {
- return $this->config->get('access.' . $key, $default);
- }
-
- protected function getAdapter(string $name): Enforcer
- {
- $adapter = $this->getConfig('component.' . $name);
- if (empty($adapter)) {
- throw new AccessException(sprintf('Access adapter [%s] not exists.', $name));
- }
- if (empty($adapter['construct']) || empty($adapter['enforcer'])) {
- throw new AccessException(sprintf('Access adapter [%s] construct or enforcer not exists.', $name));
- }
- $construct = $adapter['construct'];
- $enforcer = $adapter['enforcer'];
- return new $enforcer(...$construct);
- }
-}
diff --git a/src/SecurityAccess/src/Rbac.php b/src/SecurityAccess/src/Rbac.php
deleted file mode 100644
index 11b6b7a0..00000000
--- a/src/SecurityAccess/src/Rbac.php
+++ /dev/null
@@ -1,36 +0,0 @@
-getAccess()->get('rbac')->{$name}(...$arguments);
- }
-
- public function getAccess(): Access
- {
- return $this->access;
- }
-}
diff --git a/src/SecurityAccess/src/RbacFacade.php b/src/SecurityAccess/src/RbacFacade.php
deleted file mode 100644
index 49a6b86f..00000000
--- a/src/SecurityAccess/src/RbacFacade.php
+++ /dev/null
@@ -1,26 +0,0 @@
-assertIsArray((new ConfigProvider())());
- }
-}
diff --git a/src/SecurityAccess/tests/Cases/ManagerTest.php b/src/SecurityAccess/tests/Cases/ManagerTest.php
deleted file mode 100644
index 5d02516b..00000000
--- a/src/SecurityAccess/tests/Cases/ManagerTest.php
+++ /dev/null
@@ -1,112 +0,0 @@
-config = \Mockery::mock(Config::class);
- $this->manager = new Manager($this->config);
- }
-
- public function testGetWithoutName(): void
- {
- // Set up the expected default value from the config
- $expectedDefault = 'rbac';
- $this->config->allows('get')
- ->with('access.default', null)
- ->andReturn($expectedDefault);
- $this->config->allows('get')
- ->with('access.component.rbac', null)
- ->andReturn([
- 'construct' => [
- dirname(__DIR__, 2) . '/publish/rbac_model.conf',
- dirname(__DIR__, 2) . '/publish/rbac_policy.csv',
- ],
- 'enforcer' => Enforcer::class,
- ]);
-
- // Call the get method without passing a name
- $enforcer = $this->manager->get();
-
- // Assert that the getAdapter method is called with the expected default value
- $this->assertInstanceOf(Enforcer::class, $enforcer);
- }
-
- public function testGetWithName(): void
- {
- // Set up the expected adapter name and config
- $adapterName = 'customAdapter';
- $adapterConfig = [
- 'construct' => [
- dirname(__DIR__, 2) . '/publish/rbac_model.conf',
- dirname(__DIR__, 2) . '/publish/rbac_policy.csv',
- ],
- 'enforcer' => Enforcer::class,
- ];
- $this->config->allows('get')
- ->with('access.component.' . $adapterName, null)
- ->andReturn($adapterConfig);
-
- // Call the get method with the adapter name
- $enforcer = $this->manager->get($adapterName);
-
- // Assert that the getAdapter method is called with the expected adapter name
- $this->assertInstanceOf(Enforcer::class, $enforcer);
- }
-
- public function testGetAdapterWithNonExistentAdapter(): void
- {
- // Set up the expected adapter name and return null for the config
- $adapterName = 'nonExistentAdapter';
- $this->config->allows('get')
- ->with('access.component.' . $adapterName, null)
- ->andReturn(null);
-
- // Assert that an AccessException is thrown when the adapter does not exist
- $this->expectException(AccessException::class);
- $this->manager->get($adapterName);
- }
-
- public function testGetAdapterWithMissingConstructOrEnforcer(): void
- {
- // Set up the expected adapter name and incomplete config
- $adapterName = 'incompleteAdapter';
- $adapterConfig = [
- 'construct' => [],
- 'enforcer' => 'IncompleteEnforcerClass',
- ];
- $this->config->allows('get')
- ->with('access.component.' . $adapterName, null)
- ->andReturn($adapterConfig);
-
- // Assert that an AccessException is thrown when the adapter construct or enforcer is missing
- $this->expectException(AccessException::class);
- $this->manager->get($adapterName);
- }
-}
diff --git a/src/SecurityAccess/tests/Cases/RbacFacadeTest.php b/src/SecurityAccess/tests/Cases/RbacFacadeTest.php
deleted file mode 100644
index 34611da8..00000000
--- a/src/SecurityAccess/tests/Cases/RbacFacadeTest.php
+++ /dev/null
@@ -1,29 +0,0 @@
-assertEquals(Rbac::class, RbacFacade::getFacadeRoot());
- }
-}
diff --git a/src/SecurityAccess/tests/Cases/RbacTest.php b/src/SecurityAccess/tests/Cases/RbacTest.php
deleted file mode 100644
index e6adfb4c..00000000
--- a/src/SecurityAccess/tests/Cases/RbacTest.php
+++ /dev/null
@@ -1,50 +0,0 @@
-enforcer = \Mockery::mock(Enforcer::class);
-
- $accessMock->allows('get')
- ->with('rbac')
- ->andReturn($this->enforcer);
-
- $this->rbac = new Rbac($accessMock);
- }
-
- public function testCallMethod(): void
- {
- $methodName = 'testMethod';
- $arguments = ['arg1', 'arg2'];
- $this->enforcer->allows($methodName)->with(...$arguments)->andReturn('result');
- $res = $this->rbac->{$methodName}(...$arguments);
- $this->assertEquals('result', $res);
- }
-}
diff --git a/src/SecurityBundle/.gitattributes b/src/SecurityBundle/.gitattributes
deleted file mode 100644
index ce244ab1..00000000
--- a/src/SecurityBundle/.gitattributes
+++ /dev/null
@@ -1,2 +0,0 @@
-/tests export-ignore
-/.github export-ignore
\ No newline at end of file
diff --git a/src/SecurityBundle/.github/workflows/close-pull-request.yml b/src/SecurityBundle/.github/workflows/close-pull-request.yml
deleted file mode 100644
index c8182b84..00000000
--- a/src/SecurityBundle/.github/workflows/close-pull-request.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-name: Close Pull Request
-
-on:
- pull_request_target:
- types: [ opened ]
-
-jobs:
- run:
- runs-on: ubuntu-latest
- steps:
- - uses: superbrothers/close-pull-request@v3
- with:
- comment: "Hi, this is a READ-ONLY repository, please submit your PR on the https://github.com/mineadmin/components repository.
This Pull Request will close automatically.
Thanks! "
\ No newline at end of file
diff --git a/src/SecurityBundle/.github/workflows/release.yml b/src/SecurityBundle/.github/workflows/release.yml
deleted file mode 100644
index 2fc8404b..00000000
--- a/src/SecurityBundle/.github/workflows/release.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-on:
- push:
- 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@v4
- - 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
\ No newline at end of file
diff --git a/src/SecurityBundle/LICENSE b/src/SecurityBundle/LICENSE
deleted file mode 100644
index c5722457..00000000
--- a/src/SecurityBundle/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2024 MineAdmin
-
-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.
\ No newline at end of file
diff --git a/src/SecurityBundle/README.md b/src/SecurityBundle/README.md
deleted file mode 100644
index b931c8ab..00000000
--- a/src/SecurityBundle/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Hyperf Security Bundle
-
-像 Symfony/security 那样提供用户认证、授权、协程/请求安全上下文等功能
\ No newline at end of file
diff --git a/src/SecurityBundle/composer.json b/src/SecurityBundle/composer.json
deleted file mode 100644
index 385045ea..00000000
--- a/src/SecurityBundle/composer.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- "name": "mineadmin/security-bundle",
- "description": "MineAdmin Security bundle,类似 Symfony/Security 组件,提供用户认证、授权、安全上下文等功能。",
- "license": "MIT",
- "type": "library",
- "authors": [
- {
- "name": "xmo",
- "email": "root@imoi.cn",
- "role": "Developer"
- },
- {
- "name": "zds",
- "email": "2771717608@qq.com",
- "role": "Developer"
- }
- ],
- "require": {
- "php": ">=8.1",
- "friendsofhyperf/encryption": "^3.1",
- "hyperf/framework": "^3.1"
- },
- "autoload": {
- "psr-4": {
- "Mine\\SecurityBundle\\": "src"
- }
- },
- "autoload-dev": {
- "psr-4": {
- "Mine\\SecurityBundle\\Tests\\": "tests"
- }
- },
- "extra": {
- "hyperf": {
- "config": "Mine\\SecurityBundle\\ConfigProvider"
- }
- }
-}
\ No newline at end of file
diff --git a/src/SecurityBundle/src/AbstractUserProvider.php b/src/SecurityBundle/src/AbstractUserProvider.php
deleted file mode 100644
index bf9b2311..00000000
--- a/src/SecurityBundle/src/AbstractUserProvider.php
+++ /dev/null
@@ -1,100 +0,0 @@
-where($user->getRememberTokenName(), $token)->first();
- }, $this->getUserEntity()->getSecurityBuilder(), $this->getUserEntity(), $token);
- }
-
- public function updateRememberToken(UserInterface $user, string $token): bool
- {
- return value(function (Builder $builder, UserInterface $user, string $token) {
- return $builder->update([
- $user->getRememberTokenName() => $token,
- ]);
- }, $user->getSecurityBuilder(), $user, $token);
- }
-
- public function retrieveById(mixed $identifier): ?object
- {
- return value(
- function (Builder $builder, UserInterface $entity, mixed $identifier) {
- return $builder->where($entity->getIdentifierName(), $identifier)->first();
- },
- $this->getUserEntity()->getSecurityBuilder(),
- $this->getUserEntity(),
- $identifier
- );
- }
-
- public function credentials(array $credentials): false|UserInterface
- {
- $userEntity = $this->getUserEntity();
- $builder = $userEntity->getSecurityBuilder();
- $identifierName = $userEntity->getIdentifierName();
- if (isset($credentials[$identifierName])) {
- /**
- * @var UserInterface $entity
- */
- $entity = $builder->where($identifierName, $credentials[$identifierName])->first();
- if ($entity === null) {
- return false;
- }
- if ($this->verifyPassword($entity, $credentials['password'])) {
- $this->dispatcher->dispatch(new Login($entity));
- return $entity;
- }
- }
- return false;
- }
-
- protected function verifyPassword(UserInterface $user, string $password): bool
- {
- if (password_verify($password, $user->getPassword())) {
- $this->dispatcher->dispatch(new Verified($user));
- return true;
- }
- $this->dispatcher->dispatch(new Validated($user));
- return false;
- }
-
- protected function getUserEntity(): UserInterface
- {
- $entityClass = $this->config->get('entity', '\App\Model\User');
- if (! class_exists($entityClass)) {
- new NotFoundUserEntityException();
- }
- return new $entityClass();
- }
-}
diff --git a/src/SecurityBundle/src/Config.php b/src/SecurityBundle/src/Config.php
deleted file mode 100644
index 46d67fa9..00000000
--- a/src/SecurityBundle/src/Config.php
+++ /dev/null
@@ -1,29 +0,0 @@
-config->get(self::PREFIX . '.' . $key, $default);
- }
-}
diff --git a/src/SecurityBundle/src/ConfigProvider.php b/src/SecurityBundle/src/ConfigProvider.php
deleted file mode 100644
index ca30582c..00000000
--- a/src/SecurityBundle/src/ConfigProvider.php
+++ /dev/null
@@ -1,21 +0,0 @@
-user;
- }
-}
diff --git a/src/SecurityBundle/src/Event/Authenticated.php b/src/SecurityBundle/src/Event/Authenticated.php
deleted file mode 100644
index 38947ae1..00000000
--- a/src/SecurityBundle/src/Event/Authenticated.php
+++ /dev/null
@@ -1,27 +0,0 @@
-user;
- }
-}
diff --git a/src/SecurityBundle/src/Event/Failed.php b/src/SecurityBundle/src/Event/Failed.php
deleted file mode 100644
index f29b80fd..00000000
--- a/src/SecurityBundle/src/Event/Failed.php
+++ /dev/null
@@ -1,27 +0,0 @@
-user;
- }
-}
diff --git a/src/SecurityBundle/src/Event/Login.php b/src/SecurityBundle/src/Event/Login.php
deleted file mode 100644
index 7576a6da..00000000
--- a/src/SecurityBundle/src/Event/Login.php
+++ /dev/null
@@ -1,27 +0,0 @@
-user;
- }
-}
diff --git a/src/SecurityBundle/src/Event/Logout.php b/src/SecurityBundle/src/Event/Logout.php
deleted file mode 100644
index 8f974b11..00000000
--- a/src/SecurityBundle/src/Event/Logout.php
+++ /dev/null
@@ -1,27 +0,0 @@
-user;
- }
-}
diff --git a/src/SecurityBundle/src/Event/PasswordReset.php b/src/SecurityBundle/src/Event/PasswordReset.php
deleted file mode 100644
index ca484c91..00000000
--- a/src/SecurityBundle/src/Event/PasswordReset.php
+++ /dev/null
@@ -1,15 +0,0 @@
-user;
- }
-}
diff --git a/src/SecurityBundle/src/Event/Verified.php b/src/SecurityBundle/src/Event/Verified.php
deleted file mode 100644
index 2539b1bb..00000000
--- a/src/SecurityBundle/src/Event/Verified.php
+++ /dev/null
@@ -1,27 +0,0 @@
-user;
- }
-}
diff --git a/src/SecurityBundle/src/Exception/NotFoundUserEntityException.php b/src/SecurityBundle/src/Exception/NotFoundUserEntityException.php
deleted file mode 100644
index 2f72dea5..00000000
--- a/src/SecurityBundle/src/Exception/NotFoundUserEntityException.php
+++ /dev/null
@@ -1,15 +0,0 @@
-container->get($this->config->get('token'));
- }
-
- public function getContext(): ContextInterface
- {
- return $this->container->get($this->config->get('context'));
- }
-
- public function getUserProvider(): UserProviderInterface
- {
- return $this->container->get($this->config->get('user_provider'));
- }
-}
diff --git a/src/SecurityBundle/tests/AbstractUserProviderTest.php b/src/SecurityBundle/tests/AbstractUserProviderTest.php
deleted file mode 100644
index d308c787..00000000
--- a/src/SecurityBundle/tests/AbstractUserProviderTest.php
+++ /dev/null
@@ -1,227 +0,0 @@
-set(ConfigInterface::class, new \Hyperf\Config\Config([
- 'encryption' => [
- 'key' => 'base64:MhEHk72OcV2ttAljUu9Caaam3iP2BnGcwb6GWKkUfV4=',
- 'cipher' => 'AES-256-CBC',
- ],
- ]));
- }
-
- public function testConstruct(): void
- {
- $instance = new class(\Mockery::mock(EventDispatcherInterface::class), \Mockery::mock(Config::class)) extends AbstractUserProvider {
- public function retrieveByCredentials(array $credentials): ?object
- {
- return null;
- }
-
- public function validateCredentials(UserInterface $user, array $credentials): bool
- {
- return false;
- }
- };
- $this->assertInstanceOf(AbstractUserProvider::class, $instance);
- }
-
- public function testCredentials()
- {
- $event = \Mockery::mock(EventDispatcherInterface::class);
- $config = \Mockery::mock(Config::class);
- $config->allows('get')
- ->with('entity', '\App\Model\User')
- ->andReturn(UserModel::class);
- $builder = \Mockery::mock(Builder::class);
- $verifyModel = new UserModel();
- $verifyModel->setPassword(password_hash('xxxxxx', PASSWORD_DEFAULT));
- $builder->allows('first')->andReturn(null, new UserModel(), $verifyModel);
- $builder->allows('where')
- ->andReturnUsing(function ($column, $value) use ($builder) {
- if ($column === 'email' && $value === 'zds@qq.com') {
- return $builder;
- }
- });
- ApplicationContext::getContainer()->set('mocker.builder', $builder);
- $instance = new class($event, $config) extends AbstractUserProvider {
- public function retrieveByCredentials(array $credentials): ?object
- {
- return null;
- }
-
- public function validateCredentials(UserInterface $user, array $credentials): bool
- {
- return false;
- }
- };
- $this->assertFalse($instance->credentials([
- 'email' => 'zds@qq.com',
- 'password' => '123456',
- ]));
- $event->allows('dispatch')->andReturnUsing(function ($event) {
- $this->assertInstanceOf(Validated::class, $event);
- }, function ($event) {
- if ($event instanceof Verified) {
- $this->assertInstanceOf(Verified::class, $event);
- } else {
- $this->assertInstanceOf(Login::class, $event);
- }
- });
-
- $this->assertFalse($instance->credentials([
- 'email' => 'zds@qq.com',
- 'password' => '123456',
- ]));
-
- $this->assertInstanceOf(UserInterface::class, $instance->credentials([
- 'email' => 'zds@qq.com',
- 'password' => 'xxxxxx',
- ]));
- }
-
- public function testRetrieveById(): void
- {
- $event = \Mockery::mock(EventDispatcherInterface::class);
- $config = \Mockery::mock(Config::class);
- $config->allows('get')
- ->with('entity', '\App\Model\User')
- ->andReturn(UserModel::class);
- $builder = \Mockery::mock(Builder::class);
- $verifyModel = new UserModel();
- $verifyModel->setPassword(password_hash('xxxxxx', PASSWORD_DEFAULT));
- $builder->allows('first')->andReturn(null, new UserModel(), $verifyModel);
- $builder->allows('where')
- ->andReturnUsing(function ($column, $value) use ($builder) {
- if ($column === 'email') {
- return $builder;
- }
- });
- ApplicationContext::getContainer()->set('mocker.builder', $builder);
- $instance = new class($event, $config) extends AbstractUserProvider {
- public function retrieveByCredentials(array $credentials): ?object
- {
- return null;
- }
-
- public function validateCredentials(UserInterface $user, array $credentials): bool
- {
- return false;
- }
- };
- $this->assertNull($instance->retrieveById(1));
- $this->assertInstanceOf(UserInterface::class, $instance->retrieveById(2));
- }
-
- public function testUpdateRememberToken(): void
- {
- $event = \Mockery::mock(EventDispatcherInterface::class);
- $config = \Mockery::mock(Config::class);
- $config->allows('get')
- ->with('entity', '\App\Model\User')
- ->andReturn(UserModel::class);
- $builder = \Mockery::mock(Builder::class);
- $verifyModel = new UserModel();
- $verifyModel->setPassword(password_hash('xxxxxx', PASSWORD_DEFAULT));
- $builder->allows('update')->andReturnUsing(function ($data) {
- if ($data['remember_token'] === '123456') {
- return true;
- }
-
- return false;
- });
- ApplicationContext::getContainer()->set('mocker.builder', $builder);
- $instance = new class($event, $config) extends AbstractUserProvider {
- public function retrieveByCredentials(array $credentials): ?object
- {
- return null;
- }
-
- public function validateCredentials(UserInterface $user, array $credentials): bool
- {
- return false;
- }
- };
- $this->assertTrue($instance->updateRememberToken(new UserModel(), '123456'));
- $this->assertFalse($instance->updateRememberToken(new UserModel(), 'xxx'));
- }
-
- public function testRetrieveByToken(): void
- {
- $event = \Mockery::mock(EventDispatcherInterface::class);
- $config = \Mockery::mock(Config::class);
- $config->allows('get')
- ->with('entity', '\App\Model\User')
- ->andReturn(UserModel::class);
- $builder = \Mockery::mock(Builder::class);
- $verifyModel = new UserModel();
- $verifyModel->setPassword(password_hash('xxxxxx', PASSWORD_DEFAULT));
- $builder->allows('update')->andReturnUsing(function ($data) {
- if ($data['remember_token'] === '123456') {
- return true;
- }
-
- return false;
- });
- $builder->allows('where')->andReturnUsing(function ($column, $value) use ($builder) {
- $this->assertEquals('remember_token', $column);
- $this->assertEquals('123456', $value);
- return $builder;
- }, function ($column, $value) use ($builder) {
- $this->assertEquals('remember_token', $column);
- $this->assertNotEquals('123456', $value);
- return $builder;
- });
- $builder->allows('first')->andReturn(new UserModel(), null);
- ApplicationContext::getContainer()->set('mocker.builder', $builder);
- $instance = new class($event, $config) extends AbstractUserProvider {
- public function retrieveByCredentials(array $credentials): ?object
- {
- return null;
- }
-
- public function validateCredentials(UserInterface $user, array $credentials): bool
- {
- return false;
- }
- };
- $this->assertInstanceOf(UserInterface::class, $instance->retrieveByToken('123456'));
- $this->assertNull($instance->retrieveByToken('11111'));
- }
-}
diff --git a/src/SecurityBundle/tests/ConfigProviderTest.php b/src/SecurityBundle/tests/ConfigProviderTest.php
deleted file mode 100644
index f3e09776..00000000
--- a/src/SecurityBundle/tests/ConfigProviderTest.php
+++ /dev/null
@@ -1,28 +0,0 @@
-assertIsArray((new ConfigProvider())());
- }
-}
diff --git a/src/SecurityBundle/tests/ConfigTest.php b/src/SecurityBundle/tests/ConfigTest.php
deleted file mode 100644
index 5e5f3d4b..00000000
--- a/src/SecurityBundle/tests/ConfigTest.php
+++ /dev/null
@@ -1,32 +0,0 @@
-allows('get')->with('security.xxx', null)->andReturn('xxx');
- $config = new Config($mock);
- $this->assertEquals('xxx', $config->get('xxx'));
- }
-}
diff --git a/src/SecurityBundle/tests/Context/ConTextTest.php b/src/SecurityBundle/tests/Context/ConTextTest.php
deleted file mode 100644
index 56e3ec6f..00000000
--- a/src/SecurityBundle/tests/Context/ConTextTest.php
+++ /dev/null
@@ -1,41 +0,0 @@
-set('key', 'value');
- $this->assertEquals('value', $context->get('key'));
- $this->assertEquals(null, $context->get('not_exist'));
- $this->assertEquals('xxx', $context->get('not_exist', 'xxx'));
- $this->assertEquals('xxx', $context->getOrSet('not_exist', 'xxx'));
- $this->assertEquals('xxx2', $context->getOrSet('not_exist1', function () {
- return 'xxx2';
- }));
- $this->assertTrue($context->has('key'));
- $this->assertFalse($context->has('key2'));
- }
-}
diff --git a/src/SecurityBundle/tests/SecurityTest.php b/src/SecurityBundle/tests/SecurityTest.php
deleted file mode 100644
index 251379ef..00000000
--- a/src/SecurityBundle/tests/SecurityTest.php
+++ /dev/null
@@ -1,49 +0,0 @@
-assertInstanceOf(Security::class, new Security($config, ApplicationContext::getContainer()));
- }
-
- public function testGet()
- {
- $config = \Mockery::mock(Config::class);
- $config->allows('get')->andReturn('xxx');
- $container = \Mockery::mock(ContainerInterface::class);
- $security = new Security($config, $container);
- $container->allows('get')
- ->andReturn(\Mockery::mock(TokenInterface::class), \Mockery::mock(UserProviderInterface::class), \Mockery::mock(ContextInterface::class));
- $this->assertInstanceOf(TokenInterface::class, $security->getToken());
- $this->assertInstanceOf(UserProviderInterface::class, $security->getUserProvider());
- $this->assertInstanceOf(ContextInterface::class, $security->getContext());
- }
-}
diff --git a/src/SecurityBundle/tests/Stub/UserModel.php b/src/SecurityBundle/tests/Stub/UserModel.php
deleted file mode 100644
index b98f4d07..00000000
--- a/src/SecurityBundle/tests/Stub/UserModel.php
+++ /dev/null
@@ -1,61 +0,0 @@
-remember_token;
- }
-
- public function setRememberToken(string $token): void
- {
- $this->remember_token = $token;
- }
-
- public function getRememberTokenName(): string
- {
- return 'remember_token';
- }
-
- public function getPassword(): string
- {
- return $this->attributes['password'] ?? '123456';
- }
-
- public function setPassword(string $password): void
- {
- $this->attributes['password'] = $password;
- }
-
- public function getSecurityBuilder(): Builder
- {
- return ApplicationContext::getContainer()->get('mocker.builder');
- }
-}
diff --git a/src/SecurityHttp/.gitattributes b/src/SecurityHttp/.gitattributes
deleted file mode 100644
index ce244ab1..00000000
--- a/src/SecurityHttp/.gitattributes
+++ /dev/null
@@ -1,2 +0,0 @@
-/tests export-ignore
-/.github export-ignore
\ No newline at end of file
diff --git a/src/SecurityHttp/.github/workflows/close-pull-request.yml b/src/SecurityHttp/.github/workflows/close-pull-request.yml
deleted file mode 100644
index c8182b84..00000000
--- a/src/SecurityHttp/.github/workflows/close-pull-request.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-name: Close Pull Request
-
-on:
- pull_request_target:
- types: [ opened ]
-
-jobs:
- run:
- runs-on: ubuntu-latest
- steps:
- - uses: superbrothers/close-pull-request@v3
- with:
- comment: "Hi, this is a READ-ONLY repository, please submit your PR on the https://github.com/mineadmin/components repository.
This Pull Request will close automatically.
Thanks! "
\ No newline at end of file
diff --git a/src/SecurityHttp/.github/workflows/release.yml b/src/SecurityHttp/.github/workflows/release.yml
deleted file mode 100644
index 2fc8404b..00000000
--- a/src/SecurityHttp/.github/workflows/release.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-on:
- push:
- 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@v4
- - 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
\ No newline at end of file
diff --git a/src/SecurityHttp/LICENSE b/src/SecurityHttp/LICENSE
deleted file mode 100644
index c5722457..00000000
--- a/src/SecurityHttp/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2024 MineAdmin
-
-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.
\ No newline at end of file
diff --git a/src/SecurityHttp/README.md b/src/SecurityHttp/README.md
deleted file mode 100644
index b33c3869..00000000
--- a/src/SecurityHttp/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# MineAdmin security http component
-
-内置了一套基础的 jwt 认证机制,可以用于简单的 api 接口的认证。
\ No newline at end of file
diff --git a/src/SecurityHttp/composer.json b/src/SecurityHttp/composer.json
deleted file mode 100644
index 3da3e36a..00000000
--- a/src/SecurityHttp/composer.json
+++ /dev/null
@@ -1,39 +0,0 @@
-{
- "name": "mineadmin/security-http",
- "description": "MineAdmin Security http component",
- "license": "MIT",
- "type": "library",
- "authors": [
- {
- "name": "xmo",
- "email": "root@imoi.cn",
- "role": "Developer"
- },
- {
- "name": "zds",
- "email": "2771717608@qq.com",
- "role": "Developer"
- }
- ],
- "require": {
- "php": ">=8.1",
- "lcobucci/jwt": "^5.2",
- "mineadmin/http-server": "2.0.x-dev",
- "mineadmin/security-bundle": "2.0.x-dev"
- },
- "autoload": {
- "psr-4": {
- "Mine\\Security\\Http\\": "src/"
- }
- },
- "autoload-dev": {
- "psr-4": {
- "Mine\\Security\\Http\\Tests\\": "tests/"
- }
- },
- "extra": {
- "hyperf": {
- "config": "Mine\\Security\\Http\\ConfigProvider"
- }
- }
-}
\ No newline at end of file
diff --git a/src/SecurityHttp/publish/security.php b/src/SecurityHttp/publish/security.php
deleted file mode 100644
index 1df5f128..00000000
--- a/src/SecurityHttp/publish/security.php
+++ /dev/null
@@ -1,144 +0,0 @@
- UserProvider::class,
- 'token' => Token::class,
- /*
- * entity class
- */
- 'entity' => 'App\Models\User',
- /*
- * An object that attempts to provide a security context
- */
- 'context' => Context::class,
- 'jwt' => [
- 'login_type' => env('JWT_LOGIN_TYPE', 'mpop'), // 登录方式,sso为单点登录,mpop为多点登录
-
- /*
- * 单点登录自定义数据中必须存在uid的键值,这个key你可以自行定义,只要自定义数据中存在该键即可
- */
- 'sso_key' => 'uid',
-
- 'secret' => env('JWT_SECRET', 'phper666'), // 非对称加密使用字符串,请使用自己加密的字符串
-
- /*
- * JWT 权限keys
- * 对称算法: HS256, HS384 & HS512 使用 `JWT_SECRET`.
- * 非对称算法: RS256, RS384 & RS512 / ES256, ES384 & ES512 使用下面的公钥私钥.
- */
- 'keys' => [
- 'public' => env('JWT_PUBLIC_KEY'), // 公钥,例如:'file:///path/to/public/key'
- 'private' => env('JWT_PRIVATE_KEY'), // 私钥,例如:'file:///path/to/private/key'
- ],
-
- 'ttl' => env('JWT_TTL', 7200), // token过期时间,单位为秒
-
- 'alg' => env('JWT_ALG', 'HS256'), // jwt的hearder加密算法
-
- /*
- * 支持的算法
- */
- 'supported_algs' => [
- 'HS256' => 'Lcobucci\JWT\Signer\Hmac\Sha256',
- 'HS384' => 'Lcobucci\JWT\Signer\Hmac\Sha384',
- 'HS512' => 'Lcobucci\JWT\Signer\Hmac\Sha512',
- 'ES256' => 'Lcobucci\JWT\Signer\Ecdsa\Sha256',
- 'ES384' => 'Lcobucci\JWT\Signer\Ecdsa\Sha384',
- 'ES512' => 'Lcobucci\JWT\Signer\Ecdsa\Sha512',
- 'RS256' => 'Lcobucci\JWT\Signer\Rsa\Sha256',
- 'RS384' => 'Lcobucci\JWT\Signer\Rsa\Sha384',
- 'RS512' => 'Lcobucci\JWT\Signer\Rsa\Sha512',
- ],
-
- /*
- * 对称算法名称
- */
- 'symmetry_algs' => [
- 'HS256',
- 'HS384',
- 'HS512',
- ],
-
- /*
- * 非对称算法名称
- */
- 'asymmetric_algs' => [
- 'RS256',
- 'RS384',
- 'RS512',
- 'ES256',
- 'ES384',
- 'ES512',
- ],
-
- /*
- * 是否开启黑名单,单点登录和多点登录的注销、刷新使原token失效,必须要开启黑名单,目前黑名单缓存只支持hyperf缓存驱动
- */
- 'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true),
-
- /*
- * 黑名单的宽限时间 单位为:秒,注意:如果使用单点登录,该宽限时间无效
- */
- 'blacklist_grace_period' => env('JWT_BLACKLIST_GRACE_PERIOD', 0),
-
- /*
- * 黑名单缓存token时间,注意:该时间一定要设置比token过期时间要大一点,默认为1天,最好设置跟过期时间一样
- */
- 'blacklist_cache_ttl' => env('JWT_TTL', 86400),
-
- 'blacklist_prefix' => 'mineadmin_jwt', // 黑名单缓存的前缀
- 'black' => CacheBlack::class, // 黑名单实现类,默认使用hyperf缓存驱动
-
- /*
- * 区分不同场景的token,比如你一个项目可能会有多种类型的应用接口鉴权,下面自行定义,我只是举例子
- * 下面的配置会自动覆盖根配置,比如application1会里面的数据会覆盖掉根数据
- * 下面的scene会和根数据合并
- * scene必须存在一个default
- * 什么叫根数据,这个配置的一维数组,除了scene都叫根配置
- */
- 'scene' => [
- 'default' => [],
- 'application1' => [
- 'secret' => 'application1', // 非对称加密使用字符串,请使用自己加密的字符串
- 'login_type' => 'sso', // 登录方式,sso为单点登录,mpop为多点登录
- 'sso_key' => 'uid',
- 'ttl' => 7200, // token过期时间,单位为秒
- 'blacklist_cache_ttl' => env('JWT_TTL', 7200), // 黑名单缓存token时间,注意:该时间一定要设置比token过期时间要大一点,默认为100秒,最好设置跟过期时间一样
- ],
- 'application2' => [
- 'secret' => 'application2', // 非对称加密使用字符串,请使用自己加密的字符串
- 'login_type' => 'sso', // 登录方式,sso为单点登录,mpop为多点登录
- 'sso_key' => 'uid',
- 'ttl' => 7200, // token过期时间,单位为秒
- 'blacklist_cache_ttl' => env('JWT_TTL', 7200), // 黑名单缓存token时间,注意:该时间一定要设置比token过期时间要大一点,默认为100秒,最好设置跟过期时间一样
- ],
- 'application3' => [
- 'secret' => 'application3', // 非对称加密使用字符串,请使用自己加密的字符串
- 'login_type' => 'mppo', // 登录方式,sso为单点登录,mpop为多点登录
- 'ttl' => 7200, // token过期时间,单位为秒
- 'blacklist_cache_ttl' => env('JWT_TTL', 7200), // 黑名单缓存token时间,注意:该时间一定要设置比token过期时间要大一点,默认为100秒,最好设置跟过期时间一样
- ],
- ],
- // 是否验证当前场景配置是否是生成当前的token的配置,需要配合自定义中间件实现,false会根据当前token拿到原来的场景配置,并且验证当前token
- 'independentTokenVerify' => false,
- ],
-];
diff --git a/src/SecurityHttp/src/Aspect/CurrentUserAspect.php b/src/SecurityHttp/src/Aspect/CurrentUserAspect.php
deleted file mode 100644
index a329cb1e..00000000
--- a/src/SecurityHttp/src/Aspect/CurrentUserAspect.php
+++ /dev/null
@@ -1,29 +0,0 @@
-process();
- }
-}
diff --git a/src/SecurityHttp/src/Attribute/CurrentUser.php b/src/SecurityHttp/src/Attribute/CurrentUser.php
deleted file mode 100644
index 087d5482..00000000
--- a/src/SecurityHttp/src/Attribute/CurrentUser.php
+++ /dev/null
@@ -1,23 +0,0 @@
-getSecretName();
- $value = $this->generator();
- $envPath = $this->getEnvPath();
-
- if (! file_exists($envPath)) {
- $this->error('.env file not is exists!');
- return;
- }
- if (\Mine\Helper\Str::contains(file_get_contents($envPath), $secretName) === false) {
- file_put_contents($envPath, "\n{$secretName}={$value}\n", FILE_APPEND);
- } else {
- file_put_contents($envPath, preg_replace(
- "~{$secretName}\\s*=\\s*[^\n]*~",
- "{$secretName}=\"{$value}\"",
- file_get_contents($envPath)
- ));
- }
-
- $this->info('jwt secret generator successfully:' . $value);
- }
-
- public function getSecretName(): string
- {
- return Str::upper($this->input->getOption('secret-name'));
- }
-
- public function getEnvPath(): string
- {
- return BASE_PATH . '/.env';
- }
-
- public function generator(): string
- {
- return base64_encode(random_bytes(64));
- }
-
- protected function configure()
- {
- $this->setHelp('run "php bin/hyperf.php mine:gen-jwt" create the new jwt secret');
- $this->setDescription('MineAdmin system gen jwt command');
- }
-
- protected function getOptions(): array
- {
- return [
- 'secret-name', 'sn', InputOption::VALUE_OPTIONAL, 'The jwt secret name.default:jwt_secret', 'jwt_secret',
- ];
- }
-}
diff --git a/src/SecurityHttp/src/ConfigProvider.php b/src/SecurityHttp/src/ConfigProvider.php
deleted file mode 100644
index 0f9905a6..00000000
--- a/src/SecurityHttp/src/ConfigProvider.php
+++ /dev/null
@@ -1,30 +0,0 @@
- [
- [
- 'id' => 'security-http',
- 'description' => 'Security http configure',
- 'source' => dirname(__DIR__) . '/publish/security.php',
- 'destination' => BASE_PATH . '/config/autoload/security.php',
- ],
- ],
- ];
- }
-}
diff --git a/src/SecurityHttp/src/Constant/TokenValidConstant.php b/src/SecurityHttp/src/Constant/TokenValidConstant.php
deleted file mode 100644
index 5023e1f6..00000000
--- a/src/SecurityHttp/src/Constant/TokenValidConstant.php
+++ /dev/null
@@ -1,28 +0,0 @@
-security = $this->container->get(Security::class);
- }
-
- public function __get($name)
- {
- return $this->getAttributes()[$name] ?? null;
- }
-
- public function getEntity(): UserInterface
- {
- return $this->getSecurity()->getToken()->user($this->scene);
- }
-
- public function getIdentifier(): string
- {
- return call([$this->getEntity(), __FUNCTION__]);
- }
-
- public function getIdentifierName(): string
- {
- return call([$this->getEntity(), __FUNCTION__]);
- }
-
- public function getRememberToken(): string
- {
- return call([$this->getEntity(), __FUNCTION__]);
- }
-
- public function setRememberToken(string $token): void
- {
- call([$this->getEntity(), __FUNCTION__], func_get_args());
- }
-
- public function getRememberTokenName(): string
- {
- return call([$this->getEntity(), __FUNCTION__]);
- }
-
- public function getPassword(): string
- {
- return call([$this->getEntity(), __FUNCTION__]);
- }
-
- public function setPassword(string $password): void
- {
- call([$this->getEntity(), __FUNCTION__]);
- }
-
- public function getSecurityBuilder(): Builder
- {
- return call([$this->getEntity(), __FUNCTION__]);
- }
-
- public function setAttribute(string $key, mixed $value)
- {
- return call([$this->getEntity(), __FUNCTION__]);
- }
-
- public function getAttributes(): array
- {
- return call([$this->getEntity(), __FUNCTION__]);
- }
-
- protected function getSecurity(): Security
- {
- return $this->security;
- }
-}
diff --git a/src/SecurityHttp/src/Exception/JwtConfigException.php b/src/SecurityHttp/src/Exception/JwtConfigException.php
deleted file mode 100644
index b680e05a..00000000
--- a/src/SecurityHttp/src/Exception/JwtConfigException.php
+++ /dev/null
@@ -1,21 +0,0 @@
-claims();
- if ($config['blacklist_enabled']) {
- $cacheKey = $this->getCacheKey($claims->get('jti'), $config);
- $blacklistGracePeriod = 0;
- $expTime = $claims->get(RegisteredClaims::EXPIRATION_TIME);
- if (! is_numeric($expTime)) {
- $expTime = $expTime->getTimestamp();
- }
- $validUntil = Time::now()->addSeconds($blacklistGracePeriod)->getTimestamp();
- $expTime = Time::timestamp($expTime);
- $nowTime = Time::now();
- $tokenCacheTime = $expTime->max($nowTime)->diffInSeconds();
- return $this->storageAdd($cacheKey, ['valid_until' => $validUntil], $tokenCacheTime, $config['blacklist_prefix']);
- }
- return false;
- }
-
- abstract public function storageAdd(string $cacheKey, array $val, int $tokenCacheTime, string $prefix): bool;
-
- abstract public function storageGet(string $cacheKey, string $prefix): mixed;
-
- abstract public function storageDelete(string $cacheKey, string $prefix): bool;
-
- abstract public function storageClear(string $prefix): bool;
-
- /**
- * Determine if the token has been blacklisted.
- * @param mixed $claims
- */
- public function has($claims, array $config = []): bool
- {
- $cacheKey = $this->getCacheKey($claims['jti'], $config);
- if ($config['blacklist_enabled'] && $config['login_type'] === 'mpop') {
- $val = $this->storageGet($cacheKey, $config['blacklist_prefix']);
- return ! empty($val['valid_until']) && ! Time::isFuture($val['valid_until']);
- }
-
- if ($config['blacklist_enabled'] && $config['login_type'] === 'sso') {
- $val = $this->storageGet($cacheKey, $config['blacklist_prefix']);
- // When refreshing the token, the cache time may be the same as the issue time
- if (! is_null($claims['iat']) && ! empty($val['valid_until'])) {
- $isFuture = ($claims['iat']->getTimestamp() - $val['valid_until']) >= 0;
- } else {
- $isFuture = false;
- }
- // check whether the expiry + grace has past
- return ! $isFuture;
- }
- return false;
- }
-
- public function remove($key, array $config = []): void
- {
- $this->storageDelete($key, $config['blacklist_prefix']);
- }
-
- public function clear(array $config = []): void
- {
- $this->storageClear($config['blacklist_prefix']);
- }
-
- private function getCacheKey(string $jti, array $config = []): string
- {
- return sprintf('%s_%s', $config['blacklist_prefix'], $jti);
- }
-}
diff --git a/src/SecurityHttp/src/Jwt/Black/CacheBlack.php b/src/SecurityHttp/src/Jwt/Black/CacheBlack.php
deleted file mode 100644
index 4e3e8655..00000000
--- a/src/SecurityHttp/src/Jwt/Black/CacheBlack.php
+++ /dev/null
@@ -1,42 +0,0 @@
-cache->set($prefix . ':' . $cacheKey, $val, $tokenCacheTime);
- }
-
- public function storageGet(string $cacheKey, string $prefix): mixed
- {
- return $this->cache->get($prefix . ':' . $cacheKey);
- }
-
- public function storageDelete(string $cacheKey, string $prefix): bool
- {
- return $this->cache->delete($prefix . ':' . $cacheKey);
- }
-
- public function storageClear(string $prefix): bool
- {
- return $this->cache->delete($prefix . ':*');
- }
-}
diff --git a/src/SecurityHttp/src/Jwt/Token.php b/src/SecurityHttp/src/Jwt/Token.php
deleted file mode 100644
index 09554a71..00000000
--- a/src/SecurityHttp/src/Jwt/Token.php
+++ /dev/null
@@ -1,61 +0,0 @@
-getRequest();
- if ($request === null) {
- throw new \RuntimeException('Request is not available.');
- }
- if (! $request->hasHeader('Authorization')) {
- throw new TokenValidException(TokenValidConstant::TOKEN_NOT_FOUND, 'Token is not available.');
- }
- $token = str_replace('Bearer ', '', $request->getHeaderLine('Authorization'));
- $scene = $param[0] ?? 'default';
- $resolveToken = $this->jwt->parse($token, $scene);
- $attributes = $resolveToken->claims()->all();
- $entity = $this->getUserEntity();
- foreach ($attributes as $key => $value) {
- $entity->setAttribute(str_replace('__attribute__', '', $key), $value);
- }
- return $entity;
- }
-
- private function getUserEntity(): UserInterface
- {
- return new ($this->config->get('entity'));
- }
-
- private function getRequest(): ?RequestInterface
- {
- return $this->container->get(RequestInterface::class);
- }
-}
diff --git a/src/SecurityHttp/src/RegisterCurrentUserPropertyHandler.php b/src/SecurityHttp/src/RegisterCurrentUserPropertyHandler.php
deleted file mode 100644
index 28269219..00000000
--- a/src/SecurityHttp/src/RegisterCurrentUserPropertyHandler.php
+++ /dev/null
@@ -1,43 +0,0 @@
-setValue(new CurrentUserProxy(
- $annotation->secret,
- $container,
- ));
- }
- }
-}
diff --git a/src/SecurityHttp/src/Support/Jwt.php b/src/SecurityHttp/src/Support/Jwt.php
deleted file mode 100644
index 548a563b..00000000
--- a/src/SecurityHttp/src/Support/Jwt.php
+++ /dev/null
@@ -1,258 +0,0 @@
-getSceneConfig($scene);
- $loginType = $config['login_type'];
- $ssoKey = $config['sso_key'];
- $claims = $tokenObject->getClaims();
- $headers = $tokenObject->getHeaders();
- if ($loginType === 'mpop') { // Multi-login, scenario values with a unique id
- $unique = uniqid($scene . '_', true);
- } else { // 单点登录
- if (empty($claims[$ssoKey])) {
- throw new JwtConfigException("There is no {$ssoKey} key in the claims", 400);
- }
- // unique
- $unique = $scene . '_' . $claims[$ssoKey];
- }
-
- $signer = $this->getSigner($config);
- $time = Carbon::now()->addSeconds($this->getTtl($config));
- $datetimeImmutable = $time->toDateTimeImmutable();
- $builder = $this->getConfiguration($signer, $this->getKey($config))->builder();
- $builder = $builder
- ->issuedBy($tokenObject->getIssuedBy())
- ->identifiedBy($unique)
- ->issuedAt($datetimeImmutable)
- ->canOnlyBeUsedAfter($datetimeImmutable)
- ->expiresAt($datetimeImmutable);
-
- $claims['scene'] = $scene; // Add scene values
- foreach ($claims as $k => $v) {
- $builder = $builder->withClaim($k, $v); // Customized data
- }
- foreach ($headers as $k => $v) {
- $builder = $builder->withHeader($k, $v); // Customized data
- }
-
- $token = $builder->getToken($signer, $this->getKey($config)); // Retrieves the generated token
-
- // Single sign-on to invalidate all previously generated tokens
- if ($loginType === 'sso' && $tokenObject->isInsertSsoBlack) {
- $this->getBlack($config)->add($token, $config);
- }
-
- return $token;
- }
-
- public function getTtl(array $config): int
- {
- return (int) $config['ttl'];
- }
-
- /**
- * @throws JwtConfigException
- */
- public function parse(string $token, string $scene = 'default', bool $validate = true): Token
- {
- $config = $this->getSceneConfig($scene);
- $signer = new $config['supported_algs'][$config['alg']]();
- $parser = $this->getConfiguration($signer, $this->getKey($config))->parser();
- $resolveToken = $parser->parse($token);
- $claims = $resolveToken->claims()->all();
- $tokenScene = $claims['scene'];
- // Get the scenario configuration for the current environment and verify that the token is generated by that configuration.
- if ($tokenScene !== $scene && $this->getIndependentTokenVerify($config)) {
- throw new TokenValidException('Token authentication does not pass', 401);
- }
- // Judging from the configuration information, set the scene. scene corresponding to the current token
- if (! $this->getIndependentTokenVerify($config)) {
- $scene = $tokenScene ?? $scene;
- }
- $config = $this->getSceneConfig($scene);
- $signer = new $config['supported_algs'][$config['alg']]();
-
- // Verify that the token is blacklisted
- if ($config['blacklist_enabled'] && $this->getBlack($config)->has($claims, $config)) {
- throw new TokenValidException(TokenValidConstant::IN_BLACKLIST, 'Token authentication does not pass');
- }
-
- if ($validate && ! $this->getValidationData($signer, $this->getKey($config), $token)) {
- throw new TokenValidException(TokenValidConstant::PARSER_DATA_VALID, 'Token authentication does not pass');
- }
- return $resolveToken;
- }
-
- /**
- * Refresh token.
- * @throws JwtConfigException
- */
- public function refreshToken(string $token, string $scene = 'default'): Token
- {
- $oldToken = $this->parse($token, $scene);
- $claims = $oldToken->claims()->all();
- $headers = $oldToken->headers()->all();
- unset(
- $claims['iat'],
- $claims['nbf'],
- $claims['exp'],
- $claims['jti'],
- $claims['iss'],
- );
- $tokenInstance = new TokenObject();
- $tokenInstance->setHeaders($headers);
- $tokenInstance->setClaims($claims);
- return $this->generator($tokenInstance, $scene);
- }
-
- /**
- * Invalidate the token.
- * @throws JwtConfigException
- */
- public function logout(string $token, string $scene = 'default'): bool
- {
- $config = $this->getSceneConfig($scene);
- return $this->getBlack($config)->add($this->parse($token), $config);
- }
-
- /**
- * Get token dynamic validity time.
- */
- public function getTokenDynamicCacheTime(string $token): int
- {
- $claims = $this->parse($token)->claims();
- /**
- * @var null|\DateTimeImmutable $exp
- */
- if ($exp = $claims->get(RegisteredClaims::EXPIRATION_TIME)) {
- return Carbon::now()->diffInSeconds($exp);
- }
- return -1;
- }
-
- public function getIndependentTokenVerify(array $config): bool
- {
- return $config['independentTokenVerify'] ?? false;
- }
-
- public function getValidationData(Signer $signer, Key $key, string $token): bool
- {
- $config = $this->getConfiguration($signer, $key);
- $parser = $config->parser()->parse($token);
- $claims = $parser->claims()->all();
-
- $config->setValidationConstraints(new IdentifiedBy($claims['jti']));
- $config->setValidationConstraints(new SignedWith($signer, $key));
-
- if (! $config->validator()->validate($parser, ...$config->validationConstraints())) {
- return false;
- }
-
- return true;
- }
-
- public function getConfiguration(Signer $signer, Key $key): Configuration
- {
- return Configuration::forSymmetricSigner($signer, $key);
- }
-
- public function getBlack(array $config): BlackContract
- {
- if (empty($config['black']) || class_exists($config['black']) === false) {
- throw new JwtConfigException(sprintf('jwt config black is empty'));
- }
- return $this->container->get($config['black']);
- }
-
- public function getSceneConfig(string $scene): array
- {
- $config = $this->config->get('jwt', []);
- $isDefault = $scene === 'default';
- if (empty($config)) {
- throw new JwtConfigException(sprintf('jwt config is empty'));
- }
- if (! $isDefault && ! isset($config['scene'][$scene])) {
- throw new JwtConfigException(sprintf('jwt config scene is empty. %s', $scene));
- }
- $sceneConfig = $isDefault ? $config : $config['scene'][$scene];
- if (! $isDefault) {
- // If it is not the default scenario, the default configuration is merged in
- $keys = [
- 'login_type', 'sso_key', 'secret', 'keys',
- 'ttl', 'alg', 'supported_algs', 'symmetry_algs',
- 'asymmetric_algs', 'blacklist_enabled', 'blacklist_grace_period',
- 'blacklist_cache_ttl', 'blacklist_prefix', 'black',
- ];
- foreach ($keys as $key) {
- if (empty($sceneConfig[$key])) {
- $sceneConfig[$key] = $config[$key];
- }
- }
- }
- return $sceneConfig;
- }
-
- /**
- * Get the key needed by the corresponding algorithm.
- */
- public function getKey(array $config, string $type = 'private'): ?Key
- {
- $key = null;
- // symmetry algorithm
- if (in_array($config['alg'], $config['symmetry_algs'], true)) {
- $key = InMemory::base64Encoded($config['secret']);
- }
-
- // asymmetric
- if (in_array($config['alg'], $config['asymmetric_algs'], true)) {
- $key = InMemory::base64Encoded($config['keys'][$type]);
- }
- return $key;
- }
-
- public function getSigner(array $config): Signer
- {
- return new $config['supported_algs'][$config['alg']]();
- }
-}
diff --git a/src/SecurityHttp/src/Support/Time.php b/src/SecurityHttp/src/Support/Time.php
deleted file mode 100644
index b84f8734..00000000
--- a/src/SecurityHttp/src/Support/Time.php
+++ /dev/null
@@ -1,50 +0,0 @@
-timezone('UTC');
- }
-
- /**
- * Checks if a timestamp is in the past.
- */
- public static function isPast(int $timestamp, int $leeway = 0): bool
- {
- return static::timestamp($timestamp)->addSeconds($leeway)->isPast();
- }
-
- /**
- * Checks if a timestamp is in the future.
- */
- public static function isFuture(int $timestamp, int $leeway = 0): bool
- {
- return static::timestamp($timestamp)->subSeconds($leeway)->isFuture();
- }
-}
diff --git a/src/SecurityHttp/src/TokenObject.php b/src/SecurityHttp/src/TokenObject.php
deleted file mode 100644
index 46cbd19f..00000000
--- a/src/SecurityHttp/src/TokenObject.php
+++ /dev/null
@@ -1,54 +0,0 @@
-issuedBy;
- }
-
- public function setIssuedBy(string $issuedBy): void
- {
- $this->issuedBy = $issuedBy;
- }
-
- public function getClaims(): array
- {
- return $this->claims;
- }
-
- public function setClaims(array $claims): void
- {
- $this->claims = $claims;
- }
-
- public function getHeaders(): array
- {
- return $this->headers;
- }
-
- public function setHeaders(array $headers): void
- {
- $this->headers = $headers;
- }
-}
diff --git a/src/SecurityHttp/src/UserProvider.php b/src/SecurityHttp/src/UserProvider.php
deleted file mode 100644
index 459c46ad..00000000
--- a/src/SecurityHttp/src/UserProvider.php
+++ /dev/null
@@ -1,75 +0,0 @@
-generatorToken($entity) : null;
- }
-
- public function retrieveByCredentials(array $credentials): ?object
- {
- $entity = $this->credentials($credentials);
- return $entity ? $this->generatorToken($entity) : null;
- }
-
- private function generatorToken(UserInterface $user): Token
- {
- $attribute = $user->getAttributes();
- $clams = [];
- foreach ($attribute as $key => $value) {
- if ($value === $user->getPassword()) {
- continue;
- }
- $clams['__attribute__' . $key] = $value;
- }
- $tokenInstance = new TokenObject();
- $tokenInstance->setClaims($clams);
- $tokenInstance->setIssuedBy($user->getIdentifier());
- return $this->jwt->generator($tokenInstance, self::getScene());
- }
-}
diff --git a/src/SecurityHttp/tests/Cases/Command/GenJwtSecretCommandTest.php b/src/SecurityHttp/tests/Cases/Command/GenJwtSecretCommandTest.php
deleted file mode 100644
index f215a3c8..00000000
--- a/src/SecurityHttp/tests/Cases/Command/GenJwtSecretCommandTest.php
+++ /dev/null
@@ -1,73 +0,0 @@
-getMethod('generator');
- $this->assertIsString($invoke->invoke(\Mockery::mock(GenJwtSecretCommand::class)));
- }
-
- public function testGetSecretName(): void
- {
- $reflection = new \ReflectionClass(GenJwtSecretCommand::class);
- $invoke = $reflection->getMethod('getSecretName');
- $instance = $reflection->newInstanceWithoutConstructor();
- $input = \Mockery::mock(Input::class);
- $input->allows('getOption')->andReturn('xxx');
- $instance->setInput($input);
- $this->assertSame('XXX', $invoke->invoke($instance));
- }
-
- public function testGetEnvPath(): void
- {
- $reflection = new \ReflectionClass(GenJwtSecretCommand::class);
- $invoke = $reflection->getMethod('getEnvPath');
- $m = \Mockery::mock(GenJwtSecretCommand::class);
- $this->assertSame(BASE_PATH . '/.env', $invoke->invoke($m));
- }
-
- public function testInvoke(): void
- {
- $reflection = new \ReflectionClass(GenJwtSecretCommand::class);
- $invoke = $reflection->getMethod('__invoke');
- $m = \Mockery::mock(GenJwtSecretCommand::class);
- $m->shouldAllowMockingProtectedMethods();
- $env = sys_get_temp_dir() . '/' . Str::random(32) . '.env';
- file_put_contents($env, "xxx=1\n");
- $m->allows('getEnvPath')->andReturn($env);
- $input = \Mockery::mock(Input::class);
- $input->allows('getOption')->andReturn('Demo');
- $m->allows('setInput');
- $m->allows('getSecretName')->andReturn('DEMO');
- $m->allows('generator')->andReturn(base64_encode(random_bytes(64)));
- $m->allows('info')->andReturnUsing(function ($v) {
- echo $v;
- });
- $m->setInput($input);
- $invoke->invoke($m);
- $this->assertTrue(str_contains(file_get_contents($env), 'DEMO'));
- }
-}
diff --git a/src/SecurityHttp/tests/Cases/ConfigProviderTest.php b/src/SecurityHttp/tests/Cases/ConfigProviderTest.php
deleted file mode 100644
index 7daf08b1..00000000
--- a/src/SecurityHttp/tests/Cases/ConfigProviderTest.php
+++ /dev/null
@@ -1,28 +0,0 @@
-assertIsArray((new ConfigProvider())());
- }
-}
diff --git a/src/SecurityHttp/tests/Cases/Jwt/Black/AbstractBlackTest.php b/src/SecurityHttp/tests/Cases/Jwt/Black/AbstractBlackTest.php
deleted file mode 100644
index 0a098877..00000000
--- a/src/SecurityHttp/tests/Cases/Jwt/Black/AbstractBlackTest.php
+++ /dev/null
@@ -1,119 +0,0 @@
-black = new DummyBlack();
- }
-
- public function testAdd(): void
- {
- $token = \Mockery::mock(UnencryptedToken::class);
- $config = [
- 'blacklist_enabled' => true,
- 'blacklist_prefix' => 'prefix',
- ];
- $token->allows('claims')->andReturn(new DataSet([
- 'xxx' => 'xxx',
- 'jti' => 'xxx',
- RegisteredClaims::EXPIRATION_TIME => Carbon::now()->toDateTimeImmutable(),
- ], RegisteredClaims::class));
-
- $this->assertTrue($this->black->add($token, $config));
- }
-
- public function testAddDisable()
- {
- $token = \Mockery::mock(UnencryptedToken::class);
- $config = [
- 'blacklist_enabled' => false,
- 'blacklist_prefix' => 'prefix',
- ];
- $token->allows('claims')->andReturn(new DataSet([
- 'xxx' => 'xxx',
- 'jti' => 'xxx',
- RegisteredClaims::EXPIRATION_TIME => Carbon::now()->toDateTimeImmutable(),
- ], RegisteredClaims::class));
- $this->assertFalse($this->black->add($token, $config));
- }
-
- public function testHasWithMpopLoginType(): void
- {
- $claims = [
- 'jti' => '123456',
- 'iat' => Time::now(),
- ];
-
- $config = [
- 'blacklist_enabled' => true,
- 'login_type' => 'mpop',
- 'blacklist_prefix' => 'prefix',
- ];
- $this->assertFalse($this->black->has($claims, $config));
- }
-
- public function testHasWithSsoLoginType(): void
- {
- $claims = [
- 'jti' => '123456',
- 'iat' => Time::now(),
- ];
-
- $config = [
- 'blacklist_enabled' => true,
- 'login_type' => 'sso',
- 'blacklist_prefix' => 'prefix',
- ];
-
- $this->assertTrue($this->black->has($claims, $config));
- }
-
- public function testRemove(): void
- {
- $key = '123456';
- $config = [
- 'blacklist_prefix' => 'prefix',
- ];
-
- $this->black->remove($key, $config);
- $this->assertTrue(true);
- }
-
- public function testClear(): void
- {
- $config = [
- 'blacklist_prefix' => 'prefix',
- ];
-
- $this->black->clear($config);
- $this->assertTrue(true);
- }
-}
diff --git a/src/SecurityHttp/tests/Cases/Jwt/Black/CacheBlackTest.php b/src/SecurityHttp/tests/Cases/Jwt/Black/CacheBlackTest.php
deleted file mode 100644
index 62f5820f..00000000
--- a/src/SecurityHttp/tests/Cases/Jwt/Black/CacheBlackTest.php
+++ /dev/null
@@ -1,76 +0,0 @@
-cacheProphecy = \Mockery::mock(CacheInterface::class);
- $this->cacheBlack = new CacheBlack($this->cacheProphecy);
- }
-
- public function testStorageAdd(): void
- {
- $cacheKey = 'testKey';
- $val = ['testVal'];
- $tokenCacheTime = 3600;
- $prefix = 'testPrefix';
-
- $this->cacheProphecy->allows('set')
- ->with($prefix . ':' . $cacheKey, $val, $tokenCacheTime)
- ->andReturn(true);
-
- $result = $this->cacheBlack->storageAdd($cacheKey, $val, $tokenCacheTime, $prefix);
- $this->assertTrue($result);
- }
-
- public function testStorageGet(): void
- {
- $cacheKey = 'testKey';
- $val = ['testVal'];
- $prefix = 'testPrefix';
- $this->cacheProphecy->allows('get')->andReturn($prefix . ':' . $cacheKey)->andReturn($val);
- $result = $this->cacheBlack->storageGet($cacheKey, $prefix);
- $this->assertSame($val, $result);
- }
-
- public function testStorageDelete(): void
- {
- $cacheKey = 'testKey';
- $prefix = 'testPrefix';
- $this->cacheProphecy->allows('delete')->with($prefix . ':' . $cacheKey)->andReturn(true);
- $result = $this->cacheBlack->storageDelete($cacheKey, $prefix);
- $this->assertTrue($result);
- }
-
- public function testStorageClear(): void
- {
- $prefix = 'testPrefix';
- $this->cacheProphecy->allows('delete')->with($prefix . ':*')->andReturn(true);
- $result = $this->cacheBlack->storageClear($prefix);
- $this->assertTrue($result);
- }
-}
diff --git a/src/SecurityHttp/tests/Cases/Jwt/TokenTest.php b/src/SecurityHttp/tests/Cases/Jwt/TokenTest.php
deleted file mode 100644
index 6f01b02e..00000000
--- a/src/SecurityHttp/tests/Cases/Jwt/TokenTest.php
+++ /dev/null
@@ -1,140 +0,0 @@
-jwt = \Mockery::mock(Jwt::class);
- $this->config = \Mockery::mock(Config::class);
- $this->container = \Mockery::mock(ContainerInterface::class);
- $this->token = new Token($this->jwt, $this->config, $this->container);
- $this->request = \Mockery::mock(RequestInterface::class);
- }
-
- public function testUserWithoutRequest(): void
- {
- $this->container->allows('get')
- ->with(RequestInterface::class)
- ->andReturnNull();
-
- $this->expectException(\RuntimeException::class);
- $this->expectExceptionMessage('Request is not available.');
- $this->token->user();
- }
-
- public function testUserWithoutAuthorizationHeader(): void
- {
- $this->container->allows('get')
- ->with(RequestInterface::class)
- ->once()
- ->andReturn($this->request);
-
- $this->request->allows('hasHeader')
- ->with('Authorization')
- ->once()
- ->andReturnFalse();
-
- $this->expectException(TokenValidException::class);
- $this->expectExceptionMessage('Token is not available.');
- $this->token->user();
- }
-
- public function testUserWithValidToken(): void
- {
- $token = 'Bearer test.token';
- $scene = 'default';
- $attributes = [
- 'username' => 'test_user',
- 'email' => 'test@example.com',
- ];
-
- $this->container->allows('get')
- ->with(RequestInterface::class)
- ->andReturns($this->request);
-
- $this->request->allows('hasHeader')
- ->with('Authorization')
- ->andReturnTrue();
-
- $this->request->allows('getHeaderLine')
- ->with('Authorization')
- ->andReturns($token);
-
- $resolveToken = \Mockery::mock(UnencryptedToken::class);
- $resolveToken->allows('claims')
- ->once()
- ->andReturn(new DataSet($attributes, 'xxx'));
-
- $this->jwt->allows('parse')
- ->with('test.token', $scene)
- ->once()
- ->andReturn($resolveToken);
-
- $this->config->allows('get')
- ->with('entity')
- ->once()
- ->andReturn(UserModel::class);
-
- $user = $this->token->user();
-
- $this->assertInstanceOf(UserInterface::class, $user);
- foreach ($attributes as $key => $value) {
- $this->assertEquals($value, $user->getAttribute(str_replace('__attribute__', '', $key)));
- }
- }
-}
diff --git a/src/SecurityHttp/tests/Cases/Support/JwtTest.php b/src/SecurityHttp/tests/Cases/Support/JwtTest.php
deleted file mode 100644
index 8cd6bfc3..00000000
--- a/src/SecurityHttp/tests/Cases/Support/JwtTest.php
+++ /dev/null
@@ -1,266 +0,0 @@
-container = \Mockery::mock(ContainerInterface::class);
- $this->jwt = new Jwt(
- $this->config = \Mockery::mock(Config::class),
- $this->container
- );
- $stubConfig = require dirname(__DIR__, 3) . '/publish/security.php';
- $jwtConfig = $stubConfig['jwt'];
- $jwtConfig['secret'] = base64_encode(random_bytes(32));
- $jwtConfig['black'] = CacheBlack::class;
- $jwtConfig['scene']['sso'] = [
- 'secret' => base64_encode(random_bytes(32)),
- 'login_type' => 'sso',
- ];
- $this->config->allows('get')
- ->with('jwt', [])
- ->andReturn($jwtConfig);
- }
-
- public function testGenerator(): void
- {
- $tokenObject = new TokenObject();
- $tokenObject->setIssuedBy('xxxx');
- $tokenObject->setClaims(['foo' => 'bar']);
- $token = $this->jwt->generator($tokenObject);
- $this->assertInstanceOf(UnencryptedToken::class, $token);
- }
-
- public function testGeneratorWithSsoKey(): void
- {
- $black = \Mockery::mock(BlackContract::class);
- $config = $this->jwt->getSceneConfig('sso');
- $signer = $this->jwt->getSigner($config);
- $key = $this->jwt->getKey($config);
- $this->container->allows('get')->with(CacheBlack::class)->andReturn($black);
-
- $black->allows('add')->andReturn(true);
- $tokenObject = new TokenObject();
- $tokenObject->setClaims(['sso_key' => 'foo', 'foo' => 'bar', 'uid' => 111]);
- $token = $this->jwt->generator($tokenObject, 'sso');
- $this->assertInstanceOf(UnencryptedToken::class, $token);
- $this->assertTrue($this->jwt->getValidationData($signer, $key, $token->toString()));
- $tokenObject = new TokenObject();
- $tokenObject->setClaims(['sso_key' => 'foo', 'foo' => 'bar', 'uid' => 111]);
- $newToken = $this->jwt->generator($tokenObject, 'sso');
- $black->allows('has')->andReturnUsing(function ($key, $data) {
- return $key['jti'] === 'sso_111';
- });
- try {
- $this->jwt->parse($token->toString(), 'sso', true);
- } catch (\Exception $e) {
- $this->assertEquals($e->getMessage(), 'Token authentication does not pass');
- }
- $this->expectException(JwtConfigException::class);
- $tokenObject->setClaims(['sso_key' => 'foo', 'foo' => 'bar']);
- $this->jwt->generator($tokenObject, 'sso');
- }
-
- public function testGeneratorWithUnique(): void
- {
- $tokenObject = new TokenObject();
- $tokenObject->setClaims(['foo' => 'bar']);
- $token = $this->jwt->generator($tokenObject);
- $this->assertInstanceOf(UnencryptedToken::class, $token);
- }
-
- public function testParse(): void
- {
- $black = \Mockery::mock(BlackContract::class);
- $this->container->allows('get')->andReturn(CacheBlack::class)->andReturn($black);
- $black->allows('has')->andReturn(false);
- $object = new TokenObject();
- $object->setIssuedBy('xxxx');
- $object->setClaims(['foo' => 'bar', 'uid' => 'xxx']);
- $token = $this->jwt->generator($object);
- $parsedToken = $this->jwt->parse($token->toString());
- $this->assertInstanceOf(Token::class, $parsedToken);
- }
-
- public function testParseWithSsoKey(): void
- {
- $black = \Mockery::mock(BlackContract::class);
- $this->container->allows('get')->andReturn(CacheBlack::class)->andReturn($black);
- $black->allows('has')->andReturn(false);
- $black->allows('add')->andReturn(true);
- $tokenObject = new TokenObject();
- $tokenObject->setClaims(['sso_key' => 'foo', 'foo' => 'bar', 'uid' => 'xxx']);
- $token = $this->jwt->generator($tokenObject, 'sso');
- $parsedToken = $this->jwt->parse($token->toString(), 'sso');
- $this->assertInstanceOf(Token::class, $parsedToken);
- }
-
- public function testParseWithIndependentTokenVerify(): void
- {
- $black = \Mockery::mock(BlackContract::class);
- $this->container->allows('get')->andReturn(CacheBlack::class)->andReturn($black);
- $black->allows('has')->andReturn(false);
- $black->allows('add')->andReturn(true);
- $tokenObject = new TokenObject();
- $tokenObject->setClaims(['sso_key' => 'foo', 'foo' => 'bar', 'uid' => 'xxx']);
- $token = $this->jwt->generator($tokenObject, 'sso');
- $jwt = new Jwt($this->config, $this->container);
- $parsedToken = $jwt->parse($token->toString());
- $this->assertInstanceOf(Token::class, $parsedToken);
- }
-
- public function testParseWithValidate(): void
- {
- $black = \Mockery::mock(BlackContract::class);
- $this->container->allows('get')->andReturn(CacheBlack::class)->andReturn($black);
- $black->allows('has')->andReturn(false);
- $black->allows('add')->andReturn(true);
- $tokenObject = new TokenObject();
- $tokenObject->setClaims(['sso_key' => 'foo', 'foo' => 'bar', 'uid' => 'xxx']);
- $token = $this->jwt->generator($tokenObject);
- $parsedToken = $this->jwt->parse($token->toString(), 'default', false);
- $this->assertInstanceOf(Token::class, $parsedToken);
- }
-
- public function testRefreshToken()
- {
- $black = \Mockery::mock(BlackContract::class);
- $this->container->allows('get')->andReturn(CacheBlack::class)->andReturn($black);
- $black->allows('has')->andReturn(false);
- $black->allows('add')->andReturn(true);
- $tokenObject = new TokenObject();
- $tokenObject->setClaims(['sso_key' => 'foo', 'foo' => 'bar', 'uid' => 'xxx']);
- $token = $this->jwt->generator($tokenObject);
- $refreshedToken = $this->jwt->refreshToken($token->toString());
- $this->assertInstanceOf(Token::class, $refreshedToken);
- }
-
- public function testLogout()
- {
- $black = \Mockery::mock(CacheBlack::class);
- $this->container->allows('get')->with(CacheBlack::class)->andReturn($black);
- $instance = new TokenObject();
- $instance->setIssuedBy('xxxxx');
- $instance->setClaims([
- 'name' => 'zds',
- ]);
- $token = $this->jwt->generator($instance);
-
- $black->allows('has')->andReturn(false, true);
- $black->allows('add')->andReturn(true);
- $this->assertTrue($this->jwt->logout($token->toString()));
- $this->expectException(TokenValidException::class);
- $this->assertTrue($this->jwt->logout($token->toString()));
- }
-
- public function testGetTokenDynamicCacheTime(): void
- {
- $black = \Mockery::mock(CacheBlack::class);
- $black->allows('has')->andReturn(false);
- $this->container->allows('get')->with(CacheBlack::class)->andReturn($black);
- $instance = new TokenObject();
- $instance->setIssuedBy('xxxxx');
- $instance->setClaims([
- 'name' => 'zds',
- ]);
- $token = $this->jwt->generator($instance);
- $dynamicCacheTime = $this->jwt->getTokenDynamicCacheTime($token->toString());
- $this->assertIsInt($dynamicCacheTime);
- $this->assertEquals(7199, $dynamicCacheTime);
- sleep(1);
- $this->assertEquals(7198, $this->jwt->getTokenDynamicCacheTime($token->toString()));
- }
-
- public function testGetIndependentTokenVerify(): void
- {
- $config = ['independentTokenVerify' => true];
- $this->assertTrue($this->jwt->getIndependentTokenVerify($config));
- }
-
- public function testGetValidationData(): void
- {
- $config = $this->jwt->getSceneConfig('default');
- $black = \Mockery::mock(CacheBlack::class);
- $black->allows('has')->andReturn(false);
- $this->container->allows('get')->with(CacheBlack::class)->andReturn($black);
- $instance = new TokenObject();
- $instance->setIssuedBy('xxxxx');
- $instance->setClaims([
- 'name' => 'zds',
- ]);
- $token = $this->jwt->generator($instance);
- $signer = $this->jwt->getSigner($config);
- $key = $this->jwt->getKey($config);
- $this->assertTrue($this->jwt->getValidationData($signer, $key, $token->toString()));
- }
-
- /**
- * @throws JwtConfigException
- */
- public function testGetConfiguration(): void
- {
- $config = $this->jwt->getSceneConfig('default');
- $signer = $this->jwt->getSigner($config);
- $key = $this->jwt->getKey($config);
- $config = $this->jwt->getConfiguration($signer, $key);
- $this->assertInstanceOf(Configuration::class, $config);
- }
-
- public function testGetBlack(): void
- {
- $config = ['black' => CacheBlack::class];
- $this->container->allows('get')
- ->andReturn(CacheBlack::class)
- ->andReturn(\Mockery::mock(CacheBlack::class));
- $black = $this->jwt->getBlack($config);
- $this->assertInstanceOf(BlackContract::class, $black);
- }
-
- public function testGetBlackWithInvalidClass(): void
- {
- $config = ['black' => 'InvalidClass'];
- $this->expectException(JwtConfigException::class);
- $this->jwt->getBlack($config);
- }
-
- public function testGetSceneConfig(): void
- {
- $sceneConfig = $this->jwt->getSceneConfig('default');
- $this->assertIsArray($sceneConfig);
- }
-}
diff --git a/src/SecurityHttp/tests/Cases/Support/TimeTest.php b/src/SecurityHttp/tests/Cases/Support/TimeTest.php
deleted file mode 100644
index 61b954bf..00000000
--- a/src/SecurityHttp/tests/Cases/Support/TimeTest.php
+++ /dev/null
@@ -1,92 +0,0 @@
-assertInstanceOf(Carbon::class, $time);
- $this->assertSame('UTC', $time->getTimezone()->getName());
- }
-
- public function testTimestampReturnsCarbonInstance(): void
- {
- $timestamp = 1630000000;
- $time = Time::timestamp($timestamp);
-
- $this->assertInstanceOf(Carbon::class, $time);
- $this->assertSame('UTC', $time->getTimezone()->getName());
- $this->assertSame($timestamp, $time->getTimestamp());
- }
-
- public function testIsPastReturnsTrueForPastTimestamp(): void
- {
- $timestamp = time() - 60; // 60 seconds ago
- $result = Time::isPast($timestamp);
-
- $this->assertTrue($result);
- }
-
- public function testIsPastReturnsFalseForFutureTimestamp(): void
- {
- $timestamp = time() + 60; // 60 seconds later
- $result = Time::isPast($timestamp);
-
- $this->assertFalse($result);
- }
-
- public function testIsPastReturnsFalseForCurrentTimestampWithLeeway(): void
- {
- $timestamp = time();
- $leeway = 60; // 60 seconds
- $result = Time::isPast($timestamp, $leeway);
-
- $this->assertFalse($result);
- }
-
- public function testIsFutureReturnsTrueForFutureTimestamp(): void
- {
- $timestamp = time() + 60; // 60 seconds later
- $result = Time::isFuture($timestamp);
-
- $this->assertTrue($result);
- }
-
- public function testIsFutureReturnsFalseForPastTimestamp(): void
- {
- $timestamp = time() - 60; // 60 seconds ago
- $result = Time::isFuture($timestamp);
-
- $this->assertFalse($result);
- }
-
- public function testIsFutureReturnsFalseForCurrentTimestampWithLeeway(): void
- {
- $timestamp = time();
- $leeway = 60; // 60 seconds
- $result = Time::isFuture($timestamp, $leeway);
-
- $this->assertFalse($result);
- }
-}
diff --git a/src/SecurityHttp/tests/Cases/TokenObjectTest.php b/src/SecurityHttp/tests/Cases/TokenObjectTest.php
deleted file mode 100644
index c5df1cae..00000000
--- a/src/SecurityHttp/tests/Cases/TokenObjectTest.php
+++ /dev/null
@@ -1,36 +0,0 @@
-assertTrue(true);
- $instance = new TokenObject();
- $this->assertInstanceOf(TokenObject::class, $instance);
- $instance->setIssuedBy('xxx');
- $this->assertEquals('xxx', $instance->getIssuedBy());
- $instance->setClaims(['xxxx']);
- $this->assertEquals(['xxxx'], $instance->getClaims());
- $instance->setHeaders(['xxxx']);
- $this->assertEquals(['xxxx'], $instance->getHeaders());
- }
-}
diff --git a/src/SecurityHttp/tests/Cases/UserProviderTest.php b/src/SecurityHttp/tests/Cases/UserProviderTest.php
deleted file mode 100644
index 4721f99b..00000000
--- a/src/SecurityHttp/tests/Cases/UserProviderTest.php
+++ /dev/null
@@ -1,139 +0,0 @@
-assertEquals('admin', UserProvider::getScene());
- }
-
- public function testRetrieveByCredentials(): void
- {
- $event = \Mockery::mock(EventDispatcherInterface::class);
- $config = \Mockery::mock(Config::class);
- $config->allows('get')
- ->with('entity', '\App\Model\User')
- ->andReturn(UserModel::class);
- $builder = \Mockery::mock(Builder::class);
- ApplicationContext::getContainer()->set('mock.builder', $builder);
- $jwt = \Mockery::mock(Jwt::class);
- $userProvider = new UserProvider($event, $config, $jwt);
- $this->assertInstanceOf(UserProvider::class, $userProvider);
- $this->assertNull($userProvider->retrieveByCredentials([
- 'username' => 'admin@qq.com',
- 'password' => '123456',
- ]));
- $builder->allows('where')->andReturnUsing(function ($column, $value) use ($builder) {
- if ($column === 'email') {
- $this->assertEquals('xxx@qq.com', $value);
- }
- return $builder;
- });
- $user = new UserModel();
- $user->setPassword(password_hash('123456', PASSWORD_DEFAULT));
- $user2 = clone $user;
- $user2->setPassword(password_hash('1234567', PASSWORD_DEFAULT));
- $builder->allows('first')->andReturn($user, $user2);
- $jwt->allows('generator')->andReturnUsing(function (TokenObject $token) {
- $this->assertEquals('xxx@qq.com', $token->getIssuedBy());
- $this->assertEquals([
- '__attribute__id' => 1,
- '__attribute__email' => 'xxx@qq.com',
- ], $token->getClaims());
- return \Mockery::mock(UnencryptedToken::class);
- });
- $event->allows('dispatch')->andReturnUsing(function ($event) {
- $this->assertInstanceOf(Verified::class, $event);
- }, function ($event) {
- $this->assertInstanceOf(Login::class, $event);
- }, function ($event) {
- $this->assertInstanceOf(Validated::class, $event);
- });
- $this->assertInstanceOf(UnencryptedToken::class, $userProvider->retrieveByCredentials([
- 'email' => 'xxx@qq.com',
- 'password' => '123456',
- ]));
- $this->assertNull($userProvider->retrieveByCredentials([
- 'email' => 'xxx@qq.com',
- 'password' => '123456',
- ]));
- }
-
- public function testRetrieveById()
- {
- $event = \Mockery::mock(EventDispatcherInterface::class);
- $config = \Mockery::mock(Config::class);
- $config->allows('get')
- ->with('entity', '\App\Model\User')
- ->andReturn(UserModel::class);
- $builder = \Mockery::mock(Builder::class);
- ApplicationContext::getContainer()->set('mock.builder', $builder);
- $jwt = \Mockery::mock(Jwt::class);
- $userProvider = new UserProvider($event, $config, $jwt);
- $this->assertInstanceOf(UserProvider::class, $userProvider);
-
- $user = new UserModel();
- $user2 = clone $user;
- $builder->allows('first')->andReturn(null, $user, $user2);
- $builder->allows('where')->andReturn($builder);
- $jwt->allows('generator')->andReturnUsing(function (TokenObject $token) {
- $this->assertEquals('xxx@qq.com', $token->getIssuedBy());
- $this->assertEquals([
- '__attribute__id' => 1,
- '__attribute__email' => 'xxx@qq.com',
- ], $token->getClaims());
- return \Mockery::mock(UnencryptedToken::class);
- });
- $this->assertNull($userProvider->retrieveById('123@qq.com'));
- $this->assertInstanceOf(UnencryptedToken::class, $userProvider->retrieveById('123@qq.com'));
- }
-
- public function testUpdateRememberToken()
- {
- $reflection = new \ReflectionClass(UserProvider::class);
- $method = $reflection->getMethod('updateRememberToken');
- $instance = \Mockery::mock(UserProvider::class);
- try {
- $method->invokeArgs($instance, [\Mockery::mock(UserInterface::class), '133213123']);
- } catch (\Exception $e) {
- $this->assertEquals('Method not implemented', $e->getMessage());
- }
- }
-}
diff --git a/src/SecurityHttp/tests/Stub/DummyBlack.php b/src/SecurityHttp/tests/Stub/DummyBlack.php
deleted file mode 100644
index 64e44e87..00000000
--- a/src/SecurityHttp/tests/Stub/DummyBlack.php
+++ /dev/null
@@ -1,42 +0,0 @@
- 1,
- 'email' => 'xxx@qq.com',
- 'password' => '',
- ];
-
- public function getIdentifier(): string
- {
- return $this->attributes['email'];
- }
-
- public function getIdentifierName(): string
- {
- return 'email';
- }
-
- public function getRememberToken(): string
- {
- return '';
- }
-
- public function setRememberToken(string $token): void {}
-
- public function getRememberTokenName(): string
- {
- return '';
- }
-
- public function getPassword(): string
- {
- return $this->attributes['password'];
- }
-
- public function setPassword(string $password): void
- {
- $this->attributes['password'] = $password;
- }
-
- public function getSecurityBuilder(): Builder
- {
- return ApplicationContext::getContainer()->get('mock.builder');
- }
-}
diff --git a/src/translatable/.github/workflows/release.yml b/src/translatable/.github/workflows/release.yml
index 0f7d23fa..4ebb5d0a 100644
--- a/src/translatable/.github/workflows/release.yml
+++ b/src/translatable/.github/workflows/release.yml
@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: Create Release
id: create_release
uses: actions/create-release@v1