Compare commits
9 Commits
11_0_0-76_
...
11_0_0-83_
Author | SHA1 | Date | |
---|---|---|---|
2538ac9ea0 | |||
dbfeaa18a3 | |||
ced08b28d4 | |||
c74a71dee1 | |||
96b002e7a9 | |||
f30b4ab2b5 | |||
fa286e966d | |||
9bb2128891 | |||
accf96df0d |
12
createlinks
12
createlinks
@@ -8,12 +8,12 @@ use esmith::Build::CreateLinks qw(:all);
|
||||
my $mngrdir = '/usr/share/smanager';
|
||||
|
||||
# templates to expand
|
||||
for ( qw( sme_core.css sme_main.css sme_menu.css styles.css ) )
|
||||
{
|
||||
templates2events("$mngrdir/themes/default/public/css/$_", qw(
|
||||
bootstrap-console-save smeserver-manager-update
|
||||
));
|
||||
}
|
||||
#for ( qw( sme_core.css sme_main.css sme_menu.css styles.css ) )
|
||||
#{
|
||||
# templates2events("$mngrdir/themes/default/public/css/$_", qw(
|
||||
# bootstrap-console-save smeserver-manager-update
|
||||
# ));
|
||||
#}
|
||||
|
||||
templates2events("$mngrdir/conf/srvmngr.conf",
|
||||
qw( smeserver-manager-update smanager-theme-change smanager-modify bootstrap-console-save ));
|
||||
|
@@ -30,8 +30,11 @@ use SrvMngr::Plugin::WithoutCache;
|
||||
|
||||
use esmith::I18N;
|
||||
|
||||
# Import the function(s) you need
|
||||
use SrvMngr_Auth qw(check_admin_access);
|
||||
|
||||
#this is overwrittrn with the "release" by the spec file - release can be "99.el8.sme"
|
||||
our $VERSION = '70.el8.sme';
|
||||
our $VERSION = '78.el8.sme';
|
||||
#Extract the release value
|
||||
if ($VERSION =~ /^(\d+)/) {
|
||||
$VERSION = $1; # $1 contains the matched numeric digits
|
||||
@@ -46,7 +49,7 @@ our @EXPORT_OK = qw(
|
||||
getNavigation ip_number validate_password is_normal_password email_simple
|
||||
mac_address_or_blank mac_address ip_number_or_blank
|
||||
lang_space get_routes_list subnet_mask get_reg_mask
|
||||
gen_locale_date_string get_public_ip_address
|
||||
gen_locale_date_string get_public_ip_address simpleNavMerge
|
||||
);
|
||||
|
||||
has home => sub {
|
||||
@@ -301,10 +304,11 @@ sub setup_routing {
|
||||
$if_logged_in->get('/userpassword')->to('userpassword#main')->name('passwd');
|
||||
$if_logged_in->post('/userpassword')->to('userpassword#change_password')->name('passwd2');
|
||||
|
||||
my $if_admin = $r->under( sub {
|
||||
my $c =shift;
|
||||
return $c->is_admin || $c->auth_fail($c->l("acs_ADMIN"));
|
||||
});
|
||||
my $if_admin = $r->under( sub {
|
||||
my $c = shift;
|
||||
# Call the imported function directly
|
||||
return check_admin_access($c) || $c->auth_fail($c->l("acs_ADMIN"));
|
||||
});
|
||||
|
||||
$if_admin->get('/backup')->to('backup#main')->name('backup');
|
||||
$if_admin->post('/backup')->to('backup#do_display')->name('backupd');
|
||||
@@ -549,9 +553,10 @@ sub getNavigation {
|
||||
|
||||
use esmith::NavigationDB;
|
||||
|
||||
my $c = shift;
|
||||
my $class = shift; #not the controller as it is called as an external, not part of the controller.
|
||||
my $lang = shift || 'en-us';
|
||||
my $menu = shift || 'N';
|
||||
my $username = shift || ''; #Username when logged in as a user not admin
|
||||
|
||||
# my $lang = $c->session->{lang} || 'en-us';
|
||||
|
||||
@@ -560,6 +565,26 @@ sub getNavigation {
|
||||
|
||||
my @files = ();
|
||||
my %files_hash = ();
|
||||
|
||||
# Added: Store allowed admin panels for non-admin users
|
||||
my @allowed_admin_panels = ();
|
||||
my $is_admin = 1; # Default to admin (full access)
|
||||
|
||||
# Added: Check if user is non-admin and get their allowed panels
|
||||
if ($username ne '') {
|
||||
# Get the AccountsDB to check user permissions
|
||||
my $accountsdb = esmith::AccountsDB->open_ro() or
|
||||
die "Couldn't open AccountsDB\n";
|
||||
|
||||
# Check if user has AdminPanels property
|
||||
my $user_rec = $accountsdb->get($username);
|
||||
if (defined $user_rec && $user_rec->prop('AdminPanels')) {
|
||||
$is_admin = 0; # User is non-admin with specific panel access
|
||||
# Get comma-separated list of allowed admin panels
|
||||
my $admin_panels = $user_rec->prop('AdminPanels');
|
||||
@allowed_admin_panels = split(/,/, $admin_panels);
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------------------
|
||||
# Determine the directory where the functions are kept
|
||||
@@ -638,70 +663,110 @@ sub getNavigation {
|
||||
}
|
||||
|
||||
foreach my $file (keys %files_hash)
|
||||
{
|
||||
#my $heading = 'Unknown';
|
||||
my $heading = 'Legacy';
|
||||
|
||||
my $description = $file;
|
||||
my $headingWeight = 99999;
|
||||
my $descriptionWeight = 99999;
|
||||
my $urlpath = '';
|
||||
my $menucat = 'A'; # admin menu (default)
|
||||
{
|
||||
#my $heading = 'Unknown';
|
||||
my $heading = 'Legacy';
|
||||
|
||||
my $description = $file;
|
||||
my $headingWeight = 99999;
|
||||
my $descriptionWeight = 99999;
|
||||
my $urlpath = '';
|
||||
my $menucat = 'A'; # admin menu (default)
|
||||
|
||||
my $rec = $navdb->get($file);
|
||||
my $rec = $navdb->get($file);
|
||||
|
||||
if (defined $rec)
|
||||
{
|
||||
$heading = $rec->prop('Heading');
|
||||
$description = $rec->prop('Description');
|
||||
$headingWeight = $rec->prop('HeadingWeight') || 99999; #Stop noise in logs if file in dir does not have nav header.
|
||||
$descriptionWeight = $rec->prop('DescriptionWeight');
|
||||
$urlpath = $rec->prop('UrlPath') || '';
|
||||
$menucat = $rec->prop('MenuCat') || 'A'; # admin menu (default)
|
||||
}
|
||||
next if $menu ne $menucat;
|
||||
if (defined $rec)
|
||||
{
|
||||
$heading = $rec->prop('Heading');
|
||||
$description = $rec->prop('Description');
|
||||
$headingWeight = $rec->prop('HeadingWeight') || 99999; #Stop noise in logs if file in dir does not have nav header.
|
||||
$descriptionWeight = $rec->prop('DescriptionWeight');
|
||||
$urlpath = $rec->prop('UrlPath') || '';
|
||||
$menucat = $rec->prop('MenuCat') || 'A'; # admin menu (default)
|
||||
}
|
||||
|
||||
# Added: Check if this is an admin menu item and if user has access
|
||||
if ($menucat eq 'A' && !$is_admin) {
|
||||
# Skip this admin panel if user doesn't have access to it
|
||||
my $has_access = 0;
|
||||
my $file_no_ext = $file;
|
||||
$file_no_ext =~ s/\.pm$//; # Remove .pm extension if present
|
||||
foreach my $allowed_panel (@allowed_admin_panels) {
|
||||
if ($file_no_ext eq lc($allowed_panel)) {
|
||||
#die("Here!!$file $file_no_ext $allowed_panel ");
|
||||
$has_access = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
next if !$has_access;
|
||||
}
|
||||
|
||||
#--------------------------------------------------
|
||||
# add heading, description and weight information to data structure
|
||||
#--------------------------------------------------
|
||||
next if $menu ne $menucat;
|
||||
|
||||
unless (exists $nav {$heading})
|
||||
{
|
||||
$nav {$heading} = { COUNT => 0, WEIGHT => 0, DESCRIPTIONS => [] };
|
||||
}
|
||||
#--------------------------------------------------
|
||||
# add heading, description and weight information to data structure
|
||||
#--------------------------------------------------
|
||||
|
||||
$nav {$heading} {'COUNT'} ++;
|
||||
$nav {$heading} {'WEIGHT'} += $headingWeight;
|
||||
unless (exists $nav {$heading})
|
||||
{
|
||||
$nav {$heading} = { COUNT => 0, WEIGHT => 0, DESCRIPTIONS => [] };
|
||||
}
|
||||
|
||||
# Check for manager panel, and assign the appropriate
|
||||
# cgi-bin prefix for the links.
|
||||
# Grab the last 2 directories by splitting for '/'s and
|
||||
# then concatenating the last 2
|
||||
# probably a better way, but I don't know it.
|
||||
$nav {$heading} {'COUNT'} ++;
|
||||
$nav {$heading} {'WEIGHT'} += $headingWeight;
|
||||
|
||||
my $path;
|
||||
if ( $files_hash{$file} eq 'ctrl') {
|
||||
$path = "2";
|
||||
} elsif ( $files_hash{$file} eq 'cgim') {
|
||||
$path = "/cgi-bin";
|
||||
} else {
|
||||
my @filename = split /\//, $files_hash{$file};
|
||||
$path = "/$filename[scalar @filename - 2]/$filename[scalar @filename - 1]";
|
||||
};
|
||||
# Check for manager panel, and assign the appropriate
|
||||
# cgi-bin prefix for the links.
|
||||
# Grab the last 2 directories by splitting for '/'s and
|
||||
# then concatenating the last 2
|
||||
# probably a better way, but I don't know it.
|
||||
|
||||
push @{ $nav {$heading} {'DESCRIPTIONS'} },
|
||||
{ DESCRIPTION => $description,
|
||||
WEIGHT => $descriptionWeight,
|
||||
FILENAME => $urlpath ? $urlpath : "$path/$file",
|
||||
CGIPATH => $path,
|
||||
MENUCAT => $menucat
|
||||
my $path;
|
||||
if ( $files_hash{$file} eq 'ctrl') {
|
||||
$path = "2";
|
||||
} elsif ( $files_hash{$file} eq 'cgim') {
|
||||
$path = "/cgi-bin";
|
||||
} else {
|
||||
my @filename = split /\//, $files_hash{$file};
|
||||
$path = "/$filename[scalar @filename - 2]/$filename[scalar @filename - 1]";
|
||||
};
|
||||
|
||||
push @{ $nav {$heading} {'DESCRIPTIONS'} },
|
||||
{ DESCRIPTION => $description,
|
||||
WEIGHT => $descriptionWeight,
|
||||
FILENAME => $urlpath ? $urlpath : "$path/$file",
|
||||
CGIPATH => $path,
|
||||
MENUCAT => $menucat
|
||||
};
|
||||
}
|
||||
|
||||
return \%nav;
|
||||
|
||||
}
|
||||
|
||||
sub simpleNavMerge {
|
||||
#Used to merge two nav structures - used for the user and selected admin menu.
|
||||
my ($class,$nav1, $nav2) = @_;
|
||||
my %result = %$nav1; # Start with a copy of first nav
|
||||
|
||||
# Merge in second nav
|
||||
foreach my $heading (keys %$nav2) {
|
||||
if (exists $result{$heading}) {
|
||||
# Add counts and weights
|
||||
$result{$heading}{COUNT} += $nav2->{$heading}{COUNT};
|
||||
$result{$heading}{WEIGHT} += $nav2->{$heading}{WEIGHT};
|
||||
# Append descriptions
|
||||
push @{$result{$heading}{DESCRIPTIONS}}, @{$nav2->{$heading}{DESCRIPTIONS}};
|
||||
} else {
|
||||
# Just copy the heading
|
||||
$result{$heading} = $nav2->{$heading};
|
||||
}
|
||||
}
|
||||
|
||||
return \%result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub _lang_space {
|
||||
|
||||
@@ -925,4 +990,4 @@ sub get_reg_mask {
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
1;
|
||||
|
@@ -3,7 +3,7 @@ package SrvMngr::Controller::Login;
|
||||
#----------------------------------------------------------------------
|
||||
# heading : Support
|
||||
# description : Login
|
||||
# navigation : 0000 001
|
||||
# navigation : 0 200
|
||||
# menu : N
|
||||
#
|
||||
# routes : end
|
||||
|
@@ -3,7 +3,7 @@ package SrvMngr::Controller::Manual;
|
||||
#----------------------------------------------------------------------
|
||||
# heading : Support
|
||||
# description : Online manual
|
||||
# navigation : 0000 100
|
||||
# navigation : 0 300
|
||||
# menu : N
|
||||
#
|
||||
# routes : end
|
||||
|
@@ -3,7 +3,7 @@ package SrvMngr::Controller::Printers;
|
||||
#----------------------------------------------------------------------
|
||||
# heading : System
|
||||
# description : Printers
|
||||
# navigation : 4000 800
|
||||
# navigation : 4000 900
|
||||
#
|
||||
#
|
||||
# routes : end
|
||||
|
@@ -3,7 +3,7 @@ package SrvMngr::Controller::Proxy;
|
||||
#----------------------------------------------------------------------
|
||||
# heading : System
|
||||
# description : Proxy settings
|
||||
# navigation : 4000 710
|
||||
# navigation : 4000 800
|
||||
#----------------------------------------------------------------------
|
||||
#
|
||||
# routes : end
|
||||
|
@@ -30,7 +30,7 @@ our @EXPORT = qw( networkAccess_list passwordLogin_list get_ssh_permit_root_logi
|
||||
);
|
||||
|
||||
# get_pptp_sessions
|
||||
our $db = esmith::ConfigDB->open || warn "Couldn't open configuration database";
|
||||
my $db; # = esmith::ConfigDB->open || warn "Couldn't open configuration database";
|
||||
|
||||
sub main {
|
||||
my $c = shift;
|
||||
@@ -134,7 +134,7 @@ sub networkAccess_list {
|
||||
return [
|
||||
[ $c->l('rma_NO_ACCESS') => 'off' ],
|
||||
[ $c->l('NETWORKS_ALLOW_LOCAL') => 'private' ],
|
||||
[ $c->l('NETWORKS_ALLOW_PUBLIC') => 'normal' ]
|
||||
[ $c->l('NETWORKS_ALLOW_PUBLIC') => 'public' ]
|
||||
];
|
||||
} ## end sub networkAccess_list
|
||||
|
||||
@@ -144,6 +144,7 @@ sub passwordLogin_list {
|
||||
}
|
||||
|
||||
sub get_prop {
|
||||
$db = esmith::ConfigDB->open || warn "Couldn't open configuration database";
|
||||
my ($c, $item, $prop) = @_;
|
||||
warn "You must specify a record key" unless $item;
|
||||
warn "You must specify a property name" unless $prop;
|
||||
@@ -154,6 +155,8 @@ sub get_prop {
|
||||
sub get_value {
|
||||
my $c = shift;
|
||||
my $item = shift;
|
||||
$db = esmith::ConfigDB->open || warn "Couldn't open configuration database";
|
||||
$db = esmith::ConfigDB->open || warn "Couldn't open configuration database";
|
||||
return ($db->get($item)->value());
|
||||
} ## end sub get_value
|
||||
|
||||
@@ -179,8 +182,8 @@ sub get_ssh_password_auth {
|
||||
}
|
||||
|
||||
sub get_ssh_access {
|
||||
my $status = get_prop('', 'sshd', 'status');
|
||||
|
||||
my $c = shift;
|
||||
my $status = $c->get_prop('sshd', 'status');
|
||||
if (defined($status) && ($status eq 'enabled')) {
|
||||
my $access = get_prop('', 'sshd', 'access');
|
||||
$access = ($access eq 'public') ? 'public' : 'private';
|
||||
@@ -202,6 +205,7 @@ sub get_ftp_password_login_access {
|
||||
} ## end sub get_ftp_password_login_access
|
||||
|
||||
sub get_telnet_mode {
|
||||
$db = esmith::ConfigDB->open || warn "Couldn't open configuration database";
|
||||
my $telnet = $db->get('telnet');
|
||||
return ('off') unless $telnet;
|
||||
my $status = $telnet->prop('status') || 'disabled';
|
||||
@@ -211,8 +215,8 @@ sub get_telnet_mode {
|
||||
} ## end sub get_telnet_mode
|
||||
|
||||
sub get_ipsecrw_sessions {
|
||||
$db = esmith::ConfigDB->open || warn "Couldn't open configuration database";
|
||||
my $status = $db->get('ipsec')->prop('RoadWarriorStatus');
|
||||
|
||||
if (defined($status) && ($status eq 'enabled')) {
|
||||
return ($db->get('ipsec')->prop('RoadWarriorSessions') || '0');
|
||||
} else {
|
||||
@@ -221,6 +225,7 @@ sub get_ipsecrw_sessions {
|
||||
} ## end sub get_ipsecrw_sessions
|
||||
|
||||
sub get_ipsecrw_status {
|
||||
$db = esmith::ConfigDB->open || warn "Couldn't open configuration database";
|
||||
return undef unless ($db->get('ipsec'));
|
||||
return $db->get('ipsec')->prop('RoadWarriorStatus');
|
||||
}
|
||||
@@ -228,6 +233,7 @@ sub get_ipsecrw_status {
|
||||
sub pptp_and_dhcp_range {
|
||||
my $c = shift;
|
||||
my $val = shift || 0;
|
||||
$db = esmith::ConfigDB->open || warn "Couldn't open configuration database";
|
||||
my $dhcp_status = $db->get_prop('dhcpd', 'status') || 'disabled';
|
||||
my $dhcp_end = $db->get_prop('dhcpd', 'end') || '';
|
||||
my $dhcp_start = $db->get_prop('dhcpd', 'start') || '';
|
||||
@@ -245,6 +251,7 @@ sub pptp_and_dhcp_range {
|
||||
|
||||
sub _get_valid_from {
|
||||
my $c = shift;
|
||||
$db = esmith::ConfigDB->open || warn "Couldn't open configuration database";
|
||||
my $rec = $db->get('httpd-admin');
|
||||
return undef unless ($rec);
|
||||
my @vals = (split ',', ($rec->prop('ValidFrom') || ''));
|
||||
@@ -287,12 +294,12 @@ sub validate_network_and_mask {
|
||||
|
||||
sub change_settings {
|
||||
my ($c, %rma_datas) = @_;
|
||||
|
||||
$db = esmith::ConfigDB->open || warn "Couldn't open configuration database";
|
||||
#------------------------------------------------------------
|
||||
# good; go ahead and change the access.
|
||||
#------------------------------------------------------------
|
||||
$db = esmith::ConfigDB->open || warn "Couldn't open configuration database";
|
||||
my $rec = $db->get('telnet');
|
||||
|
||||
if ($rec) {
|
||||
if ($rma_datas{telnetAccess} eq "off") {
|
||||
$rec->set_prop('status', 'disabled');
|
||||
@@ -363,7 +370,7 @@ sub change_settings {
|
||||
sub set_ipsecrw_sessions {
|
||||
my $c = shift;
|
||||
my $sessions = shift;
|
||||
|
||||
$db = esmith::ConfigDB->open || warn "Couldn't open configuration database";
|
||||
if (defined $sessions) {
|
||||
$db->get('ipsec')->set_prop('RoadWarriorSessions', $sessions);
|
||||
|
||||
@@ -378,6 +385,7 @@ sub add_new_valid_from {
|
||||
my $c = shift;
|
||||
my $net = shift;
|
||||
my $mask = shift;
|
||||
$db = esmith::ConfigDB->open || warn "Couldn't open configuration database";
|
||||
|
||||
# we transform bit mask to regular mask
|
||||
$mask = get_reg_mask($net, $mask);
|
||||
@@ -400,6 +408,7 @@ sub remove_valid_from {
|
||||
my $c = shift;
|
||||
my $remove_nets = shift;
|
||||
my @remove = split /,/, $remove_nets;
|
||||
$db = esmith::ConfigDB->open || warn "Couldn't open configuration database";
|
||||
|
||||
# my @remove = $c->param('Remove_nets');
|
||||
my @vals = $c->_get_valid_from();
|
||||
@@ -430,4 +439,4 @@ sub remove_valid_from {
|
||||
$db->get('httpd-admin')->set_prop('ValidFrom', $prop);
|
||||
return 1;
|
||||
} ## end sub remove_valid_from
|
||||
1;
|
||||
1;
|
@@ -3,7 +3,7 @@ package SrvMngr::Controller::Review;
|
||||
#----------------------------------------------------------------------
|
||||
# heading : Investigation
|
||||
# description : Review configuration
|
||||
# navigation : 6000 6800
|
||||
# navigation : 7000 600
|
||||
# routes : end
|
||||
#----------------------------------------------------------------------
|
||||
use strict;
|
||||
|
@@ -1,9 +1,9 @@
|
||||
package SrvMngr::Controller::Roundcubepanel;
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# heading : System
|
||||
# heading : Network
|
||||
# description : Webmail
|
||||
# navigation : 99999 9999
|
||||
# navigation : 6000 900
|
||||
#----------------------------------------------------------------------
|
||||
#----------------------------------------------------------------------
|
||||
# name : roundcubepanel, method : get, url : /roundcubepanel, ctlact : Roundcubepanel#main
|
||||
|
@@ -3,7 +3,7 @@ package SrvMngr::Controller::Support;
|
||||
#----------------------------------------------------------------------
|
||||
# heading : Support
|
||||
# description : Support and licensing
|
||||
# navigation : 0000 200
|
||||
# navigation : 0 400
|
||||
# menu : N
|
||||
#
|
||||
# routes : end
|
||||
|
@@ -31,7 +31,8 @@ sub main {
|
||||
my %log_datas = ();
|
||||
my $title = $c->l('log_FORM_TITLE');
|
||||
my $notif = '';
|
||||
$log_datas{default_op} = ($cdb->get('viewlogfiles')->prop('DefaultOperation')) || 'view';
|
||||
my $viewlog = $cdb->get('viewlogfiles');
|
||||
$log_datas{default_op} = ($viewlog ? $viewlog->prop('DefaultOperation') : undef) || 'view';
|
||||
$c->stash(title => $title, notif => $notif, log_datas => \%log_datas);
|
||||
$c->render(template => 'viewlogfiles');
|
||||
} ## end sub main
|
||||
|
100
root/usr/share/smanager/lib/SrvMngr_Auth.pm
Normal file
100
root/usr/share/smanager/lib/SrvMngr_Auth.pm
Normal file
@@ -0,0 +1,100 @@
|
||||
# Optimized SrvMngr_Auth module using stash caching and Exporter
|
||||
|
||||
package SrvMngr_Auth;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Exporter qw(import); # Import the Exporter module
|
||||
use esmith::AccountsDB;
|
||||
|
||||
# Define functions to be exported upon request
|
||||
our @EXPORT_OK = qw(check_admin_access load_user_auth_info has_panel_access get_panel_from_path);
|
||||
|
||||
# Helper function to extract panel name from path
|
||||
sub get_panel_from_path {
|
||||
my ($path) = @_;
|
||||
|
||||
if ($path =~ m{^/([^/]+)}) {
|
||||
return $1;
|
||||
}
|
||||
|
||||
return ''; # Return empty string if no panel found
|
||||
}
|
||||
|
||||
# Load user authentication info and cache it in the stash
|
||||
sub load_user_auth_info {
|
||||
my ($c) = @_;
|
||||
|
||||
# Check if auth info is already cached in the stash
|
||||
return if exists $c->stash->{auth_info};
|
||||
|
||||
my %auth_info = (
|
||||
username => '', # Initialize username
|
||||
is_admin => 0,
|
||||
allowed_panels => [],
|
||||
);
|
||||
|
||||
# Get username from session
|
||||
$auth_info{username} = $c->session->{username} || ''; # Provide default empty string
|
||||
|
||||
# Check if user is admin
|
||||
$auth_info{is_admin} = $c->is_admin || 0;
|
||||
|
||||
# If not admin, get allowed panels
|
||||
if (!$auth_info{is_admin} && $auth_info{username}) {
|
||||
my $accountsdb = esmith::AccountsDB->open_ro();
|
||||
if ($accountsdb) {
|
||||
my $user_rec = $accountsdb->get($auth_info{username});
|
||||
# Check if the property exists before trying to get its value
|
||||
if (defined $user_rec && $user_rec->prop('AdminPanels')) {
|
||||
# Get comma-separated list of allowed admin panels
|
||||
my $admin_panels = $user_rec->prop('AdminPanels');
|
||||
$auth_info{allowed_panels} = [split(/,/, $admin_panels)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Store the calculated info in the stash
|
||||
$c->stash(auth_info => \%auth_info);
|
||||
}
|
||||
|
||||
# Check if a user has access to a specific panel (uses cached info)
|
||||
sub has_panel_access {
|
||||
my ($c, $panel) = @_;
|
||||
|
||||
# Ensure auth info is loaded
|
||||
load_user_auth_info($c);
|
||||
|
||||
my $auth_info = $c->stash->{auth_info};
|
||||
|
||||
# Check if requested panel is in allowed panels
|
||||
foreach my $allowed_panel (@{$auth_info->{allowed_panels}}) {
|
||||
return 1 if lc($panel) eq lc($allowed_panel)
|
||||
|| lc(substr($panel, 0, length($allowed_panel))) eq lc($allowed_panel);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Main function to check admin access (uses cached info)
|
||||
sub check_admin_access {
|
||||
my ($c) = @_;
|
||||
|
||||
# Ensure auth info is loaded
|
||||
load_user_auth_info($c);
|
||||
|
||||
my $auth_info = $c->stash->{auth_info};
|
||||
|
||||
# First check if user is admin
|
||||
return 1 if $auth_info->{is_admin};
|
||||
|
||||
# If not admin, check if they have access to the specific panel
|
||||
my $current_path = $c->req->url->path;
|
||||
my $requested_panel = $current_path;
|
||||
return 0 unless $requested_panel;
|
||||
|
||||
# Check if user has access to this panel using the cached info
|
||||
return has_panel_access($c, $requested_panel);
|
||||
}
|
||||
|
||||
1; # Return true value for module loading
|
@@ -1,5 +1,7 @@
|
||||
% use SrvMngr qw( getNavigation );
|
||||
% my %nav = %{SrvMngr->getNavigation( $c->languages(), 'U' )};
|
||||
% use SrvMngr qw( getNavigation simpleNavMerge );
|
||||
% my %nav1 = %{SrvMngr->getNavigation( $c->languages(), 'U' )};
|
||||
% my %nav2 = %{SrvMngr->getNavigation( $c->languages(), 'A', session('username') )};
|
||||
% my %nav = $c->session->{is_admin} ? %nav1 : %{SrvMngr->simpleNavMerge(\%nav1, \%nav2)};
|
||||
|
||||
<div id='usermenu'>
|
||||
<a href='#' id='toguser' class='section section-title'>Current User (<%= session 'username' %>)</a>
|
||||
@@ -7,26 +9,24 @@
|
||||
% my $cc = 300;
|
||||
% foreach my $h (sort { ($nav{$a}{'WEIGHT'}/$nav{$a}{'COUNT'})
|
||||
% <=> ($nav{$b}{'WEIGHT'}/$nav{$b}{'COUNT'}) } keys %nav) {
|
||||
<!-- div class='section'><%= $h %></div -->
|
||||
% my ($classNew, $target, $href) = '';
|
||||
% foreach (sort { $a->{'WEIGHT'} <=> $b->{'WEIGHT'} } @{$nav{$h}{'DESCRIPTIONS'}}) {
|
||||
|
||||
% next if ($_->{'MENUCAT'} ne 'U' ); # menu User
|
||||
|
||||
% if ( $_->{'FILENAME'} =~ m/^2\// ) {
|
||||
% $target = '_self';
|
||||
% (my $file2 = $_->{'FILENAME'}) =~ s|^2/||;
|
||||
% $href = '/smanager/' . $file2;
|
||||
% } else {
|
||||
% $target = 'main';
|
||||
% $href = '/server-manager' . $_->{'FILENAME'};
|
||||
% }
|
||||
<div class='menu-cell'><a class='item<%= $classNew %>' target='<%= $target %>'
|
||||
id='sme<%= $cc %>' href='<%= $href %>'><%= $_->{'DESCRIPTION'} %></a></div>
|
||||
<!-- div class='section'><%= $h %></div -->
|
||||
% my ($classNew, $target, $href) = '';
|
||||
% foreach (sort { $a->{'WEIGHT'} <=> $b->{'WEIGHT'} } @{$nav{$h}{'DESCRIPTIONS'}}) {
|
||||
% next if ($_->{'MENUCAT'} ne 'A' && $_->{'MENUCAT'} ne 'U' ); # menu User
|
||||
% if ( $_->{'FILENAME'} =~ m/^2\// ) {
|
||||
% $target = '_self';
|
||||
% (my $file2 = $_->{'FILENAME'}) =~ s|^2/||;
|
||||
% $href = '/smanager/' . $file2;
|
||||
% } else {
|
||||
% $target = 'main';
|
||||
% $href = '/server-manager' . $_->{'FILENAME'};
|
||||
% }
|
||||
<div class='menu-cell'><a class='item<%= $classNew %>' target='<%= $target %>'
|
||||
id='sme<%= $cc %>' href='<%= $href %>'><%= $_->{'DESCRIPTION'} %></a></div>
|
||||
% $cc++;
|
||||
% }
|
||||
% }
|
||||
|
||||
% }
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -85,7 +85,7 @@
|
||||
%= t td => (class => 'sme-border') => $net
|
||||
%= t td => (class => 'sme-border') => $mask
|
||||
%= t td => (class => 'sme-border') => $numhosts
|
||||
<td class='sme-border'><input type='checkbox' name='Remote_nets' value='<%= $net.'/'.$mask %>'> </td>
|
||||
<td class='sme-border'><input type='checkbox' name='Remove_nets' value='<%= $net.'/'.$mask %>'> </td>
|
||||
</tr>
|
||||
% }
|
||||
|
||||
|
@@ -2,7 +2,7 @@ Summary: Sme server navigation module : manager 2
|
||||
%define name smeserver-manager
|
||||
Name: %{name}
|
||||
%define version 11.0.0
|
||||
%define release 76
|
||||
%define release 83
|
||||
Version: %{version}
|
||||
Release: %{release}%{?dist}
|
||||
License: GPL
|
||||
@@ -143,6 +143,26 @@ true
|
||||
%defattr(-,root,root)
|
||||
|
||||
%changelog
|
||||
* Mon May 05 2025 Brian Read <brianr@koozali.org> 11.0.0-83.sme
|
||||
- Mod to SrvMngr-Auth to account for partials matching AdminPanels options
|
||||
|
||||
* Thu May 01 2025 Brian Read <brianr@koozali.org> 11.0.0-82.sme
|
||||
- Correct Weights for menus [SME: 12996]
|
||||
|
||||
* Wed Apr 30 2025 Brian Read <brianr@koozali.org> 11.0.0-80.sme
|
||||
- Remove expansion of css files from createlinks [SME: 12989]
|
||||
|
||||
* Wed Apr 30 2025 Brian Read <brianr@koozali.org> 11.0.0-79.sme
|
||||
- Add code in SrvMngr to take note of user panel setting
|
||||
|
||||
* Thu Apr 17 2025 Brian Read <brianr@koozali.org> 11.0.0-78.sme
|
||||
- typo in remoteaccess panel
|
||||
- Fix crash in veiwlogfiles if viewlogfiles key not in DB
|
||||
|
||||
* Sat Apr 12 2025 Brian Read <brianr@koozali.org> 11.0.0-77.sme
|
||||
- Sort out local and pulic access setting in remote panel [SME: 12988]
|
||||
- caching problem, plus confusion between normal and public setting in sshd / access in DB
|
||||
|
||||
* Fri Apr 11 2025 Brian Read <brianr@koozali.org> 11.0.0-76.sme
|
||||
- Restore css for roundcube embedded [SME: 12987]
|
||||
|
||||
|
Reference in New Issue
Block a user