QwikClock is an employee time tracking app.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 

403 lignes
10 KiB

  1. <?php
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. /**
  6. * Authentication and account functions. Connects to a Portal instance.
  7. */
  8. /**
  9. * Check the login server API for sanity
  10. * @return boolean true if OK, else false
  11. */
  12. function checkLoginServer() {
  13. try {
  14. $client = new GuzzleHttp\Client();
  15. $response = $client
  16. ->request('POST', PORTAL_API, [
  17. 'form_params' => [
  18. 'key' => PORTAL_KEY,
  19. 'action' => "ping"
  20. ]
  21. ]);
  22. if ($response->getStatusCode() != 200) {
  23. return false;
  24. }
  25. $resp = json_decode($response->getBody(), TRUE);
  26. if ($resp['status'] == "OK") {
  27. return true;
  28. } else {
  29. return false;
  30. }
  31. } catch (Exception $e) {
  32. return false;
  33. }
  34. }
  35. /**
  36. * Checks if the given AccountHub API key is valid by attempting to
  37. * access the API with it.
  38. * @param String $key The API key to check
  39. * @return boolean TRUE if the key is valid, FALSE if invalid or something went wrong
  40. */
  41. function checkAPIKey($key) {
  42. try {
  43. $client = new GuzzleHttp\Client();
  44. $response = $client
  45. ->request('POST', PORTAL_API, [
  46. 'form_params' => [
  47. 'key' => $key,
  48. 'action' => "ping"
  49. ]
  50. ]);
  51. if ($response->getStatusCode() === 200) {
  52. return true;
  53. }
  54. return false;
  55. } catch (Exception $e) {
  56. return false;
  57. }
  58. }
  59. ////////////////////////////////////////////////////////////////////////////////
  60. // Account handling //
  61. ////////////////////////////////////////////////////////////////////////////////
  62. /**
  63. * Checks the given credentials against the API.
  64. * @param string $username
  65. * @param string $password
  66. * @return boolean True if OK, else false
  67. */
  68. function authenticate_user($username, $password, &$errmsg) {
  69. $client = new GuzzleHttp\Client();
  70. $response = $client
  71. ->request('POST', PORTAL_API, [
  72. 'form_params' => [
  73. 'key' => PORTAL_KEY,
  74. 'action' => "auth",
  75. 'username' => $username,
  76. 'password' => $password
  77. ]
  78. ]);
  79. if ($response->getStatusCode() > 299) {
  80. sendError("Login server error: " . $response->getBody());
  81. }
  82. $resp = json_decode($response->getBody(), TRUE);
  83. if ($resp['status'] == "OK") {
  84. return true;
  85. } else {
  86. $errmsg = $resp['msg'];
  87. return false;
  88. }
  89. }
  90. /**
  91. * Check if a username exists.
  92. * @param String $username
  93. */
  94. function user_exists($username) {
  95. $client = new GuzzleHttp\Client();
  96. $response = $client
  97. ->request('POST', PORTAL_API, [
  98. 'form_params' => [
  99. 'key' => PORTAL_KEY,
  100. 'action' => "userexists",
  101. 'username' => $username
  102. ]
  103. ]);
  104. if ($response->getStatusCode() > 299) {
  105. sendError("Login server error: " . $response->getBody());
  106. }
  107. $resp = json_decode($response->getBody(), TRUE);
  108. if ($resp['status'] == "OK" && $resp['exists'] === true) {
  109. return true;
  110. } else {
  111. return false;
  112. }
  113. }
  114. /**
  115. * Check if a UID exists.
  116. * @param String $uid
  117. */
  118. function uid_exists($uid) {
  119. $client = new GuzzleHttp\Client();
  120. $response = $client
  121. ->request('POST', PORTAL_API, [
  122. 'form_params' => [
  123. 'key' => PORTAL_KEY,
  124. 'action' => "userexists",
  125. 'uid' => $uid
  126. ]
  127. ]);
  128. if ($response->getStatusCode() > 299) {
  129. sendError("Login server error: " . $response->getBody());
  130. }
  131. $resp = json_decode($response->getBody(), TRUE);
  132. if ($resp['status'] == "OK" && $resp['exists'] === true) {
  133. return true;
  134. } else {
  135. return false;
  136. }
  137. }
  138. /**
  139. * Get the account status: NORMAL, TERMINATED, LOCKED_OR_DISABLED,
  140. * CHANGE_PASSWORD, or ALERT_ON_ACCESS
  141. * @param string $username
  142. * @return string
  143. */
  144. function get_account_status($username) {
  145. $client = new GuzzleHttp\Client();
  146. $response = $client
  147. ->request('POST', PORTAL_API, [
  148. 'form_params' => [
  149. 'key' => PORTAL_KEY,
  150. 'action' => "acctstatus",
  151. 'username' => $username
  152. ]
  153. ]);
  154. if ($response->getStatusCode() > 299) {
  155. sendError("Login server error: " . $response->getBody());
  156. }
  157. $resp = json_decode($response->getBody(), TRUE);
  158. if ($resp['status'] == "OK") {
  159. return $resp['account'];
  160. } else {
  161. return false;
  162. }
  163. }
  164. /**
  165. * Check if the given username has the given permission (or admin access)
  166. * @param string $username
  167. * @param string $permcode
  168. * @return boolean TRUE if the user has the permission (or admin access), else FALSE
  169. */
  170. function account_has_permission($username, $permcode) {
  171. $client = new GuzzleHttp\Client();
  172. $response = $client
  173. ->request('POST', PORTAL_API, [
  174. 'form_params' => [
  175. 'key' => PORTAL_KEY,
  176. 'action' => "permission",
  177. 'username' => $username,
  178. 'code' => $permcode
  179. ]
  180. ]);
  181. if ($response->getStatusCode() > 299) {
  182. sendError("Login server error: " . $response->getBody());
  183. }
  184. $resp = json_decode($response->getBody(), TRUE);
  185. if ($resp['status'] == "OK") {
  186. return $resp['has_permission'];
  187. } else {
  188. return false;
  189. }
  190. }
  191. ////////////////////////////////////////////////////////////////////////////////
  192. // Login handling //
  193. ////////////////////////////////////////////////////////////////////////////////
  194. /**
  195. * Setup $_SESSION values with user data and set loggedin flag to true
  196. * @param string $username
  197. */
  198. function doLoginUser($username) {
  199. $client = new GuzzleHttp\Client();
  200. $response = $client
  201. ->request('POST', PORTAL_API, [
  202. 'form_params' => [
  203. 'key' => PORTAL_KEY,
  204. 'action' => "userinfo",
  205. 'username' => $username
  206. ]
  207. ]);
  208. if ($response->getStatusCode() > 299) {
  209. sendError("Login server error: " . $response->getBody());
  210. }
  211. $resp = json_decode($response->getBody(), TRUE);
  212. if ($resp['status'] == "OK") {
  213. $userinfo = $resp['data'];
  214. session_regenerate_id(true);
  215. $newSession = session_id();
  216. session_write_close();
  217. session_id($newSession);
  218. session_start();
  219. $_SESSION['username'] = $username;
  220. $_SESSION['uid'] = $userinfo['uid'];
  221. $_SESSION['email'] = $userinfo['email'];
  222. $_SESSION['realname'] = $userinfo['name'];
  223. $_SESSION['loggedin'] = true;
  224. return true;
  225. } else {
  226. return false;
  227. }
  228. }
  229. function sendLoginAlertEmail($username) {
  230. $client = new GuzzleHttp\Client();
  231. $response = $client
  232. ->request('POST', PORTAL_API, [
  233. 'form_params' => [
  234. 'key' => PORTAL_KEY,
  235. 'action' => "alertemail",
  236. 'username' => $username,
  237. 'appname' => SITE_TITLE
  238. ]
  239. ]);
  240. if ($response->getStatusCode() > 299) {
  241. return "An unknown error occurred.";
  242. }
  243. $resp = json_decode($response->getBody(), TRUE);
  244. if ($resp['status'] == "OK") {
  245. return true;
  246. } else {
  247. return $resp['msg'];
  248. }
  249. }
  250. function simLogin($username, $password) {
  251. $client = new GuzzleHttp\Client();
  252. $response = $client
  253. ->request('POST', PORTAL_API, [
  254. 'form_params' => [
  255. 'key' => PORTAL_KEY,
  256. 'action' => "login",
  257. 'username' => $username,
  258. 'password' => $password
  259. ]
  260. ]);
  261. if ($response->getStatusCode() > 299) {
  262. sendError("Login server error: " . $response->getBody());
  263. }
  264. $resp = json_decode($response->getBody(), TRUE);
  265. if ($resp['status'] == "OK") {
  266. return true;
  267. } else {
  268. return $resp['msg'];
  269. }
  270. }
  271. function verifyCaptcheck($session, $answer, $url) {
  272. $data = [
  273. 'session_id' => $session,
  274. 'answer_id' => $answer,
  275. 'action' => "verify"
  276. ];
  277. $options = [
  278. 'http' => [
  279. 'header' => "Content-type: application/x-www-form-urlencoded\r\n",
  280. 'method' => 'POST',
  281. 'content' => http_build_query($data)
  282. ]
  283. ];
  284. $context = stream_context_create($options);
  285. $result = file_get_contents($url, false, $context);
  286. $resp = json_decode($result, TRUE);
  287. if (!$resp['result']) {
  288. return false;
  289. } else {
  290. return true;
  291. }
  292. }
  293. ////////////////////////////////////////////////////////////////////////////////
  294. // 2-factor authentication //
  295. ////////////////////////////////////////////////////////////////////////////////
  296. /**
  297. * Check if a user has TOTP setup
  298. * @param string $username
  299. * @return boolean true if TOTP secret exists, else false
  300. */
  301. function userHasTOTP($username) {
  302. $client = new GuzzleHttp\Client();
  303. $response = $client
  304. ->request('POST', PORTAL_API, [
  305. 'form_params' => [
  306. 'key' => PORTAL_KEY,
  307. 'action' => "hastotp",
  308. 'username' => $username
  309. ]
  310. ]);
  311. if ($response->getStatusCode() > 299) {
  312. sendError("Login server error: " . $response->getBody());
  313. }
  314. $resp = json_decode($response->getBody(), TRUE);
  315. if ($resp['status'] == "OK") {
  316. return $resp['otp'];
  317. } else {
  318. return false;
  319. }
  320. }
  321. /**
  322. * Verify a TOTP multiauth code
  323. * @global $database
  324. * @param string $username
  325. * @param int $code
  326. * @return boolean true if it's legit, else false
  327. */
  328. function verifyTOTP($username, $code) {
  329. $client = new GuzzleHttp\Client();
  330. $response = $client
  331. ->request('POST', PORTAL_API, [
  332. 'form_params' => [
  333. 'key' => PORTAL_KEY,
  334. 'action' => "verifytotp",
  335. 'username' => $username,
  336. 'code' => $code
  337. ]
  338. ]);
  339. if ($response->getStatusCode() > 299) {
  340. sendError("Login server error: " . $response->getBody());
  341. }
  342. $resp = json_decode($response->getBody(), TRUE);
  343. if ($resp['status'] == "OK") {
  344. return $resp['valid'];
  345. } else {
  346. return false;
  347. }
  348. }