[Web] Allow to skip IP check for API

master
andryyy 2020-02-16 20:08:36 +01:00
parent c7f932c587
commit 0ac4281f0e
No known key found for this signature in database
GPG Key ID: 8EC34FF2794E25EF
8 changed files with 56 additions and 13 deletions

View File

@ -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">

View File

@ -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,21 +1193,32 @@ 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`) $stmt = $pdo->prepare("INSERT INTO `api` (`api_key`, `skip_ip_check`, `active`, `allow_from`)
VALUES (:api_key, :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 ;"); 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( $stmt->execute(array(
':active' => $active, ':active' => $active,
':skip_ip_check' => $skip_ip_check,
':allow_from' => $allow_from ':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":
$api_key = implode('-', array( $api_key = implode('-', array(

View File

@ -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'"

View File

@ -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;

View File

@ -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("-");

View File

@ -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());

View File

@ -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.",

View File

@ -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.",