git subrepo clone https://github.com/mailcow/mailcow-dockerized.git mailcow/src/mailcow-dockerized
subrepo: subdir: "mailcow/src/mailcow-dockerized"
merged: "a832becb"
upstream: origin: "https://github.com/mailcow/mailcow-dockerized.git"
branch: "master"
commit: "a832becb"
git-subrepo: version: "0.4.3"
origin: "???"
commit: "???"
Change-Id: If5be2d621a211e164c9b6577adaa7884449f16b5
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/functions.ratelimit.inc.php b/mailcow/src/mailcow-dockerized/data/web/inc/functions.ratelimit.inc.php
new file mode 100644
index 0000000..f9e7a71
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/functions.ratelimit.inc.php
@@ -0,0 +1,242 @@
+<?php
+function ratelimit($_action, $_scope, $_data = null) {
+ global $redis;
+ $_data_log = $_data;
+ switch ($_action) {
+ case 'edit':
+ if (!isset($_SESSION['acl']['ratelimit']) || $_SESSION['acl']['ratelimit'] != "1" ) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => 'access_denied'
+ );
+ return false;
+ }
+ switch ($_scope) {
+ case 'domain':
+ if (!is_array($_data['object'])) {
+ $objects = array();
+ $objects[] = $_data['object'];
+ }
+ else {
+ $objects = $_data['object'];
+ }
+ foreach ($objects as $object) {
+ $rl_value = intval($_data['rl_value']);
+ $rl_frame = $_data['rl_frame'];
+ if (!in_array($rl_frame, array('s', 'm', 'h', 'd'))) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
+ 'msg' => 'rl_timeframe'
+ );
+ continue;
+ }
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
+ 'msg' => 'access_denied'
+ );
+ continue;
+ }
+ if (empty($rl_value)) {
+ try {
+ $redis->hDel('RL_VALUE', $object);
+ }
+ catch (RedisException $e) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
+ 'msg' => array('redis_error', $e)
+ );
+ continue;
+ }
+ }
+ else {
+ try {
+ $redis->hSet('RL_VALUE', $object, $rl_value . ' / 1' . $rl_frame);
+ }
+ catch (RedisException $e) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
+ 'msg' => array('redis_error', $e)
+ );
+ continue;
+ }
+ }
+ $_SESSION['return'][] = array(
+ 'type' => 'success',
+ 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
+ 'msg' => array('rl_saved', $object)
+ );
+ }
+ break;
+ case 'mailbox':
+ if (!is_array($_data['object'])) {
+ $objects = array();
+ $objects[] = $_data['object'];
+ }
+ else {
+ $objects = $_data['object'];
+ }
+ foreach ($objects as $object) {
+ $rl_value = intval($_data['rl_value']);
+ $rl_frame = $_data['rl_frame'];
+ if (!in_array($rl_frame, array('s', 'm', 'h', 'd'))) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
+ 'msg' => 'rl_timeframe'
+ );
+ continue;
+ }
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)
+ || ($_SESSION['mailcow_cc_role'] != 'admin' && $_SESSION['mailcow_cc_role'] != 'domainadmin')) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
+ 'msg' => 'access_denied'
+ );
+ continue;
+ }
+ if (empty($rl_value)) {
+ try {
+ $redis->hDel('RL_VALUE', $object);
+ }
+ catch (RedisException $e) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
+ 'msg' => array('redis_error', $e)
+ );
+ continue;
+ }
+ }
+ else {
+ try {
+ $redis->hSet('RL_VALUE', $object, $rl_value . ' / 1' . $rl_frame);
+ }
+ catch (RedisException $e) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
+ 'msg' => array('redis_error', $e)
+ );
+ continue;
+ }
+ }
+ $_SESSION['return'][] = array(
+ 'type' => 'success',
+ 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
+ 'msg' => array('rl_saved', $object)
+ );
+ }
+ break;
+ }
+ break;
+ case 'get':
+ switch ($_scope) {
+ case 'domain':
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ return false;
+ }
+ try {
+ if ($rl_value = $redis->hGet('RL_VALUE', $_data)) {
+ $rl = explode(' / 1', $rl_value);
+ $data['value'] = $rl[0];
+ $data['frame'] = $rl[1];
+ return $data;
+ }
+ else {
+ return false;
+ }
+ }
+ catch (RedisException $e) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
+ 'msg' => array('redis_error', $e)
+ );
+ return false;
+ }
+ return false;
+ break;
+ case 'mailbox':
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)
+ || ($_SESSION['mailcow_cc_role'] != 'admin' && $_SESSION['mailcow_cc_role'] != 'domainadmin')) {
+ return false;
+ }
+ try {
+ if ($rl_value = $redis->hGet('RL_VALUE', $_data)) {
+ $rl = explode(' / 1', $rl_value);
+ $data['value'] = $rl[0];
+ $data['frame'] = $rl[1];
+ return $data;
+ }
+ else {
+ return false;
+ }
+ }
+ catch (RedisException $e) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
+ 'msg' => array('redis_error', $e)
+ );
+ return false;
+ }
+ return false;
+ break;
+ }
+ break;
+ case 'delete':
+ $data['hash'] = $_data;
+ if ($_SESSION['mailcow_cc_role'] != 'admin' || !preg_match('/^RL[0-9A-Za-z=]+$/i', trim($data['hash']))) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+ 'msg' => 'access_denied'
+ );
+ return false;
+ }
+ try {
+ $data_rllog = $redis->lRange('RL_LOG', 0, -1);
+ if ($data_rllog) {
+ foreach ($data_rllog as $json_line) {
+ if (preg_match('/' . $data['hash'] . '/i', $json_line)) {
+ $redis->lRem('RL_LOG', $json_line, 0);
+ }
+ }
+ }
+ if ($redis->type($data['hash']) == Redis::REDIS_HASH) {
+ $redis->delete($data['hash']);
+ $_SESSION['return'][] = array(
+ 'type' => 'success',
+ 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
+ 'msg' => 'hash_deleted'
+ );
+ return true;
+ }
+ else {
+ $_SESSION['return'][] = array(
+ 'type' => 'warning',
+ 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
+ 'msg' => 'hash_not_found'
+ );
+ return false;
+ }
+ }
+ catch (RedisException $e) {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
+ 'msg' => array('redis_error', $e)
+ );
+ return false;
+ }
+ return false;
+ break;
+ }
+}
\ No newline at end of file