index.php 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. <?php
  2. namespace Controller;
  3. class Index extends \Controller {
  4. public function index($f3, $params) {
  5. if($f3->get("user.id")) {
  6. $user_controller = new \Controller\User();
  7. return $user_controller->dashboard($f3, $params);
  8. } else {
  9. if($f3->get("site.public")) {
  10. $this->_render("index/index.html");
  11. } else {
  12. if($f3->get("site.demo") && is_numeric($f3->get("site.demo"))) {
  13. $user = new \Model\User();
  14. $user->load($f3->get("site.demo"));
  15. if($user->id) {
  16. $session = new \Model\Session($user->id);
  17. $f3->set("COOKIE.phproj_token", $session->token);
  18. $f3->reroute("/");
  19. return;
  20. } else {
  21. $f3->set("error", "Auto-login failed, demo user was not found.");
  22. }
  23. }
  24. $f3->reroute("/login");
  25. }
  26. }
  27. }
  28. public function login($f3) {
  29. if($f3->get("user.id")) {
  30. if(!$f3->get("GET.to")) {
  31. $f3->reroute("/");
  32. } else {
  33. $f3->reroute($f3->get("GET.to"));
  34. }
  35. } else {
  36. if($f3->get("GET.to")) {
  37. $f3->set("to", $f3->get("GET.to"));
  38. }
  39. $this->_render("index/login.html");
  40. }
  41. }
  42. public function loginpost($f3) {
  43. $user = new \Model\User();
  44. // Load user by username or email address
  45. if(strpos($f3->get("POST.username"), "@")) {
  46. $user->load(array("email=? AND deleted_date IS NULL", $f3->get("POST.username")));
  47. } else {
  48. $user->load(array("username=? AND deleted_date IS NULL", $f3->get("POST.username")));
  49. }
  50. // Verify password
  51. $security = \Helper\Security::instance();
  52. if($security->hash($f3->get("POST.password"), $user->salt ?: "") == $user->password) {
  53. // Create a session and use it
  54. $session = new \Model\Session($user->id);
  55. $session->setCurrent();
  56. if($user->salt) {
  57. if(!$f3->get("POST.to")) {
  58. $f3->reroute("/");
  59. } else {
  60. $f3->reroute($f3->get("POST.to"));
  61. }
  62. } else {
  63. $f3->set("user", $user->cast());
  64. $this->_render("index/reset_forced.html");
  65. }
  66. } else {
  67. if($f3->get("POST.to")) {
  68. $f3->set("to", $f3->get("POST.to"));
  69. }
  70. $f3->set("login.error", "Invalid login information, try again.");
  71. $this->_render("index/login.html");
  72. }
  73. }
  74. public function registerpost($f3) {
  75. // Exit immediately if public registrations are disabled
  76. if(!$f3->get("site.public_registration")) {
  77. $f3->error(400);
  78. return;
  79. }
  80. $errors = array();
  81. $user = new \Model\User;
  82. // Check for existing users
  83. $user->load(array("email=?", $f3->get("POST.register-email")));
  84. if($user->id) {
  85. $errors[] = "A user already exists with this email address.";
  86. }
  87. $user->load(array("username=?", $f3->get("POST.register-username")));
  88. if($user->id) {
  89. $errors[] = "A user already exists with this username.";
  90. }
  91. // Validate user data
  92. if(!$f3->get("POST.register-name")) {
  93. $errors[] = "Name is required";
  94. }
  95. if(!preg_match("/^[0-9a-z]{4,}$/i", $f3->get("POST.register-username"))) {
  96. $errors[] = "Usernames must be at least 4 characters and can only contain letters and numbers.";
  97. }
  98. if(!filter_var($f3->get("POST.register-email"), FILTER_VALIDATE_EMAIL)) {
  99. $errors[] = "A valid email address is required.";
  100. }
  101. if(strlen($f3->get("POST.register-password")) < 6) {
  102. $errors[] = "Password must be at least 6 characters.";
  103. }
  104. // Show errors or create new user
  105. if($errors) {
  106. $f3->set("register.error", implode("<br>", $errors));
  107. $this->_render("index/login.html");
  108. } else {
  109. $user->reset();
  110. $user->username = trim($f3->get("POST.register-username"));
  111. $user->email = trim($f3->get("POST.register-email"));
  112. $user->name = trim($f3->get("POST.register-name"));
  113. $security = \Helper\Security::instance();
  114. extract($security->hash($f3->get("POST.register-password")));
  115. $user->password = $hash;
  116. $user->salt = $salt;
  117. $user->task_color = sprintf("#%02X%02X%02X", mt_rand(0, 0xFF), mt_rand(0, 0xFF), mt_rand(0, 0xFF));
  118. $user->save();
  119. // Create a session and use it
  120. $session = new \Model\Session($user->id);
  121. $session->setCurrent();
  122. $f3->reroute("/");
  123. }
  124. }
  125. public function reset($f3) {
  126. if($f3->get("user.id")) {
  127. $f3->reroute("/");
  128. } else {
  129. if($f3->get("POST.email")) {
  130. $user = new \Model\User;
  131. $user->load(array("email = ?", $f3->get("POST.email")));
  132. if($user->id && !$user->deleted_date) {
  133. $notification = \Helper\Notification::instance();
  134. $notification->user_reset($user->id);
  135. $f3->set("reset.success", "We've sent an email to " . $f3->get("POST.email") . " with a link to reset your password.");
  136. } else {
  137. $f3->set("reset.error", "No user exists with the email address " . $f3->get("POST.email") . ".");
  138. }
  139. }
  140. unset($user);
  141. $this->_render("index/reset.html");
  142. }
  143. }
  144. public function reset_complete($f3, $params) {
  145. if($f3->get("user.id")) {
  146. $f3->reroute("/");
  147. } else {
  148. $user = new \Model\User;
  149. $user->load(array("CONCAT(password, salt) = ?", $params["hash"]));
  150. if(!$user->id || !$params["hash"]) {
  151. $f3->set("reset.error", "Invalid reset URL.");
  152. $this->_render("index/reset.html");
  153. return;
  154. }
  155. if($f3->get("POST.password1")) {
  156. // Validate new password
  157. if($f3->get("POST.password1") != $f3->get("POST.password2")) {
  158. $f3->set("reset.error", "The given passwords don't match.");
  159. } elseif(strlen($f3->get("POST.password1")) < 6) {
  160. $f3->set("reset.error", "The given password is too short. Passwords must be at least 6 characters.");
  161. } else {
  162. // Save new password and redirect to login
  163. $security = \Helper\Security::instance();
  164. $user->salt = $security->salt();
  165. $user->password = $security->hash($f3->get("POST.password1"), $user->salt);
  166. $user->save();
  167. $f3->reroute("/login");
  168. return;
  169. }
  170. }
  171. $f3->set("resetuser", $user);
  172. $this->_render("index/reset_complete.html");
  173. }
  174. }
  175. public function reset_forced($f3) {
  176. $user = new \Model\User;
  177. $user->loadCurrent();
  178. if($f3->get("POST.password1") != $f3->get("POST.password2")) {
  179. $f3->set("reset.error", "The given passwords don't match.");
  180. } elseif(strlen($f3->get("POST.password1")) < 6) {
  181. $f3->set("reset.error", "The given password is too short. Passwords must be at least 6 characters.");
  182. } else {
  183. // Save new password and redirect to dashboard
  184. $security = \Helper\Security::instance();
  185. $user->salt = $security->salt();
  186. $user->password = $security->hash($f3->get("POST.password1"), $user->salt);
  187. $user->save();
  188. $f3->reroute("/");
  189. return;
  190. }
  191. $this->_render("index/reset_forced.html");
  192. }
  193. public function logout($f3) {
  194. $session = new \Model\Session;
  195. $session->delete();
  196. $f3->reroute("/");
  197. }
  198. public function ping($f3) {
  199. if($f3->get("user.id")) {
  200. $this->_printJson(array("user_id" => $f3->get("user.id"), "is_logged_in" => true));
  201. } else {
  202. $this->_printJson(array("user_id" => null, "is_logged_in" => false));
  203. }
  204. }
  205. public function atom($f3) {
  206. // Authenticate user
  207. if($f3->get("GET.key")) {
  208. $user = new \Model\User;
  209. $user->load(array("api_key = ?", $f3->get("GET.key")));
  210. if(!$user->id) {
  211. $f3->error(403);
  212. return;
  213. }
  214. } else {
  215. $f3->error(403);
  216. return;
  217. }
  218. // Get requested array substituting defaults
  219. $get = $f3->get("GET") + array("type" => "assigned", "user" => $user->username);
  220. unset($user);
  221. // Load target user
  222. $user = new \Model\User;
  223. $user->load(array("username = ?", $get["user"]));
  224. if(!$user->id) {
  225. $f3->error(404);
  226. return;
  227. }
  228. // Load issues
  229. $issue = new \Model\Issue\Detail;
  230. $options = array("order" => "created_date DESC");
  231. if($get["type"] == "assigned") {
  232. $issues = $issue->find(array("author_id = ? AND status_closed = 0 AND deleted_date IS NULL", $user->id), $options);
  233. } elseif($get["type"] == "created") {
  234. $issues = $issue->find(array("owner = ? AND status_closed = 0 AND deleted_date IS NULL", $user->id), $options);
  235. } elseif($get["type"] == "all") {
  236. $issues = $issue->find("status_closed = 0 AND deleted_date IS NULL", $options + array("limit" => 50));
  237. } else {
  238. $f3->error(400, "Invalid feed type");
  239. return;
  240. }
  241. // Render feed
  242. $f3->set("get", $get);
  243. $f3->set("feed_user", $user);
  244. $f3->set("issues", $issues);
  245. $this->_render("index/atom.xml", "application/atom+xml");
  246. }
  247. }