Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #1635 - Escape underscores in packages for markdown #2243

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/NuGetGallery/App_Start/ContainerBindings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Web;
using System.Web.Hosting;
using System.Web.Mvc;
using AnglicanGeek.MarkdownMailer;
using Elmah;
using Microsoft.WindowsAzure.ServiceRuntime;
using Ninject;
Expand All @@ -16,6 +15,7 @@
using System.Diagnostics;
using NuGetGallery.Auditing;
using NuGetGallery.Infrastructure.Lucene;
using NuGetGallery.Services;

namespace NuGetGallery
{
Expand Down
9 changes: 5 additions & 4 deletions src/NuGetGallery/NuGetGallery.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,6 @@
<CodeAnalysisRuleSet>..\Frontend.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="AnglicanGeek.MarkdownMailer, Version=1.2.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\AnglicanGeek.MarkdownMailer.1.2\lib\net40\AnglicanGeek.MarkdownMailer.dll</HintPath>
</Reference>
<Reference Include="Antlr3.Runtime, Version=3.3.1.7705, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\WebGrease.1.1.0\lib\Antlr3.Runtime.dll</HintPath>
Expand Down Expand Up @@ -973,6 +969,8 @@
<Compile Include="Services\ContentService.cs" />
<Compile Include="Services\IContentService.cs" />
<Compile Include="Services\IFileReference.cs" />
<Compile Include="Services\IMailSender.cs" />
<Compile Include="Services\ISmtpClient.cs" />
<Compile Include="Services\IStatusService.cs" />
<Compile Include="Services\JsonStatisticsService.cs" />
<Compile Include="Services\CloudReportService.cs" />
Expand All @@ -995,11 +993,14 @@
<Compile Include="Services\ISearchService.cs" />
<Compile Include="Services\IUploadFileService.cs" />
<Compile Include="Services\LocalFileReference.cs" />
<Compile Include="Services\MailSender.cs" />
<Compile Include="Services\MailSenderConfiguration.cs" />
<Compile Include="Services\NuGetExeDownloaderService.cs" />
<Compile Include="Services\PackageFileService.cs" />
<Compile Include="Filters\RequireSslAttribute.cs" />
<Compile Include="Services\PackageSearchResults.cs" />
<Compile Include="Services\JsonAggregateStatsService.cs" />
<Compile Include="Services\SmtpClientWrapper.cs" />
<Compile Include="Services\SqlAggregateStatsService.cs" />
<Compile Include="Services\ReportPackageRequest.cs" />
<Compile Include="Services\SearchFilter.cs" />
Expand Down
22 changes: 22 additions & 0 deletions src/NuGetGallery/Services/IMailSender.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using System.Net.Mail;

namespace NuGetGallery.Services
{
public interface IMailSender : IDisposable
{
void Send(
string fromAddress,
string toAddress,
string subject,
string markdownBody);

void Send(
MailAddress fromAddress,
MailAddress toAddress,
string subject,
string markdownBody);

void Send(MailMessage mailMessage);
}
}
18 changes: 18 additions & 0 deletions src/NuGetGallery/Services/ISmtpClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Net;
using System.Net.Mail;

namespace NuGetGallery.Services
{
public interface ISmtpClient : IDisposable
{
ICredentialsByHost Credentials { get; set; }
SmtpDeliveryMethod DeliveryMethod { get; set; }
bool EnableSsl { get; set; }
string Host { get; set; }
string PickupDirectoryLocation { get; set; }
int Port { get; set; }
void Send(MailMessage message);
bool UseDefaultCredentials { get; set; }
}
}
118 changes: 118 additions & 0 deletions src/NuGetGallery/Services/MailSender.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
using System;
using System.IO;
using System.Net.Mail;
using System.Net.Mime;
using MarkdownSharp;

namespace NuGetGallery.Services
{
public class MailSender : IMailSender
{
readonly ISmtpClient smtpClient;

public MailSender()
: this(new SmtpClientWrapper(new SmtpClient()), null)
{
}

public MailSender(MailSenderConfiguration configuration)
: this(new SmtpClientWrapper(new SmtpClient()), configuration)
{
}

public MailSender(SmtpClient smtpClient)
: this(new SmtpClientWrapper(smtpClient), null)
{
}

internal MailSender(
ISmtpClient smtpClient,
MailSenderConfiguration configuration)
{
if (smtpClient == null)
throw new ArgumentNullException("smtpClient");

if (configuration != null)
ConfigureSmtpClient(smtpClient, configuration);

this.smtpClient = smtpClient;
}

static internal void ConfigureSmtpClient(
ISmtpClient smtpClient,
MailSenderConfiguration configuration)
{
if (configuration.Host != null)
smtpClient.Host = configuration.Host;
if (configuration.Port.HasValue)
smtpClient.Port = configuration.Port.Value;
if (configuration.EnableSsl.HasValue)
smtpClient.EnableSsl = configuration.EnableSsl.Value;
if (configuration.DeliveryMethod.HasValue)
smtpClient.DeliveryMethod = configuration.DeliveryMethod.Value;
if (configuration.UseDefaultCredentials.HasValue)
smtpClient.UseDefaultCredentials = configuration.UseDefaultCredentials.Value;
if (configuration.Credentials != null)
smtpClient.Credentials = configuration.Credentials;
if (configuration.PickupDirectoryLocation != null)
smtpClient.PickupDirectoryLocation = configuration.PickupDirectoryLocation;
}

public void Send(
string fromAddress,
string toAddress,
string subject,
string markdownBody)
{
Send(
new MailAddress(fromAddress),
new MailAddress(toAddress),
subject,
markdownBody);
}

public void Send(
MailAddress fromAddress,
MailAddress toAddress,
string subject,
string markdownBody)
{
var mailMessage = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = markdownBody
};

Send(mailMessage);
}

public void Send(MailMessage mailMessage)
{
if (smtpClient.DeliveryMethod == SmtpDeliveryMethod.SpecifiedPickupDirectory
&& !Directory.Exists(smtpClient.PickupDirectoryLocation))
Directory.CreateDirectory(smtpClient.PickupDirectoryLocation);

string markdownBody = mailMessage.Body;
string htmlBody = new Markdown().Transform(markdownBody);

AlternateView textView = AlternateView.CreateAlternateViewFromString(
markdownBody,
null,
MediaTypeNames.Text.Plain);
mailMessage.AlternateViews.Add(textView);

AlternateView htmlView = AlternateView.CreateAlternateViewFromString(
htmlBody,
null,
MediaTypeNames.Text.Html);
mailMessage.AlternateViews.Add(htmlView);

smtpClient.Send(mailMessage);
}

public void Dispose()
{
smtpClient.Dispose();
}
}
}
16 changes: 16 additions & 0 deletions src/NuGetGallery/Services/MailSenderConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Net;
using System.Net.Mail;

