Browse Source

[Web] Allow to skip IP check for API

andryyy 5 years ago
parent
commit
0ac4281f0e

+ 8 - 1
data/web/admin.php

@@ -124,7 +124,14 @@ if (!isset($_SESSION['gal']) && $license_cache = $redis->Get('LICENSE_STATUS_CAC
           <div class="form-group">
           <div class="form-group">
             <label class="control-label col-sm-3" for="allow_from"><?=$lang['admin']['api_allow_from'];?>:</label>
             <label class="control-label col-sm-3" for="allow_from"><?=$lang['admin']['api_allow_from'];?>:</label>
             <div class="col-sm-9">
             <div class="col-sm-9">
-              <textarea class="form-control" rows="5" name="allow_from" id="allow_from" required><?=htmlspecialchars($api['allow_from']);?></textarea>
+              <textarea class="form-control" rows="5" name="allow_from" id="allow_from" <?=($api['skip_ip_check'] == 1) ? 'disabled' : null;?> required><?=htmlspecialchars($api['allow_from']);?></textarea>
+            </div>
+          </div>
+          <div class="form-group">
+            <div class="col-sm-offset-3 col-sm-9">
+              <label>
+                <input type="checkbox" id="skip_ip_check" name="skip_ip_check" <?=($api['skip_ip_check'] == 1) ? 'checked' : null;?>> <?=$lang['admin']['api_skip_ip_check'];?>
+              </label>
             </div>
             </div>
           </div>
           </div>
           <div class="form-group">
           <div class="form-group">

+ 23 - 8
data/web/inc/functions.inc.php

@@ -1158,8 +1158,12 @@ function admin_api($action, $data = null) {
 		case "edit":
 		case "edit":
       $regen_key = $data['admin_api_regen_key'];
       $regen_key = $data['admin_api_regen_key'];
       $active = (isset($data['active'])) ? 1 : 0;
       $active = (isset($data['active'])) ? 1 : 0;
+      $skip_ip_check = (isset($data['skip_ip_check'])) ? 1 : 0;
       $allow_from = array_map('trim', preg_split( "/( |,|;|\n)/", $data['allow_from']));
       $allow_from = array_map('trim', preg_split( "/( |,|;|\n)/", $data['allow_from']));
       foreach ($allow_from as $key => $val) {
       foreach ($allow_from as $key => $val) {
+        if (empty($val)) {
+          continue;
+        }
         if (!filter_var($val, FILTER_VALIDATE_IP)) {
         if (!filter_var($val, FILTER_VALIDATE_IP)) {
           $_SESSION['return'][] =  array(
           $_SESSION['return'][] =  array(
             'type' => 'warning',
             'type' => 'warning',
@@ -1171,7 +1175,7 @@ function admin_api($action, $data = null) {
         }
         }
       }
       }
       $allow_from = implode(',', array_unique(array_filter($allow_from)));
       $allow_from = implode(',', array_unique(array_filter($allow_from)));
-      if (empty($allow_from)) {
+      if (empty($allow_from) && $skip_ip_check == 0) {
         $_SESSION['return'][] =  array(
         $_SESSION['return'][] =  array(
           'type' => 'danger',
           'type' => 'danger',
           'log' => array(__FUNCTION__, $data),
           'log' => array(__FUNCTION__, $data),
@@ -1189,20 +1193,31 @@ function admin_api($action, $data = null) {
       $stmt = $pdo->query("SELECT `api_key` FROM `api`");
       $stmt = $pdo->query("SELECT `api_key` FROM `api`");
       $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
       $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
       if (empty($num_results)) {
       if (empty($num_results)) {
-        $stmt = $pdo->prepare("INSERT INTO `api` (`api_key`, `active`, `allow_from`)
-          VALUES (:api_key, :active, :allow_from);");
+        $stmt = $pdo->prepare("INSERT INTO `api` (`api_key`, `skip_ip_check`, `active`, `allow_from`)
+          VALUES (:api_key, :skip_ip_check, :active, :allow_from);");
         $stmt->execute(array(
         $stmt->execute(array(
           ':api_key' => $api_key,
           ':api_key' => $api_key,
+          ':skip_ip_check' => $skip_ip_check,
           ':active' => $active,
           ':active' => $active,
           ':allow_from' => $allow_from
           ':allow_from' => $allow_from
         ));
         ));
       }
       }
       else {
       else {
-        $stmt = $pdo->prepare("UPDATE `api` SET `active` = :active, `allow_from` = :allow_from ;");
-        $stmt->execute(array(
-          ':active' => $active,
-          ':allow_from' => $allow_from
-        ));
+        if ($skip_ip_check == 0) {
+          $stmt = $pdo->prepare("UPDATE `api` SET `skip_ip_check` = :skip_ip_check, `active` = :active, `allow_from` = :allow_from ;");
+          $stmt->execute(array(
+            ':active' => $active,
+            ':skip_ip_check' => $skip_ip_check,
+            ':allow_from' => $allow_from
+          ));
+        }
+        else {
+          $stmt = $pdo->prepare("UPDATE `api` SET `skip_ip_check` = :skip_ip_check, `active` = :active ;");
+          $stmt->execute(array(
+            ':active' => $active,
+            ':skip_ip_check' => $skip_ip_check
+          ));
+        }
       }
       }
     break;
     break;
     case "regen_key":
     case "regen_key":

+ 2 - 1
data/web/inc/init_db.inc.php

@@ -3,7 +3,7 @@ function init_db_schema() {
   try {
   try {
     global $pdo;
     global $pdo;
 
 
-    $db_version = "16022020_1304";
+    $db_version = "16022020_1804";
 
 
     $stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
     $stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
     $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
     $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
@@ -170,6 +170,7 @@ function init_db_schema() {
         "cols" => array(
         "cols" => array(
           "api_key" => "VARCHAR(255) NOT NULL",
           "api_key" => "VARCHAR(255) NOT NULL",
           "allow_from" => "VARCHAR(512) NOT NULL",
           "allow_from" => "VARCHAR(512) NOT NULL",
+          "skip_ip_check" => "TINYINT(1) NOT NULL DEFAULT '0'",
           "created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
           "created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
           "modified" => "DATETIME ON UPDATE NOW(0)",
           "modified" => "DATETIME ON UPDATE NOW(0)",
           "active" => "TINYINT(1) NOT NULL DEFAULT '1'"
           "active" => "TINYINT(1) NOT NULL DEFAULT '1'"

+ 4 - 3
data/web/inc/sessions.inc.php

@@ -44,15 +44,16 @@ $_SESSION['LAST_ACTIVITY'] = time();
 
 
 // API
 // API
 if (!empty($_SERVER['HTTP_X_API_KEY'])) {
 if (!empty($_SERVER['HTTP_X_API_KEY'])) {
-  $stmt = $pdo->prepare("SELECT `allow_from` FROM `api` WHERE `api_key` = :api_key AND `active` = '1';");
+  $stmt = $pdo->prepare("SELECT * FROM `api` WHERE `api_key` = :api_key AND `active` = '1';");
   $stmt->execute(array(
   $stmt->execute(array(
     ':api_key' => preg_replace('/[^a-zA-Z0-9-]/', '', $_SERVER['HTTP_X_API_KEY'])
     ':api_key' => preg_replace('/[^a-zA-Z0-9-]/', '', $_SERVER['HTTP_X_API_KEY'])
   ));
   ));
   $api_return = $stmt->fetch(PDO::FETCH_ASSOC);
   $api_return = $stmt->fetch(PDO::FETCH_ASSOC);
-  if (!empty($api_return['allow_from'])) {
+  if (!empty($api_return['api_key'])) {
+    $skip_ip_check = ($api_return['skip_ip_check'] == 1);
     $remote = get_remote_ip(false);
     $remote = get_remote_ip(false);
     $allow_from = array_map('trim', preg_split( "/( |,|;|\n)/", $api_return['allow_from']));
     $allow_from = array_map('trim', preg_split( "/( |,|;|\n)/", $api_return['allow_from']));
-    if (in_array($remote, $allow_from)) {
+    if (in_array($remote, $allow_from) || $skip_ip_check === true) {
       $_SESSION['mailcow_cc_username'] = 'API';
       $_SESSION['mailcow_cc_username'] = 'API';
       $_SESSION['mailcow_cc_role'] = 'admin';
       $_SESSION['mailcow_cc_role'] = 'admin';
       $_SESSION['mailcow_cc_api'] = true;
       $_SESSION['mailcow_cc_api'] = true;

+ 10 - 0
data/web/js/site/admin.js

@@ -359,6 +359,16 @@ jQuery(function($){
   draw_oauth2_clients();
   draw_oauth2_clients();
   draw_transport_maps();
   draw_transport_maps();
   draw_queue();
   draw_queue();
+  // API IP check toggle
+  $("#skip_ip_check").click(function( event ) {
+   $("#skip_ip_check").not(this).prop('checked', false);
+    if ($("#skip_ip_check:checked").length > 0) {
+      $('#allow_from').prop('disabled', true);
+    }
+    else {
+      $("#allow_from").removeAttr('disabled');
+    }
+  });
   // Relayhost
   // Relayhost
   $('#testRelayhostModal').on('show.bs.modal', function (e) {
   $('#testRelayhostModal').on('show.bs.modal', function (e) {
     $('#test_relayhost_result').text("-");
     $('#test_relayhost_result').text("-");

+ 7 - 0
data/web/js/site/mailbox.js

@@ -48,6 +48,13 @@ $(document).ready(function() {
       $(this.$domain).closest("select").selectpicker();
       $(this.$domain).closest("select").selectpicker();
     }
     }
   });
   });
+  // todo
+  $('[data-page-size]').on('click', function(e){
+    e.preventDefault();
+    var newSize = $(this).data('page-size');
+    var nextTable = $(this).nextAll('.table-responsive').find('table');
+    FooTable.get(nextTable).pageSize(newSize);
+  });
   // Clone mailbox mass actions
   // Clone mailbox mass actions
   $("div").find("[data-actions-header='true'").each(function() {
   $("div").find("[data-actions-header='true'").each(function() {
     $(this).html($(this).nextAll('.mass-actions-mailbox:first').html());
     $(this).html($(this).nextAll('.mass-actions-mailbox:first').html());

+ 1 - 0
data/web/lang/lang.de.json

@@ -427,6 +427,7 @@
         "nexthop": "Next Hop",
         "nexthop": "Next Hop",
         "api_allow_from": "IP-Adressen für Zugriff",
         "api_allow_from": "IP-Adressen für Zugriff",
         "api_key": "API-Key",
         "api_key": "API-Key",
+        "api_skip_ip_check": "IP-Check für API nicht ausführen",
         "activate_api": "API aktivieren",
         "activate_api": "API aktivieren",
         "regen_api_key": "API-Key regenerieren",
         "regen_api_key": "API-Key regenerieren",
         "ban_list_info": "Übersicht ausgesperrter Netzwerke: <b>Netzwerk (verbleibende Banzeit) - [Aktionen]</b>.<br />IPs, die zum Entsperren eingereiht werden, verlassen die Liste aktiver Bans nach wenigen Sekunden.<br />Rote Labels sind Indikatoren für aktive Blacklisteinträge.",
         "ban_list_info": "Übersicht ausgesperrter Netzwerke: <b>Netzwerk (verbleibende Banzeit) - [Aktionen]</b>.<br />IPs, die zum Entsperren eingereiht werden, verlassen die Liste aktiver Bans nach wenigen Sekunden.<br />Rote Labels sind Indikatoren für aktive Blacklisteinträge.",

+ 1 - 0
data/web/lang/lang.en.json

@@ -447,6 +447,7 @@
         "relay_run": "Run test",
         "relay_run": "Run test",
         "api_allow_from": "Allow API access from these IPs (separated by comma or new line)",
         "api_allow_from": "Allow API access from these IPs (separated by comma or new line)",
         "api_key": "API key",
         "api_key": "API key",
+        "api_skip_ip_check": "Skip IP check for API",
         "activate_api": "Activate API",
         "activate_api": "Activate API",
         "regen_api_key": "Regenerate API key",
         "regen_api_key": "Regenerate API key",
         "ban_list_info": "See a list of banned IPs below: <b>network (remaining ban time) - [actions]</b>.<br />IPs queued to be unbanned will be removed from the active ban list within a few seconds.<br />Red labels indicate active permanent bans by blacklisting.",
         "ban_list_info": "See a list of banned IPs below: <b>network (remaining ban time) - [actions]</b>.<br />IPs queued to be unbanned will be removed from the active ban list within a few seconds.<br />Red labels indicate active permanent bans by blacklisting.",