functions.ratelimit.inc.php 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. <?php
  2. function ratelimit($_action, $_scope, $_data = null, $_extra = null) {
  3. global $redis;
  4. $_data_log = $_data;
  5. switch ($_action) {
  6. case 'edit':
  7. if ((!isset($_SESSION['acl']['ratelimit']) || $_SESSION['acl']['ratelimit'] != "1") && !$_extra['iam_create_login']) {
  8. $_SESSION['return'][] = array(
  9. 'type' => 'danger',
  10. 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
  11. 'msg' => 'access_denied'
  12. );
  13. return false;
  14. }
  15. switch ($_scope) {
  16. case 'domain':
  17. if (!is_array($_data['object'])) {
  18. $objects = array();
  19. $objects[] = $_data['object'];
  20. }
  21. else {
  22. $objects = $_data['object'];
  23. }
  24. foreach ($objects as $object) {
  25. $rl_value = intval($_data['rl_value']);
  26. $rl_frame = $_data['rl_frame'];
  27. if (!in_array($rl_frame, array('s', 'm', 'h', 'd'))) {
  28. $_SESSION['return'][] = array(
  29. 'type' => 'danger',
  30. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  31. 'msg' => 'rl_timeframe'
  32. );
  33. continue;
  34. }
  35. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
  36. $_SESSION['return'][] = array(
  37. 'type' => 'danger',
  38. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  39. 'msg' => 'access_denied'
  40. );
  41. continue;
  42. }
  43. if (empty($rl_value)) {
  44. try {
  45. $redis->hDel('RL_VALUE', $object);
  46. }
  47. catch (RedisException $e) {
  48. $_SESSION['return'][] = array(
  49. 'type' => 'danger',
  50. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  51. 'msg' => array('redis_error', $e)
  52. );
  53. continue;
  54. }
  55. }
  56. else {
  57. try {
  58. $redis->hSet('RL_VALUE', $object, $rl_value . ' / 1' . $rl_frame);
  59. }
  60. catch (RedisException $e) {
  61. $_SESSION['return'][] = array(
  62. 'type' => 'danger',
  63. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  64. 'msg' => array('redis_error', $e)
  65. );
  66. continue;
  67. }
  68. }
  69. $_SESSION['return'][] = array(
  70. 'type' => 'success',
  71. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  72. 'msg' => array('rl_saved', $object)
  73. );
  74. }
  75. break;
  76. case 'mailbox':
  77. if (!is_array($_data['object'])) {
  78. $objects = array();
  79. $objects[] = $_data['object'];
  80. }
  81. else {
  82. $objects = $_data['object'];
  83. }
  84. foreach ($objects as $object) {
  85. $rl_value = intval($_data['rl_value']);
  86. $rl_frame = $_data['rl_frame'];
  87. if (!in_array($rl_frame, array('s', 'm', 'h', 'd'))) {
  88. $_SESSION['return'][] = array(
  89. 'type' => 'danger',
  90. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  91. 'msg' => 'rl_timeframe'
  92. );
  93. continue;
  94. }
  95. if ((!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)
  96. || ($_SESSION['mailcow_cc_role'] != 'admin' && $_SESSION['mailcow_cc_role'] != 'domainadmin')) && !$_extra['iam_create_login']) {
  97. $_SESSION['return'][] = array(
  98. 'type' => 'danger',
  99. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  100. 'msg' => 'access_denied'
  101. );
  102. continue;
  103. }
  104. if (empty($rl_value)) {
  105. try {
  106. $redis->hDel('RL_VALUE', $object);
  107. }
  108. catch (RedisException $e) {
  109. $_SESSION['return'][] = array(
  110. 'type' => 'danger',
  111. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  112. 'msg' => array('redis_error', $e)
  113. );
  114. continue;
  115. }
  116. }
  117. else {
  118. try {
  119. $redis->hSet('RL_VALUE', $object, $rl_value . ' / 1' . $rl_frame);
  120. }
  121. catch (RedisException $e) {
  122. $_SESSION['return'][] = array(
  123. 'type' => 'danger',
  124. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  125. 'msg' => array('redis_error', $e)
  126. );
  127. continue;
  128. }
  129. }
  130. $_SESSION['return'][] = array(
  131. 'type' => 'success',
  132. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  133. 'msg' => array('rl_saved', $object)
  134. );
  135. }
  136. break;
  137. }
  138. break;
  139. case 'get':
  140. switch ($_scope) {
  141. case 'domain':
  142. if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
  143. return false;
  144. }
  145. try {
  146. if ($rl_value = $redis->hGet('RL_VALUE', $_data)) {
  147. $rl = explode(' / 1', $rl_value);
  148. $data['value'] = $rl[0];
  149. $data['frame'] = $rl[1];
  150. return $data;
  151. }
  152. else {
  153. return false;
  154. }
  155. }
  156. catch (RedisException $e) {
  157. $_SESSION['return'][] = array(
  158. 'type' => 'danger',
  159. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  160. 'msg' => array('redis_error', $e)
  161. );
  162. return false;
  163. }
  164. return false;
  165. break;
  166. case 'mailbox':
  167. if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)
  168. || ($_SESSION['mailcow_cc_role'] != 'admin' && $_SESSION['mailcow_cc_role'] != 'domainadmin')) {
  169. return false;
  170. }
  171. try {
  172. if ($rl_value = $redis->hGet('RL_VALUE', $_data)) {
  173. $rl = explode(' / 1', $rl_value);
  174. $data['value'] = $rl[0];
  175. $data['frame'] = $rl[1];
  176. return $data;
  177. }
  178. else {
  179. return false;
  180. }
  181. }
  182. catch (RedisException $e) {
  183. $_SESSION['return'][] = array(
  184. 'type' => 'danger',
  185. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  186. 'msg' => array('redis_error', $e)
  187. );
  188. return false;
  189. }
  190. return false;
  191. break;
  192. }
  193. break;
  194. case 'delete':
  195. $data['hash'] = $_data;
  196. if ($_SESSION['mailcow_cc_role'] != 'admin' || !preg_match('/^RL[0-9A-Za-z=]+$/i', trim($data['hash']))) {
  197. $_SESSION['return'][] = array(
  198. 'type' => 'danger',
  199. 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
  200. 'msg' => 'access_denied'
  201. );
  202. return false;
  203. }
  204. try {
  205. $data_rllog = $redis->lRange('RL_LOG', 0, -1);
  206. if ($data_rllog) {
  207. foreach ($data_rllog as $json_line) {
  208. if (preg_match('/' . $data['hash'] . '/i', $json_line)) {
  209. $redis->lRem('RL_LOG', $json_line, 0);
  210. }
  211. }
  212. }
  213. if ($redis->type($data['hash']) == Redis::REDIS_HASH) {
  214. $redis->delete($data['hash']);
  215. $_SESSION['return'][] = array(
  216. 'type' => 'success',
  217. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  218. 'msg' => 'hash_deleted'
  219. );
  220. return true;
  221. }
  222. else {
  223. $_SESSION['return'][] = array(
  224. 'type' => 'warning',
  225. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  226. 'msg' => 'hash_not_found'
  227. );
  228. return false;
  229. }
  230. }
  231. catch (RedisException $e) {
  232. $_SESSION['return'][] = array(
  233. 'type' => 'danger',
  234. 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
  235. 'msg' => array('redis_error', $e)
  236. );
  237. return false;
  238. }
  239. return false;
  240. break;
  241. }
  242. }