bypass angular sanitization, doing it with jsoup and allowing embedded videos

add html content to dom only when entry is opened
This commit is contained in:
Jeremie Panzer
2013-03-27 16:42:05 +01:00
parent 3b33d7588b
commit 054be51c9c
6 changed files with 37 additions and 21 deletions

View File

@@ -9,6 +9,7 @@ import javax.ejb.Stateless;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.SystemUtils;
import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;
import com.commafeed.backend.model.Feed;
import com.commafeed.backend.model.FeedEntry;
@@ -71,8 +72,14 @@ public class FeedParser {
}
private String handleContent(String content) {
org.jsoup.nodes.Document doc = Jsoup.parse(content, "UTF-8");
doc.select("a").attr("target", "_blank");
return doc.outerHtml();
Whitelist whitelist = Whitelist.relaxed();
whitelist.addEnforcedAttribute("a", "target", "_blank");
// TODO evaluate potential security issues
whitelist.addTags("iframe");
whitelist.addAttributes("iframe", "src", "height", "width",
"allowfullscreen", "frameborder");
return Jsoup.clean(content, whitelist);
}
}

View File

@@ -28,7 +28,7 @@
</div>
</div>
<div class="span10">
<toolbar class="pull-right"></toolbar>
<toolbar></toolbar>
<ng:view></ng:view>
</div>
</div>

View File

@@ -58,7 +58,7 @@
}
.entrylist-header h3 {
margin: 0px 0px 5px 0px;
margin: 5px 0px 5px 0px;
}
#feed-accordion .accordion-group {

View File

@@ -1,19 +1,22 @@
<div>
<div class="pull-left" spinner shown="loading"></div>
<div class="btn-group read-mode" data-toggle="buttons-radio">
<button type="button" class="btn" ng-model="settings.readingMode" btn-radio="'unread'">Unread</button>
<button type="button" class="btn" ng-model="settings.readingMode" btn-radio="'all'">All</button>
<div class="pull-right" spinner shown="loading"></div>
<div>
<div class="btn-group read-mode" data-toggle="buttons-radio">
<button type="button" class="btn" ng-model="settings.readingMode" btn-radio="'unread'">Unread</button>
<button type="button" class="btn" ng-model="settings.readingMode" btn-radio="'all'">All</button>
</div>
<button type="button" class="btn" ng-click="refresh()"><i class="icon-refresh"></i> Refresh</button>
<button type="button" class="btn" ng-click="markAllAsRead()"><i class="icon-ok"></i> Mark all as read</button>
<div class="btn-group">
<a class="btn dropdown-toggle" data-toggle="dropdown" href="settings"><i class="icon-cog"></i><span class="caret"></span></a>
<ul class="dropdown-menu pull-right">
<li><a href="settings"><i class="icon-wrench"></i> Settings</a></li>
<li class="divider"></li>
<li><a href="logout"><i class="icon-user"></i> Logout</a></li>
</ul>
</div>
</div>
<button type="button" class="btn" ng-click="refresh()"><i class="icon-refresh"></i> Refresh</button>
<button type="button" class="btn" ng-click="markAllAsRead()"><i class="icon-ok"></i> Mark all as read</button>
<div class="btn-group">
<a class="btn dropdown-toggle" data-toggle="dropdown" href="settings"><i class="icon-cog"></i><span class="caret"></span></a>
<ul class="dropdown-menu pull-right">
<li><a href="settings"><i class="icon-wrench"></i> Settings</a></li>
<li class="divider"></li>
<li><a href="logout"><i class="icon-user"></i> Logout</a></li>
</ul>
</div>
</div>

View File

@@ -155,7 +155,13 @@ module.controller('FeedListCtrl', function($scope, $routeParams, $http,
}
};
$scope.isOpen = false
$scope.toggle = function(entry) {
if ($scope.current != entry) {
$scope.isOpen = true;
} else {
$scope.isOpen = !$scope.isOpen;
}
$scope.current = entry;
$scope.mark(entry, true);
}

View File

@@ -19,7 +19,7 @@
<a href="{{entry.url}}" target="_blank">{{entry.title}}</a>
</h4>
</div>
<div ng-bind-html="entry.content"></div>
<div ng-bind-html-unsafe="entry.content" ui-if="isOpen && current == entry"></div>
</div>
</accordion-group>
</accordion>