Moving Usersecrets feature to its own repo
This change introduced a circular dependency. Configuration -> Logging -> DI -> Configuration To break this moving the user secrets feature into its own repo.
This commit is contained in:
Родитель
7a4af7df7c
Коммит
19351c773b
|
@ -27,12 +27,6 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Framework.Configu
|
|||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Framework.ConfigurationModel.Test.Common", "test\Microsoft.Framework.ConfigurationModel.Test.Common\Microsoft.Framework.ConfigurationModel.Test.Common.xproj", "{29C120E5-F682-4BFB-826B-040A594802CA}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Framework.ConfigurationModel.UserSecrets", "src\Microsoft.Framework.ConfigurationModel.UserSecrets\Microsoft.Framework.ConfigurationModel.UserSecrets.xproj", "{58B6443B-1278-4DF9-B7BB-DDF3BFFCF868}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SecretManager", "src\SecretManager\SecretManager.xproj", "{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SecretManager.Tests", "test\SecretManager.Tests\SecretManager.Tests.xproj", "{113EBBD2-E857-4CAF-9B53-7A8742CBCD4A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -147,42 +141,6 @@ Global
|
|||
{29C120E5-F682-4BFB-826B-040A594802CA}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{29C120E5-F682-4BFB-826B-040A594802CA}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{29C120E5-F682-4BFB-826B-040A594802CA}.Release|x86.Build.0 = Release|Any CPU
|
||||
{58B6443B-1278-4DF9-B7BB-DDF3BFFCF868}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{58B6443B-1278-4DF9-B7BB-DDF3BFFCF868}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{58B6443B-1278-4DF9-B7BB-DDF3BFFCF868}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{58B6443B-1278-4DF9-B7BB-DDF3BFFCF868}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{58B6443B-1278-4DF9-B7BB-DDF3BFFCF868}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{58B6443B-1278-4DF9-B7BB-DDF3BFFCF868}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{58B6443B-1278-4DF9-B7BB-DDF3BFFCF868}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{58B6443B-1278-4DF9-B7BB-DDF3BFFCF868}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{58B6443B-1278-4DF9-B7BB-DDF3BFFCF868}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{58B6443B-1278-4DF9-B7BB-DDF3BFFCF868}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{58B6443B-1278-4DF9-B7BB-DDF3BFFCF868}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{58B6443B-1278-4DF9-B7BB-DDF3BFFCF868}.Release|x86.Build.0 = Release|Any CPU
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.Release|x86.Build.0 = Release|Any CPU
|
||||
{113EBBD2-E857-4CAF-9B53-7A8742CBCD4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{113EBBD2-E857-4CAF-9B53-7A8742CBCD4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{113EBBD2-E857-4CAF-9B53-7A8742CBCD4A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{113EBBD2-E857-4CAF-9B53-7A8742CBCD4A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{113EBBD2-E857-4CAF-9B53-7A8742CBCD4A}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{113EBBD2-E857-4CAF-9B53-7A8742CBCD4A}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{113EBBD2-E857-4CAF-9B53-7A8742CBCD4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{113EBBD2-E857-4CAF-9B53-7A8742CBCD4A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{113EBBD2-E857-4CAF-9B53-7A8742CBCD4A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{113EBBD2-E857-4CAF-9B53-7A8742CBCD4A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{113EBBD2-E857-4CAF-9B53-7A8742CBCD4A}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{113EBBD2-E857-4CAF-9B53-7A8742CBCD4A}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -198,8 +156,5 @@ Global
|
|||
{8967162D-4966-40A7-9970-395A206732AC} = {F141E2D0-F9B8-4ADB-A19A-7B6FF4CA19A1}
|
||||
{3F1CB08E-9FBD-4CAE-A78A-4AC43F24FC49} = {F141E2D0-F9B8-4ADB-A19A-7B6FF4CA19A1}
|
||||
{29C120E5-F682-4BFB-826B-040A594802CA} = {B54371FF-B920-46C8-8D55-6B19DBB43EBF}
|
||||
{58B6443B-1278-4DF9-B7BB-DDF3BFFCF868} = {F141E2D0-F9B8-4ADB-A19A-7B6FF4CA19A1}
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E} = {F141E2D0-F9B8-4ADB-A19A-7B6FF4CA19A1}
|
||||
{113EBBD2-E857-4CAF-9B53-7A8742CBCD4A} = {B54371FF-B920-46C8-8D55-6B19DBB43EBF}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.IO;
|
||||
using Microsoft.Framework.ConfigurationModel.UserSecrets;
|
||||
using Microsoft.Framework.Internal;
|
||||
using Microsoft.Framework.Runtime;
|
||||
using Microsoft.Framework.Runtime.Infrastructure;
|
||||
|
||||
namespace Microsoft.Framework.ConfigurationModel
|
||||
{
|
||||
public static class ConfigurationExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the user secrets configuration source.
|
||||
/// </summary>
|
||||
/// <param name="configuration"></param>
|
||||
/// <returns></returns>
|
||||
public static IConfigurationSourceRoot AddUserSecrets([NotNull]this IConfigurationSourceRoot configuration)
|
||||
{
|
||||
var appEnv = (IApplicationEnvironment)CallContextServiceLocator.Locator.ServiceProvider.GetService(typeof(IApplicationEnvironment));
|
||||
var secretPath = PathHelper.GetSecretsPath(appEnv.ApplicationBasePath);
|
||||
|
||||
if (!File.Exists(secretPath))
|
||||
{
|
||||
// TODO: Use the optional config add after that's available?.
|
||||
return configuration;
|
||||
}
|
||||
|
||||
return configuration.AddJsonFile(secretPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the user secrets configuration source with specified secrets id.
|
||||
/// </summary>
|
||||
/// <param name="configuration"></param>
|
||||
/// <returns></returns>
|
||||
public static IConfigurationSourceRoot AddUserSecrets([NotNull]this IConfigurationSourceRoot configuration, [NotNull]string userSecretsId)
|
||||
{
|
||||
var secretPath = PathHelper.GetSecretsPathFromSecretsId(userSecretsId);
|
||||
|
||||
if (!File.Exists(secretPath))
|
||||
{
|
||||
// TODO: Use the optional config add after that's available?.
|
||||
return configuration;
|
||||
}
|
||||
|
||||
return configuration.AddJsonFile(secretPath);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="__ToolsVersion__" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>58b6443b-1278-4df9-b7bb-ddf3bffcf868</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'" Label="Configuration">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" Label="Configuration">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
|
@ -1,62 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. 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.IO;
|
||||
using Microsoft.Framework.Internal;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Framework.ConfigurationModel.UserSecrets
|
||||
{
|
||||
public class PathHelper
|
||||
{
|
||||
private const string Secrets_File_Name = "secrets.json";
|
||||
|
||||
public static string GetSecretsPath([NotNull]string projectPath)
|
||||
{
|
||||
var projectFilePath = Path.Combine(projectPath, "project.json");
|
||||
|
||||
if (!File.Exists(projectFilePath))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
string.Format(Resources.Error_Missing_Project_Json, projectFilePath));
|
||||
}
|
||||
|
||||
var obj = JObject.Parse(File.ReadAllText(projectFilePath));
|
||||
var userSecretsId = obj.Value<string>("userSecretsId");
|
||||
|
||||
if (string.IsNullOrEmpty(userSecretsId))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
string.Format(Resources.Error_Missing_UserSecretId_In_Project_Json, projectFilePath));
|
||||
}
|
||||
|
||||
return GetSecretsPathFromSecretsId(userSecretsId);
|
||||
}
|
||||
|
||||
public static string GetSecretsPathFromSecretsId([NotNull]string userSecretsId)
|
||||
{
|
||||
var badCharIndex = userSecretsId.IndexOfAny(Path.GetInvalidPathChars());
|
||||
if (badCharIndex != -1)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
string.Format(
|
||||
Resources.Error_Invalid_Character_In_UserSecrets_Id,
|
||||
userSecretsId[badCharIndex],
|
||||
badCharIndex));
|
||||
}
|
||||
|
||||
var root = Environment.GetEnvironmentVariable("APPDATA") ?? // On Windows it goes to %APPDATA%\Microsoft\UserSecrets\
|
||||
Environment.GetEnvironmentVariable("HOME"); // On Mac/Linux it goes to ~/.microsoft/usersecrets/
|
||||
|
||||
if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("APPDATA")))
|
||||
{
|
||||
return Path.Combine(root, "Microsoft", "UserSecrets", userSecretsId, Secrets_File_Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Path.Combine(root, ".microsoft", "usersecrets", userSecretsId, Secrets_File_Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
// <auto-generated />
|
||||
namespace Microsoft.Framework.ConfigurationModel.UserSecrets
|
||||
{
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
|
||||
internal static class Resources
|
||||
{
|
||||
private static readonly ResourceManager _resourceManager
|
||||
= new ResourceManager("Microsoft.Framework.ConfigurationModel.UserSecrets.Resources", typeof(Resources).GetTypeInfo().Assembly);
|
||||
|
||||
/// <summary>
|
||||
/// Invalid character '{0}' found in 'userSecretsId' value at index '{1}'.
|
||||
/// </summary>
|
||||
internal static string Error_Invalid_Character_In_UserSecrets_Id
|
||||
{
|
||||
get { return GetString("Error_Invalid_Character_In_UserSecrets_Id"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invalid character '{0}' found in 'userSecretsId' value at index '{1}'.
|
||||
/// </summary>
|
||||
internal static string FormatError_Invalid_Character_In_UserSecrets_Id(object p0, object p1)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("Error_Invalid_Character_In_UserSecrets_Id"), p0, p1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unable to locate a project.json at '{0}'.
|
||||
/// </summary>
|
||||
internal static string Error_Missing_Project_Json
|
||||
{
|
||||
get { return GetString("Error_Missing_Project_Json"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unable to locate a project.json at '{0}'.
|
||||
/// </summary>
|
||||
internal static string FormatError_Missing_Project_Json(object p0)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("Error_Missing_Project_Json"), p0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Missing 'userSecretsId' in '{0}'.
|
||||
/// </summary>
|
||||
internal static string Error_Missing_UserSecretId_In_Project_Json
|
||||
{
|
||||
get { return GetString("Error_Missing_UserSecretId_In_Project_Json"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Missing 'userSecretsId' in '{0}'.
|
||||
/// </summary>
|
||||
internal static string FormatError_Missing_UserSecretId_In_Project_Json(object p0)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("Error_Missing_UserSecretId_In_Project_Json"), p0);
|
||||
}
|
||||
|
||||
private static string GetString(string name, params string[] formatterNames)
|
||||
{
|
||||
var value = _resourceManager.GetString(name);
|
||||
|
||||
System.Diagnostics.Debug.Assert(value != null);
|
||||
|
||||
if (formatterNames != null)
|
||||
{
|
||||
for (var i = 0; i < formatterNames.Length; i++)
|
||||
{
|
||||
value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}");
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,129 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Error_Invalid_Character_In_UserSecrets_Id" xml:space="preserve">
|
||||
<value>Invalid character '{0}' found in 'userSecretsId' value at index '{1}'.</value>
|
||||
</data>
|
||||
<data name="Error_Missing_Project_Json" xml:space="preserve">
|
||||
<value>Unable to locate a project.json at '{0}'.</value>
|
||||
</data>
|
||||
<data name="Error_Missing_UserSecretId_In_Project_Json" xml:space="preserve">
|
||||
<value>Missing 'userSecretsId' in '{0}'.</value>
|
||||
</data>
|
||||
</root>
|
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
"version": "1.0.0-*",
|
||||
"description": "ASP.NET 5 Configuration extensions to load user secrets.",
|
||||
"dependencies": {
|
||||
"Microsoft.Framework.ConfigurationModel.Json": "1.0.0-*",
|
||||
"Microsoft.Framework.NotNullAttribute.Internal": { "type": "build", "version": "1.0.0-*" }
|
||||
},
|
||||
"frameworks": {
|
||||
"dnx451": { },
|
||||
"dnxcore50": {
|
||||
"dependencies": {
|
||||
"System.Runtime": "4.0.20-beta-*"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.Framework.Logging;
|
||||
using Microsoft.Framework.Runtime.Common.CommandLine;
|
||||
|
||||
namespace SecretManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Logger to print formatted command output.
|
||||
/// </summary>
|
||||
public class CommandOutputLogger : ILogger
|
||||
{
|
||||
private readonly CommandOutputProvider _provider;
|
||||
|
||||
public CommandOutputLogger(CommandOutputProvider commandOutputProvider)
|
||||
{
|
||||
_provider = commandOutputProvider;
|
||||
}
|
||||
|
||||
public IDisposable BeginScope(object state)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool IsEnabled(LogLevel logLevel)
|
||||
{
|
||||
if (logLevel < _provider.LogLevel)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Log(LogLevel logLevel, int eventId, object state, Exception exception, Func<object, Exception, string> formatter)
|
||||
{
|
||||
if (IsEnabled(logLevel))
|
||||
{
|
||||
AnsiConsole.Output.WriteLine(string.Format("{0}: {1}", Caption(logLevel), formatter(state, exception)));
|
||||
}
|
||||
}
|
||||
|
||||
private string Caption(LogLevel logLevel)
|
||||
{
|
||||
switch (logLevel)
|
||||
{
|
||||
case LogLevel.Debug: return "\x1b[35mdebug\x1b[39m";
|
||||
case LogLevel.Verbose: return "\x1b[35mverbose\x1b[39m";
|
||||
case LogLevel.Information: return "\x1b[32minfo\x1b[39m";
|
||||
case LogLevel.Warning: return "\x1b[33mwarn\x1b[39m";
|
||||
case LogLevel.Error: return "\x1b[31mfail\x1b[39m";
|
||||
case LogLevel.Critical: return "\x1b[31mcritical\x1b[39m";
|
||||
}
|
||||
|
||||
throw new Exception("Unknown LogLevel");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.Framework.Logging;
|
||||
|
||||
namespace SecretManager
|
||||
{
|
||||
public class CommandOutputProvider : ILoggerProvider
|
||||
{
|
||||
public ILogger CreateLogger(string name)
|
||||
{
|
||||
return new CommandOutputLogger(this);
|
||||
}
|
||||
|
||||
public LogLevel LogLevel { get; set; } = LogLevel.Information;
|
||||
}
|
||||
}
|
|
@ -1,225 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. 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.IO;
|
||||
using Microsoft.Framework.ConfigurationModel.UserSecrets;
|
||||
using Microsoft.Framework.Logging;
|
||||
using Microsoft.Framework.Runtime.Common.CommandLine;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace SecretManager
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
private ILogger _logger;
|
||||
private CommandOutputProvider _loggerProvider;
|
||||
|
||||
public Program()
|
||||
{
|
||||
var loggerFactory = new LoggerFactory();
|
||||
CommandOutputProvider = new CommandOutputProvider();
|
||||
loggerFactory.AddProvider(CommandOutputProvider);
|
||||
Logger = loggerFactory.CreateLogger<Program>();
|
||||
}
|
||||
|
||||
public ILogger Logger
|
||||
{
|
||||
get { return _logger; }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException("value");
|
||||
}
|
||||
|
||||
_logger = value;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandOutputProvider CommandOutputProvider
|
||||
{
|
||||
get { return _loggerProvider; }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException("value");
|
||||
}
|
||||
|
||||
_loggerProvider = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Main(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
var app = new CommandLineApplication();
|
||||
app.Name = "user-secret";
|
||||
app.Description = "Manages user secrets";
|
||||
|
||||
app.HelpOption("-?|-h|--help");
|
||||
var optVerbose = app.Option("-v|--verbose", "Verbose output", CommandOptionType.NoValue);
|
||||
|
||||
app.Command("set", c =>
|
||||
{
|
||||
c.Description = "Sets the user secret to the specified value";
|
||||
|
||||
var optionProject = c.Option("-p|--project <PATH>", "Path to project, default is current directory", CommandOptionType.SingleValue);
|
||||
var keyArg = c.Argument("[name]", "Name of the secret");
|
||||
var valueArg = c.Argument("[value]", "Value of the secret");
|
||||
c.HelpOption("-?|-h|--help");
|
||||
|
||||
c.OnExecute(() =>
|
||||
{
|
||||
var projectPath = optionProject.Value() ?? Directory.GetCurrentDirectory();
|
||||
|
||||
if (optVerbose.HasValue())
|
||||
{
|
||||
CommandOutputProvider.LogLevel = LogLevel.Verbose;
|
||||
}
|
||||
|
||||
ProcessSecretFile(projectPath, secrets =>
|
||||
{
|
||||
secrets[keyArg.Value] = valueArg.Value;
|
||||
});
|
||||
|
||||
Logger.LogInformation(Resources.Message_Saved_Secret, keyArg.Value, valueArg.Value);
|
||||
return 0;
|
||||
});
|
||||
});
|
||||
|
||||
app.Command("remove", c =>
|
||||
{
|
||||
c.Description = "Removes the specified user secret";
|
||||
|
||||
var optionProject = c.Option("-p|--project <PATH>", "Path to project, default is current directory", CommandOptionType.SingleValue);
|
||||
var keyArg = c.Argument("[name]", "Name of the secret");
|
||||
c.HelpOption("-?|-h|--help");
|
||||
|
||||
c.OnExecute(() =>
|
||||
{
|
||||
var projectPath = optionProject.Value() ?? Directory.GetCurrentDirectory();
|
||||
|
||||
if (optVerbose.HasValue())
|
||||
{
|
||||
CommandOutputProvider.LogLevel = LogLevel.Verbose;
|
||||
}
|
||||
|
||||
ProcessSecretFile(projectPath, secrets =>
|
||||
{
|
||||
if (secrets[keyArg.Value] == null)
|
||||
{
|
||||
Logger.LogWarning(Resources.Error_Missing_Secret, keyArg.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
secrets.Remove(keyArg.Value);
|
||||
}
|
||||
});
|
||||
|
||||
return 0;
|
||||
});
|
||||
});
|
||||
|
||||
app.Command("list", c =>
|
||||
{
|
||||
c.Description = "Lists all the application secrets";
|
||||
|
||||
var optionProject = c.Option("-p|--project <PATH>", "Path to project, default is current directory", CommandOptionType.SingleValue);
|
||||
c.HelpOption("-?|-h|--help");
|
||||
|
||||
c.OnExecute(() =>
|
||||
{
|
||||
var projectPath = optionProject.Value() ?? Directory.GetCurrentDirectory();
|
||||
|
||||
if (optVerbose.HasValue())
|
||||
{
|
||||
CommandOutputProvider.LogLevel = LogLevel.Verbose;
|
||||
}
|
||||
|
||||
ProcessSecretFile(projectPath, secrets =>
|
||||
{
|
||||
PrintAll(secrets);
|
||||
},
|
||||
persist: false);
|
||||
return 0;
|
||||
});
|
||||
});
|
||||
|
||||
app.Command("clear", c =>
|
||||
{
|
||||
c.Description = "Deletes all the application secrets";
|
||||
|
||||
var optionProject = c.Option("-p|--project <PATH>", "Path to project, default is current directory", CommandOptionType.SingleValue);
|
||||
c.HelpOption("-?|-h|--help");
|
||||
|
||||
c.OnExecute(() =>
|
||||
{
|
||||
var projectPath = optionProject.Value() ?? Directory.GetCurrentDirectory();
|
||||
|
||||
if (optVerbose.HasValue())
|
||||
{
|
||||
CommandOutputProvider.LogLevel = LogLevel.Verbose;
|
||||
}
|
||||
|
||||
ProcessSecretFile(projectPath, secrets =>
|
||||
{
|
||||
secrets.RemoveAll();
|
||||
});
|
||||
|
||||
return 0;
|
||||
});
|
||||
});
|
||||
|
||||
// Show help information if no subcommand/option was specified.
|
||||
app.OnExecute(() =>
|
||||
{
|
||||
app.ShowHelp();
|
||||
return 2;
|
||||
});
|
||||
|
||||
return app.Execute(args);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Logger.LogCritical(Resources.Error_Command_Failed, exception.Message);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
private void PrintAll(JObject secrets)
|
||||
{
|
||||
if (secrets.Count == 0)
|
||||
{
|
||||
Logger.LogInformation(Resources.Error_No_Secrets_Found);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var secret in secrets)
|
||||
{
|
||||
Logger.LogInformation(Resources.Message_Secret_Value_Format, secret.Key, secret.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessSecretFile(string projectPath, Action<JObject> observer, bool persist = true)
|
||||
{
|
||||
Logger.LogVerbose(Resources.Message_Project_File_Path, projectPath);
|
||||
var secretsFilePath = PathHelper.GetSecretsPath(projectPath);
|
||||
Logger.LogVerbose(Resources.Message_Secret_File_Path, secretsFilePath);
|
||||
var secretObj = File.Exists(secretsFilePath) ?
|
||||
JObject.Parse(File.ReadAllText(secretsFilePath)) :
|
||||
new JObject();
|
||||
|
||||
observer(secretObj);
|
||||
|
||||
if (persist)
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(secretsFilePath));
|
||||
File.WriteAllText(secretsFilePath, secretObj.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("SecretManager.Tests")]
|
|
@ -1,142 +0,0 @@
|
|||
// <auto-generated />
|
||||
namespace SecretManager
|
||||
{
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
|
||||
internal static class Resources
|
||||
{
|
||||
private static readonly ResourceManager _resourceManager
|
||||
= new ResourceManager("SecretManager.Resources", typeof(Resources).GetTypeInfo().Assembly);
|
||||
|
||||
/// <summary>
|
||||
/// Command failed : {message}
|
||||
/// </summary>
|
||||
internal static string Error_Command_Failed
|
||||
{
|
||||
get { return GetString("Error_Command_Failed"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command failed : {message}
|
||||
/// </summary>
|
||||
internal static string FormatError_Command_Failed(object message)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("Error_Command_Failed", "message"), message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cannot find '{key}' in the secret store.
|
||||
/// </summary>
|
||||
internal static string Error_Missing_Secret
|
||||
{
|
||||
get { return GetString("Error_Missing_Secret"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cannot find '{key}' in the secret store.
|
||||
/// </summary>
|
||||
internal static string FormatError_Missing_Secret(object key)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("Error_Missing_Secret", "key"), key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// No secrets configured for this application.
|
||||
/// </summary>
|
||||
internal static string Error_No_Secrets_Found
|
||||
{
|
||||
get { return GetString("Error_No_Secrets_Found"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// No secrets configured for this application.
|
||||
/// </summary>
|
||||
internal static string FormatError_No_Secrets_Found()
|
||||
{
|
||||
return GetString("Error_No_Secrets_Found");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Project file path {project}.
|
||||
/// </summary>
|
||||
internal static string Message_Project_File_Path
|
||||
{
|
||||
get { return GetString("Message_Project_File_Path"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Project file path {project}.
|
||||
/// </summary>
|
||||
internal static string FormatMessage_Project_File_Path(object project)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("Message_Project_File_Path", "project"), project);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Successfully saved {key} = {value} to the secret store.
|
||||
/// </summary>
|
||||
internal static string Message_Saved_Secret
|
||||
{
|
||||
get { return GetString("Message_Saved_Secret"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Successfully saved {key} = {value} to the secret store.
|
||||
/// </summary>
|
||||
internal static string FormatMessage_Saved_Secret(object key, object value)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("Message_Saved_Secret", "key", "value"), key, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Secrets file path {secretsFilePath}.
|
||||
/// </summary>
|
||||
internal static string Message_Secret_File_Path
|
||||
{
|
||||
get { return GetString("Message_Secret_File_Path"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Secrets file path {secretsFilePath}.
|
||||
/// </summary>
|
||||
internal static string FormatMessage_Secret_File_Path(object secretsFilePath)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("Message_Secret_File_Path", "secretsFilePath"), secretsFilePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// {key} = {value}
|
||||
/// </summary>
|
||||
internal static string Message_Secret_Value_Format
|
||||
{
|
||||
get { return GetString("Message_Secret_Value_Format"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// {key} = {value}
|
||||
/// </summary>
|
||||
internal static string FormatMessage_Secret_Value_Format(object key, object value)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("Message_Secret_Value_Format", "key", "value"), key, value);
|
||||
}
|
||||
|
||||
private static string GetString(string name, params string[] formatterNames)
|
||||
{
|
||||
var value = _resourceManager.GetString(name);
|
||||
|
||||
System.Diagnostics.Debug.Assert(value != null);
|
||||
|
||||
if (formatterNames != null)
|
||||
{
|
||||
for (var i = 0; i < formatterNames.Length; i++)
|
||||
{
|
||||
value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}");
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,141 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Error_Command_Failed" xml:space="preserve">
|
||||
<value>Command failed : {message}</value>
|
||||
</data>
|
||||
<data name="Error_Missing_Secret" xml:space="preserve">
|
||||
<value>Cannot find '{key}' in the secret store.</value>
|
||||
</data>
|
||||
<data name="Error_No_Secrets_Found" xml:space="preserve">
|
||||
<value>No secrets configured for this application.</value>
|
||||
</data>
|
||||
<data name="Message_Project_File_Path" xml:space="preserve">
|
||||
<value>Project file path {project}.</value>
|
||||
</data>
|
||||
<data name="Message_Saved_Secret" xml:space="preserve">
|
||||
<value>Successfully saved {key} = {value} to the secret store.</value>
|
||||
</data>
|
||||
<data name="Message_Secret_File_Path" xml:space="preserve">
|
||||
<value>Secrets file path {secretsFilePath}.</value>
|
||||
</data>
|
||||
<data name="Message_Secret_Value_Format" xml:space="preserve">
|
||||
<value>{key} = {value}</value>
|
||||
</data>
|
||||
</root>
|
|
@ -1,20 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="__ToolsVersion__" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>8730e848-ca0f-4e0a-9a2f-bc22ad0b2c4e</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'" Label="Configuration">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" Label="Configuration">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
|
@ -1,22 +0,0 @@
|
|||
{
|
||||
"version": "1.0.0-*",
|
||||
"description": "ASP.NET 5 tool to manage user secrets.",
|
||||
"dependencies": {
|
||||
"Microsoft.Framework.ConfigurationModel.UserSecrets": "1.0.0-*",
|
||||
"Microsoft.Framework.CommandLineUtils": { "version": "1.0.0-*", "type": "build" },
|
||||
"Microsoft.Framework.Logging": "1.0.0-*",
|
||||
"Newtonsoft.Json": "6.0.6"
|
||||
},
|
||||
"commands": {
|
||||
"user-secret": "SecretManager"
|
||||
},
|
||||
"userSecretsId": "testuserSecretsId",
|
||||
"frameworks": {
|
||||
"dnx451": { },
|
||||
"dnxcore50": {
|
||||
"dependencies": {
|
||||
"System.Console": "4.0.0-beta-*"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. 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.IO;
|
||||
using Microsoft.Framework.ConfigurationModel.UserSecrets;
|
||||
using Xunit;
|
||||
|
||||
namespace SecretManager.Tests
|
||||
{
|
||||
public class PathHelperTests
|
||||
{
|
||||
[Fact]
|
||||
public void Gives_Correct_Secret_Path()
|
||||
{
|
||||
string userSecretsId;
|
||||
var projectPath = UserSecretHelper.GetTempSecretProject(out userSecretsId);
|
||||
var actualSecretPath = PathHelper.GetSecretsPath(projectPath);
|
||||
|
||||
var root = Environment.GetEnvironmentVariable("APPDATA") ?? // On Windows it goes to %APPDATA%\Microsoft\UserSecrets\
|
||||
Environment.GetEnvironmentVariable("HOME"); // On Mac/Linux it goes to ~/.microsoft/usersecrets/
|
||||
|
||||
var expectedSecretPath = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("APPDATA"))?
|
||||
Path.Combine(root, "Microsoft", "UserSecrets", userSecretsId, "secrets.json") :
|
||||
Path.Combine(root, ".microsoft", "usersecrets", userSecretsId, "secrets.json");
|
||||
|
||||
Assert.Equal(expectedSecretPath, actualSecretPath);
|
||||
|
||||
UserSecretHelper.DeleteTempSecretProject(projectPath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Throws_If_Project_Json_Not_Found()
|
||||
{
|
||||
var projectPath = UserSecretHelper.GetTempSecretProject();
|
||||
File.Delete(Path.Combine(projectPath, "project.json"));
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
{
|
||||
PathHelper.GetSecretsPath(projectPath);
|
||||
});
|
||||
|
||||
UserSecretHelper.DeleteTempSecretProject(projectPath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Throws_If_Project_Json_Does_Not_Contain_UserSecretId()
|
||||
{
|
||||
var projectPath = UserSecretHelper.GetTempSecretProject();
|
||||
File.WriteAllText(Path.Combine(projectPath, "project.json"), "{}");
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
{
|
||||
PathHelper.GetSecretsPath(projectPath);
|
||||
});
|
||||
|
||||
UserSecretHelper.DeleteTempSecretProject(projectPath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Throws_If_UserSecretId_Contains_Invalid_Characters()
|
||||
{
|
||||
var projectPath = UserSecretHelper.GetTempSecretProject();
|
||||
|
||||
foreach (var character in Path.GetInvalidPathChars())
|
||||
{
|
||||
UserSecretHelper.SetTempSecretInProject(projectPath, "Test" + character);
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
{
|
||||
PathHelper.GetSecretsPath(projectPath);
|
||||
});
|
||||
}
|
||||
|
||||
UserSecretHelper.DeleteTempSecretProject(projectPath);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>113ebbd2-e857-4caf-9b53-7a8742cbcd4a</ProjectGuid>
|
||||
<RootNamespace>SecretManager.Tests</RootNamespace>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
|
@ -1,247 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. 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.IO;
|
||||
using Microsoft.Framework.ConfigurationModel.UserSecrets;
|
||||
using Xunit;
|
||||
|
||||
namespace SecretManager.Tests
|
||||
{
|
||||
public class SecretManagerTests
|
||||
{
|
||||
[Fact]
|
||||
public void SetSecret_With_ProjectPath_As_CommandLine_Parameter()
|
||||
{
|
||||
SetSecrets(fromCurrentDirectory: false);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetSecret_From_CurrentDirectory()
|
||||
{
|
||||
var backUpCurrentDirectory = Directory.GetCurrentDirectory();
|
||||
|
||||
try
|
||||
{
|
||||
SetSecrets(fromCurrentDirectory: true);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Directory.SetCurrentDirectory(backUpCurrentDirectory);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetSecrets(bool fromCurrentDirectory)
|
||||
{
|
||||
var secrets = new KeyValuePair<string, string>[]
|
||||
{
|
||||
new KeyValuePair<string, string>("key1", Guid.NewGuid().ToString()),
|
||||
new KeyValuePair<string, string>("Facebook:AppId", Guid.NewGuid().ToString()),
|
||||
new KeyValuePair<string, string>(@"key-@\/.~123!#$%^&*())-+==", @"key-@\/.~123!#$%^&*())-+=="),
|
||||
new KeyValuePair<string, string>("key2", string.Empty)
|
||||
};
|
||||
|
||||
var projectPath = UserSecretHelper.GetTempSecretProject();
|
||||
if (fromCurrentDirectory)
|
||||
{
|
||||
Directory.SetCurrentDirectory(projectPath); // Point current directory to the project.json directory.
|
||||
}
|
||||
|
||||
var logger = new TestLogger();
|
||||
var secretManager = new Program() { Logger = logger };
|
||||
|
||||
foreach (var secret in secrets)
|
||||
{
|
||||
var parameters = fromCurrentDirectory ?
|
||||
new string[] { "set", secret.Key, secret.Value } :
|
||||
new string[] { "set", secret.Key, secret.Value, "-p", projectPath };
|
||||
secretManager.Main(parameters);
|
||||
}
|
||||
|
||||
Assert.Equal(4, logger.Messages.Count);
|
||||
|
||||
foreach (var keyValue in secrets)
|
||||
{
|
||||
Assert.Contains(
|
||||
string.Format("Successfully saved {0} = {1} to the secret store.", keyValue.Key, keyValue.Value),
|
||||
logger.Messages);
|
||||
}
|
||||
|
||||
logger.Messages.Clear();
|
||||
var args = fromCurrentDirectory ?
|
||||
new string[] { "list" } : new string[] { "list", "-p", projectPath };
|
||||
secretManager.Main(args);
|
||||
Assert.Equal(4, logger.Messages.Count);
|
||||
foreach (var keyValue in secrets)
|
||||
{
|
||||
Assert.Contains(
|
||||
string.Format("{0} = {1}", keyValue.Key, keyValue.Value),
|
||||
logger.Messages);
|
||||
}
|
||||
|
||||
// Remove secrets.
|
||||
logger.Messages.Clear();
|
||||
foreach (var secret in secrets)
|
||||
{
|
||||
var parameters = fromCurrentDirectory ?
|
||||
new string[] { "remove", secret.Key } :
|
||||
new string[] { "remove", secret.Key, "-p", projectPath };
|
||||
secretManager.Main(parameters);
|
||||
}
|
||||
|
||||
// Verify secrets are removed.
|
||||
logger.Messages.Clear();
|
||||
args = fromCurrentDirectory ?
|
||||
new string[] { "list" } : new string[] { "list", "-p", projectPath };
|
||||
secretManager.Main(args);
|
||||
Assert.Equal(1, logger.Messages.Count);
|
||||
Assert.Contains(Resources.Error_No_Secrets_Found, logger.Messages);
|
||||
|
||||
UserSecretHelper.DeleteTempSecretProject(projectPath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetSecret_Update_Existing_Secret()
|
||||
{
|
||||
var projectPath = UserSecretHelper.GetTempSecretProject();
|
||||
var logger = new TestLogger();
|
||||
var secretManager = new Program() { Logger = logger };
|
||||
|
||||
secretManager.Main(new string[] { "set", "secret1", "value1", "-p", projectPath });
|
||||
Assert.Equal(1, logger.Messages.Count);
|
||||
Assert.Contains("Successfully saved secret1 = value1 to the secret store.", logger.Messages);
|
||||
secretManager.Main(new string[] { "set", "secret1", "value2", "-p", projectPath });
|
||||
Assert.Equal(2, logger.Messages.Count);
|
||||
Assert.Contains("Successfully saved secret1 = value2 to the secret store.", logger.Messages);
|
||||
|
||||
logger.Messages.Clear();
|
||||
|
||||
secretManager.Main(new string[] { "list", "-p", projectPath });
|
||||
Assert.Equal(1, logger.Messages.Count);
|
||||
Assert.Contains("secret1 = value2", logger.Messages);
|
||||
|
||||
UserSecretHelper.DeleteTempSecretProject(projectPath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetSecret_With_Verbose_Flag()
|
||||
{
|
||||
var projectPath = UserSecretHelper.GetTempSecretProject();
|
||||
var logger = new TestLogger(verbose: true);
|
||||
var secretManager = new Program() { Logger = logger };
|
||||
|
||||
secretManager.Main(new string[] { "-v", "set", "secret1", "value1", "-p", projectPath });
|
||||
Assert.Equal(3, logger.Messages.Count);
|
||||
Assert.Contains(string.Format("Project file path {0}.", projectPath), logger.Messages);
|
||||
Assert.Contains(string.Format("Secrets file path {0}.", PathHelper.GetSecretsPath(projectPath)), logger.Messages);
|
||||
Assert.Contains("Successfully saved secret1 = value1 to the secret store.", logger.Messages);
|
||||
logger.Messages.Clear();
|
||||
|
||||
secretManager.Main(new string[] { "-v", "list", "-p", projectPath });
|
||||
Assert.Equal(3, logger.Messages.Count);
|
||||
Assert.Contains(string.Format("Project file path {0}.", projectPath), logger.Messages);
|
||||
Assert.Contains(string.Format("Secrets file path {0}.", PathHelper.GetSecretsPath(projectPath)), logger.Messages);
|
||||
Assert.Contains("secret1 = value1", logger.Messages);
|
||||
|
||||
UserSecretHelper.DeleteTempSecretProject(projectPath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Remove_Non_Existing_Secret()
|
||||
{
|
||||
var projectPath = UserSecretHelper.GetTempSecretProject();
|
||||
var logger = new TestLogger();
|
||||
var secretManager = new Program() { Logger = logger };
|
||||
secretManager.Main(new string[] { "remove", "secret1", "-p", projectPath });
|
||||
Assert.Equal(1, logger.Messages.Count);
|
||||
Assert.Contains("Cannot find 'secret1' in the secret store.", logger.Messages);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void List_Empty_Secrets_File()
|
||||
{
|
||||
var projectPath = UserSecretHelper.GetTempSecretProject();
|
||||
var logger = new TestLogger();
|
||||
var secretManager = new Program() { Logger = logger };
|
||||
secretManager.Main(new string[] { "list", "-p", projectPath });
|
||||
Assert.Equal(1, logger.Messages.Count);
|
||||
Assert.Contains(Resources.Error_No_Secrets_Found, logger.Messages);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Clear_All_Secrets_With_ProjectPath_As_Parameter()
|
||||
{
|
||||
Clear_Secrets(fromCurrentDirectory: false);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Clear_All_Secrets_From_Current_Directory()
|
||||
{
|
||||
Clear_Secrets(fromCurrentDirectory: true);
|
||||
}
|
||||
|
||||
private void Clear_Secrets(bool fromCurrentDirectory)
|
||||
{
|
||||
var projectPath = UserSecretHelper.GetTempSecretProject();
|
||||
if (fromCurrentDirectory)
|
||||
{
|
||||
Directory.SetCurrentDirectory(projectPath); // Point current directory to the project.json directory.
|
||||
}
|
||||
|
||||
var logger = new TestLogger();
|
||||
var secretManager = new Program() { Logger = logger };
|
||||
|
||||
var secrets = new KeyValuePair<string, string>[]
|
||||
{
|
||||
new KeyValuePair<string, string>("key1", Guid.NewGuid().ToString()),
|
||||
new KeyValuePair<string, string>("Facebook:AppId", Guid.NewGuid().ToString()),
|
||||
new KeyValuePair<string, string>(@"key-@\/.~123!#$%^&*())-+==", @"key-@\/.~123!#$%^&*())-+=="),
|
||||
new KeyValuePair<string, string>("key2", string.Empty)
|
||||
};
|
||||
|
||||
foreach (var secret in secrets)
|
||||
{
|
||||
var parameters = fromCurrentDirectory ?
|
||||
new string[] { "set", secret.Key, secret.Value } :
|
||||
new string[] { "set", secret.Key, secret.Value, "-p", projectPath };
|
||||
secretManager.Main(parameters);
|
||||
}
|
||||
|
||||
Assert.Equal(4, logger.Messages.Count);
|
||||
|
||||
foreach (var keyValue in secrets)
|
||||
{
|
||||
Assert.Contains(
|
||||
string.Format("Successfully saved {0} = {1} to the secret store.", keyValue.Key, keyValue.Value),
|
||||
logger.Messages);
|
||||
}
|
||||
|
||||
// Verify secrets are persisted.
|
||||
logger.Messages.Clear();
|
||||
var args = fromCurrentDirectory ?
|
||||
new string[] { "list" } :
|
||||
new string[] { "list", "-p", projectPath };
|
||||
secretManager.Main(args);
|
||||
Assert.Equal(4, logger.Messages.Count);
|
||||
foreach (var keyValue in secrets)
|
||||
{
|
||||
Assert.Contains(
|
||||
string.Format("{0} = {1}", keyValue.Key, keyValue.Value),
|
||||
logger.Messages);
|
||||
}
|
||||
|
||||
// Clear secrets.
|
||||
logger.Messages.Clear();
|
||||
args = fromCurrentDirectory ? new string[] { "clear" } : new string[] { "clear", "-p", projectPath };
|
||||
secretManager.Main(args);
|
||||
Assert.Equal(0, logger.Messages.Count);
|
||||
|
||||
args = fromCurrentDirectory ? new string[] { "list" } : new string[] { "list", "-p", projectPath };
|
||||
secretManager.Main(args);
|
||||
Assert.Equal(1, logger.Messages.Count);
|
||||
Assert.Contains(Resources.Error_No_Secrets_Found, logger.Messages);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.Framework.Logging;
|
||||
|
||||
namespace SecretManager.Tests
|
||||
{
|
||||
public class TestLogger : ILogger
|
||||
{
|
||||
private readonly CommandOutputLogger _commandOutputLogger;
|
||||
|
||||
public TestLogger(bool verbose = false)
|
||||
{
|
||||
var commandOutputProvider = new CommandOutputProvider();
|
||||
if (verbose)
|
||||
{
|
||||
commandOutputProvider.LogLevel = LogLevel.Verbose;
|
||||
}
|
||||
|
||||
_commandOutputLogger = new CommandOutputLogger(commandOutputProvider);
|
||||
}
|
||||
|
||||
public List<string> Messages { get; set; } = new List<string>();
|
||||
|
||||
public IDisposable BeginScope(object state)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool IsEnabled(LogLevel logLevel)
|
||||
{
|
||||
return _commandOutputLogger.IsEnabled(logLevel);
|
||||
}
|
||||
|
||||
public void Log(LogLevel logLevel, int eventId, object state, Exception exception, Func<object, Exception, string> formatter)
|
||||
{
|
||||
if (IsEnabled(logLevel))
|
||||
{
|
||||
Messages.Add(formatter(state, exception));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. 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.IO;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace SecretManager.Tests
|
||||
{
|
||||
public class UserSecretHelper
|
||||
{
|
||||
internal static string GetTempSecretProject()
|
||||
{
|
||||
string userSecretsId;
|
||||
return GetTempSecretProject(out userSecretsId);
|
||||
}
|
||||
|
||||
internal static string GetTempSecretProject(out string userSecretsId)
|
||||
{
|
||||
var projectPath = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()));
|
||||
userSecretsId = Guid.NewGuid().ToString();
|
||||
File.WriteAllText(
|
||||
Path.Combine(projectPath.FullName, "project.json"),
|
||||
string.Format("{{\"userSecretsId\": {0}}}", JsonConvert.ToString(userSecretsId)));
|
||||
return projectPath.FullName;
|
||||
}
|
||||
|
||||
internal static void SetTempSecretInProject(string projectPath, string userSecretsId)
|
||||
{
|
||||
File.WriteAllText(
|
||||
Path.Combine(projectPath, "project.json"),
|
||||
string.Format("{{\"userSecretsId\": {0}}}", JsonConvert.ToString(userSecretsId)));
|
||||
}
|
||||
|
||||
internal static void DeleteTempSecretProject(string projectPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete(projectPath, true);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Ignore failures.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"SecretManager": "1.0.0-*",
|
||||
"xunit.runner.aspnet": "2.0.0-aspnet-*"
|
||||
},
|
||||
"frameworks": {
|
||||
"dnx451": { },
|
||||
"dnxcore50": { }
|
||||
},
|
||||
"commands": {
|
||||
"test": "xunit.runner.aspnet"
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче