#!/usr/bin/perl -Tw -I. -I/usr/local/positive/Perl use Pos::web; # This is kinda old.. but I still use somem stuff in it use Pos::db; use Pos::defaults; use Pos::Webtop::Web::OEMLoader; use Pos::Webtop::Web::Client; use Pos::Webtop::Web::Page; #use Pos::Webtop::Web::Box; use Pos::Webtop::Supernat; use Pos::Webtop::Dns; use Pos::Webtop::Wins; use CGI (); use strict; package Pos::Webtop::Toolbox; # Verbose logging my $verboseLog = 0; =head1 Toolbox object The Toolbox object is a utility class which has all the standard 'attributes and methods' that any runtime will need for execution. Utility methods that cross the whole scope of webtop (such as acl checking and message sending or similar) and common attributes that may be needed and should not be inherited (such as the ability to at any time call getWebtopDb to get a Pos::db object connected to the webtop db). =head1 METHODS =over 4 =cut =over 4 =item B Constructor, does the obvious. =cut sub new { my $this = shift; my $class = ref($this) || $this; my ($self) = @{{@_}}{qw/self/}; my ($tempTableFlag, $useClient) = @{{@_}}{qw/tempTableFlag useClient/}; $tempTableFlag = 1 unless defined $tempTableFlag; $useClient = 1 unless defined $useClient; if ( not defined $self ) { $self = {}; bless($self,$class); } # if we are in the web env with modperl, we need to make a page and client object... $self->{'page'} = undef; $self->{'client'} = undef; $self->{'cgi'} = undef; $self->{'oem'} = undef; my $cgi = $self->getCgi(); $self->setTempTableFlag(tempTableFlag=>$tempTableFlag); # Load OEM information my $db = $self->getWebtopDbReader; # We only create the client object if the caller requseted it (which is # default). RDA registration does not use a client object by default. if ($useClient) { my $client = $self->getClient; #$self->{'oem'} = Pos::Webtop::Web::OEMLoader::load(db => $db, userId => '2409' ); $self->{'oem'} = Pos::Webtop::Web::OEMLoader::load(db => $db, userId => $client->getUserId, cgi=> $cgi); } #$self->{'debugLevel'} = Pos::defaults::getWebtopDebugLevel(); # DEBUG: Uncomment this line to override default debug level $self->{'debugLevel'} = 1; return $self; } =item B Returns a Pos::db object connected to the policy database for writing. The connection is made on the first call to this function. Subsequent calls to this method return the same db object created by the first call. =cut sub getPolicyDb { my $self = shift; if ( not defined $self->{'policyDb'} ) { # v1 to v2 db move support #$self->{'policyDb'} = Pos::db::connectDB( name=> "policy", debug=> 1 ); my $dbinfo = Pos::defaults::db_info(name => "policy"); $dbinfo =~ s/policy1/policy/g; my $tempTableFlag = $self->{'tempTableFlag'}; $tempTableFlag = 1 unless defined $tempTableFlag; $self->{'policyDb'} = Pos::db->new( user=> $dbinfo, debug=> 0 , tempTableFlag=>$tempTableFlag ); } return $self->{'policyDb'}; } =item B Returns a Pos::db object connected to the webtop database for writing. The connection is made on the first call to this function. Subsequent calls to this method return the same db object created by the first call. =cut sub getWebtopDbWriter { return shift->getPolicyDb(); } sub getWebtopDbReader { return shift->getWebtopDbWriter(); } sub getOem { my $self = shift; return $self->{'oem'}; } sub getOemId { my $self = shift; return $self->getOem()->getSetting( setting=> 'id' ); } sub getPage { my $self = shift; if ( exists $ENV{'GATEWAY_INTERFACE'} ) { if ( not defined $self->{'page'} ) { # we pass the args on this one since we want getPage # to accept the title param that the page constructor does my %args = (); $args{'client'} = $self->getClient(); $self->{'page'} = Pos::Webtop::Web::Page->new( %args ); } return $self->{'page'}; } else { warn ref($self) . "::getPage(): not in cgi interface!\n"; return undef; } } sub getClient { my $self = shift; if ( not exists $ENV{'GATEWAY_INTERFACE'} ) { warn ref($self) . "::getClient(): this client will not have a valid web session since it is not running from the web server.\n"; } if ( not defined $self->{'client'} ) { $self->{'client'} = Pos::Webtop::Web::Client->new( db=> $self->getWebtopDbWriter() ); } return $self->{'client'}; } sub setTempTableFlag { my $self = shift; my ($tempTableFlag) = @{{@_}}{qw/tempTableFlag/}; $self->{'tempTableFlag'} = $tempTableFlag; } sub setClient { my $self = shift; my ($client) = @{{@_}}{qw/client/}; $self->{'client'} = $client; } sub getCgi { my $self = shift; if ( exists $ENV{'GATEWAY_INTERFACE'} ) { if ( not defined $self->{'cgi'} ) { $self->{'cgi'} = CGI->new(); } return $self->{'cgi'}; } else { warn ref($self) . "::getCgi(): not in cgi interface!\n"; return undef; } } sub getUserNameFromId { my $self = shift; my ($userId) = @{{@_}}{qw/userId/}; my $sql = " SELECT user_name FROM users WHERE user_id = '" . $self->getClient()->getUserId() . "' "; my $db = getPolicyDb(); my $userName = $db->query(sql => $sql); return $userName if defined $userName; return undef; } sub createBox { # just a wrapper for the Pos::Webtop::Web::Box constructor my $self = shift; if ( exists $ENV{'GATEWAY_INTERFACE'} ) { my $oemId = $self->getOem()->getSetting( setting=> 'id' ); return Pos::Webtop::Web::OEMLoader::createBox( constructorArgs=> \@_, oemId=> $oemId ); } else { warn ref($self) . "::createBox(): not in cgi interface!\n"; return undef; } } sub debugLog { my $self = shift; my ($msg) = @{{@_}}{qw/msg/}; if ( $self->{'debugLevel'} ) { return "warn $msg"; } else { return; } } sub getCompanyLogoSettings { my $self = shift; my $client = $self->getClient(); my $userId = $client->getUserId(); my $db = $self->getWebtopDbReader; my $customerId = $client->getCustomerId(); # User id may not always be valid (such as during password expiration) return { companyText=> "", companyImage=> "", removeSupportImages=> "" } if (not defined($userId)); my @companyLogo = $db->query(sql => " select a.company_text, b.image_name, a.remove_support_images from w_user_company_logo a left outer join customer_custom_images b on a.customer_image_id = b.customer_image_id where a.user_id = $userId "); my $companyText; my $companyImage; my $removeSupportImages; if (scalar @companyLogo) { ($companyText, $companyImage, $removeSupportImages) = @{ $companyLogo[0] }; } if (defined($companyImage)) { $companyImage = "$customerId/$companyImage"; } else { $companyImage = 0; } return { companyText=> $companyText, companyImage=> $companyImage, removeSupportImages=> $removeSupportImages }; } # Return the HTML with a pretty error message sub getErrorPage { my $self = shift; my ($errorMsg,$errorTitle,$currentDir,$initialFolder) = @{{@_}}{qw/errorMsg errorTitle currentDir initialFolder/}; my $oem = $self->getOem; my $oemId = $self->getOemId; my $page = $self->getPage(); my $errorBox = $self->createBox( title => "" . $oem->getSetting(setting=> 'webtopProductName') . " Error" ); my $client = $self->getClient(); my $sessionId = $client->getSessionId; my $sessionHash = $client->getSessionHash; $errorMsg = "Unknown error" unless defined $errorMsg; $errorTitle = "" unless defined $errorTitle; my $backLink = ""; if ( $currentDir eq "\\" . $initialFolder || ((!defined($currentDir) || !length($currentDir)) && (!defined($initialFolder) || !length($initialFolder))) ) { $backLink = "" . ($client->getFormGetCode( text=> "Click here to go back", values=> [ { name=> "module", value=> "FileShares" } ])) . ""; } else { $backLink = "" . ($client->getFormGetCode( text=> "Click here to go back", values=> [ { name=> "module", value=> "FileShares" }, { name=> "act", value=> "browseShareDir" }, { name=> "initialFolder", value=> $initialFolder }, { name=> "currentDir", value=> $currentDir } ])) . ""; } $currentDir =~ s/\\[^\\]+$//g; my $ret = $page->getHeaderHtml( title => "WebTop Error" ); #$ret .= Pos::Webtop::OcxLauncher::getLauncherHtml( tb => $self ); my $phone = $oem->getSetting(setting => 'customerServicePhone'); if (not defined($phone)) { $phone = "your system administrator"; } $ret .= " " . $client->getFormInputs() . "
" . $errorBox->getHeaderHtml() . "

