* 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
This commit is contained in:
parent
fa286e966d
commit
f30b4ab2b5
@ -30,8 +30,11 @@ use SrvMngr::Plugin::WithoutCache;
|
|||||||
|
|
||||||
use esmith::I18N;
|
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"
|
#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
|
#Extract the release value
|
||||||
if ($VERSION =~ /^(\d+)/) {
|
if ($VERSION =~ /^(\d+)/) {
|
||||||
$VERSION = $1; # $1 contains the matched numeric digits
|
$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
|
getNavigation ip_number validate_password is_normal_password email_simple
|
||||||
mac_address_or_blank mac_address ip_number_or_blank
|
mac_address_or_blank mac_address ip_number_or_blank
|
||||||
lang_space get_routes_list subnet_mask get_reg_mask
|
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 {
|
has home => sub {
|
||||||
@ -302,8 +305,9 @@ sub setup_routing {
|
|||||||
$if_logged_in->post('/userpassword')->to('userpassword#change_password')->name('passwd2');
|
$if_logged_in->post('/userpassword')->to('userpassword#change_password')->name('passwd2');
|
||||||
|
|
||||||
my $if_admin = $r->under( sub {
|
my $if_admin = $r->under( sub {
|
||||||
my $c =shift;
|
my $c = shift;
|
||||||
return $c->is_admin || $c->auth_fail($c->l("acs_ADMIN"));
|
# 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->get('/backup')->to('backup#main')->name('backup');
|
||||||
@ -549,9 +553,10 @@ sub getNavigation {
|
|||||||
|
|
||||||
use esmith::NavigationDB;
|
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 $lang = shift || 'en-us';
|
||||||
my $menu = shift || 'N';
|
my $menu = shift || 'N';
|
||||||
|
my $username = shift || ''; #Username when logged in as a user not admin
|
||||||
|
|
||||||
# my $lang = $c->session->{lang} || 'en-us';
|
# my $lang = $c->session->{lang} || 'en-us';
|
||||||
|
|
||||||
@ -561,6 +566,26 @@ sub getNavigation {
|
|||||||
my @files = ();
|
my @files = ();
|
||||||
my %files_hash = ();
|
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
|
# Determine the directory where the functions are kept
|
||||||
#-----------------------------------------------------
|
#-----------------------------------------------------
|
||||||
@ -659,6 +684,23 @@ sub getNavigation {
|
|||||||
$urlpath = $rec->prop('UrlPath') || '';
|
$urlpath = $rec->prop('UrlPath') || '';
|
||||||
$menucat = $rec->prop('MenuCat') || 'A'; # admin menu (default)
|
$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;
|
||||||
|
}
|
||||||
|
|
||||||
next if $menu ne $menucat;
|
next if $menu ne $menucat;
|
||||||
|
|
||||||
#--------------------------------------------------
|
#--------------------------------------------------
|
||||||
@ -702,6 +744,29 @@ sub getNavigation {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
sub _lang_space {
|
||||||
|
|
||||||
|
99
root/usr/share/smanager/lib/SrvMngr_Auth.pm
Normal file
99
root/usr/share/smanager/lib/SrvMngr_Auth.pm
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
# 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 $panel eq lc($allowed_panel); #Controller files are capitalised, but that is lost in panel id.
|
||||||
|
}
|
||||||
|
|
||||||
|
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 );
|
% use SrvMngr qw( getNavigation simpleNavMerge );
|
||||||
% my %nav = %{SrvMngr->getNavigation( $c->languages(), 'U' )};
|
% 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'>
|
<div id='usermenu'>
|
||||||
<a href='#' id='toguser' class='section section-title'>Current User (<%= session 'username' %>)</a>
|
<a href='#' id='toguser' class='section section-title'>Current User (<%= session 'username' %>)</a>
|
||||||
@ -10,9 +12,7 @@
|
|||||||
<!-- div class='section'><%= $h %></div -->
|
<!-- div class='section'><%= $h %></div -->
|
||||||
% my ($classNew, $target, $href) = '';
|
% my ($classNew, $target, $href) = '';
|
||||||
% foreach (sort { $a->{'WEIGHT'} <=> $b->{'WEIGHT'} } @{$nav{$h}{'DESCRIPTIONS'}}) {
|
% foreach (sort { $a->{'WEIGHT'} <=> $b->{'WEIGHT'} } @{$nav{$h}{'DESCRIPTIONS'}}) {
|
||||||
|
% next if ($_->{'MENUCAT'} ne 'A' && $_->{'MENUCAT'} ne 'U' ); # menu User
|
||||||
% next if ($_->{'MENUCAT'} ne 'U' ); # menu User
|
|
||||||
|
|
||||||
% if ( $_->{'FILENAME'} =~ m/^2\// ) {
|
% if ( $_->{'FILENAME'} =~ m/^2\// ) {
|
||||||
% $target = '_self';
|
% $target = '_self';
|
||||||
% (my $file2 = $_->{'FILENAME'}) =~ s|^2/||;
|
% (my $file2 = $_->{'FILENAME'}) =~ s|^2/||;
|
||||||
|
@ -2,7 +2,7 @@ Summary: Sme server navigation module : manager 2
|
|||||||
%define name smeserver-manager
|
%define name smeserver-manager
|
||||||
Name: %{name}
|
Name: %{name}
|
||||||
%define version 11.0.0
|
%define version 11.0.0
|
||||||
%define release 78
|
%define release 79
|
||||||
Version: %{version}
|
Version: %{version}
|
||||||
Release: %{release}%{?dist}
|
Release: %{release}%{?dist}
|
||||||
License: GPL
|
License: GPL
|
||||||
@ -143,6 +143,9 @@ true
|
|||||||
%defattr(-,root,root)
|
%defattr(-,root,root)
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* 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
|
* Thu Apr 17 2025 Brian Read <brianr@koozali.org> 11.0.0-78.sme
|
||||||
- typo in remoteaccess panel
|
- typo in remoteaccess panel
|
||||||
- Fix crash in veiwlogfiles if viewlogfiles key not in DB
|
- Fix crash in veiwlogfiles if viewlogfiles key not in DB
|
||||||
|
Loading…
x
Reference in New Issue
Block a user