AuthController.php 4.9 KB

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