From f3b14a227c0b77e9f2c33b39e61364180f0ee7da Mon Sep 17 00:00:00 2001 From: Yung Han Khoe Date: Tue, 27 May 2008 15:27:52 +0000 Subject: [PATCH] Added Database link access for SQL Macro --- docs/changelog/7.x.x.txt | 1 + docs/upgrades/upgrade_7.5.10-7.5.11.pl | 8 +++ lib/WebGUI/DatabaseLink.pm | 18 ++++++- lib/WebGUI/Macro/SQL.pm | 23 ++++++-- lib/WebGUI/Operation/DatabaseLink.pm | 73 +++++++++++++++++--------- lib/WebGUI/i18n/English/Macro_SQL.pm | 5 ++ t/Macro/SQL.t | 18 +++++++ 7 files changed, 116 insertions(+), 30 deletions(-) diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt index 6b4faeb2a..536739150 100644 --- a/docs/changelog/7.x.x.txt +++ b/docs/changelog/7.x.x.txt @@ -67,6 +67,7 @@ - fixed: CS mail retrieval doesn't decode subject properly - fixed: email password recovery fields effected by UI level - Complete rewrite of the Asset Manager + - added: Database link access for SQL Macro (Yung Han Khoe) 7.5.10 - fix: Syntax error in GetCsMail diff --git a/docs/upgrades/upgrade_7.5.10-7.5.11.pl b/docs/upgrades/upgrade_7.5.10-7.5.11.pl index 760e285c8..38a6e5ab4 100644 --- a/docs/upgrades/upgrade_7.5.10-7.5.11.pl +++ b/docs/upgrades/upgrade_7.5.10-7.5.11.pl @@ -61,6 +61,7 @@ addVendors($session); modifyThingyPossibleValues( $session ); removeLegacyTable($session); migrateSubscriptions( $session ); +addDBLinkAccessToSQLMacro($session); addAssetManager( $session ); finish($session); # this line required @@ -1363,6 +1364,13 @@ EOSQL3 print "\tDone.\n"; } +#---------------------------------------------------------------------------- +sub addDBLinkAccessToSQLMacro { + my $session = shift; + print "\tAdding DBLink access to SQL Macro ..." unless ($quiet); + $session->db->write("insert into databaseLink (databaseLinkId, allowMacroAccess) values ('0','1')"); + print "Done.\n" unless $quiet; +} # -------------- DO NOT EDIT BELOW THIS LINE -------------------------------- diff --git a/lib/WebGUI/DatabaseLink.pm b/lib/WebGUI/DatabaseLink.pm index 6f731714e..65842ea4b 100644 --- a/lib/WebGUI/DatabaseLink.pm +++ b/lib/WebGUI/DatabaseLink.pm @@ -294,12 +294,26 @@ A reference to the current session. sub getList { my $class = shift; my $session = shift; - my $list = $session->db->buildHashRef("select databaseLinkId, title from databaseLink order by title"); + my $list = $session->db->buildHashRef("select databaseLinkId, title from databaseLink where databaseLinkId != +'0' order by title"); my $i18n = WebGUI::International->new($session); $list->{'0'} = $i18n->get(1076); return $list; } +#------------------------------------------------------------------- + +=head2 macroAccessIsAllowed ( ) + +Returns a boolean indicating if macros are allowed to access this database link. + +=cut + +sub macroAccessIsAllowed { + my $self = shift; + return $self->{_databaseLink}{allowMacroAccess}; +} + #------------------------------------------------------------------- @@ -333,7 +347,7 @@ sub new { identifier=>$session->config->get("dbpass"), title=>"WebGUI Database", allowedKeywords=>"select\ndescribe\ndesc\nshow\ncall", - allowMacroAccess=>0, + allowMacroAccess=>$session->db->quickScalar("select allowMacroAccess from databaseLink where databaseLinkId='0'"), additionalParameters=>'', ); } else { diff --git a/lib/WebGUI/Macro/SQL.pm b/lib/WebGUI/Macro/SQL.pm index 156ebbe12..02236f477 100644 --- a/lib/WebGUI/Macro/SQL.pm +++ b/lib/WebGUI/Macro/SQL.pm @@ -34,17 +34,32 @@ Describes how to format the results of the SQL statement. For each term in in a select-type statement, a numeric macro (^0, ^1, etc.)can be used to position its output in the format. +=head3 databaseLinkId + +The id of the databaseLink to use. Default is the WebGUI database which has id '0'. +The databaseLink must allow macro access, otherwise an error will be returned. + =cut #------------------------------------------------------------------- sub process { my $session = shift; - my ($output, @data, $rownum, $temp); - my ($statement, $format) = @_; - my $i18n = WebGUI::International->new($session,'Macro_SQL'); + my ($output, @data, $rownum, $temp, $dbh); + my ($statement, $format, $databaseLinkId) = @_; + my $i18n = WebGUI::International->new($session,'Macro_SQL'); + + $databaseLinkId ||= '0'; + my $dbLink = WebGUI::DatabaseLink->new($session, $databaseLinkId); + if($dbLink->macroAccessIsAllowed()){ + $dbh = $dbLink->db; + } + else{ + return $i18n->get('database access not allowed'); + } + $format = '^0;' if ($format eq ""); if ($statement =~ /^\s*select/i || $statement =~ /^\s*show/i || $statement =~ /^\s*describe/i) { - my $sth = $session->dbSlave->unconditionalRead($statement); + my $sth = $dbh->unconditionalRead($statement); unless ($sth->errorCode < 1) { return sprintf $i18n->get('sql error'), $sth->errorMessage; } else { diff --git a/lib/WebGUI/Operation/DatabaseLink.pm b/lib/WebGUI/Operation/DatabaseLink.pm index 30dbcb557..b56fde329 100644 --- a/lib/WebGUI/Operation/DatabaseLink.pm +++ b/lib/WebGUI/Operation/DatabaseLink.pm @@ -56,8 +56,10 @@ sub _submenu { my $dlid = $session->form->process("dlid"); if (($session->form->process("op") eq "editDatabaseLink" && $dlid ne "new") || $session->form->process("op") eq "deleteDatabaseLink") { $ac->addSubmenuItem($session->url->page('op=editDatabaseLink;dlid='.$dlid), $i18n->get(983)); - $ac->addSubmenuItem($session->url->page('op=copyDatabaseLink;dlid='.$dlid), $i18n->get(984)); - $ac->addConfirmedSubmenuItem($session->url->page("op=deleteDatabaseLinkConfirm;dlid=".$dlid), $i18n->get(985), $i18n->get(988)); + unless ($dlid eq "0"){ + $ac->addSubmenuItem($session->url->page('op=copyDatabaseLink;dlid='.$dlid), $i18n->get(984)); + $ac->addConfirmedSubmenuItem($session->url->page("op=deleteDatabaseLinkConfirm;dlid=".$dlid), $i18n->get(985), $i18n->get(988)); + } $ac->addSubmenuItem($session->url->page('op=listDatabaseLinks'), $i18n->get(986)); } return $ac->render($workarea, $title); @@ -158,10 +160,9 @@ sub www_editDatabaseLink { if ($session->form->process("dlid") eq "new") { # Default values are SELECT, DESCRIBE and SHOW $db{allowedKeywords} = "select\ndescribe\nshow"; - } elsif ($session->form->process("dlid") eq "0") { - - } else { - %db = %{WebGUI::DatabaseLink->new($session,$session->form->process("dlid"))->get}; + } + else { + %db = %{WebGUI::DatabaseLink->new($session,$session->form->process("dlid"))->get}; } my $i18n = WebGUI::International->new($session); $f = WebGUI::HTMLForm->new($session, @@ -181,12 +182,22 @@ sub www_editDatabaseLink { -label => $i18n->get(991), -hoverHelp => $i18n->get('991 description'), ); - $f->text( - -name => "title", + if ($session->form->process("dlid") eq "0"){ + $f->readOnly( -label => $i18n->get(992), -hoverHelp => $i18n->get('992 description'), -value => $db{title}, ); + } + else{ + $f->text( + -name => "title", + -label => $i18n->get(992), + -hoverHelp => $i18n->get('992 description'), + -value => $db{title}, + ); + } + unless ($session->form->process("dlid") eq "0"){ $f->text( -name => "DSN", -label => $i18n->get(993), @@ -205,12 +216,13 @@ sub www_editDatabaseLink { -hoverHelp => $i18n->get('995 description'), -value => $db{identifier}, ); - $f->textarea( + $f->textarea( -name => "allowedKeywords", -label => $i18n->get('allowed keywords'), -hoverHelp => $i18n->get('allowed keywords description'), -value => $db{allowedKeywords}, - ); + ); + } $f->yesNo( -name => "allowMacroAccess", -label => $i18n->get('allow access from macros'), @@ -218,13 +230,15 @@ sub www_editDatabaseLink { -defaultValue=>0, -value => $db{allowMacroAccess}, ); - $f->textarea( + unless ($session->form->process("dlid") eq "0"){ + $f->textarea( -name => "additionalParameters", -label => $i18n->get('additional parameters'), -hoverHelp => $i18n->get('additional parameters help'), -defaultValue=>'', -value => $db{additionalParameters}, - ); + ); + } $f->submit; $output .= $f->print; return _submenu($session,$output,"990"); @@ -244,25 +258,33 @@ Returns the user the Link Database Links screen. sub www_editDatabaseLinkSave { my ($allowedKeywords); my $session = shift; - return $session->privilege->insufficient unless canView($session); + my $params; + return $session->privilege->insufficient unless canView($session); # Convert enters to a single \n. - ($allowedKeywords = $session->form->process("allowedKeywords")) =~ s/\s+/\n/g; - my $params = { - title=>$session->form->process("title"), - username=>$session->form->process("dbusername"), - identifier=>$session->form->process("dbidentifier"), - DSN=>$session->form->process("DSN"), - allowedKeywords=>$allowedKeywords, - allowMacroAccess=>$session->form->process("allowMacroAccess"), - additionalParameters=>$session->form->process("additionalParameters"), - }; + if ($session->form->process("dlid") eq "0"){ + $params = { + allowMacroAccess=>$session->form->process("allowMacroAccess"), + }; + } + else{ + ($allowedKeywords = $session->form->process("allowedKeywords")) =~ s/\s+/\n/g; + $params = { + title=>$session->form->process("title"), + username=>$session->form->process("dbusername"), + identifier=>$session->form->process("dbidentifier"), + DSN=>$session->form->process("DSN"), + allowedKeywords=>$allowedKeywords, + allowMacroAccess=>$session->form->process("allowMacroAccess"), + additionalParameters=>$session->form->process("additionalParameters"), + }; + } if ($session->form->process("dlid") eq "new") { WebGUI::DatabaseLink->create($session,$params); } else { WebGUI::DatabaseLink->new($session,$session->form->process("dlid"))->set($params); } - return www_listDatabaseLinks($session); + return www_listDatabaseLinks($session); } #------------------------------------------------------------------- @@ -288,6 +310,9 @@ sub www_listDatabaseLinks { .$session->icon->edit('op=editDatabaseLink;dlid='.$id) .$session->icon->copy('op=copyDatabaseLink;dlid='.$id); } + elsif ($id eq '0') { + $output .= $session->icon->edit('op=editDatabaseLink;dlid='.$id); + } $output .= ''; $output .= ''.$links->{$id}.''; } diff --git a/lib/WebGUI/i18n/English/Macro_SQL.pm b/lib/WebGUI/i18n/English/Macro_SQL.pm index 3c978f72c..144c9517f 100644 --- a/lib/WebGUI/i18n/English/Macro_SQL.pm +++ b/lib/WebGUI/i18n/English/Macro_SQL.pm @@ -18,6 +18,11 @@ our $I18N = { lastUpdated => 1135105919, }, + 'database access not allowed' => { + message => q|The database does not allow access from Macro's.|, + lastUpdated => 1135105919, + }, + }; 1; diff --git a/t/Macro/SQL.t b/t/Macro/SQL.t index 143104a89..f00a232c0 100644 --- a/t/Macro/SQL.t +++ b/t/Macro/SQL.t @@ -16,6 +16,7 @@ use WebGUI::Test; use WebGUI::Macro::Slash_gatewayUrl; use WebGUI::Session; use WebGUI::International; +use WebGUI::DatabaseLink; use Data::Dumper; use Test::More; # increment this value for each test you create @@ -26,6 +27,9 @@ my $url = WebGUI::Macro::Slash_gatewayUrl::process($session); my $i18n = WebGUI::International->new($session, 'Macro_SQL'); +my $WebGUIdbLink = WebGUI::DatabaseLink->new($session, '0'); +my $originalMacroAccessValue = $WebGUIdbLink->macroAccessIsAllowed(); + $session->db->dbh->do('DROP TABLE IF EXISTS testTable'); $session->db->dbh->do('CREATE TABLE testTable (zero int(8), one int(8), two int(8), three int(8), four int(8), five int(8), six int(8), seven int(8), eight int(8), nine int(8), ten int(8), eleven int(8) ) TYPE=InnoDB'); $session->db->dbh->do('INSERT INTO testTable (zero, one, two, three, four, five, six, seven, eight, nine, ten, eleven ) VALUES(0,1,2,3,4,5,6,7,8,9,10,11)'); @@ -116,12 +120,22 @@ my @testSets = ( my $numTests = scalar @testSets; ++$numTests; ##For the load check; +++$numTests; ##For the allow macro access test; plan tests => $numTests; my $macro = 'WebGUI::Macro::SQL'; my $loaded = use_ok($macro); +$WebGUIdbLink->set({allowMacroAccess=>0}); + +# run one test to test allowMacroAccess +my $output = WebGUI::Macro::SQL::process($session, 'select count(*) from users', 'There are ^0; users'); +is($output, $i18n->get('database access not allowed'), 'Test allow access from macros setting.'); + +# set allowMacroAccess to 1 to allow other tests to run +$WebGUIdbLink->set({allowMacroAccess=>1}); + SKIP: { skip "Unable to load $macro", $numTests-1 unless $loaded; @@ -133,6 +147,10 @@ foreach my $testSet (@testSets) { } +# reset allowMacroAccess to original value +$WebGUIdbLink->set({allowMacroAccess=>$originalMacroAccessValue}); + + END { $session->db->dbh->do('DROP TABLE testTable'); }