AuthController.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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. # check if user has confirmed the account
  101. if(isset($userdata['optintoken']) && $userdata['optintoken'])
  102. {
  103. $this->c->flash->addMessage('error', 'Your registration is not confirmed yet. Please check your e-mails and use the confirmation link.');
  104. return $response->withRedirect($this->c->router->pathFor('auth.show'));
  105. }
  106. $user->login($userdata['username']);
  107. /* clear the user login attemps */
  108. if($userLogins)
  109. {
  110. unset($logins[$userIP]);
  111. $yaml->updateYaml('settings/users', '.logins', $logins);
  112. }
  113. # if user is allowed to view content-area
  114. if($this->c->acl->isAllowed($userdata['userrole'], 'content', 'view'))
  115. {
  116. $settings = $this->c->get('settings');
  117. $editor = (isset($settings['editor']) && $settings['editor'] == 'visual') ? 'visual' : 'raw';
  118. return $response->withRedirect($this->c->router->pathFor('content.' . $editor));
  119. }
  120. return $response->withRedirect($this->c->router->pathFor('user.account'));
  121. }
  122. }
  123. /* if authentication failed, add attempt to log file */
  124. $logins[$userIP][] = time();
  125. $yaml->updateYaml('settings/users', '.logins', $logins);
  126. $this->c->flash->addMessage('error', 'Ups, wrong password or username, please try again.');
  127. return $response->withRedirect($this->c->router->pathFor('auth.show'));
  128. }
  129. /**
  130. * log out a user
  131. *
  132. * @param obj $request the slim request object
  133. * @param obj $response the slim response object
  134. * @return obje $response with redirect to route
  135. */
  136. public function logout(Request $request, Response $response)
  137. {
  138. if(isset($_SESSION))
  139. {
  140. session_destroy();
  141. }
  142. return $response->withRedirect($this->c->router->pathFor('auth.show'));
  143. }
  144. private function getUserIP()
  145. {
  146. $client = @$_SERVER['HTTP_CLIENT_IP'];
  147. $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
  148. $remote = $_SERVER['REMOTE_ADDR'];
  149. if(filter_var($client, FILTER_VALIDATE_IP))
  150. {
  151. $ip = $client;
  152. }
  153. elseif(filter_var($forward, FILTER_VALIDATE_IP))
  154. {
  155. $ip = $forward;
  156. }
  157. else
  158. {
  159. $ip = $remote;
  160. }
  161. return $ip;
  162. }
  163. }