Browse Source

Merge branch 'feature/disable-user-login' into feature/user-roles

Kristan Kenney 5 years ago
parent
commit
281fb0f81c

+ 3 - 0
bin/v-add-user

@@ -238,6 +238,9 @@ LANGUAGE=''
 THEME=''
 NOTIFICATIONS='no'
 PREF_UI_SORT='name'
+LOGIN_DISABLED='no'
+LOGIN_USE_IPLIST='no'
+LOGIN_ALLOW_IPS=''
 TIME='$time'
 DATE='$date'" > $USER_DATA/user.conf
 chmod 660 $USER_DATA/user.conf

+ 55 - 0
bin/v-change-user-config-value

@@ -0,0 +1,55 @@
+#!/bin/bash
+# info: changes user configuration value
+# options: USER KEY VALUE
+# labels: hestia
+#
+# example: v-change-user-config-value admin ROLE admin
+#
+# Changes key/value for specified user.
+
+#----------------------------------------------------------#
+#                    Variable&Function                     #
+#----------------------------------------------------------#
+
+# Argument definition
+user=$1
+key="$2"
+value="$3"
+
+# Includes
+# shellcheck source=/usr/local/hestia/func/main.sh
+source $HESTIA/func/main.sh
+# shellcheck source=/usr/local/hestia/conf/hestia.conf
+source $HESTIA/conf/hestia.conf
+
+#----------------------------------------------------------#
+#                    Verifications                         #
+#----------------------------------------------------------#
+
+# Reading user values
+source $USER_DATA/user.conf
+
+is_format_valid 'user' 'theme'
+is_object_valid 'user' 'USER' "$user"
+is_object_unsuspended 'user' 'USER' "$user"
+
+# Perform verification if read-only mode is enabled
+check_hestia_demo_mode
+
+#----------------------------------------------------------#
+#                       Action                             #
+#----------------------------------------------------------#
+
+# Set theme value
+check_ckey=$(grep "^${key^^}" $USER_DATA/user.conf)
+if [ -z "$check_ckey" ]; then
+    # Rebuild user configuration to repair missing value
+    $BIN/v-rebuild-user $user
+fi
+update_user_value "$user" "${key^^}" "$value"
+
+#----------------------------------------------------------#
+#                       Hestia                             #
+#----------------------------------------------------------#
+
+exit

+ 3 - 0
bin/v-list-user