$errorTitle

$errorMsg

For technical support, contact $phone
$backLink
" . $errorBox->getFooterHtml() . "
" . $page->getFooterHtml(); return $ret; } # Wrapper for resolveHostDns and resolveHostWins sub resolveHost { my $self = shift; my ($host) = @{{@_}}{qw/host/}; my $ip; # It's simply an IP, no need for resolution. if ($host =~ /^(\d+\.){3}\d+$/) { return $host; } # If the hostname has no dot in it, try the customer WINS server. if ($host !~ /\./) { # Try with WINS $ip = $self->resolveHostWins( host => $host ); return $ip unless not defined $ip; } # Try with DNS $ip = $self->resolveHostDns( host => $host ); return $ip unless not defined $ip; # If none of the above work, fail return undef; } # Wrapper for Pos::Webtop::Dns::posdnsResolveHost sub resolveHostDns { my $self = shift; my ($host) = @{{@_}}{qw/host/}; my $ip = Pos::Webtop::Dns::posdnsResolveHost( toolBox => $self, host => $host ); if ( (defined $ip) && ($ip =~ /^(\d+\.){3}\d+$/) ) { if ($verboseLog) { warn ref($self) . "->resolveHostDns(): resolved $host -> $ip"; } return $ip; } else { if ($verboseLog) { my $client = $self->getClient(); my $customerId = $client->getCustomerId(); warn ref($self) . "->resolveHostDns(): unable to resolve $host for customerId '$customerId'"; } return undef; } } # Wrapper for Pos::Webtop::Wins::posdnsResolveHost sub resolveHostWins { my $self = shift; my ($host) = @{{@_}}{qw/host/}; my $dbr = $self->getWebtopDbReader(); my $client = $self->getClient(); my $userId = $client->getUserId(); my $ip = Pos::Webtop::Wins::resolveHost( db => $dbr, userId => $userId, host => $host, toolBox => $self ); if ( (defined $ip) && ($ip =~ /^(\d+\.){3}\d+$/) ) { #warn ref($self) . "->resolveHostWins(): resolved $host -> $ip"; return $ip; } else { if ($verboseLog) { warn ref($self) . "->resolveHostWins(): unable to resolve $host for userId '$userId'"; } return undef; } } # Wrapper for Pos::Webtop::Supernat::supernatGetInternalAddress # # if you call this function with webSessionNat set to false, # you must remember to release the backend_dynamic nat that is made # by calling Supernat::supernatReleaseDynamicBakcnedNat with the # ip address you originally asked to supernat when you are done with it # or the nat table on supernat will never remove that nat since # it's reference count will never reach 0. sub getSupernatInternalAddress { my $self = shift; my ($ip,$requestor,$webSessionNat) = @{{@_}}{qw/ip requestor webSessionNat/}; my $dbr = $self->getWebtopDbReader(); my $client = $self->getClient(); my $customerId = $client->getCustomerId(); my $sessionId = $client->getSessionId(); my $supernatIp = Pos::defaults::getSupernatIp(db => $dbr); my $supernatPort = Pos::defaults::getSupernatPort(); $webSessionNat = 1 unless defined $webSessionNat; my ($ieaSupernatIp) = $dbr->query(sql=> " select rawip32_to_dotted_quad_no(notscreen_internal_ip) from customer_iea_properties p inner join notscreens n on n.notscreen_id = p.primary_notscreen_id where customer_id = $customerId"); if (defined($ieaSupernatIp)) { $supernatIp = $ieaSupernatIp } if ( not (defined $ip && $ip =~ /^(\d+\.){3}\d+$/) ) { if ($verboseLog) { warn ref($self) . "->getSupernatInternalAddress: didn't get a valid IP address ('$ip')"; } return undef; } if ( !(Pos::Webtop::Supernat::supernatIsIpInsideCompanyIntranet( db => $dbr, companyId => $customerId, actualAddress => $ip)) ) { if ($verboseLog) { warn ref($self) . "->getSupernatInternalAddress: supplied IP is not inside company intranet ('$ip')"; } return undef; } my $internalAddress; if ( $webSessionNat ) { # TODO: Get some of these parameters from Pos::defaults $internalAddress = Pos::Webtop::Supernat::supernatGetInternalAddress( supernatIp => $supernatIp, supernatPort => $supernatPort, companyId => $customerId, requestType => 'WEB_SESSION', requestTypeId => $sessionId, actualAddress => $ip, requestor => $requestor ); } else { $internalAddress = Pos::Webtop::Supernat::supernatGetInternalAddress( supernatIp => $supernatIp, supernatPort => $supernatPort, companyId => $customerId, requestType => 'BACKEND_DYNAMIC', actualAddress => $ip, requestor => $requestor # Might be undef, that's okay. ); } if ( (defined $internalAddress) && ($internalAddress =~ /^(\d+\.){3}\d+$/) ) { return $internalAddress; } else { if ($verboseLog) { warn ref($self) . "->getSupernatInternalAddress: Pos::Webtop::Supernat::supernatGetInternalAddress returned an invalid IP address"; } } return undef; } # Wrapper for resolveHost and getSupernatInternalAddress # Will do a DNS lookup if a name is passed in sub getSupernattedIp { my $self = shift; my ($host) = @{{@_}}{qw/host/}; my $client = $self->getClient(); my $customerId = $client->getCustomerId(); my $db = $self->getWebtopDbReader; if ( not (defined $host && $host) ) { return undef; } my $ip; if ( $host =~ /^(\d+\.){3}\d+$/ ) { # They provided an IP address... move on $ip = $host; } elsif ( $host =~ /\w/ ) { # They provided a hostname; do a DNS/WINS lookup $ip = $self->resolveHost( host => $host ); if ( not(defined $ip && $ip) ) { if ($verboseLog) { warn ref($self) . "->getSupernattedIp: couldn't resolve host '$host'"; } return undef; } } else { # They're stupid return undef; } # we need to check for the use case of connecting to a dialup ip from their company my ($isDialupIp) = $db->query( sql=> "select is_ip_dialup($customerId,'$ip') " . ((Pos::defaults::isPostgresDb()) ? "" : "from dual") ); my $supernattedIp = undef; if ( $isDialupIp ) { $verboseLog and warn ref($self) . "->etSupernattedIp(): ip was determined to be corporate dialup ip -- no supernat needed."; $supernattedIp = $ip; } else { $supernattedIp = $self->getSupernatInternalAddress( ip => $ip ); } if ( defined $supernattedIp && $supernattedIp ) { if ($verboseLog) { warn ref($self) . "->getSupernattedIp(): resolved Host: '$host' -> IP: '$ip' -> Supernatted IP: '$supernattedIp'"; } return $supernattedIp; } else { if ($verboseLog) { warn ref($self) . "->getSupernattedIp(): unable to resolve supernatted ip for host: '$host', IP: '$ip'"; } return undef; } } sub getDomJs { my $self = shift; my $client = $self->getClient(); my $buf = ""; my $mobile = $client->isMobileWebtop(); $buf = " "; return $buf; } sub getRefreshFormHtml { my $self = shift; my ($refreshUrl, $extraVars, $top) = @{{@_}}{qw/refreshUrl extraVars top/}; $extraVars = {} unless defined $extraVars; my ($url, $p) = split /\?/, $refreshUrl; my @parms = split /&/, $p; my $ret = "Content-type: text/html\n\n
"; foreach (@parms) { my ($name, $val) = split /=/, $_; $ret .= "\n"; } foreach (keys %{$extraVars}) { my $name = $_; my $val = $extraVars->{$_}; $ret .= "\n"; } $ret .= "
"; return $ret; } =back =cut 1;