Просмотр исходного кода

成り代わり処理の整備

develop
sosuke.iwabuchi 1 год назад
Родитель
Сommit
aa8e6d1dba
11 измененных файлов: 255 добавлений и 31 удалений
  1. +1
    -0
      app/Http/Controllers/Web/Auth/LogoutController.php
  2. +39
    -0
      app/Http/Controllers/Web/Auth/SwitchController.php
  3. +34
    -0
      app/Http/Controllers/Web/Auth/SwitchEndController.php
  4. +9
    -0
      app/Http/Controllers/Web/Auth/SwitchEndParam.php
  5. +18
    -0
      app/Http/Controllers/Web/Auth/SwitchParam.php
  6. +4
    -24
      app/Http/Controllers/Web/WebController.php
  7. +2
    -1
      app/Http/Kernel.php
  8. +38
    -0
      app/Http/Middleware/RoleMiddleware.php
  9. +85
    -5
      app/Sessions/SessionUser.php
  10. +15
    -0
      app/Util/RouteHelper.php
  11. +10
    -1
      routes/api.php

+ 1
- 0
app/Http/Controllers/Web/Auth/LogoutController.php Просмотреть файл

@@ -28,6 +28,7 @@ class LogoutController extends WebController
protected function run(Request $request): JsonResponse
{
Auth::logout();
$this->sessionUser->switchEnd();
return $this->successResponse();
}
}

+ 39
- 0
app/Http/Controllers/Web/Auth/SwitchController.php Просмотреть файл

@@ -0,0 +1,39 @@
<?php

namespace App\Http\Controllers\Web\Auth;

use App\Http\Controllers\Web\WebController;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class SwitchController extends WebController
{

public function name(): string
{
return "成り代わり";
}

public function description(): string
{
return "成り代わりを行う";
}


public function __construct(protected SwitchParam $param)
{
parent::__construct();
}

protected function run(Request $request): JsonResponse
{
$param = $this->param;

$user = User::findOrFail($param->userId);

$this->sessionUser->switch($user);

return $this->successResponse();
}
}

+ 34
- 0
app/Http/Controllers/Web/Auth/SwitchEndController.php Просмотреть файл

@@ -0,0 +1,34 @@
<?php

namespace App\Http\Controllers\Web\Auth;

use App\Http\Controllers\Web\WebController;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class SwitchEndController extends WebController
{

public function name(): string
{
return "成り代わりを終了する";
}

public function description(): string
{
return "成り代わりを終了する";
}


public function __construct(protected SwitchParam $param)
{
parent::__construct();
}

protected function run(Request $request): JsonResponse
{
$this->sessionUser->switchEnd();

return $this->successResponse();
}
}

+ 9
- 0
app/Http/Controllers/Web/Auth/SwitchEndParam.php Просмотреть файл

@@ -0,0 +1,9 @@
<?php

namespace App\Http\Controllers\Web\Auth;

use App\Http\Controllers\Web\NoneParams;

class SwitchParam extends NoneParams
{
}

+ 18
- 0
app/Http/Controllers/Web/Auth/SwitchParam.php Просмотреть файл

@@ -0,0 +1,18 @@
<?php

namespace App\Http\Controllers\Web\Auth;

use App\Http\Controllers\Web\BaseParam;

/**
* @property string userId
*/
class SwitchParam extends BaseParam
{
public function rules(): array
{
return [
'user_id' => $this->str(),
];
}
}

+ 4
- 24
app/Http/Controllers/Web/WebController.php Просмотреть файл

@@ -8,6 +8,7 @@ use App\Codes\UserRole;
use App\Exceptions\AppCommonException;
use App\Exceptions\ExclusiveException;
use App\Exceptions\GeneralErrorMessageException;
use App\Sessions\SessionUser;
use App\Util\DBUtil;
use Exception;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
@@ -79,6 +80,8 @@ abstract class WebController extends BaseController

protected DBUtil $transaction;

protected SessionUser $sessionUser;

/**
* 返却する結果コード
*
@@ -89,6 +92,7 @@ abstract class WebController extends BaseController
public function __construct()
{
$this->transaction = DBUtil::instance();
$this->sessionUser = SessionUser::instance();
}


@@ -168,8 +172,6 @@ abstract class WebController extends BaseController
$this->validated = $validator->validated();
$this->getParam()->setData($this->validated);

$this->authorize();

$this->transaction->beginTransaction();
$ret = $this->run($request);

@@ -326,28 +328,6 @@ abstract class WebController extends BaseController
return $header;
}

// 以下 認可関係
protected array|null $roleAllow = null;
protected array|null $roleDisallow = null;
protected array|null $customAllow = null;

protected function roleAllow(UserRole $role)
{
$this->roleAllow = [];
foreach (UserRole::cases() as $ele) {
if ($role->value <= $ele->value) {
$this->roleAllow[] = $ele;
}
}
}

private function authorize()
{
if (!Auth::check()) {
return;
}
}

// 返却用データの登録
protected function setEmailId(int $emailId)
{


+ 2
- 1
app/Http/Kernel.php Просмотреть файл

@@ -40,7 +40,7 @@ class Kernel extends HttpKernel

'api' => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
\Illuminate\Routing\Middleware\ThrottleRequests::class . ':api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
@@ -64,5 +64,6 @@ class Kernel extends HttpKernel
'signed' => \App\Http\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'role' => \App\Http\Middleware\RoleMiddleware::class,
];
}

+ 38
- 0
app/Http/Middleware/RoleMiddleware.php Просмотреть файл

@@ -0,0 +1,38 @@
<?php

namespace App\Http\Middleware;

use App\Codes\UserRole;
use App\Sessions\SessionUser;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class RoleMiddleware
{

public function __construct(private SessionUser $sessionUser)
{
}
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next, string $rolesStr): Response
{
$allowRoles = [];

foreach (explode(",", $rolesStr) as $roleSrt) {
$role = UserRole::from($roleSrt);
$allowRoles[] = $role;
}


if (in_array($this->sessionUser->user()->role, $allowRoles, true) === false) {
abort(403);
}

return $next($request);
}
}

+ 85
- 5
app/Sessions/SessionUser.php Просмотреть файл

@@ -2,20 +2,100 @@

namespace App\Sessions;

use App\Codes\UserRole;
use App\Exceptions\AppCommonException;
use App\Features\InstanceAble;
use App\Models\HtpmsCustomer\HtpmsCustomerConnectionSwitch;
use App\Models\User;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\UnauthorizedException;
use Illuminate\Support\Facades\Session;
use LogicException;

class SessionUser
{
use InstanceAble;

public function user()
private const KEY_成り代わりログインユーザーID = "KEY_成り代わりログインユーザーID";

private User|null $user;
private bool $isSwtiched = false;

public function __construct()
{
// 認証していない場合はスキップ
$this->user = Auth::user();
if ($this->user === null) {
return;
}

$userId = Session::get($this->getStoreKey(self::KEY_成り代わりログインユーザーID));

if ($userId === null) {
return;
}

$user = User::find($userId);

if ($user) {
$this->user = $user;
if ($user->customer_id) {
HtpmsCustomerConnectionSwitch::switch($user->customer_id);
$this->isSwtiched = true;
}
} else {
logger("無効な成り代わり 破棄");
$this->switchEnd();
}
}

public function switch(User $targetUser): void
{
$user = Auth::user();
if ($user === null) {
throw new UnauthorizedException();
if ($user === null) throw new AuthenticationException();

// 成り代わりできるかパターンチェック
if ($user->role === UserRole::ADMIN) {
if (in_array($targetUser->role, [UserRole::CUSTOMER, UserRole::SHOP], true) === false) {
throw new LogicException("不適切な成り代わり");
}
} else if ($user->role === UserRole::CUSTOMER) {
if (in_array($targetUser->role, [UserRole::SHOP], true) === false) {
throw new LogicException("不適切な成り代わり");
}
} else {
throw new LogicException("不適切な成り代わり");
}

// 顧客IDチェック
if ($targetUser->customer_id === null) {
throw new AppCommonException("顧客IDがnullのため成り代わり不可");
}
return $user;


Session::put($this->getStoreKey(self::KEY_成り代わりログインユーザーID), $targetUser->id);
HtpmsCustomerConnectionSwitch::switch($targetUser->customer_id);
$this->isSwtiched = true;
}

public function switchEnd()
{
$this->isSwtiched = false;
Session::remove($this->getStoreKey(self::KEY_成り代わりログインユーザーID));
}

public function user(): ?User
{
return $this->user ?? Auth::user();
}

public function isSwtiched(): bool
{
return $this->isSwtiched;
}

private function getStoreKey(string $key): string
{
return sprintf("%s-%s", self::class, $key);
}
}

+ 15
- 0
app/Util/RouteHelper.php Просмотреть файл

@@ -2,6 +2,7 @@

namespace App\Util;

use App\Codes\UserRole;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Str;

@@ -43,4 +44,18 @@ class RouteHelper
{
return Str::replaceFirst('/api', '', $route);
}

/**
* @param UserRole[] $roles
*/
static public function role(array $roles): string
{
$rolesStrArr = [];

foreach ($roles as $role) {
$rolesStrArr[] = $role->value;
}

return "role:" . implode(",", $rolesStrArr);
}
}

+ 10
- 1
routes/api.php Просмотреть файл

@@ -1,5 +1,6 @@
<?php

use App\Codes\UserRole;
use App\Util\RouteHelper;
use Illuminate\Support\Facades\Route;

@@ -15,10 +16,18 @@ use Illuminate\Support\Facades\Route;
*/

RouteHelper::post('/login', App\Http\Controllers\Web\Auth\LoginController::class);
RouteHelper::get('/logout', App\Http\Controllers\Web\Auth\LogoutController::class);
RouteHelper::get('/me', App\Http\Controllers\Web\Auth\MeController::class);
RouteHelper::get('/logout', App\Http\Controllers\Web\Auth\LogoutController::class);

RouteHelper::get('/qr-service/get-ticket', App\Http\Controllers\Web\QRService\CreateTicketController::class);

Route::middleware('auth:sanctum')->group(function () {

Route::middleware(RouteHelper::role([UserRole::ADMIN]))->group(function () {
});

Route::middleware(RouteHelper::role([UserRole::ADMIN, UserRole::CUSTOMER]))->group(function () {
RouteHelper::post('/role/switch', App\Http\Controllers\Web\Auth\SwitchController::class);
RouteHelper::get('/role/switch/end', App\Http\Controllers\Web\Auth\SwitchEndController::class);
});
});

Загрузка…
Отмена
Сохранить