#16950: Validating chars used for tags

Work Item: 16950

--HG--
branch : 1.x
This commit is contained in:
Sebastien Ros
2011-11-29 10:21:23 -08:00
parent 7d2ac4b560
commit 3d0fcab261
7 changed files with 206 additions and 4 deletions

View File

@@ -0,0 +1,32 @@
Feature: Tags
In order to add tags to my content
As an author
I want to create, publish and edit pages
Scenario: I can add a tag to a new Page
Given I have installed Orchard
When I go to "admin/contents/create/page"
And I fill in
| name | value |
| Routable.Title | Super Duper |
| Body.Text | This is super. |
| Tags.Tags | Foo, Bar |
And I hit "Publish Now"
And I go to "super-duper"
Then I should see "<h1[^>]*>.*?Super Duper.*?</h1>"
And I should see "Foo"
And I should see "Bar"
Scenario: I can't add a tag with disallowed chars to a new Page
Given I have installed Orchard
When I go to "admin/contents/create/page"
And I fill in
| name | value |
| Routable.Title | Super Duper |
| Body.Text | This is super. |
| Tags.Tags | Foo, I <3 Orchard |
And I hit "Publish Now"
And I go to "super-duper"
Then I should see "<h1[^>]*>.*?Super Duper.*?</h1>"
And I should see "<a[^>]*>Foo</a>"
And I should not see "<a[^>]*>I &lt;3 Orchard</a>"

150
src/Orchard.Specs/Tags.feature.cs generated Normal file
View File

@@ -0,0 +1,150 @@
// ------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by SpecFlow (http://www.specflow.org/).
// SpecFlow Version:1.8.1.0
// SpecFlow Generator Version:1.8.0.0
// Runtime Version:4.0.30319.239
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
// ------------------------------------------------------------------------------
#region Designer generated code
#pragma warning disable
namespace Orchard.Specs
{
using TechTalk.SpecFlow;
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.8.1.0")]
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[NUnit.Framework.TestFixtureAttribute()]
[NUnit.Framework.DescriptionAttribute("Tags")]
public partial class TagsFeature
{
private static TechTalk.SpecFlow.ITestRunner testRunner;
#line 1 "Tags.feature"
#line hidden
[NUnit.Framework.TestFixtureSetUpAttribute()]
public virtual void FeatureSetup()
{
testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner();
TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Tags", " In order to add tags to my content\r\n As an author\r\n I want to create, publish" +
" and edit pages", ProgrammingLanguage.CSharp, ((string[])(null)));
testRunner.OnFeatureStart(featureInfo);
}
[NUnit.Framework.TestFixtureTearDownAttribute()]
public virtual void FeatureTearDown()
{
testRunner.OnFeatureEnd();
testRunner = null;
}
[NUnit.Framework.SetUpAttribute()]
public virtual void TestInitialize()
{
}
[NUnit.Framework.TearDownAttribute()]
public virtual void ScenarioTearDown()
{
testRunner.OnScenarioEnd();
}
public virtual void ScenarioSetup(TechTalk.SpecFlow.ScenarioInfo scenarioInfo)
{
testRunner.OnScenarioStart(scenarioInfo);
}
public virtual void ScenarioCleanup()
{
testRunner.CollectScenarioErrors();
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("I can add a tag to a new Page")]
public virtual void ICanAddATagToANewPage()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can add a tag to a new Page", ((string[])(null)));
#line 6
this.ScenarioSetup(scenarioInfo);
#line 7
testRunner.Given("I have installed Orchard");
#line 8
testRunner.When("I go to \"admin/contents/create/page\"");
#line hidden
TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table1.AddRow(new string[] {
"Routable.Title",
"Super Duper"});
table1.AddRow(new string[] {
"Body.Text",
"This is super."});
table1.AddRow(new string[] {
"Tags.Tags",
"Foo, Bar"});
#line 9
testRunner.And("I fill in", ((string)(null)), table1);
#line 14
testRunner.And("I hit \"Publish Now\"");
#line 15
testRunner.And("I go to \"super-duper\"");
#line 16
testRunner.Then("I should see \"<h1[^>]*>.*?Super Duper.*?</h1>\"");
#line 17
testRunner.And("I should see \"Foo\"");
#line 18
testRunner.And("I should see \"Bar\"");
#line hidden
this.ScenarioCleanup();
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("I can\'t add a tag with disallowed chars to a new Page")]
public virtual void ICanTAddATagWithDisallowedCharsToANewPage()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can\'t add a tag with disallowed chars to a new Page", ((string[])(null)));
#line 20
this.ScenarioSetup(scenarioInfo);
#line 21
testRunner.Given("I have installed Orchard");
#line 22
testRunner.When("I go to \"admin/contents/create/page\"");
#line hidden
TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table2.AddRow(new string[] {
"Routable.Title",
"Super Duper"});
table2.AddRow(new string[] {
"Body.Text",
"This is super."});
table2.AddRow(new string[] {
"Tags.Tags",
"Foo, I <3 Orchard"});
#line 23
testRunner.And("I fill in", ((string)(null)), table2);
#line 28
testRunner.And("I hit \"Publish Now\"");
#line 29
testRunner.And("I go to \"super-duper\"");
#line 30
testRunner.Then("I should see \"<h1[^>]*>.*?Super Duper.*?</h1>\"");
#line 31
testRunner.And("I should see \"<a[^>]*>Foo</a>\"");
#line 32
testRunner.And("I should not see \"<a[^>]*>I &lt;3 Orchard</a>\"");
#line hidden
this.ScenarioCleanup();
}
}
}
#pragma warning restore
#endregion

