# vim: set et ts=4 sw=4: #***************************************************************************** # # Copyright (c) 2013-2015 Matteo Pasotti # # 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 ManaTools::Module::Proxy; use Modern::Perl '2011'; use autodie; use Moose; use POSIX qw(ceil); use English; use utf8; use yui; use ManaTools::Shared qw(trim); use ManaTools::Shared::GUI; use ManaTools::Shared::Proxy; # TODROP but provides network::network use lib qw(/usr/lib/libDrakX); use network::network; use MDK::Common::System qw(getVarsFromSh); extends qw( ManaTools::Module ); has '+icon' => ( default => "/usr/share/mcc/themes/default/drakproxy-mdk.png" ); has '+name' => ( default => "Proxymanager", ); =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 'proxy' => ( is => 'rw', isa => 'HashRef', builder => "init_proxy" ); has 'sh_gui' => ( is => 'rw', init_arg => undef, builder => '_SharedUGUIInitialize' ); has 'loc' => ( is => 'rw', init_arg => undef, builder => '_localeInitialize' ); sub _localeInitialize { my $self = shift(); # TODO fix domain binding for translation $self->loc(ManaTools::Shared::Locales->new(domain_name => 'drakx-net') ); # TODO if we want to give the opportunity to test locally add dir_name => 'path' } sub _SharedUGUIInitialize { my $self = shift(); $self->sh_gui( ManaTools::Shared::GUI->new() ); } #============================================================= =head2 init_proxy =head3 DESCRIPTION =over 4 =item This method does initialize the proxy attribute provided by this class. =item $self->proxy is structured as follows: =over 6 =item B the string with the list of the excluded domains/addresses =item B the url of the http proxy =item B the url of the https proxy =item B the url for the ftp proxy =back =back =cut #============================================================= sub init_proxy { my %p = ( 'no_proxy' => '', 'http_proxy' => '', 'https_proxy' => '', 'ftp_proxy' => '', ); return \%p; } #============================================================= =head2 start =head3 INPUT $self: this object =head3 DESCRIPTION This method extends Module::start and is invoked to start proxy manager =cut #============================================================= sub start { my $self = shift; if ($EUID != 0) { $self->sh_gui->warningMsgBox({ title => $self->name, text => $self->loc->N("root privileges required"), }); return; } $self->_manageProxyDialog(); }; #============================================================= =head2 ask_for_X_restart =head3 INPUT $self: this object =head3 DESCRIPTION This method shows a message box warning the user that a X server restart is required =cut #============================================================= sub ask_for_X_restart { my $self = shift; $self->sh_gui->warningMsgBox({title=>$self->loc->N("X Restart Required"),text=>$self->loc->N("You need to log out and back in again for changes to take effect"),richtext=>1}); } #============================================================= =head2 validate =head3 INPUT $self: this object $proxy: the hash containing what returns from getVarFromSh eventually modified by the user =head3 DESCRIPTION This method returns true if the each value match certain conditions like the leading http:// for http proxy or https:// for the https proxy, etc. $proxy is passed by reference thus $proxy->{no_proxy} value is sanitized (trimmed). =cut #============================================================= sub validate { my $self = shift; my $proxy = shift; my $retval = 1; $proxy->{no_proxy} =~ s/\s//g; # using commas rather than slashes if($proxy->{http_proxy} !~ m,^($|http://),) { $self->sh_gui->warningMsgBox({title=>'Error',text=>$self->loc->N("Proxy should be http://..."),richtext=>0}); $retval = 0; } if($proxy->{https_proxy} !~ m,^($|https?://),) { $self->sh_gui->warningMsgBox({title=>'Error',text=>$self->loc->N("Proxy should be http://... or https://..."),richtext=>0}); $retval = 0; } if($proxy->{ftp_proxy} !~ m,^($|ftp://|http://),) { $self->sh_gui->warningMsgBox({title=>'Error',text=>$self->loc->N("URL should begin with 'ftp:' or 'http:'"),richtext=>0}); $retval = 0; } return $retval; } sub _manageProxyDialog { my $self = shift; ## TODO fix for manatools my $appTitle = yui::YUI::app()->applicationTitle(); my $appIcon = yui::YUI::app()->applicationIcon(); ## set new title to get it in dialog my $newTitle = $self->loc->N("Proxies configuration"); yui::YUI::app()->setApplicationTitle($newTitle); my $factory = yui::YUI::widgetFactory; my $optional = yui::YUI::optionalWidgetFactory; my $label_width = 25; my $inputfield_width = 45; # getVarsFromSh returns an empty hash if no vars are defined # possible alternatives: # . Config::Auto::parse my $proxy_curr_settings = { getVarsFromSh('/etc/profile.d/proxy.sh') }; my $httpsProxyEqualToHttpProxy = 0; if((defined($proxy_curr_settings->{http_proxy}) && defined($proxy_curr_settings->{https_proxy}))&& (($proxy_curr_settings->{http_proxy} eq $proxy_curr_settings->{https_proxy}) && ($proxy_curr_settings->{http_proxy} ne ""))){ $httpsProxyEqualToHttpProxy = 1; } # # @layout # # +------------------------------+ # | +------------+-------------+ | # | |LABELS | VALUES | | # | | | | | # | | | | | # | | | | | # | +------------+-------------+ | # +------------------------------+ $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); # app description my $hbox_content = $factory->createHBox($layout); $factory->createLabel($hbox_content, $self->loc->N("Here you can set up your proxies configuration (eg: http://my_caching_server:8080)")); $hbox_content = $factory->createHBox($layout); my $vbox_labels_flags = $factory->createVBox($hbox_content); my $vbox_inputfields = $factory->createVBox($hbox_content); # http proxy section my $httpproxy_label = $factory->createLabel($vbox_labels_flags, $self->loc->N("HTTP proxy")); my $http_proxy = $factory->createInputField($factory->createHBox($vbox_inputfields),"",0); $http_proxy->setValue($proxy_curr_settings->{http_proxy}) if(defined($proxy_curr_settings->{http_proxy})); $http_proxy->setWeight($yui::YD_HORIZ, 30); # flag to setup the https proxy with the same value of the http proxy my $ckbHttpEqHttps = $factory->createCheckBox($vbox_labels_flags, $self->loc->N("Use HTTP proxy for HTTPS connections"),$httpsProxyEqualToHttpProxy); $ckbHttpEqHttps->setNotify(1); # add a spacing as we have $factory->createLabel($factory->createHBox($vbox_inputfields)," "); # https proxy $factory->createLabel($vbox_labels_flags, $self->loc->N("HTTPS proxy")); my $https_proxy = $factory->createInputField($factory->createHBox($vbox_inputfields),"",0); $https_proxy->setValue($proxy_curr_settings->{https_proxy}) if(defined($proxy_curr_settings->{https_proxy})); $https_proxy->setWeight($yui::YD_HORIZ, 30); # ftp proxy $factory->createLabel($vbox_labels_flags, $self->loc->N("FTP proxy")); my $ftp_proxy = $factory->createInputField($factory->createHBox($vbox_inputfields),"",0); $ftp_proxy->setValue($proxy_curr_settings->{ftp_proxy}) if(defined($proxy_curr_settings->{ftp_proxy})); $ftp_proxy->setWeight($yui::YD_HORIZ, 30); # no-proxy list $factory->createLabel($vbox_labels_flags, $self->loc->N("No proxy for (comma separated list):")); my $no_proxy = $factory->createInputField($factory->createHBox($vbox_inputfields),"",0); $no_proxy->setValue($proxy_curr_settings->{no_proxy}) if(defined($proxy_curr_settings->{no_proxy})); $no_proxy->setWeight($yui::YD_HORIZ, 30); my $hbox_filler = $factory->createHBox($layout); $factory->createSpacing($hbox_filler,$yui::YD_VERT,2); 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,$self->loc->N("&About")); my $cancelButton = $factory->createPushButton($vbox_foot_right,$self->loc->N("&Cancel")); my $okButton = $factory->createPushButton($vbox_foot_right,$self->loc->N("&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 == $aboutButton) { $self->sh_gui->AboutDialog({ name => $appTitle, version => $VERSION, credits => "Copyright (c) 2013-2014 by Matteo Pasotti", license => "GPLv2", description => $self->loc->N("Graphical manager for proxies"), authors => "Matteo Pasotti <matteo.pasotti\@gmail.com>" } ); }elsif ($widget == $okButton) { # setup proxy attribute my %_proxy = ( no_proxy => $no_proxy->value(), http_proxy => $http_proxy->value(), https_proxy => $https_proxy->value(), ftp_proxy => $ftp_proxy->value() ); if($self->validate(\%_proxy)) { # validation succeded $self->proxy(\%_proxy); # save changes network::network::proxy_configure($self->proxy); $self->ask_for_X_restart(); last; } # validation failed next; }elsif ($widget == $ckbHttpEqHttps){ $https_proxy->setEnabled(!$ckbHttpEqHttps->isChecked()); } } } $self->dialog->destroy() ; #restore old application title yui::YUI::app()->setApplicationTitle($appTitle); } 1;