trafficmonitor init...2
This commit is contained in:
parent
c79db51fac
commit
13d63450c3
@ -395,5 +395,5 @@ define("ROLE", [
|
|||||||
'DIRECTOR' => "director",
|
'DIRECTOR' => "director",
|
||||||
'MASTER' => "master",
|
'MASTER' => "master",
|
||||||
],
|
],
|
||||||
['CLIENT'] => []
|
'CLIENT' => [],
|
||||||
]);
|
]);
|
||||||
|
|||||||
@ -76,4 +76,13 @@ abstract class AuthController extends CommonController
|
|||||||
return redirect()->back()->withInput()->with('error', "로그아웃 중 오류가 발생했습니다.");
|
return redirect()->back()->withInput()->with('error', "로그아웃 중 오류가 발생했습니다.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
protected function create_form_process(): void {}
|
||||||
|
protected function create_process(): RedirectResponse
|
||||||
|
{
|
||||||
|
return redirect()->to('/');
|
||||||
|
}
|
||||||
|
protected function modify_form_process($uid): mixed
|
||||||
|
{
|
||||||
|
return new UserEntity();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,13 +3,16 @@
|
|||||||
namespace App\DTOs;
|
namespace App\DTOs;
|
||||||
|
|
||||||
use App\Services\Auth\AuthService;
|
use App\Services\Auth\AuthService;
|
||||||
|
use CodeIgniter\Entity\Entity; // DTO가 Entity를 상속받지 않는 경우, 필요한 경우 CommonDTO 또는 Entity 상속을 유지합니다.
|
||||||
|
|
||||||
class CertificationDTO extends CommonDTO
|
class CertificationDTO extends Entity // DTO가 Entity를 상속받는 것으로 가정합니다.
|
||||||
{
|
{
|
||||||
public bool $isLogin = false;
|
// 💡 role의 타입을 ?string에서 ?array로 변경합니다.
|
||||||
public ?int $uid = null;
|
public ?string $uid = null;
|
||||||
|
public ?bool $isLogin = null;
|
||||||
public ?string $name = null;
|
public ?string $name = null;
|
||||||
public ?string $role = null;
|
public ?array $role = null;
|
||||||
|
|
||||||
public function __construct(array $datas = [])
|
public function __construct(array $datas = [])
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
@ -19,6 +22,7 @@ class CertificationDTO extends CommonDTO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function fromByAuthService(AuthService $service): self
|
public static function fromByAuthService(AuthService $service): self
|
||||||
{
|
{
|
||||||
return new self(
|
return new self(
|
||||||
@ -26,7 +30,7 @@ class CertificationDTO extends CommonDTO
|
|||||||
'isLogin' => $service->isLoggedIn(),
|
'isLogin' => $service->isLoggedIn(),
|
||||||
'uid' => $service->getUID(),
|
'uid' => $service->getUID(),
|
||||||
'name' => $service->getName(),
|
'name' => $service->getName(),
|
||||||
'role' => $service->getRole(),
|
'role' => $service->getRole(), //배열(array|null)을 반환합니다.
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ namespace App\Entities;
|
|||||||
|
|
||||||
use App\Entities\CommonEntity;
|
use App\Entities\CommonEntity;
|
||||||
use App\Models\UserModel as Model;
|
use App\Models\UserModel as Model;
|
||||||
|
use CodeIgniter\Entity\Entity; // Entity 클래스를 명시적으로 use 하는 것이 좋습니다.
|
||||||
|
|
||||||
class UserEntity extends CommonEntity
|
class UserEntity extends CommonEntity
|
||||||
{
|
{
|
||||||
@ -11,9 +12,12 @@ class UserEntity extends CommonEntity
|
|||||||
const TITLE = Model::TITLE;
|
const TITLE = Model::TITLE;
|
||||||
const DEFAULT_STATUS = STATUS['AVAILABLE'];
|
const DEFAULT_STATUS = STATUS['AVAILABLE'];
|
||||||
|
|
||||||
// 💡 1. $casts 속성 추가:
|
/**
|
||||||
// DB에 JSON 형태로 저장된 'role' 컬럼을 PHP에서 배열로 자동 변환합니다.
|
* @var array Entity 속성을 DB에 저장하거나 DB에서 로드할 때의 형 변환 규칙
|
||||||
|
*/
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
|
// 'role' 컬럼에 배열을 할당하면 DB에 JSON 문자열로 저장되며,
|
||||||
|
// DB에서 로드할 때 JSON 문자열이 자동으로 PHP 배열로 변환됩니다.
|
||||||
'role' => 'json-array',
|
'role' => 'json-array',
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -26,21 +30,45 @@ class UserEntity extends CommonEntity
|
|||||||
{
|
{
|
||||||
return $this->attributes['passwd'];
|
return $this->attributes['passwd'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// $formDatas['passwd']에 평문 비밀번호가 들어있으면,
|
// $formDatas['passwd']에 평문 비밀번호가 들어있으면,
|
||||||
//Model->insert시 Entity 생성자($formDatas)가 setPasswd()를 자동으로 호출합니다.
|
// Model->insert시 Entity 생성자($formDatas)가 setPasswd()를 자동으로 호출합니다.
|
||||||
public function setPasswd(string $password)
|
public function setPasswd(string $password)
|
||||||
{
|
{
|
||||||
|
// 비밀번호를 암호화하여 저장합니다.
|
||||||
$this->attributes['passwd'] = password_hash($password, PASSWORD_BCRYPT);
|
$this->attributes['passwd'] = password_hash($password, PASSWORD_BCRYPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 사용자의 역할을 배열 형태로 반환합니다.
|
* 사용자의 역할을 배열 형태로 반환합니다.
|
||||||
* $casts에 의해 DB에서 읽어올 때 이미 배열로 변환되어 있습니다.
|
* $casts에 의해 DB에서 읽어올 때 이미 배열로 변환될 것을 기대합니다.
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getRole(): array
|
public function getRole(): array
|
||||||
{
|
{
|
||||||
// 💡 2. 반환 타입을 array로 변경하고,
|
$role = $this->attributes['role'] ?? [];
|
||||||
// null일 경우를 대비해 빈 배열을 반환하도록 처리합니다.
|
|
||||||
return $this->attributes['role'] ?? [];
|
// 1. $casts가 성공적으로 작동했거나, 이미 배열인 경우 바로 반환합니다.
|
||||||
|
if (is_array($role)) {
|
||||||
|
return $role;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 캐스팅에 실패했으나 원본이 문자열로 남아있는 경우 (JSON 또는 CSV)
|
||||||
|
if (is_string($role) && !empty($role)) {
|
||||||
|
// 2-a. JSON 디코딩을 시도합니다.
|
||||||
|
$decodedRole = json_decode($role, true);
|
||||||
|
|
||||||
|
if (json_last_error() === JSON_ERROR_NONE && is_array($decodedRole)) {
|
||||||
|
return $decodedRole; // 유효한 JSON 배열인 경우
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2-b. JSON이 아니면 레거시 CSV 형식이라고 가정하고 explode로 변환합니다.
|
||||||
|
if (defined('DEFAULTS') && isset(DEFAULTS['DELIMITER_ROLE'])) {
|
||||||
|
return explode(DEFAULTS['DELIMITER_ROLE'], $role);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 변환에 실패했거나 데이터가 없는 경우 빈 배열 반환
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,7 +39,7 @@ class AuthFilter implements FilterInterface
|
|||||||
if (!$auth->isAccessRole($arguments)) {
|
if (!$auth->isAccessRole($arguments)) {
|
||||||
return redirect()->back()->with(
|
return redirect()->back()->with(
|
||||||
'error',
|
'error',
|
||||||
"회원[{$auth->getNameByAuthInfo()}]님은 접속에 필요한 권한이 없습니다. "
|
"회원[{$auth->getName()}]님은 접속에 필요한 권한이 없습니다. "
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace App\Helpers;
|
namespace App\Helpers;
|
||||||
|
|
||||||
|
use App\Entities\UserEntity;
|
||||||
|
|
||||||
class UserHelper extends CommonHelper
|
class UserHelper extends CommonHelper
|
||||||
{
|
{
|
||||||
public function __construct()
|
public function __construct()
|
||||||
@ -16,23 +18,19 @@ class UserHelper extends CommonHelper
|
|||||||
$form = form_password($field, "", [...$extras]);
|
$form = form_password($field, "", [...$extras]);
|
||||||
break;
|
break;
|
||||||
case 'role':
|
case 'role':
|
||||||
// 💡 $value는 수정 폼 로드시 현재 Entity의 'role' 배열입니다.
|
//$viewDatas['control']['entity']->$field에서 getRole()로 캐스팅이 되지 않아서 대체함
|
||||||
// (old() 값이 있다면 old() 배열이 됩니다.)
|
if (($viewDatas['control']['entity'] ?? null) instanceof UserEntity) {
|
||||||
$currentRoles = is_array($value) ? $value : [];
|
$value = $viewDatas['control']['entity']->getRole();
|
||||||
// 사용 가능한 모든 역할 목록 (Service 등에서 가져온다고 가정)
|
}
|
||||||
$allRoles = $viewDatas['control']['formOptions']['role'] ?? ROLE['USER'];
|
$currentRoles = is_array($value)
|
||||||
|
? array_map('strtolower', array_map('trim', $value))
|
||||||
|
: [];
|
||||||
$form = '';
|
$form = '';
|
||||||
// 2. 각 역할에 대한 체크박스를 순회하며 생성
|
//체크박스를 순회하며 생성
|
||||||
foreach ($allRoles as $roleValue => $roleLabel) {
|
foreach ($viewDatas['control']['formOptions']['role'] as $roleValue => $roleLabel) {
|
||||||
|
$checked = in_array(strtolower(trim($roleValue)), $currentRoles);
|
||||||
// $roleLabel이 배열이 아닌 문자열만 있는 경우를 대비
|
|
||||||
if (is_int($roleValue)) {
|
|
||||||
$roleValue = $roleLabel;
|
|
||||||
$roleLabel = ucfirst($roleValue);
|
|
||||||
}
|
|
||||||
$checked = in_array($roleValue, $currentRoles);
|
|
||||||
// 3. name="role[]" 형태로 배열 데이터 전송 준비
|
|
||||||
$form .= '<label class="me-3">';
|
$form .= '<label class="me-3">';
|
||||||
|
// form_checkbox에 들어가는 값($roleValue)은 원본 값을 유지(저장용).
|
||||||
$form .= form_checkbox('role[]', $roleValue, $checked, array_merge(['id' => "role_{$roleValue}"], $extras));
|
$form .= form_checkbox('role[]', $roleValue, $checked, array_merge(['id' => "role_{$roleValue}"], $extras));
|
||||||
$form .= " {$roleLabel}";
|
$form .= " {$roleLabel}";
|
||||||
$form .= '</label>';
|
$form .= '</label>';
|
||||||
|
|||||||
@ -66,23 +66,41 @@ abstract class AuthService extends CommonService
|
|||||||
{
|
{
|
||||||
return $this->getAuthInfo('name');
|
return $this->getAuthInfo('name');
|
||||||
}
|
}
|
||||||
final public function getRole(): string|null
|
|
||||||
|
/**
|
||||||
|
* 현재 로그인된 사용자의 역할을 배열 형태로 반환합니다.
|
||||||
|
* UserEntity::getRole()의 반환 타입과 일치시킵니다.
|
||||||
|
* @return array|null
|
||||||
|
*/
|
||||||
|
final public function getRole(): array|null // <-- 타입 힌트를 array|null로 변경
|
||||||
{
|
{
|
||||||
|
// getAuthInfo는 UserEntity에서 배열을 받아옵니다.
|
||||||
return $this->getAuthInfo('role');
|
return $this->getAuthInfo('role');
|
||||||
}
|
}
|
||||||
|
|
||||||
final public function isLoggedIn(): bool
|
final public function isLoggedIn(): bool
|
||||||
{
|
{
|
||||||
return $this->getSession()->has(SESSION_NAMES['ISLOGIN']);
|
return $this->getSession()->has(SESSION_NAMES['ISLOGIN']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 사용자가 필요한 접근 권한($roles)을 가지고 있는지 확인합니다.
|
||||||
|
* @param array $roles 요구되는 권한 목록
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
final public function isAccessRole(array $roles): bool
|
final public function isAccessRole(array $roles): bool
|
||||||
{
|
{
|
||||||
$role = $this->getRole();
|
// (1) getRole()의 반환 타입이 이제 배열이므로 바로 받습니다.
|
||||||
if ($role === "") {
|
$userRoles = $this->getRole();
|
||||||
|
// 역할 정보 자체가 없거나 빈 배열인 경우 접근 불가
|
||||||
|
if (empty($userRoles) || !is_array($userRoles)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// (2) 문자열 explode() 대신 array_intersect를 사용하여 배열 간의 공통점을 찾습니다.
|
||||||
// 교집합이 없으면 false
|
// 교집합이 없으면 false
|
||||||
return !empty(array_intersect(explode(DEFAULTS['DELIMITER_ROLE'], $role), $roles));
|
return !empty(array_intersect($userRoles, $roles));
|
||||||
}
|
}
|
||||||
|
|
||||||
final public function pushCurrentUrl(string $url): void
|
final public function pushCurrentUrl(string $url): void
|
||||||
{
|
{
|
||||||
$this->getSession()->set($this->url_stack_name, $url);
|
$this->getSession()->set($this->url_stack_name, $url);
|
||||||
@ -103,7 +121,7 @@ abstract class AuthService extends CommonService
|
|||||||
'uid' => $entity->getPK(),
|
'uid' => $entity->getPK(),
|
||||||
'id' => $entity->getID(),
|
'id' => $entity->getID(),
|
||||||
'name' => $entity->getTitle(),
|
'name' => $entity->getTitle(),
|
||||||
'role' => $entity->role
|
'role' => $entity->getRole()
|
||||||
]);
|
]);
|
||||||
return $entity;
|
return $entity;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,6 @@
|
|||||||
<?php foreach ($viewDatas['control']['formFields'] as $field): ?>
|
<?php foreach ($viewDatas['control']['formFields'] as $field): ?>
|
||||||
<tr>
|
<tr>
|
||||||
<th nowrap class="text-end"><?= $viewDatas['control']['helper']->getFieldLabel($field, "", $viewDatas) ?></th>
|
<th nowrap class="text-end"><?= $viewDatas['control']['helper']->getFieldLabel($field, "", $viewDatas) ?></th>
|
||||||
<?= dd($viewDatas); ?>
|
|
||||||
<td nowrap class="text-start">
|
<td nowrap class="text-start">
|
||||||
<?= $viewDatas['control']['helper']->getFieldForm($field, old($field) ?? ($viewDatas['control']['entity']->$field ?? null), $viewDatas) ?>
|
<?= $viewDatas['control']['helper']->getFieldForm($field, old($field) ?? ($viewDatas['control']['entity']->$field ?? null), $viewDatas) ?>
|
||||||
<span><?= validation_show_error($field); ?></span>
|
<span><?= validation_show_error($field); ?></span>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user