View File

@@ -24,7 +24,7 @@
@foreach (var report in Model.Reports) {
<tr>
<td>
@Html.ActionLink(Html.Encode(report.ActivityName), "Display", new {id = report.ReportId})
@Html.ActionLink(report.ActivityName, "Display", new {id = report.ReportId})
</td>
<td>
@report.Title

View File

@@ -4,21 +4,29 @@ using JetBrains.Annotations;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.ContentManagement.Handlers;
using Orchard.Localization;
using Orchard.Tags.Helpers;
using Orchard.Tags.Models;
using Orchard.Tags.Services;
using Orchard.Tags.ViewModels;
using Orchard.UI.Notify;
namespace Orchard.Tags.Drivers {
[UsedImplicitly]
public class TagsPartDriver : ContentPartDriver<TagsPart> {
private static readonly char[] _disalowedChars = new [] { '<', '>', '*', '%', ':', '&', '\\', '"', '|' };
private const string TemplateName = "Parts/Tags";
private readonly ITagService _tagService;
private readonly INotifier _notifier;
public TagsPartDriver(ITagService tagService) {
public TagsPartDriver(ITagService tagService, INotifier notifier) {
_tagService = tagService;
_notifier = notifier;
T = NullLocalizer.Instance;
}
public Localizer T { get; set; }
protected override string Prefix {
get { return "Tags"; }
}
@@ -38,6 +46,17 @@ namespace Orchard.Tags.Drivers {
updater.TryUpdateModel(model, Prefix, null, null);
var tagNames = TagHelpers.ParseCommaSeparatedTagNames(model.Tags);
// as the tag names are used in the route directly, prevent them from having ASP.NET disallowed chars
// c.f., http://www.hanselman.com/blog/ExperimentsInWackinessAllowingPercentsAnglebracketsAndOtherNaughtyThingsInTheASPNETIISRequestURL.aspx
var disallowedTags = tagNames.Where(x => _disalowedChars.Intersect(x).Any()).ToList();
if (disallowedTags.Any()) {
_notifier.Warning(T("The tags \"{0}\" could not be added because they contain forbidden chars: {1}", String.Join(", ", disallowedTags), String.Join(", ", _disalowedChars)));
tagNames = tagNames.Where(x => !disallowedTags.Contains(x)).ToList();
}
if (part.ContentItem.Id != 0) {
_tagService.UpdateTagsForContentItem(part.ContentItem, tagNames);
}

View File

@@ -8,7 +8,7 @@ namespace Orchard.Tags.Helpers {
return new List<string>();
}
IEnumerable<string> tagNames = tags.Split(',');
List<string> sanitizedTagNames = new List<string>();
var sanitizedTagNames = new List<string>();
foreach (var tagName in tagNames) {
string sanitizedTagName = tagName.Trim();
if (!String.IsNullOrEmpty(sanitizedTagName)) {

View File

@@ -8,6 +8,7 @@
<fieldset>
@Html.LabelFor(m => m.Tags, T("Tags"))
@Html.TextBoxFor(m => m.Tags, new { @class = "large text" })
<span class="hint">Separate multiple tags with commas</span>
</fieldset>
@using (Script.Foot()) {

View File

@@ -4,7 +4,7 @@
@Html.UnorderedList(
Model.Tags,
(t, i) => Html.ActionLink(
Html.Encode(t.TagName),
t.TagName,
"Search",
new { tagName = t.TagName },
new { @class = "" /* todo: (heskew) classify according to tag use */ }