Automation ini...

This commit is contained in:
최준흠 2024-08-30 19:32:21 +09:00
parent 330900cee6
commit 2748fed46b
22 changed files with 418 additions and 156 deletions

View File

@ -93,6 +93,45 @@ define('EVENT_PRIORITY_NORMAL', 100);
*/
define('EVENT_PRIORITY_HIGH', 10);
//Default값 정의
define('DEFAULTS', [
'ROLE' => getenv('default.role') ?: "guest",
'STATUS' => getenv('default.status') ?: "use",
'EMPTY' => getenv('default.empty') ?: "",
'PERPAGE' => getenv('default.perpage') ?: 20,
'DELIMITER_FILE' => getenv('default.delimiter.file') ?: "||",
'DELIMITER_ROLE' => getenv('default.delimiter.role') ?: ",",
]);
//URL
define('URLS', [
'LOGIN' => '/user/login',
'SIGNUP' => '/user/signup',
'LOGOUT' => '/user/logout',
]);
//SESSION 관련
define('SESSION', [
'NAMES' => ['RETURN_URL' => "return_url", 'ISLOGIN' => "islogined", 'AUTH' => 'auth', 'CART' => 'cart'],
]);
//인증 관련
define('AUTH', [
'ROLES' => ['guest', 'user', 'vip', 'manager', 'cloudflare', 'director', 'master'],
'FIELDS' => ['ID' => 'id', 'TITLE' => 'title', 'ROLE' => 'role'],
'AUTH_ADAPTERS' => [
'Local' => [
'DEBUG' => getenv("auth.loca.debug") ?: false,
],
'Google' => [
'DEBUG' => getenv("auth.google.debug") ?: false,
'ICON' => getenv("auth.google.icon") ?: '<img src="/images/auth/google_login_button.png"/>',
'CLIENT_ID' => getenv("auth.google.client.id"),
'CLIENT_KEY' => getenv("auth.google.client.key"),
'CALLBACK_URL' => getenv("auth.google.client.callback_url"),
'TOKEN_NAME' => getenv('auth.google.client.token_name') ?: "access_token",
],
]
]);
define('MANGBOARD', [
'point' => ['unit' => 1000],
'admin' => ['level' => 10],

View File

@ -12,6 +12,7 @@ use CodeIgniter\Filters\InvalidChars;
use CodeIgniter\Filters\PageCache;
use CodeIgniter\Filters\PerformanceMetrics;
use CodeIgniter\Filters\SecureHeaders;
use App\Filters\AuthFilter;
class Filters extends BaseFilters
{
@ -34,6 +35,7 @@ class Filters extends BaseFilters
'forcehttps' => ForceHTTPS::class,
'pagecache' => PageCache::class,
'performance' => PerformanceMetrics::class,
'authFilter' => AuthFilter::class,
];
/**

View File

@ -5,14 +5,33 @@ use CodeIgniter\Router\RouteCollection;
/**
* @var RouteCollection $routes
*/
//추가 Custom RULE 만들때 : ex)UUID형식
$routes->addPlaceholder('uuid', '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}');
//authFilter는 추가적인 작업이 필요
//1. app/Filters/AuthFilter.php
//2. Config/Filters.php -> $aliases = ['authFilter' => AuthFilter::class]
$routes->get('/', 'Home::index');
$routes->group('/user', function ($routes) {
$routes->get('', 'UserController::index');
$routes->get('view', 'UserController::view', ['filter' => 'authFilter:user']);
});
$routes->group('cli', ['namespace' => 'App\Controllers\CLI'], function ($routes) {
$routes->group('mangboard', ['namespace' => 'App\Controllers\CLI\Mangboard'], function ($routes) {
$routes->group('user', static function ($routes) {
$routes->cli('point', 'UserController::point');
$routes->cli('point/(:any)', 'UserController::point/$1');
$routes->cli('level', 'UserController::level');
$routes->cli('level/(:any)', 'UserController::level/$1');
});
$routes->cli('mangboard/level', 'Mangboard::level');
$routes->cli('crawl/html', 'Crawl::html');
});
$routes->group('admin', ['namespace' => 'App\Controllers\Admin', 'filter' => 'authFilter:manager'], function ($routes) {
$routes->group('/user', function ($routes) {
$routes->get('insert', 'UserController::form_insert');
$routes->post('insert', 'UserController::insert');
$routes->get('update', 'UserController::form_update');
$routes->post('update', 'UserController::upadate');
$routes->get('delete/', 'UserController::delete', ['filter' => 'authFilter:master']);
$routes->get('view', 'UserController::view');
});
});

View File

@ -0,0 +1,36 @@
<?php
namespace App\Controllers\Admin;
use App\Controllers\BaseController;
abstract class AdminController extends BaseController
{
private $_datas = [];
final public function __get($name)
{
// echo "Getting '$name'\n";
if (array_key_exists($name, $this->_datas)) {
return $this->_datas[$name];
}
return null;
}
final public function __set($name, $value)
{
// echo "Setting '$name' to '$value'\n";
$this->_datas[$name] = $value;
}
protected function __construct()
{
//사용자 기본 Role 지정
$this->_datas[SESSION['NAMES']['ISLOGIN']] = false;
$this->_datas['currentRoles'] = [DEFAULTS["ROLE"]];
if ($this->_session->get(SESSION['NAMES']['ISLOGIN'])) {
$this->_datas[SESSION['NAMES']['ISLOGIN']] = true;
$this->_datas['auth'] = $this->_session->get(SESSION['NAMES']['AUTH']);
$currentRoles = explode(DEFAULTS['DELIMITER_ROLE'], $this->_datas['auth'][AUTH['FIELDS']['ROLE']]);
$this->_datas['currentRoles'] = is_array($currentRoles) ? $currentRoles : [DEFAULTS["ROLE"]];
}
}
}

View File

@ -0,0 +1,48 @@
<?php
namespace App\Controllers\Admin;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
use App\Models\UserModel;
use App\Traits\MangboardTrait;
class UserController extends AdminController
{
use MangboardTrait;
private $_model = null;
public function __construct()
{
$this->_model = new UserModel();
}
public function index()
{
return __METHOD__;
}
public function update()
{
try {
$id = $this->request->getPost('id');
$point = $this->request->getPost('point');
$sign = $this->request->getPost('point') ?: "+";
$entity = is_numeric($id) ? $this->_model->getEntityByPK(intval($id)) : $this->_model->getEntityByID($id);
if (!$entity) {
throw new \Exception(sprintf("해당 회원[%s:%s]이 없습니다.", gettype($id), $id));
}
if (!is_numeric($point)) {
throw new \Exception("포인트 값에 {$point}를 사용할 수 없습니다.");
}
$entity = $this->setUserPointByMangboardTrait($entity, intval($point), $sign);
return "완료되었습니다.";
} catch (\Exception $e) {
log_message('error', $e->getMessage());
return $e->getMessage();
}
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace App\Controllers\CLI;
use App\Controllers\BaseController;
use GuzzleHttp\Client;
use Symfony\Component\DomCrawler\Crawler;
class Crawl extends BaseController
{
public function html()
{
try {
$client = new Client();
$response = $client->request('GET', 'https://www.yamap16.com/Board/List.aspx?id=free&ca=1');
$html = $response->getBody()->getContents();
$crawler = new Crawler($html);
// 모든 이미지의 src 속성 가져오기
$crawler->filter('img')->each(function (Crawler $node) {
echo $node->attr('src') . "\n";
});
//file_put_contents("test.txt", var_export($crawler, true));
} catch (\Exception $e) {
echo $e->getMessage();
}
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace App\Controllers\CLI;
use App\Controllers\BaseController;
use App\Traits\MangboardTrait;
use App\Models\UserModel;
class Mangboard extends BaseController
{
use MangboardTrait;
public function level(): bool
{
try {
$userModel = new UserModel();
foreach ($userModel->getEntitys() as $entity) {
$entity = $this->setUserLevelByMangboardTrait($entity);
log_message("debug", __FUNCTION__ . "=>[{$entity}] 회원님의 Level은 {$entity->getLevel()} 입니다.");
}
log_message('info', "완료되었습니다.");
return true;
} catch (\Exception $e) {
log_message('error', $e->getMessage());
return false;
}
}
}

View File

@ -1,19 +0,0 @@
<?php
namespace App\Controllers\CLI\Mangboard;
use App\Controllers\BaseController;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
abstract class MangboardController extends BaseController
{
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
// Do Not Edit This Line
parent::initController($request, $response, $logger);
// Preload any models, libraries, etc, here.
// E.g.: $this->session = \Config\Services::session();
}
}

View File

@ -1,79 +0,0 @@
<?php
namespace App\Controllers\CLI\Mangboard;
use App\Controllers\BaseController;
use App\Models\Mangboard\UserModel;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
class UserController extends MangboardController
{
private $_model = null;
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
// Do Not Edit This Line
parent::initController($request, $response, $logger);
// Preload any models, libraries, etc, here.
// E.g.: $this->session = \Config\Services::session();
$this->_model = new UserModel();
}
public function index()
{
//
}
public function point($id = null, $point = null, string $sign = "+")
{
try {
$entitys = [];
if ($id) {
$entity = is_numeric($id) ? $this->_model->getEntityByPK(intval($id)) : $this->_model->getEntityByID($id);
if (!$entity) {
throw new \Exception(sprintf("해당 회원[%s:%s]이 없습니다.", gettype($id), $id));
}
if (is_numeric($point)) {
$entitys[] = $this->_model->setPoint($entity, $point, $sign);
}
} else {
$entitys = $this->_model->getEntitys();
}
foreach ($entitys as $entity) {
log_message("debug", __FUNCTION__ . "=>[{$entity}] 회원님의 Point는 {$entity->getPoint()} 입니다.");
}
return "완료되었습니다.";
} catch (\Exception $e) {
log_message('error', '[ERROR] {exception}', ['exception' => $e]);
return $e->getMessage();
}
}
public function level($id = null, $level = null)
{
try {
$entitys = [];
if ($id) {
$entity = is_numeric($id) ? $this->_model->getEntityByPK(intval($id)) : $this->_model->getEntityByID($id);
if (!$entity) {
throw new \Exception(sprintf("해당 회원[%s:%s]이 없습니다.", gettype($id), $id));
}
if (is_numeric($level)) {
$entitys[] = $this->_model->checkLevel($entity, $level);
}
} else {
foreach ($this->_model->getEntitys() as $entity) {
$entitys[] = $this->_model->checkLevel($entity);
}
}
foreach ($entitys as $entity) {
log_message("debug", __FUNCTION__ . "=>[{$entity}] 회원님의 Level은 {$entity->getLevel()} 입니다.");
}
return "완료되었습니다.";
} catch (\Exception $e) {
log_message('error', '[ERROR] {exception}', ['exception' => $e]);
return $e->getMessage();
}
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace App\Controllers;
class UserController extends BaseController
{
public function index() {}
}

View File

@ -1,10 +1,10 @@
<?php
namespace App\Entities\Mangboard;
namespace App\Entities;
use CodeIgniter\Entity\Entity;
abstract class MangboardEntity extends Entity
abstract class CommonEntity extends Entity
{
protected $datamap = [];
protected $dates = ['created_at', 'updated_at', 'deleted_at'];

View File

@ -1,14 +1,14 @@
<?php
namespace App\Entities\Mangboard;
namespace App\Entities;
use CodeIgniter\Entity\Entity;
class UserEntity extends MangboardEntity
class UserEntity extends CommonEntity
{
public function __toString()
{
return "{$this->getPK()}:{$this->getID()}:{$this->getName()}";
return "{$this->getPK()}:{$this->getID()}:{$this->getName()},{$this->getLevel()}/{$this->getPoint()}";
}
public function getPK()
{

View File

@ -0,0 +1,65 @@
<?php
namespace App\Filters;
use CodeIgniter\Filters\FilterInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
class AuthFilter implements FilterInterface
{
/**
* Do whatever processing this filter needs to do.
* By default it should not return anything during
* normal execution. However, when an abnormal state
* is found, it should return an instance of
* CodeIgniter\HTTP\Response. If it does, script
* execution will end and that Response will be
* sent back to the client, allowing for error pages,
* redirects, etc.
*
* @param RequestInterface $request
* @param array|null $arguments
*
* @return mixed
*/
public function before(RequestInterface $request, $arguments = null)
{
// 로그인을 했으면
if (session()->get(SESSION['NAMES']['ISLOGIN'])) {
$auth = session()->get(SESSION['NAMES']['AUTH']);
// 회원 ROLES이 필요ROLE($arguments[0]) 목록에 존재하지 않으면(ACL)
if (!in_array($arguments[0], explode(DEFAULTS['DELIMITER_ROLE'], $auth[AUTH['FIELDS']['ROLE']]))) {
return redirect()->to(URLS['LOGIN'])->with(
'return_message',
sprintf(
"%s,%s회원님은 접속에 필요한 권한[%s]이 없습니다. ",
$auth[AUTH['FIELDS']['ROLE']],
$auth[AUTH['FIELDS']['TITLE']],
implode(",", $arguments)
)
);
}
} else {
session()->setFlashdata(SESSION['NAMES']['RETURN_URL'], $request->getUri()->getPath() . '?' . $request->getUri()->getQuery());
return redirect()->to(URLS['LOGIN'])->with('return_message', '로그인을하셔야합니다.');
}
}
/**
* Allows After filters to inspect and modify the response
* object as needed. This method does not allow any way
* to stop execution of other after filters, short of
* throwing an Exception or Error.
*
* @param RequestInterface $request
* @param ResponseInterface $response
* @param array|null $arguments
*
* @return mixed
*/
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
//
}
}

View File

@ -0,0 +1,47 @@
<?php
namespace App\Libraries;
class LoginLibrary
{
private $url;
private $credentials;
private $cookieFile;
// $credentials = [
// 'username' => 'your_username',
// 'password' => 'your_password'
// ];
public function __construct(string $url, array $credentials)
{
$this->url = $url;
$this->credentials = $credentials;
$this->cookieFile = tempnam(sys_get_temp_dir(), 'cookie'); // 임시 쿠키 파일 생성
}
public function execute()
{
$ch = curl_init($this->url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($this->credentials));
curl_setopt($ch, CURLOPT_COOKIEJAR, $this->cookieFile); // 쿠키를 저장할 파일 지정
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
public function getCookie()
{
return $this->cookieFile;
}
public function clearCookie()
{
// 쿠키 파일 삭제
unlink($this->cookieFile);
}
}

View File

@ -1,10 +1,10 @@
<?php
namespace App\Models\Mangboard;
namespace App\Models;
use CodeIgniter\Model;
class MangboardModel extends Model
class CommonModel extends Model
{
protected $table = '';
protected $primaryKey = '';

View File

@ -1,10 +1,10 @@
<?php
namespace App\Models\Mangboard;
namespace App\Models;
use App\Entities\Mangboard\UserEntity;
use App\Entities\UserEntity;
class UserModel extends MangboardModel
class UserModel extends CommonModel
{
protected $table = 'mb_users';
protected $primaryKey = 'pid';
@ -42,22 +42,8 @@ class UserModel extends MangboardModel
return $this->getEntity();
}
public function setPoint(UserEntity $entity, int $point, $sign = '+'): UserEntity
public function setPoint(UserEntity $entity, int $point): UserEntity
{
switch ($sign) {
case '-':
if ($entity->getPoint() < $point) {
throw new \Exception("기존포인트:{$entity->getPoint()}가 감소 포인트:-{$point} 작습니다.\n");
}
$point = $entity->getPoint() - $point;
break;
case '+':
$point = $entity->getPoint() + $point;
break;
default:
throw new \Exception(__FUNCTION__ . "에서는 {$sign}은 사용할수 없습니다.\n");
// break;
}
if ($entity->getPoint() != $point) {
$old_point = $entity->getPoint();
$entity->setPoint($point);
@ -77,29 +63,4 @@ class UserModel extends MangboardModel
}
return $entity;
}
final public function checkLevel(UserEntity $entity, int $level = null): UserEntity
{
//사용자 Point별 Level 계산
$level = intval(is_numeric($level) ? $level : $entity->getPoint() / MANGBOARD['point']['unit'] * MANGBOARD['point']['unit'] / MANGBOARD['point']['unit']);
//관리자면 변경불가
if ($entity->getLevel() == MANGBOARD['admin']['level']) {
return $entity;
}
//운영자면 7~9
if (MANGBOARD['manager']['level']['min'] <= $entity->getLevel() && $entity->getLevel() <= MANGBOARD['manager']['level']['max']) {
$level = $level < MANGBOARD['manager']['level']['min'] ? MANGBOARD['manager']['level']['min'] : $level;
$level = MANGBOARD['manager']['level']['max'] < $level ? MANGBOARD['manager']['level']['max'] : $level;
}
// echo "point:" . $entity->getPoint() . ",level:" . $level . "\n";
//사용자 Level 1~5;
if (MANGBOARD['user']['level']['min'] <= $entity->getLevel() && $entity->getLevel() <= MANGBOARD['user']['level']['max']) {
$level = $level < MANGBOARD['user']['level']['min'] ? MANGBOARD['user']['level']['min'] : $level;
$level = MANGBOARD['user']['level']['max'] < $level ? MANGBOARD['user']['level']['max'] : $level;
}
// echo "point:" . $entity->getPoint() . ",level:" . $level . "\n";
return $this->setLevel($entity, $level);
}
}

View File

@ -0,0 +1,66 @@
<?php
namespace App\Traits;
use App\Entities\UserEntity;
use App\Models\UserModel;
trait MangboardTrait
{
private $_userModel = null;
public function getUserModel(): UserModel
{
if (is_null($this->_userModel)) {
$this->_userModel = new UserModel();
}
return $this->_userModel;
}
public function setUserPointByMangboardTrait(UserEntity $entity, int $point, $sign = '+'): UserEntity
{
switch ($sign) {
case '-':
if ($point < $point) {
throw new \Exception("기존포인트:{$point}가 감소 포인트:-{$point} 작습니다.\n");
}
$point = $point - $point;
break;
case '+':
$point = $point + $point;
break;
default:
throw new \Exception(__FUNCTION__ . "에서는 {$sign}은 사용할수 없습니다.\n");
// break;
}
$entity = $this->getUserModel()->setPoint($entity, $point);
return $this->setUserLevelByMangboardTrait($entity);
}
public function setUserLevelByMangboardTrait(UserEntity $entity): UserEntity
{
//Admin용 Level로는 변경불가
if ($entity->getLevel() == MANGBOARD['admin']['level']) {
// throw new \Exception("Admin용 Level을 변경하실수 없습니다.\n");
return $entity;
}
//사용자 Point별 Level 계산
$level = intval($entity->getPoint() / MANGBOARD['point']['unit'] * MANGBOARD['point']['unit'] / MANGBOARD['point']['unit']);
//운영자면 7~9
if (MANGBOARD['manager']['level']['min'] <= $level && $level <= MANGBOARD['manager']['level']['max']) {
$level = $level < MANGBOARD['manager']['level']['min'] ? MANGBOARD['manager']['level']['min'] : $level;
$level = MANGBOARD['manager']['level']['max'] < $level ? MANGBOARD['manager']['level']['max'] : $level;
}
// echo "point:" . $entity->getPoint() . ",level:" . $level . "\n";
//사용자 Level 1~5;
if (MANGBOARD['user']['level']['min'] <= $level && $level <= MANGBOARD['user']['level']['max']) {
$level = $level < MANGBOARD['user']['level']['min'] ? MANGBOARD['user']['level']['min'] : $level;
$level = MANGBOARD['user']['level']['max'] < $level ? MANGBOARD['user']['level']['max'] : $level;
}
// echo "point:" . $entity->getPoint() . ",level:" . $level . "\n";
return $this->getUserModel()->setLevel($entity, $level);
}
}

View File

@ -11,7 +11,9 @@
},
"require": {
"php": "^8.1",
"codeigniter4/framework": "^4.0"
"codeigniter4/framework": "^4.0",
"guzzlehttp/guzzle": "^7.9",
"symfony/dom-crawler": "^7.1"
},
"require-dev": {
"fakerphp/faker": "^1.9",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long