@@ -81,6 +81,9 @@ json_list() {
         "THEME": "'$THEME'",
         "NOTIFICATIONS": "'$NOTIFICATIONS'",
         "PREF_UI_SORT": "'$PREF_UI_SORT'",
+        "LOGIN_DISABLED": "'$LOGIN_DISABLED'",
+        "LOGIN_USE_IPLIST": "'$LOGIN_USE_IPLIST'",
+        "LOGIN_ALLOW_IPS": "'$LOGIN_ALLOW_IPS'",
         "PHPCLI": "'$PHPCLI'",
         "TIME": "'$TIME'",
         "DATE": "'$DATE'"

+ 10 - 0
func/rebuild.sh

@@ -42,6 +42,16 @@ rebuild_user_conf() {
     if [ -z "${PREF_UI_SORT+x}" ]; then 
         sed -i "/NOTIFICATIONS/a PREF_UI_SORT='name'" $USER_DATA/user.conf 
     fi
+    if [ -z "${LOGIN_DISABLED+x}" ]; then 
+        sed -i "/PREF_UI_SORT/a LOGIN_DISABLED=''" $USER_DATA/user.conf 
+    fi
+    if [ -z "${LOGIN_USE_IPLIST+x}" ]; then 
+        sed -i "/LOGIN_DISABLED/a LOGIN_USE_IPLIST=''" $USER_DATA/user.conf 
+    fi
+    if [ -z "${LOGIN_ALLOW_IPS+x}" ]; then 
+        sed -i "/LOGIN_USE_IPLIST/a LOGIN_ALLOW_IPS=''" $USER_DATA/user.conf 
+    fi
+
     # Run template trigger
     if [ -x "$HESTIA/data/packages/$PACKAGE.sh" ]; then
         $HESTIA/data/packages/$PACKAGE.sh "$user" "$CONTACT" "$NAME"

+ 10 - 0
web/add/user/index.php

@@ -85,6 +85,16 @@ if (!empty($_POST['ok'])) {
         unset($output);
     }
 
+    // Set login restriction
+    if (empty($_SESSION['error_msg'])) {
+        if ($_POST['v_login_disabled']) {
+            if ($_POST['v_login_disabled'] == 'on') { $_POST['v_login_disabled'] = 'yes'; } else { $_POST['v_login_disabled'] = 'no'; }
+            exec (HESTIA_CMD."v-change-user-config-value ".$v_username." LOGIN_DISABLED ".escapeshellarg($_POST['v_login_disabled']), $output, $return_var);
+            check_return_code($return_var,$output);
+            unset($output);
+        }
+    }
+
     // Send email to the new user
     if ((empty($_SESSION['error_msg'])) && (!empty($v_notify))) {
         $to = $_POST['v_notify'];

+ 32 - 0
web/edit/user/index.php

@@ -53,6 +53,9 @@ $v_twofa = $data[$v_username]['TWOFA'];
 $v_qrcode = $data[$v_username]['QRCODE'];
 $v_phpcli = $data[$v_username]['PHPCLI'];
 $v_role = $data[$v_username]['ROLE'];
+$v_login_disabled = $data[$v_username]['LOGIN_DISABLED'];
+$v_login_use_iplist = $data[$v_username]['LOGIN_USE_IPLIST'];
+$v_login_allowed_ips = $data[$v_username]['LOGIN_ALLOW_IPS'];
 $v_ns = $data[$v_username]['NS'];
 $nameservers = explode(",", $v_ns);
 $v_ns1 = $nameservers[0];
@@ -176,6 +179,35 @@ if (!empty($_POST['save'])) {
         unset($output);
     }
 
+    // Update Control Panel login disabled status (admin only)
+    if (empty($_SESSION['error_msg'])) {
+        if ($_POST['v_login_disabled'] != $data[$user]['LOGIN_DISABLED']) {
+            if ($_POST['v_login_disabled'] == 'on') { $_POST['v_login_disabled'] = 'yes'; } else { $_POST['v_login_disabled'] = 'no'; }
+            exec (HESTIA_CMD."v-change-user-config-value ".escapeshellarg($v_username)." LOGIN_DISABLED ".escapeshellarg($_POST['v_login_disabled']), $output, $return_var);
+            check_return_code($return_var,$output);
+            $data[$user]['LOGIN_DISABLED'] = $_POST['v_login_disabled'];
+            unset($output);
+        }
+    }
+
+    // Update IP whitelist option
+    if (empty($_SESSION['error_msg'])) {
+        if ($_POST['v_login_use_iplist'] != $data[$user]['LOGIN_USE_IPLIST']) {
+            if ($_POST['v_login_use_iplist'] == 'on') { $_POST['v_login_use_iplist'] = 'yes'; } else { $_POST['v_login_use_iplist'] = 'no'; }
+            exec (HESTIA_CMD."v-change-user-config-value ".escapeshellarg($v_username)." LOGIN_USE_IPLIST ".escapeshellarg($_POST['v_login_use_iplist']), $output, $return_var);
+            if ($_POST['v_login_use_iplist'] === 'no') {
+                exec (HESTIA_CMD."v-change-user-config-value ".escapeshellarg($v_username)." LOGIN_ALLOW_IPS ''", $output, $return_var);
+                $v_login_allowed_ips = '';
+            } else {
+                exec (HESTIA_CMD."v-change-user-config-value ".escapeshellarg($v_username)." LOGIN_ALLOW_IPS ".escapeshellarg($_POST['v_login_allowed_ips']), $output, $return_var);
+                unset($v_login_allowed_ips);
+                $v_login_allowed_ips = $_POST['v_login_allowed_ips'];
+            }
+            check_return_code($return_var,$output);
+            $data[$user]['LOGIN_USE_IPLIST'] = $_POST['v_login_use_iplist'];
+            unset($output);
+        }
+    }
 
     // Change package (admin only)
     if (($v_package != $_POST['v_package']) && ($_SESSION['userContext'] === 'admin') && (empty($_SESSION['error_msg']))) {

+ 19 - 1
web/login/index.php

@@ -142,7 +142,6 @@ function authenticate_user($user, $password, $twofa = ''){
                 $error = "<a class=\"error\">"._('Invalid username or password')."</a>";
                 $v_session_id = escapeshellarg($_POST['token']);
                 exec(HESTIA_CMD."v-log-user-login ".$v_user." ".$v_ip." failed ".$v_session_id." ".$v_user_agent, $output, $return_var);
-
                 return $error;
             } else {
 
@@ -150,6 +149,25 @@ function authenticate_user($user, $password, $twofa = ''){
                 exec (HESTIA_CMD . "v-list-user ".$v_user." json", $output, $return_var);
                 $data = json_decode(implode('', $output), true);
                 unset($output); 
+                if ($data[$user]['LOGIN_DISABLED'] === 'yes') {
+                    sleep(2);
+                    $error = "<a class=\"error\">"._('Invalid username or password')."</a>";
+                    $v_session_id = escapeshellarg($_POST['token']);
+                    exec(HESTIA_CMD."v-log-user-login ".$v_user." ".$v_ip." failed ".$v_session_id." ".$v_user_agent, $output, $return_var);
+                    return $error;
+                }
+
+                if ($data[$user]['LOGIN_USE_IPLIST'] === 'yes') {
+                    $v_login_user_allowed_ips = explode(',',$data[$user]['LOGIN_ALLOW_IPS']);
+                    if (!in_array($ip,$v_login_user_allowed_ips)) {
+                        sleep(2);
+                        $error = "<a class=\"error\">"._('Invalid username or password')."</a>";
+                        $v_session_id = escapeshellarg($_POST['token']);
+                        exec(HESTIA_CMD."v-log-user-login ".$v_user." ".$v_ip." failed ".$v_session_id." ".$v_user_agent, $output, $return_var);
+                        return $error;
+                    }
+                }
+
                 if ($data[$user]['TWOFA'] != '') {
                         if(empty($twofa)){
                             $_SESSION['login']['username'] = $user;

+ 6 - 1
web/templates/pages/add_user.html

@@ -102,7 +102,12 @@
                                     </ul>
                                 </td>
                             </tr>
-                             <tr>
+                                <tr>
+                                    <td>
+                                        <label><input type="checkbox" size="20" class="vst-checkbox" onclick="javascript:elementHideShow('send-welcome');" name="v_login_disabled" <?php if ($data[$user]['LOGIN_DISABLED'] == "yes") echo "checked=yes" ?>><?php print _('Do not allow user to log in to Control Panel');?></label>
+                                    </td>
+                                </tr>
+                             <tr id="send-welcome">
                                 <td class="vst-text input-label">
                                     <label><input type="checkbox" size="20" class="vst-checkbox" name="v_email_notice" id='v_email_notify' value="" tabindex="5" /><?php print _('Send welcome email');?></label>
                                 </td>

+ 48 - 17
web/templates/pages/edit_user.html

@@ -129,24 +129,53 @@
                                     <meter max="4" id="meter"></meter>
                                 </td>
                             </tr>
-                            <tr>
-                                <td class="vst-text">
-                                    <?php print _('Your password must have at least');?>:
-                                    <ul>
-                                        <li><?php print _('8 characters long');?></li>
-                                        <li><?php print _('1 uppercase & 1 lowercase character');?></li>
-                                        <li><?php print _('1 number');?></li>
-                                    </ul>
-                                </td>
-                            </tr>
                             <tr>
                                 <td>
-                                    <label><input type="checkbox" class="vst-checkbox password-option" name="v_twofa" <?php if(!empty($v_twofa)) echo "checked=yes" ?>><?php print _('Enable 2FA');?></label>
-                                    <?php if (!empty($v_twofa)) { ?>
-                                    <p><?php echo _('2FA Reset Code:').' '.$v_twofa; ?></br></p>
-                                    <p><?php echo _('Please scan the code below in your 2FA application:'); ?></p>
-                                    <div><img class="qr-code" src="<?php echo $v_qrcode; ?>"></div>
-                                    <?php } ?>
+                                    <table id="password-details">
+                                        <tr>
+                                            <td class="vst-text">
+                                                <?php print _('Your password must have at least');?>:
+                                                <ul>
+                                                    <li><?php print _('8 characters long');?></li>
+                                                    <li><?php print _('1 uppercase & 1 lowercase character');?></li>
+                                                    <li><?php print _('1 number');?></li>
+                                                </ul>
+                                            </td>
+                                        </tr>
+                                        <? if ($_SESSION['userContext'] === 'admin') {?>
+                                            <tr>
+                                                <td>
+                                                    <label><input type="checkbox" size="20" class="vst-checkbox" onclick="javascript:elementHideShow('password-options');elementHideShow('password-options-ip');" name="v_login_disabled" <?php if ($data[$user]['LOGIN_DISABLED'] == "yes") echo "checked=yes" ?>><?php print _('Do not allow user to log in to Control Panel');?></label>
+                                                </td>
+                                            </tr>
+                                        <? } ?>
+                                        <tr>
+                                            <td id="password-options" style="<?php if ($data[$user]['LOGIN_DISABLED'] == "yes") { echo 'display: none;'; } else { echo 'display: table-cell;'; }?>">
+                                                <label><input type="checkbox" class="vst-checkbox password-option" name="v_twofa" <?php if(!empty($v_twofa)) echo "checked=yes" ?>><?php print _('Enable 2FA');?></label>
+                                                <?php if (!empty($v_twofa)) { ?>
+                                                <p><?php echo _('2FA Reset Code:').' '.$v_twofa; ?></br></p>
+                                                <p><?php echo _('Please scan the code below in your 2FA application:'); ?></p>
+                                                <div><img class="qr-code" src="<?php echo $v_qrcode; ?>"></div>
+                                                <?php } ?>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td id="password-options-ip" style="<?php if ($data[$user]['LOGIN_DISABLED'] == "yes") { echo 'display: none;'; } else { echo 'display: table-cell;'; }?>">
+                                                <label><input type="checkbox" size="20" class="vst-checkbox" onclick="javascript:elementHideShow('ip-allowlist')" name="v_login_use_iplist" <?php if ($data[$user]['LOGIN_USE_IPLIST'] === "yes") echo "checked=yes" ?>><?php print _('Use IP address allow list for login attempts');?></label>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td>
+                                                <table id="ip-allowlist" style="<? if ($data[$user]['LOGIN_USE_IPLIST'] === 'yes') { echo 'display: table-cell;'; } else { echo 'display: none;'; } ?>">
+                                                    <tr>
+                                                        <td>
+                                                            <input type="text" size="20" class="vst-input" placeholder="<?=_('Example: 127.0.0.1,192.168.1.100');?>" name="v_login_allowed_ips" value="<?=htmlentities(trim($v_login_allowed_ips, "'"))?>">
+                                                        </td>
+                                                    </tr>
+                                                </table>
+                                            </td>
+                                        </tr>
+                                    </table>
                                 </td>
                             </tr>
                             <tr>
@@ -220,9 +249,10 @@
                                 </td>
                             </tr>
                             <?}?>
+                            <? if ($_GET['user'] === $_SESSION['user']) { ?>
                             <tr>
                                 <td class="vst-text input-label">
-                                    <?php print _('Default sort order');?>
+                                    <?php print _('Default list sort order');?>
                                 </td>
                             </tr>
                             <tr>
@@ -233,6 +263,7 @@
                                     </select>
                                 </td>
                             </tr>
+                            <? } ?>
                             <? if ($_SESSION['userContext'] === 'admin') {?>
                             <tr>
                                 <td class="vst-text input-label">

+ 1 - 1
web/templates/pages/list_cron.html

@@ -23,7 +23,7 @@
                 <?=_('sort by');?>: <span>
                   <b>
                     <? if ($_SESSION['userSortOrder'] === 'name') { $label = 'Command'; } else { $label = 'Date'; } ?>
-                    <?=_($label)?><i class="fas fa-sort-alpha-down"></i>
+                    <?=_($label)?> <i class="fas fa-sort-alpha-down"></i>
                   </b>
                 </span>
               </td>

+ 1 - 1
web/templates/pages/list_db.html

@@ -41,7 +41,7 @@
                 <?=_('sort by');?>: <span>
                   <b>
                     <? if ($_SESSION['userSortOrder'] === 'name') { $label = 'Name'; } else { $label = 'Date'; } ?>
-                    <?=_($label)?><i class="fas fa-sort-alpha-down"></i>
+                    <?=_($label)?> <i class="fas fa-sort-alpha-down"></i>
                   </b>
                 </span>
               </td>

+ 1 - 1
web/templates/pages/list_dns.html

@@ -21,7 +21,7 @@
                 <?=_('sort by');?>: <span>
                   <b>
                     <? if ($_SESSION['userSortOrder'] === 'name') { $label = 'Name'; } else { $label = 'Date'; } ?>
-                    <?=_($label)?><i class="fas fa-sort-alpha-down"></i>
+                    <?=_($label)?> <i class="fas fa-sort-alpha-down"></i>
                   </b>
                 </span>
               </td>

+ 1 - 1
web/templates/pages/list_dns_rec.html

@@ -23,7 +23,7 @@
                 <?=_('sort by');?>: <span>
                   <b>
                     <? if ($_SESSION['userSortOrder'] === 'name') { $label = 'Record'; } else { $label = 'Date'; } ?>
-                    <?=_($label)?><i class="fas fa-sort-alpha-down"></i>
+                    <?=_($label)?> <i class="fas fa-sort-alpha-down"></i>
                   </b>
                 </span>
               </td>

+ 1 - 1
web/templates/pages/list_mail.html

@@ -20,7 +20,7 @@
                 <?=_('sort by');?>: <span>
                   <b>
                     <? if ($_SESSION['userSortOrder'] === 'name') { $label = 'Name'; } else { $label = 'Date'; } ?>
-                    <?=_($label)?><i class="fas fa-sort-alpha-down"></i>
+                    <?=_($label)?> <i class="fas fa-sort-alpha-down"></i>
                   </b>
                 </span>
               </td>

+ 1 - 1
web/templates/pages/list_mail_acc.html

@@ -26,7 +26,7 @@
                 <?=_('sort by');?>: <span>
                   <b>
                     <? if ($_SESSION['userSortOrder'] === 'name') { $label = 'Name'; } else { $label = 'Date'; } ?>
-                    <?=_($label)?><i class="fas fa-sort-alpha-down"></i>
+                    <?=_($label)?> <i class="fas fa-sort-alpha-down"></i>
                   </b>
                 </span>
               </td>

+ 2 - 2
web/templates/pages/list_user.html

@@ -22,8 +22,8 @@
               <td class="sort-by" title="<?=_('Sort items');?>">
                 <?=_('sort by');?>: <span>
                   <b>
-                    <? if ($_SESSION['userSortOrder'] === 'name') { $label = 'Domain'; } else { $label = 'Date'; } ?>
-                    <?=_($label)?><i class="fas fa-sort-alpha-down"></i>
+                    <? if ($_SESSION['userSortOrder'] === 'name') { $label = 'Name'; } else { $label = 'Date'; } ?>
+                    <?=_($label)?> <i class="fas fa-sort-alpha-down"></i>
                   </b>
                 </span>
               </td>

+ 1 - 1
web/templates/pages/list_web.html

@@ -21,7 +21,7 @@
                 <?=_('sort by');?>: <span>
                   <b>
                     <? if ($_SESSION['userSortOrder'] === 'name') { $label = 'Name'; } else { $label = 'Date'; } ?>
-                    <?=_($label)?><i class="fas fa-sort-alpha-down"></i>
+                    <?=_($label)?> <i class="fas fa-sort-alpha-down"></i>
                   </b>
                 </span>
               </td>