Add Redis IXmlRepository implementation (#173)
This commit is contained in:
parent
e94106e28c
commit
b340b0f0f7
|
|
@ -1,7 +1,6 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 14
|
# Visual Studio 14
|
||||||
VisualStudioVersion = 14.0.22710.0
|
VisualStudioVersion = 14.0.25420.1
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5FCB2DA3-5395-47F5-BCEE-E0EA319448EA}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5FCB2DA3-5395-47F5-BCEE-E0EA319448EA}"
|
||||||
EndProject
|
EndProject
|
||||||
|
|
@ -33,6 +32,14 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.DataPr
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.DataProtection.Extensions", "src\Microsoft.AspNetCore.DataProtection.Extensions\Microsoft.AspNetCore.DataProtection.Extensions.xproj", "{BF8681DB-C28B-441F-BD92-0DCFE9537A9F}"
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.DataProtection.Extensions", "src\Microsoft.AspNetCore.DataProtection.Extensions\Microsoft.AspNetCore.DataProtection.Extensions.xproj", "{BF8681DB-C28B-441F-BD92-0DCFE9537A9F}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.DataProtection.Redis", "src\Microsoft.AspNetCore.DataProtection.Redis\Microsoft.AspNetCore.DataProtection.Redis.xproj", "{0508ADB0-9D2E-4506-9AA3-C15D7BEAE7C9}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Redis", "samples\Redis\Redis.xproj", "{24AAEC96-DF46-4F61-B2FF-3D5E056685D9}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sample", "sample", "{3A6C77DB-FD3D-4B20-A52B-34F7A7E1AED2}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.DataProtection.Redis.Test", "test\Microsoft.AspNetCore.DataProtection.Redis.Test\Microsoft.AspNetCore.DataProtection.Redis.Test.xproj", "{ABCF00E5-5B2F-469C-90DC-908C5A04C08D}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
|
@ -141,6 +148,30 @@ Global
|
||||||
{BF8681DB-C28B-441F-BD92-0DCFE9537A9F}.Release|Any CPU.Build.0 = Release|Any CPU
|
{BF8681DB-C28B-441F-BD92-0DCFE9537A9F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{BF8681DB-C28B-441F-BD92-0DCFE9537A9F}.Release|x86.ActiveCfg = Release|Any CPU
|
{BF8681DB-C28B-441F-BD92-0DCFE9537A9F}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{BF8681DB-C28B-441F-BD92-0DCFE9537A9F}.Release|x86.Build.0 = Release|Any CPU
|
{BF8681DB-C28B-441F-BD92-0DCFE9537A9F}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{0508ADB0-9D2E-4506-9AA3-C15D7BEAE7C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{0508ADB0-9D2E-4506-9AA3-C15D7BEAE7C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{0508ADB0-9D2E-4506-9AA3-C15D7BEAE7C9}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{0508ADB0-9D2E-4506-9AA3-C15D7BEAE7C9}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{0508ADB0-9D2E-4506-9AA3-C15D7BEAE7C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{0508ADB0-9D2E-4506-9AA3-C15D7BEAE7C9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{0508ADB0-9D2E-4506-9AA3-C15D7BEAE7C9}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{0508ADB0-9D2E-4506-9AA3-C15D7BEAE7C9}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{24AAEC96-DF46-4F61-B2FF-3D5E056685D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{24AAEC96-DF46-4F61-B2FF-3D5E056685D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{24AAEC96-DF46-4F61-B2FF-3D5E056685D9}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{24AAEC96-DF46-4F61-B2FF-3D5E056685D9}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{24AAEC96-DF46-4F61-B2FF-3D5E056685D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{24AAEC96-DF46-4F61-B2FF-3D5E056685D9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{24AAEC96-DF46-4F61-B2FF-3D5E056685D9}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{24AAEC96-DF46-4F61-B2FF-3D5E056685D9}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{ABCF00E5-5B2F-469C-90DC-908C5A04C08D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{ABCF00E5-5B2F-469C-90DC-908C5A04C08D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{ABCF00E5-5B2F-469C-90DC-908C5A04C08D}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{ABCF00E5-5B2F-469C-90DC-908C5A04C08D}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{ABCF00E5-5B2F-469C-90DC-908C5A04C08D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{ABCF00E5-5B2F-469C-90DC-908C5A04C08D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{ABCF00E5-5B2F-469C-90DC-908C5A04C08D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{ABCF00E5-5B2F-469C-90DC-908C5A04C08D}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
@ -159,5 +190,8 @@ Global
|
||||||
{E3552DEB-4173-43AE-BF69-3C10DFF3BAB6} = {5FCB2DA3-5395-47F5-BCEE-E0EA319448EA}
|
{E3552DEB-4173-43AE-BF69-3C10DFF3BAB6} = {5FCB2DA3-5395-47F5-BCEE-E0EA319448EA}
|
||||||
{04AA8E60-A053-4D50-89FE-E76C3DF45200} = {60336AB3-948D-4D15-A5FB-F32A2B91E814}
|
{04AA8E60-A053-4D50-89FE-E76C3DF45200} = {60336AB3-948D-4D15-A5FB-F32A2B91E814}
|
||||||
{BF8681DB-C28B-441F-BD92-0DCFE9537A9F} = {5FCB2DA3-5395-47F5-BCEE-E0EA319448EA}
|
{BF8681DB-C28B-441F-BD92-0DCFE9537A9F} = {5FCB2DA3-5395-47F5-BCEE-E0EA319448EA}
|
||||||
|
{0508ADB0-9D2E-4506-9AA3-C15D7BEAE7C9} = {5FCB2DA3-5395-47F5-BCEE-E0EA319448EA}
|
||||||
|
{24AAEC96-DF46-4F61-B2FF-3D5E056685D9} = {3A6C77DB-FD3D-4B20-A52B-34F7A7E1AED2}
|
||||||
|
{ABCF00E5-5B2F-469C-90DC-908C5A04C08D} = {60336AB3-948D-4D15-A5FB-F32A2B91E814}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
"Microsoft.AspNetCore.DataProtection": { },
|
"Microsoft.AspNetCore.DataProtection": { },
|
||||||
"Microsoft.AspNetCore.DataProtection.Abstractions": { },
|
"Microsoft.AspNetCore.DataProtection.Abstractions": { },
|
||||||
"Microsoft.AspNetCore.DataProtection.Extensions": { },
|
"Microsoft.AspNetCore.DataProtection.Extensions": { },
|
||||||
|
"Microsoft.AspNetCore.DataProtection.Redis": { },
|
||||||
"Microsoft.AspNetCore.DataProtection.SystemWeb": { }
|
"Microsoft.AspNetCore.DataProtection.SystemWeb": { }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
using System;
|
||||||
|
using Microsoft.AspNetCore.DataProtection;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.AspNetCore.DataProtection.Redis;
|
||||||
|
using StackExchange.Redis;
|
||||||
|
|
||||||
|
namespace Redis
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
// Connect
|
||||||
|
var redis = ConnectionMultiplexer.Connect("localhost:6379");
|
||||||
|
|
||||||
|
// Configure
|
||||||
|
var serviceCollection = new ServiceCollection();
|
||||||
|
serviceCollection.AddLogging();
|
||||||
|
serviceCollection.AddDataProtection()
|
||||||
|
.PersistKeysToRedis(redis, "DataProtection-Keys");
|
||||||
|
|
||||||
|
var services = serviceCollection.BuildServiceProvider();
|
||||||
|
var loggerFactory = services.GetService<ILoggerFactory>();
|
||||||
|
loggerFactory.AddConsole(LogLevel.Trace);
|
||||||
|
|
||||||
|
// Run a sample payload
|
||||||
|
var protector = services.GetDataProtector("sample-purpose");
|
||||||
|
var protectedData = protector.Protect("Hello world!");
|
||||||
|
Console.WriteLine(protectedData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0.25420" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25420</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>24aaec96-df46-4f61-b2ff-3d5e056685d9</ProjectGuid>
|
||||||
|
<RootNamespace>Redis</RootNamespace>
|
||||||
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
|
||||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"version": "1.0.0-*",
|
||||||
|
"buildOptions": {
|
||||||
|
"debugType": "portable",
|
||||||
|
"emitEntryPoint": true
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.AspNetCore.DataProtection.Redis": "1.1.0-*",
|
||||||
|
"Microsoft.Extensions.DependencyInjection": "1.1.0-*",
|
||||||
|
"Microsoft.Extensions.Logging": "1.1.0-*",
|
||||||
|
"Microsoft.Extensions.Logging.Console": "1.1.0-*"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net451": { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0.25420" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25420</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>0508adb0-9d2e-4506-9aa3-c15d7beae7c9</ProjectGuid>
|
||||||
|
<RootNamespace>Microsoft.AspNetCore.DataProtection.Redis</RootNamespace>
|
||||||
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
|
||||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using StackExchange.Redis;
|
||||||
|
using Microsoft.AspNetCore.DataProtection.Repositories;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.DataProtection
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Contains Redis-specific extension methods for modifying a <see cref="IDataProtectionBuilder"/>.
|
||||||
|
/// </summary>
|
||||||
|
public static class RedisDataProtectionBuilderExtensions
|
||||||
|
{
|
||||||
|
private const string DataProtectionKeysName = "DataProtection-Keys";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Configures the data protection system to persist keys to specified key in Redis database
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">The builder instance to modify.</param>
|
||||||
|
/// <param name="databaseFactory">The delegate used to create <see cref="IDatabase"/> instances.</param>
|
||||||
|
/// <param name="key">The <see cref="RedisKey"/> used to store key list.</param>
|
||||||
|
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
|
||||||
|
public static IDataProtectionBuilder PersistKeysToRedis(this IDataProtectionBuilder builder, Func<IDatabase> databaseFactory, RedisKey key)
|
||||||
|
{
|
||||||
|
if (builder == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(builder));
|
||||||
|
}
|
||||||
|
if (databaseFactory == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(databaseFactory));
|
||||||
|
}
|
||||||
|
return PersistKeysToRedisInternal(builder, databaseFactory, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Configures the data protection system to persist keys to the default key ('DataProtection-Keys') in Redis database
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">The builder instance to modify.</param>
|
||||||
|
/// <param name="connectionMultiplexer">The <see cref="IConnectionMultiplexer"/> for database access.</param>
|
||||||
|
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
|
||||||
|
public static IDataProtectionBuilder PersistKeysToRedis(this IDataProtectionBuilder builder, IConnectionMultiplexer connectionMultiplexer)
|
||||||
|
{
|
||||||
|
return PersistKeysToRedis(builder, connectionMultiplexer, DataProtectionKeysName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Configures the data protection system to persist keys to the specified key in Redis database
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">The builder instance to modify.</param>
|
||||||
|
/// <param name="connectionMultiplexer">The <see cref="IConnectionMultiplexer"/> for database access.</param>
|
||||||
|
/// <param name="key">The <see cref="RedisKey"/> used to store key list.</param>
|
||||||
|
/// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns>
|
||||||
|
public static IDataProtectionBuilder PersistKeysToRedis(this IDataProtectionBuilder builder, IConnectionMultiplexer connectionMultiplexer, RedisKey key)
|
||||||
|
{
|
||||||
|
if (builder == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(builder));
|
||||||
|
}
|
||||||
|
if (connectionMultiplexer == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(connectionMultiplexer));
|
||||||
|
}
|
||||||
|
return PersistKeysToRedisInternal(builder, () => connectionMultiplexer.GetDatabase(), key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IDataProtectionBuilder PersistKeysToRedisInternal(IDataProtectionBuilder config, Func<IDatabase> databaseFactory, RedisKey key)
|
||||||
|
{
|
||||||
|
config.Services.TryAddSingleton<IXmlRepository>(services => new RedisXmlRepository(databaseFactory, key));
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using StackExchange.Redis;
|
||||||
|
using Microsoft.AspNetCore.DataProtection.Repositories;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.DataProtection
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An XML repository backed by a Redis list entry.
|
||||||
|
/// </summary>
|
||||||
|
public class RedisXmlRepository: IXmlRepository
|
||||||
|
{
|
||||||
|
private readonly Func<IDatabase> _databaseFactory;
|
||||||
|
private readonly RedisKey _key;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a <see cref="RedisXmlRepository"/> with keys stored at the given directory.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="databaseFactory">The delegate used to create <see cref="IDatabase"/> instances.</param>
|
||||||
|
/// <param name="key">The <see cref="RedisKey"/> used to store key list.</param>
|
||||||
|
public RedisXmlRepository(Func<IDatabase> databaseFactory, RedisKey key)
|
||||||
|
{
|
||||||
|
_databaseFactory = databaseFactory;
|
||||||
|
_key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IReadOnlyCollection<XElement> GetAllElements()
|
||||||
|
{
|
||||||
|
return GetAllElementsCore().ToList().AsReadOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<XElement> GetAllElementsCore()
|
||||||
|
{
|
||||||
|
// Note: Inability to read any value is considered a fatal error (since the file may contain
|
||||||
|
// revocation information), and we'll fail the entire operation rather than return a partial
|
||||||
|
// set of elements. If a value contains well-formed XML but its contents are meaningless, we
|
||||||
|
// won't fail that operation here. The caller is responsible for failing as appropriate given
|
||||||
|
// that scenario.
|
||||||
|
var database = _databaseFactory();
|
||||||
|
foreach (var value in database.ListRange(_key))
|
||||||
|
{
|
||||||
|
yield return XElement.Parse(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void StoreElement(XElement element, string friendlyName)
|
||||||
|
{
|
||||||
|
var database = _databaseFactory();
|
||||||
|
database.ListRightPush(_key, element.ToString(SaveOptions.DisableFormatting));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"version": "0.1.0-*",
|
||||||
|
"description": "Redis storrage support as key store.",
|
||||||
|
"packOptions": {
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git://github.com/aspnet/dataprotection"
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
"aspnetcore",
|
||||||
|
"dataprotection",
|
||||||
|
"redis"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.AspNetCore.DataProtection": "1.1.0-*",
|
||||||
|
"StackExchange.Redis.StrongName": "1.1.603"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net451": {}
|
||||||
|
},
|
||||||
|
"buildOptions": {
|
||||||
|
"allowUnsafe": true,
|
||||||
|
"warningsAsErrors": true,
|
||||||
|
"keyFile": "../../tools/Key.snk",
|
||||||
|
"nowarn": [
|
||||||
|
"CS1591"
|
||||||
|
],
|
||||||
|
"xmlDoc": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using Moq;
|
||||||
|
using StackExchange.Redis;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.DataProtection
|
||||||
|
{
|
||||||
|
public class DataProtectionRedisTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void GetAllElements_ReturnsAllXmlValuesForGivenKey()
|
||||||
|
{
|
||||||
|
var database = new Mock<IDatabase>();
|
||||||
|
database.Setup(d => d.ListRange("Key", 0, -1, CommandFlags.None)).Returns(new RedisValue[]
|
||||||
|
{
|
||||||
|
"<Element1/>",
|
||||||
|
"<Element2/>",
|
||||||
|
}).Verifiable();
|
||||||
|
var repo = new RedisXmlRepository(() => database.Object, "Key");
|
||||||
|
|
||||||
|
var elements = repo.GetAllElements().ToArray();
|
||||||
|
|
||||||
|
database.Verify();
|
||||||
|
Assert.Equal(new XElement("Element1").ToString(), elements[0].ToString());
|
||||||
|
Assert.Equal(new XElement("Element2").ToString(), elements[1].ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetAllElements_ThrowsParsingException()
|
||||||
|
{
|
||||||
|
var database = new Mock<IDatabase>();
|
||||||
|
database.Setup(d => d.ListRange("Key", 0, -1, CommandFlags.None)).Returns(new RedisValue[]
|
||||||
|
{
|
||||||
|
"<Element1/>",
|
||||||
|
"<Element2",
|
||||||
|
}).Verifiable();
|
||||||
|
var repo = new RedisXmlRepository(() => database.Object, "Key");
|
||||||
|
|
||||||
|
Assert.Throws<XmlException>(() => repo.GetAllElements());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void StoreElement_PushesValueToList()
|
||||||
|
{
|
||||||
|
var database = new Mock<IDatabase>();
|
||||||
|
database.Setup(d => d.ListRightPush("Key", "<Element2 />", When.Always, CommandFlags.None)).Verifiable();
|
||||||
|
var repo = new RedisXmlRepository(() => database.Object, "Key");
|
||||||
|
|
||||||
|
repo.StoreElement(new XElement("Element2"), null);
|
||||||
|
|
||||||
|
database.Verify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0.25420" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25420</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>abcf00e5-5b2f-469c-90dc-908c5a04c08d</ProjectGuid>
|
||||||
|
<RootNamespace>Microsoft.AspNetCore.DataProtection.Redis.Test</RootNamespace>
|
||||||
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
|
||||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"dotnet-test-xunit": "2.2.0-*",
|
||||||
|
"Microsoft.AspNetCore.DataProtection.Abstractions": "1.1.0-*",
|
||||||
|
"Microsoft.AspNetCore.DataProtection.Redis": "1.1.0-*",
|
||||||
|
"Microsoft.AspNetCore.Testing": "1.1.0-*",
|
||||||
|
"Moq": "4.6.36-*",
|
||||||
|
"xunit": "2.2.0-*"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net451": {}
|
||||||
|
},
|
||||||
|
"testRunner": "xunit",
|
||||||
|
"buildOptions": {
|
||||||
|
"warningsAsErrors": true,
|
||||||
|
"keyFile": "../../tools/Key.snk",
|
||||||
|
"compile": {
|
||||||
|
"include": "../common/**/*.cs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue