From 47852015f08e9155055b10d6f2f56731523e5455 Mon Sep 17 00:00:00 2001 From: Brian Read Date: Fri, 23 May 2025 08:27:55 +0100 Subject: [PATCH] Update - permissions and lex files - still WIP --- .../lib/SrvMngr/Controller/Shares-Custom.pm | 281 +++++++------- .../smanager/lib/SrvMngr/Controller/Shares.pm | 1 + .../SrvMngr/I18N/Modules/Shares/shares_en.lex | 6 +- .../partials/_sf_PERMISSIONS.html.ep | 350 ++---------------- 4 files changed, 171 insertions(+), 467 deletions(-) diff --git a/root/usr/share/smanager/lib/SrvMngr/Controller/Shares-Custom.pm b/root/usr/share/smanager/lib/SrvMngr/Controller/Shares-Custom.pm index 86978eb..2098ec7 100644 --- a/root/usr/share/smanager/lib/SrvMngr/Controller/Shares-Custom.pm +++ b/root/usr/share/smanager/lib/SrvMngr/Controller/Shares-Custom.pm @@ -199,50 +199,17 @@ my $ddb; } sub get_data_for_panel_PERMISSIONS { + # Return a hash with the fields required which will be loaded into the shared data # Return a hash with the fields required which will be loaded into the shared data my $c = shift; + my $name = $c->param('Selected'); + $adb = esmith::AccountsDB->open() || die("Couldn't open Accounts db"); + my $rec = $adb->get($name) || die("Share $name is not in DB "); my %ret = ( - 'Data1'=>'Data for PERMISSIONS', #Example - # fields from Inputs in PERMISSIONS $fields['PERMISSIONS'] - 'writegroup'=>'writegroup contents', - 'readgroup'=>'readgroup contents', - 'writegroup'=>'writegroup contents', - 'readgroup'=>'readgroup contents', - 'writegroup'=>'writegroup contents', - 'readgroup'=>'readgroup contents', - 'writegroup'=>'writegroup contents', - 'readgroup'=>'readgroup contents', - 'writegroup'=>'writegroup contents', - 'readgroup'=>'readgroup contents', - 'writeuser'=>'writeuser contents', - 'readuser'=>'readuser contents', - 'writeuser'=>'writeuser contents', - 'readuser'=>'readuser contents', - 'writeuser'=>'writeuser contents', - 'readuser'=>'readuser contents', - 'writeuser'=>'writeuser contents', - 'readuser'=>'readuser contents', - 'writeuser'=>'writeuser contents', - 'readuser'=>'readuser contents', - 'writeuser'=>'writeuser contents', - 'readuser'=>'readuser contents', - 'writeuser'=>'writeuser contents', - 'readuser'=>'readuser contents', - 'writeuser'=>'writeuser contents', - 'readuser'=>'readuser contents', - 'writeuser'=>'writeuser contents', - 'readuser'=>'readuser contents', - 'writeuser'=>'writeuser contents', - 'readuser'=>'readuser contents', - 'writeuser'=>'writeuser contents', - 'readuser'=>'readuser contents', - 'writeuser'=>'writeuser contents', - 'readuser'=>'readuser contents', - 'writeuser'=>'writeuser contents', - 'readuser'=>'readuser contents', - 'writeuser'=>'writeuser contents', - 'readuser'=>'readuser contents', - + 'Data1'=>'Data for MODIFY', #Example + # fields from Inputs in MODIFY $fields['MODIFY'] + 'name' => $name, + 'description'=>$rec->prop('Name'), ); return %ret; } @@ -326,10 +293,10 @@ sub get_Table1 { # Define a constant hash for field name mapping use constant Table2_FIELD_MAPPING => ( - 'Table2-Groups' => 'Source-for-Table2-Groups', - 'Table2-Description' => 'Source-for-Table2-Description', - 'Table2-Read / Write' => 'Source-for-Table2-Read / Write', - 'Table2-Read Only' => 'Source-for-Table2-Read Only' + 'Table2_Groups' => 'Username', + 'Table2_Description' => 'Description', + 'Table2_Read / Write' => 'WritePerms', + 'Table2_Read Only' => 'ReadPerms' #'target_field2' => 'source_field2', # Add more mappings as needed ); @@ -337,8 +304,10 @@ sub get_Table1 { sub actual_Table2 { my $c = shift; my @ret = (); - # Actual code for extracting Table2 - return @ret; + # Actual code for extracting Table2, Table3 + my $groups_ref = $c->acl_list('groups'); + my @groups = @$groups_ref; + return @groups; } sub get_Table2 { @@ -364,6 +333,48 @@ sub get_Table2 { return \@transformed_records; } + # Define a constant hash for field name mapping + use constant Table3_FIELD_MAPPING => ( + 'Table3_Users' => 'Username', + 'Table3_Description' => 'Description', + 'Table3_Read / Write' => 'WritePerms', + 'Table3_Read Only' => 'ReadPerms' + #'target_field3' => 'source_field3', + # Add more mappings as needed + ); + +sub actual_Table3 { + my $c = shift; + my @ret = (); + # Actual code for extracting Table3, Table3 - this is called twice - by table 2 and table 3 processiong (!) + my $users_ref = $c->acl_list('users'); + my @users = @$users_ref; + return @users; +} + +sub get_Table3 { + # Return an array of hashes of the contents for each row and column for Table3 + my $c = shift; + my @source_records = $c->actual_Table3(); + my @transformed_records; + my %Field_Mapping = Table3_FIELD_MAPPING(); + # Iterate over each record in the source array + for my $source_record (@source_records) { + my %transformed_record; + # Iterate over each key-value pair in the $Field_Mapping constant + while (my ($target, $source) = each %Field_Mapping) { + # Check if the source field exists in the source record + if (exists $source_record->{$source}) { + # Assign the source field value to the target field in the transformed record + $transformed_record{$target} = $source_record->{$source}; + } + } + # Add transformed record to the array if it's not empty + push @transformed_records, \%transformed_record if %transformed_record; + } + return \@transformed_records; +} + # Return hash with values from row in which link clicked on table @@ -541,7 +552,7 @@ sub get_Table2 { my $db = $cdb; #maybe one of the others my $dbkey = 'ChangeThis'; # To make it write to DB as comment, delete this (regex) string in each if statement "TRUE\) \#copy or perform with value: .* e.g." - + $ret = $c->remove_share(); if ($ret eq "") {$ret = 'ok';} return $ret; } @@ -556,116 +567,9 @@ sub create_link{ # Create a new shared folder -#sub create_share { - #my $c = shift; - #my $name = $c->param('name'); - #my $encryption = $c->param('encryption') || 'disabled'; - #my $password = $c->param('password'); - #my $password2 = $c->param('password2'); - - #my $msg = $c->validate_name($name); - - #unless ($msg eq "OK") { - #return $c->error($msg); - #} - - #$msg = $c->max_share_name_length($name); - - #unless ($msg eq "OK") { - #return $c->error($msg); - #} - - #$msg = $c->conflict_check($name); - #unless ($msg eq "OK") { - #return $c->error($msg); - #} - - #$msg = ($encryption eq 'enabled') ? $c->confirm_password($password,$password2) : 'OK'; - #unless ($msg eq "OK") { - #return $c->error($msg); - #} - - #if (my $acct = $a->new_record($name, { - #Name => $c->param('description'), - #Encryption => $encryption, - #InactivityTimeOut => ($c->param('inactivity') || ''), - #RecycleBin => $c->param('recyclebin'), - #RecycleBinRetention => $c->param('retention'), - #smbAccess => $c->param('smbaccess'), - #httpAccess => $c->param('httpaccess'), - #WebDav => $c->param('webdav'), - #Pydio => ($c->param('pydio') || 'disabled'), - #RequireSSL => $c->param('requireSSL'), - #Indexes => $c->param('indexes'), - #DynamicContent => $c->param('dynamic'), - #type => 'share', - #}) ) { - ## Untaint $name before use in system() - #$name =~ /(.+)/; $name = $1; - - #if ($encryption eq 'enabled') { - #my $source = '/home/e-smith/files/shares/' . $name . '/.store'; - #my $dest = '/home/e-smith/files/shares/' . $name . '/files'; - #File::Path::mkpath ($source); - #mkdir $dest; - #open(DIR, "| /usr/bin/encfs -S --public -o nonempty,umask=000 $source $dest > /dev/null 2>&1"); - #print DIR "\n$password"; - #close DIR; - #$c->error("ERROR_WITH_ENCRYPTION") unless( - #system("/bin/fusermount -uz $dest") == 0 - #); - #} - - #if (system ("/sbin/e-smith/signal-event", "share-create", $name) == 0) { - #$c->success("SUCCESSFULLY_CREATED_SHARE", "Permissions"); - #} - #else { - #$c->error("ERROR_WHILE_CREATING_SHARE"); - #} - #} - #else { - #$c->error('CANT_CREATE_SHARE'); - #} -#} - -## Modify a share. -## This sub shares a lot of code with create share -## It should be merged -#sub modify_share { - #my $c = shift; - #my $name = $c->param('name'); - #my $acct = $a->get($name); - - #return $c->error('CANT_FIND_SHARE') unless($acct && $acct->prop('type') eq 'share'); - - #$acct->merge_props( - #Name => $c->param('description'), - #InactivityTimeOut => ($c->param('inactivity') || ''), - #RecycleBin => $c->param('recyclebin'), - #RecycleBinRetention => $c->param('retention'), - #smbAccess => $c->param('smbaccess'), - #httpAccess => $c->param('httpaccess'), - #WebDav => $c->param('webdav'), - #Pydio => ($c->param('pydio') || 'disabled'), - #RequireSSL => $c->param('requireSSL'), - #Indexes => $c->param('indexes'), - #DynamicContent => $c->param('dynamic'), - #); - - ## Untaint $name before use in system() - #$name =~ /(.+)/; $name = $1; - #if (system ("/sbin/e-smith/signal-event", "share-modify", $name) == 0) { - #$c->success("SUCCESSFULLY_MODIFIED_SHARE"); - #} - #else { - #$c->error("ERROR_WHILE_MODIFYING_SHARE"); - #} - #return undef; -#} - sub save_share { # - # Merged the two subs + # Merged the two subs from SM1 # my $c = shift; my $name = $c->param('name'); @@ -819,7 +723,7 @@ sub modify_perm { sub remove_share { my $c = shift; $adb = esmith::AccountsDB->open() || die("Couldn't open Accounts db"); - my $name = $c->param('name'); + my $name = $c->param('Selected'); my $acct = $adb->get($name); return $c->l('sf_CANCELED','First') if ($c->param('cancel')); return $c->l('sf_CANT_FIND_SHARE') unless ($acct && $acct->prop('type') eq 'share'); @@ -938,5 +842,68 @@ sub max_share_name_length { } } +#Get arrays of users and gtroups who have read only or read/write access +sub acl_list { + my ($c, $which) = @_; + my $sharename = $c->param('Selected'); + my $adb = esmith::AccountsDB->open() || die("Couldn't open Accounts db"); + my $share = $adb->get($sharename); + return $c->l('sf_SHARE_NOT_FOUND') unless ($share); + + if ($which eq 'groups') { + my $WriteGroups = $share->prop('WriteGroups') || ''; + my $ReadGroups = $share->prop('ReadGroups') || ''; + my (%WriteGroups, %ReadGroups); + + $WriteGroups{$_} = 1 for grep { $_ } split /[,;]/, $WriteGroups; + $ReadGroups{$_} = 1 for grep { $_ } split /[,;]/, $ReadGroups; + + my @groups; + # The "shared" pseudo-group (Everyone) + push @groups, { + Username => 'shared', + Description => 'Everyone', + WritePerms => $WriteGroups{'shared'} ? 1 : 0, + ReadPerms => $ReadGroups{'shared'} ? 1 : 0 + }; + foreach my $group (sort { $a->key cmp $b->key } $adb->groups) { + my $name = $group->key; + my $desc = $group->prop('Description') || ''; + push @groups, { + Username => $name, + Description => $desc, + WritePerms => $WriteGroups{$name} ? 1 : 0, + ReadPerms => $ReadGroups{$name} ? 1 : 0 + }; + } + return \@groups; + } + elsif ($which eq 'users') { + my $WriteUsers = $share->prop('WriteUsers') || ''; + my $ReadUsers = $share->prop('ReadUsers') || ''; + my (%WriteUsers, %ReadUsers); + + $WriteUsers{$_} = 1 for grep { $_ } split /[,;]/, $WriteUsers; + $ReadUsers{$_} = 1 for grep { $_ } split /[,;]/, $ReadUsers; + + my @users; + foreach my $user (sort { $a->key cmp $b->key } $adb->users) { + my $name = $user->key; + my $desc = join(' ', grep { $_ } ($user->prop('FirstName'), $user->prop('LastName'))); + push @users, { + Username => $name, + Description => $desc, + WritePerms => $WriteUsers{$name} ? 1 : 0, + ReadPerms => $ReadUsers{$name} ? 1 : 0 + }; + } + return \@users; + } + else { + die "Invalid parameter to acl_list: must be 'groups' or 'users'"; + } +} + + 1; \ No newline at end of file diff --git a/root/usr/share/smanager/lib/SrvMngr/Controller/Shares.pm b/root/usr/share/smanager/lib/SrvMngr/Controller/Shares.pm index 0b4e5b3..9d44118 100644 --- a/root/usr/share/smanager/lib/SrvMngr/Controller/Shares.pm +++ b/root/usr/share/smanager/lib/SrvMngr/Controller/Shares.pm @@ -385,6 +385,7 @@ sub do_display { # and table control fields $c->stash(Table1=>$c->get_Table1()); $c->stash(Table2=>$c->get_Table2()); + $c->stash(Table3=>$c->get_Table3()); # Data for panel diff --git a/root/usr/share/smanager/lib/SrvMngr/I18N/Modules/Shares/shares_en.lex b/root/usr/share/smanager/lib/SrvMngr/I18N/Modules/Shares/shares_en.lex index a8caa70..8507d6d 100644 --- a/root/usr/share/smanager/lib/SrvMngr/I18N/Modules/Shares/shares_en.lex +++ b/root/usr/share/smanager/lib/SrvMngr/I18N/Modules/Shares/shares_en.lex @@ -3,6 +3,10 @@ # 'sf_readgroup' => 'regroup', 'sf_Description' => 'Description', +'sf_Users' => 'Users', +'sf_name' => 'Name of Shared Area', +'sf_Permisssions' => 'Permissions', +'sf_Modify' => 'Modify', 'sf_dynamic' => 'Dynamic', 'sf_description' => 'Description', 'sf_The_following_settings_control_the' => 'The following settings control the access of this shared folder using the HTTP/HTTPS protocol', @@ -43,4 +47,4 @@ 'sf_Read_/_Write' => 'Read / Write', 'sf_Create_or_modify_a_shared' => 'Create or modify a shared folder', 'sf_The_following_settings_control_the' => 'The following settings control the access of this shared folder from the local network Using the SMB/CIFS protocol', -'sf_recyclebin' => 'Recyclebin', +'sf_recyclebin' => 'Recyclebin', \ No newline at end of file diff --git a/root/usr/share/smanager/themes/default/templates/partials/_sf_PERMISSIONS.html.ep b/root/usr/share/smanager/themes/default/templates/partials/_sf_PERMISSIONS.html.ep index 89b398b..bd6e858 100644 --- a/root/usr/share/smanager/themes/default/templates/partials/_sf_PERMISSIONS.html.ep +++ b/root/usr/share/smanager/themes/default/templates/partials/_sf_PERMISSIONS.html.ep @@ -28,6 +28,21 @@

%=l('sf_You_can_use_this_matrix')

+ +

+ %=l('sf_name') + + % param 'name' => $sf_data->{name} unless param 'name'; + %= text_field 'name', size => '50', class => 'textinput name' , pattern=>'.*' , placeholder=>'name', title =>'Pattern regex mismatch', id => 'name_text', readonly => 1 +

+ +

+ %=l('sf_description') + + % param 'description' => $sf_data->{description} unless param 'description'; + %= text_field 'description', size => '50', class => 'textinput description' , pattern=>'.*' , placeholder=>'description', title =>'Pattern regex mismatch', id => 'description_text', readonly => 1 +

+
@@ -42,319 +57,36 @@ % my $control_data = $c->stash('Table2'); % foreach my $row (@$control_data) { - - - - + + + + + + %} + +
<%=$c->render_to_string(inline=>$row->{'Table2-Groups'})%><%=$c->render_to_string(inline=>$row->{'Table2-Description'})%><%=$c->render_to_string(inline=>$row->{'Table2-Read / Write'})%><%=$c->render_to_string(inline=>$row->{'Table2-Read Only'})%><%=$c->render_to_string(inline=>$row->{'Table2_Groups'})%><%=$c->render_to_string(inline=>$row->{'Table2_Description'})%><%=check_box 'writegroup',($row->{'Table2_Read / Write'} ? ('checked' => 1) : ())%><%=check_box 'readgroup',($row->{'Table2_Read Only'} ? ('checked' => 1) : ())%>
+ +
+ + + + + + + + + + % my $control_data = $c->stash('Table3'); + % foreach my $row (@$control_data) { + + + + + %}
<%=l('sf_Users')%><%=l('sf_Description')%><%=l('sf_Read_/_Write')%><%=l('sf_Read_Only')%>
<%=$c->render_to_string(inline=>$row->{'Table3_Users'})%><%=$c->render_to_string(inline=>$row->{'Table3_Description'})%><%=check_box 'writeuser',($row->{'Table3_Read / Write'} ? ('checked' => 1) : ())%><%=check_box 'readuser',($row->{'Table3_Read Only'} ? ('checked' => 1) : ())%>
- - -

- %=l('sf_writegroup') - - % param 'writegroup' => $sf_data->{writegroup} unless param 'writegroup'; - %=checkbox_field 'writegroup', class => 'chec110' -

- - -

- %=l('sf_readgroup') - - % param 'readgroup' => $sf_data->{readgroup} unless param 'readgroup'; - %=checkbox_field 'readgroup', class => 'chec111' -

- - -

- %=l('sf_writegroup') - - % param 'writegroup' => $sf_data->{writegroup} unless param 'writegroup'; - %=checkbox_field 'writegroup', class => 'chec112' -

- - -

- %=l('sf_readgroup') - - % param 'readgroup' => $sf_data->{readgroup} unless param 'readgroup'; - %=checkbox_field 'readgroup', class => 'chec113' -

- - -

- %=l('sf_writegroup') - - % param 'writegroup' => $sf_data->{writegroup} unless param 'writegroup'; - %=checkbox_field 'writegroup', class => 'chec114' -

- - -

- %=l('sf_readgroup') - - % param 'readgroup' => $sf_data->{readgroup} unless param 'readgroup'; - %=checkbox_field 'readgroup', class => 'chec115' -

- - -

- %=l('sf_writegroup') - - % param 'writegroup' => $sf_data->{writegroup} unless param 'writegroup'; - %=checkbox_field 'writegroup', class => 'chec116' -

- - -

- %=l('sf_readgroup') - - % param 'readgroup' => $sf_data->{readgroup} unless param 'readgroup'; - %=checkbox_field 'readgroup', class => 'chec117' -

- - -

- %=l('sf_writegroup') - - % param 'writegroup' => $sf_data->{writegroup} unless param 'writegroup'; - %=checkbox_field 'writegroup', class => 'chec118' -

- - -

- %=l('sf_readgroup') - - % param 'readgroup' => $sf_data->{readgroup} unless param 'readgroup'; - %=checkbox_field 'readgroup', class => 'chec119' -

- - -

- %=l('sf_writeuser') - - % param 'writeuser' => $sf_data->{writeuser} unless param 'writeuser'; - %=checkbox_field 'writeuser', class => 'chec120' -

- - -

- %=l('sf_readuser') - - % param 'readuser' => $sf_data->{readuser} unless param 'readuser'; - %=checkbox_field 'readuser', class => 'chec121' -

- - -

- %=l('sf_writeuser') - - % param 'writeuser' => $sf_data->{writeuser} unless param 'writeuser'; - %=checkbox_field 'writeuser', class => 'chec122' -

- - -

- %=l('sf_readuser') - - % param 'readuser' => $sf_data->{readuser} unless param 'readuser'; - %=checkbox_field 'readuser', class => 'chec123' -

- - -

- %=l('sf_writeuser') - - % param 'writeuser' => $sf_data->{writeuser} unless param 'writeuser'; - %=checkbox_field 'writeuser', class => 'chec124' -

- - -

- %=l('sf_readuser') - - % param 'readuser' => $sf_data->{readuser} unless param 'readuser'; - %=checkbox_field 'readuser', class => 'chec125' -

- - -

- %=l('sf_writeuser') - - % param 'writeuser' => $sf_data->{writeuser} unless param 'writeuser'; - %=checkbox_field 'writeuser', class => 'chec126' -

- - -

- %=l('sf_readuser') - - % param 'readuser' => $sf_data->{readuser} unless param 'readuser'; - %=checkbox_field 'readuser', class => 'chec127' -

- - -

- %=l('sf_writeuser') - - % param 'writeuser' => $sf_data->{writeuser} unless param 'writeuser'; - %=checkbox_field 'writeuser', class => 'chec128' -

- - -

- %=l('sf_readuser') - - % param 'readuser' => $sf_data->{readuser} unless param 'readuser'; - %=checkbox_field 'readuser', class => 'chec129' -

- - -

- %=l('sf_writeuser') - - % param 'writeuser' => $sf_data->{writeuser} unless param 'writeuser'; - %=checkbox_field 'writeuser', class => 'chec130' -

- - -

- %=l('sf_readuser') - - % param 'readuser' => $sf_data->{readuser} unless param 'readuser'; - %=checkbox_field 'readuser', class => 'chec131' -

- - -

- %=l('sf_writeuser') - - % param 'writeuser' => $sf_data->{writeuser} unless param 'writeuser'; - %=checkbox_field 'writeuser', class => 'chec132' -

- - -

- %=l('sf_readuser') - - % param 'readuser' => $sf_data->{readuser} unless param 'readuser'; - %=checkbox_field 'readuser', class => 'chec133' -

- - -

- %=l('sf_writeuser') - - % param 'writeuser' => $sf_data->{writeuser} unless param 'writeuser'; - %=checkbox_field 'writeuser', class => 'chec134' -

- - -

- %=l('sf_readuser') - - % param 'readuser' => $sf_data->{readuser} unless param 'readuser'; - %=checkbox_field 'readuser', class => 'chec135' -

- - -

- %=l('sf_writeuser') - - % param 'writeuser' => $sf_data->{writeuser} unless param 'writeuser'; - %=checkbox_field 'writeuser', class => 'chec136' -

- - -

- %=l('sf_readuser') - - % param 'readuser' => $sf_data->{readuser} unless param 'readuser'; - %=checkbox_field 'readuser', class => 'chec137' -

- - -

- %=l('sf_writeuser') - - % param 'writeuser' => $sf_data->{writeuser} unless param 'writeuser'; - %=checkbox_field 'writeuser', class => 'chec138' -

- - -

- %=l('sf_readuser') - - % param 'readuser' => $sf_data->{readuser} unless param 'readuser'; - %=checkbox_field 'readuser', class => 'chec139' -

- - -

- %=l('sf_writeuser') - - % param 'writeuser' => $sf_data->{writeuser} unless param 'writeuser'; - %=checkbox_field 'writeuser', class => 'chec140' -

- - -

- %=l('sf_readuser') - - % param 'readuser' => $sf_data->{readuser} unless param 'readuser'; - %=checkbox_field 'readuser', class => 'chec141' -

- - -

- %=l('sf_writeuser') - - % param 'writeuser' => $sf_data->{writeuser} unless param 'writeuser'; - %=checkbox_field 'writeuser', class => 'chec142' -

- - -

- %=l('sf_readuser') - - % param 'readuser' => $sf_data->{readuser} unless param 'readuser'; - %=checkbox_field 'readuser', class => 'chec143' -

- - -

- %=l('sf_writeuser') - - % param 'writeuser' => $sf_data->{writeuser} unless param 'writeuser'; - %=checkbox_field 'writeuser', class => 'chec144' -

- - -

- %=l('sf_readuser') - - % param 'readuser' => $sf_data->{readuser} unless param 'readuser'; - %=checkbox_field 'readuser', class => 'chec145' -

- - -

- %=l('sf_writeuser') - - % param 'writeuser' => $sf_data->{writeuser} unless param 'writeuser'; - %=checkbox_field 'writeuser', class => 'chec146' -

- - -

- %=l('sf_readuser') - - % param 'readuser' => $sf_data->{readuser} unless param 'readuser'; - %=checkbox_field 'readuser', class => 'chec147' -

- %= submit_button l('sf_Save'), class => 'action subm148'