aboutsummaryrefslogtreecommitdiffstats
path: root/lib/AdminPanel/Module
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AdminPanel/Module')
-rw-r--r--lib/AdminPanel/Module/AdminMouse.pm278
-rw-r--r--lib/AdminPanel/Module/Hosts.pm355
-rw-r--r--lib/AdminPanel/Module/Services.pm559
-rw-r--r--lib/AdminPanel/Module/Users.pm2570
4 files changed, 3762 insertions, 0 deletions
diff --git a/lib/AdminPanel/Module/AdminMouse.pm b/lib/AdminPanel/Module/AdminMouse.pm
new file mode 100644
index 00000000..9e4e37c0
--- /dev/null
+++ b/lib/AdminPanel/Module/AdminMouse.pm
@@ -0,0 +1,278 @@
+# vim: set et ts=4 sw=4:
+#*****************************************************************************
+#
+# Copyright (c) 2013 Angelo Naselli <anaselli@linux.it>
+# from drakx services
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2, as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+#*****************************************************************************
+
+package AdminPanel::Module::AdminMouse;
+
+#leaving them atm
+use lib qw(/usr/lib/libDrakX);
+
+# i18n: IMPORTANT: to get correct namespace (drakx-kbd-mouse-x11 instead of libDrakX)
+BEGIN { unshift @::textdomains, 'drakx-kbd-mouse-x11' }
+
+use common;
+use modules;
+use mouse;
+use c;
+
+use AdminPanel::Shared;
+
+use yui;
+use Moose;
+
+extends qw( AdminPanel::Module );
+
+has '+icon' => (
+ default => "/usr/share/mcc/themes/default/mousedrake-mdk.png",
+);
+
+has '+name' => (
+ default => N("AdminMouse"),
+);
+
+sub start {
+ my $self = shift;
+
+ $self->_adminMouseDialog();
+}
+
+sub _getUntranslatedName {
+ my ($self, $name, $list) = @_;
+
+ foreach my $n (@{$list}) {
+ my @names = split(/\|/, $n);
+ for (my $lev=0; $lev < scalar(@names); $lev++) {
+ if (translate($names[$lev]) eq $name) {
+ return $names[$lev];
+ }
+ }
+ }
+
+ return undef;
+}
+
+
+sub _adminMouseDialog {
+ my $self = shift;
+
+ my $datavalue = "TEST";
+
+ my $appTitle = yui::YUI::app()->applicationTitle();
+
+ ## set new title to get it in dialog
+ yui::YUI::app()->setApplicationTitle($self->name);
+ ## set icon if not already set by external launcher
+ yui::YUI::app()->setApplicationIcon($self->icon);
+
+ my $factory = yui::YUI::widgetFactory;
+
+ my $dialog = $factory->createMainDialog;
+ my $vbox = $factory->createVBox( $dialog );
+ my $frame = $factory->createFrame ($vbox, N("Please choose your type of mouse."));
+ my $treeWidget = $factory->createTree($frame, "");
+
+ my $modules_conf = modules::any_conf->read;
+
+ my $mouse = mouse::read();
+
+ if (!$::noauto) {
+ my $probed_mouse = mouse::detect($modules_conf);
+ $mouse = $probed_mouse if !$mouse->{Protocol} || !$probed_mouse->{unsafe};
+ }
+
+ if (!$mouse || !$::auto) {
+ $mouse ||= mouse::fullname2mouse('Universal|Any PS/2 & USB mice');
+
+ my $prev = my $fullname = $mouse->{type} . '|' . $mouse->{name};
+ my $selected = $mouse->{name};
+
+ my $fullList = { list => [ mouse::_fullnames() ], items => [], separator => '|', val => \$fullname,
+ format => sub { join('|', map { translate($_) } split('\|', $_[0])) } } ;
+ my $i;
+
+ my $itemColl = new yui::YItemCollection;
+ my @items;
+ for ($i=0; $i<scalar(@{$fullList->{list}}); $i++) {
+ my @names = split(/\|/, $fullList->{list}[$i]);
+ for (my $lev=0; $lev < scalar(@names); $lev++) {
+ $names[$lev] = N($names[$lev]);
+ }
+ if ($i == 0 || $names[0] ne $items[0]->{label}) {
+ if ($i != 0) {
+ $itemColl->push($items[0]->{item});
+ push @{$fullList->{items}}, $items[-1]->{item};;
+ }
+ @items = undef;
+ my $item = new yui::YTreeItem ($names[0]);
+
+ if ($selected eq $self->_getUntranslatedName($item->label(), $fullList->{list})) {
+ $item->setSelected(1) ;
+ $item->setOpen(1);
+ my $parent = $item;
+ while($parent = $parent->parent()) {
+ $parent->setOpen(1);
+ }
+ }
+ $item->DISOWN();
+ @items = ({item => $item, label => $names[0], level => 0});
+ for (my $lev=1; $lev < scalar(@names); $lev++) {
+ $item = new yui::YTreeItem ($items[$lev-1]->{item}, $names[$lev]);
+
+ if ($selected eq $self->_getUntranslatedName($item->label(), $fullList->{list})) {
+ $item->setSelected(1) ;
+ $item->setOpen(1);
+ my $parent = $item;
+ while($parent = $parent->parent()) {
+ $parent->setOpen(1);
+ }
+ }
+ $item->DISOWN();
+ if ($lev < scalar(@names)-1) {
+ push @items, {item => $item, label => $names[$lev], level => $lev};
+ }
+ }
+ }
+ else {
+ my $prevItem = 0;
+ for (my $lev=1; $lev < scalar(@names); $lev++) {
+ my $it;
+ for ($it=1; $it < scalar(@items); $it++){
+ if ($items[$it]->{label} eq $names[$lev] && $items[$it]->{level} == $lev) {
+ $prevItem = $it;
+ last;
+ }
+ }
+ if ($it == scalar(@items)) {
+ my $item = new yui::YTreeItem ($items[$prevItem]->{item}, $names[$lev]);
+
+ if ($selected eq $self->_getUntranslatedName($item->label(), $fullList->{list})) {
+ $item->setSelected(1) ;
+ $item->setOpen(1);
+ my $parent = $item;
+ while($parent = $parent->parent()) {
+ $parent->setOpen(1);
+ }
+ }
+ $item->DISOWN();
+ push @items, {item => $item, label => $names[$lev], level => $lev};
+ }
+ }
+ }
+ }
+ $itemColl->push($items[0]->{item});
+ push @{$fullList->{items}}, $items[-1]->{item};
+
+ $treeWidget->addItems($itemColl);
+ my $align = $factory->createLeft($vbox);
+ my $hbox = $factory->createHBox($align);
+ my $aboutButton = $factory->createPushButton($hbox, N("About") );
+ $align = $factory->createRight($hbox);
+ $hbox = $factory->createHBox($align);
+ my $cancelButton = $factory->createPushButton($hbox, N("Cancel") );
+ my $okButton = $factory->createPushButton($hbox, N("Ok") );
+
+ while(1) {
+ my $event = $dialog->waitForEvent();
+ my $eventType = $event->eventType();
+
+ #event type checking
+ if ($eventType == $yui::YEvent::CancelEvent) {
+ last;
+ }
+ elsif ($eventType == $yui::YEvent::WidgetEvent) {
+ # widget selected
+ my $widget = $event->widget();
+
+ if ($widget == $cancelButton) {
+ last;
+ }
+ elsif ($widget == $aboutButton) {
+ my $license = translate($AdminPanel::Shared::License);
+ AdminPanel::Shared::AboutDialog(
+ { name => N("AdminMouse"),
+ version => $self->VERSION,
+ copyright => N("Copyright (C) %s Mageia community", '2014'),
+ license => $license,
+ comments => N("AdminMouse is the Mageia mouse management tool \n(from the original idea of Mandriva mousedrake)."),
+ website => 'http://www.mageia.org',
+ website_label => N("Mageia"),
+ authors => "Angelo Naselli <anaselli\@linux.it>\nMatteo Pasotti <matteo.pasotti\@gmail.com>",
+ translator_credits =>
+ #-PO: put here name(s) and email(s) of translator(s) (eg: "John Smith <jsmith@nowhere.com>")
+ N("_: Translator(s) name(s) & email(s)\n")}
+ );
+ }
+ elsif ($widget == $okButton) {
+ my $continue = 1;
+ my $selectedItem = $treeWidget->selectedItem();
+
+ my $it=$selectedItem;
+ my $fullname = $self->_getUntranslatedName($it->label(), $fullList->{list});
+ while($it = yui::toYTreeItem($it)->parent()) {
+ $fullname = join("|", $self->_getUntranslatedName($it->label(), $fullList->{list}), $fullname);
+ }
+
+ if ($fullname ne $prev) {
+ my $mouse_ = mouse::fullname2mouse($fullname, device => $mouse->{device});
+ if ($fullname =~ /evdev/) {
+ $mouse_->{evdev_mice} = $mouse_->{evdev_mice_all} = $mouse->{evdev_mice_all};
+ }
+ %$mouse = %$mouse_;
+ }
+
+ if ($mouse->{nbuttons} < 3 ) {
+ $mouse->{Emulate3Buttons} = AdminPanel::Shared::ask_YesOrNo('', N("Emulate third button?"));
+ }
+ if ($mouse->{type} eq 'serial') {
+ my @list = ();
+ foreach (detect_devices::serialPorts()) {
+ push @list, detect_devices::serialPort2text($_);
+ }
+ my $choice = AdminPanel::Shared::ask_fromList(N("Mouse Port"),
+ N("Please choose which serial port your mouse is connected to."),
+ \@list);
+ if ( !$choice ) {
+ $continue = 0;
+ }
+ else {
+ $mouse->{device} = $choice;
+ }
+ }
+
+ if ($continue) {
+ last;
+ }
+ }
+ }
+ }
+
+ }
+
+ # TODO manage write conf without interactive things
+ # mouse::write_conf($in->do_pkgs, $modules_conf, $mouse, 1);
+ system('systemctl', 'try-restart', 'gpm.service') if -e '/usr/lib/systemd/system/gpm.service';
+
+ $dialog->destroy();
+
+ #restore old application title
+ yui::YUI::app()->setApplicationTitle($appTitle);
+}
+
+1;
diff --git a/lib/AdminPanel/Module/Hosts.pm b/lib/AdminPanel/Module/Hosts.pm
new file mode 100644
index 00000000..fe6e0117
--- /dev/null
+++ b/lib/AdminPanel/Module/Hosts.pm
@@ -0,0 +1,355 @@
+# vim: set et ts=4 sw=4:
+#*****************************************************************************
+#
+# Copyright (c) 2013-2014 Matteo Pasotti <matteo.pasotti@gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2, as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+#*****************************************************************************
+
+package AdminPanel::Module::Hosts;
+
+use Modern::Perl 2011;
+use autodie;
+use Moose;
+use POSIX qw(ceil);
+use utf8;
+
+use Glib;
+use yui;
+use AdminPanel::Shared;
+use AdminPanel::Shared::Hosts;
+
+extends qw( AdminPanel::Module );
+
+
+has '+icon' => (
+ default => "/usr/lib/libDrakX/icons/IC-Dhost-48.png"
+);
+
+has '+name' => (
+ default => "Hostmanager",
+);
+
+=head1 VERSION
+
+Version 1.0.0
+
+=cut
+
+our $VERSION = '1.0.0';
+
+has 'dialog' => (
+ is => 'rw',
+ init_arg => undef
+);
+
+has 'table' => (
+ is => 'rw',
+ init_arg => undef
+);
+
+has 'cfgHosts' => (
+ is => 'rw',
+ init_arg => undef
+);
+
+sub start {
+ my $self = shift;
+
+ $self->manageHostsDialog();
+};
+
+
+#=============================================================
+
+=head2 _addHostDialog
+
+=head3 INPUT
+
+ $self: this object
+
+=head3 DESCRIPTION
+
+This subroutine creates the Host dialog to add host definitions
+
+=cut
+
+#=============================================================
+sub _manipulateHostDialog {
+ my $self = shift;
+
+ my $headerString = shift();
+ my $boolEdit = shift();
+
+ my $hostIpString = "";
+ my $hostNameString = "";
+ my $hostAliasesString = "";
+
+ if($boolEdit == 1){
+ $hostIpString = shift();
+ $hostNameString = shift();
+ $hostAliasesString = shift();
+ }
+
+ my $factory = yui::YUI::widgetFactory;
+ my $dlg = $factory->createPopupDialog();
+ my $layout = $factory->createVBox($dlg);
+
+ my $hbox_header = $factory->createHBox($layout);
+ my $vbox_content = $factory->createVBox($layout);
+ my $hbox_footer = $factory->createHBox($layout);
+
+ # header
+ my $labelDescription = $factory->createLabel($hbox_header,$headerString);
+
+ # content
+ my $firstHbox = $factory->createHBox($vbox_content);
+ my $secondHbox = $factory->createHBox($vbox_content);
+ my $thirdHbox = $factory->createHBox($vbox_content);
+
+ my $labelIPAddress = $factory->createLabel($firstHbox,"IP Address");
+ my $labelHostName = $factory->createLabel($secondHbox,"Hostname");
+ my $labelHostAlias = $factory->createLabel($thirdHbox,"Host aliases");
+ $labelIPAddress->setWeight($yui::YD_HORIZ, 10);
+ $labelHostName->setWeight($yui::YD_HORIZ, 10);
+ $labelHostAlias->setWeight($yui::YD_HORIZ, 10);
+
+ my $textIPAddress = $factory->createInputField($firstHbox,"");
+ my $textHostName = $factory->createInputField($secondHbox,"");
+ my $textHostAlias = $factory->createInputField($thirdHbox,"");
+ $textIPAddress->setWeight($yui::YD_HORIZ, 30);
+ $textHostName->setWeight($yui::YD_HORIZ, 30);
+ $textHostAlias->setWeight($yui::YD_HORIZ, 30);
+
+ if($boolEdit == 1){
+ $textIPAddress->setValue($hostIpString);
+ $textHostName->setValue($hostNameString);
+ $textHostAlias->setValue($hostAliasesString);
+ }
+
+ # footer
+ my $cancelButton = $factory->createPushButton($factory->createLeft($hbox_footer),"Cancel");
+ my $okButton = $factory->createPushButton($factory->createRight($hbox_footer),"OK");
+
+ while(1){
+ my $event = $dlg->waitForEvent();
+ my $eventType = $event->eventType();
+
+ #event type checking
+ if ($eventType == $yui::YEvent::CancelEvent) {
+ last;
+ }
+ elsif ($eventType == $yui::YEvent::WidgetEvent) {
+ # widget selected
+ my $widget = $event->widget();
+ if ($widget == $cancelButton) {
+ last;
+ }
+ elsif($widget == $okButton) {
+ my $res = undef;
+ my @hosts_toadd;
+ push @hosts_toadd, $textHostName->value();
+ if(trim($textHostAlias->value()) ne ""){
+ push @hosts_toadd, $textHostAlias->value();
+ }
+ print "@hosts_toadd\n";
+ if($boolEdit == 0){
+ $res = $self->cfgHosts->_insertHost($textIPAddress->value(),[@hosts_toadd]);
+ }else{
+ $res = $self->cfgHosts->_modifyHost($textIPAddress->value(),[@hosts_toadd]);
+ }
+ $res = $self->cfgHosts->_writeHosts();
+ print "Write result: $res\n";
+ last;
+ }
+ }
+ }
+
+ destroy $dlg;
+}
+
+sub _addHostDialog {
+ my $self = shift();
+ return $self->_manipulateHostDialog("Add the information",0);
+}
+
+sub _edtHostDialog {
+ my $self = shift();
+ my $hostIp = shift();
+ my $hostName = shift();
+ my $hostAliases = shift();
+ return $self->_manipulateHostDialog("Modify the information",1,$hostIp,$hostName,$hostAliases);
+}
+
+#=============================================================
+
+=head2 setupTable
+
+=head3 INPUT
+
+ $self: this object
+
+ $data: reference to the array containaing the host data to show into the table
+
+=head3 DESCRIPTION
+
+This subroutine populates a previously created YTable with the hosts data
+retrieved by the Config::Hosts module
+
+=cut
+
+#=============================================================
+sub setupTable {
+ my $self = shift();
+
+ my @hosts = $self->cfgHosts->_getHosts();
+ # clear table
+ $self->table->deleteAllItems();
+ foreach my $host (@hosts){
+ my $tblItem;
+ my $aliases = join(',',@{$host->{'hosts'}});
+ if(scalar(@{$host->{'hosts'}}) > 1){
+ $aliases =~s/^$host->{'hosts'}[0]\,*//g;
+ }elsif(scalar(@{$host->{'hosts'}}) == 1){
+ $aliases = "";
+ }
+ $tblItem = new yui::YTableItem($host->{'ip'},$host->{'hosts'}[0],$aliases);
+ $self->table->addItem($tblItem);
+ }
+}
+
+sub manageHostsDialog {
+ my $self = shift;
+
+ ## TODO fix for adminpanel
+ my $appTitle = yui::YUI::app()->applicationTitle();
+ my $appIcon = yui::YUI::app()->applicationIcon();
+ ## set new title to get it in dialog
+ my $newTitle = "Manage hosts definitions";
+ yui::YUI::app()->setApplicationTitle($newTitle);
+
+ my $factory = yui::YUI::widgetFactory;
+ my $optional = yui::YUI::optionalWidgetFactory;
+
+
+ $self->dialog($factory->createMainDialog());
+ my $layout = $factory->createVBox($self->dialog);
+
+ my $hbox_header = $factory->createHBox($layout);
+ my $headLeft = $factory->createHBox($factory->createLeft($hbox_header));
+ my $headRight = $factory->createHBox($factory->createRight($hbox_header));
+
+ my $logoImage = $factory->createImage($headLeft, $appIcon);
+ my $labelAppDescription = $factory->createLabel($headRight,$newTitle);
+ $logoImage->setWeight($yui::YD_HORIZ,0);
+ $labelAppDescription->setWeight($yui::YD_HORIZ,3);
+
+ my $hbox_content = $factory->createHBox($layout);
+
+ my $tableHeader = new yui::YTableHeader();
+ $tableHeader->addColumn("IP Address");
+ $tableHeader->addColumn("Hostname");
+ $tableHeader->addColumn("Host Aliases");
+ my $leftContent = $factory->createLeft($hbox_content);
+ $leftContent->setWeight($yui::YD_HORIZ,45);
+ $self->table($factory->createTable($leftContent,$tableHeader));
+
+ # initialize Config::Hosts
+ $self->cfgHosts(AdminPanel::Shared::Hosts->new());
+ $self->setupTable();
+
+ my $rightContent = $factory->createRight($hbox_content);
+ $rightContent->setWeight($yui::YD_HORIZ,10);
+ my $topContent = $factory->createTop($rightContent);
+ my $vbox_commands = $factory->createVBox($topContent);
+ my $addButton = $factory->createPushButton($factory->createHBox($vbox_commands),"Add");
+ my $edtButton = $factory->createPushButton($factory->createHBox($vbox_commands),"Edit");
+ my $remButton = $factory->createPushButton($factory->createHBox($vbox_commands),"Remove");
+ $addButton->setWeight($yui::YD_HORIZ,1);
+ $edtButton->setWeight($yui::YD_HORIZ,1);
+ $remButton->setWeight($yui::YD_HORIZ,1);
+
+ my $hbox_foot = $factory->createHBox($layout);
+ my $vbox_foot_left = $factory->createVBox($factory->createLeft($hbox_foot));
+ my $vbox_foot_right = $factory->createVBox($factory->createRight($hbox_foot));
+ my $aboutButton = $factory->createPushButton($vbox_foot_left,"About");
+ my $cancelButton = $factory->createPushButton($vbox_foot_right,"Cancel");
+ my $okButton = $factory->createPushButton($vbox_foot_right,"OK");
+
+ # main loop
+ while(1) {
+ my $event = $self->dialog->waitForEvent();
+ my $eventType = $event->eventType();
+
+ #event type checking
+ if ($eventType == $yui::YEvent::CancelEvent) {
+ last;
+ }
+ elsif ($eventType == $yui::YEvent::WidgetEvent) {
+### Buttons and widgets ###
+ my $widget = $event->widget();
+ if ($widget == $cancelButton) {
+ last;
+ }
+ elsif ($widget == $addButton) {
+ $self->_addHostDialog();
+ $self->setupTable();
+ }
+ elsif ($widget == $edtButton) {
+ my $tblItem = yui::toYTableItem($self->table->selectedItem());
+ if($tblItem->cellCount() >= 3){
+ $self->_edtHostDialog($tblItem->cell(0)->label(),$tblItem->cell(1)->label(),$tblItem->cell(2)->label());
+ }else{
+ $self->_edtHostDialog($tblItem->cell(0)->label(),$tblItem->cell(1)->label(),"");
+ }
+ $self->setupTable();
+ }
+ elsif ($widget == $remButton) {
+ # implement deletion dialog
+ if(AdminPanel::Shared::ask_YesOrNo("Confirmation","Are you sure to drop this host?") == 1){
+ my $tblItem = yui::toYTableItem($self->table->selectedItem());
+ # drop the host using the ip
+ $self->cfgHosts->_dropHost($tblItem->cell(0)->label());
+ # write changes
+ $self->cfgHosts->_writeHosts();
+ $self->setupTable();
+ }
+ }elsif ($widget == $aboutButton) {
+ AdminPanel::Shared::AboutDialog({
+ name => $appTitle,
+ version => $VERSION,
+ copyright => "Copyright (c) 2013-2014 by Matteo Pasotti",
+ license => $AdminPanel::Shared::License,
+ comments => "Graphical manager for hosts definitions",
+ website => "http://gitweb.mageia.org/software/adminpanel",
+ website_label => "WebSite",
+ authors => "Matteo Pasotti <matteo.pasotti\@gmail.com>"
+ }
+ );
+ }elsif ($widget == $okButton) {
+ # write changes
+ $self->cfgHosts->_writeHosts();
+ last;
+ }
+ }
+ }
+
+ $self->dialog->destroy() ;
+
+ #restore old application title
+ yui::YUI::app()->setApplicationTitle($appTitle);
+}
+
+1;
diff --git a/lib/AdminPanel/Module/Services.pm b/lib/AdminPanel/Module/Services.pm
new file mode 100644
index 00000000..33326379
--- /dev/null
+++ b/lib/AdminPanel/Module/Services.pm
@@ -0,0 +1,559 @@
+# vim: set et ts=4 sw=4:
+#*****************************************************************************
+#
+# Copyright (c) 2013 Angelo Naselli <anaselli@linux.it>
+# from drakx services
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2, as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+#*****************************************************************************
+
+package AdminPanel::Module::Services;
+
+#-######################################################################################
+#- misc imports
+#-######################################################################################
+
+use strict;
+
+# TODO same translation atm
+use lib qw(/usr/lib/libDrakX);
+use common qw(N
+ N_
+ cat_
+ formatAlaTeX
+ translate
+ find);
+use run_program;
+
+use Moose;
+
+use yui;
+use AdminPanel::Shared;
+use AdminPanel::Shared::Services qw(
+ services
+ xinetd_services
+ is_service_running
+ restart_or_start
+ stop
+ set_service
+ );
+
+use File::Basename;
+
+extends qw( AdminPanel::Module );
+
+has '+icon' => (
+ default => "/usr/share/mcc/themes/default/service-mdk.png",
+);
+
+has '+name' => (
+ default => N("AdminService"),
+);
+
+has 'services' => (
+ traits => ['Array'],
+ is => 'rw',
+ isa => 'ArrayRef[Str]',
+ default => sub { [] },
+ init_arg => undef,
+ handles => {
+ all_services => 'elements',
+ add_service => 'push',
+ map_service => 'map',
+ service_count => 'count',
+ sorted_services => 'sort',
+ },
+);
+
+has 'xinetd_services' => (
+ traits => ['Array'],
+ is => 'rw',
+ isa => 'ArrayRef[Str]',
+ default => sub { [] },
+ init_arg => undef,
+ handles => {
+ all_xinetd_services => 'elements',
+ add_xinetd_service => 'push',
+ map_xinetd_service => 'map',
+ xinetd_service_count => 'count',
+ sorted_xinetd_services => 'sort',
+ },
+);
+
+has 'on_services' => (
+ traits => ['Array'],
+ is => 'rw',
+ isa => 'ArrayRef[Str]',
+ default => sub { [] },
+ init_arg => undef,
+ handles => {
+ all_on_services => 'elements',
+ add_on_service => 'push',
+ map_on_service => 'map',
+ on_service_count => 'count',
+ sorted_on_services => 'sort',
+ },
+);
+
+
+has 'running_services' => (
+ traits => ['Array'],
+ is => 'rw',
+ isa => 'ArrayRef[Str]',
+ default => sub { [] },
+ init_arg => undef,
+ handles => {
+ all_running_services => 'elements',
+ add_running_service => 'push',
+ map_running_service => 'map',
+ running_service_count => 'count',
+ sorted_running_services => 'sort',
+ },
+);
+=head1 VERSION
+
+Version 1.0.0
+
+=cut
+
+our $VERSION = '1.0.0';
+
+
+sub description {
+ my %services = (
+acpid => N_("Listen and dispatch ACPI events from the kernel"),
+alsa => N_("Launch the ALSA (Advanced Linux Sound Architecture) sound system"),
+anacron => N_("Anacron is a periodic command scheduler."),
+apmd => N_("apmd is used for monitoring battery status and logging it via syslog.
+It can also be used for shutting down the machine when the battery is low."),
+atd => N_("Runs commands scheduled by the at command at the time specified when
+at was run, and runs batch commands when the load average is low enough."),
+'avahi-deamon' => N_("Avahi is a ZeroConf daemon which implements an mDNS stack"),
+chronyd => N_("An NTP client/server"),
+cpufreq => N_("Set CPU frequency settings"),
+crond => N_("cron is a standard UNIX program that runs user-specified programs
+at periodic scheduled times. vixie cron adds a number of features to the basic
+UNIX cron, including better security and more powerful configuration options."),
+cups => N_("Common UNIX Printing System (CUPS) is an advanced printer spooling system"),
+dm => N_("Launches the graphical display manager"),
+fam => N_("FAM is a file monitoring daemon. It is used to get reports when files change.
+It is used by GNOME and KDE"),
+g15daemon => N_("G15Daemon allows users access to all extra keys by decoding them and
+pushing them back into the kernel via the linux UINPUT driver. This driver must be loaded
+before g15daemon can be used for keyboard access. The G15 LCD is also supported. By default,
+with no other clients active, g15daemon will display a clock. Client applications and
+scripts can access the LCD via a simple API."),
+gpm => N_("GPM adds mouse support to text-based Linux applications such the
+Midnight Commander. It also allows mouse-based console cut-and-paste operations,
+and includes support for pop-up menus on the console."),
+haldaemon => N_("HAL is a daemon that collects and maintains information about hardware"),
+harddrake => N_("HardDrake runs a hardware probe, and optionally configures
+new/changed hardware."),
+httpd => N_("Apache is a World Wide Web server. It is used to serve HTML files and CGI."),
+inet => N_("The internet superserver daemon (commonly called inetd) starts a
+variety of other internet services as needed. It is responsible for starting
+many services, including telnet, ftp, rsh, and rlogin. Disabling inetd disables
+all of the services it is responsible for."),
+ip6tables => N_("Automates a packet filtering firewall with ip6tables"),
+iptables => N_("Automates a packet filtering firewall with iptables"),
+irqbalance => N_("Evenly distributes IRQ load across multiple CPUs for enhanced performance"),
+keytable => N_("This package loads the selected keyboard map as set in
+/etc/sysconfig/keyboard. This can be selected using the kbdconfig utility.
+You should leave this enabled for most machines."),
+kheader => N_("Automatic regeneration of kernel header in /boot for
+/usr/include/linux/{autoconf,version}.h"),
+kudzu => N_("Automatic detection and configuration of hardware at boot."),
+'laptop-mode' => N_("Tweaks system behavior to extend battery life"),
+linuxconf => N_("Linuxconf will sometimes arrange to perform various tasks
+at boot-time to maintain the system configuration."),
+lpd => N_("lpd is the print daemon required for lpr to work properly. It is
+basically a server that arbitrates print jobs to printer(s)."),
+lvs => N_("Linux Virtual Server, used to build a high-performance and highly
+available server."),
+mandi => N_("Monitors the network (Interactive Firewall and wireless"),
+mdadm => N_("Software RAID monitoring and management"),
+messagebus => N_("DBUS is a daemon which broadcasts notifications of system events and other messages"),
+msec => N_("Enables MSEC security policy on system startup"),
+named => N_("named (BIND) is a Domain Name Server (DNS) that is used to resolve host names to IP addresses."),
+netconsole => N_("Initializes network console logging"),
+netfs => N_("Mounts and unmounts all Network File System (NFS), SMB (Lan
+Manager/Windows), and NCP (NetWare) mount points."),
+network => N_("Activates/Deactivates all network interfaces configured to start
+at boot time."),
+'network-auth' => N_("Requires network to be up if enabled"),
+'network-up' => N_("Wait for the hotplugged network to be up"),
+nfs => N_("NFS is a popular protocol for file sharing across TCP/IP networks.
+This service provides NFS server functionality, which is configured via the
+/etc/exports file."),
+nfslock => N_("NFS is a popular protocol for file sharing across TCP/IP
+networks. This service provides NFS file locking functionality."),
+ntpd => N_("Synchronizes system time using the Network Time Protocol (NTP)"),
+numlock => N_("Automatically switch on numlock key locker under console
+and Xorg at boot."),
+oki4daemon => N_("Support the OKI 4w and compatible winprinters."),
+partmon => N_("Checks if a partition is close to full up"),
+pcmcia => N_("PCMCIA support is usually to support things like ethernet and
+modems in laptops. It will not get started unless configured so it is safe to have
+it installed on machines that do not need it."),
+portmap => N_("The portmapper manages RPC connections, which are used by
+protocols such as NFS and NIS. The portmap server must be running on machines
+which act as servers for protocols which make use of the RPC mechanism."),
+portreserve => N_("Reserves some TCP ports"),
+postfix => N_("Postfix is a Mail Transport Agent, which is the program that moves mail from one machine to another."),
+random => N_("Saves and restores system entropy pool for higher quality random
+number generation."),
+rawdevices => N_("Assign raw devices to block devices (such as hard disk drive
+partitions), for the use of applications such as Oracle or DVD players"),
+resolvconf => N_("Nameserver information manager"),
+routed => N_("The routed daemon allows for automatic IP router table updated via
+the RIP protocol. While RIP is widely used on small networks, more complex
+routing protocols are needed for complex networks."),
+rstatd => N_("The rstat protocol allows users on a network to retrieve
+performance metrics for any machine on that network."),
+rsyslog => N_("Syslog is the facility by which many daemons use to log messages to various system log files. It is a good idea to always run rsyslog."),
+rusersd => N_("The rusers protocol allows users on a network to identify who is
+logged in on other responding machines."),
+rwhod => N_("The rwho protocol lets remote users get a list of all of the users
+logged into a machine running the rwho daemon (similar to finger)."),
+saned => N_("SANE (Scanner Access Now Easy) enables to access scanners, video cameras, ..."),
+shorewall => N_("Packet filtering firewall"),
+smb => N_("The SMB/CIFS protocol enables to share access to files & printers and also integrates with a Windows Server domain"),
+sound => N_("Launch the sound system on your machine"),
+'speech-dispatcherd' => N_("layer for speech analysis"),
+sshd => N_("Secure Shell is a network protocol that allows data to be exchanged over a secure channel between two computers"),
+syslog => N_("Syslog is the facility by which many daemons use to log messages
+to various system log files. It is a good idea to always run syslog."),
+'udev-post' => N_("Moves the generated persistent udev rules to /etc/udev/rules.d"),
+usb => N_("Load the drivers for your usb devices."),
+vnStat => N_("A lightweight network traffic monitor"),
+xfs => N_("Starts the X Font Server."),
+xinetd => N_("Starts other deamons on demand."),
+ );
+ my ($name) = @_;
+ my $s = $services{$name};
+ if ($s) {
+ $s = translate($s);
+ } else {
+ my $file = "$::prefix/usr/lib/systemd/system/$name.service";
+ if (-e $file) {
+ $s = cat_($file);
+ $s = $s =~ /^Description=(.*)/mg ? $1 : '';
+ } else {
+ $file = find { -e $_ } map { "$::prefix$_/$name" } '/etc/rc.d/init.d', '/etc/init.d', '/etc/xinetd.d';
+ $s = cat_($file);
+ $s =~ s/\\\s*\n#\s*//mg;
+ $s =
+ $s =~ /^#\s+(?:Short-)?[dD]escription:\s+(.*?)^(?:[^#]|# {0,2}\S)/sm ? $1 :
+ $s =~ /^#\s*(.*?)^[^#]/sm ? $1 : '';
+
+ $s =~ s/#\s*//mg;
+ }
+ }
+ $s =~ s/\n/ /gm; $s =~ s/\s+$//;
+ $s;
+}
+
+sub BUILD {
+ my $self = shift;
+
+ $self->loadServices();
+}
+
+
+#=============================================================
+
+=head2 start
+
+=head3 INPUT
+
+ $self: this object
+
+=head3 DESCRIPTION
+
+ This method extends Module::start and is invoked to
+ start adminService
+
+=cut
+
+#=============================================================
+sub start {
+ my $self = shift;
+
+ $self->servicePanel();
+};
+
+
+#=============================================================
+
+=head2 loadServices
+
+=head3 INPUT
+
+ $self: this object
+
+=head3 DESCRIPTION
+
+ This methonds load service info into local attributes such
+ as xinetd_services, on_services and all the available,
+ services
+
+=cut
+
+#=============================================================
+sub loadServices {
+ my $self = shift;
+
+ my ($l, $on_services) = AdminPanel::Shared::Services::services();
+ my @xinetd_services = map { $_->[0] } AdminPanel::Shared::Services::xinetd_services();
+
+ $self->xinetd_services();
+ $self->xinetd_services(\@xinetd_services);
+ $self->services(\@$l);
+ $self->on_services(\@$on_services);
+
+ $self->refreshRunningServices();
+}
+
+sub refreshRunningServices {
+ my $self = shift;
+
+ my @running;
+ foreach ($self->all_services) {
+
+ my $serviceName = $_;
+ push @running, $serviceName if is_service_running($serviceName);
+ }
+ $self->running_services(\@running);
+}
+
+## serviceInfo sets widgets accordingly to selected service status
+## param
+## 'service' service name
+## 'infoPanel' service information widget
+sub serviceInfo {
+ my ($self, $service, $infoPanel) = @_;
+
+ yui::YUI::ui()->blockEvents();
+ ## infoPanel
+ $infoPanel->setValue(formatAlaTeX(description($service)));
+ yui::YUI::ui()->unblockEvents();
+}
+
+sub serviceStatus {
+ my ($self, $tbl, $item) = @_;
+
+ my $started;
+
+ if (member($item->label(), $self->all_xinetd_services)) {
+ $started = N("Start when requested");
+ }
+ else {
+ $started = (member($item->label(), $self->all_running_services)? N("running") : N("stopped"));
+ }
+# TODO add icon green/red led
+ my $cell = $tbl->toCBYTableItem($item)->cell(1);
+ if ($cell) {
+ $cell->setLabel($started);
+ $tbl->cellChanged($cell);
+ }
+}
+
+## draw service panel and manage it
+sub servicePanel {
+ my $self = shift;
+
+ my $appTitle = yui::YUI::app()->applicationTitle();
+
+ ## set new title to get it in dialog
+ yui::YUI::app()->setApplicationTitle($self->name);
+ ## set icon if not already set by external launcher
+ yui::YUI::app()->setApplicationIcon($self->icon);
+
+# my ($l, $on_services) = services();
+# my @xinetd_services = map { $_->[0] } xinetd_services();
+
+ my $mageiaPlugin = "mga";
+ my $factory = yui::YUI::widgetFactory;
+ my $mgaFactory = yui::YExternalWidgets::externalWidgetFactory($mageiaPlugin);
+ $mgaFactory = yui::YMGAWidgetFactory::getYMGAWidgetFactory($mgaFactory);
+
+ my $dialog = $factory->createMainDialog;
+ my $vbox = $factory->createVBox( $dialog );
+ my $frame = $factory->createFrame ($vbox, N("Services"));
+
+ my $frmVbox = $factory->createVBox( $frame );
+ my $hbox = $factory->createHBox( $frmVbox );
+
+ my $yTableHeader = new yui::YTableHeader();
+ $yTableHeader->addColumn(N("Service"), $yui::YAlignBegin);
+ $yTableHeader->addColumn(N("Status"), $yui::YAlignCenter);
+ $yTableHeader->addColumn(N("On boot"), $yui::YAlignBegin);
+
+ ## service list (serviceBox)
+ my $serviceTbl = $mgaFactory->createCBTable($hbox, $yTableHeader, $yui::YCBTableCheckBoxOnLastColumn);
+ my $itemCollection = new yui::YItemCollection;
+ foreach ($self->all_services) {
+
+ my $serviceName = $_;
+
+ my $item = new yui::YCBTableItem($serviceName);
+ my $started;
+ if (member($serviceName, $self->all_xinetd_services)) {
+ $started = N("Start when requested");
+ }
+ else {
+ $started = (member($serviceName, $self->all_running_services)? N("running") : N("stopped"));
+ }
+
+# TODO add icon green/red led
+ my $cell = new yui::YTableCell($started);
+ $item->addCell($cell);
+
+ $item->check(member($serviceName, $self->all_on_services));
+ $item->setLabel($serviceName);
+ $itemCollection->push($item);
+ $item->DISOWN();
+ }
+ $serviceTbl->addItems($itemCollection);
+ $serviceTbl->setImmediateMode(1);
+ $serviceTbl->setWeight(0, 50);
+
+ ## info panel (infoPanel)
+ $frame = $factory->createFrame ($hbox, N("Information"));
+ $frame->setWeight(0, 30);
+ $frmVbox = $factory->createVBox( $frame );
+ my $infoPanel = $factory->createRichText($frmVbox, "--------------"); #, 0, 0);
+ $infoPanel->setAutoScrollDown();
+
+ ### Service Start button ($startButton)
+ $hbox = $factory->createHBox( $frmVbox );
+ my $startButton = $factory->createPushButton($hbox, N("Start"));
+
+ ### Service Stop button ($stopButton)
+ my $stopButton = $factory->createPushButton($hbox, N("Stop"));
+
+ # dialog buttons
+ $factory->createVSpacing($vbox, 1.0);
+ ## Window push buttons
+ $hbox = $factory->createHBox( $vbox );
+ my $align = $factory->createLeft($hbox);
+ $hbox = $factory->createHBox($align);
+ my $aboutButton = $factory->createPushButton($hbox, N("About") );
+ $align = $factory->createRight($hbox);
+ $hbox = $factory->createHBox($align);
+ my $closeButton = $factory->createPushButton($hbox, N("Close") );
+
+ #first item status
+ my $item = $serviceTbl->selectedItem();
+ if ($item) {
+ $self->serviceInfo($item->label(), $infoPanel);
+ if (member($item->label(), $self->all_xinetd_services)) {
+ $stopButton->setDisabled();
+ $startButton->setDisabled();
+ }
+ else {
+ $stopButton->setEnabled(1);
+ $startButton->setEnabled(1);
+ }
+ }
+
+ while(1) {
+ my $event = $dialog->waitForEvent();
+ my $eventType = $event->eventType();
+
+ #event type checking
+ if ($eventType == $yui::YEvent::CancelEvent) {
+ last;
+ }
+ elsif ($eventType == $yui::YEvent::WidgetEvent) {
+ # widget selected
+ my $widget = $event->widget();
+ my $wEvent = yui::toYWidgetEvent($event);
+
+ if ($widget == $closeButton) {
+ last;
+ }
+ elsif ($widget == $aboutButton) {
+ my $license = translate($AdminPanel::Shared::License);
+ # TODO fix version value
+ AboutDialog({ name => N("AdminService"),
+ version => $self->VERSION,
+ copyright => N("Copyright (C) %s Mageia community", '2013-2014'),
+ license => $license,
+ comments => N("Service Manager is the Mageia service and daemon management tool \n(from the original idea of Mandriva draxservice)."),
+ website => 'http://www.mageia.org',
+ website_label => N("Mageia"),
+ authors => "Angelo Naselli <anaselli\@linux.it>\nMatteo Pasotti <matteo.pasotti\@gmail.com>",
+ translator_credits =>
+ #-PO: put here name(s) and email(s) of translator(s) (eg: "John Smith <jsmith@nowhere.com>")
+ N("_: Translator(s) name(s) & email(s)\n")}
+ );
+ }
+ elsif ($widget == $serviceTbl) {
+
+ # service selection changed
+ $item = $serviceTbl->selectedItem();
+ if ($item) {
+ $self->serviceInfo($item->label(), $infoPanel);
+ if (member($item->label(), $self->all_xinetd_services)) {
+ $stopButton->setDisabled();
+ $startButton->setDisabled();
+ }
+ else {
+ $stopButton->setEnabled(1);
+ $startButton->setEnabled(1);
+ }
+ }
+# TODO fix libyui-mga-XXX item will always be changed after first one
+ if ($wEvent->reason() == $yui::YEvent::ValueChanged) {
+ $item = $serviceTbl->changedItem();
+ if ($item) {
+
+ set_service($item->label(), $item->checked());
+ # we can push/pop service, but this (slower) should return real situation
+ $self->refreshRunningServices();
+ }
+ }
+ }
+ elsif ($widget == $startButton) {
+ $item = $serviceTbl->selectedItem();
+ if ($item) {
+ restart_or_start($item->label());
+ # we can push/pop service, but this (slower) should return real situation
+ $self->refreshRunningServices();
+ $self->serviceStatus($serviceTbl, $item);
+ }
+ }
+ elsif ($widget == $stopButton) {
+ $item = $serviceTbl->selectedItem();
+ if ($item) {
+ stop($item->label());
+ # we can push/pop service, but this (slower) should return real situation
+ $self->refreshRunningServices();
+ $self->serviceStatus($serviceTbl, $item);
+ }
+ }
+ }
+ }
+ $dialog->destroy();
+
+ #restore old application title
+ yui::YUI::app()->setApplicationTitle($appTitle) if $appTitle;
+}
+
+no Moose;
+__PACKAGE__->meta->make_immutable;
+
+1;
diff --git a/lib/AdminPanel/Module/Users.pm b/lib/AdminPanel/Module/Users.pm
new file mode 100644
index 00000000..16ea058a
--- /dev/null
+++ b/lib/AdminPanel/Module/Users.pm
@@ -0,0 +1,2570 @@
+# vim: set et ts=4 sw=4:
+#*****************************************************************************
+#
+# Copyright (c) 2013 Angelo Naselli <anaselli@linux.it>
+# from adduserdrake and userdrake
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2, as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+#*****************************************************************************
+
+package AdminPanel::Module::Users;
+
+###############################################
+##
+## graphic related routines for managing user
+##
+###############################################
+
+
+use strict;
+# TODO evaluate if Moose is too heavy and use Moo
+# instead
+use POSIX qw(ceil);
+# use Time::localtime;
+
+# TODO same translation atm
+use lib qw(/usr/lib/libDrakX);
+# i18n: IMPORTANT: to get correct namespace (userdrake instead of libDrakX)
+BEGIN { unshift @::textdomains, 'userdrake', 'libuser', 'drakconf' }
+
+use common qw(N
+ translate);
+use security::level;
+use run_program;
+## USER is from userdrake
+use USER;
+use utf8;
+use log;
+
+use Glib;
+use yui;
+use AdminPanel::Shared;
+use AdminPanel::Shared::Users;
+use Moose;
+extends qw( AdminPanel::Module );
+
+has '+icon' => (
+ default => "/usr/share/icons/userdrake.png",
+);
+
+has '+name' => (
+ default => N("AdminUser"),
+);
+
+
+=head1 VERSION
+
+Version 1.0.0
+
+=cut
+
+our $VERSION = '1.0.0';
+
+# main dialog
+has 'dialog' => (
+ is => 'rw',
+ init_arg => undef,
+);
+
+has 'widgets' => (
+ traits => ['Hash'],
+ default => sub { {} },
+ is => 'rw',
+ isa => 'HashRef',
+ handles => {
+ set_widget => 'set',
+ get_widget => 'get',
+ widget_pairs => 'kv',
+ },
+ init_arg => undef,
+);
+
+has 'action_menu' => (
+ traits => ['Hash'],
+ default => sub { {} },
+ is => 'rw',
+ isa => 'HashRef',
+ handles => {
+ set_action_menu => 'set',
+ get_action_menu => 'get',
+ action_menu_pairs => 'kv',
+ },
+ init_arg => undef,
+);
+
+## Used by USER (for getting values? TODO need explanations, where?)
+has 'USER_GetValue' => (
+ default => -65533,
+ is => 'ro',
+ isa => 'Int',
+ init_arg => undef,
+);
+
+## Used by USER (for getting values? TODO need explanations, where?)
+has 'ctx' => (
+ default => sub {USER::ADMIN->new},
+ is => 'ro',
+ init_arg => undef,
+);
+
+
+has 'edit_tab_widgets' => (
+ traits => ['Hash'],
+ default => sub { {} },
+ is => 'rw',
+ isa => 'HashRef',
+ handles => {
+ set_edit_tab_widget => 'set',
+ get_edit_tab_widget => 'get',
+ edit_tab_pairs => 'kv',
+ },
+ init_arg => undef,
+);
+
+sub start {
+ my $self = shift;
+
+ $self->manageUsersDialog();
+};
+
+# TODO move to Shared?
+sub labeledFrameBox {
+ my ($parent, $label) = @_;
+
+ my $factory = yui::YUI::widgetFactory;
+
+ my $frame = $factory->createFrame($parent, $label);
+ $frame->setWeight( $yui::YD_HORIZ, 1);
+ $frame->setWeight( $yui::YD_VERT, 2);
+ $frame = $factory->createHVCenter( $frame );
+ $frame = $factory->createVBox( $frame );
+ return $frame;
+}
+
+# usefull local variable to avoid duplicating
+# translation point for user edit labels
+my %userEditLabel = (
+ user_data => N("User Data"),
+ account_info => N("Account Info"),
+ password_info => N("Password Info"),
+ groups => N("Groups"),
+);
+# usefull local variable to avoid duplicating
+# translation point for group edit labels
+my %groupEditLabel = (
+ group_data => N("Group Data"),
+ group_users => N("Group Users"),
+);
+#=============================================================
+
+=head2 ChooseGroup
+
+=head3 INPUT
+
+ $self: this object
+
+=head3 OUTPUT
+
+ $choice: 0 or 1 (choice)
+ -1 cancel or exit
+
+=head3 DESCRIPTION
+
+creates a popup dialog to ask if adding user to an existing
+group or to the 'users' group
+
+=cut
+
+#=============================================================
+sub ChooseGroup {
+ my $self = shift;
+
+ my $choice = -1;
+
+ ## push application title
+ my $appTitle = yui::YUI::app()->applicationTitle();
+ ## set new title to get it in dialog
+ yui::YUI::app()->setApplicationTitle(N("Choose group"));
+
+ my $factory = yui::YUI::widgetFactory;
+
+ my $dlg = $factory->createPopupDialog();
+ my $layout = $factory->createVBox($dlg);
+
+
+ my $frame = labeledFrameBox($layout, N("A group with this name already exists. What would you like to do?"));
+
+ my $rbg = $factory->createRadioButtonGroup( $frame );
+ $frame = $factory->createVBox( $rbg );
+ my $align = $factory->createLeft($frame);
+
+ my $rb1 = $factory->createRadioButton( $align, N("Add to the existing group"), 1);
+ $rb1->setNotify(1);
+ $rbg->addRadioButton( $rb1 );
+ $align = $factory->createLeft($frame);
+ my $rb2 = $factory->createRadioButton( $align, N("Add to the 'users' group"), 0);
+ $rb2->setNotify(1);
+ $rbg->addRadioButton( $rb2 );
+
+ my $hbox = $factory->createHBox($layout);
+ $align = $factory->createRight($hbox);
+ my $cancelButton = $factory->createPushButton($align, N("Cancel"));
+ my $okButton = $factory->createPushButton($hbox, N("Ok"));
+ while(1) {
+ my $event = $dlg->waitForEvent();
+ my $eventType = $event->eventType();
+
+ #event type checking
+ if ($eventType == $yui::YEvent::CancelEvent) {
+ last;
+ }
+ elsif ($eventType == $yui::YEvent::WidgetEvent) {
+ # widget selected
+ my $widget = $event->widget();
+ if ($widget == $cancelButton) {
+ last;
+ }
+ if ($widget == $okButton) {
+ $choice = $rb1->value() ? 0 : 1 ;
+ last;
+ }
+ }
+ }
+
+ destroy $dlg;
+
+ #restore old application title
+ yui::YUI::app()->setApplicationTitle($appTitle);
+
+ return $choice;
+}
+
+#=============================================================
+
+=head2 _updateOrDelUsersInGroup
+
+=head3 INPUT
+
+ $name: username
+
+=head3 DESCRIPTION
+
+ Fixes user deletion into groups.
+
+=cut
+
+#=============================================================
+sub _updateOrDelUserInGroup {
+ my ($self, $name) = @_;
+ my $groups = $self->ctx->GroupsEnumerateFull;
+ foreach my $g (@$groups) {
+ my $members = $g->MemberName(1, 0);
+ if ($self->_inArray($name, $members)) {
+ eval { $g->MemberName($name, 2) };
+ eval { $self->ctx->GroupModify($g) };
+ }
+ }
+}
+
+#=============================================================
+
+=head2 _deleteGroupDialog
+
+=head3 INPUT
+
+ $self: this object
+
+=head3 DESCRIPTION
+
+ This method open a dialog to delete the selected group.
+
+=cut
+
+#=============================================================
+sub _deleteGroupDialog {
+ my $self = shift;
+
+ my $item = $self->get_widget('table')->selectedItem();
+ if (! $item) {
+ return;
+ }
+
+ my $groupname = $item->label();
+ ## push application title
+ my $appTitle = yui::YUI::app()->applicationTitle();
+ ## set new title to get it in dialog
+ yui::YUI::app()->setApplicationTitle(N("Warning"));
+
+ my $factory = yui::YUI::widgetFactory;
+ my $dlg = $factory->createPopupDialog();
+ my $layout = $factory->createVBox($dlg);
+
+ my $align = $factory->createLeft($layout);
+
+ $factory->createLabel($align, N("Do you really want to delete the group %s?",
+ $groupname));
+
+ $align = $factory->createRight($layout);
+ my $hbox = $factory->createHBox($align);
+ my $cancelButton = $factory->createPushButton($hbox, N("Cancel"));
+ my $deleteButton = $factory->createPushButton($hbox, N("Delete"));
+
+ while(1) {
+ my $event = $dlg->waitForEvent();
+ my $eventType = $event->eventType();
+
+ #event type checking
+ if ($eventType == $yui::YEvent::CancelEvent) {
+ last;
+ }
+ elsif ($eventType == $yui::YEvent::WidgetEvent) {
+ # widget selected
+ my $widget = $event->widget();
+ if ($widget == $cancelButton) {
+ last;
+ }
+ elsif ($widget == $deleteButton) {
+ my $groupEnt = $self->ctx->LookupGroupByName($groupname);
+ my $members = $self->ctx->EnumerateUsersByGroup($groupname);
+ my $continue = 1;
+ GLOOP: foreach my $username (@$members) {
+ my $userEnt = $self->ctx->LookupUserByName($username);
+ if ($userEnt && $userEnt->Gid($self->USER_GetValue) == $groupEnt->Gid($self->USER_GetValue)) {
+ AdminPanel::Shared::msgBox(N("%s is a primary group for user %s\n Remove the user first",
+ $groupname, $username));
+ $continue = 0;
+ last GLOOP;
+ }
+ }
+ if ($continue) {
+ log::explanations(N("Removing group: %s", $groupname));
+ eval { $self->ctx->GroupDel($groupEnt) };
+ $self->_refresh();
+ }
+ last;
+ }
+ }
+ }
+
+ destroy $dlg;
+
+ #restore old application title
+ yui::YUI::app()->setApplicationTitle($appTitle);
+}
+
+#=============================================================
+
+=head2 _deleteUserDialog
+
+=head3 INPUT
+
+ $self: this object
+
+=head3 DESCRIPTION
+
+ This method open a dialog to delete the selected user.
+ It also asks for additional information to be removed.
+
+=cut
+
+#=============================================================
+sub _deleteUserDialog {
+ my $self = shift;
+
+ my $item = $self->get_widget('table')->selectedItem();
+ if (! $item) {
+ return;
+ }
+ my $username = $item->label();
+
+ my $userEnt = $self->ctx->LookupUserByName($username);
+ my $homedir = $userEnt->HomeDir($self->USER_GetValue);
+
+ ## push application title
+ my $appTitle = yui::YUI::app()->applicationTitle();
+ ## set new title to get it in dialog
+ yui::YUI::app()->setApplicationTitle(N("Delete files or not?"));
+
+ my $factory = yui::YUI::widgetFactory;
+ my $dlg = $factory->createPopupDialog();
+ my $layout = $factory->createVBox($dlg);
+
+ my $align = $factory->createLeft($layout);
+ $factory->createLabel($align, N("Deleting user %s\nAlso perform the following actions\n",
+ $username));
+ $align = $factory->createLeft($layout);
+ my $checkhome = $factory->createCheckBox($align, N("Delete Home Directory: %s", $homedir, 0));
+ $align = $factory->createLeft($layout);
+ my $checkspool = $factory->createCheckBox($align, N("Delete Mailbox: /var/spool/mail/%s",
+ $username), 0);
+ $align = $factory->createRight($layout);
+ my $hbox = $factory->createHBox($align);
+ my $cancelButton = $factory->createPushButton($hbox, N("Cancel"));
+ my $deleteButton = $factory->createPushButton($hbox, N("Delete"));
+
+ if ($homedir !~ m!(?:/home|/var/spool)!) {
+ $checkhome->setDisabled();
+ $checkspool->setDisabled();
+ }
+
+
+ while(1) {
+ my $event = $dlg->waitForEvent();
+ my $eventType = $event->eventType();
+
+ #event type checking
+ if ($eventType == $yui::YEvent::CancelEvent) {
+ last;
+ }
+ elsif ($eventType == $yui::YEvent::WidgetEvent) {
+ # widget selected
+ my $widget = $event->widget();
+ if ($widget == $cancelButton) {
+ last;
+ }
+ elsif ($widget == $deleteButton) {
+ log::explanations(N("Removing user: %s", $username));
+ $self->ctx->UserDel($userEnt);
+ $self->_updateOrDelUserInGroup($username);
+ #Let's check out the user's primary group
+ my $usergid = $userEnt->Gid($self->USER_GetValue);
+ my $groupEnt = $self->ctx->LookupGroupById($usergid);
+ if ($groupEnt) {
+ my $member = $groupEnt->MemberName(1, 0);
+ if (scalar(@$member) == 0 && $groupEnt->Gid($self->USER_GetValue) > 499) {
+ $self->ctx->GroupDel($groupEnt);
+ }
+ }
+ if ($checkhome->isChecked()) {
+ eval { $self->ctx->CleanHome($userEnt) };
+ $@ and AdminPanel::Shared::msgBox($@) and last;
+ }
+ if ($checkspool->isChecked()) {
+ eval { $self->ctx->CleanSpool($userEnt) };
+ $@ and AdminPanel::Shared::msgBox($@) and last;
+ }
+ $self->_refresh();
+ last;
+ }
+ }
+ }
+
+ destroy $dlg;
+
+ #restore old application title
+ yui::YUI::app()->setApplicationTitle($appTitle);
+
+}
+
+
+sub _addGroupDialog {
+ my $self = shift;
+
+ my $is_system = 0;
+
+ ## push application title
+ my $appTitle = yui::YUI::app()->applicationTitle();
+ ## set new title to get it in dialog
+ yui::YUI::app()->setApplicationTitle(N("Create New Group"));
+ my $factory = yui::YUI::widgetFactory;
+ my $optional = yui::YUI::optionalWidgetFactory;
+
+ my $dlg = $factory->createPopupDialog();
+ my $layout = $factory->createVBox($dlg);
+
+ ## 'group name'
+ my $align = $factory->createRight($layout);
+ my $hbox = $factory->createHBox($align);
+ my $label = $factory->createLabel($hbox, N("Group Name:") );
+ my $groupName = $factory->createInputField($hbox, "", 0);
+ $label->setWeight($yui::YD_HORIZ, 1);
+ $groupName->setWeight($yui::YD_HORIZ, 2);
+
+ $factory->createVSpacing($layout, 1);
+
+ # Specify group id manually
+ $align = $factory->createLeft($layout);
+ $hbox = $factory->createHBox($align);
+ my $gidManually = $factory->createCheckBox($hbox, N("Specify group ID manually"), 0);
+ $factory->createHSpacing($hbox, 2);
+ my $GID = $factory->createIntField($hbox, N("GID"), 1, 65000, 500);
+ $GID->setEnabled($gidManually->value());
+ $gidManually->setNotify(1);
+
+ $hbox = $factory->createHBox($layout);
+ $align = $factory->createRight($hbox);
+ my $cancelButton = $factory->createPushButton($align, N("Cancel"));
+ my $okButton = $factory->createPushButton($hbox, N("Ok"));
+ while(1) {
+ my $event = $dlg->waitForEvent();
+ my $eventType = $event->eventType();
+
+ #event type checking
+ if ($eventType == $yui::YEvent::CancelEvent) {
+ last;
+ }
+ elsif ($eventType == $yui::YEvent::WidgetEvent) {
+ # widget selected
+ my $widget = $event->widget();
+ if ($widget == $cancelButton) {
+ last;
+ }
+ elsif ($widget == $gidManually) {
+ # GID inserction enabled?
+ $GID->setEnabled($gidManually->value());
+ }
+ elsif ($widget == $okButton) {
+ ## check data
+ my $groupname = $groupName->value();
+ my ($continue, $errorString) = valid_groupname($groupname);
+ my $nm = $continue && $self->ctx->LookupGroupByName($groupname);
+ if ($nm) {
+ $groupName->setValue("");
+ $errorString = N("Group already exists, please choose another Group Name");
+ $continue = 0;
+ }
+ my $groupEnt = $self->ctx->InitGroup($groupname, $is_system);
+
+ my $gid = 0;
+ if ($continue && $gidManually->value()) {
+ if (($gid = $GID->value()) < 500) {
+ $errorString = "";
+ my $gidchoice = AdminPanel::Shared::ask_YesOrNo(N(" Group Gid is < 500"),
+ N("Creating a group with a GID less than 500 is not recommended.\n Are you sure you want to do this?\n\n"));
+ $continue = $gidchoice and $groupEnt->Gid($gid);
+ } else {
+ my $g = $self->ctx->LookupGroupById($gid);
+ if ($g) {
+ $errorString = "";
+ my $gidchoice = AdminPanel::Shared::ask_YesOrNo(N(" Group ID is already used "),
+ N("Creating a group with a non unique GID?\n\n"));
+ $continue = $gidchoice and $groupEnt->Gid($gid);
+ }
+ else {
+ $groupEnt and $groupEnt->Gid($gid);
+ }
+ }
+ }
+
+
+ if (!$continue) {
+ #--- raise error
+ AdminPanel::Shared::msgBox($errorString) if ($errorString);
+ }
+ else {
+ log::explanations(N("Adding group: %s ", $groupname));
+ $self->ctx->GroupAdd($groupEnt);
+ $self->_refresh();
+ last;
+ }
+ }
+ }
+ }
+ destroy $dlg;
+
+ #restore old application title
+ yui::YUI::app()->setApplicationTitle($appTitle);
+}
+
+
+#=============================================================
+
+=head2 _buildUserData
+
+=head3 INPUT
+
+ $self: this object
+ $layout : layout in wich drawing graphic user data
+
+=head3 OUTPUT
+
+ %userData: hash containing reference to graphical object
+ such as:
+ full_name, login_name, password, password1,
+ login_shell
+
+=head3 DESCRIPTION
+
+ This method is used by addUserDialog and _editUserDialog
+ to create User Data dialog
+=cut
+
+#=============================================================
+sub _buildUserData {
+ my ($self, $layout, $selected_shell) = @_;
+
+
+ my @shells = @{$self->ctx->GetUserShells};
+
+ my $factory = yui::YUI::widgetFactory;
+
+ ## user 'full name'
+ my $align = $factory->createRight($layout);
+ my $hbox = $factory->createHBox($align);
+ my $label = $factory->createLabel($hbox, N("Full Name:") );
+ my $fullName = $factory->createInputField($hbox, "", 0);
+ $label->setWeight($yui::YD_HORIZ, 1);
+ $fullName->setWeight($yui::YD_HORIZ, 2);
+
+ ## user 'login name'
+ $align = $factory->createRight($layout);
+ $hbox = $factory->createHBox($align);
+ $label = $factory->createLabel($hbox, N("Login:") );
+ my $loginName = $factory->createInputField($hbox, "", 0);
+ $label->setWeight($yui::YD_HORIZ, 1);
+ $loginName->setWeight($yui::YD_HORIZ, 2);
+ $loginName->setNotify(1);
+
+ ## user 'Password'
+ $align = $factory->createRight($layout);
+ $hbox = $factory->createHBox($align);
+ $label = $factory->createLabel($hbox, N("Password:") );
+ my $password = $factory->createInputField($hbox, "", 1);
+ $label->setWeight($yui::YD_HORIZ, 1);
+ $password->setWeight($yui::YD_HORIZ, 2);
+
+ ## user 'confirm Password'
+ $align = $factory->createRight($layout);
+ $hbox = $factory->createHBox($align);
+ $label = $factory->createLabel($hbox, N("Confirm Password:") );
+ my $password1 = $factory->createInputField($hbox, "", 1);
+ $label->setWeight($yui::YD_HORIZ, 1);
+ $password1->setWeight($yui::YD_HORIZ, 2);
+
+ ## user 'Login Shell'
+ $align = $factory->createRight($layout);
+ $hbox = $factory->createHBox($align);
+ $label = $factory->createLabel($hbox, N("Login Shell:") );
+ my $loginShell = $factory->createComboBox($hbox, "", 0);
+ my $itemColl = new yui::YItemCollection;
+ foreach my $shell (@shells) {
+ my $item = new yui::YItem ($shell, 0);
+ $item->setSelected(1) if ($selected_shell && $selected_shell eq $shell);
+ $itemColl->push($item);
+ $item->DISOWN();
+ }
+ $loginShell->addItems($itemColl);
+ $label->setWeight($yui::YD_HORIZ, 1);
+ $loginShell->setWeight($yui::YD_HORIZ, 2);
+
+ my %userData = (
+ full_name => $fullName,
+ login_name => $loginName,
+ password => $password,
+ password1 => $password1,
+ login_shell => $loginShell,
+ );
+
+ return ( %userData );
+}
+
+#=============================================================
+
+=head2 addUserDialog
+
+=head3 INPUT
+
+ $self: this object
+ $standalone: if set the application title is set
+ from the name set in costructor
+
+=head3 DESCRIPTION
+
+ This method creates and manages the dialog to add a new
+ user.
+
+=cut
+
+#=============================================================
+sub addUserDialog {
+ my $self = shift;
+ my $standalone = shift;
+
+ my $dontcreatehomedir = 0;
+ my $is_system = 0;
+
+ ## push application title
+ my $appTitle = yui::YUI::app()->applicationTitle();
+ ## set new title to get it in dialog
+ if ($standalone) {
+ yui::YUI::app()->setApplicationTitle($self->name);
+ }
+ else {
+ yui::YUI::app()->setApplicationTitle(N("Create New User"));
+ }
+
+ my $factory = yui::YUI::widgetFactory;
+ my $optional = yui::YUI::optionalWidgetFactory;
+
+ my $dlg = $factory->createPopupDialog();
+ my $layout = $factory->createVBox($dlg);
+
+ my %userData = $self->_buildUserData($layout);
+
+ ##### add a separator
+ ## Create Home directory
+ my $align = $factory->createLeft($layout);
+ my $hbox = $factory->createHBox($align);
+ my $createHome = $factory->createCheckBox($hbox, N("Create Home Directory"), 1);
+ ## Home directory
+ $align = $factory->createLeft($layout);
+ $hbox = $factory->createHBox($align);
+ my $label = $factory->createLabel($hbox, N("Home Directory:") );
+ my $homeDir = $factory->createInputField($hbox, "", 0);
+ $label->setWeight($yui::YD_HORIZ, 1);
+ $homeDir->setWeight($yui::YD_HORIZ, 2);
+
+ # Create private group
+ $align = $factory->createLeft($layout);
+ $hbox = $factory->createHBox($align);
+ my $createGroup = $factory->createCheckBox($hbox, N("Create a private group for the user"), 1);
+
+ # Specify user id manually
+ $align = $factory->createRight($layout);
+ $hbox = $factory->createHBox($align);
+ my $uidManually = $factory->createCheckBox($hbox, N("Specify user ID manually"), 0);
+ my $UID = $factory->createIntField($hbox, N("UID"), 1, 65000, 500);
+ $UID->setEnabled($uidManually->value());
+ $uidManually->setNotify(1);
+ $uidManually->setWeight($yui::YD_HORIZ, 2);
+ $UID->setWeight($yui::YD_HORIZ, 1);
+
+ ## user 'icon'
+ $hbox = $factory->createHBox($layout);
+ $factory->createLabel($hbox, N("Click on icon to change it") );
+ my $iconFace = AdminPanel::Shared::Users::GetFaceIcon();
+ my $icon = $factory->createPushButton($hbox, "");
+ $icon->setIcon(AdminPanel::Shared::Users::face2png($iconFace));
+ $icon->setLabel($iconFace);
+
+ $hbox = $factory->createHBox($layout);
+ $align = $factory->createRight($hbox);
+ my $cancelButton = $factory->createPushButton($align, N("Cancel"));
+ my $okButton = $factory->createPushButton($hbox, N("Ok"));
+ while(1) {
+ my $event = $dlg->waitForEvent();
+ my $eventType = $event->eventType();
+
+ #event type checking
+ if ($eventType == $yui::YEvent::CancelEvent) {
+ last;
+ }
+ elsif ($eventType == $yui::YEvent::WidgetEvent) {
+ # widget selected
+ my $widget = $event->widget();
+ if ($widget == $cancelButton) {
+ last;
+ }
+ elsif ($widget == $icon) {
+ #remove shortcut from label
+ my $iconLabel = $self->_skipShortcut($icon->label());
+
+ my $nextIcon = GetFaceIcon($icon->label(), 1);
+ $icon->setLabel($nextIcon);
+ $icon->setIcon(AdminPanel::Shared::Users::face2png($nextIcon));
+ }
+ elsif ($widget == $uidManually) {
+ # UID inserction enabled?
+ $UID->setEnabled($uidManually->value());
+ }
+ elsif ($widget == $userData{ login_name }) {
+ my $username = $userData{ login_name }->value();
+ $homeDir->setValue("/home/$username");
+ }
+ elsif ($widget == $okButton) {
+ ## check data
+ my $username = $userData{ login_name }->value();
+ my ($continue, $errorString) = valid_username($username);
+ my $nm = $continue && $self->ctx->LookupUserByName($username);
+ if ($nm) {
+ $userData{ login_name }->setValue("");
+ $homeDir->setValue("");
+ $errorString = N("User already exists, please choose another User Name");
+ $continue = 0;
+ }
+ my $passwd = $continue && $userData{ password }->value();
+ if ($continue && $passwd ne $userData{ password1 }->value()) {
+ $errorString = N("Password Mismatch");
+ $continue = 0;
+ }
+ my $sec = security::level::get();
+ if ($sec > 3 && length($passwd) < 6) {
+ $errorString = N("This password is too simple. \n Good passwords should be > 6 characters");
+ $continue = 0;
+ }
+ my $userEnt = $continue && $self->ctx->InitUser($username, $is_system);
+ if ($continue && $createHome->value()) {
+ $dontcreatehomedir = 0;
+ my $homedir = $homeDir->value();
+ $userEnt and $userEnt->HomeDir($homedir);
+ } else {
+ $dontcreatehomedir = 1;
+ }
+ my $uid = 0;
+ if ($continue && $uidManually->value()) {
+ if (($uid = $UID->value()) < 500) {
+ $errorString = "";
+ my $uidchoice = AdminPanel::Shared::ask_YesOrNo(N("User Uid is < 500"),
+ N("Creating a user with a UID less than 500 is not recommended.\nAre you sure you want to do this?\n\n"));
+ $continue = $uidchoice and $userEnt->Uid($uid);
+ } else {
+ $userEnt and $userEnt->Uid($uid);
+ }
+ }
+ my $gid = 0;
+ if ($createGroup->value()) {
+ if ($continue) {
+ #Check if group exist
+ my $gr = $self->ctx->LookupGroupByName($username);
+ if ($gr) {
+ my $groupchoice = $self->ChooseGroup();
+ if ($groupchoice == 0 ) {
+ #You choose to put it in the existing group
+ $gid = $gr->Gid($self->USER_GetValue);
+ } elsif ($groupchoice == 1) {
+ # Put it in 'users' group
+ log::explanations(N("Putting %s to 'users' group",
+ $username));
+ $gid = AdminPanel::Shared::Users::Add2UsersGroup($username, $self->ctx);
+ }
+ else {
+ $errorString = "";
+ $continue = 0;
+ }
+ } else {
+ #it's a new group: Add it
+ my $newgroup = $self->ctx->InitGroup($username,$is_system);
+ log::explanations(N("Creating new group: %s", $username));
+ $gid = $newgroup->Gid($self->USER_GetValue);
+ $self->ctx->GroupAdd($newgroup);
+ }
+ }
+ } else {
+ $continue and $gid = AdminPanel::Shared::Users::Add2UsersGroup($username, $self->ctx);
+ }
+
+ if (!$continue) {
+ #---rasie error
+ AdminPanel::Shared::msgBox($errorString) if ($errorString);
+ }
+ else {
+ ## OK let's create the user
+ print N("Adding user: ") . $username . " \n";
+ log::explanations(N("Adding user: %s"), $username);
+ my $loginshell = $userData{ login_shell }->value();
+ my $fullname = $userData{ full_name }->value();
+ $userEnt->Gecos($fullname); $userEnt->LoginShell($loginshell);
+ $userEnt->Gid($gid);
+ $userEnt->ShadowMin(-1); $userEnt->ShadowMax(99999);
+ $userEnt->ShadowWarn(-1); $userEnt->ShadowInact(-1);
+ $self->ctx->UserAdd($userEnt, $is_system, $dontcreatehomedir);
+ $self->ctx->UserSetPass($userEnt, $passwd);
+ defined $icon->label() and
+ AdminPanel::Shared::Users::addKdmIcon($username, $icon->label());
+### TODO Migration wizard
+#
+# Refresh($sysfilter, $stringsearch);
+# transfugdrake::get_windows_disk()
+# and $in->ask_yesorno(N("Migration wizard"),
+# N("Do you want to run the migration wizard in order to import Windows documents and settings in your Mageia distribution?"))
+# and run_program::raw({ detach => 1 }, 'transfugdrake');
+
+
+ last;
+ }
+ }
+ }
+ }
+
+ destroy $dlg;
+
+ #restore old application title
+ yui::YUI::app()->setApplicationTitle($appTitle) if $appTitle;
+}
+
+#=============================================================
+
+=head2 _createUserTable
+
+=head3 INPUT
+
+ $self: this object
+
+=head3 DESCRIPTION
+
+This function create the User table to be added to the replace
+point of the tab widget. Note this function is meant for internal
+use only
+
+=cut
+
+#=============================================================
+sub _createUserTable {
+ my $self = shift;
+
+ $self->dialog->startMultipleChanges();
+ $self->get_widget('replace_pnt')->deleteChildren();
+ my $parent = $self->get_widget('replace_pnt');
+ my $factory = yui::YUI::widgetFactory;
+ my $yTableHeader = new yui::YTableHeader();
+ $yTableHeader->addColumn(N("User Name"), $yui::YAlignBegin);
+ $yTableHeader->addColumn(N("User ID"), $yui::YAlignBegin);
+ $yTableHeader->addColumn(N("Primary Group"), $yui::YAlignBegin);
+ $yTableHeader->addColumn(N("Full Name"), $yui::YAlignBegin);
+ $yTableHeader->addColumn(N("Login Shell"), $yui::YAlignBegin);
+ $yTableHeader->addColumn(N("Home Directory"), $yui::YAlignBegin);
+ $yTableHeader->DISOWN();
+
+ $self->set_widget(table => $factory->createTable($parent, $yTableHeader));
+
+ $self->get_widget('table')->setImmediateMode(1);
+ $self->get_widget('table')->DISOWN();
+ $self->get_widget('replace_pnt')->showChild();
+ $self->dialog->recalcLayout();
+ $self->dialog->doneMultipleChanges();
+ $self->_refreshUsers();
+}
+
+#=============================================================
+
+=head2 _createGroupTable
+
+=head3 INPUT
+
+ $self: this object
+
+=head3 DESCRIPTION
+
+This function create the Group table to be added to the replace
+point of the tab widget. Note this function is meant for internal
+use only
+
+
+=cut
+
+#=============================================================
+sub _createGroupTable {
+ my $self = shift;
+
+
+ $self->dialog->startMultipleChanges();
+ $self->get_widget('replace_pnt')->deleteChildren();
+ my $parent = $self->get_widget('replace_pnt');
+ my $factory = yui::YUI::widgetFactory;
+ my $yTableHeader = new yui::YTableHeader();
+ $yTableHeader->addColumn(N("Group Name"), $yui::YAlignBegin);
+ $yTableHeader->addColumn(N("Group ID"), $yui::YAlignBegin);
+ $yTableHeader->addColumn(N("Group Members"), $yui::YAlignBegin);
+ $yTableHeader->DISOWN();
+
+ $self->set_widget(table => $factory->createTable($parent, $yTableHeader));
+
+ $self->get_widget('table')->setImmediateMode(1);
+ $self->get_widget('table')->DISOWN();
+ $self->get_widget('replace_pnt')->showChild();
+ $self->dialog->recalcLayout();
+ $self->dialog->doneMultipleChanges();
+ $self->_refreshGroups();
+}
+
+
+#=============================================================
+
+=head2 _computeLockExpire
+
+=head3 INPUT
+
+ $l: login user info
+
+=head3 OUTPUT
+
+ $status: Locked, Expired, or empty string
+
+=head3 DESCRIPTION
+
+ This method returns if the login is Locked, Expired or ok.
+ Note this function is meant for internal use only
+
+=cut
+
+#=============================================================
+sub _computeLockExpire {
+ my ( $self, $l ) = @_;
+ my $ep = $l->ShadowExpire($self->USER_GetValue);
+ my $tm = ceil(time()/(24*60*60));
+ $ep = -1 if int($tm) <= $ep;
+ my $status = $self->ctx->IsLocked($l) ? N("Locked") : ($ep != -1 ? N("Expired") : '');
+ $status;
+}
+
+#=============================================================
+
+=head2 _refreshUsers
+
+=head3 INPUT
+
+ $self: this object
+
+=head3 DESCRIPTION
+
+ This method refresh user info into User tab widget.
+ Note this function is meant for internal use only
+
+=cut
+
+#=============================================================
+sub _refreshUsers {
+ my $self = shift;
+
+ my $strfilt = $self->get_widget('filter')->value();
+ my $filterusers = $self->get_widget('filter_system')->isChecked();
+
+ my ($users, $group, $groupnm, $expr);
+ defined $self->ctx and $users = $self->ctx->UsersEnumerateFull;
+
+ $self->dialog->startMultipleChanges();
+ #for some reasons QT send an event using table->selectItem()
+ # WA remove notification immediate
+ $self->get_widget('table')->setImmediateMode(0);
+ $self->get_widget('table')->deleteAllItems();
+
+ my @UserReal;
+ LOOP: foreach my $l (@$users) {
+ next LOOP if $filterusers && $l->Uid($self->USER_GetValue) <= 499 || $l->Uid($self->USER_GetValue) == 65534;
+ push @UserReal, $l if $l->UserName($self->USER_GetValue) =~ /^\Q$strfilt/;
+ }
+ my $i;
+ my $itemColl = new yui::YItemCollection;
+ foreach my $l (@UserReal) {
+ $i++;
+ my $uid = $l->Uid($self->USER_GetValue);
+ if (!defined $uid) {
+ warn "bogus user at line $i\n";
+ next;
+ }
+ my $a = $l->Gid($self->USER_GetValue);
+ $group = $self->ctx->LookupGroupById($a);
+ $groupnm = '';
+ $expr = $self->_computeLockExpire($l);
+ $group and $groupnm = $group->GroupName($self->USER_GetValue);
+ my $s = $l->Gecos($self->USER_GetValue);
+ c::set_tagged_utf8($s);
+ my $username = $l->UserName($self->USER_GetValue);
+ my $Uid = $l->Uid($self->USER_GetValue);
+ my $shell = $l->LoginShell($self->USER_GetValue);
+ my $homedir = $l->HomeDir($self->USER_GetValue);
+ my $item = new yui::YTableItem ("$username",
+ "$Uid",
+ "$groupnm",
+ "$s",
+ "$shell",
+ "$homedir",
+ "$expr");
+ # TODO workaround to get first cell at least until we don't
+ # a cast from YItem
+ $item->setLabel( $username );
+ $itemColl->push($item);
+ $item->DISOWN();
+ }
+ $self->get_widget('table')->addItems($itemColl);
+ my $item = $self->get_widget('table')->selectedItem();
+ $self->get_widget('table')->selectItem($item, 0) if $item;
+ $self->dialog->recalcLayout();
+ $self->dialog->doneMultipleChanges();
+ $self->_refreshActions();
+ $self->get_widget('table')->setImmediateMode(1);
+}
+
+#=============================================================
+
+=head2 _refreshGroups
+
+=head3 INPUT
+
+ $self: this object
+
+=head3 DESCRIPTION
+
+ This method refresh group info into Group tab widget.
+ Note this function is meant for internal use only
+
+=cut
+
+#=============================================================
+sub _refreshGroups {
+ my $self = shift;
+
+ my $strfilt = $self->get_widget('filter')->value();
+ my $filtergroups = $self->get_widget('filter_system')->isChecked();
+
+ my $groups;
+ defined $self->ctx and $groups = $self->ctx->GroupsEnumerateFull;
+
+ $self->dialog->startMultipleChanges();
+ #for some reasons QT send an event using table->selectItem()
+ # WA remove notification immediate
+ $self->get_widget('table')->setImmediateMode(0);
+ $self->get_widget('table')->deleteAllItems();
+ my @GroupReal;
+ LOOP: foreach my $g (@$groups) {
+ next LOOP if $filtergroups && $g->Gid($self->USER_GetValue) <= 499 || $g->Gid($self->USER_GetValue) == 65534;
+ push @GroupReal, $g if $g->GroupName($self->USER_GetValue) =~ /^\Q$strfilt/;
+ }
+
+ my $itemColl = new yui::YItemCollection;
+ foreach my $g (@GroupReal) {
+ my $a = $g->GroupName($self->USER_GetValue);
+ #my $group = $ctx->LookupGroupById($a);
+ my $u_b_g = $a && $self->ctx->EnumerateUsersByGroup($a);
+ my $listUbyG = join(',', @$u_b_g);
+ my $group_id = $g->Gid($self->USER_GetValue);
+ my $groupname = $g->GroupName($self->USER_GetValue);
+ my $item = new yui::YTableItem ("$groupname",
+ "$group_id",
+ "$listUbyG");
+ $item->setLabel( $groupname );
+ $itemColl->push($item);
+ $item->DISOWN();
+ }
+
+ $self->get_widget('table')->addItems($itemColl);
+ my $item = $self->get_widget('table')->selectedItem();
+ $self->get_widget('table')->selectItem($item, 0) if $item;
+ $self->dialog->recalcLayout();
+ $self->dialog->doneMultipleChanges();
+ $self->_refreshActions();
+ $self->get_widget('table')->setImmediateMode(1);
+}
+
+
+#=============================================================
+
+=head2 _getUserInfo
+
+=head3 INPUT
+
+ $self: this object
+
+=head3 OUTPUT
+
+ %userData: selected user info as:
+ username: username
+ full_name: full name of user
+ shell: shell used
+ homedir: home dir path
+ UID: User identifier
+ acc_check_exp: account expiration enabling
+ acc_expy: account expiration year
+ acc_expm: account expiration month
+ acc_expd: account expiration day
+ lockuser: account locked
+ pwd_check_exp: password expiration enabling
+ pwd_exp_min: days before changing password
+ is allowed
+ pwd_exp_max: days before changing password
+ is required
+ pwd_exp_warn: warning days before changing
+ pwd_exp_inact: days before account becomes
+ inact
+ members: Array containing groups the user
+ belongs to.
+ primary_group: primary group ID for the user
+
+=head3 DESCRIPTION
+
+ Retrieves the selected user info from the system
+ Note that acc_expy, acc_expm and acc_expd are valid if
+ acc_check_exp is enabled.
+ Note that pwd_exp_min, pwd_exp_max, pwd_exp_warn,
+ pwd_exp_inact are valid if pwd_check_exp is enabled.
+
+=cut
+
+#=============================================================
+
+sub _getUserInfo {
+ my $self = shift;
+
+ my $label = $self->_skipShortcut($self->get_widget('tabs')->selectedItem()->label());
+ if ($label ne N("Users") ) {
+ return undef;
+ }
+
+ my $item = $self->get_widget('table')->selectedItem();
+ if (! $item) {
+ return undef;
+ }
+
+ my %userData;
+ $userData{username} = $item->label();
+ my $userEnt = $self->ctx->LookupUserByName($userData{username});
+
+ my $s = $userEnt->Gecos($self->USER_GetValue);
+ c::set_tagged_utf8($s);
+ $userData{full_name} = $s;
+ $userData{shell} = $userEnt->LoginShell($self->USER_GetValue);
+ $userData{homedir} = $userEnt->HomeDir($self->USER_GetValue);
+ $userData{UID} = $userEnt->Uid($self->USER_GetValue);
+
+ # default expiration time
+ my ($day, $mo, $ye) = (localtime())[3, 4, 5];
+ $userData{acc_expy} = $ye+1900;
+ $userData{acc_expm} = $mo+1;
+ $userData{acc_expd} = $day;
+ $userData{acc_check_exp} = 0;
+ my $expire = $userEnt->ShadowExpire($self->USER_GetValue);
+ if ($expire && $expire != -1) {
+ my $times = TimeOfArray($expire, 1);
+ $userData{acc_expy} = $times->{year};
+ $userData{acc_expm} = $times->{month};
+ $userData{acc_expd} = $times->{dayint};
+ $userData{acc_check_exp} = 1;
+ }
+
+ # user password are not retrieved if admin wants
+ # to change it has to insert a new one
+ $userData{password} = undef;
+ $userData{password1} = undef;
+ # Check if user account is locked
+
+ $userData{lockuser} = $self->ctx->IsLocked($userEnt);
+
+ $userData{icon_face} = AdminPanel::Shared::Users::GetFaceIcon($userData{username});
+ $userData{pwd_check_exp} = 0;
+ $userData{pwd_exp_min} = $userEnt->ShadowMin($self->USER_GetValue);
+ $userData{pwd_exp_max} = $userEnt->ShadowMax($self->USER_GetValue);
+ $userData{pwd_exp_warn} = $userEnt->ShadowWarn($self->USER_GetValue);
+ $userData{pwd_exp_inact} = $userEnt->ShadowInact($self->USER_GetValue);
+
+ if ($userData{pwd_exp_min} && $userData{pwd_exp_min} != -1 ||
+ $userData{pwd_exp_max} && $userData{pwd_exp_max} != 99999 ||
+ $userData{pwd_exp_warn} && $userData{pwd_exp_warn} != 7 && $userData{pwd_exp_warn} != -1 ||
+ $userData{pwd_exp_inact} && $userData{pwd_exp_inact} != -1) {
+ $userData{pwd_check_exp} = 1;
+ }
+
+ $userData{members} = $self->ctx->EnumerateGroupsByUser($userData{username});
+ $userData{primary_group} = $userEnt->Gid($self->USER_GetValue);
+
+ return %userData;
+
+}
+
+#=============================================================
+
+=head2 _getUserInfo
+
+=head3 INPUT
+
+ $self: this object
+
+=head3 OUTPUT
+
+ %groupData: selected group info as:
+ $groupname: group name
+ $members: users that are members of this group
+
+=head3 DESCRIPTION
+
+ Retrieves the selected group info from the system
+
+=cut
+
+#=============================================================
+
+sub _getGroupInfo {
+ my $self = shift;
+
+ my $label = $self->_skipShortcut($self->get_widget('tabs')->selectedItem()->label());
+ if ($label ne N("Groups") ) {
+ return undef;
+ }
+
+ my $item = $self->get_widget('table')->selectedItem();
+ if (! $item) {
+ return undef;
+ }
+
+ my %groupData;
+ $groupData{start_groupname} = $item->label();
+ $groupData{groupname} = $item->label();
+
+ my $groupEnt = $self->ctx->LookupGroupByName($groupData{groupname});
+ $groupData{members} = $self->ctx->EnumerateUsersByGroup($groupData{groupname});
+
+ return %groupData;
+
+}
+
+sub _storeDataFromGroupEditPreviousTab {
+ my ($self, %groupData) = @_;
+
+ my $previus_tab = $self->get_edit_tab_widget('edit_tab_label');
+ if (!$previus_tab) {
+ return %groupData;
+ }
+ elsif ($previus_tab eq $groupEditLabel{group_data}) {
+ $groupData{groupname} = $self->get_edit_tab_widget('groupname')->value();
+ }
+ elsif ($previus_tab eq $groupEditLabel{group_users}) {
+ my $tbl = $self->get_edit_tab_widget('members');
+ $groupData{members} = undef;
+ my @members;
+ my $i;
+ for($i=0;$i<$tbl->itemsCount();$i++) {
+ push (@members, $tbl->item($i)->label()) if $tbl->toCBYTableItem($tbl->item($i))->checked();
+ }
+ $groupData{members} = [ @members ];
+ }
+
+ return %groupData;
+}
+
+
+sub _storeDataFromUserEditPreviousTab {
+ my ($self, %userData) = @_;
+
+ my $previus_tab = $self->get_edit_tab_widget('edit_tab_label');
+ if (!$previus_tab) {
+ return %userData;
+ }
+ elsif ($previus_tab eq $userEditLabel{user_data}) {
+ $userData{full_name} = $self->get_edit_tab_widget('full_name')->value();
+ $userData{username} = $self->get_edit_tab_widget('login_name')->value() ;
+ $userData{shell} = $self->get_edit_tab_widget('login_shell')->value();
+ $userData{homedir} = $self->get_edit_tab_widget('homedir')->value();
+ my $passwd = $self->get_edit_tab_widget('password')->value();
+ $userData{password} = $passwd;
+ $passwd = $self->get_edit_tab_widget('password1')->value();
+ $userData{password1} = $passwd;
+ }
+ elsif ($previus_tab eq $userEditLabel{account_info}) {
+ $userData{acc_check_exp} = $self->get_edit_tab_widget('acc_check_exp')->value();
+ $userData{acc_expy} = $self->get_edit_tab_widget('acc_expy')->value();
+ $userData{acc_expm} = $self->get_edit_tab_widget('acc_expm')->value();
+ $userData{acc_expd} = $self->get_edit_tab_widget('acc_expd')->value();
+ $userData{lockuser} = $self->get_edit_tab_widget('lockuser')->value();
+ $userData{icon_face} = $self->get_edit_tab_widget('icon_face')->label();
+ }
+ elsif ($previus_tab eq $userEditLabel{password_info}) {
+ $userData{pwd_check_exp} = $self->get_edit_tab_widget('pwd_check_exp')->value();
+ $userData{pwd_exp_min} = $self->get_edit_tab_widget('pwd_exp_min')->value();
+ $userData{pwd_exp_max} = $self->get_edit_tab_widget('pwd_exp_max')->value();
+ $userData{pwd_exp_warn} = $self->get_edit_tab_widget('pwd_exp_warn')->value();
+ $userData{pwd_exp_inact} = $self->get_edit_tab_widget('pwd_exp_inact')->value();
+ }
+ elsif ($previus_tab eq $userEditLabel{groups}) {
+ my $tbl = $self->get_edit_tab_widget('members');
+ $userData{members} = undef;
+ my @members;
+ my $i;
+ for($i=0;$i<$tbl->itemsCount();$i++) {
+ push (@members, $tbl->item($i)->label()) if $tbl->toCBYTableItem($tbl->item($i))->checked();
+ }
+ $userData{members} = [ @members ];
+
+ if ($self->get_edit_tab_widget('primary_group')->selectedItem()) {
+ my $Gent = $self->ctx->LookupGroupByName($self->get_edit_tab_widget('primary_group')->selectedItem()->label());
+ my $primgroup = $Gent->Gid($self->USER_GetValue);
+
+ $userData{primary_group} = $primgroup;
+ }
+ else {
+ $userData{primary_group} = -1;
+ }
+ }
+
+ return %userData;
+}
+
+#=============================================================
+
+=head2 _userDataTabWidget
+
+=head3 INPUT
+
+ $self: this object
+ $dialog: YUI dialog that owns the YUI replace point
+ $replace_pnt: YUI replace point, needed to add a new tab
+ widget
+ %userData: hash containing user data info, tabs are
+ removed and added again on selection, so
+ data must be saved outside of widgets.
+ $previus_tab: previous tab widget label, needed to store
+ user data from the old tab before removing
+ it, if user changed something.
+
+=head3 OUTPUT
+
+ %userDataWidget: hash containing new YUI widget objects
+ such as:
+ retunred onject from _buildUserData and
+ homedir.
+
+=head3 DESCRIPTION
+
+ This internal method removes old tab widget saving its
+ relevant data into userData and creates new selected table
+ to be shown.
+
+=cut
+
+#=============================================================
+sub _userDataTabWidget {
+ my ($self, $dialog, $replace_pnt, %userData) = @_;
+
+ my $factory = yui::YUI::widgetFactory;
+
+ $dialog->startMultipleChanges();
+
+ $replace_pnt->deleteChildren();
+ my $layout = $factory->createVBox($replace_pnt);
+ my %userDataWidget = $self->_buildUserData($layout, $userData{shell});
+
+ ## user 'login name'
+ my $align = $factory->createRight($layout);
+ my $hbox = $factory->createHBox($align);
+ my $label = $factory->createLabel($hbox, N("Home:") );
+ $userDataWidget{homedir} = $factory->createInputField($hbox, "", 0);
+ $label->setWeight($yui::YD_HORIZ, 1);
+ $userDataWidget{homedir}->setWeight($yui::YD_HORIZ, 2);
+
+ # fill data into widgets
+ ##
+ # full_name, login_name, password, password1,
+ # login_shell
+ $userDataWidget{full_name}->setValue($userData{full_name});
+ $userDataWidget{login_name}->setValue($userData{username});
+ $userDataWidget{password}->setValue($userData{password}) if $userData{password};
+ $userDataWidget{password1}->setValue($userData{password1}) if $userData{password1};
+ $userDataWidget{homedir}->setValue($userData{homedir});
+
+ $replace_pnt->showChild();
+ $dialog->recalcLayout();
+ $dialog->doneMultipleChanges();
+
+ return %userDataWidget;
+}
+
+
+#=============================================================
+
+=head2 _groupDataTabWidget
+
+=head3 INPUT
+
+ $self: this object
+ $dialog: YUI dialog that owns the YUI replace point
+ $replace_pnt: YUI replace point, needed to add a new tab
+ widget
+ %groupData: hash containing group data info, tabs are
+ removed and added again on selection, so
+ data must be saved outside of widgets.
+ $previus_tab: previous tab widget label, needed to store
+ group data from the old tab before removing
+ it, if user changed something.
+
+=head3 OUTPUT
+
+ %groupDataWidget: hash containing new YUI widget objects
+ such as:
+ groupname.
+
+=head3 DESCRIPTION
+
+ This internal method removes old tab widget saving its
+ relevant data into groupData and creates new selected table
+ to be shown.
+
+=cut
+
+#=============================================================
+sub _groupDataTabWidget {
+ my ($self, $dialog, $replace_pnt, %groupData) = @_;
+
+ my $factory = yui::YUI::widgetFactory;
+
+ $dialog->startMultipleChanges();
+
+ $replace_pnt->deleteChildren();
+ my $layout = $factory->createVBox($replace_pnt);
+
+ my %groupDataWidget;
+
+ ## user 'login name'
+ my $align = $factory->createRight($layout);
+ my $hbox = $factory->createHBox($align);
+ my $label = $factory->createLabel($hbox, N("Group Name:") );
+ $groupDataWidget{groupname} = $factory->createInputField($hbox, "", 0);
+ $label->setWeight($yui::YD_HORIZ, 1);
+ $groupDataWidget{groupname}->setWeight($yui::YD_HORIZ, 2);
+
+ $groupDataWidget{groupname}->setValue($groupData{groupname});
+
+ $replace_pnt->showChild();
+ $dialog->recalcLayout();
+ $dialog->doneMultipleChanges();
+
+ return %groupDataWidget;
+}
+
+
+sub _userAccountInfoTabWidget {
+ my ($self, $dialog, $replace_pnt, %userData) = @_;
+
+ my $factory = yui::YUI::widgetFactory;
+
+ $dialog->startMultipleChanges();
+
+ $replace_pnt->deleteChildren();
+ my $layout = $factory->createVBox($replace_pnt);
+
+ my %userAccountWidget;
+ $userAccountWidget{acc_check_exp} = $factory->createCheckBoxFrame($layout, N("Enable account expiration"), 1);
+ my $align = $factory->createRight($userAccountWidget{acc_check_exp});
+ my $hbox = $factory->createHBox($align);
+ my $label = $factory->createLabel($hbox, N("Account expires (YYYY-MM-DD):"));
+ $userAccountWidget{acc_expy} = $factory->createIntField($hbox, "", 1970, 9999, $userData{acc_expy});
+ $userAccountWidget{acc_expm} = $factory->createIntField($hbox, "", 1, 12, $userData{acc_expm});
+ $userAccountWidget{acc_expd} = $factory->createIntField($hbox, "", 1, 31, $userData{acc_expd});
+ $userAccountWidget{acc_check_exp}->setValue($userData{acc_check_exp});
+ $label->setWeight($yui::YD_HORIZ, 2);
+ $align = $factory->createLeft($layout);
+ $userAccountWidget{lockuser} = $factory->createCheckBox($align, N("Lock User Account"), $userData{lockuser});
+
+ $align = $factory->createLeft($layout);
+ $hbox = $factory->createHBox($align);
+ $label = $factory->createLabel($hbox, N("Click on the icon to change it"));
+ $userAccountWidget{icon_face} = $factory->createPushButton($hbox, "");
+ $userAccountWidget{icon_face}->setIcon(AdminPanel::Shared::Users::face2png($userData{icon_face}));
+ $userAccountWidget{icon_face}->setLabel($userData{icon_face});
+
+ $replace_pnt->showChild();
+ $dialog->recalcLayout();
+ $dialog->doneMultipleChanges();
+
+ return %userAccountWidget;
+}
+
+
+sub _userPasswordInfoTabWidget {
+ my ($self, $dialog, $replace_pnt, %userData) = @_;
+
+ my $factory = yui::YUI::widgetFactory;
+
+ $dialog->startMultipleChanges();
+
+ $replace_pnt->deleteChildren();
+ my $layout = $factory->createVBox($replace_pnt);
+
+ my %userPasswordWidget;
+ my $userEnt = $self->ctx->LookupUserByName($userData{username});
+ my $lastchg = $userEnt->ShadowLastChange($self->USER_GetValue);
+
+ my $align = $factory->createLeft($layout);
+ my $hbox = $factory->createHBox($align);
+ my $label = $factory->createLabel($hbox, N("User last changed password on: "));
+ my $dayStr = $factory->createLabel($hbox, "");
+ my $month = $factory->createLabel($hbox, "");
+ my $dayInt = $factory->createLabel($hbox, "");
+ my $year = $factory->createLabel($hbox, "");
+ if ($lastchg) {
+ my $times = TimeOfArray($lastchg, 0);
+ $dayStr->setValue($times->{daystr});
+ $month->setValue($times->{month});
+ $dayInt->setValue($times->{dayint});
+ $year->setValue($times->{year});
+ }
+
+ $userPasswordWidget{pwd_check_exp} = $factory->createCheckBoxFrame($layout, N("Enable Password Expiration"), 1);
+ $layout = $factory->createVBox($userPasswordWidget{pwd_check_exp});
+ $align = $factory->createLeft($layout);
+ $hbox = $factory->createHBox($align);
+ $label = $factory->createLabel($hbox, N("Days before change allowed:"));
+ $userPasswordWidget{pwd_exp_min} = $factory->createInputField($hbox, "", 0);
+ $userPasswordWidget{pwd_exp_min}->setValue("$userData{pwd_exp_min}");
+ $label->setWeight($yui::YD_HORIZ, 1);
+ $userPasswordWidget{pwd_exp_min}->setWeight($yui::YD_HORIZ, 2);
+
+ $align = $factory->createLeft($layout);
+ $hbox = $factory->createHBox($align);
+ $label = $factory->createLabel($hbox, N("Days before change required:"));
+ $userPasswordWidget{pwd_exp_max} = $factory->createInputField($hbox, "", 0);
+ $userPasswordWidget{pwd_exp_max}->setValue("$userData{pwd_exp_max}");
+ $label->setWeight($yui::YD_HORIZ, 1);
+ $userPasswordWidget{pwd_exp_max}->setWeight($yui::YD_HORIZ, 2);
+
+ $align = $factory->createLeft($layout);
+ $hbox = $factory->createHBox($align);
+ $label = $factory->createLabel($hbox, N("Days warning before change:"));
+ $userPasswordWidget{pwd_exp_warn} = $factory->createInputField($hbox, "", 0);
+ $userPasswordWidget{pwd_exp_warn}->setValue("$userData{pwd_exp_warn}");
+ $label->setWeight($yui::YD_HORIZ, 1);
+ $userPasswordWidget{pwd_exp_warn}->setWeight($yui::YD_HORIZ, 2);
+
+ $align = $factory->createLeft($layout);
+ $hbox = $factory->createHBox($align);
+ $label = $factory->createLabel($hbox, N("Days before account inactive:"));
+ $userPasswordWidget{pwd_exp_inact} = $factory->createInputField($hbox, "", 0);
+ $userPasswordWidget{pwd_exp_inact}->setValue("$userData{pwd_exp_inact}");
+ $label->setWeight($yui::YD_HORIZ, 1);
+ $userPasswordWidget{pwd_exp_inact}->setWeight($yui::YD_HORIZ, 2);
+
+ $userPasswordWidget{pwd_check_exp}->setValue($userData{pwd_check_exp});
+
+ $replace_pnt->showChild();
+ $dialog->recalcLayout();
+ $dialog->doneMultipleChanges();
+
+ return %userPasswordWidget;
+}
+
+sub _groupUsersTabWidget {
+ my ($self, $dialog, $replace_pnt, %groupData) = @_;
+
+ my $factory = yui::YUI::widgetFactory;
+ my $mageiaPlugin = "mga";
+ my $mgaFactory = yui::YExternalWidgets::externalWidgetFactory($mageiaPlugin);
+ $mgaFactory = yui::YMGAWidgetFactory::getYMGAWidgetFactory($mgaFactory);
+
+ $dialog->startMultipleChanges();
+
+ $replace_pnt->deleteChildren();
+
+ my %groupUsersWidget;
+
+ my $layout = labeledFrameBox($replace_pnt, N("Select the users to join this group:"));
+
+ my $yTableHeader = new yui::YTableHeader();
+ $yTableHeader->addColumn("", $yui::YAlignBegin);
+ $yTableHeader->addColumn(N("User"), $yui::YAlignBegin);
+
+ $groupUsersWidget{members} = $mgaFactory->createCBTable($layout, $yTableHeader, $yui::YCBTableCheckBoxOnFirstColumn);
+
+ my $groupEnt = $self->ctx->LookupGroupByName($groupData{groupname});
+ my $users = $self->ctx->UsersEnumerate;
+ my @susers = sort(@$users);
+
+ my $itemCollection = new yui::YItemCollection;
+ my $members = $groupData{members};
+ foreach my $user (@susers) {
+ my $item = new yui::YCBTableItem($user);
+ $item->check(member($user, @$members));
+ $item->setLabel($user);
+ $itemCollection->push($item);
+ $item->DISOWN();
+ }
+ $groupUsersWidget{members}->addItems($itemCollection);
+
+ $replace_pnt->showChild();
+ $dialog->recalcLayout();
+ $dialog->doneMultipleChanges();
+
+ return %groupUsersWidget;
+}
+
+sub _userGroupsTabWidget {
+ my ($self, $dialog, $replace_pnt, %userData) = @_;
+
+ my $factory = yui::YUI::widgetFactory;
+ my $mageiaPlugin = "mga";
+ my $mgaFactory = yui::YExternalWidgets::externalWidgetFactory($mageiaPlugin);
+ $mgaFactory = yui::YMGAWidgetFactory::getYMGAWidgetFactory($mgaFactory);
+
+ $dialog->startMultipleChanges();
+
+ $replace_pnt->deleteChildren();
+
+ my %userGroupsWidget;
+ my $userEnt = $self->ctx->LookupUserByName($userData{username});
+ my $lastchg = $userEnt->ShadowLastChange($self->USER_GetValue);
+
+ my $layout = labeledFrameBox($replace_pnt, N("Select groups that the user will be member of:"));
+
+ my $yTableHeader = new yui::YTableHeader();
+ $yTableHeader->addColumn("", $yui::YAlignBegin);
+ $yTableHeader->addColumn(N("Group"), $yui::YAlignBegin);
+
+ $userGroupsWidget{members} = $mgaFactory->createCBTable($layout, $yTableHeader, $yui::YCBTableCheckBoxOnFirstColumn);
+
+ my $grps = $self->ctx->GroupsEnumerate;
+ my @sgroups = sort @$grps;
+
+ my $itemCollection = new yui::YItemCollection;
+ my $members = $userData{members};
+ foreach my $group (@sgroups) {
+ my $item = new yui::YCBTableItem($group);
+ $item->check(member($group, @$members));
+ $item->setLabel($group);
+ $itemCollection->push($item);
+ $item->DISOWN();
+ }
+ $userGroupsWidget{members}->addItems($itemCollection);
+ $userGroupsWidget{members}->setNotify(1);
+ my $primgroup = '';
+ if ($userData{primary_group} != -1) {
+ my $Gent = $self->ctx->LookupGroupById($userData{primary_group});
+ $primgroup = $Gent->GroupName($self->USER_GetValue);
+ }
+
+ my $align = $factory->createLeft($layout);
+ my $hbox = $factory->createHBox($align);
+ my $label = $factory->createLabel($hbox, N("Primary Group"));
+ $userGroupsWidget{primary_group} = $factory->createComboBox($hbox, "", 0);
+ my $itemColl = new yui::YItemCollection;
+ foreach my $member (@$members) {
+ my $item = new yui::YItem ($member, 0);
+ $item->setSelected(1) if ($item->label() eq $primgroup);
+ $itemColl->push($item);
+ $item->DISOWN();
+ }
+ $userGroupsWidget{primary_group}->addItems($itemColl);
+ $label->setWeight($yui::YD_HORIZ, 1);
+ $userGroupsWidget{primary_group}->setWeight($yui::YD_HORIZ, 2);
+
+ $replace_pnt->showChild();
+ $dialog->recalcLayout();
+ $dialog->doneMultipleChanges();
+
+ return %userGroupsWidget;
+}
+
+sub _groupEdit_Ok {
+ my ($self, %groupData) = @_;
+
+ # update last changes if any
+ %groupData = $self->_storeDataFromGroupEditPreviousTab(%groupData);
+
+ my ($continue, $errorString) = valid_groupname($groupData{groupname});
+ if (!$continue) {
+ AdminPanel::Shared::msgBox($errorString) if ($errorString);
+ return $continue;
+ }
+ my $groupEnt = $self->ctx->LookupGroupByName($groupData{start_groupname});
+ if ($groupData{start_groupname} ne $groupData{groupname}) {
+ $groupEnt->GroupName($groupData{groupname});
+ }
+
+ my $members = $groupData{members};
+ my $gid = $groupEnt->Gid($self->USER_GetValue);
+ my $users = $self->ctx->UsersEnumerate;
+ my @susers = sort(@$users);
+
+ foreach my $user (@susers) {
+ my $uEnt = $self->ctx->LookupGroupByName($user);
+ if ($uEnt) {
+ my $ugid = $uEnt->Gid($self->USER_GetValue);
+ my $m = $self->ctx->EnumerateUsersByGroup($groupData{start_groupname});
+ if (member($user, @$members)) {
+ if (!$self->_inArray($user, $m)) {
+ if ($ugid != $gid) {
+ eval { $groupEnt->MemberName($user,1) };
+ }
+ }
+ }
+ else {
+ if ($self->_inArray($user, $m)) {
+ if ($ugid == $gid) {
+ AdminPanel::Shared::msgBox(N("You cannot remove user '%s' from their primary group", $user));
+ return 0;
+ }
+ else {
+ eval { $groupEnt->MemberName($user,2) };
+ }
+ }
+ }
+ }
+ }
+
+ $self->ctx->GroupModify($groupEnt);
+ $self->_refresh();
+
+ return 1;
+}
+
+sub _userEdit_Ok {
+ my ($self, %userData) = @_;
+
+ # update last changes if any
+ %userData = $self->_storeDataFromUserEditPreviousTab(%userData);
+
+ my ($continue, $errorString) = valid_username($userData{username});
+ if (!$continue) {
+ AdminPanel::Shared::msgBox($errorString) if ($errorString);
+ return $continue;
+ }
+
+ if ( $userData{password} ne $userData{password1}) {
+ AdminPanel::Shared::msgBox(N("Password Mismatch"));
+ return 0;
+ }
+ my $userEnt = $self->ctx->LookupUserByName($userData{username});
+ if ($userData{password} ne '') {
+ my $sec = security::level::get();
+ if ($sec > 3 && length($userData{password}) < 6) {
+ AdminPanel::Shared::msgBox(N("This password is too simple. \n Good passwords should be > 6 characters"));
+ return 0;
+ }
+ $self->ctx->UserSetPass($userEnt, $userData{password});
+ }
+
+ $userEnt->UserName($userData{username});
+ $userEnt->Gecos($userData{full_name});
+ $userEnt->HomeDir($userData{homedir});
+ $userEnt->LoginShell($userData{shell});
+ my $username = $userEnt->UserName($self->USER_GetValue);
+ my $grps = $self->ctx->GroupsEnumerate;
+ my @sgroups = sort @$grps;
+
+ my $members = $userData{members};
+ foreach my $group (@sgroups) {
+
+ my $gEnt = $self->ctx->LookupGroupByName($group);
+ my $ugid = $gEnt->Gid($self->USER_GetValue);
+ my $m = $gEnt->MemberName(1,0);
+ if (member($group, @$members)) {
+ if (!$self->_inArray($username, $m) && $userData{primary_group} != $ugid) {
+ eval { $gEnt->MemberName($username, 1) };
+ $self->ctx->GroupModify($gEnt);
+ }
+ }
+ else {
+ if ($self->_inArray($username, $m)) {
+ eval { $gEnt->MemberName($username, 2) };
+ $self->ctx->GroupModify($gEnt);
+ }
+ }
+ }
+ if ($userData{primary_group} == -1) {
+ AdminPanel::Shared::msgBox(N("Please select at least one group for the user"));
+ return 0;
+ }
+ $userEnt->Gid($userData{primary_group});
+
+ if ($userData{acc_check_exp}) {
+ my $yr = $userData{acc_expy};
+ my $mo = $userData{acc_expm};
+ my $dy = $userData{acc_expd};
+ if (!ValidInt($yr, $dy, $mo)) {
+ AdminPanel::Shared::msgBox(N("Please specify Year, Month and Day \n for Account Expiration "));
+ return 0;
+ }
+ my $Exp = ConvTime($dy, $mo, $yr);
+ $userEnt->ShadowExpire($Exp);
+ }
+ else {
+ $userEnt->ShadowExpire(ceil(-1))
+ }
+
+ if ($userData{pwd_check_exp}) {
+ my $allowed = int($userData{pwd_exp_min});
+ my $required = int($userData{pwd_exp_max});
+ my $warning = int($userData{pwd_exp_warn});
+ my $inactive = int($userData{pwd_exp_inact});
+ if ($allowed && $required && $warning && $inactive) {
+ $userEnt->ShadowMin($allowed);
+ $userEnt->ShadowMax($required);
+ $userEnt->ShadowWarn($warning);
+ $userEnt->ShadowInact($inactive);
+ }
+ else {
+ AdminPanel::Shared::msgBox(N("Please fill up all fields in password aging\n"));
+ return 0;
+ }
+ }
+ else {
+ $userEnt->ShadowMin(-1);
+ $userEnt->ShadowMax(99999);
+ $userEnt->ShadowWarn(-1);
+ $userEnt->ShadowInact(-1);
+ }
+
+ $self->ctx->UserModify($userEnt);
+
+ if ($userData{lockuser}) {
+ !$self->ctx->IsLocked($userEnt) and $self->ctx->Lock($userEnt);
+ }
+ else {
+ $self->ctx->IsLocked($userEnt) and $self->ctx->UnLock($userEnt);
+ }
+
+ defined $userData{icon_face} and AdminPanel::Shared::Users::addKdmIcon($userData{username}, $userData{icon_face});
+ $self->_refresh();
+
+ return 1;
+}
+
+
+
+sub _editUserDialog {
+ my $self = shift;
+
+ my $dontcreatehomedir = 0;
+ my $is_system = 0;
+
+ ## push application title
+ my $appTitle = yui::YUI::app()->applicationTitle();
+ ## set new title to get it in dialog
+ yui::YUI::app()->setApplicationTitle(N("Edit User"));
+
+ my $factory = yui::YUI::widgetFactory;
+ my $optional = yui::YUI::optionalWidgetFactory;
+
+ my $dlg = $factory->createPopupDialog();
+ my $layout = $factory->createVBox($dlg);
+
+ my %tabs;
+ if ($optional->hasDumbTab()) {
+ my $hbox = $factory->createHBox($layout);
+ my $align = $factory->createHCenter($hbox);
+ $tabs{widget} = $optional->createDumbTab($align);
+
+ $tabs{user_data} = new yui::YItem($userEditLabel{user_data});
+ $tabs{user_data}->setSelected();
+ $tabs{used} = $tabs{user_data}->label();
+ $tabs{widget}->addItem( $tabs{user_data} );
+ $tabs{user_data}->DISOWN();
+
+ $tabs{account_info} = new yui::YItem($userEditLabel{account_info});
+ $tabs{widget}->addItem( $tabs{account_info} );
+ $tabs{account_info}->DISOWN();
+
+ $tabs{password_info} = new yui::YItem($userEditLabel{password_info});
+ $tabs{widget}->addItem( $tabs{password_info} );
+ $tabs{password_info}->DISOWN();
+
+ $tabs{groups} = new yui::YItem($userEditLabel{groups});
+ $tabs{widget}->addItem( $tabs{groups} );
+ $tabs{groups}->DISOWN();
+
+ my $vbox = $factory->createVBox($tabs{widget});
+ $align = $factory->createLeft($vbox);
+ $tabs{replace_pnt} = $factory->createReplacePoint($align);
+
+ $hbox = $factory->createHBox($vbox);
+ $align = $factory->createRight($hbox);
+ my $cancelButton = $factory->createPushButton($align, N("Cancel"));
+ my $okButton = $factory->createPushButton($hbox, N("Ok"));
+
+ my %userData = $self->_getUserInfo();
+ # userData here should be tested because it could be undef
+
+ # Useful entry point for the current edit user/group tab widget
+ $self->set_edit_tab_widget( $self->_userDataTabWidget($dlg, $tabs{replace_pnt}, %userData) );
+ $self->set_edit_tab_widget( edit_tab_label => $userEditLabel{user_data});
+
+ while(1) {
+ my $event = $dlg->waitForEvent();
+ my $eventType = $event->eventType();
+
+ #event type checking
+ if ($eventType == $yui::YEvent::CancelEvent) {
+ last;
+ }
+ elsif ($eventType == $yui::YEvent::MenuEvent) {
+ ### MENU ###
+ my $item = $event->item();
+ if ($item->label() eq $tabs{user_data}->label()) {
+ %userData = $self->_storeDataFromUserEditPreviousTab(%userData);
+ my %edit_tab = $self->_userDataTabWidget($dlg, $tabs{replace_pnt}, %userData );
+ $self->edit_tab_widgets( {} );
+ $self->set_edit_tab_widget(%edit_tab);
+ $self->set_edit_tab_widget( edit_tab_label => $userEditLabel{user_data});
+ }
+ elsif ($item->label() eq $tabs{account_info}->label()) {
+ %userData = $self->_storeDataFromUserEditPreviousTab(%userData);
+ my %edit_tab = $self->_userAccountInfoTabWidget($dlg, $tabs{replace_pnt}, %userData );
+ $self->edit_tab_widgets( {} );
+ $self->set_edit_tab_widget(%edit_tab);
+ $self->set_edit_tab_widget( edit_tab_label => $userEditLabel{account_info});
+ }
+ elsif ($item->label() eq $tabs{password_info}->label()) {
+ %userData = $self->_storeDataFromUserEditPreviousTab(%userData);
+ my %edit_tab = $self->_userPasswordInfoTabWidget($dlg, $tabs{replace_pnt}, %userData );
+ $self->edit_tab_widgets( {} );
+ $self->set_edit_tab_widget(%edit_tab);
+ $self->set_edit_tab_widget( edit_tab_label => $userEditLabel{password_info});
+ }
+ elsif ($item->label() eq $tabs{groups}->label()) {
+ %userData = $self->_storeDataFromUserEditPreviousTab(%userData);
+ my %edit_tab = $self->_userGroupsTabWidget($dlg, $tabs{replace_pnt}, %userData );
+ $self->edit_tab_widgets( {} );
+ $self->set_edit_tab_widget(%edit_tab);
+ $self->set_edit_tab_widget( edit_tab_label => $userEditLabel{groups});
+ }
+ }
+ elsif ($eventType == $yui::YEvent::WidgetEvent) {
+ ### widget
+ my $widget = $event->widget();
+ if ($widget == $cancelButton) {
+ last;
+ }
+ elsif ($widget == $okButton) {
+ ## save changes
+ if ($self->_userEdit_Ok(%userData)) {
+ last;
+ }
+ }
+# last: managing tab widget events
+ else {
+ my $current_tab = $self->get_edit_tab_widget('edit_tab_label');
+ if ($current_tab && $current_tab eq $userEditLabel{account_info}) {
+ if ($widget == $self->get_edit_tab_widget('icon_face')) {
+ my $iconLabel = $self->_skipShortcut($self->get_edit_tab_widget('icon_face')->label());
+ my $nextIcon = GetFaceIcon($iconLabel, 1);
+ $self->get_edit_tab_widget('icon_face')->setLabel($nextIcon);
+ $self->get_edit_tab_widget('icon_face')->setIcon(AdminPanel::Shared::Users::face2png($nextIcon));
+ }
+ }
+ elsif ($current_tab && $current_tab eq $userEditLabel{groups}) {
+ if ($widget == $self->get_edit_tab_widget('members')) {
+ my $item = $self->get_edit_tab_widget('members')->changedItem();
+ if ($item) {
+ if ($item->checked()) {
+ # add it to possible primary groups
+ my $pgItem = new yui::YItem ($item->label(), 0);
+ $self->get_edit_tab_widget('primary_group')->addItem($pgItem);
+ }
+ else {
+ # remove it to possible primary groups
+ $dlg->startMultipleChanges();
+ my $itemColl = new yui::YItemCollection;
+ my $tbl = $self->get_edit_tab_widget('members');
+ for(my $i=0;$i < $tbl->itemsCount();$i++) {
+ if ($tbl->toCBYTableItem($tbl->item($i))->checked()) {
+ my $pgItem = new yui::YItem ($tbl->item($i)->label(), 0);
+ my $Gent = $self->ctx->LookupGroupById($userData{primary_group});
+ my $primgroup = $Gent->GroupName($self->USER_GetValue);
+ $pgItem->setSelected(1) if ($pgItem->label() eq $primgroup);
+
+ $itemColl->push($pgItem);
+ $pgItem->DISOWN();
+ }
+ }
+ $self->get_edit_tab_widget('primary_group')->deleteAllItems();
+ $self->get_edit_tab_widget('primary_group')->addItems($itemColl);
+ $dlg->recalcLayout();
+ $dlg->doneMultipleChanges();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ }
+ else {
+ AdminPanel::Shared::warningMsgBox(N("Cannot create tab widgets"));
+ }
+
+ destroy $dlg;
+
+ #restore old application title
+ yui::YUI::app()->setApplicationTitle($appTitle);
+
+}
+
+sub _editGroupDialog {
+ my $self = shift;
+
+ ## push application title
+ my $appTitle = yui::YUI::app()->applicationTitle();
+ ## set new title to get it in dialog
+ yui::YUI::app()->setApplicationTitle(N("Edit Group"));
+
+ my $factory = yui::YUI::widgetFactory;
+ my $optional = yui::YUI::optionalWidgetFactory;
+
+ my $dlg = $factory->createPopupDialog();
+ my $layout = $factory->createVBox($dlg);
+
+ my %tabs;
+ if ($optional->hasDumbTab()) {
+ my $hbox = $factory->createHBox($layout);
+ my $align = $factory->createHCenter($hbox);
+ $tabs{widget} = $optional->createDumbTab($align);
+
+ $tabs{group_data} = new yui::YItem($groupEditLabel{group_data});
+ $tabs{group_data}->setSelected();
+ $tabs{widget}->addItem( $tabs{group_data} );
+ $tabs{group_data}->DISOWN();
+
+ $tabs{group_users} = new yui::YItem($groupEditLabel{group_users});
+ $tabs{widget}->addItem( $tabs{group_users} );
+ $tabs{group_users}->DISOWN();
+
+ my $vbox = $factory->createVBox($tabs{widget});
+ $align = $factory->createLeft($vbox);
+ $tabs{replace_pnt} = $factory->createReplacePoint($align);
+
+ $hbox = $factory->createHBox($vbox);
+ $align = $factory->createRight($hbox);
+ my $cancelButton = $factory->createPushButton($align, N("Cancel"));
+ my $okButton = $factory->createPushButton($hbox, N("Ok"));
+
+ my %groupData = $self->_getGroupInfo();
+ # groupData here should be tested because it could be undef
+
+# %groupData: selected group info as:
+# $groupname: group name
+# $members: users that are members of this group
+
+
+ # Useful entry point for the current edit user/group tab widget
+ $self->set_edit_tab_widget( $self->_groupDataTabWidget($dlg, $tabs{replace_pnt}, %groupData) );
+ $self->set_edit_tab_widget( edit_tab_label => $groupEditLabel{group_data});
+
+ while(1) {
+ my $event = $dlg->waitForEvent();
+ my $eventType = $event->eventType();
+
+ #event type checking
+ if ($eventType == $yui::YEvent::CancelEvent) {
+ last;
+ }
+ elsif ($eventType == $yui::YEvent::MenuEvent) {
+ ### MENU ###
+ my $item = $event->item();
+ if ($item->label() eq $tabs{group_data}->label()) {
+ %groupData = $self->_storeDataFromGroupEditPreviousTab(%groupData);
+ my %edit_tab = $self->_groupDataTabWidget($dlg, $tabs{replace_pnt}, %groupData );
+ $self->edit_tab_widgets( {} );
+ $self->set_edit_tab_widget(%edit_tab);
+ $self->set_edit_tab_widget( edit_tab_label => $groupEditLabel{group_data});
+ }
+ elsif ($item->label() eq $tabs{group_users}->label()) {
+ %groupData = $self->_storeDataFromGroupEditPreviousTab(%groupData);
+ my %edit_tab = $self->_groupUsersTabWidget($dlg, $tabs{replace_pnt}, %groupData );
+ $self->edit_tab_widgets( {} );
+ $self->set_edit_tab_widget(%edit_tab);
+ $self->set_edit_tab_widget( edit_tab_label => $groupEditLabel{group_users});
+ }
+ }
+ elsif ($eventType == $yui::YEvent::WidgetEvent) {
+ ### widget
+ my $widget = $event->widget();
+ if ($widget == $cancelButton) {
+ last;
+ }
+ elsif ($widget == $okButton) {
+ ## save changes
+ if ($self->_groupEdit_Ok(%groupData)) {
+ last;
+ }
+ }
+ }
+ }
+
+ }
+ else {
+ AdminPanel::Shared::warningMsgBox(N("Cannot create tab widgets"));
+ }
+
+ destroy $dlg;
+
+ #restore old application title
+ yui::YUI::app()->setApplicationTitle($appTitle);
+
+}
+
+sub _editUserOrGroup {
+ my $self = shift;
+
+ # TODO item management avoid label if possible
+ my $label = $self->_skipShortcut($self->get_widget('tabs')->selectedItem()->label());
+ if ($label eq N("Users") ) {
+ $self->_editUserDialog();
+ }
+ else {
+ $self->_editGroupDialog();
+ }
+ $self->_refresh();
+}
+
+
+sub _deleteUserOrGroup {
+ my $self = shift;
+
+ # TODO item management avoid label if possible
+ my $label = $self->_skipShortcut($self->get_widget('tabs')->selectedItem()->label());
+ if ($label eq N("Users") ) {
+ $self->_deleteUserDialog();
+ $self->_refresh();
+ }
+ else {
+ $self->_deleteGroupDialog();
+ $self->_refresh();
+ }
+}
+
+
+sub _refresh {
+ my $self = shift;
+
+ # TODO item management avoid label if possible
+ my $label = $self->_skipShortcut($self->get_widget('tabs')->selectedItem()->label());
+ if ($label eq N("Users") ) {
+ $self->_refreshUsers();
+ }
+ else {
+ $self->_refreshGroups();
+ }
+# TODO xguest
+# RefreshXguest(1);
+}
+
+# TODO context menu creation is missed in libyui
+sub _contextMenuActions {
+ my $self = shift;
+
+ my $item = $self->get_widget('table')->selectedItem();
+ if ($item) {
+ }
+}
+
+sub _refreshActions {
+ my $self = shift;
+
+ my $item = $self->get_widget('table')->selectedItem();
+ $self->dialog->startMultipleChanges();
+ $self->get_widget('action_menu')->deleteAllItems();
+
+ # do we need to undef them first?
+ $self->set_action_menu(
+ add_user => undef,
+ add_group => undef,
+ edit => undef,
+ del => undef,
+ inst => undef,
+ );
+ $self->set_action_menu(
+ add_user => new yui::YMenuItem(N("Add User")),
+ add_group => new yui::YMenuItem(N("Add Group")),
+ edit => new yui::YMenuItem(N("&Edit")),
+ del => new yui::YMenuItem(N("&Delete")),
+ inst => new yui::YMenuItem(N("Install guest account")),
+ );
+
+ my $itemColl = new yui::YItemCollection;
+ for my $pair ( $self->action_menu_pairs ) {
+ my $menuItem = $pair->[1];
+ if ($pair->[0] eq 'edit' || $pair->[0] eq 'del') {
+ if ($item) {
+ $itemColl->push($menuItem);
+ }
+ }
+ else {
+ $itemColl->push($menuItem);
+ }
+ $menuItem->DISOWN();
+ }
+ $self->get_widget('action_menu')->addItems($itemColl);
+ $self->get_widget('action_menu')->rebuildMenuTree();
+ if ($item) {
+ $self->get_widget('edit')->setEnabled();
+ $self->get_widget('del')->setEnabled();
+ }
+ else {
+ $self->get_widget('edit')->setDisabled();
+ $self->get_widget('del')->setDisabled();
+ }
+
+ $self->dialog->doneMultipleChanges();
+}
+
+
+sub manageUsersDialog {
+ my $self = shift;
+
+ ## TODO fix for adminpanel
+ my $pixdir = '/usr/share/userdrake/pixmaps/';
+ ## push application title
+ my $appTitle = yui::YUI::app()->applicationTitle();
+
+ ## set new title to get it in dialog
+ yui::YUI::app()->setApplicationTitle($self->name);
+ ## set icon if not already set by external launcher
+ yui::YUI::app()->setApplicationIcon($self->icon);
+
+
+ my $factory = yui::YUI::widgetFactory;
+ my $optional = yui::YUI::optionalWidgetFactory;
+
+
+ $self->dialog($factory->createMainDialog());
+ my $layout = $factory->createVBox($self->dialog);
+
+ my $hbox_headbar = $factory->createHBox($layout);
+ my $head_align_left = $factory->createLeft($hbox_headbar);
+ my $head_align_right = $factory->createRight($hbox_headbar);
+ my $headbar = $factory->createHBox($head_align_left);
+ my $headRight = $factory->createHBox($head_align_right);
+
+ my %fileMenu = (
+ widget => $factory->createMenuButton($headbar,N("File")),
+ refresh => new yui::YMenuItem(N("Refresh")),
+ quit => new yui::YMenuItem(N("&Quit")),
+ );
+
+ $fileMenu{ widget }->addItem($fileMenu{ refresh });
+ $fileMenu{ widget }->addItem($fileMenu{ quit });
+ $fileMenu{ widget }->rebuildMenuTree();
+
+ my $actionMenu = $factory->createMenuButton($headbar, N("Actions"));
+ $actionMenu->DISOWN();
+
+ my %helpMenu = (
+ widget => $factory->createMenuButton($headRight, N("&Help")),
+ help => new yui::YMenuItem(N("Help")),
+ report_bug => new yui::YMenuItem(N("Report Bug")),
+ about => new yui::YMenuItem(N("&About")),
+ );
+
+ while ( my ($key, $value) = each(%helpMenu) ) {
+ if ($key ne 'widget' ) {
+ $helpMenu{ widget }->addItem($value);
+ }
+ }
+ $helpMenu{ widget }->rebuildMenuTree();
+
+ my $hbox = $factory->createHBox($layout);
+ $hbox = $factory->createHBox($factory->createLeft($hbox));
+ $self->set_widget(
+ add_user => $factory->createIconButton($hbox, $pixdir . 'user_add.png', N("Add User")),
+ add_group => $factory->createIconButton($hbox, $pixdir . 'group_add.png', N("Add Group")),
+ edit => $factory->createIconButton($hbox, $pixdir . 'user_conf.png', N("Edit")),
+ del => $factory->createIconButton($hbox, $pixdir . 'user_del.png', N("Delete")),
+ refresh => $factory->createIconButton($hbox, $pixdir . 'refresh.png', N("Refresh")),
+ action_menu => $actionMenu,
+ );
+
+
+ $hbox = $factory->createHBox($layout);
+ $head_align_left = $factory->createLeft($hbox);
+ $self->set_widget(filter_system => $factory->createCheckBox($head_align_left, N("Filter system users"), 1));
+ $factory->createHSpacing($hbox, 3);
+ $head_align_right = $factory->createRight($hbox);
+ $headRight = $factory->createHBox($head_align_right);
+ $factory->createLabel($headRight, N("Search:"));
+ $self->set_widget(filter => $factory->createInputField($headRight, "", 0));
+ $self->set_widget(apply_filter => $factory->createPushButton($headRight, N("Apply filter")));
+ $self->get_widget('filter')->setWeight($yui::YD_HORIZ, 2);
+ $self->get_widget('apply_filter')->setWeight($yui::YD_HORIZ, 1);
+ $self->get_widget('filter_system')->setNotify(1);
+
+ my %tabs;
+ if ($optional->hasDumbTab()) {
+ $hbox = $factory->createHBox($layout);
+ my $align = $factory->createHCenter($hbox);
+ $self->set_widget(tabs => $optional->createDumbTab($align));
+ $tabs{users} = new yui::YItem(N("Users"));
+ $tabs{users}->setSelected();
+ $self->get_widget('tabs')->addItem( $tabs{users} );
+ $tabs{users}->DISOWN();
+ $tabs{groups} = new yui::YItem(N("Groups"));
+ $self->get_widget('tabs')->addItem( $tabs{groups} );
+ $tabs{groups}->DISOWN();
+ my $vbox = $factory->createVBox($self->get_widget('tabs'));
+ $align = $factory->createLeft($vbox);
+ $self->set_widget(replace_pnt => $factory->createReplacePoint($align));
+ $self->_createUserTable();
+ $self->get_widget('table')->setImmediateMode(1);
+ $self->get_widget('table')->DISOWN();
+ }
+
+ $self->_refreshActions();
+
+ # main loop
+ while(1) {
+ my $event = $self->dialog->waitForEvent();
+ my $eventType = $event->eventType();
+
+ #event type checking
+ if ($eventType == $yui::YEvent::CancelEvent) {
+ last;
+ }
+ elsif ($eventType == $yui::YEvent::MenuEvent) {
+### MENU ###
+ my $item = $event->item();
+ my $menuLabel = $item->label();
+ if ($menuLabel eq $fileMenu{ quit }->label()) {
+ last;
+ }
+ elsif ($menuLabel eq $helpMenu{about}->label()) {
+ my $license = translate($AdminPanel::Shared::License);
+ AboutDialog({ name => N("AdminUser"),
+ version => $self->VERSION,
+ copyright => N("Copyright (C) %s Mageia community", '2013-2014'),
+ license => $license,
+ comments => N("AdminUser is a Mageia user management tool \n(from the original idea of Mandriva userdrake)."),
+ website => 'http://www.mageia.org',
+ website_label => N("Mageia"),
+ authors => "Angelo Naselli <anaselli\@linux.it>\nMatteo Pasotti <matteo.pasotti\@gmail.com>",
+ translator_credits =>
+ #-PO: put here name(s) and email(s) of translator(s) (eg: "John Smith <jsmith@nowhere.com>")
+ N("_: Translator(s) name(s) & email(s)\n")}
+ );
+ }
+ elsif ($menuLabel eq $self->get_action_menu('add_user')->label()) {
+ $self->addUserDialog();
+ $self->_refresh();
+ }
+ elsif ($menuLabel eq $self->get_action_menu('add_group')->label()) {
+ $self->_addGroupDialog();
+ $self->_refresh();
+ }
+ elsif ($menuLabel eq $self->get_action_menu('del')->label()) {
+ $self->_deleteUserOrGroup();
+ }
+ elsif ($menuLabel eq $self->get_action_menu('edit')->label()) {
+ $self->_editUserOrGroup();
+ }
+ elsif ($self->get_widget('tabs') && $menuLabel eq $tabs{groups}->label()) {
+ $self->_createGroupTable();
+ }
+ elsif ($self->get_widget('tabs') && $menuLabel eq $tabs{users}->label()) {
+ $self->_createUserTable();
+ }
+ elsif ($menuLabel eq $fileMenu{refresh}->label()) {
+ $self->_refresh();
+ }
+ }
+ elsif ($eventType == $yui::YEvent::WidgetEvent) {
+### Buttons and widgets ###
+ my $widget = $event->widget();
+ if ($widget == $self->get_widget('add_user')) {
+ $self->addUserDialog();
+ $self->_refresh();
+ }
+ elsif ($widget == $self->get_widget('del')) {
+ $self->_deleteUserOrGroup();
+ }
+ elsif ($widget == $self->get_widget('table')) {
+ $self->_refreshActions();
+ my $wEvent = yui::YMGAWidgetFactory::getYWidgetEvent($event);
+ if ($wEvent && $wEvent->reason() == $yui::YEvent::Activated) {
+ $self->_editUserOrGroup();
+ }
+ }
+ elsif ($widget == $self->get_widget('add_group')) {
+ $self->_addGroupDialog();
+ $self->_refresh();
+ }
+ elsif ($widget == $self->get_widget('edit')) {
+ $self->_editUserOrGroup();
+ }
+ elsif ( $widget == $self->get_widget('filter_system') ||
+ $widget == $self->get_widget('refresh') ||
+ $widget == $self->get_widget('apply_filter') ) {
+ $self->_refresh();
+ }
+ }
+ }
+
+ $self->dialog->destroy() ;
+
+ #restore old application title
+ yui::YUI::app()->setApplicationTitle($appTitle) if $appTitle;
+}
+
+#=============================================================
+
+=head2 _skipShortcut
+
+=head3 INPUT
+
+ $self: this object
+ $label: an item label to be cleaned by keyboard shortcut "&"
+
+=head3 OUTPUT
+
+ $label: cleaned label
+
+=head3 DESCRIPTION
+
+ This internal method is a workaround to label that are
+ changed by "&" due to keyborad shortcut.
+
+=cut
+
+#=============================================================
+sub _skipShortcut {
+ my ($self, $label) = @_;
+
+ $label =~ s/&// if ($label);
+
+ return ($label);
+}
+
+#=============================================================
+
+=head2 _inArray
+
+=head3 INPUT
+
+ $self: this object
+ $item: item to search
+ $arr: array container
+
+=head3 OUTPUT
+
+ true: if the array contains the item
+
+=head3 DESCRIPTION
+
+This method returns if an item is into the array container
+
+=cut
+
+#=============================================================
+sub _inArray {
+ my ($self, $item, $arr) = @_;
+
+ return grep( /^$item$/, @$arr );
+}
+
+
+sub ValidInt {
+ foreach my $i (@_) { $i =~ /\d+/ or return 0 }
+ return 1;
+}
+
+sub ConvTime {
+ my ($day, $month, $year) = @_;
+ my ($tm, $days, $mon, $yr);
+ $mon = $month - 1; $yr = $year - 1900;
+ $tm = POSIX::mktime(0, 0, 0, $day, $mon, $yr);
+ $days = ceil($tm / (24 * 60 * 60));
+ return $days;
+}
+
+sub TimeOfArray {
+ my ($reltime, $cm) = @_;
+ my $h; my %mth = (Jan => 1, Feb => 2, Mar => 3, Apr => 4, May => 5, Jun => 6, Jul => 7, Aug => 8, Sep => 9, Oct => 10, Nov => 11, Dec => 12);
+ my $_t = localtime($reltime * 24 * 60 * 60) =~ /(\S+)\s+(\S+)\s+(\d+)\s+(\S+)\s+(\d+)/;
+ $h->{daystr} = $1;
+ $h->{month} = $2;
+ $h->{dayint} = $3;
+ $h->{year} = $5;
+ $cm and $h->{month} = $mth{$2};
+ $h;
+}
+
+
+no Moose;
+__PACKAGE__->meta->make_immutable;
+
+1;