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

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