From 0dd927a559ced87f81cede020c80b4aa5d4d4f2b Mon Sep 17 00:00:00 2001 From: Jamie Cameron Date: Wed, 15 Jan 2014 15:55:14 -0800 Subject: [PATCH] Allow multiple users to be added to a group http://virtualmin.com/node/32070 --- acl/CHANGELOG | 2 ++ acl/acl-lib.pl | 16 +++++++++++++ acl/delete_users.cgi | 56 ++++++++++++++++++++++++++++++++++++++++++-- acl/index.cgi | 9 +++++-- acl/lang/en | 2 ++ acl/log_parser.pl | 3 +++ 6 files changed, 84 insertions(+), 4 deletions(-) diff --git a/acl/CHANGELOG b/acl/CHANGELOG index 0b27ecbea..585562132 100644 --- a/acl/CHANGELOG +++ b/acl/CHANGELOG @@ -62,3 +62,5 @@ Added support for two-factor authentication using Authy or Google Authenticator. ---- Changes since 1.660 ---- Converted all pages to use the common Webmin UI library for a more consistent interface. Made all code Perl strict and warnings compliant. +---- Changes since 1.670 ---- +Added a button for adding multiple Webmin users to a group. diff --git a/acl/acl-lib.pl b/acl/acl-lib.pl index 0744afb41..b00dff779 100755 --- a/acl/acl-lib.pl +++ b/acl/acl-lib.pl @@ -1715,6 +1715,22 @@ foreach my $g (&list_groups()) { } } +=head2 get_users_group(username) + +Returns the group a user is in, if any + +=cut +sub get_users_group +{ +my ($username) = @_; +foreach my $g (&list_groups()) { + my @mems = @{$g->{'members'} || []}; + if (&indexof($username, @mems) >= 0) { + return $g; + } + } +} + =head2 check_password_restrictions(username, password) Checks if some new password is valid for a user, and if not returns diff --git a/acl/delete_users.cgi b/acl/delete_users.cgi index 06112003e..c805db66a 100755 --- a/acl/delete_users.cgi +++ b/acl/delete_users.cgi @@ -1,5 +1,5 @@ #!/usr/local/bin/perl -# Delete a bunch of Webmin users +# Delete a bunch of Webmin users, or add them to a group use strict; use warnings; @@ -21,7 +21,59 @@ foreach my $user (@d) { $uinfo->{'readonly'} && &error($text{'udeletes_ereadonly'}); } -if ($in{'confirm'}) { +if ($in{'joingroup'}) { + # Add users to a group + my $newgroup = &get_group($in{'group'}); + foreach my $user (@d) { + my $uinfo = &get_user($user); + next if (!$uinfo); + next if (&indexof($user, @{$newgroup->{'members'}}) >= 0); + + # Remove from old group, if any + my $oldgroup = &get_users_group($user); + if ($oldgroup) { + $oldgroup->{'members'} = + [ grep { $_ ne $user } + @{$oldgroup->{'members'}} ]; + &modify_group($oldgroup->{'name'}, $oldgroup); + } + + # Add to new group + push(@{$newgroup->{'members'}}, $user); + &modify_group($newgroup->{'name'}, $newgroup); + + my @mods = @{$uinfo->{'modules'}}; + if ($oldgroup) { + # Remove modules from the old group + @mods = grep { &indexof($_, @{$oldgroup->{'modules'}}) + < 0 } @mods; + } + + if ($newgroup) { + # Add modules from group to list + my @ownmods; + foreach my $m (@mods) { + push(@ownmods, $m) if (&indexof($m, + @{$newgroup->{'modules'}}) < 0); + } + @mods = &unique(@mods, @{$newgroup->{'modules'}}); + $uinfo->{'ownmods'} = \@ownmods; + + # Copy ACL files for group + ©_group_user_acl_files($in{'group'}, $user, + [ @{$newgroup->{'modules'}}, "" ]); + } + $uinfo->{'modules'} = \@mods; + + # Save the user + &modify_user($user, $uinfo); + } + + &webmin_log("joingroup", "users", scalar(@d), + { 'group' => $in{'group'} }); + &redirect(""); + } +elsif ($in{'confirm'}) { # Do it foreach my $user (@d) { &delete_user($user); diff --git a/acl/index.cgi b/acl/index.cgi index c9507b314..3a7c0b16f 100755 --- a/acl/index.cgi +++ b/acl/index.cgi @@ -44,6 +44,9 @@ foreach my $m (&list_module_infos()) { } my @canulist = grep { &can_edit_user($_->{'name'}, \@glist) } @ulist; my ($form, $shown_users); +my @gbut = @glist ? ( undef, [ 'joingroup', $text{'index_joingroup'}, + &ui_select("group", undef, [ map { $_->{'name'} } @glist ]) ] ) + : ( ); if (!@canulist) { # If no users, only show section heading if can create if ($access{'create'}) { @@ -61,7 +64,8 @@ elsif ($config{'display'}) { &show_name_table(\@canulist, "edit_user.cgi", $access{'create'} ? $text{'index_create'} : undef, $text{'index_users'}, "user"); - print &ui_form_end([ [ "delete", $text{'index_delete'} ] ]); + print &ui_form_end([ [ "delete", $text{'index_delete'} ], + @gbut ]); $shown_users = 1; $form++; } @@ -101,7 +105,8 @@ else { print &ui_columns_end(); print &ui_links_row(\@rowlinks); if (!$config{'select'}) { - print &ui_form_end([ [ "delete", $text{'index_delete'} ] ]); + print &ui_form_end([ [ "delete", $text{'index_delete'} ], + @gbut ]); } $shown_users = 1; $form++; diff --git a/acl/lang/en b/acl/lang/en index b6507000e..b7bf251f2 100644 --- a/acl/lang/en +++ b/acl/lang/en @@ -24,6 +24,7 @@ index_unix=Configure Unix User Authentication index_sessions=View Login Sessions index_rbac=Setup RBAC index_delete=Delete Selected +index_joingroup=Add To Group: index_eulist=Failed to list users : $1 index_eglist=Failed to list groups : $1 @@ -230,6 +231,7 @@ log_delete_g=Deleted Webmin group $1 log_switch=Switched to Webmin user $1 log_delete_users=Deleted $1 Webmin users log_delete_groups=Deleted $1 Webmin groups +log_joingroup=Added $1 Webmin users to group $2 log_pass=Changed password restrictions log_unix=Changed unix user authentication log_sync=Changed unix user synchronization diff --git a/acl/log_parser.pl b/acl/log_parser.pl index 86e290095..2179115db 100755 --- a/acl/log_parser.pl +++ b/acl/log_parser.pl @@ -40,6 +40,9 @@ elsif ($action eq 'delete') { return &text('log_delete'.$g, "$object"); } } +elsif ($action eq 'joingroup') { + return &text('log_joingroup', $object, $p->{'group'}); + } elsif ($action eq 'acl') { return &text('log_acl', "$object", "".&html_escape($p->{'moddesc'})."");