Compare commits

..

43 Commits
1.0.3 ... 1.9.1

Author SHA1 Message Date
Sebastien Ros
2c3973bfa0 Merge branch '1.9.1' 2015-06-30 11:30:37 -07:00
Sipke Schoorstra
c3dffb79f5 #5378: Fixed content field elements placement for content picker field and media picker field. 2015-06-29 14:27:23 +03:00
Sipke Schoorstra
5b40567b6d #5407: Layout elements now evaluate tokens. 2015-06-29 14:01:58 +03:00
Lombiq
e10ba8126a Fixing that ClientHostAddressAccessor failed in a background task
This was the case e.g. when roles were modified in a background task with Audit Trail trying to record the event
2015-06-25 00:35:21 +02:00
Lombiq
a7626b78f5 Fixing that instead of just widgets all content items were retrieved in some WidgetsService methods 2015-06-24 16:04:11 +02:00
Sebastien Ros
760e30855c Updating version number 1.9.1 2015-06-23 11:20:06 -07:00
Sébastien Ros
ac305af963 Merge pull request #5406 from MpDzik/pr/media-import-loc
MediaLibrary - Fix localization of Import button
2015-06-22 15:45:46 -07:00
Sebastien Ros
78fb58f016 Fixing localization gender 2015-06-22 10:10:58 -07:00
Sebastien Ros
8481768b58 Fixing culture list encoding 2015-06-22 10:06:34 -07:00
Marek Dzikiewicz
50d65bc0b9 MediaLibrary - Fix localization of Import button 2015-06-21 17:42:54 +02:00
agriffard
4eb8d1d2ea Fix some typos #5405 2015-06-21 15:44:04 +02:00
Daniel Stolt
220c1b591a Restored reset of markup content styling in layout editor. 2015-06-20 20:38:42 +03:00
Daniel Stolt
b06a4ecb73 #5403 Improved native clipboard support in layout editor. 2015-06-20 19:35:11 +03:00
Daniel Stolt
764db254da Made layout editor toolbox separately scrollable while in sticky mode. 2015-06-20 16:42:53 +03:00
Bertrand Le Roy
c1359f7a86 Add a heading element that renders as h1-h6 tags. 2015-06-19 18:57:45 -07:00
Sebastien Ros
51409346cc Fixing mismatched assembly versions 2015-06-19 12:57:19 -07:00
Sebastien Ros
2cd5af5193 Reverting IMembership usage in FormsAuthenticationService 2015-06-19 10:54:46 -07:00
Sebastien Ros
1180425109 Updating libraries 2015-06-19 10:39:00 -07:00
Sébastien Ros
3c3a6df6dd Merge pull request #5391 from paynecrl97/5390/delay_output_cache_key_creation
Defers output cache key creation until we know we need it
2015-06-19 09:35:10 -07:00
paynecrl97
c6e96867c7 Only executes itemDescriptor logic if Debug logging is enabled 2015-06-19 09:17:29 +01:00
Sebastien Ros
8d134ba0c5 Fixing html-encoding in WebSearch settings page 2015-06-18 16:47:38 -07:00
Sebastien Ros
9d5bc20666 Fixing unit tests 2015-06-18 14:19:44 -07:00
Sébastien Ros
1fcf7c86d0 Merge pull request #5371 from gcsuk/1.9.x
Improved Recipe Journal Logging Detail
2015-06-18 12:39:05 -07:00
Sébastien Ros
bca643bf1f Merge pull request #5292 from Hazzamanic/1.9.x
fixing placementeditor try/catch block
2015-06-18 12:28:00 -07:00
Sebastien Ros
f276501923 Merge branch 'sebros/authcookie' into 1.9.x 2015-06-18 10:31:57 -07:00
Sebastien Ros
76408da930 #5315: Adding new settings to configure SSL cookies
- Creating ISslSettingsProvider to define whether cookies can only be sent over SSL or not
- Implementing DefaultSslSettingsProvider based on Sites.config and web.config
making it configurable per tenant or for the whole site
- Implementing SecureSocketsLayerSettingsProvider in Orchard.SecureSocketsLayerSettingsProvider

Fixes 5315
2015-06-17 18:06:47 -07:00
Skrypt
43497c8093 Closes #5389; Admin Culture Picker wrong cookie domain. 2015-06-17 20:02:04 -04:00
paynecrl97
f13c9d47c7 Adds more detail to itemDescriptor 2015-06-17 16:05:53 +01:00
paynecrl97
1a8b17d04e Defers output cache key creation until we know we need it 2015-06-17 14:02:05 +01:00
Sebastien Ros
20c5b494cd By default, html-encode translation parameters
Also ensure that any existing parameter is not double-encoded by
removing .Text when used as a translation parameter.
2015-06-16 16:50:45 -07:00
Sebastien Ros
cd49d2ccf2 Updating ruleset location for all projects 2015-06-16 16:22:04 -07:00
Sebastien Ros
aa2e2cf1d0 Ignoring VS 2015 settings files 2015-06-16 11:16:35 -07:00
Bertrand Le Roy
8eea9a6771 Add missing reference to media library from image editor web config so that views compile properly. 2015-06-15 12:42:50 -07:00
Lombiq
1d445c5438 Fixing that Custom Forms didn't display a submit button text if there was none configured
The button text not being configured can happen on an 1.8 to 1.9 upgrade for example.
2015-06-15 00:07:01 +02:00
Lombiq
6aabc4d9f9 Fixing that the Audit Trail Recycle Bin caused YSOD if a content item didn't have a display text (like Comments) 2015-06-14 23:18:25 +02:00
Bertrand Le Roy
14172fec51 Fix compilation issue on dynamic forms admin views that use namespaces from layouts. 2015-06-13 16:42:09 -07:00
Sipke Schoorstra
9e88d16273 Added missing null check to Projection element driver's export method. 2015-06-13 19:11:25 +03:00
Lombiq
66af4a8cdf Adding null check for query string parameters in AuditTrail to prevent possible YSOD 2015-06-13 01:02:16 +02:00
Rob King
92bde1ac71 Merge pull request #2 from gcsuk/ImprovedRecipeJournal
Replaced string.format with Localizable T
2015-06-10 12:24:32 +01:00
Rob King
7e149c4bc1 Replaced string.format with Localizable T 2015-06-10 10:07:04 +01:00
Rob King
d78afaeb51 Merge pull request #1 from gcsuk/ImprovedRecipeJournal
Improved Recipe Journal Logging Detail
2015-06-09 16:09:53 +01:00
Rob King
a0279f2d9c Improved recipe logging to give a trail of executed tasks 2015-06-09 15:59:44 +01:00
Hazza
98475f7aa0 fixing placementeditor try/catch block 2015-05-16 16:34:20 +01:00
813 changed files with 2158 additions and 32741 deletions

17
.gitignore vendored
View File

