Game server and admin dashboard for TerranQuest.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

User.lib.php 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. <?php
  2. /*
  3. * This Source Code Form is subject to the terms of the Mozilla Public
  4. * License, v. 2.0. If a copy of the MPL was not distributed with this
  5. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. */
  7. class User {
  8. private $uid = null;
  9. private $username;
  10. private $email;
  11. private $realname;
  12. private $has2fa = false;
  13. private $exists = false;
  14. public function __construct(int $uid, string $username = "") {
  15. // Check if user exists
  16. $resp = AccountHubApi::get("userexists", ["uid" => $uid]);
  17. if ($resp['status'] == "OK" && $resp['exists'] === true) {
  18. $this->exists = true;
  19. } else {
  20. $this->uid = $uid;
  21. $this->username = $username;
  22. $this->exists = false;
  23. }
  24. if ($this->exists) {
  25. // Get user info
  26. $resp = AccountHubApi::get("userinfo", ["uid" => $uid]);
  27. if ($resp['status'] == "OK") {
  28. $this->uid = $resp['data']['uid'] * 1;
  29. $this->username = $resp['data']['username'];
  30. $this->email = $resp['data']['email'];
  31. $this->realname = $resp['data']['name'];
  32. } else {
  33. sendError("Login server error: " . $resp['msg']);
  34. }
  35. }
  36. }
  37. public static function byUsername(string $username): User {
  38. $resp = AccountHubApi::get("userinfo", ["username" => $username]);
  39. if (!isset($resp['status'])) {
  40. sendError("Login server error: " . $resp);
  41. }
  42. if ($resp['status'] == "OK") {
  43. return new self($resp['data']['uid'] * 1);
  44. } else {
  45. return new self(-1, $username);
  46. }
  47. }
  48. public function exists(): bool {
  49. return $this->exists;
  50. }
  51. public function has2fa(): bool {
  52. if (!$this->exists) {
  53. return false;
  54. }
  55. $resp = AccountHubApi::get("hastotp", ['username' => $this->username]);
  56. if ($resp['status'] == "OK") {
  57. return $resp['otp'] == true;
  58. } else {
  59. return false;
  60. }
  61. }
  62. function getUsername() {
  63. return $this->username;
  64. }
  65. function getUID() {
  66. return $this->uid;
  67. }
  68. function getEmail() {
  69. return $this->email;
  70. }
  71. function getName() {
  72. return $this->realname;
  73. }
  74. /**
  75. * Check the given plaintext password against the stored hash.
  76. * @param string $password
  77. * @param bool $apppass Set to true to enforce app passwords when 2fa is on.
  78. * @return bool
  79. */
  80. function checkPassword(string $password, bool $apppass = false): bool {
  81. $resp = AccountHubApi::get("auth", ['username' => $this->username, 'password' => $password, 'apppass' => ($apppass ? "1" : "0")]);
  82. if ($resp['status'] == "OK") {
  83. return true;
  84. } else {
  85. return false;
  86. }
  87. }
  88. function check2fa(string $code): bool {
  89. if (!$this->has2fa) {
  90. return true;
  91. }
  92. $resp = AccountHubApi::get("verifytotp", ['username' => $this->username, 'code' => $code]);
  93. if ($resp['status'] == "OK") {
  94. return $resp['valid'];
  95. } else {
  96. return false;
  97. }
  98. }
  99. /**
  100. * Check if the given username has the given permission (or admin access)
  101. * @global $database $database
  102. * @param string $code
  103. * @return boolean TRUE if the user has the permission (or admin access), else FALSE
  104. */
  105. function hasPermission(string $code): bool {
  106. $resp = AccountHubApi::get("permission", ['username' => $this->username, 'code' => $code]);
  107. if ($resp['status'] == "OK") {
  108. return $resp['has_permission'];
  109. } else {
  110. return false;
  111. }
  112. }
  113. /**
  114. * Get the account status.
  115. * @return \AccountStatus
  116. */
  117. function getStatus(): AccountStatus {
  118. $resp = AccountHubApi::get("acctstatus", ['username' => $this->username]);
  119. if ($resp['status'] == "OK") {
  120. return AccountStatus::fromString($resp['account']);
  121. } else {
  122. return null;
  123. }
  124. }
  125. function sendAlertEmail(string $appname = null) {
  126. global $SETTINGS;
  127. if (is_null($appname)) {
  128. $appname = $SETTINGS['site_title'];
  129. }
  130. $resp = AccountHubApi::get("alertemail", ['username' => $this->username, 'appname' => $SETTINGS['site_title']]);
  131. if ($resp['status'] == "OK") {
  132. return true;
  133. } else {
  134. return $resp['msg'];
  135. }
  136. }
  137. }
  138. class AccountStatus {
  139. const NORMAL = 1;
  140. const LOCKED_OR_DISABLED = 2;
  141. const CHANGE_PASSWORD = 3;
  142. const TERMINATED = 4;
  143. const ALERT_ON_ACCESS = 5;
  144. private $status;
  145. public function __construct(int $status) {
  146. $this->status = $status;
  147. }
  148. public static function fromString(string $status): AccountStatus {
  149. switch ($status) {
  150. case "NORMAL":
  151. return new self(self::NORMAL);
  152. case "LOCKED_OR_DISABLED":
  153. return new self(self::LOCKED_OR_DISABLED);
  154. case "CHANGE_PASSWORD":
  155. return new self(self::CHANGE_PASSWORD);
  156. case "TERMINATED":
  157. return new self(self::TERMINATED);
  158. case "ALERT_ON_ACCESS":
  159. return new self(self::ALERT_ON_ACCESS);
  160. default:
  161. return new self(0);
  162. }
  163. }
  164. /**
  165. * Get the account status/state as an integer.
  166. * @return int
  167. */
  168. public function get(): int {
  169. return $this->status;
  170. }
  171. /**
  172. * Get the account status/state as a string representation.
  173. * @return string
  174. */
  175. public function getString(): string {
  176. switch ($this->status) {
  177. case self::NORMAL:
  178. return "NORMAL";
  179. case self::LOCKED_OR_DISABLED:
  180. return "LOCKED_OR_DISABLED";
  181. case self::CHANGE_PASSWORD:
  182. return "CHANGE_PASSWORD";
  183. case self::TERMINATED:
  184. return "TERMINATED";
  185. case self::ALERT_ON_ACCESS:
  186. return "ALERT_ON_ACCESS";
  187. default:
  188. return "OTHER_" . $this->status;
  189. }
  190. }
  191. }