diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt
index bae5031a3..1282037ac 100644
--- a/docs/changelog/7.x.x.txt
+++ b/docs/changelog/7.x.x.txt
@@ -5,6 +5,13 @@
- fix: Closed Posts Displaying in CS
- RFE: testEnvironment improvement
- fix: Cannot add new page to the Wiki
+ - fix: Wiki does not have content type restrictions and can not use
+ the content filtering system
+ - fix: GetSyndicatedContent Workflow Activity not trapping errors.
+ - fix: GetSyndicatedContent Workflow Activity not checking for timeout.
+ - fix: Wiki displays 'Add a new page" link to users who are not allowed to
+ add pages.
+ - fix: XSS vulnerability in Wiki Page titles.
- Removed the requirement for DBIx::FullTextSearch from testEnvironment.pl
since it hasn't been needed since 6.5. It was just never removed.
diff --git a/docs/upgrades/templates-7.3.4/wiki_search.tmpl b/docs/upgrades/templates-7.3.4/wiki_search.tmpl
new file mode 100644
index 000000000..dfddd6348
--- /dev/null
+++ b/docs/upgrades/templates-7.3.4/wiki_search.tmpl
@@ -0,0 +1,26 @@
+#WikiSearchTmpl00000001
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+~~~
+
+
diff --git a/docs/upgrades/upgrade_7.3.3-7.3.4.pl b/docs/upgrades/upgrade_7.3.3-7.3.4.pl
index 518f704f1..bbd6a679a 100644
--- a/docs/upgrades/upgrade_7.3.3-7.3.4.pl
+++ b/docs/upgrades/upgrade_7.3.3-7.3.4.pl
@@ -20,17 +20,19 @@ my $quiet; # this line required
my $session = start(); # this line required
-# upgrade functions go here
+fixWiki($session);
finish($session); # this line required
##-------------------------------------------------
-#sub exampleFunction {
-# my $session = shift;
-# print "\tWe're doing some stuff here that you should know about.\n" unless ($quiet);
-# # and here's our code
-#}
+sub fixWiki {
+ my $session = shift;
+ print "\tImplementing replacements and content filtering for the Wiki Wobject.\n" unless ($quiet);
+
+ $session->db->write("alter table WikiMaster add column useContentFilter int(11) default 0");
+ $session->db->write("alter table WikiMaster add column filterCode varchar(30) default 'javascript'");
+}
diff --git a/lib/WebGUI/Asset/WikiPage.pm b/lib/WebGUI/Asset/WikiPage.pm
index 1febbce8b..c50477003 100644
--- a/lib/WebGUI/Asset/WikiPage.pm
+++ b/lib/WebGUI/Asset/WikiPage.pm
@@ -233,17 +233,23 @@ sub processPropertiesFromFormPost {
my $self = shift;
$self->SUPER::processPropertiesFromFormPost(@_);
my $actionTaken = ($self->session->form->process("assetId") eq "new") ? "Created" : "Edited";
+
$self->update({ groupIdView => $self->getWiki->get('groupIdView'),
groupIdEdit => $self->getWiki->get('groupToAdminister'),
isHidden => 1,
actionTakenBy => $self->session->user->userId,
- actionTaken => $actionTaken});
+ actionTaken => $actionTaken,
+ title => WebGUI::HTML::filter($self->get("title"), "all"),
+ });
+
if ($self->getWiki->canAdminister) {
$self->update({isProtected => $self->session->form("isProtected")});
}
+
delete $self->{_storageLocation};
my $size = 0;
my $storage = $self->getStorageLocation;
+
foreach my $file (@{$storage->getFiles}) {
if ($storage->isImage($file)) {
##Use generateThumbnail to shrink size to site's max image size
@@ -255,9 +261,35 @@ sub processPropertiesFromFormPost {
}
$size += $storage->getFileSize($file);
}
+
$self->setSize($size);
}
+#-------------------------------------------------------------------
+
+=head2 scrubContent ( [ content ] )
+
+Uses WikiMaster settings to remove unwanted markup and apply site wide replacements.
+
+=head3 content
+
+Optionally pass the ontent that we want to run the filters on. Otherwise we get it from self.
+
+=cut
+
+sub scrubContent {
+ my $self = shift;
+ my $content = shift || $self->get("content");
+
+ my $scrubbedContent = WebGUI::HTML::filter($content, $self->getWiki->get("filterCode"));
+
+ if ($self->getWiki->get("useContentFilter")) {
+ $scrubbedContent = WebGUI::HTML::processReplacements($self->session, $scrubbedContent);
+ }
+
+ return $scrubbedContent;
+}
+
#-------------------------------------------------------------------
sub view {
my $self = shift;
@@ -276,7 +308,7 @@ sub view {
wikiHomeUrl=>$self->getParent->getUrl,
historyUrl=>$self->getUrl("func=getHistory"),
editContent=>$self->getEditForm,
- content => $self->getWiki->autolinkHtml($self->get('content')),
+ content => $self->getWiki->autolinkHtml($self->scrubContent),
};
return $self->processTemplate($var, $self->getWiki->get("pageTemplateId"));
}
diff --git a/lib/WebGUI/Asset/Wobject/WikiMaster.pm b/lib/WebGUI/Asset/Wobject/WikiMaster.pm
index 17b72dadc..f1368bcf1 100644
--- a/lib/WebGUI/Asset/Wobject/WikiMaster.pm
+++ b/lib/WebGUI/Asset/Wobject/WikiMaster.pm
@@ -67,6 +67,7 @@ sub appendSearchBoxVars {
$var->{'searchQuery'} = WebGUI::Form::text($self->session, { name => 'query', value => $queryText });
$var->{'searchSubmit'} = WebGUI::Form::submit($self->session, { value => $submitText });
$var->{'searchFormFooter'} = WebGUI::Form::formFooter($self->session);
+ $var->{'canAddPages'} = $self->canEditPages();
return $self;
}
@@ -274,6 +275,20 @@ sub definition {
label => $i18n->get("max image size"),
hoverHelp => $i18n->get("max image size help")
},
+ useContentFilter =>{
+ fieldType=>"yesNo",
+ defaultValue=>1,
+ tab=>'display',
+ label=>$i18n->get('content filter'),
+ hoverHelp=>$i18n->get('content filter description'),
+ },
+ filterCode =>{
+ fieldType=>"filterContent",
+ defaultValue=>'javascript',
+ tab=>'security',
+ label=>$i18n->get('filter code'),
+ hoverHelp=>$i18n->get('filter code description'),
+ },
);
push @$definition,
diff --git a/lib/WebGUI/Help/Asset_WikiMaster.pm b/lib/WebGUI/Help/Asset_WikiMaster.pm
index e6ac8b20a..87fe2efb5 100644
--- a/lib/WebGUI/Help/Asset_WikiMaster.pm
+++ b/lib/WebGUI/Help/Asset_WikiMaster.pm
@@ -452,6 +452,10 @@ our $HELP = {
{
'name' => 'performSearch',
},
+ {
+ 'name' => 'canAddPages',
+ 'description' => 'canAddPages variable',
+ },
{
'name' => 'searchResults',
variables => [
diff --git a/lib/WebGUI/Workflow/Activity/GetSyndicatedContent.pm b/lib/WebGUI/Workflow/Activity/GetSyndicatedContent.pm
index dbfc72c7a..ef7ab4efc 100644
--- a/lib/WebGUI/Workflow/Activity/GetSyndicatedContent.pm
+++ b/lib/WebGUI/Workflow/Activity/GetSyndicatedContent.pm
@@ -18,6 +18,7 @@ package WebGUI::Workflow::Activity::GetSyndicatedContent;
use strict;
use base 'WebGUI::Workflow::Activity';
use WebGUI::Asset::Wobject::SyndicatedContent;
+use JSON;
=head1 NAME
@@ -69,20 +70,81 @@ See WebGUI::Workflow::Activity::execute() for details.
sub execute {
my $self = shift;
- #In the new Wobject, "rssURL" actually can refer to more than one URL.
- my @syndicatedWobjectURLs = $self->session->db->buildArray("select distinct SyndicatedContent.rssUrl from SyndicatedContent left join asset on SyndicatedContent.assetId=asset.assetId where asset.state='published'");
- foreach my $url(@syndicatedWobjectURLs) {
+ my $object = shift;
+ my $instance = shift;
+ unless (defined $instance) {
+ $self->session->errorHandler->error("Could not instanciate Workflow Instance in GetSyndicatedContent Activity");
+ return $self->ERROR;
+ }
+
+ my @syndicatedUrls = @{$self->getSyndicatedUrls($instance)};
+ my @arrayCopy = @syndicatedUrls; # copy we can delete elements from inside the foreach loop
+ my $time = time();
+
+ foreach my $urls (@syndicatedUrls) {
#Loop through the SyndicatedWobjects and split all the URLs they are syndicating off into
#a separate array.
- my @urlsToSyndicate = split(/\s+/,$url);
- foreach ((@urlsToSyndicate)) {
- WebGUI::Asset::Wobject::SyndicatedContent::_get_rss_data($self->session,$_);
+ my @urlsToSyndicate = split(/\s+/,$urls);
+
+ foreach my $url (@urlsToSyndicate) {
+ # We could timeout in here but I don't see a good way to handle that right now
+ # May need to fix this in the future.
+ my $returnValue = WebGUI::Asset::Wobject::SyndicatedContent::_get_rss_data($self->session, $url);
+ unless (defined $returnValue) {
+ $self->session->errorHandler->error("GetSyndicatedContent Workflow Activity: _get_rss_data returned undef while trying to process syndicated content url $url");
+ return $self->ERROR;
+ }
}
+
+ # Delete this element from the array
+ splice(@arrayCopy,0,1);
+
+ # Check for timeout
+ last unless (time() - $time <= 60);
}
+
+ # See if we're done
+ if (scalar(@arrayCopy) > 0) {
+ $instance->setScratch("syndicatedUrls", objToJson(@arrayCopy));
+ return $self->WAITING;
+ }
+
+ $instance->deleteScratch("syndicatedUrls");
return $self->COMPLETE;
}
+#---------------------------------------------------------------------
+=head2 getWobjectUrls ( )
+
+Returns URLs from all of the Syndicated Content Wobjects from scratch or fetches them from the db if needed
+
+=head3 session
+
+A reference to the current webgui session
+
+=cut
+
+sub getSyndicatedUrls {
+ my $self = shift;
+ my $instance = shift;
+ my $syndicatedUrls = $instance->getScratch("syndicatedUrls");
+
+ unless ($syndicatedUrls) {
+ my $urls = $self->session->db->buildArrayRef("select
+ distinct SyndicatedContent.rssUrl from SyndicatedContent
+ left join
+ asset on SyndicatedContent.assetId=asset.assetId
+ where
+ asset.state='published'"
+ );
+
+ $instance->setScratch("syndicatedUrls", objToJson($urls));
+ return $urls;
+ }
+
+ return jsonToObj($syndicatedUrls);
+}
1;
diff --git a/lib/WebGUI/i18n/English/Asset_WikiMaster.pm b/lib/WebGUI/i18n/English/Asset_WikiMaster.pm
index 9647362f8..6ff85530e 100644
--- a/lib/WebGUI/i18n/English/Asset_WikiMaster.pm
+++ b/lib/WebGUI/i18n/English/Asset_WikiMaster.pm
@@ -13,6 +13,30 @@ our $I18N = {
addPageLabel=>{message=>q|Add a new page.|, lastUpdated=>0},
wikiHomeLabel=>{message=>q|Wiki Home|, lastUpdated=>0},
+ 'filter code' => {
+ message => q|Filter Code|,
+ lastUpdated => 0,
+ context => q|Label for edit wobject screen|,
+ },
+
+ 'filter code description' => {
+ message => q|Sets the level of HTML Filtering done on each Wiki entry|,
+ lastUpdated => 0,
+ context => q|Hover help for edit wobject screen|,
+ },
+
+ 'content filter' => {
+ message => q|Use Content Filter?|,
+ lastUpdated => 0,
+ context => q|Label for edit wobject screen|,
+ },
+
+ 'content filter description' => {
+ message => q|Process the content of Wiki pages through the WebGUI Content Filtering system. This can also be used to create custom markup symbols for inserting reusable content styling.|,
+ lastUpdated => 0,
+ context => q|Hover help for edit wobject screen|,
+ },
+
'wikiHomeLabel variable' => {
message=>q|An internationalized label to go with wikiHomeUrl.|,
lastUpdated=>1165816161,
@@ -444,6 +468,16 @@ our $I18N = {
lastUpdated => 1165946014,
},
+ 'canAddPages' => {
+ message => q|canAddPages Variable|,
+ lastUpdated=>0,
+ },
+
+ 'canAddPages variable' => {
+ message => q|Boolean value that is true when the user is allowed to add and edit pages in the Wiki.|,
+ lastUpdated=> 0,
+ },
+
};
1;