@@ -96,6 +96,7 @@ publish/
# Publish Web Output
*.Publish.xml
*.pubxml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
@@ -164,7 +165,7 @@ build/
/buildtasks
/artifacts
*.sln.cache
#src/Orchard.Web/Media/*
src/Orchard.Web/Media/*
log.xml
profiling/
*.orig
@@ -182,14 +183,10 @@ src/Orchard.Web/Orchard.Web.Publish.xml
src/TestResults/*
src/Orchard.Web/Properties/PublishProfiles
src/Orchard.Azure/Orchard.Azure.CloudService/Staging/
node_modules/
src/Orchard.Web/Modules/Orchard.Azure.MediaServices/node_modules
src/Orchard.Web/Modules/Orchard.Layouts/node_modules
src/Orchard.Web/Modules/Orchard.DynamicForms/node_modules
# Enable all /lib artifacts
#enable all /lib artifacts
!lib/*/*.*
# Enable version control of some IDeliverable specifics.
src/Orchard.Web/Media/Default/RecipeJournal/*
src/Orchard.Web/Media/Default/_Profiles/*
# Enable "IDeliverable/Packaging/" folder.
!src/IDeliverable/Packaging/*/*.*
*/.vs/*

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{F1467A6B-2397-447B-BE90-766D192EC3D9}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>IDeliverable.Licensing.Orchard</RootNamespace>
<AssemblyName>IDeliverable.Licensing.Orchard</AssemblyName>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\lib\autofac\Autofac.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>..\..\..\lib\newtonsoft.json\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Abstractions" />
<Reference Include="System.Web.Http, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\lib\aspnetwebapi\System.Web.Http.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc, Version=5.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\lib\aspnetmvc\System.Web.Mvc.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ILicensedProductManifest.cs" />
<Compile Include="LicenseValidationControllerBase.cs" />
<Compile Include="LicenseValidationErrorBannerBase.cs" />
<Compile Include="LicenseValidationHelper.cs" />
<Compile Include="LicenseVerificationTokenStore.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="LicenseSettingsPartHandlerBase.cs" />
<Compile Include="LicenseSettingsPartBase.cs" />
<Compile Include="LicenseSettingsPartDriverBase.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IDeliverable.Licensing\IDeliverable.Licensing.csproj">
<Project>{7e439cb7-1ace-435f-a8f3-5bb929423e34}</Project>
<Name>IDeliverable.Licensing</Name>
</ProjectReference>
<ProjectReference Include="..\..\Orchard\Orchard.Framework.csproj">
<Project>{2d1d92bb-4555-4cbe-8d0e-63563d6ce4c6}</Project>
<Name>Orchard.Framework</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -1,15 +0,0 @@
using Orchard;
using Orchard.Logging;
namespace IDeliverable.Licensing.Orchard
{
public interface ILicensedProductManifest : IDependency
{
string ProductId { get; }
string ProductName { get; }
string ExtensionId { get; }
bool SkipValidationForLocalRequests { get; }
string LicenseKey { get; }
ILogger Logger { get; }
}
}

View File

@@ -1,19 +0,0 @@
using Orchard.ContentManagement;
using Orchard.ContentManagement.Utilities;
namespace IDeliverable.Licensing.Orchard
{
public abstract class LicenseSettingsPartBase : ContentPart
{
public readonly LazyField<string> mProductVersionField = new LazyField<string>();
public abstract string ProductId { get; }
public string LicenseKey
{
get { return this.Retrieve(x => x.LicenseKey); }
set { this.Store(x => x.LicenseKey, value); }
}
public string ProductVersion => mProductVersionField.Value;
}
}

View File

@@ -1,28 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.Environment.Extensions;
namespace IDeliverable.Licensing.Orchard
{
public abstract class LicenseSettingsPartDriverBase<TPart> : ContentPartDriver<TPart> where TPart : LicenseSettingsPartBase, new()
{
protected abstract string EditorShapeName { get; }
protected abstract string EditorShapeTemplateName { get; }
protected override DriverResult Editor(TPart part, dynamic shapeHelper)
{
return Editor(part, null, shapeHelper);
}
protected override DriverResult Editor(TPart part, IUpdateModel updater, dynamic shapeHelper)
{
return ContentShape(EditorShapeName, () =>
{
updater?.TryUpdateModel(part, Prefix, null, null);
return shapeHelper.EditorTemplate(TemplateName: EditorShapeTemplateName, Prefix: Prefix, Model: part);
}).OnGroup("Licenses");
}
}
}

View File

@@ -1,37 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Handlers;
using Orchard.Environment.Extensions;
using Orchard.Localization;
namespace IDeliverable.Licensing.Orchard
{
public abstract class LicenseSettingsPartHandlerBase<TPart> : ContentHandler where TPart : LicenseSettingsPartBase, new()
{
protected LicenseSettingsPartHandlerBase(IEnumerable<ILicensedProductManifest> products, IExtensionManager extensionManager)
{
Filters.Add(new ActivatingFilter<TPart>("Site"));
OnGetContentItemMetadata<TPart>((context, part) => context.Metadata.EditorGroupInfo.Add(new GroupInfo(T("Licenses"))));
OnActivated<TPart>(SetupLazyFields);
mProducts = products;
mExtensionManager = extensionManager;
}
private readonly IEnumerable<ILicensedProductManifest> mProducts;
private readonly IExtensionManager mExtensionManager;
public Localizer T { get; set; } = NullLocalizer.Instance;
private void SetupLazyFields(ActivatedContentContext context, TPart part)
{
part.mProductVersionField.Loader(value =>
{
var productManifest = mProducts.Single(x => x.ProductId == part.ProductId);
var extension = mExtensionManager.GetExtension(productManifest.ExtensionId);
return extension.Version;
});
}
}
}

View File

@@ -1,31 +0,0 @@
using System.Web.Mvc;
using Orchard.Localization;
using Orchard.UI.Notify;
using Orchard.Utility.Extensions;
namespace IDeliverable.Licensing.Orchard
{
public abstract class LicenseValidationControllerBase : Controller
{
protected LicenseValidationControllerBase(INotifier notifier)
{
Notifier = notifier;
T = NullLocalizer.Instance;
}
public Localizer T { get; set; }
protected INotifier Notifier { get; }
protected abstract string ProductId { get; }
public ActionResult VerifyLicenseKey()
{
LicenseValidationHelper.Instance.ClearLicenseValidationResult(ProductId);
if (LicenseValidationHelper.GetLicenseIsValid(ProductId))
Notifier.Information(T("License key succesfully validated."));
var urlReferrer = Request.UrlReferrer?.ToString();
return Redirect(Request.IsLocalUrl(urlReferrer) ? urlReferrer : "~/");
}
}
}

View File

@@ -1,71 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using IDeliverable.Licensing.Validation;
using Orchard;
using Orchard.Localization;
using Orchard.Logging;
using Orchard.UI.Admin.Notification;
using Orchard.UI.Notify;
namespace IDeliverable.Licensing.Orchard
{
public abstract class LicenseValidationErrorBannerBase : Component, INotificationProvider
{
protected LicenseValidationErrorBannerBase(IEnumerable<ILicensedProductManifest> products, UrlHelper urlHelper, string productId)
{
mProducts = products;
mUrlHelper = urlHelper;
mProductId = productId;
}
private readonly IEnumerable<ILicensedProductManifest> mProducts;
private readonly UrlHelper mUrlHelper;
private readonly string mProductId;
public IEnumerable<NotifyEntry> GetNotifications()
{
var productManifest = mProducts.Single(x => x.ProductId == mProductId);
var licenseSettingsUrl = mUrlHelper.Action("Index", "Admin", new { area = "Settings", groupInfoId = "Licenses" });
var retryResultUrl = mUrlHelper.Action("VerifyLicenseKey", "LicenseValidation", new { area = productManifest.ProductName });
var retryResultLink = T("<a href=\"{0}\">Try again</a>", retryResultUrl);
LocalizedString message = null;
try
{
LicenseValidationHelper.EnsureLicenseIsValid(productManifest.ProductId);
}
catch (LicenseValidationException ex)
{
switch (ex.Error)
{
case LicenseValidationError.UnknownLicenseKey:
message = T("The <a href=\"{0}\">configured license key</a> for the {1} module is invalid. {2}", licenseSettingsUrl, productManifest.ProductName, retryResultLink);
break;
case LicenseValidationError.HostnameMismatch:
message = T("The <a href=\"{0}\">configured license key</a> for the {1} module is invalid for the current host name. {2}", licenseSettingsUrl, productManifest.ProductName, retryResultLink);
break;
case LicenseValidationError.NoActiveSubscription:
message = T("The <a href=\"{0}\">configured license key</a> for the {1} module has no active subscription. {2}", licenseSettingsUrl, productManifest.ProductName, retryResultLink);
break;
case LicenseValidationError.LicenseRevoked:
message = T("The <a href=\"{0}\">configured license key</a> for the {1} module has been revoked. {2}", licenseSettingsUrl, productManifest.ProductName, retryResultLink);
break;
case LicenseValidationError.TokenAgeValidationFailed:
case LicenseValidationError.TokenSignatureValidationFailed:
case LicenseValidationError.LicensingServiceError:
case LicenseValidationError.LicensingServiceUnreachable:
case LicenseValidationError.UnexpectedError:
default:
message = T("There was an error validating the <a href=\"{0}\">configured license key</a> for the {1} module. {2}", licenseSettingsUrl, productManifest.ProductName, retryResultLink);
break;
}
Logger.Warning(ex, "An error occurred while validating the configured license key for the {0} module. {1}", productManifest.ProductName, retryResultLink);
}
if (message != null)
yield return new NotifyEntry { Message = message, Type = NotifyType.Warning };
}
}
}

View File

@@ -1,112 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using IDeliverable.Licensing.Validation;
using IDeliverable.Licensing.VerificationTokens;
using Orchard;
using Orchard.Logging;
using Orchard.FileSystems.AppData;
namespace IDeliverable.Licensing.Orchard
{
public class LicenseValidationHelper
{
public static bool GetLicenseIsValid(string productId)
{
try
{
EnsureLicenseIsValid(productId);
return true;
}
catch
{
return false;
}
}
public static void EnsureLicenseIsValid(string productId)
{
Instance.ValidateLicense(productId);
}
public static LicenseValidationHelper Instance
{
get
{
var workContext = HttpContext.Current.Request.RequestContext.GetWorkContext();
var products = workContext.Resolve<IEnumerable<ILicensedProductManifest>>();
var appDataFolder = workContext.Resolve<IAppDataFolder>();
var instance = new LicenseValidationHelper(products, appDataFolder);
return instance;
}
}
private static readonly TimeSpan _validationResultCachedFor = TimeSpan.FromMinutes(5);
public LicenseValidationHelper(IEnumerable<ILicensedProductManifest> products, IAppDataFolder appDataFolder)
{
var tokenStore = new LicenseVerificationTokenStore(appDataFolder);
var tokenAccessor = new LicenseVerificationTokenAccessor(tokenStore);
mProducts = products;
mLicenseValidator = new LicenseValidator(tokenAccessor);
mCacheService = new CacheService();
}
private readonly IEnumerable<ILicensedProductManifest> mProducts;
private readonly LicenseValidator mLicenseValidator;
private readonly CacheService mCacheService;
public void ValidateLicense(string productId)
{
var productManifest = GetLicensedProductManifest(productId);
productManifest.Logger.Debug("Validating license for product '{0}'...", productId);
try
{
var cacheKey = ComputeCacheKey(productManifest);
mCacheService.GetValue(cacheKey, context =>
{
context.ValidFor = _validationResultCachedFor;
var options = LicenseValidationOptions.Default;
if (productManifest.SkipValidationForLocalRequests)
options = options | LicenseValidationOptions.SkipForLocalRequests;
productManifest.Logger.Debug("Validation result not in cache. Invoking the license validator for product '{0}'...", productId);
mLicenseValidator.ValidateLicense(productManifest.ProductId, productManifest.LicenseKey, options);
return true;
});
productManifest.Logger.Debug("License successfully validated for product '{0}'.", productId);
}
catch (Exception ex)
{
productManifest.Logger.Error(ex, "An error occurred while validating the license for product '{0}'.", productId);
throw;
}
}
public void ClearLicenseValidationResult(string productId)
{
var productManifest = GetLicensedProductManifest(productId);
productManifest.Logger.Debug("Clearing license validation result for product '{0}'...", productId);
var cacheKey = ComputeCacheKey(productManifest);
mCacheService.RemoveValue(cacheKey);
}
private ILicensedProductManifest GetLicensedProductManifest(string productId)
{
return mProducts.Single(x => x.ProductId == productId);
}
private string ComputeCacheKey(ILicensedProductManifest productManifest)
{
return $"ValidateLicenseResult-{productManifest.ProductId}-{productManifest.LicenseKey}-{productManifest.SkipValidationForLocalRequests}";
}
}
}

View File

@@ -1,63 +0,0 @@
using System;
using IDeliverable.Licensing.VerificationTokens;
using Orchard.FileSystems.AppData;
using Orchard.Logging;
namespace IDeliverable.Licensing.Orchard
{
internal class LicenseVerificationTokenStore : ILicenseVerificationTokenStore
{
public LicenseVerificationTokenStore(IAppDataFolder appDataFolder)
{
mAppDataFolder = appDataFolder;
}
private readonly IAppDataFolder mAppDataFolder;
public LicenseVerificationToken Load(string productId)
{
var path = GetRelativeTokenFilePath(productId);
if (!mAppDataFolder.FileExists(path))
return null;
LicenseVerificationToken token = null;
var tokenBase64 = mAppDataFolder.ReadFile(path);
try
{
token = LicenseVerificationToken.FromBase64(tokenBase64);
}
catch
{
// An exception while parsing the token indicates somebody probably
// tampered with it or it got corrupted. In this case, let's clear out
// the store and return nothing.
Clear(productId);
}
return token;
}
public void Save(string productId, LicenseVerificationToken token)
{
Clear(productId);
var path = GetRelativeTokenFilePath(productId);
var tokenBase64 = token.ToBase64();
mAppDataFolder.CreateFile(path, tokenBase64);
}
public void Clear(string productId)
{
var path = GetRelativeTokenFilePath(productId);
if (mAppDataFolder.FileExists(path))
mAppDataFolder.DeleteFile(path);
}
private string GetRelativeTokenFilePath(string productId)
{
return $"IDeliverable.Licensing/{productId}.lic";
}
}
}

View File

@@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("IDeliverable.Licensing.Orchard.Orchard")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("IDeliverable.Licensing.Orchard.Orchard")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("f1467a6b-2397-447b-be90-766d192ec3d9")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -1,40 +0,0 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
namespace IDeliverable.Licensing.Service
{
internal class ApiKeyAuthorizationAttribute : AuthorizationFilterAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
var values = new List<string>();
var paramsQuery =
from param in actionContext.Request.GetQueryNameValuePairs()
where String.Equals(param.Key, "ApiKey", StringComparison.OrdinalIgnoreCase)
select param.Value;
values.AddRange(paramsQuery.ToArray());
IEnumerable<string> headers;
actionContext.Request.Headers.TryGetValues("ApiKey", out headers);
if (headers != null)
values.AddRange(headers);
string apiKey = values != null ? values.FirstOrDefault() : null;
if (String.IsNullOrWhiteSpace(apiKey))
actionContext.Response = actionContext.ControllerContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
var expectedApiKey = ConfigurationManager.AppSettings["ApiKey"];
if (apiKey != expectedApiKey)
actionContext.Response = actionContext.ControllerContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.Web.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace IDeliverable.Licensing.Service
{
internal static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
ConfigSerializationSettings(config);
config.MapHttpAttributeRoutes();
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
}
private static void ConfigSerializationSettings(HttpConfiguration config)
{
var jsonSetting = new JsonSerializerSettings();
jsonSetting.Converters.Add(new StringEnumConverter());
config.Formatters.JsonFormatter.SerializerSettings = jsonSetting;
}
}
}

View File

@@ -1,53 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ApplicationInsights xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings">
<!--
Learn more about Application Insights configuration with ApplicationInsights.config here:
http://go.microsoft.com/fwlink/?LinkID=513840
-->
<TelemetryModules>
<Add Type="Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing.DiagnosticsTelemetryModule, Microsoft.ApplicationInsights" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.PerfCollector.PerformanceCollectorModule, Microsoft.ApplicationInsights.Extensibility.PerfCollector">
<!--
Use the following syntax here to collect additional performance counters:
<Counters>
<Add PerformanceCounter="\Process(??APP_WIN32_PROC??)\Handle Count" ReportAs="Process handle count" />
...
</Counters>
PerformanceCounter must be either \CategoryName(InstanceName)\CounterName or \CategoryName\CounterName
Counter names may only contain letters, round brackets, forward slashes, hyphens, underscores, spaces and dots.
You may provide an optional ReportAs attribute which will be used as the metric name when reporting counter data.
For the purposes of reporting, metric names will be sanitized by removing all invalid characters from the resulting metric name.
The following placeholders are supported as InstanceName:
??APP_WIN32_PROC?? - instance name of the application process for Win32 counters.
??APP_W3SVC_PROC?? - instance name of the application IIS worker process for IIS/ASP.NET counters.
??APP_CLR_PROC?? - instance name of the application CLR process for .NET counters.
-->
</Add>
<Add Type="Microsoft.ApplicationInsights.Extensibility.RuntimeTelemetry.RemoteDependencyModule, Microsoft.ApplicationInsights.Extensibility.RuntimeTelemetry" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryModules.WebApplicationLifecycleModule, Microsoft.ApplicationInsights.Extensibility.Web" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryModules.WebRequestTrackingTelemetryModule, Microsoft.ApplicationInsights.Extensibility.Web" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryModules.WebExceptionTrackingTelemetryModule, Microsoft.ApplicationInsights.Extensibility.Web" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryModules.WebSessionTrackingTelemetryModule, Microsoft.ApplicationInsights.Extensibility.Web" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryModules.WebUserTrackingTelemetryModule, Microsoft.ApplicationInsights.Extensibility.Web" />
</TelemetryModules>
<TelemetryChannel Type="Microsoft.ApplicationInsights.Channel.PersistenceChannel, Microsoft.ApplicationInsights.PersistenceChannel" />
<ContextInitializers>
<Add Type="Microsoft.ApplicationInsights.Extensibility.BuildInfoConfigComponentVersionContextInitializer, Microsoft.ApplicationInsights" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.DeviceContextInitializer, Microsoft.ApplicationInsights" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.ContextInitializers.AzureRoleEnvironmentContextInitializer, Microsoft.ApplicationInsights.Extensibility.Web" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.ContextInitializers.DomainNameRoleInstanceContextInitializer, Microsoft.ApplicationInsights.Extensibility.Web" />
</ContextInitializers>
<TelemetryInitializers>
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryInitializers.WebSyntheticTelemetryInitializer, Microsoft.ApplicationInsights.Extensibility.Web" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryInitializers.WebClientIpHeaderTelemetryInitializer, Microsoft.ApplicationInsights.Extensibility.Web" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryInitializers.WebUserAgentTelemetryInitializer, Microsoft.ApplicationInsights.Extensibility.Web" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryInitializers.WebOperationNameTelemetryInitializer, Microsoft.ApplicationInsights.Extensibility.Web" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryInitializers.WebOperationIdTelemetryInitializer, Microsoft.ApplicationInsights.Extensibility.Web" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryInitializers.WebUserTelemetryInitializer, Microsoft.ApplicationInsights.Extensibility.Web" />
<Add Type="Microsoft.ApplicationInsights.Extensibility.Web.TelemetryInitializers.WebSessionTelemetryInitializer, Microsoft.ApplicationInsights.Extensibility.Web" />
</TelemetryInitializers>
</ApplicationInsights>

View File

@@ -1,89 +0,0 @@
using System;
using System.Configuration;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using IDeliverable.Licensing.Exceptions;
using IDeliverable.Licensing.Service.Services;
using IDeliverable.Licensing.VerificationTokens;
namespace IDeliverable.Licensing.Service.Controllers
{
[RoutePrefix("api/v1")]
public class LicenseController : ApiController
{
[HttpGet]
[Route("license/{licenseKey}/verify")]
[ApiKeyAuthorization]
public LicenseVerificationToken Verify(string licenseKey, string productId, string hostname)
{
var service = GetLicenseService();
try
{
return service.VerifyLicense(licenseKey, productId, hostname, throwOnError: false);
}
catch (LicenseVerificationException ex)
{
switch (ex.Error)
{
case LicenseVerificationError.UnknownLicenseKey:
ThrowHttpResponseException(ex, HttpStatusCode.NotFound);
break;
case LicenseVerificationError.HostnameMismatch:
ThrowHttpResponseException(ex, HttpStatusCode.Forbidden);
break;
case LicenseVerificationError.NoActiveSubscription:
case LicenseVerificationError.LicenseRevoked:
ThrowHttpResponseException(ex, HttpStatusCode.Gone);
break;
default:
throw;
}
}
return null;
}
[HttpGet]
[Route("test")]
[ApiKeyAuthorization]
public HttpResponseMessage Test()
{
var testKey = ConfigurationManager.AppSettings["TestKey"];
var testProductId = ConfigurationManager.AppSettings["TestProductId"];
var testHostname = ConfigurationManager.AppSettings["TestHostname"];
var service = GetLicenseService();
try
{
service.VerifyLicense(testKey, testProductId, testHostname, throwOnError: true);
}
catch (Exception ex)
{
return new HttpResponseMessage(HttpStatusCode.InternalServerError) { ReasonPhrase = $"Verification for a supposedly valid license failed: {ex.Message}." };
}
return new HttpResponseMessage(HttpStatusCode.OK);
}
private static LicenseService GetLicenseService()
{
var sendOwlApiEndpoint = ConfigurationManager.AppSettings["SendOwlApiEndpoint"];
var sendOwlApiKey = ConfigurationManager.AppSettings["SendOwlApiKey"];
var sendOwlApiSecret = ConfigurationManager.AppSettings["SendOwlApiSecret"];
var tokenSigningCertificateThumbprint = ConfigurationManager.AppSettings["TokenSigningCertificateThumbprint"];
return new LicenseService(sendOwlApiEndpoint, sendOwlApiKey, sendOwlApiSecret, tokenSigningCertificateThumbprint);
}
private static void ThrowHttpResponseException(LicenseVerificationException ex, HttpStatusCode httpStatusCode)
{
var response = new HttpResponseMessage(httpStatusCode) { ReasonPhrase = ex.Message };
response.Headers.Add("LicensingErrorCode", ex.Error.ToString());
throw new HttpResponseException(response);
}
}
}

View File

@@ -1 +0,0 @@
<%@ Application Codebehind="Global.asax.cs" Inherits="IDeliverable.Licensing.Service.WebApiApplication" Language="C#" %>

View File

@@ -1,22 +0,0 @@
using System;
using System.Configuration;
using System.Web.Http;
using Microsoft.ApplicationInsights.Extensibility;
namespace IDeliverable.Licensing.Service
{
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
// Configure ApplicationInsights instrumentation key.
var instrumentationKey = ConfigurationManager.AppSettings["ApplicationInsights.InstrumentationKey"];
if (!String.IsNullOrWhiteSpace(instrumentationKey))
TelemetryConfiguration.Active.InstrumentationKey = instrumentationKey;
else
TelemetryConfiguration.Active.DisableTelemetry = true;
}
}
}

View File

@@ -1,251 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>
</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{6014E7AC-C979-4D50-B8D9-5FD9DC8CA641}</ProjectGuid>
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>IDeliverable.Licensing.Service</RootNamespace>
<AssemblyName>IDeliverable.Licensing.Service</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<MvcBuildViews>false</MvcBuildViews>
<UseIISExpress>true</UseIISExpress>
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
<UseGlobalApplicationHostFile>true</UseGlobalApplicationHostFile>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<ApplicationInsightsResourceId>/subscriptions/1788357e-d506-4118-9f88-092c1dcddc16/resourcegroups/Internal/providers/microsoft.insights/components/ideliverable-licensing</ApplicationInsightsResourceId>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net, Version=1.2.13.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\..\packages\log4net.2.0.3\lib\net40-full\log4net.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="LogentriesCore, Version=2.6.7.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\logentries.core.2.7.0\lib\net40\LogentriesCore.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="LogentriesLog4net, Version=2.6.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\logentries.log4net.2.7.0\lib\net40\LogentriesLog4net.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.ApplicationInsights, Version=0.14.3.177, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.0.14.3-build00177\lib\net40\Microsoft.ApplicationInsights.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.ApplicationInsights.Extensibility.PerfCollector, Version=0.14.3.185, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.PerformanceCollector.0.14.3-build00177\lib\net40\Microsoft.ApplicationInsights.Extensibility.PerfCollector.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.ApplicationInsights.Extensibility.RuntimeTelemetry, Version=0.14.3.177, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.RuntimeTelemetry.0.14.3-build00177\lib\net45\Microsoft.ApplicationInsights.Extensibility.RuntimeTelemetry.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.ApplicationInsights.Extensibility.Web, Version=0.14.3.177, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.Web.0.14.3-build00177\lib\net45\Microsoft.ApplicationInsights.Extensibility.Web.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.ApplicationInsights.PersistenceChannel, Version=0.14.3.186, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.PersistenceChannel.0.14.3-build00177\lib\net40\Microsoft.ApplicationInsights.PersistenceChannel.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.Diagnostics.Instrumentation.Extensions.Intercept, Version=0.14.0.8007, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.Agent.Intercept.0.14.0-build08008\lib\net40\Microsoft.Diagnostics.Instrumentation.Extensions.Intercept.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Diagnostics.Tracing.EventSource, Version=1.1.16.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Diagnostics.Tracing.EventSource.Redist.1.1.16-beta\lib\net45\Microsoft.Diagnostics.Tracing.EventSource.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Threading.Tasks.Extensions, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop, Version=1.0.168.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Web.Infrastructure">
<HintPath>..\..\..\lib\aspnetmvc\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Configuration, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.WindowsAzure.ConfigurationManager.3.1.0\lib\net40\Microsoft.WindowsAzure.Configuration.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>..\..\..\lib\newtonsoft.json\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net" />
<Reference Include="System.Net.Http.Formatting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</Reference>
<Reference Include="System.Web.Entity" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Web.Helpers">
<HintPath>..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http.WebHost, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc, Version=4.0.0.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll</HintPath>
</Reference>
<Reference Include="System.Web.Razor">
<HintPath>..\..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages">
<HintPath>..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Deployment">
<HintPath>..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Razor">
<HintPath>..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Abstractions" />
<Reference Include="System.Web.Routing" />
<Reference Include="System.Xml" />
<Reference Include="System.Configuration" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Net.Http">
</Reference>
<Reference Include="System.Net.Http.WebRequest">
</Reference>
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Compile Include="App_Start\WebApiConfig.cs" />
<Compile Include="ApiKeyAuthorizationAttribute.cs" />
<Compile Include="Controllers\LicenseController.cs" />
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\LicenseInfo.cs" />
<Compile Include="Services\LicenseService.cs" />
<Compile Include="Services\Logger.cs" />
<Compile Include="Services\OrderInfo.cs" />
<Compile Include="Services\OrderStatus.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Global.asax" />
<Content Include="packages.config" />
<Content Include="ApplicationInsights.config" />
<Content Include="Log4net.config" />
<None Include="Properties\PublishProfiles\ideliverable-licensing.pubxml" />
<Content Include="Web.config">
<SubType>Designer</SubType>
</Content>
<Content Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon>
</Content>
<Content Include="Web.Release.config">
<DependentUpon>Web.config</DependentUpon>
</Content>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IDeliverable.Licensing\IDeliverable.Licensing.csproj">
<Project>{7e439cb7-1ace-435f-a8f3-5bb929423e34}</Project>
<Name>IDeliverable.Licensing</Name>
</ProjectReference>
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>56979</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:56979/</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
<Import Project="..\..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets" Condition="Exists('..\..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" />
<Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''">
<Error Condition="!Exists('..\..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
<Error Condition="Exists('..\..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
</Target>
<Import Project="..\..\packages\Microsoft.Diagnostics.Tracing.EventSource.Redist.1.1.16-beta\build\portable-net45+win8+wpa81\Microsoft.Diagnostics.Tracing.EventSource.Redist.targets" Condition="Exists('..\..\packages\Microsoft.Diagnostics.Tracing.EventSource.Redist.1.1.16-beta\build\portable-net45+win8+wpa81\Microsoft.Diagnostics.Tracing.EventSource.Redist.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\Microsoft.Diagnostics.Tracing.EventSource.Redist.1.1.16-beta\build\portable-net45+win8+wpa81\Microsoft.Diagnostics.Tracing.EventSource.Redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Diagnostics.Tracing.EventSource.Redist.1.1.16-beta\build\portable-net45+win8+wpa81\Microsoft.Diagnostics.Tracing.EventSource.Redist.targets'))" />
<Error Condition="!Exists('..\..\packages\Microsoft.ApplicationInsights.Agent.Intercept.0.14.0-build08008\build\Microsoft.ApplicationInsights.Agent.Intercept.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.ApplicationInsights.Agent.Intercept.0.14.0-build08008\build\Microsoft.ApplicationInsights.Agent.Intercept.targets'))" />
</Target>
<Import Project="..\..\packages\Microsoft.ApplicationInsights.0.14.3-build00177\tools\net40\Microsoft.ApplicationInsights.targets" Condition="Exists('..\..\packages\Microsoft.ApplicationInsights.0.14.3-build00177\tools\net40\Microsoft.ApplicationInsights.targets')" />
<Target Name="EnsureApplicationInsightsImported" BeforeTargets="BeforeBuild" Condition="'$(ApplicationInsightsImported)' == ''">
<Error Condition="!Exists('..\..\packages\Microsoft.ApplicationInsights.0.14.3-build00177\tools\net40\Microsoft.ApplicationInsights.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." />
<Error Condition="Exists('..\..\packages\Microsoft.ApplicationInsights.0.14.3-build00177\tools\net40\Microsoft.ApplicationInsights.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." />
</Target>
<Import Project="..\..\packages\Microsoft.ApplicationInsights.Agent.Intercept.0.14.0-build08008\build\Microsoft.ApplicationInsights.Agent.Intercept.targets" Condition="Exists('..\..\packages\Microsoft.ApplicationInsights.Agent.Intercept.0.14.0-build08008\build\Microsoft.ApplicationInsights.Agent.Intercept.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target> -->
</Project>

View File

@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<root>
<!-- Value of level may be ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF -->
<level value="DEBUG" />
<appender-ref ref="DebuggerAppender" />
<appender-ref ref="LeAppender" />
</root>
<appender name="LeAppender" type="log4net.Appender.LogentriesAppender, LogentriesLog4net">
<!-- Credentials are read from appSettings. -->
<immediateFlush value="true" />
<debug value="true" />
<useHttpPut value="false" />
<useSsl value="false" />
<layout type="log4net.Layout.PatternLayout">
<!-- The below pattern has been carefully formatted and optimized to work well with the Logentries.com entry parser. For reference see https://logentries.com/doc/search/. -->
<param name="ConversionPattern" value="%d %logger %level% %m%n%exceptionSessionId='%aspnet-request{ASP.NET_SessionId}'; Username='%aspnet-request{AUTH_USER}'; ClientIpAddress='%aspnet-request{REMOTE_ADDR}'; ClientUserAgent='%aspnet-request{HTTP_USER_AGENT}'; ServerName='%aspnet-request{SERVER_NAME}'; RequestMethod='%aspnet-request{REQUEST_METHOD}'; RequestUrl='%aspnet-request{URL}'; RequestQueryString='%aspnet-request{QUERY_STRING}'; RequestCookies='%aspnet-request{HTTP_COOKIE}'; MachineName='%property{log4net:HostName}';%n" />
</layout>
</appender>
<appender name="DebuggerAppender" type="log4net.Appender.DebugAppender">
<immediateFlush value="true" />
<layout type="log4net.Layout.SimpleLayout" />
</appender>
</log4net>

View File

@@ -1,35 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("IDeliverable.Licensing.Service")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("IDeliverable.Licensing.Service")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("c2a67b6c-4615-4ecf-bfc6-39bf0f975c1f")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit http://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<ADUsesOwinOrOpenIdConnect>False</ADUsesOwinOrOpenIdConnect>
<LastUsedBuildConfiguration>Debug</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish>http://ideliverable-licensing.azurewebsites.net</SiteUrlToLaunchAfterPublish>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<MSDeployServiceURL>ideliverable-licensing.scm.azurewebsites.net:443</MSDeployServiceURL>
<DeployIisAppPath>ideliverable-licensing</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<EnableMSDeployBackup>True</EnableMSDeployBackup>
<UserName>$ideliverable-licensing</UserName>
<_SavePWD>True</_SavePWD>
<_DestinationType>AzureWebSite</_DestinationType>
</PropertyGroup>
</Project>

View File

@@ -1,14 +0,0 @@
namespace IDeliverable.Licensing.Service.Services
{
internal class LicenseInfo
{
public LicenseInfo(string key, int orderId)
{
Key = key;
OrderId = orderId;
}
public string Key { get; }
public int OrderId { get; }
}
}

View File

@@ -1,185 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using IDeliverable.Licensing.Exceptions;
using IDeliverable.Licensing.VerificationTokens;
using Newtonsoft.Json.Linq;
namespace IDeliverable.Licensing.Service.Services
{
internal class LicenseService
{
public LicenseService(string sendOwlApiEndpoint, string sendOwlApiKey, string sendOwlApiSecret, string tokenSigningCertificateThumbprint)
{
mSendOwlApiEndpoint = sendOwlApiEndpoint;
mSendOwlApiKey = sendOwlApiKey;
mSendOwlApiSecret = sendOwlApiSecret;
mTokenSigningCertificateThumbprint = tokenSigningCertificateThumbprint;
mLogger = new Logger(nameof(LicenseService));
}
private readonly string mSendOwlApiEndpoint;
private readonly string mSendOwlApiKey;
private readonly string mSendOwlApiSecret;
private readonly string mTokenSigningCertificateThumbprint;
private readonly Logger mLogger;
public LicenseVerificationToken VerifyLicense(string licenseKey, string productId, string hostname, bool throwOnError)
{
mLogger.Info($"Starting license verification... LicenseKey={licenseKey}; ProductId={productId}; Hostname={hostname};");
try
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(mSendOwlApiEndpoint);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", CreateBasicAuthenticationToken(mSendOwlApiKey, mSendOwlApiSecret));
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var licenses = ParseLicenseInfo(client.GetAsync($"products/{productId}/licenses/check_valid?key={licenseKey}").Result.Content.ReadAsStringAsync().Result).ToList();
if (!licenses.Any())
throw new LicenseVerificationException($"No license with key '{licenseKey}' was found.", LicenseVerificationError.UnknownLicenseKey);
var orderId = licenses.First(x => x.Key == licenseKey).OrderId;
var order = ParseOrderInfo(client.GetAsync($"orders/{orderId}").Result.Content.ReadAsStringAsync().Result);
if (!order.IsProductAccessAllowed)
{
if(order.SubscriptionId != null)
throw new LicenseVerificationException($"The license with key '{licenseKey}' is not associated with an active subscription.", LicenseVerificationError.NoActiveSubscription);
throw new LicenseVerificationException($"The license with key '{licenseKey}' has been revoked.", LicenseVerificationError.LicenseRevoked);
}
if (!order.Hostnames.Contains(hostname, StringComparer.OrdinalIgnoreCase))
throw new LicenseVerificationException($"The license with key '{licenseKey}' is not valid for the provided '{hostname}'. Valid hostnames are '{String.Join(",", order.Hostnames)}", LicenseVerificationError.HostnameMismatch);
}
}
catch (Exception ex) when (!(ex is LicenseVerificationException))
{
mLogger.Error($"An error occurred while verifying license with SendOwl. LicenseKey={licenseKey}; ProductId={productId}; Hostname={hostname};", ex);
if (throwOnError)
throw;
mLogger.Info("Ignoring error and issuing verification token anyway. LicenseKey={licenseKey}; ProductId={productId}; Hostname={hostname};");
}
mLogger.Info($"License verification finished. LicenseKey={licenseKey}; ProductId={productId}; Hostname={hostname};");
return CreateVerificationToken(productId, hostname, licenseKey);
}
private LicenseVerificationToken CreateVerificationToken(string productId, string hostname, string key)
{
X509Certificate2 signingCert = null;
// Try to find the certificate in either the CurrentUser or LocalMachine stores
// to maximize code portability.
signingCert = GetSigningCertificateFrom(StoreLocation.CurrentUser) ?? GetSigningCertificateFrom(StoreLocation.LocalMachine);
if (signingCert == null)
throw new Exception($"No certificate with thumbprint '{mTokenSigningCertificateThumbprint}' was found in the certificate store.");
var info = new LicenseVerificationInfo(productId, hostname, key, DateTime.UtcNow.Ticks);
var token = LicenseVerificationToken.Create(info, signingCert);
return token;
}
private X509Certificate2 GetSigningCertificateFrom(StoreLocation location)
{
var store = new X509Store(StoreName.My, location);
store.Open(OpenFlags.ReadOnly);
try
{
var certificates = store.Certificates.Find(X509FindType.FindByThumbprint, mTokenSigningCertificateThumbprint, validOnly: false);
return certificates.Count > 0 ? certificates[0] : null;
}
finally
{
store.Close();
}
}
private string CreateBasicAuthenticationToken(string userName, string password)
{
return Convert.ToBase64String(Encoding.UTF8.GetBytes($"{userName}:{password}"), Base64FormattingOptions.None);
}
private IEnumerable<LicenseInfo> ParseLicenseInfo(string json)
{
var licensesQuery =
from node in JArray.Parse(json)
select new LicenseInfo((string)node["license"]["key"], (int)node["license"]["order_id"]);
return licensesQuery.ToArray();
}
private OrderInfo ParseOrderInfo(string json)
{
var order = JObject.Parse(json)["order"];
var status = ReadOrderStatus(order);
var isAccessAllowed = (bool) order["access_allowed"];
var subscriptionId = (int?) order["subscription_id"];
var customFields = (JArray)order["order_custom_checkout_fields"];
var hostnames = new List<string>();
if (customFields.Count > 0)
{
var hostnameString = (string)customFields[0]["order_custom_checkout_field"]["value"];
if (!String.IsNullOrWhiteSpace(hostnameString))
hostnames.Add(ParseHostname(hostnameString));
}
if (customFields.Count > 1)
{
var hostnameString = (string)customFields[1]["order_custom_checkout_field"]["value"];
if (!String.IsNullOrWhiteSpace(hostnameString))
hostnames.Add(ParseHostname(hostnameString));
}
return new OrderInfo((int)order["id"], status, isAccessAllowed, subscriptionId, hostnames);
}
private string ParseHostname(string hostnameString)
{
Uri uri = null;
if (Uri.TryCreate(hostnameString, UriKind.Absolute, out uri))
return uri.Host;
return hostnameString;
}
private static OrderStatus ReadOrderStatus(JToken order)
{
var dictionary = new Dictionary<string, OrderStatus>
{
{"initial", OrderStatus.Initial },
{"payment_started", OrderStatus.PaymentStarted },
{"payment_pending", OrderStatus.PaymentPending },
{"failed", OrderStatus.Failed },
{"complete", OrderStatus.Complete },
{"chargeback", OrderStatus.Chargeback },
{"refunded", OrderStatus.Refunded },
{"in_dispute", OrderStatus.InDispute },
{"free", OrderStatus.Free },
{"imported", OrderStatus.Imported },
{"fraud_review", OrderStatus.FraudReview },
{"subscription_setup", OrderStatus.SubscriptionSetup },
{"subscription_active", OrderStatus.SubscriptionActive },
{"subscription_complete", OrderStatus.SubscriptionComplete },
{"subscription_cancelled", OrderStatus.SubscriptionCancelled }
};
var status = (string) order["state"];
return dictionary.ContainsKey(status) ? dictionary[status] : OrderStatus.Unknown;
}
}
}

View File

@@ -1,64 +0,0 @@
using System;
using System.IO;
using log4net;
using log4net.Config;
namespace IDeliverable.Licensing.Service.Services
{
public class Logger
{
private const string ConfigFileName = "Log4net.config";
static Logger()
{
var basePath = AppDomain.CurrentDomain.BaseDirectory;
var configFilePath = Path.Combine(basePath, ConfigFileName);
if (File.Exists(configFilePath))
XmlConfigurator.Configure(new FileInfo(configFilePath));
else
throw new Exception($"The log4net configuration file could not be found at path '{configFilePath}'.");
}
public Logger(Type loggerType)
:this(loggerType.FullName)
{
}
public Logger(string loggerName)
{
mLog = LogManager.GetLogger(loggerName);
}
private ILog mLog;
public void Fatal(string message, Exception ex = null)
{
if (mLog.IsFatalEnabled)
mLog.Fatal(message, ex);
}
public void Error(string message, Exception ex = null)
{
if (mLog.IsErrorEnabled)
mLog.Error(message, ex);
}
public void Warn(string message, Exception ex = null)
{
if (mLog.IsWarnEnabled)
mLog.Warn(message, ex);
}
public void Info(string message, Exception ex = null)
{
if (mLog.IsInfoEnabled)
mLog.Info(message, ex);
}
public void Debug(string message, Exception ex = null)
{
if (mLog.IsDebugEnabled)
mLog.Debug(message, ex);
}
}
}

View File

@@ -1,22 +0,0 @@
using System.Collections.Generic;
namespace IDeliverable.Licensing.Service.Services
{
internal class OrderInfo
{
public OrderInfo(int orderId, OrderStatus status, bool isProductAccessAllowed, int? subscriptionId, IEnumerable<string> hostnames)
{
OrderId = orderId;
Hostnames = hostnames;
Status = status;
IsProductAccessAllowed = isProductAccessAllowed;
SubscriptionId = subscriptionId;
}
public int OrderId { get; }
public IEnumerable<string> Hostnames { get; }
public OrderStatus Status { get; }
public bool IsProductAccessAllowed { get; }
public int? SubscriptionId { get; }
}
}

View File

@@ -1,21 +0,0 @@
namespace IDeliverable.Licensing.Service.Services {
internal enum OrderStatus
{
Unknown,
Initial,
PaymentStarted,
PaymentPending,
Failed,
Complete,
Chargeback,
Refunded,
InDispute,
Free,
Imported,
FraudReview,
SubscriptionSetup,
SubscriptionActive,
SubscriptionComplete,
SubscriptionCancelled,
}
}

View File

@@ -1,30 +0,0 @@
<?xml version="1.0"?>
<!-- For more information on using Web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=301874 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!--
In the example below, the "SetAttributes" transform will change the value of
"connectionString" to use "ReleaseSQLServer" only when the "Match" locator
finds an attribute "name" that has a value of "MyDB".
<connectionStrings>
<add name="MyDB"
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
-->
<system.web>
<!--
In the example below, the "Replace" transform will replace the entire
<customErrors> section of your Web.config file.
Note that because there is only one customErrors section under the
<system.web> node, there is no need to use the "xdt:Locator" attribute.
<customErrors defaultRedirect="GenericError.htm"
mode="RemoteOnly" xdt:Transform="Replace">
<error statusCode="500" redirect="InternalError.htm"/>
</customErrors>
-->
</system.web>
</configuration>

View File

@@ -1,31 +0,0 @@
<?xml version="1.0"?>
<!-- For more information on using Web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=301874 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!--
In the example below, the "SetAttributes" transform will change the value of
"connectionString" to use "ReleaseSQLServer" only when the "Match" locator
finds an attribute "name" that has a value of "MyDB".
<connectionStrings>
<add name="MyDB"
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
-->
<system.web>
<compilation xdt:Transform="RemoveAttributes(debug)" />
<!--
In the example below, the "Replace" transform will replace the entire
<customErrors> section of your Web.config file.
Note that because there is only one customErrors section under the
<system.web> node, there is no need to use the "xdt:Locator" attribute.
<customErrors defaultRedirect="GenericError.htm"
mode="RemoteOnly" xdt:Transform="Replace">
<error statusCode="500" redirect="InternalError.htm"/>
</customErrors>
-->
</system.web>
</configuration>

View File

@@ -1,52 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="ApiKey" value="MJb17j7YAzSjyEYkhsoI" />
<add key="TestProductId" value="233554" />
<add key="TestHostname" value="ideliverable.com" />
<add key="TestKey" value="ADB5-2D53-0A62-4C2F" />
<add key="SendOwlApiEndpoint" value="https://www.sendowl.com/api/v1/" />
<add key="SendOwlApiKey" value="14be9ee5e05222e" />
<add key="SendOwlApiSecret" value="1a10fe7987724e0a56a1" />
<add key="TokenSigningCertificateThumbprint" value="fa4746a778716109e7e80e1b8dc2ed2a2ba3b852" />
<add key="Logentries.Token" value="5c73ab7f-39a3-4171-b730-03da5c3d4b24"/> <!-- Local -->
<add key="ApplicationInsights.InstrumentationKey" value="" /> <!-- Disabled -->
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2" />
<httpModules>
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Extensibility.Web.RequestTracking.WebRequestTrackingModule, Microsoft.ApplicationInsights.Extensibility.Web" />
</httpModules>
</system.web>
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<validation validateIntegratedModeConfiguration="false" />
<modules>
<remove name="ApplicationInsightsWebTracking" />
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Extensibility.Web.RequestTracking.WebRequestTrackingModule, Microsoft.ApplicationInsights.Extensibility.Web" preCondition="managedHandler" />
</modules>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.3" targetFramework="net452" userInstalled="true" />
<package id="logentries.core" version="2.7.0" targetFramework="net452" userInstalled="true" />
<package id="logentries.log4net" version="2.7.0" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.ApplicationInsights" version="0.14.3-build00177" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.ApplicationInsights.Agent.Intercept" version="0.14.0-build08008" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.ApplicationInsights.JavaScript" version="0.11.0-build09387" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.ApplicationInsights.PerformanceCollector" version="0.14.3-build00177" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.ApplicationInsights.PersistenceChannel" version="0.14.3-build00177" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.ApplicationInsights.RuntimeTelemetry" version="0.14.3-build00177" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.ApplicationInsights.Web" version="0.14.3-build00177" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.AspNet.WebApi.HelpPage" version="5.2.3" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.Bcl" version="1.1.8" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.Diagnostics.Tracing.EventSource.Redist" version="1.1.16-beta" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net452" userInstalled="true" />
<package id="Microsoft.WindowsAzure.ConfigurationManager" version="3.1.0" targetFramework="net452" userInstalled="true" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net452" userInstalled="true" />
</packages>

View File

@@ -1,11 +0,0 @@
using System;
using System.Web.Caching;
namespace IDeliverable.Licensing
{
public class CacheInvalidationContext
{
public CacheDependency CacheDependency { get; set; }
public TimeSpan? ValidFor { get; set; }
}
}

View File

@@ -1,52 +0,0 @@
using System;
using System.Web.Caching;
namespace IDeliverable.Licensing
{
public class CacheService
{
private readonly HttpContextAccessor mHttpContextAccessor = new HttpContextAccessor();
private Cache Cache => mHttpContextAccessor.Current().Cache;
public void SetValue<T>(string key, T value, CacheDependency dependency = null, TimeSpan? validFor = null)
{
var absoluteExpiration = validFor != null ? DateTime.UtcNow.Add(validFor.Value) : Cache.NoAbsoluteExpiration;
Cache.Insert(key, value, dependency, absoluteExpiration, Cache.NoSlidingExpiration);
}
public T GetValue<T>(string key, Func<CacheInvalidationContext, T> valueFactory = null)
{
var value = Cache.Get(key);
var exception = value as Exception;
if (exception != null)
throw (Exception)value;
if (value != null)
return (T)value;
if (valueFactory == null)
return default(T);
var context = new CacheInvalidationContext();
try
{
value = valueFactory(context);
SetValue(key, value, context.CacheDependency, context.ValidFor);
return (T) value;
}
catch (Exception ex)
{
SetValue(key, ex, context.CacheDependency, context.ValidFor);
throw;
}
}
public object RemoveValue(string key)
{
return Cache.Remove(key);
}
}
}

View File

@@ -1,11 +0,0 @@
namespace IDeliverable.Licensing.Exceptions
{
public enum LicenseVerificationError
{
UnknownLicenseKey,
NoActiveSubscription,
LicenseRevoked,
HostnameMismatch,
UnhandledException
}
}

View File

@@ -1,29 +0,0 @@
using System;
namespace IDeliverable.Licensing.Exceptions
{
public class LicenseVerificationException : Exception
{
public LicenseVerificationException(LicenseVerificationError error)
:this("An error occurred while verifying the license.", error)
{
}
public LicenseVerificationException(string message, LicenseVerificationError error) : base(message)
{
Error = error;
}
public LicenseVerificationException(LicenseVerificationError error, Exception innerException)
: this("An error occurred while verifying the license.", error, innerException)
{
}
public LicenseVerificationException(string message, LicenseVerificationError error, Exception innerException) : base(message, innerException)
{
Error = error;
}
public LicenseVerificationError Error { get; private set; }
}
}

View File

@@ -1,12 +0,0 @@
using System.Web;
namespace IDeliverable.Licensing
{
public class HttpContextAccessor
{
public HttpContextBase Current()
{
return new HttpContextWrapper(HttpContext.Current);
}
}
}

View File

@@ -1,17 +0,0 @@
using System.Web;
namespace IDeliverable.Licensing
{
internal static class HttpRequestExtensions
{
public static string GetHttpHost(this HttpRequestBase request)
{
var host = request.ServerVariables["HTTP_HOST"];
if (host?.Contains(":") == true)
host = host.Substring(0, host.IndexOf(':'));
return host;
}
}
}

View File

@@ -1,74 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7E439CB7-1ACE-435F-A8F3-5BB929423E34}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>IDeliverable.Licensing</RootNamespace>
<AssemblyName>IDeliverable.Licensing</AssemblyName>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json">
<HintPath>..\..\..\lib\newtonsoft.json\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CacheInvalidationContext.cs" />
<Compile Include="CacheService.cs" />
<Compile Include="Exceptions\LicenseVerificationError.cs" />
<Compile Include="Exceptions\LicenseVerificationException.cs" />
<Compile Include="HttpContextAccessor.cs" />
<Compile Include="HttpRequestExtensions.cs" />
<Compile Include="Validation\LicenseValidationError.cs" />
<Compile Include="Validation\LicenseValidationException.cs" />
<Compile Include="Validation\LicenseValidator.cs" />
<Compile Include="VerificationTokens\LicenseVerificationTokenError.cs" />
<Compile Include="VerificationTokens\LicenseVerificationTokenException.cs" />
<Compile Include="VerificationTokens\LicenseVerificationInfo.cs" />
<Compile Include="VerificationTokens\LicenseVerificationToken.cs" />
<Compile Include="VerificationTokens\LicenseVerificationTokenAccessor.cs" />
<Compile Include="VerificationTokens\LicensingServiceClient.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Validation\LicenseValidationOptions.cs" />
<Compile Include="VerificationTokens\ILicenseVerificationTokenStore.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("IDeliverable.LicensingFramework")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("IDeliverable.LicensingFramework")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("7e439cb7-1ace-435f-a8f3-5bb929423e34")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -1,15 +0,0 @@
namespace IDeliverable.Licensing.Validation
{
public enum LicenseValidationError
{
UnknownLicenseKey,
HostnameMismatch,
NoActiveSubscription,
LicenseRevoked,
LicensingServiceError,
LicensingServiceUnreachable,
TokenAgeValidationFailed,
TokenSignatureValidationFailed,
UnexpectedError,
}
}

View File

@@ -1,29 +0,0 @@
using System;
namespace IDeliverable.Licensing.Validation
{
public class LicenseValidationException : Exception
{
public LicenseValidationException(LicenseValidationError error)
:this("An error occurred while validating the license.", error)
{
}
public LicenseValidationException(string message, LicenseValidationError error) : base(message)
{
Error = error;
}
public LicenseValidationException(LicenseValidationError error, Exception innerException)
: this("An error occurred while validating the license.", error, innerException)
{
}
public LicenseValidationException(string message, LicenseValidationError error, Exception innerException) : base(message, innerException)
{
Error = error;
}
public LicenseValidationError Error { get; private set; }
}
}

View File

@@ -1,12 +0,0 @@
using System;
namespace IDeliverable.Licensing.Validation
{
[Flags]
public enum LicenseValidationOptions
{
Default = 0,
SkipForLocalRequests = 1,
ForceRenewToken = 2,
}
}

View File

@@ -1,144 +0,0 @@
using System;
using System.Security.Cryptography.X509Certificates;
using IDeliverable.Licensing.VerificationTokens;
namespace IDeliverable.Licensing.Validation
{
public class LicenseValidator
{
private static readonly TimeSpan sVerificationTokenValidFor = TimeSpan.FromDays(21);
private static readonly TimeSpan sAllowableClockSkew = TimeSpan.FromMinutes(10);
public LicenseValidator(LicenseVerificationTokenAccessor verificationTokenAccessor)
{
mHttpContextAccessor = new HttpContextAccessor();
mVerificationTokenAccessor = verificationTokenAccessor;
}
private readonly HttpContextAccessor mHttpContextAccessor;
private readonly LicenseVerificationTokenAccessor mVerificationTokenAccessor;
public void ValidateLicense(string productId, string licenseKey, LicenseValidationOptions options = LicenseValidationOptions.Default)
{
var request = mHttpContextAccessor.Current().Request;
var isLocal = request.IsLocal;
var isDebugMode = mHttpContextAccessor.Current().IsDebuggingEnabled;
var skipForLocalRequests = (options & LicenseValidationOptions.SkipForLocalRequests) == LicenseValidationOptions.SkipForLocalRequests;
if (skipForLocalRequests && isLocal && isDebugMode)
return;
LicenseVerificationToken token;
try
{
var forceRenewToken = (options & LicenseValidationOptions.ForceRenewToken) == LicenseValidationOptions.ForceRenewToken;
token = mVerificationTokenAccessor.GetLicenseVerificationToken(productId, licenseKey, request.GetHttpHost(), forceRenewToken);
// If the token we got back is too old to be considered valid anymore, try to get the token
// again, this time forcing token renewal.
if (token.Age > sVerificationTokenValidFor)
token = mVerificationTokenAccessor.GetLicenseVerificationToken(productId, licenseKey, request.GetHttpHost(), forceRenew: true);
}
catch (LicenseVerificationTokenException ex)
{
var error = LicenseValidationError.UnexpectedError;
switch (ex.Error)
{
case LicenseVerificationTokenError.UnknownLicenseKey:
error = LicenseValidationError.UnknownLicenseKey;
break;
case LicenseVerificationTokenError.HostnameMismatch:
error = LicenseValidationError.HostnameMismatch;
break;
case LicenseVerificationTokenError.NoActiveSubscription:
error = LicenseValidationError.NoActiveSubscription;
break;
case LicenseVerificationTokenError.LicenseRevoked:
error = LicenseValidationError.LicenseRevoked;
break;
case LicenseVerificationTokenError.LicenseServiceError:
error = LicenseValidationError.LicensingServiceError;
break;
case LicenseVerificationTokenError.LicenseServiceUnreachable:
error = LicenseValidationError.LicensingServiceUnreachable;
break;
}
throw new LicenseValidationException(ex.Message, error);
}
catch (Exception ex)
{
throw new LicenseValidationException("An unexpected error occurred while validating the license.", LicenseValidationError.UnexpectedError, ex);
}
// It should never happen that at this point we don't have a token or it's too old.
if (token == null || token.Age > sVerificationTokenValidFor)
throw new LicenseValidationException(LicenseValidationError.UnexpectedError);
// If the token age is negative by more than 10 minutes (allowable clock skew between licensing
// service and local machine) then this is a strong indication of an attempt to bypass license
// validation by changing the system clock.
if (token.Age < -sAllowableClockSkew)
throw new LicenseValidationException("The license verification token age is negative by more than the allowable clock skew. This might indicate that system clock of either the client or the licensing service is offset.", LicenseValidationError.TokenAgeValidationFailed);
var signingCertificate = GetSigningCertificate();
if (!token.GetSignatureIsValid(signingCertificate))
throw new LicenseValidationException("License verification token signature validation failed.", LicenseValidationError.TokenSignatureValidationFailed);
}
private static X509Certificate2 GetSigningCertificate()
{
const string certBase64 =
@"MIIG0TCCBLmgAwIBAgIQ7qnUeLGos7hDPcw3o9G74jANBgkqhkiG9w0BAQ0FADCB
ozELMAkGA1UEBhMCQ1kxETAPBgNVBAgTCExpbWFzc29sMREwDwYDVQQHEwhMaW1h
c3NvbDEZMBcGA1UEChMQSURlbGl2ZXJhYmxlIEx0ZDETMBEGA1UECxMKT3BlcmF0
aW9uczEYMBYGA1UEAxMPSURlbGl2ZXJhYmxlIENBMSQwIgYJKoZIhvcNAQkBFhVp
bmZvQGlkZWxpdmVyYWJsZS5jb20wHhcNMTQxMjMxMjEwMDAwWhcNMjQxMjMxMjEw
MDAwWjCBrjELMAkGA1UEBhMCQ1kxETAPBgNVBAgTCExpbWFzc29sMREwDwYDVQQH
EwhMaW1hc3NvbDEZMBcGA1UEChMQSURlbGl2ZXJhYmxlIEx0ZDETMBEGA1UECxMK
T3BlcmF0aW9uczEjMCEGA1UEAxMabGljZW5zaW5nLmlkZWxpdmVyYWJsZS5jb20x
JDAiBgkqhkiG9w0BCQEWFWluZm9AaWRlbGl2ZXJhYmxlLmNvbTCCAiIwDQYJKoZI
hvcNAQEBBQADggIPADCCAgoCggIBAJ0LddkeiE9f0p60exUCR1PxrKBHoVwF5von
Lq+4GxA4I7Frtt8MV/dEYnYT44d/S6lEkAPLfF70CnyyWfpPO7MkIJYlFNZ2eJSz
9wu0VZ12CZO9RilxrEzK1xLS+f6g7P+rPP3m1CqSt84wpd3YloLdBuB3HwPWNh5H
a0Ew7W6IKyhzIX4MNzXXNc2evDIoaur3jQiPewtSastXzSQEEUx+S4St4qFbJ8lK
v6pwC1BmqX37uoNURqqS1CWg3iKiAfzqtTIwt9vBu8C1ev4ZnlKmAF4C1fTuH3Wo
X1lT+wpkycqWIUxoV7zoXYpxkleeNCw/GavDYmqhfU0qSjI4bdD/uy0s66dubtWB
rCZ3VRC7mjHhmEWj1Y9GYvvg6Fjt/BchVMNEhIBd873MdXDqIx0cV6SILiQgudtr
uvAUm5rT6KEYNSsHq9gQWN+LAgy8mDSOGLjYXdBtAOJMxS/w8XNA+bXWzvNYOl9q
QO8w7Py3U/8mnLkxgHaVGktWazwQ1QkwaLyQz7lbTBedXkxOzP3LvLAe+POd4Zre
wYcNUs/W51WfLup9o/IMEvDk/z0FCJ1fGFiHny3QFWrhJB3dAia1dwYtUpy42ZuY
w4UQEuZVr3BzDCXudx6638WOURpvaMe/Enfdr2bcqvCYvzbT06RPD/VTtuKtZ8O7
Q/hr0NvTAgMBAAGjgfMwgfAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwgdgGA1UdAQSB
0DCBzYAQFBF2JL0Y1AduVxGNb4H7DqGBpjCBozELMAkGA1UEBhMCQ1kxETAPBgNV
BAgTCExpbWFzc29sMREwDwYDVQQHEwhMaW1hc3NvbDEZMBcGA1UEChMQSURlbGl2
ZXJhYmxlIEx0ZDETMBEGA1UECxMKT3BlcmF0aW9uczEYMBYGA1UEAxMPSURlbGl2
ZXJhYmxlIENBMSQwIgYJKoZIhvcNAQkBFhVpbmZvQGlkZWxpdmVyYWJsZS5jb22C
EMgq1WuLQwSJTj+ogMza3/YwDQYJKoZIhvcNAQENBQADggIBAEU9gdrydWT3ZwtA
LP/HEct2DJRQdK9WuL02x2xbdmszyb8xoayTIcJdvs2WHPBqxM417XAhNTZuG3Aw
Yx6OPSzbfmS1X7aVctSeBwZCfzxOk2MhTsKoZ+wjmFn6LVYz3P6K2deJVz6t+HRc
mMwFrsctzgGZsxIvMXa0eqyDE6hhxj0XKYLFmYNGBdUd5sW68Ko26Njv1FPLkoqo
Me2y+Gi6SltgjD/bmza36IRvaQVQtOjOxq+TncOBqLJ2+ikQOr93pkCgx3nso3CM
YH1ryRpXbSAb5aA9sF0jb6LLLUgHv5q2ExpEFcoRja5gww5R2VKwEJ2PXjK+2O/A
DgHOLKuiODxBF61+Ou/d29XiSX2HxCoH+onppi2h6ceJPcFwPrgzKVszsGkavtKL
7myxufgdBUgTFxYMaTEtrU0yaRiJItxreH1wj/vl1zKyl25MXZLM1LyFvszAX49h
9hgWApwE9hL1i6ygIfrpq2B+djPS8ZwX5S/t/QO5SmBjNLmw1GD1gHN5xqY0vMzS
VxDXrH6Kllhwipu8GLeMWn/VmWWLy1vr//GoBjujhplIZHJPYBrYjqwfxH1ZLa4B
O+N7bHDp63M0UVX5FdX1sN0laL29L1jXX/oe7x8PHNt3W4aOwVaIilh+/adXNDxr
1yumH4G7QEeMQisiMhlPxnZJHajX";
var certBytes = Convert.FromBase64String(certBase64);
var cert = new X509Certificate2(certBytes);
return cert;
}
}
}

View File

@@ -1,9 +0,0 @@
namespace IDeliverable.Licensing.VerificationTokens
{
public interface ILicenseVerificationTokenStore
{
LicenseVerificationToken Load(string productId);
void Save(string productId, LicenseVerificationToken token);
void Clear(string productId);
}
}

View File

@@ -1,36 +0,0 @@
using System;
using Newtonsoft.Json;
namespace IDeliverable.Licensing.VerificationTokens
{
public class LicenseVerificationInfo
{
public LicenseVerificationInfo(string productId, string hostname, string licenseKey, long verifiedUtcTicks)
{
ProductId = productId;
Hostname = hostname;
LicenseKey = licenseKey;
VerifiedUtcTicks = verifiedUtcTicks;
}
public string ProductId { get; }
public string Hostname { get; }
public string LicenseKey { get; }
public long VerifiedUtcTicks { get; }
public DateTime VerifiedUtc => new DateTime(VerifiedUtcTicks, DateTimeKind.Utc);
public TimeSpan Age => DateTime.UtcNow - VerifiedUtc;
public override string ToString()
{
return JsonConvert.SerializeObject(
new
{
ProductId,
Hostname,
LicenseKey,
VerifiedUtcTicks
});
}
}
}

View File

@@ -1,72 +0,0 @@
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace IDeliverable.Licensing.VerificationTokens
{
public class LicenseVerificationToken
{
public static LicenseVerificationToken Create(LicenseVerificationInfo info, X509Certificate2 signingCert)
{
var infoString = info.ToString();
var infoBytes = Encoding.UTF8.GetBytes(infoString);
var privateKey = (RSACryptoServiceProvider)signingCert.PrivateKey;
var signatureBytes = privateKey.SignData(infoBytes, "md5");
var signature = Convert.ToBase64String(signatureBytes);
return new LicenseVerificationToken(info, signature);
}
public static LicenseVerificationToken FromBase64(string value)
{
var tokenBytes = Convert.FromBase64String(value);
var tokenJson = Encoding.UTF8.GetString(tokenBytes);
return Parse(tokenJson);
}
public static LicenseVerificationToken Parse(string value)
{
return JsonConvert.DeserializeObject<LicenseVerificationToken>(value, new StringEnumConverter());
}
public LicenseVerificationToken(LicenseVerificationInfo info, string signature)
{
if (info == null)
throw new ArgumentNullException(nameof(info), $"The parameter {nameof(info)} cannot be null.");
Info = info;
Signature = signature;
}
public LicenseVerificationInfo Info { get; }
public string Signature { get; }
public DateTime VerifiedUtc => Info.VerifiedUtc; // Delegated to Info because it needs to be included in signature.
public TimeSpan Age => Info.Age; // Delegated to Info because it needs to be included in signature.
public string ToBase64()
{
var tokenJson = ToString();
var tokenBytes = Encoding.UTF8.GetBytes(tokenJson);
return Convert.ToBase64String(tokenBytes);
}
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
public bool GetSignatureIsValid(X509Certificate2 signingCert)
{
var publicKey = (RSACryptoServiceProvider)signingCert.PublicKey.Key;
var infoBytes = Encoding.UTF8.GetBytes(Info.ToString());
var signatureBytes = Convert.FromBase64String(Signature);
var isValid = publicKey.VerifyData(infoBytes, "md5", signatureBytes);
return isValid;
}
}
}

View File

@@ -1,73 +0,0 @@
using System;
namespace IDeliverable.Licensing.VerificationTokens
{
public class LicenseVerificationTokenAccessor
{
private static readonly TimeSpan sTokenRenewalInterval = TimeSpan.FromHours(48);
public LicenseVerificationTokenAccessor(ILicenseVerificationTokenStore store)
{
mStore = store;
mLicensingServiceClient = new LicensingServiceClient();
}
private readonly ILicenseVerificationTokenStore mStore;
private readonly LicensingServiceClient mLicensingServiceClient;
public LicenseVerificationToken GetLicenseVerificationToken(string productId, string licenseKey, string hostname, bool forceRenew = false)
{
var token = mStore.Load(productId);
// Delete the existing verification token from store if:
// * It was issued for a different license key OR
// * We are instructed by caller to force renewal
if (token != null && (token.Info.LicenseKey != licenseKey || forceRenew))
{
mStore.Clear(productId);
token = null;
}
// Try to renew verification token from licensing service if:
// * We don't have a token in store OR
// * The one we have has passed the token renewal interval
if (token == null || token.Age > sTokenRenewalInterval)
{
try
{
token = mLicensingServiceClient.VerifyLicense(productId, licenseKey, hostname);
}
catch (Exception ex)
{
// If the license key is reported by licensing service to be either invalid or for
// a different hostname, we delete any existing token from store and throw unconditionally.
if (ex is LicenseVerificationTokenException)
{
var lvtex = (LicenseVerificationTokenException)ex;
if (lvtex.Error == LicenseVerificationTokenError.UnknownLicenseKey ||
lvtex.Error == LicenseVerificationTokenError.HostnameMismatch ||
lvtex.Error == LicenseVerificationTokenError.NoActiveSubscription ||
lvtex.Error == LicenseVerificationTokenError.LicenseRevoked)
{
mStore.Clear(productId);
throw;
}
}
// If we have an existing token from before, return it rather than throwing.
if (token != null)
return token;
if (ex is LicenseVerificationTokenException)
throw;
throw new LicenseVerificationTokenException(LicenseVerificationTokenError.UnexpectedError, ex);
}
mStore.Save(productId, token);
}
return token;
}
}
}

View File

@@ -1,13 +0,0 @@
namespace IDeliverable.Licensing.VerificationTokens
{
public enum LicenseVerificationTokenError
{
UnknownLicenseKey,
HostnameMismatch,
NoActiveSubscription,
LicenseRevoked,
LicenseServiceError,
LicenseServiceUnreachable,
UnexpectedError
}
}

View File

@@ -1,29 +0,0 @@
using System;
namespace IDeliverable.Licensing.VerificationTokens
{
public class LicenseVerificationTokenException : Exception
{
public LicenseVerificationTokenException(LicenseVerificationTokenError error)
:this("An error occurred while getting a license verification token.", error)
{
}
public LicenseVerificationTokenException(string message, LicenseVerificationTokenError error) : base(message)
{
Error = error;
}
public LicenseVerificationTokenException(LicenseVerificationTokenError error, Exception innerException)
: this("An error occurred while getting a license verification token.", error, innerException)
{
}
public LicenseVerificationTokenException(string message, LicenseVerificationTokenError error, Exception innerException) : base(message, innerException)
{
Error = error;
}
public LicenseVerificationTokenError Error { get; private set; }
}
}

View File

@@ -1,97 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using IDeliverable.Licensing.Exceptions;
namespace IDeliverable.Licensing.VerificationTokens
{
public class LicensingServiceClient
{
// These are consciously hard coded (need to be obfuscated).
private static readonly string sLicensingServiceUrl = "https://licensing.ideliverable.com/api/v1/";
private static readonly string sLicensingServiceApiKey = "MJb17j7YAzSjyEYkhsoI";
private static readonly string sExpectedServerCertificateThumbprint = "fa4746a778716109e7e80e1b8dc2ed2a2ba3b852";
public LicenseVerificationToken VerifyLicense(string productId, string licenseKey, string hostname)
{
RemoteCertificateValidationCallback certValidationHandler = (sender, certificate, chain, errors) =>
{
// Accept the server certificate as long as it matches the expected thumbprint. This makes sure
// that the API call works even if the client host doesn't trust IDeliverable CA certificate, but
// fails if somebody is trying to spoof the service.
var serverCertThumbprint = ((X509Certificate2)certificate).Thumbprint;
return String.Equals(serverCertThumbprint, sExpectedServerCertificateThumbprint, StringComparison.OrdinalIgnoreCase);
};
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(sLicensingServiceUrl);
client.DefaultRequestHeaders.Add("ApiKey", sLicensingServiceApiKey);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
ServicePointManager.ServerCertificateValidationCallback += certValidationHandler;
try
{
HttpResponseMessage response;
try
{
response = client.GetAsync($"license/{licenseKey}/verify?productId={productId}&hostname={hostname}").Result;
}
catch (Exception ex)
{
throw new LicenseVerificationTokenException("An error occurred while calling the licensing service.", LicenseVerificationTokenError.LicenseServiceUnreachable, ex);
}
if (!response.IsSuccessStatusCode)
{
var licenseVerificationError = ReadLicenseVerificationError(response);
switch (licenseVerificationError)
{
case LicenseVerificationError.UnknownLicenseKey:
throw new LicenseVerificationTokenException(response.ReasonPhrase, LicenseVerificationTokenError.UnknownLicenseKey);
case LicenseVerificationError.HostnameMismatch:
throw new LicenseVerificationTokenException(response.ReasonPhrase, LicenseVerificationTokenError.HostnameMismatch);
case LicenseVerificationError.NoActiveSubscription:
throw new LicenseVerificationTokenException(response.ReasonPhrase, LicenseVerificationTokenError.NoActiveSubscription);
case LicenseVerificationError.LicenseRevoked:
throw new LicenseVerificationTokenException(response.ReasonPhrase, LicenseVerificationTokenError.LicenseRevoked);
default:
throw new LicenseVerificationTokenException(response.ReasonPhrase, LicenseVerificationTokenError.LicenseServiceError);
}
}
var responseText = response.Content.ReadAsStringAsync().Result;
var token = LicenseVerificationToken.Parse(responseText);
return token;
}
finally
{
ServicePointManager.ServerCertificateValidationCallback -= certValidationHandler;
}
}
}
private static LicenseVerificationError? ReadLicenseVerificationError(HttpResponseMessage response)
{
IEnumerable<string> values;
if (!response.Headers.TryGetValues("LicensingErrorCode", out values))
return null;
var value = values.First();
return (LicenseVerificationError)Enum.Parse(typeof(LicenseVerificationError), value);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +0,0 @@
<?xml version="1.0"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Practices.ServiceLocation" publicKeyToken="31BF3856AD364E35"
culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.2.0.0" newVersion="1.2.0.0" />
</dependentAssembly>
</assemblyBinding>
<loadFromRemoteSources enabled="true" />
</runtime>
</configuration>

View File

@@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.9.0")]
[assembly: AssemblyFileVersion("1.9.0")]
[assembly: AssemblyVersion("1.9.1")]
[assembly: AssemblyFileVersion("1.9.1")]

View File

@@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.9.0")]
[assembly: AssemblyFileVersion("1.9.0")]
[assembly: AssemblyVersion("1.9.1")]
[assembly: AssemblyFileVersion("1.9.1")]

View File

@@ -7,7 +7,7 @@
<system.web>
<compilation targetFramework="4.5">
<assemblies>
<add assembly="System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
<add assembly="System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
</assemblies>
</compilation>
<pages>

View File

@@ -10,11 +10,11 @@
-->
<pages
validateRequest="false"
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"
pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"
userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"
pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"
userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<controls>
<add assembly="System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" namespace="System.Web.Mvc" tagPrefix="mvc" />
<add assembly="System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" namespace="System.Web.Mvc" tagPrefix="mvc" />
</controls>
</pages>
</system.web>

View File

@@ -21,13 +21,13 @@
<appSettings>
<add key="webpages:Enabled" value="false" />
<add key="webpages:Version" value="3.0.0.0"/>
<add key="webpages:Version" value="3.0.0"/>
<add key="log4net.Config" value="Config\log4net.config" />
<add key="owin:AutomaticAppStartup" value="false" />
</appSettings>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<pages pageBaseType="Orchard.Mvc.ViewEngines.Razor.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
@@ -62,7 +62,7 @@
<add extension=".csproj" type="Orchard.Environment.Extensions.Compilers.CSharpExtensionBuildProviderShim"/>
</buildProviders>
<assemblies>
<add assembly="System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
<add assembly="System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
@@ -150,63 +150,74 @@
<httpErrors existingResponse="PassThrough" />
</system.webServer>
<runtime>
<gcServer enabled="true"/>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="App_Data/Dependencies"/>
<dependentAssembly>
<assemblyIdentity name="Iesi.Collections" publicKeyToken="AA95F207798DFDB4" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.0.0" newVersion="5.2.0.0"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Razor" publicKeyToken="31bf3856ad364e35" />
<assemblyIdentity name="System.Web.Razor" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages.Deployment" publicKeyToken="31bf3856ad364e35" />
<assemblyIdentity name="System.Web.WebPages.Deployment" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages.Razor" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" />
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" />
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.0.4000" newVersion="4.0.0.4000"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da"/>
<bindingRedirect oldVersion="0.0.0.0-3.5.0.0" newVersion="3.5.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed"/>
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.WindowsAzure.Storage" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.3.0.0" newVersion="4.3.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31BF3856AD364E35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-5.6.3.0" newVersion="5.6.3.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31BF3856AD364E35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-5.6.3.0" newVersion="5.6.3.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31BF3856AD364E35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-5.6.3.0" newVersion="5.6.3.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -51,7 +51,7 @@
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
<add assembly="System.Web.Abstractions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
<add assembly="System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
<add assembly="System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
<add assembly="System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Data.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
@@ -140,48 +140,81 @@
<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode"
type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
<add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<add name="MvcHttpHandler" preCondition="integratedMode" verb="*" path="*.mvc" type="System.Web.Mvc.MvcHttpHandler, System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
<add name="MvcHttpHandler" preCondition="integratedMode" verb="*" path="*.mvc" type="System.Web.Mvc.MvcHttpHandler, System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
<add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</handlers>
</system.webServer>
<runtime>
<gcServer enabled="true"/>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="App_Data/Dependencies"/>
<dependentAssembly>
<assemblyIdentity name="Iesi.Collections" publicKeyToken="AA95F207798DFDB4" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.0.0" newVersion="5.2.0.0"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Razor" publicKeyToken="31bf3856ad364e35" />
<assemblyIdentity name="System.Web.Razor" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages.Deployment" publicKeyToken="31bf3856ad364e35" />
<assemblyIdentity name="System.Web.WebPages.Deployment" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages.Razor" publicKeyToken="31bf3856ad364e35" />
<assemblyIdentity name="System.Web.WebPages.Razor" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" culture="neutral" />
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.0.4000" newVersion="4.0.0.4000"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da"/>
<bindingRedirect oldVersion="0.0.0.0-3.5.0.0" newVersion="3.5.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed"/>
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.WindowsAzure.Storage" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.3.0.0" newVersion="4.3.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31BF3856AD364E35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-5.6.3.0" newVersion="5.6.3.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31BF3856AD364E35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-5.6.3.0" newVersion="5.6.3.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31BF3856AD364E35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-5.6.3.0" newVersion="5.6.3.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.9.0")]
[assembly: AssemblyFileVersion("1.9.0")]
[assembly: AssemblyVersion("1.9.1")]
[assembly: AssemblyFileVersion("1.9.1")]

View File

@@ -16,7 +16,7 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.0.0" newVersion="5.2.0.0"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" culture="neutral"/>

View File

@@ -50,7 +50,7 @@
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.Mvc, Version=5.2.3, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\lib\aspnetmvc\System.Web.Mvc.dll</HintPath>
</Reference>

View File

@@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.9.0")]
[assembly: AssemblyFileVersion("1.9.0")]
[assembly: AssemblyVersion("1.9.1")]
[assembly: AssemblyFileVersion("1.9.1")]

View File

@@ -29,6 +29,7 @@ using Orchard.Tests.Environment.Extensions;
using Orchard.Tests.Environment.Features;
using Orchard.Tests.Stubs;
using IPackageManager = Orchard.Packaging.Services.IPackageManager;
using Orchard.Tests.Modules.Recipes.Services;
namespace Orchard.Tests.Modules.Recipes.RecipeHandlers {
[TestFixture]
@@ -66,6 +67,7 @@ namespace Orchard.Tests.Modules.Recipes.RecipeHandlers {
builder.RegisterType<ShellStateManager>().As<IShellStateManager>().SingleInstance();
builder.RegisterType<StubEventBus>().As<IEventBus>().SingleInstance();
builder.RegisterType<ModuleRecipeHandler>();
builder.RegisterType<StubRecipeJournal>().As<IRecipeJournal>();
builder.RegisterSource(new EventsRegistrationSource());
}

View File

@@ -16,7 +16,7 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.0.0" newVersion="5.2.0.0"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" culture="neutral"/>

View File

@@ -0,0 +1,46 @@
using Autofac;
using Moq;
using NUnit.Framework;
using Orchard.Localization;
using Orchard.Localization.Services;
using Orchard.Mvc;
using Orchard.Tests.Stubs;
using System.Web;
namespace Orchard.Tests.Localization {
[TestFixture]
public class TextTests {
private IContainer _container;
private IText _text;
[SetUp]
public void Init() {
var mockLocalizedManager = new Mock<ILocalizedStringManager>();
mockLocalizedManager
.Setup(x => x.GetLocalizedString(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
.Returns("foo {0}");
var builder = new ContainerBuilder();
builder.RegisterInstance(new StubCultureSelector("fr-CA")).As<ICultureSelector>();
builder.RegisterInstance(new StubWorkContext()).As<WorkContext>();
builder.RegisterType<StubWorkContextAccessor>().As<IWorkContextAccessor>();
builder.RegisterInstance(mockLocalizedManager.Object);
builder.RegisterType<Orchard.Localization.Text>().As<IText>().WithParameter(new NamedParameter("scope", "scope"));
_container = builder.Build();
_text = _container.Resolve<IText>();
}
[Test]
public void TextHtmlEncodeAllArguments() {
Assert.That(_text.Get("foo {0}", "bar").Text, Is.EqualTo("foo bar"));
Assert.That(_text.Get("foo {0}", "<bar>").Text, Is.EqualTo("foo &lt;bar&gt;"));
}
[Test]
public void TextDoesEncodeHtmlEncodedArguments()
{
Assert.That(_text.Get("foo {0}", new HtmlString("bar")).Text, Is.EqualTo("foo bar"));
Assert.That(_text.Get("foo {0}", new HtmlString("<bar>")).Text, Is.EqualTo("foo <bar>"));
}
}
}

View File

@@ -259,6 +259,7 @@
<Compile Include="FileSystems\Dependencies\AssemblyProbingFolderTests.cs" />
<Compile Include="FileSystems\Dependencies\DependenciesFolderTests.cs" />
<Compile Include="FileSystems\VirtualPath\DefaultVirtualPathProviderTests.cs" />
<Compile Include="Localization\TextTests.cs" />
<Compile Include="Localization\CurrentCultureWorkContextTests.cs" />
<Compile Include="Localization\CultureManagerTests.cs" />
<Compile Include="Localization\DateTimePartsTests.cs" />

View File

@@ -33,5 +33,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.9.0")]
[assembly: AssemblyFileVersion("1.9.0")]
[assembly: AssemblyVersion("1.9.1")]
[assembly: AssemblyFileVersion("1.9.1")]

View File

@@ -282,5 +282,21 @@ namespace Orchard.Tests.Utility.Extensions {
Assert.That("abc".Translate("d".ToCharArray(), "d".ToCharArray()), Is.StringMatching("abc"));
Assert.That("abc".Translate("abc".ToCharArray(), "def".ToCharArray()), Is.StringMatching("def"));
}
[Test]
public void ShouldEncodeToBase64() {
Assert.That("abc".ToBase64(), Is.EqualTo("YWJj"));
}
[Test]
public void ShouldDecodeFromBase64() {
Assert.That("YWJj".FromBase64(), Is.EqualTo("abc"));
}
[Test]
public void ShouldRoundtripBase64() {
Assert.That("abc".ToBase64().FromBase64(), Is.EqualTo("abc"));
Assert.That("YWJj".FromBase64().ToBase64(), Is.EqualTo("YWJj"));
}
}
}

View File

@@ -24,6 +24,7 @@
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<UseVSHostingProcess>false</UseVSHostingProcess>
<CodeAnalysisRuleSet>..\OrchardBasicCorrectness.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>

View File

@@ -32,8 +32,8 @@ using System.Security;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.9.0")]
[assembly: AssemblyFileVersion("1.9.0")]
[assembly: AssemblyVersion("1.9.1")]
[assembly: AssemblyFileVersion("1.9.1")]
// Enable web application to call this assembly in Full Trust
[assembly: AllowPartiallyTrustedCallers]

View File

@@ -33,5 +33,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.9.0")]
[assembly: AssemblyFileVersion("1.9.0")]
[assembly: AssemblyVersion("1.9.1")]
[assembly: AssemblyFileVersion("1.9.1")]

View File

@@ -33,16 +33,16 @@
<Component Type="Orchard.Environment.Extensions.Compilers.DefaultProjectFileParser">
<Properties>
<!-- Set Value="true" to disable project files monitoring (/Modules/**/*.csproj) -->
<Property Name="DisableMonitoring" Value="true"/>
<Property Name="DisableMonitoring" Value="false"/>
</Properties>
</Component>
<Component Type="Orchard.Environment.Extensions.Loaders.DynamicExtensionLoader">
<Properties>
<!-- Set Value="true" to disable source files monitoring -->
<Property Name="DisableMonitoring" Value="true"/>
<Property Name="DisableMonitoring" Value="false"/>
<!-- Set Value="true" to completely disable the Dynamic Extension Loader -->
<Property Name="Disabled" Value="true"/>
<Property Name="Disabled" Value="false"/>
</Properties>
</Component>

View File

@@ -2,7 +2,7 @@
AntiForgery: enabled
Author: The Orchard Team
Website: http://orchardproject.net
Version: 1.9.0
Version: 1.9.1
OrchardVersion: 1.9
Description: The common module introduces content parts that are going to be used by most content types (common, body, identity).
FeatureDescription: Core content parts.

View File

@@ -2,7 +2,7 @@
AntiForgery: enabled
Author: The Orchard Team
Website: http://orchardproject.net
Version: 1.9.0
Version: 1.9.1
OrchardVersion: 1.9
Description: The containers module introduces container and containable behaviors for content items.
FeatureDescription: Container and containable parts to enable parent-child relationships between content items.

View File

@@ -2,7 +2,7 @@
AntiForgery: enabled
Author: The Orchard Team
Website: http://orchardproject.net
Version: 1.9.0
Version: 1.9.1
OrchardVersion: 1.9
Description: The contents module enables the creation of custom content types.
Features:

View File

@@ -2,7 +2,7 @@
AntiForgery: enabled
Author: The Orchard Team
Website: http://orchardproject.net
Version: 1.9.0
Version: 1.9.1
OrchardVersion: 1.9
Description: The dashboard module is providing the dashboard screen of the admininstration UI of the application.
FeatureDescription: Standard admin dashboard.

Some files were not shown because too many files have changed in this diff Show More