Skip to content

Commit 281fb0f

Browse files
author
Kristan Kenney
committed
Merge branch 'feature/disable-user-login' into feature/user-roles
2 parents 8c204ee + f808cc9 commit 281fb0f

File tree

17 files changed

+195
-28
lines changed

17 files changed

+195
-28
lines changed

bin/v-add-user

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,9 @@ LANGUAGE=''
238238
THEME=''
239239
NOTIFICATIONS='no'
240240
PREF_UI_SORT='name'
241+
LOGIN_DISABLED='no'
242+
LOGIN_USE_IPLIST='no'
243+
LOGIN_ALLOW_IPS=''
241244
TIME='$time'
242245
DATE='$date'" > $USER_DATA/user.conf
243246
chmod 660 $USER_DATA/user.conf

bin/v-change-user-config-value

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/bin/bash
2+
# info: changes user configuration value
3+
# options: USER KEY VALUE
4+
# labels: hestia
5+
#
6+
# example: v-change-user-config-value admin ROLE admin
7+
#
8+
# Changes key/value for specified user.
9+
10+
#----------------------------------------------------------#
11+
# Variable&Function #
12+
#----------------------------------------------------------#
13+
14+
# Argument definition
15+
user=$1
16+
key="$2"
17+
value="$3"
18+
19+
# Includes
20+
# shellcheck source=/usr/local/hestia/func/main.sh
21+
source $HESTIA/func/main.sh
22+
# shellcheck source=/usr/local/hestia/conf/hestia.conf
23+
source $HESTIA/conf/hestia.conf
24+
25+
#----------------------------------------------------------#
26+
# Verifications #
27+
#----------------------------------------------------------#
28+
29+
# Reading user values
30+
source $USER_DATA/user.conf
31+
32+
is_format_valid 'user' 'theme'
33+
is_object_valid 'user' 'USER' "$user"
34+
is_object_unsuspended 'user' 'USER' "$user"
35+
36+
# Perform verification if read-only mode is enabled
37+
check_hestia_demo_mode
38+
39+
#----------------------------------------------------------#
40+
# Action #
41+
#----------------------------------------------------------#
42+
43+
# Set theme value
44+
check_ckey=$(grep "^${key^^}" $USER_DATA/user.conf)
45+
if [ -z "$check_ckey" ]; then
46+
# Rebuild user configuration to repair missing value
47+
$BIN/v-rebuild-user $user
48+
fi
49+
update_user_value "$user" "${key^^}" "$value"
50+
51+
#----------------------------------------------------------#
52+
# Hestia #
53+
#----------------------------------------------------------#
54+
55+
exit

