api de gestion de ticket, basé sur php-crud-api. Le but est de décorrélé les outils de gestion des données, afin
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DbAuthMiddleware.php 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. <?php
  2. namespace Tqdev\PhpCrudApi\Middleware;
  3. use Psr\Http\Message\ResponseInterface;
  4. use Psr\Http\Message\ServerRequestInterface;
  5. use Psr\Http\Server\RequestHandlerInterface;
  6. use Tqdev\PhpCrudApi\Column\ReflectionService;
  7. use Tqdev\PhpCrudApi\Controller\Responder;
  8. use Tqdev\PhpCrudApi\Database\GenericDB;
  9. use Tqdev\PhpCrudApi\Middleware\Base\Middleware;
  10. use Tqdev\PhpCrudApi\Middleware\Router\Router;
  11. use Tqdev\PhpCrudApi\Record\Condition\ColumnCondition;
  12. use Tqdev\PhpCrudApi\Record\ErrorCode;
  13. use Tqdev\PhpCrudApi\Record\OrderingInfo;
  14. use Tqdev\PhpCrudApi\RequestUtils;
  15. class DbAuthMiddleware extends Middleware
  16. {
  17. private $reflection;
  18. private $db;
  19. private $ordering;
  20. public function __construct(Router $router, Responder $responder, array $properties, ReflectionService $reflection, GenericDB $db)
  21. {
  22. parent::__construct($router, $responder, $properties);
  23. $this->reflection = $reflection;
  24. $this->db = $db;
  25. $this->ordering = new OrderingInfo();
  26. }
  27. public function process(ServerRequestInterface $request, RequestHandlerInterface $next): ResponseInterface
  28. {
  29. if (session_status() == PHP_SESSION_NONE) {
  30. if (!headers_sent()) {
  31. $sessionName = $this->getProperty('sessionName', '');
  32. if ($sessionName) {
  33. session_name($sessionName);
  34. }
  35. session_start();
  36. }
  37. }
  38. $path = RequestUtils::getPathSegment($request, 1);
  39. $method = $request->getMethod();
  40. if ($method == 'POST' && in_array($path, ['login', 'register', 'password'])) {
  41. $body = $request->getParsedBody();
  42. $username = isset($body->username) ? $body->username : '';
  43. $password = isset($body->password) ? $body->password : '';
  44. $newPassword = isset($body->newPassword) ? $body->newPassword : '';
  45. $tableName = $this->getProperty('usersTable', 'users');
  46. $table = $this->reflection->getTable($tableName);
  47. $usernameColumnName = $this->getProperty('usernameColumn', 'username');
  48. $usernameColumn = $table->getColumn($usernameColumnName);
  49. $passwordColumnName = $this->getProperty('passwordColumn', 'password');
  50. $passwordLength = $this->getProperty('passwordLength', '12');
  51. $pkName = $table->getPk()->getName();
  52. $registerUser = $this->getProperty('registerUser', '');
  53. $condition = new ColumnCondition($usernameColumn, 'eq', $username);
  54. $returnedColumns = $this->getProperty('returnedColumns', '');
  55. if (!$returnedColumns) {
  56. $columnNames = $table->getColumnNames();
  57. } else {
  58. $columnNames = array_map('trim', explode(',', $returnedColumns));
  59. $columnNames[] = $passwordColumnName;
  60. $columnNames[] = $pkName;
  61. }
  62. $columnOrdering = $this->ordering->getDefaultColumnOrdering($table);
  63. if ($path == 'register') {
  64. if (!$registerUser) {
  65. return $this->responder->error(ErrorCode::AUTHENTICATION_FAILED, $username);
  66. }
  67. if (strlen($password) < $passwordLength) {
  68. return $this->responder->error(ErrorCode::PASSWORD_TOO_SHORT, $passwordLength);
  69. }
  70. $users = $this->db->selectAll($table, $columnNames, $condition, $columnOrdering, 0, 1);
  71. if (!empty($users)) {
  72. return $this->responder->error(ErrorCode::USER_ALREADY_EXIST, $username);
  73. }
  74. $data = json_decode($registerUser, true);
  75. $data = is_array($data) ? $data : [];
  76. $data[$usernameColumnName] = $username;
  77. $data[$passwordColumnName] = password_hash($password, PASSWORD_DEFAULT);
  78. $this->db->createSingle($table, $data);
  79. $users = $this->db->selectAll($table, $columnNames, $condition, $columnOrdering, 0, 1);
  80. foreach ($users as $user) {
  81. unset($user[$passwordColumnName]);
  82. return $this->responder->success($user);
  83. }
  84. return $this->responder->error(ErrorCode::AUTHENTICATION_FAILED, $username);
  85. }
  86. if ($path == 'login') {
  87. $users = $this->db->selectAll($table, $columnNames, $condition, $columnOrdering, 0, 1);
  88. foreach ($users as $user) {
  89. if (password_verify($password, $user[$passwordColumnName]) == 1) {
  90. if (!headers_sent()) {
  91. session_regenerate_id(true);
  92. }
  93. unset($user[$passwordColumnName]);
  94. $_SESSION['user'] = $user;
  95. return $this->responder->success($user);
  96. }
  97. }
  98. return $this->responder->error(ErrorCode::AUTHENTICATION_FAILED, $username);
  99. }
  100. if ($path == 'password') {
  101. if ($username != ($_SESSION['user'][$usernameColumnName] ?? '')) {
  102. return $this->responder->error(ErrorCode::AUTHENTICATION_FAILED, $username);
  103. }
  104. if (strlen($newPassword) < $passwordLength) {
  105. return $this->responder->error(ErrorCode::PASSWORD_TOO_SHORT, $passwordLength);
  106. }
  107. $users = $this->db->selectAll($table, $columnNames, $condition, $columnOrdering, 0, 1);
  108. foreach ($users as $user) {
  109. if (password_verify($password, $user[$passwordColumnName]) == 1) {
  110. if (!headers_sent()) {
  111. session_regenerate_id(true);
  112. }
  113. $data = [$passwordColumnName => password_hash($newPassword, PASSWORD_DEFAULT)];
  114. $this->db->updateSingle($table, $data, $user[$pkName]);
  115. unset($user[$passwordColumnName]);
  116. return $this->responder->success($user);
  117. }
  118. }
  119. return $this->responder->error(ErrorCode::AUTHENTICATION_FAILED, $username);
  120. }
  121. }
  122. if ($method == 'POST' && $path == 'logout') {
  123. if (isset($_SESSION['user'])) {
  124. $user = $_SESSION['user'];
  125. unset($_SESSION['user']);
  126. if (session_status() != PHP_SESSION_NONE) {
  127. session_destroy();
  128. }
  129. return $this->responder->success($user);
  130. }
  131. return $this->responder->error(ErrorCode::AUTHENTICATION_REQUIRED, '');
  132. }
  133. if ($method == 'GET' && $path == 'me') {
  134. if (isset($_SESSION['user'])) {
  135. return $this->responder->success($_SESSION['user']);
  136. }
  137. return $this->responder->error(ErrorCode::AUTHENTICATION_REQUIRED, '');
  138. }
  139. if (!isset($_SESSION['user']) || !$_SESSION['user']) {
  140. $authenticationMode = $this->getProperty('mode', 'required');
  141. if ($authenticationMode == 'required') {
  142. return $this->responder->error(ErrorCode::AUTHENTICATION_REQUIRED, '');
  143. }
  144. }
  145. return $next->handle($request);
  146. }
  147. }