AuthController.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <?php
  2. namespace Typemill\Controllers;
  3. use Slim\Views\Twig;
  4. use Slim\Http\Request;
  5. use Slim\Http\Response;
  6. use Typemill\Models\Validation;
  7. use Typemill\Models\User;
  8. use Typemill\Models\WriteYaml;
  9. class AuthController extends Controller
  10. {
  11. public function redirect(Request $request, Response $response)
  12. {
  13. if(isset($_SESSION['login']))
  14. {
  15. return $response->withRedirect($this->c->router->pathFor('content.raw'));
  16. }
  17. else
  18. {
  19. return $response->withRedirect($this->c->router->pathFor('auth.show'));
  20. }
  21. }
  22. /**
  23. * show login form
  24. *
  25. * @param obj $request the slim request object.
  26. * @param obj $response the slim response object.
  27. * @param array $args with arguments past to the slim router
  28. * @return obj $response and string route.
  29. */
  30. public function show(Request $request, Response $response, $args)
  31. {
  32. $data = array();
  33. /* check previous login attemps */
  34. $yaml = new WriteYaml();
  35. $logins = $yaml->getYaml('settings/users', '.logins');
  36. $userIP = $this->getUserIP();
  37. $userLogins = isset($logins[$userIP]) ? count($logins[$userIP]) : false;
  38. if($userLogins)
  39. {
  40. /* get the latest */
  41. $lastLogin = intval($logins[$userIP][$userLogins-1]);
  42. /* if last login is longer than 60 seconds ago, clear it. */
  43. if(time() - $lastLogin > 60)
  44. {
  45. unset($logins[$userIP]);
  46. $yaml->updateYaml('settings/users', '.logins', $logins);
  47. }
  48. /* Did the user made three login attemps that failed? */
  49. elseif($userLogins >= 3)
  50. {
  51. $timeleft = 60 - (time() - $lastLogin);
  52. $data['messages'] = array('time' => $timeleft, 'error' => array( 'Too many bad logins. Please wait.'));
  53. }
  54. }
  55. return $this->render($response, '/auth/login.twig', $data);
  56. }
  57. /**
  58. * signin an existing user
  59. *
  60. * @param obj $request the slim request object with form data in the post params.
  61. * @param obj $response the slim response object.
  62. * @return obj $response with redirect to route.
  63. */
  64. public function login(Request $request, Response $response)
  65. {
  66. /* log user attemps to authenticate */
  67. $yaml = new WriteYaml();
  68. $logins = $yaml->getYaml('settings/users', '.logins');
  69. $userIP = $this->getUserIP();
  70. $userLogins = isset($logins[$userIP]) ? count($logins[$userIP]) : false;
  71. /* if there have been user logins before. You have to do this again, because user does not always refresh the login page and old login attemps are stored. */
  72. if($userLogins)
  73. {
  74. /* get the latest */
  75. $lastLogin = intval($logins[$userIP][$userLogins-1]);
  76. /* if last login is longer than 60 seconds ago, clear it and add this attempt */
  77. if(time() - $lastLogin > 60)
  78. {
  79. unset($logins[$userIP]);
  80. $yaml->updateYaml('settings/users', '.logins', $logins);
  81. }
  82. /* Did the user made three login attemps that failed? */
  83. elseif($userLogins >= 2)
  84. {
  85. $logins[$userIP][] = time();
  86. $yaml->updateYaml('settings/users', '.logins', $logins);
  87. return $response->withRedirect($this->c->router->pathFor('auth.show'));
  88. }
  89. }
  90. /* authentication */
  91. $params = $request->getParams();
  92. $validation = new Validation();
  93. if($validation->signin($params))
  94. {
  95. $user = new User();
  96. $userdata = $user->getUser($params['username']);
  97. if($userdata && password_verify($params['password'], $userdata['password']))
  98. {
  99. $user->login($userdata['username']);
  100. /* clear the user login attemps */
  101. if($userLogins)
  102. {
  103. unset($logins[$userIP]);
  104. $yaml->updateYaml('settings/users', '.logins', $logins);
  105. }
  106. return $response->withRedirect($this->c->router->pathFor('content.raw'));
  107. }
  108. }
  109. /* if authentication failed, add attempt to log file */
  110. $logins[$userIP][] = time();
  111. $yaml->updateYaml('settings/users', '.logins', $logins);
  112. $this->c->flash->addMessage('error', 'Ups, wrong password or username, please try again.');
  113. return $response->withRedirect($this->c->router->pathFor('auth.show'));
  114. }
  115. /**
  116. * log out a user
  117. *
  118. * @param obj $request the slim request object
  119. * @param obj $response the slim response object
  120. * @return obje $response with redirect to route
  121. */
  122. public function logout(Request $request, Response $response)
  123. {
  124. if(isset($_SESSION))
  125. {
  126. session_destroy();
  127. }
  128. return $response->withRedirect($this->c->router->pathFor('auth.show'));
  129. }
  130. private function getUserIP()
  131. {
  132. $client = @$_SERVER['HTTP_CLIENT_IP'];
  133. $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
  134. $remote = $_SERVER['REMOTE_ADDR'];
  135. if(filter_var($client, FILTER_VALIDATE_IP))
  136. {
  137. $ip = $client;
  138. }
  139. elseif(filter_var($forward, FILTER_VALIDATE_IP))
  140. {
  141. $ip = $forward;
  142. }
  143. else
  144. {
  145. $ip = $remote;
  146. }
  147. return $ip;
  148. }
  149. }