bin/v-list-user

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ json_list() {
8181
"THEME": "'$THEME'",
8282
"NOTIFICATIONS": "'$NOTIFICATIONS'",
8383
"PREF_UI_SORT": "'$PREF_UI_SORT'",
84+
"LOGIN_DISABLED": "'$LOGIN_DISABLED'",
85+
"LOGIN_USE_IPLIST": "'$LOGIN_USE_IPLIST'",
86+
"LOGIN_ALLOW_IPS": "'$LOGIN_ALLOW_IPS'",
8487
"PHPCLI": "'$PHPCLI'",
8588
"TIME": "'$TIME'",
8689
"DATE": "'$DATE'"

func/rebuild.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@ rebuild_user_conf() {
4242
if [ -z "${PREF_UI_SORT+x}" ]; then
4343
sed -i "/NOTIFICATIONS/a PREF_UI_SORT='name'" $USER_DATA/user.conf
4444
fi
45+
if [ -z "${LOGIN_DISABLED+x}" ]; then
46+
sed -i "/PREF_UI_SORT/a LOGIN_DISABLED=''" $USER_DATA/user.conf
47+
fi
48+
if [ -z "${LOGIN_USE_IPLIST+x}" ]; then
49+
sed -i "/LOGIN_DISABLED/a LOGIN_USE_IPLIST=''" $USER_DATA/user.conf
50+
fi
51+
if [ -z "${LOGIN_ALLOW_IPS+x}" ]; then
52+
sed -i "/LOGIN_USE_IPLIST/a LOGIN_ALLOW_IPS=''" $USER_DATA/user.conf
53+
fi
54+
4555
# Run template trigger
4656
if [ -x "$HESTIA/data/packages/$PACKAGE.sh" ]; then
4757
$HESTIA/data/packages/$PACKAGE.sh "$user" "$CONTACT" "$NAME"

web/add/user/index.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,16 @@
8585
unset($output);
8686
}
8787

88+
// Set login restriction
89+
if (empty($_SESSION['error_msg'])) {
90+
if ($_POST['v_login_disabled']) {
91+
if ($_POST['v_login_disabled'] == 'on') { $_POST['v_login_disabled'] = 'yes'; } else { $_POST['v_login_disabled'] = 'no'; }
92+
exec (HESTIA_CMD."v-change-user-config-value ".$v_username." LOGIN_DISABLED ".escapeshellarg($_POST['v_login_disabled']), $output, $return_var);
93+
check_return_code($return_var,$output);
94+
unset($output);
95+
}
96+
}
97+
8898
// Send email to the new user
8999
if ((empty($_SESSION['error_msg'])) && (!empty($v_notify))) {
90100
$to = $_POST['v_notify'];

web/edit/user/index.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@
5353
$v_qrcode = $data[$v_username]['QRCODE'];
5454
$v_phpcli = $data[$v_username]['PHPCLI'];
5555
$v_role = $data[$v_username]['ROLE'];
56+
$v_login_disabled = $data[$v_username]['LOGIN_DISABLED'];
57+
$v_login_use_iplist = $data[$v_username]['LOGIN_USE_IPLIST'];
58+
$v_login_allowed_ips = $data[$v_username]['LOGIN_ALLOW_IPS'];
5659
$v_ns = $data[$v_username]['NS'];
5760
$nameservers = explode(",", $v_ns);
5861
$v_ns1 = $nameservers[0];
@@ -176,6 +179,35 @@
176179
unset($output);
177180
}
178181

182+
// Update Control Panel login disabled status (admin only)
183+
if (empty($_SESSION['error_msg'])) {
184+
if ($_POST['v_login_disabled'] != $data[$user]['LOGIN_DISABLED']) {
185+
if ($_POST['v_login_disabled'] == 'on') { $_POST['v_login_disabled'] = 'yes'; } else { $_POST['v_login_disabled'] = 'no'; }
186+
exec (HESTIA_CMD."v-change-user-config-value ".escapeshellarg($v_username)." LOGIN_DISABLED ".escapeshellarg($_POST['v_login_disabled']), $output, $return_var);
187+
check_return_code($return_var,$output);
188+
$data[$user]['LOGIN_DISABLED'] = $_POST['v_login_disabled'];
189+
unset($output);
190+
}
191+
}
192+
193+
// Update IP whitelist option
194+
if (empty($_SESSION['error_msg'])) {
195+
if ($_POST['v_login_use_iplist'] != $data[$user]['LOGIN_USE_IPLIST']) {
196+
if ($_POST['v_login_use_iplist'] == 'on') { $_POST['v_login_use_iplist'] = 'yes'; } else { $_POST['v_login_use_iplist'] = 'no'; }
197+
exec (HESTIA_CMD."v-change-user-config-value ".escapeshellarg($v_username)." LOGIN_USE_IPLIST ".escapeshellarg($_POST['v_login_use_iplist']), $output, $return_var);
198+
if ($_POST['v_login_use_iplist'] === 'no') {
199+
exec (HESTIA_CMD."v-change-user-config-value ".escapeshellarg($v_username)." LOGIN_ALLOW_IPS ''", $output, $return_var);
200+
$v_login_allowed_ips = '';
201+
} else {
202+
exec (HESTIA_CMD."v-change-user-config-value ".escapeshellarg($v_username)." LOGIN_ALLOW_IPS ".escapeshellarg($_POST['v_login_allowed_ips']), $output, $return_var);
203+
unset($v_login_allowed_ips);
204+
$v_login_allowed_ips = $_POST['v_login_allowed_ips'];
205+
}
206+
check_return_code($return_var,$output);
207+
$data[$user]['LOGIN_USE_IPLIST'] = $_POST['v_login_use_iplist'];
208+
unset($output);
209+
}
210+
}
179211

180212
// Change package (admin only)
181213
if (($v_package != $_POST['v_package']) && ($_SESSION['userContext'] === 'admin') && (empty($_SESSION['error_msg']))) {

web/login/index.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,14 +142,32 @@ function authenticate_user($user, $password, $twofa = ''){
142142
$error = "<a class=\"error\">"._('Invalid username or password')."</a>";
143143
$v_session_id = escapeshellarg($_POST['token']);
144144
exec(HESTIA_CMD."v-log-user-login ".$v_user." ".$v_ip." failed ".$v_session_id." ".$v_user_agent, $output, $return_var);
145-
146145
return $error;
147146
} else {
148147

149148
// Get user specific parameters
150149
exec (HESTIA_CMD . "v-list-user ".$v_user." json", $output, $return_var);
151150
$data = json_decode(implode('', $output), true);
152151
unset($output);
152+
if ($data[$user]['LOGIN_DISABLED'] === 'yes') {
153+
sleep(2);
154+
$error = "<a class=\"error\">"._('Invalid username or password')."</a>";
155+
$v_session_id = escapeshellarg($_POST['token']);
156+
exec(HESTIA_CMD."v-log-user-login ".$v_user." ".$v_ip." failed ".$v_session_id." ".$v_user_agent, $output, $return_var);
157+
return $error;
158+
}
159+
160+
if ($data[$user]['LOGIN_USE_IPLIST'] === 'yes') {
161+
$v_login_user_allowed_ips = explode(',',$data[$user]['LOGIN_ALLOW_IPS']);
162+
if (!in_array($ip,$v_login_user_allowed_ips)) {
163+
sleep(2);
164+
$error = "<a class=\"error\">"._('Invalid username or password')."</a>";
165+
$v_session_id = escapeshellarg($_POST['token']);
166+
exec(HESTIA_CMD."v-log-user-login ".$v_user." ".$v_ip." failed ".$v_session_id." ".$v_user_agent, $output, $return_var);
167+
return $error;
168+
}
169+
}
170+
153171
if ($data[$user]['TWOFA'] != '') {
154172
if(empty($twofa)){
155173
$_SESSION['login']['username'] = $user;

web/templates/pages/add_user.html

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,12 @@
102102
</ul>
103103
</td>
104104
</tr>
105-
<tr>
105+
<tr>
106+
<td>
107+
<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>
108+
</td>
109+
</tr>
110+
<tr id="send-welcome">
106111
<td class="vst-text input-label">
107112
<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>
108113
</td>

web/templates/pages/edit_user.html

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -129,24 +129,53 @@
129129
<meter max="4" id="meter"></meter>
130130
</td>
131131
</tr>
132-
<tr>
133-
<td class="vst-text">
134-
<?php print _('Your password must have at least');?>:
135-
<ul>
136-
<li><?php print _('8 characters long');?></li>
137-
<li><?php print _('1 uppercase & 1 lowercase character');?></li>
138-
<li><?php print _('1 number');?></li>
139-
</ul>
140-
</td>
141-
</tr>
142132
<tr>
143133
<td>
144-
<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>
145-
<?php if (!empty($v_twofa)) { ?>
146-
<p><?php echo _('2FA Reset Code:').' '.$v_twofa; ?></br></p>
147-
<p><?php echo _('Please scan the code below in your 2FA application:'); ?></p>
148-
<div><img class="qr-code" src="<?php echo $v_qrcode; ?>"></div>
149-
<?php } ?>
134+
<table id="password-details">
135+
<tr>
136+
<td class="vst-text">
137+
<?php print _('Your password must have at least');?>:
138+
<ul>
139+
<li><?php print _('8 characters long');?></li>
140+
<li><?php print _('1 uppercase & 1 lowercase character');?></li>
141+
<li><?php print _('1 number');?></li>
142+
</ul>
143+
</td>
144+
</tr>
145+
<? if ($_SESSION['userContext'] === 'admin') {?>
146+
<tr>
147+
<td>
148+
<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>
149+
</td>
150+
</tr>
151+
<? } ?>
152+
<tr>
153+
<td id="password-options" style="<?php if ($data[$user]['LOGIN_DISABLED'] == "yes") { echo 'display: none;'; } else { echo 'display: table-cell;'; }?>">
154+
<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>
155+
<?php if (!empty($v_twofa)) { ?>
156+
<p><?php echo _('2FA Reset Code:').' '.$v_twofa; ?></br></p>
157+
<p><?php echo _('Please scan the code below in your 2FA application:'); ?></p>
158+
<div><img class="qr-code" src="<?php echo $v_qrcode; ?>"></div>
159+
<?php } ?>
160+
</td>
161+
</tr>
162+
<tr>
163+
<td id="password-options-ip" style="<?php if ($data[$user]['LOGIN_DISABLED'] == "yes") { echo 'display: none;'; } else { echo 'display: table-cell;'; }?>">
164+
<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>
165+
</td>
166+
</tr>
167+
<tr>
168+
<td>
169+
<table id="ip-allowlist" style="<? if ($data[$user]['LOGIN_USE_IPLIST'] === 'yes') { echo 'display: table-cell;'; } else { echo 'display: none;'; } ?>">
170+
<tr>
171+
<td>
172+
<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, "'"))?>">
173+
</td>
174+
</tr>
175+
</table>
176+
</td>
177+
</tr>
178+
</table>
150179
</td>
151180
</tr>
152181
<tr>
@@ -220,9 +249,10 @@
220249
</td>
221250
</tr>
222251
<?}?>
252+
<? if ($_GET['user'] === $_SESSION['user']) { ?>
223253
<tr>
224254
<td class="vst-text input-label">
225-
<?php print _('Default sort order');?>
255+
<?php print _('Default list sort order');?>
226256
</td>
227257
</tr>
228258
<tr>
@@ -233,6 +263,7 @@
233263
</select>
234264
</td>
235265
</tr>
266+
<? } ?>
236267
<? if ($_SESSION['userContext'] === 'admin') {?>
237268
<tr>
238269
<td class="vst-text input-label">

web/templates/pages/list_cron.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
<?=_('sort by');?>: <span>
2424
<b>
2525
<? if ($_SESSION['userSortOrder'] === 'name') { $label = 'Command'; } else { $label = 'Date'; } ?>
26-
<?=_($label)?><i class="fas fa-sort-alpha-down"></i>
26+
<?=_($label)?> <i class="fas fa-sort-alpha-down"></i>
2727
</b>
2828
</span>
2929
</td>

0 commit comments

Comments
 (0)