BioTorrents.de’s version of Gazelle
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.

enable_requests.php 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. <?php
  2. #declare(strict_types=1);
  3. if (!check_perms('users_mod')) {
  4. error(403);
  5. }
  6. if (!FEATURE_EMAIL_REENABLE) {
  7. // This feature is disabled
  8. header('Location: tools.php');
  9. error();
  10. }
  11. // Silence undefined variable warnings
  12. foreach (array('username', 'ip', 'submitted_between', 'submitted_between', 'submitted_timestamp1', 'submitted_timestamp2', 'handled_username', 'handled_between', 'handled_timestamp1', 'handled_timestamp2', 'outcome_search', 'order', 'way') as $S) {
  13. if (!isset($_GET[$S])) {
  14. $_GET[$S] = null;
  15. }
  16. }
  17. View::show_header('Enable Requests', 'enable_requests');
  18. // Pagination
  19. $RequestsPerPage = 25;
  20. list($Page, $Limit) = Format::page_limit($RequestsPerPage);
  21. // How can things be ordered?
  22. $OrderBys = array(
  23. 'submitted_timestamp' => 'uer.`Timestamp`',
  24. 'outcome' => 'uer.`Outcome`',
  25. 'handled_timestamp' => 'uer.`HandledTimestamp`');
  26. $Where = [];
  27. $Joins = [];
  28. // Default orderings
  29. $OrderBy = "uer.`Timestamp`";
  30. $OrderWay = "DESC";
  31. // Build query for different views
  32. // TODO: Work with encrypted values
  33. if (!isset($_GET['view'])) {
  34. $_GET['view'] = 'main';
  35. }
  36. switch ($_GET['view']) {
  37. case 'perfect':
  38. $Where[] = "um.`Email` = uer.`Email`";
  39. $Joins[] = "JOIN `users_main` um ON um.`ID` = uer.`UserID`";
  40. $Where[] = "ui.`BanReason` = '3'";
  41. break;
  42. case 'minus_ip':
  43. $Where[] = "um.`Email` = uer.`Email`";
  44. $Joins[] = "JOIN `users_main` um ON um.`ID` = uer.`UserID`";
  45. $Where[] = "ui.`BanReason` = '3'";
  46. break;
  47. case 'invalid_email':
  48. $Joins[] = "JOIN `users_main` um ON um.`ID` = uer.`UserID`";
  49. $Where[] = "um.`Email` != uer.`Email`";
  50. break;
  51. case 'manual_disable':
  52. $Where[] = "ui.`BanReason` != '3'";
  53. break;
  54. default:
  55. $Joins[] = '';
  56. break;
  57. }
  58. // End views
  59. // Build query further based on search
  60. if (isset($_GET['search'])) {
  61. $Username = db_string($_GET['username']);
  62. $IP = db_string($_GET['ip']);
  63. $SubmittedBetween = db_string($_GET['submitted_between']);
  64. $SubmittedTimestamp1 = db_string($_GET['submitted_timestamp1']);
  65. $SubmittedTimestamp2 = db_string($_GET['submitted_timestamp2']);
  66. $HandledUsername = db_string($_GET['handled_username']);
  67. $HandledBetween = db_string($_GET['handled_between']);
  68. $HandledTimestamp1 = db_string($_GET['handled_timestamp1']);
  69. $HandledTimestamp2 = db_string($_GET['handled_timestamp2']);
  70. $OutcomeSearch = (int) $_GET['outcome_search'];
  71. $Checked = (isset($_GET['show_checked']));
  72. if (array_key_exists($_GET['order'], $OrderBys)) {
  73. $OrderBy = $OrderBys[$_GET['order']];
  74. }
  75. if ($_GET['way'] === 'asc' || $_GET['way'] === 'desc') {
  76. $OrderWay = $_GET['way'];
  77. }
  78. if (!empty($Username)) {
  79. $Joins[] = "JOIN `users_main` um1 ON um1.`ID` = uer.`UserID`";
  80. }
  81. if (!empty($HandledUsername)) {
  82. $Joins[] = "JOIN `users_main` um2 ON um2.`ID` = uer.`CheckedBy`";
  83. }
  84. $Where = array_merge($Where, AutoEnable::build_search_query(
  85. $Username,
  86. $IP,
  87. $SubmittedBetween,
  88. $SubmittedTimestamp1,
  89. $SubmittedTimestamp2,
  90. $HandledUsername,
  91. $HandledBetween,
  92. $HandledTimestamp1,
  93. $HandledTimestamp2,
  94. $OutcomeSearch,
  95. $Checked
  96. ));
  97. }
  98. // End search queries
  99. $ShowChecked = (isset($Checked) && $Checked) || !empty($HandledUsername) || !empty($HandledTimestamp1) || !empty($OutcomeSearch);
  100. if (!$ShowChecked || count($Where) === 0) {
  101. // If no search is entered, add this to the query to only show unchecked requests
  102. $Where[] = '`Outcome` IS NULL';
  103. }
  104. $QueryID = $DB->query("
  105. SELECT SQL_CALC_FOUND_ROWS
  106. uer.`ID`,
  107. uer.`UserID`,
  108. uer.`Email`,
  109. uer.`IP`,
  110. uer.`UserAgent`,
  111. uer.`Timestamp`,
  112. ui.`BanReason`,
  113. uer.`CheckedBy`,
  114. uer.`HandledTimestamp`,
  115. uer.`Outcome`
  116. FROM
  117. `users_enable_requests` AS uer
  118. JOIN `users_info` ui ON
  119. ui.`UserID` = uer.`UserID` ".implode(' ', $Joins)."
  120. WHERE
  121. ".implode(' AND ', $Where)."
  122. ORDER BY
  123. $OrderBy $OrderWay
  124. LIMIT
  125. $Limit
  126. ");
  127. $DB->query("SELECT FOUND_ROWS()");
  128. list($NumResults) = $DB->next_record();
  129. $DB->set_query_id($QueryID);
  130. ?>
  131. <div class="header">
  132. <h2>Auto-Enable Requests</h2>
  133. </div>
  134. <div align="center">
  135. <a class="brackets tooltip" href="tools.php?action=enable_requests" title="Default view">Main</a>
  136. <a class="brackets tooltip"
  137. href="tools.php?action=enable_requests&amp;view=perfect&amp;<?=Format::get_url(array('view', 'action'))?>"
  138. title="Valid username, matching email, current IP with no matches, and inactivity disabled">Perfect</a>
  139. <a class="brackets tooltip"
  140. href="tools.php?action=enable_requests&amp;view=minus_ip&amp;<?=Format::get_url(array('view', 'action'))?>"
  141. title="Valid username, matching email, and inactivity disabled">Perfect Minus IP</a>
  142. <a class="brackets tooltip"
  143. href="tools.php?action=enable_requests&amp;view=invalid_email&amp;<?=Format::get_url(array('view', 'action'))?>"
  144. title="Non-matching email address">Invalid Email</a>
  145. <a class="brackets tooltip"
  146. href="tools.php?action=enable_requests&amp;view=ip_overlap&amp;<?=Format::get_url(array('view', 'action'))?>"
  147. title="Requests with IP matches to other accounts">IP Overlap</a>
  148. <a class="brackets tooltip"
  149. href="tools.php?action=enable_requests&amp;view=manual_disable&amp;<?=Format::get_url(array('view', 'action'))?>"
  150. title="Requests for accounts that were not disabled for inactivity">Manual Disable</a>
  151. <a class="brackets tooltip" title="Show/Hide Search" data-toggle-target="#search_form">Search</a>
  152. <a class="brackets tooltip" title="Show/Hide Search" data-toggle-target="#scores">Scores</a>
  153. </div>
  154. <div>
  155. <table id="scores" class="hidden" style="width: 50%; margin: 0 auto;">
  156. <tr>
  157. <th>Username</th>
  158. <th>Checked</th>
  159. </tr>
  160. <?php
  161. $DB->query("
  162. SELECT
  163. COUNT(`CheckedBy`),
  164. `CheckedBy`
  165. FROM
  166. `users_enable_requests`
  167. WHERE
  168. `CheckedBy` IS NOT NULL
  169. GROUP BY
  170. `CheckedBy`
  171. ORDER BY
  172. COUNT(`CheckedBy`)
  173. DESC
  174. LIMIT 50
  175. ");
  176. while (list($Checked, $UserID) = $DB->next_record()) { ?>
  177. <tr>
  178. <td>
  179. <?=Users::format_username($UserID)?>
  180. </td>
  181. <td>
  182. <?=$Checked?>
  183. </td>
  184. </tr>
  185. <?php
  186. }
  187. $DB->set_query_id($QueryID); ?>
  188. </table>
  189. <form action="" method="GET" id="search_form" <?=!isset($_GET['search']) ? 'class="hidden"' : ''?>>
  190. <input type="hidden" name="action" value="enable_requests" />
  191. <input type="hidden" name="view"
  192. value="<?=$_GET['view']?>" />
  193. <input type="hidden" name="search" value="1" />
  194. <table>
  195. <tr>
  196. <td class="label">Username</td>
  197. <td>
  198. <input type="text" name="username"
  199. value="<?=$_GET['username']?>" />
  200. </td>
  201. </tr>
  202. <tr>
  203. <td class="label">IP Address</td>
  204. <td>
  205. <input type="text" name="ip"
  206. value="<?=$_GET['ip']?>" />
  207. </td>
  208. </tr>
  209. <tr>
  210. <td class="label tooltip" title="This will search between the entered date and 24 hours after it">
  211. Submitted Timestamp
  212. </td>
  213. <td>
  214. <select name="submitted_between" onchange="ChangeDateSearch(this.value, 'submitted_timestamp2');">
  215. <option value="on" <?=$_GET['submitted_between'] === 'on' ? 'selected' : ''?>>On
  216. </option>
  217. <option value="before" <?=$_GET['submitted_between'] === 'before' ? 'selected' : ''?>>Before
  218. </option>
  219. <option value="after" <?=$_GET['submitted_between'] === 'after' ? 'selected' : ''?>>After
  220. </option>
  221. <option value="between" <?=$_GET['submitted_between'] === 'between' ? 'selected' : ''?>>Between
  222. </option>
  223. </select>&nbsp;
  224. <input type="date" name="submitted_timestamp1"
  225. value="<?=$_GET['submitted_timestamp1']?>" />
  226. <input type="date" id="submitted_timestamp2" name="submitted_timestamp2"
  227. value="<?=$_GET['submitted_timestamp2']?>"
  228. <?=$_GET['submitted_between'] !== 'between' ? 'style="display: none;"' : ''?>
  229. />
  230. </td>
  231. </tr>
  232. <tr>
  233. <td class="label">Handled By Username</td>
  234. <td>
  235. <input type="text" name="handled_username"
  236. value="<?=$_GET['handled_username']?>" />
  237. </td>
  238. </tr>
  239. <tr>
  240. <td class="label tooltip" title="This will search between the entered date and 24 hours after it">
  241. Handled Timestamp
  242. </td>
  243. <td>
  244. <select name="handled_between" onchange="ChangeDateSearch(this.value, 'handled_timestamp2');">
  245. <option value="on" <?=$_GET['handled_between'] === 'on' ? 'selected' : ''?>>On
  246. </option>
  247. <option value="before" <?=$_GET['handled_between'] === 'before' ? 'selected' : ''?>>Before
  248. </option>
  249. <option value="after" <?=$_GET['handled_between'] === 'after' ? 'selected' : ''?>>After
  250. </option>
  251. <option value="between" <?=$_GET['handled_between'] === 'between' ? 'selected' : ''?>>Between
  252. </option>
  253. </select>&nbsp;
  254. <input type="date" name="handled_timestamp1"
  255. value="<?=$_GET['handled_timestamp1']?>" />
  256. <input type="date" id="handled_timestamp2" name="handled_timestamp2"
  257. value="<?=$_GET['handled_timestamp2']?>"
  258. <?=$_GET['handled_between'] !== 'between' ? 'style="display: none;"' : ''?>
  259. />
  260. </td>
  261. </tr>
  262. <tr>
  263. <td class="label">Outcome</td>
  264. <td>
  265. <select name="outcome_search">
  266. <option value="">---</option>
  267. <option value="<?=AutoEnable::APPROVED?>"
  268. <?=$_GET['outcome_search'] === AutoEnable::APPROVED ? 'selected' : ''?>>Approved
  269. </option>
  270. <option value="<?=AutoEnable::DENIED?>"
  271. <?=$_GET['outcome_search'] === AutoEnable::DENIED ? 'selected' : ''?>>Denied
  272. </option>
  273. <option value="<?=AutoEnable::DISCARDED?>"
  274. <?=$_GET['outcome_search'] === AutoEnable::DISCARDED ? 'selected' : ''?>>Discarded
  275. </option>
  276. </select>
  277. </td>
  278. </tr>
  279. <tr>
  280. <td class="label">Include Checked</td>
  281. <td>
  282. <input type="checkbox" name="show_checked" <?=isset($_GET['show_checked']) ? 'checked' : ''?>
  283. />
  284. </td>
  285. </tr>
  286. <tr>
  287. <td class="label">Order By</td>
  288. <td>
  289. <select name="order">
  290. <option value="submitted_timestamp" <?=$_GET['order'] === 'submitted_timestamp' ? 'selected' : '' ?>>Submitted
  291. Timestamp</option>
  292. <option value="outcome" <?=$_GET['order'] === 'outcome' ? 'selected' : '' ?>>Outcome
  293. </option>
  294. <option value="handled_timestamp" <?=$_GET['order'] === 'handled_timestamp' ? 'selected' : '' ?>>Handled
  295. Timestamp</option>
  296. </select>&nbsp;
  297. <select name="way">
  298. <option value="asc" <?=$_GET['way'] === 'asc' ? 'selected' : '' ?>>Ascending
  299. </option>
  300. <option value="desc" <?=!isset($_GET['way']) || $_GET['way'] === 'desc' ? 'selected' : '' ?>>Descending
  301. </option>
  302. </select>
  303. </td>
  304. </tr>
  305. <tr>
  306. <td colspan=2>
  307. <input type="submit" value="Search" />
  308. </td>
  309. </tr>
  310. </table>
  311. </form>
  312. </div>
  313. <?php
  314. if ($NumResults > 0) { ?>
  315. <div class="linkbox">
  316. <?php
  317. $Pages = Format::get_pages($Page, $NumResults, $RequestsPerPage);
  318. echo $Pages;
  319. ?>
  320. </div>
  321. <table width="100%">
  322. <tr class="colhead">
  323. <td class="center"><input type="checkbox" id="check_all" /></td>
  324. <td>
  325. Username
  326. </td>
  327. <td>
  328. Email Address
  329. </td>
  330. <td>
  331. IP Address
  332. </td>
  333. <td>
  334. User Agent
  335. </td>
  336. <td>
  337. Age
  338. </td>
  339. <td>
  340. Ban Reason
  341. </td>
  342. <td>
  343. Comment<?=$ShowChecked ? '/Checked By' : ''?>
  344. </td>
  345. <td>
  346. Submit<?=$ShowChecked ? '/Checked Date' : ''?>
  347. </td>
  348. <?php if ($ShowChecked) { ?>
  349. <td>
  350. Outcome
  351. </td>
  352. <?php } ?>
  353. </tr>
  354. <?php
  355. while (list($ID, $UserID, $Email, $IP, $UserAgent, $Timestamp, $BanReason, $CheckedBy, $HandledTimestamp, $Outcome) = $DB->next_record()) {
  356. ?>
  357. <tr class="row" id="row_<?=$ID?>">
  358. <td class="center">
  359. <?php if (!$HandledTimestamp) { ?>
  360. <input type="checkbox" id="multi" data-id="<?=$ID?>" />
  361. <?php } ?>
  362. </td>
  363. <td>
  364. <?=Users::format_username($UserID)?>
  365. </td>
  366. <td>
  367. <?=display_str(Crypto::decrypt($Email))?>
  368. </td>
  369. <td>
  370. <?=display_str(Crypto::decrypt($IP))?>
  371. </td>
  372. <td>
  373. <?=display_str($UserAgent)?>
  374. </td>
  375. <td>
  376. <?=time_diff($Timestamp)?>
  377. </td>
  378. <td>
  379. <?=($BanReason == 3) ? '<b>Inactivity</b>' : 'Other'?>
  380. </td>
  381. <?php if (!$HandledTimestamp) { ?>
  382. <td>
  383. <input class="inputtext" type="text" id="comment<?=$ID?>"
  384. placeholder="Comment" />
  385. </td>
  386. <td>
  387. <input type="submit" id="outcome" value="Approve"
  388. data-id="<?=$ID?>" />
  389. <input type="submit" id="outcome" value="Reject"
  390. data-id="<?=$ID?>" />
  391. <input type="submit" id="outcome" value="Discard"
  392. data-id="<?=$ID?>" />
  393. </td>
  394. <?php } else { ?>
  395. <td>
  396. <?=Users::format_username($CheckedBy);?>
  397. </td>
  398. <td>
  399. <?=$HandledTimestamp?>
  400. </td>
  401. <?php }
  402. if ($ShowChecked) { ?>
  403. <td>
  404. <?=AutoEnable::get_outcome_string($Outcome)?>
  405. <?php if ($Outcome === AutoEnable::DISCARDED) { ?>
  406. <a href="" id="unresolve" onclick="return false;" class="brackets"
  407. data-id="<?=$ID?>">Unresolve</a>
  408. <?php } ?>
  409. </td>
  410. <?php } ?>
  411. </tr>
  412. <?php
  413. }
  414. ?>
  415. </table>
  416. <div class="linkbox">
  417. <?php
  418. $Pages = Format::get_pages($Page, $NumResults, $RequestsPerPage);
  419. echo $Pages;
  420. ?>
  421. </div>
  422. <div style="padding-bottom: 11px;">
  423. <input type="submit" id="multi" value="Approve Selected" />
  424. <input type="submit" id="multi" value="Reject Selected" />
  425. <input type="submit" id="multi" value="Discard Selected" />
  426. </div>
  427. <?php } else { ?>
  428. <h2>
  429. No new pending auto enable requests <?=($_GET['view'] === 'main') ? '' : ' in this view' ?>
  430. </h2>
  431. <?php }
  432. View::show_footer();