namespace NuGetGallery.Services
{
public class MailSenderConfiguration
{
public ICredentialsByHost Credentials { get; set; }
public SmtpDeliveryMethod? DeliveryMethod { get; set; }
public bool? EnableSsl { get; set; }
public string Host { get; set; }
public string PickupDirectoryLocation { get; set; }
public int? Port { get; set; }
public bool? UseDefaultCredentials { get; set; }
}
}
3 changes: 1 addition & 2 deletions src/NuGetGallery/Services/MessageService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@
using System.Net.Mail;
using System.Text;
using System.Web;
using AnglicanGeek.MarkdownMailer;
using Elmah;
using NuGetGallery.Authentication;
using Glimpse.AspNet.AlternateType;
using NuGetGallery.Configuration;
using NuGetGallery.Services;

namespace NuGetGallery
{
Expand Down
9 changes: 6 additions & 3 deletions src/NuGetGallery/Services/ReportPackageRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ internal string FillIn(string subject, IAppConfiguration config)
// note, format blocks {xxx} are matched by ordinal-case-sensitive comparison
var builder = new StringBuilder(subject);

string packageIdMarkdownEscaped = Package.PackageRegistration.Id.Replace("_", "\\_");

Substitute(builder, "{GalleryOwnerName}", config.GalleryOwner.DisplayName);
Substitute(builder, "{Id}", Package.PackageRegistration.Id);
Substitute(builder, "{Id}", packageIdMarkdownEscaped);
Substitute(builder, "{Version}", Package.Version);
Substitute(builder, "{Reason}", Reason);
if (RequestingUser != null)
Expand All @@ -44,8 +46,9 @@ internal string FillIn(string subject, IAppConfiguration config)
Substitute(builder, "{Name}", FromAddress.DisplayName);
Substitute(builder, "{Address}", FromAddress.Address);
Substitute(builder, "{AlreadyContactedOwners}", AlreadyContactedOwners ? "Yes" : "No");
Substitute(builder, "{PackageUrl}", Url.Package(Package.PackageRegistration.Id, null, scheme: "http"));
Substitute(builder, "{VersionUrl}", Url.Package(Package.PackageRegistration.Id, Package.Version, scheme: "http"));
// Fix for Markdown Mailer compatible urls containing _
Substitute(builder, "{PackageUrl}", Url.Package(packageIdMarkdownEscaped, null, scheme: "http").Replace("%5C", "\\"));
Substitute(builder, "{VersionUrl}", Url.Package(packageIdMarkdownEscaped, Package.Version, scheme: "http").Replace("%5C", "\\"));
Substitute(builder, "{Reason}", Reason);
Substitute(builder, "{Message}", Message);

Expand Down
67 changes: 67 additions & 0 deletions src/NuGetGallery/Services/SmtpClientWrapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using System.Net;
using System.Net.Mail;

namespace NuGetGallery.Services
{
public class SmtpClientWrapper : ISmtpClient
{
readonly SmtpClient smtpClient;

public SmtpClientWrapper(SmtpClient smtpClient)
{
this.smtpClient = smtpClient;
}

public ICredentialsByHost Credentials
{
get { return smtpClient.Credentials; }
set { smtpClient.Credentials = value; }
}

public SmtpDeliveryMethod DeliveryMethod
{
get { return smtpClient.DeliveryMethod; }
set { smtpClient.DeliveryMethod = value; }
}

public bool EnableSsl
{
get { return smtpClient.EnableSsl; }
set { smtpClient.EnableSsl = value; }
}

public void Dispose()
{
smtpClient.Dispose();
}

public string Host
{
get { return smtpClient.Host; }
set { smtpClient.Host = value; }
}

public string PickupDirectoryLocation
{
get { return smtpClient.PickupDirectoryLocation; }
set { smtpClient.PickupDirectoryLocation = value; }
}

public int Port
{
get { return smtpClient.Port; }
set { smtpClient.Port = value; }
}

public void Send(MailMessage message)
{
smtpClient.Send(message);
}

public bool UseDefaultCredentials
{
get { return smtpClient.UseDefaultCredentials; }
set { smtpClient.UseDefaultCredentials = value; }
}
}
}
1 change: 0 additions & 1 deletion src/NuGetGallery/packages.config
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AnglicanGeek.MarkdownMailer" version="1.2" />
<package id="AnglicanGeek.WindowsAzure.ServiceRuntime" version="1.6" targetFramework="net45" />
<package id="d3" version="3.0.2" targetFramework="net45" />
<package id="DynamicData.EFCodeFirstProvider" version="0.3.0.0" />
Expand Down
4 changes: 0 additions & 4 deletions tests/NuGetGallery.Facts/NuGetGallery.Facts.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="AnglicanGeek.MarkdownMailer, Version=1.2.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\AnglicanGeek.MarkdownMailer.1.2\lib\net40\AnglicanGeek.MarkdownMailer.dll</HintPath>
</Reference>
<Reference Include="EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\EntityFramework.5.0.0\lib\net45\EntityFramework.dll</HintPath>
Expand Down
6 changes: 5 additions & 1 deletion tests/NuGetGallery.Facts/Services/MessageServiceFacts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
using System.Linq;
using System.Collections.ObjectModel;
using System.Net.Mail;
using AnglicanGeek.MarkdownMailer;
using Moq;
using NuGetGallery.Areas.Admin.DynamicData;
using NuGetGallery.Services;
using Xunit;
using NuGetGallery.Configuration;
using NuGetGallery.Framework;
Expand Down Expand Up @@ -506,6 +506,10 @@ public void Send(string fromAddress, string toAddress, string subject, string ma
{
Send(new MailMessage(fromAddress, toAddress, subject, markdownBody));
}

public void Dispose()
{
}
}
}
}
1 change: 0 additions & 1 deletion tests/NuGetGallery.Facts/packages.config
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AnglicanGeek.MarkdownMailer" version="1.2" />
<package id="EntityFramework" version="5.0.0" targetFramework="net45" />
<package id="Glimpse" version="1.8.0" targetFramework="net45" />
<package id="Glimpse.AspNet" version="1.6.0" targetFramework="net45" />
Expand Down