diff options
Diffstat (limited to 'lib/AdminPanel/Module')
| -rw-r--r-- | lib/AdminPanel/Module/AdminMouse.pm | 278 | ||||
| -rw-r--r-- | lib/AdminPanel/Module/Hosts.pm | 355 | ||||
| -rw-r--r-- | lib/AdminPanel/Module/Services.pm | 559 | ||||
| -rw-r--r-- | lib/AdminPanel/Module/Users.pm | 2570 | 
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 0000000..9e4e37c --- /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 0000000..fe6e011 --- /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 0000000..3332637 --- /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 0000000..16ea058 --- /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; | 
