diff --git a/composer.lock b/composer.lock index e8917c9..77f0f40 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "45dd495df00abd36d94dc7ca02dce256", + "content-hash": "89f7ae78ea05c4cc22cc32f405d736ac", "packages": [ { "name": "brick/math", @@ -337,16 +337,16 @@ }, { "name": "illuminate/collections", - "version": "v11.22.0", + "version": "v11.23.5", "source": { "type": "git", "url": "https://github.com/illuminate/collections.git", - "reference": "66d2c9bdf5641599735d402c1c504b54734a9cca" + "reference": "cbea9d7a82984bbc1a9376498533cc77513f9a09" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/collections/zipball/66d2c9bdf5641599735d402c1c504b54734a9cca", - "reference": "66d2c9bdf5641599735d402c1c504b54734a9cca", + "url": "https://api.github.com/repos/illuminate/collections/zipball/cbea9d7a82984bbc1a9376498533cc77513f9a09", + "reference": "cbea9d7a82984bbc1a9376498533cc77513f9a09", "shasum": "" }, "require": { @@ -388,11 +388,11 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-08-23T18:49:36+00:00" + "time": "2024-09-12T14:50:04+00:00" }, { "name": "illuminate/conditionable", - "version": "v11.22.0", + "version": "v11.23.5", "source": { "type": "git", "url": "https://github.com/illuminate/conditionable.git", @@ -438,16 +438,16 @@ }, { "name": "illuminate/container", - "version": "v11.22.0", + "version": "v11.23.5", "source": { "type": "git", "url": "https://github.com/illuminate/container.git", - "reference": "85e3396fde3139eae3f37128222c9a7746ca4bbb" + "reference": "66d20471c8c55ef056044dc1ff16da90d7b4d649" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/container/zipball/85e3396fde3139eae3f37128222c9a7746ca4bbb", - "reference": "85e3396fde3139eae3f37128222c9a7746ca4bbb", + "url": "https://api.github.com/repos/illuminate/container/zipball/66d20471c8c55ef056044dc1ff16da90d7b4d649", + "reference": "66d20471c8c55ef056044dc1ff16da90d7b4d649", "shasum": "" }, "require": { @@ -485,20 +485,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-08-21T16:01:30+00:00" + "time": "2024-09-11T20:15:17+00:00" }, { "name": "illuminate/contracts", - "version": "v11.22.0", + "version": "v11.23.5", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", - "reference": "af9b459f195d57f279ec30a45446ddaeb3337bcb" + "reference": "5a4c6dcf633c1f69e1b70bbea1ef1b7d2186d3da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/contracts/zipball/af9b459f195d57f279ec30a45446ddaeb3337bcb", - "reference": "af9b459f195d57f279ec30a45446ddaeb3337bcb", + "url": "https://api.github.com/repos/illuminate/contracts/zipball/5a4c6dcf633c1f69e1b70bbea1ef1b7d2186d3da", + "reference": "5a4c6dcf633c1f69e1b70bbea1ef1b7d2186d3da", "shasum": "" }, "require": { @@ -533,7 +533,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-08-21T16:02:16+00:00" + "time": "2024-09-12T15:25:08+00:00" }, { "name": "illuminate/database", @@ -672,7 +672,7 @@ }, { "name": "illuminate/macroable", - "version": "v11.22.0", + "version": "v11.23.5", "source": { "type": "git", "url": "https://github.com/illuminate/macroable.git", @@ -718,16 +718,16 @@ }, { "name": "illuminate/support", - "version": "v11.22.0", + "version": "v11.23.5", "source": { "type": "git", "url": "https://github.com/illuminate/support.git", - "reference": "51efc0516526413b4be641a1731d15d4394de2ff" + "reference": "8199097b4e24b05e8a035a6ea2fb5aeba645d71b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/support/zipball/51efc0516526413b4be641a1731d15d4394de2ff", - "reference": "51efc0516526413b4be641a1731d15d4394de2ff", + "url": "https://api.github.com/repos/illuminate/support/zipball/8199097b4e24b05e8a035a6ea2fb5aeba645d71b", + "reference": "8199097b4e24b05e8a035a6ea2fb5aeba645d71b", "shasum": "" }, "require": { @@ -751,6 +751,7 @@ }, "suggest": { "illuminate/filesystem": "Required to use the composer class (^11.0).", + "laravel/serializable-closure": "Required to use the once function (^1.3).", "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^2.0.2).", "ramsey/uuid": "Required to use Str::uuid() (^4.7).", "symfony/process": "Required to use the composer class (^7.0).", @@ -788,7 +789,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-09-03T13:21:20+00:00" + "time": "2024-09-12T15:25:39+00:00" }, { "name": "itguild/eloquent-table", @@ -886,11 +887,11 @@ }, { "name": "itguild/tables", - "version": "1.0.6", + "version": "1.0.7", "source": { "type": "git", "url": "https://git.itguild.info/ItGuild/tables", - "reference": "d747203d99871ab39a5f18c449727f150b937c44" + "reference": "02a3e52b7d365c44a32b7580a2246d47ea032736" }, "type": "library", "autoload": { @@ -908,7 +909,7 @@ "email": "apuc06@mail.ru" } ], - "time": "2024-09-02T19:34:25+00:00" + "time": "2024-09-24T12:42:55+00:00" }, { "name": "madesimple/php-arrays", @@ -2027,16 +2028,16 @@ }, { "name": "symfony/translation", - "version": "v7.1.3", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "8d5e50c813ba2859a6dfc99a0765c550507934a1" + "reference": "235535e3f84f3dfbdbde0208ede6ca75c3a489ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/8d5e50c813ba2859a6dfc99a0765c550507934a1", - "reference": "8d5e50c813ba2859a6dfc99a0765c550507934a1", + "url": "https://api.github.com/repos/symfony/translation/zipball/235535e3f84f3dfbdbde0208ede6ca75c3a489ea", + "reference": "235535e3f84f3dfbdbde0208ede6ca75c3a489ea", "shasum": "" }, "require": { @@ -2101,7 +2102,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v7.1.3" + "source": "https://github.com/symfony/translation/tree/v7.1.5" }, "funding": [ { @@ -2117,7 +2118,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:41:01+00:00" + "time": "2024-09-16T06:30:38+00:00" }, { "name": "symfony/translation-contracts", @@ -2493,7 +2494,9 @@ }, "prefer-stable": false, "prefer-lowest": false, - "platform": [], + "platform": { + "ext-zip": "*" + }, "platform-dev": [], - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.3.0" } diff --git a/kernel/admin_themes/default/layout/login.php b/kernel/admin_themes/default/layout/login.php new file mode 100644 index 0000000..902e4ee --- /dev/null +++ b/kernel/admin_themes/default/layout/login.php @@ -0,0 +1,34 @@ + + + + + Sidebar 01 + + + + + + + + + + +
+ + +
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/kernel/admin_themes/default/layout/main.php b/kernel/admin_themes/default/layout/main.php index 359d115..052e831 100644 --- a/kernel/admin_themes/default/layout/main.php +++ b/kernel/admin_themes/default/layout/main.php @@ -14,14 +14,18 @@ - +
- +
- - - - + + + + \ No newline at end of file diff --git a/kernel/console/controllers/AdminConsoleController.php b/kernel/console/controllers/AdminConsoleController.php index d4a48fd..9cf868a 100644 --- a/kernel/console/controllers/AdminConsoleController.php +++ b/kernel/console/controllers/AdminConsoleController.php @@ -5,6 +5,9 @@ namespace kernel\console\controllers; use kernel\console\ConsoleController; use kernel\modules\menu\service\MenuService; use kernel\modules\option\service\OptionService; +use kernel\modules\user\models\forms\CreateUserForm; +use kernel\modules\user\models\User; +use kernel\modules\user\service\UserService; use kernel\services\MigrationService; class AdminConsoleController extends ConsoleController @@ -13,7 +16,9 @@ class AdminConsoleController extends ConsoleController protected MigrationService $migrationService; protected OptionService $optionService; - public MenuService $menuService; + protected MenuService $menuService; + + protected UserService $userService; public function __construct() { @@ -21,6 +26,7 @@ class AdminConsoleController extends ConsoleController $this->migrationService = new MigrationService(); $this->optionService = new OptionService(); $this->menuService = new MenuService(); + $this->userService = new UserService(); } /** @@ -73,7 +79,6 @@ class AdminConsoleController extends ConsoleController "url" => "/admin", "slug" => "module", "priority" => 1, - "status" => 2 ]); $this->out->r("create item menu module", "green"); @@ -91,6 +96,16 @@ class AdminConsoleController extends ConsoleController "parent_slug" => "settings" ]); $this->out->r("create item menu admin-themes", "green"); + + $user = new CreateUserForm(); + $user->load([ + 'username' => 'admin', + 'password' => 'ChangeMe', + 'email' => 'admin@test.ru', + 'role' => User::ADMIN_USER_ROLE, + ]); + $this->userService->create($user); + $this->out->r("create user with username admin", "green"); } } \ No newline at end of file diff --git a/kernel/controllers/SecureController.php b/kernel/controllers/SecureController.php new file mode 100644 index 0000000..518e3cd --- /dev/null +++ b/kernel/controllers/SecureController.php @@ -0,0 +1,60 @@ +cgView->viewPath = KERNEL_DIR . "/views/secure/"; + $this->cgView->layout = "/login.php"; + $this->userService = new UserService(); + } + + public function actionLogin(): void + { + $this->cgView->render('login.php'); + } + + public function actionAuth(): void + { + $loginForm = new LoginForm(); + $loginForm->load($_REQUEST); + + if(filter_var($loginForm->getItem("username"), FILTER_VALIDATE_EMAIL)) { + $field = "email"; + } + else { + $field = "username"; + } + + $user = $this->userService->getByField($field, $loginForm->getItem("username")); + if (!$user){ + throw new \Exception(message: "User not found"); + } + + if (password_verify($loginForm->getItem("password"), $user->password_hash)) { + setcookie('user_id', $user->id, time()+60*60*24, '/', $_SERVER['SERVER_NAME'], false); + $this->redirect("/admin"); + } else { + $this->redirect("/admin/login"); + } + } + + #[NoReturn] public function actionLogout(): void + { + unset($_COOKIE['user_id']); + setcookie('user_id', "", time() - 3600, '/'); + $this->redirect("/"); + } + +} \ No newline at end of file diff --git a/kernel/models/forms/LoginForm.php b/kernel/models/forms/LoginForm.php new file mode 100644 index 0000000..902d9ee --- /dev/null +++ b/kernel/models/forms/LoginForm.php @@ -0,0 +1,18 @@ + 'required|min-str-len:5|max-str-len:50', + 'password' => 'required|min-str-len:6|max-str-len:50', + ]; + } + +} \ No newline at end of file diff --git a/kernel/modules/admin_themes/controllers/AdminThemeController.php b/kernel/modules/admin_themes/controllers/AdminThemeController.php index 8123b80..48fc8a5 100644 --- a/kernel/modules/admin_themes/controllers/AdminThemeController.php +++ b/kernel/modules/admin_themes/controllers/AdminThemeController.php @@ -20,6 +20,7 @@ class AdminThemeController extends AdminController public function actionIndex(): void { $admin_theme_paths = Option::where("key", "admin_theme_paths")->first(); + $dirs = []; if ($admin_theme_paths){ $path = json_decode($admin_theme_paths->value); diff --git a/kernel/modules/admin_themes/views/index.php b/kernel/modules/admin_themes/views/index.php index 8ae87ff..50d728e 100644 --- a/kernel/modules/admin_themes/views/index.php +++ b/kernel/modules/admin_themes/views/index.php @@ -14,9 +14,9 @@ $table->columns([ ]); $table->addAction(function ($row, $url){ $path = $row['path']; - $active_admin_theme = Option::where("key", "active_admin_theme")->first(); + $active_admin_theme = \kernel\modules\option\service\OptionService::getItem('active_admin_theme'); $btn = "Активировать"; - if ($path === $active_admin_theme->value){ + if ($path === $active_admin_theme){ $btn = "Активна"; } diff --git a/kernel/modules/option/service/OptionService.php b/kernel/modules/option/service/OptionService.php index ba674d9..139d0fb 100644 --- a/kernel/modules/option/service/OptionService.php +++ b/kernel/modules/option/service/OptionService.php @@ -49,6 +49,20 @@ class OptionService return false; } + /** + * @param $key + * @return false|array|string + */ + public static function getItem($key): false|array|string + { + $item = Option::where("key", $key)->first(); + if ($item){ + return getConst($item->value); + } + + return false; + } + // public function createOptionArr(): array // { // foreach (Option::all()->toArray() as $option) { diff --git a/kernel/modules/user/models/User.php b/kernel/modules/user/models/User.php index f6a37c7..6663709 100644 --- a/kernel/modules/user/models/User.php +++ b/kernel/modules/user/models/User.php @@ -7,10 +7,13 @@ use Illuminate\Database\Eloquent\Model; * @property string $username * @property string $email * @property string $password_hash - * @method static where(int[] $array) * @method static find($id) */ class User extends Model { + + const DEFAULT_USER_ROLE = 1; + const ADMIN_USER_ROLE = 9; + protected $table = 'user'; protected $fillable = ['username', 'email', 'password_hash', 'role']; protected array $dates = ['deleted at']; diff --git a/kernel/modules/user/service/UserService.php b/kernel/modules/user/service/UserService.php index 9d8bafa..514675e 100644 --- a/kernel/modules/user/service/UserService.php +++ b/kernel/modules/user/service/UserService.php @@ -33,6 +33,11 @@ class UserService return false; } + public function getByField(string $field, string $value) + { + return User::where($field, $value)->first(); + } + public static function createUsernameArr(): array { foreach (User::all()->toArray() as $user) { @@ -45,4 +50,26 @@ class UserService return []; } + public static function getAuthUser() + { + if (isset($_COOKIE['user_id'])){ + $user = User::where("id", $_COOKIE['user_id'])->first(); + if ($user){ + return $user; + } + } + + return false; + } + + public static function getAuthUsername(): string + { + $user = self::getAuthUser(); + if ($user){ + return $user->username; + } + + return ''; + } + } \ No newline at end of file diff --git a/kernel/routs/admin.php b/kernel/routs/admin.php index cad4eba..86f7abf 100644 --- a/kernel/routs/admin.php +++ b/kernel/routs/admin.php @@ -5,12 +5,26 @@ use kernel\App; use kernel\modules\admin_themes\controllers\AdminThemeController; use Phroute\Phroute\RouteCollector; +App::$collector->filter("auth", function (){ + if(!isset($_COOKIE['user_id'])) + { + header('Location: /admin/login'); + + return false; + } +}); App::$collector->group(["prefix" => "admin"], function (RouteCollector $router){ - App::$collector->get('/', [\kernel\controllers\ModuleController::class, 'actionIndex']); - App::$collector->group(["prefix" => "module"], function (RouteCollector $router){ + App::$collector->group(["before" => "auth"], function (RouteCollector $router){ App::$collector->get('/', [\kernel\controllers\ModuleController::class, 'actionIndex']); - App::$collector->get('/activate', [\kernel\controllers\ModuleController::class, 'actionActivate']); }); - + App::$collector->get('/login', [\kernel\controllers\SecureController::class, 'actionLogin']); + App::$collector->get('/logout', [\kernel\controllers\SecureController::class, 'actionLogout']); + App::$collector->post('/auth', [\kernel\controllers\SecureController::class, 'actionAuth']); + App::$collector->group(["before" => "auth"], function (RouteCollector $router){ + App::$collector->group(["prefix" => "module"], function (RouteCollector $router){ + App::$collector->get('/', [\kernel\controllers\ModuleController::class, 'actionIndex']); + App::$collector->get('/activate', [\kernel\controllers\ModuleController::class, 'actionActivate']); + }); + }); }); \ No newline at end of file diff --git a/kernel/views/secure/login.php b/kernel/views/secure/login.php new file mode 100644 index 0000000..c6cd7c3 --- /dev/null +++ b/kernel/views/secure/login.php @@ -0,0 +1,67 @@ + +
+ +
+
+
+ Trendy Pants and Shoes +
+
+
+ +
+ +
+ + +
+ + +
+ + +
+ + +
+
+ +
+ + +
+
+ + +
+ + + + +
+ +
+
+
+
+
+ \ No newline at end of file