mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-09-22 20:13:50 +08:00
#16950: Validating chars used for tags
Work Item: 16950 --HG-- branch : 1.x
This commit is contained in:
32
src/Orchard.Specs/Tags.feature
Normal file
32
src/Orchard.Specs/Tags.feature
Normal 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 <3 Orchard</a>"
|
150
src/Orchard.Specs/Tags.feature.cs
generated
Normal file
150
src/Orchard.Specs/Tags.feature.cs
generated
Normal 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 <3 Orchard</a>\"");
|
||||
#line hidden
|
||||
this.ScenarioCleanup();
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endregion
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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)) {
|
||||
|
@@ -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()) {
|
||||
|
@@ -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 */ }
|
||||
|
Reference in New Issue
Block a user