diff --git a/AzSdk.props b/AzSdk.props index b0d94dc9ea92..d85410928253 100644 --- a/AzSdk.props +++ b/AzSdk.props @@ -6,4 +6,5 @@ $(LibraryToolsFolder)\MSSharedLibKey.snk --> + \ No newline at end of file diff --git a/Directory.Build.props b/Directory.Build.props index 671089e27c64..cd99f16d264f 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -8,7 +8,7 @@ src\Authentication\Authentication.sln AzureManagementLibraries.sln $(LibraryRoot)binaries - $(LibraryToolsFolder)\BuildAssets + $(LibraryToolsFolder)\BuildAssets $(LibraryRoot)PolicheckOutput $(BinariesFolder)\packages false @@ -17,12 +17,13 @@ "$(LibraryToolsFolder)\nuget.exe" 1234 true - $(LibraryToolsFolder)\SdkBuildTools + $(LibraryToolsFolder)\SdkBuildTools true $(OnPremiseBuildTasks) + $(CIToolsPath)\tools true false diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Microsoft.Azure.Sdk.Build.Common.csproj b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Microsoft.Azure.Sdk.Build.Common.csproj new file mode 100644 index 000000000000..09f4dc9b3b81 --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Microsoft.Azure.Sdk.Build.Common.csproj @@ -0,0 +1,29 @@ + + + Microsoft.Azure.Sdk.Build.Common + Azure SDK build common + Microsoft.Azure.Sdk.Build.Common + Microsoft.Azure.Sdk.Build.Common + 1.0.0 + + + bin\$(Configuration)\ + + + ..\..\..\tasks + + + net46 + $(TaskBinaryOutput) + + + + + + + + + + + + \ No newline at end of file diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Models/Esrp/EsrpServiceModelBase.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Models/Esrp/EsrpServiceModelBase.cs new file mode 100644 index 000000000000..96eb7b5d8943 --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Models/Esrp/EsrpServiceModelBase.cs @@ -0,0 +1,86 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Microsoft.Azure.Sdk.Build.Common.Models.Esrp +{ + using Newtonsoft.Json; + using Newtonsoft.Json.Converters; + using System; + using System.Collections.Generic; + using System.Globalization; + using System.IO; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + + public class EsrpServiceModelBase where T: class + { + private static JsonSerializerSettings _esrpModelSerializerSetting; + private static JsonSerializerSettings _esrpModelDeSerializerSetting; + + protected static JsonSerializerSettings EsrpModelSerializerSetting + { + get + { + if (_esrpModelSerializerSetting == null) + { + _esrpModelSerializerSetting = new JsonSerializerSettings + { + MetadataPropertyHandling = MetadataPropertyHandling.Ignore, + DateParseHandling = DateParseHandling.None, + Converters = { + new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } + }, + }; + } + + return _esrpModelSerializerSetting; + } + + set + { + _esrpModelSerializerSetting = value; + } + } + + protected static JsonSerializerSettings EsrpModelDeSerializerSetting + { + get + { + if (_esrpModelSerializerSetting == null) + { + _esrpModelSerializerSetting = new JsonSerializerSettings + { + MetadataPropertyHandling = MetadataPropertyHandling.Ignore, + DateParseHandling = DateParseHandling.None, + Converters = { + new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } + }, + }; + } + + return _esrpModelDeSerializerSetting; + } + + set + { + _esrpModelDeSerializerSetting = value; + } + } + + public EsrpServiceModelBase() + { + + } + + + + public static T FromJson(string json) => JsonConvert.DeserializeObject(json, EsrpModelDeSerializerSetting); + + public static T FromJsonFile(string jsonFilePath) => FromJson(File.ReadAllText(jsonFilePath)); + + public string ToJson() => JsonConvert.SerializeObject(this, EsrpModelSerializerSetting); + + + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Models/Esrp/ScanFileRequest.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Models/Esrp/ScanFileRequest.cs new file mode 100644 index 000000000000..79e7417a6a1b --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Models/Esrp/ScanFileRequest.cs @@ -0,0 +1,79 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Microsoft.Azure.Sdk.Build.Common.Models.Esrp.Scan +{ + using Newtonsoft.Json; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + + + + public partial class ScanFileRequest : EsrpServiceModelBase + { + [JsonProperty("Version")] + public string Version { get; set; } + + [JsonProperty("ContextData")] + public ContextData ContextData { get; set; } + + [JsonProperty("DriEmail")] + public List DriEmail { get; set; } + + [JsonProperty("GroupId")] + public object GroupId { get; set; } + + [JsonProperty("CorrelationVector")] + public object CorrelationVector { get; set; } + + [JsonProperty("ScanBatches")] + public List ScanBatches { get; set; } + + + public ScanFileRequest() { } + + + } + + public partial class ContextData + { + [JsonProperty("mykey1")] + public string Mykey1 { get; set; } + + [JsonProperty("myKey2")] + public string MyKey2 { get; set; } + } + + public partial class ScanBatch + { + [JsonProperty("SourceLocationType")] + public string SourceLocationType { get; set; } + + [JsonProperty("SourceRootDirectory")] + public string SourceRootDirectory { get; set; } + + [JsonProperty("ScanRequestFiles")] + public List ScanRequestFiles { get; set; } + } + + public partial class ScanRequestFile + { + [JsonProperty("CustomerCorrelationId")] + public string CustomerCorrelationId { get; set; } + + [JsonProperty("SourceLocation")] + public string SourceLocation { get; set; } + + [JsonProperty("SizeInBytes")] + public long SizeInBytes { get; set; } + + [JsonProperty("HashType")] + public string HashType { get; set; } + + [JsonProperty("SourceHash")] + public string SourceHash { get; set; } + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Models/Esrp/ScanFileResponse.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Models/Esrp/ScanFileResponse.cs new file mode 100644 index 000000000000..b3cd1aaf29c5 --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Models/Esrp/ScanFileResponse.cs @@ -0,0 +1,68 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Microsoft.Azure.Sdk.Build.Common.Models.Esrp +{ + using Newtonsoft.Json; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + + public partial class ScanFileResponse : EsrpServiceModelBase + { + [JsonProperty("Version")] + public string Version { get; set; } + + [JsonProperty("EsrpClientSessionGuid")] + public string EsrpClientSessionGuid { get; set; } + + [JsonProperty("SubmissionResponses")] + public List SubmissionResponses { get; set; } + + public ScanFileResponse() { } + } + + public partial class SubmissionResponse + { + [JsonProperty("FileHash")] + public string FileHash { get; set; } + + [JsonProperty("FileHashType")] + public string FileHashType { get; set; } + + [JsonProperty("OperationId")] + public string OperationId { get; set; } + + [JsonProperty("CustomerCorrelationId")] + public string CustomerCorrelationId { get; set; } + + [JsonProperty("StatusCode", NullValueHandling = NullValueHandling.Ignore)] + public string StatusCode { get; set; } + + [JsonProperty("ErrorInfo")] + public ErrorInfo ErrorInfo { get; set; } + } + + public partial class ErrorInfo + { + [JsonProperty("code")] + public string Code { get; set; } + + [JsonProperty("details")] + public Details Details { get; set; } + + [JsonProperty("innerError")] + public ErrorInfo InnerError { get; set; } + } + + public partial class Details + { + [JsonProperty("clientId")] + public string ClientId { get; set; } + + [JsonProperty("keyCode")] + public string KeyCode { get; set; } + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Models/Esrp/SerializeExtensions.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Models/Esrp/SerializeExtensions.cs new file mode 100644 index 000000000000..4fd77109a479 --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Models/Esrp/SerializeExtensions.cs @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Microsoft.Azure.Sdk.Build.Common.Models.Esrp +{ + using Newtonsoft.Json; + using Newtonsoft.Json.Converters; + using System; + using System.Collections.Generic; + using System.Globalization; + using System.IO; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + //using Microsoft.Azure.Sdk.Build.Tasks.Models.Esrp.Scan; + //using Microsoft.Azure.Sdk.Build.Tasks.Models.Esrp.Sign; + using Microsoft.Azure.Sdk.Build.Common.Models.Esrp.Scan; + using Microsoft.Azure.Sdk.Build.Common.Models.Esrp.Sign; + public static class SerializeExtensions + { + + #region Sign + //public static SignRequest FromSignManifestJson(string json) => JsonConvert.DeserializeObject(json, SerializerConfig); + + //public static SignRequest FromSignManifestFile(string jsonFilePath) + //{ + // string fileContents = File.ReadAllText(jsonFilePath); + // return FromSignManifestJson(fileContents); + //} + + public static string ToSignJson(this SignRequest self) => JsonConvert.SerializeObject(self, SerializerConfig); + + #endregion + + + #region Scan + //public static ScanFileRequest FromJson(string json) => JsonConvert.DeserializeObject(json, SerializerConfig); + + + //public static ScanFileResponse FromJson(string json) => JsonConvert.DeserializeObject(json, QuickType.Converter.Settings); + + public static string ToScanJson(this ScanFileRequest self) => JsonConvert.SerializeObject(self, SerializerConfig); + + #endregion + + + public static readonly JsonSerializerSettings SerializerConfig = new JsonSerializerSettings + { + MetadataPropertyHandling = MetadataPropertyHandling.Ignore, + DateParseHandling = DateParseHandling.None, + Converters = { + new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } + }, + }; + + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Models/Esrp/SignRequest.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Models/Esrp/SignRequest.cs new file mode 100644 index 000000000000..3467ecc415f3 --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Models/Esrp/SignRequest.cs @@ -0,0 +1,200 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Microsoft.Azure.Sdk.Build.Common.Models.Esrp.Sign +{ + using Newtonsoft.Json; + using System.Collections.Generic; + + public class SignRequest : EsrpServiceModelBase + { + #region Properties + [JsonProperty("Version")] + public string Version { get; set; } + + [JsonProperty("ContextData")] + public ContextData ContextData { get; set; } + + [JsonProperty("DriEmail")] + public List DriEmail { get; set; } + + [JsonProperty("GroupId")] + public object GroupId { get; set; } + + [JsonProperty("CorrelationVector")] + public object CorrelationVector { get; set; } + + [JsonProperty("SignBatches")] + public List SignBatches { get; set; } + #endregion + + public SignRequest() + { + Version = ""; + ContextData = new ContextData(); + SignBatches = new List(); + + + } + + + private SignRequest CreateSampleRequest() + { + SignRequest signReq = new SignRequest(); + + signReq.Version = "1.0.0"; + signReq.ContextData = new ContextData(); + signReq.DriEmail = new List() { "abhishah@microsoft.com" }; + signReq.SignBatches = new List(); + + SignBatch sbatch = new SignBatch(); + sbatch.SourceLocationType = "UNC"; + sbatch.SourceRootDirectory = @"C:\signFiles\Input"; + sbatch.DestinationLocationType = "UNC"; + sbatch.DestinationRootDirectory = @"C:\signFiles\Output"; + + SignRequestFile srf = new SignRequestFile(); + srf.Name = "ClientRuntime.dll"; + srf.SourceLocation = @"InputFile\ClientRuntime.dll"; + srf.DestinationLocation = @"OutputFile\ClientRuntime.dll"; + srf.HashType = null; + srf.SizeInBytes = 0; + + sbatch.SignRequestFiles.Add(srf); + + Operation op = new Operation(); + op.KeyCode = "CodeSignTestCertSha2TestRoot"; + op.OperationCode = "Authenticode_SignTool6.2.9304_NPH"; + + sbatch.SigningInfo.Operations.Add(op); + + signReq.SignBatches.Add(sbatch); + + return signReq; + } + + //public SignRequest FromJson(string json) => JsonConvert.DeserializeObject(json, this.EsrpModelDeSerializerSetting); + + //public SignRequest FromJsonFile(string jsonFilePath) => FromJson(File.ReadAllText(jsonFilePath)); + + //public string ToJson() => JsonConvert.SerializeObject(this, this.EsrpModelSerializerSetting); + } + + public partial class ContextData + { + [JsonProperty("mykey1")] + public string Mykey1 { get; set; } + + [JsonProperty("myKey2")] + public string MyKey2 { get; set; } + } + + public partial class SignBatch + { + private string _sourceLocationType; + private string _destinationLocationType; + + const string DEFAULT_LOCATION_TYPE = "UNC"; + + + [JsonProperty("SourceLocationType")] + public string SourceLocationType + { + get + { + if(string.IsNullOrEmpty(_sourceLocationType)) + { + _sourceLocationType = DEFAULT_LOCATION_TYPE; + } + + return _sourceLocationType; + } + set { _sourceLocationType = value; } + } + + [JsonProperty("SourceRootDirectory")] + public string SourceRootDirectory { get; set; } + + [JsonProperty("DestinationLocationType")] + public string DestinationLocationType + { + get + { + if(string.IsNullOrEmpty(_destinationLocationType)) + { + _destinationLocationType = DEFAULT_LOCATION_TYPE; + } + + return _destinationLocationType; + } + set { _destinationLocationType = value; } + } + + [JsonProperty("DestinationRootDirectory")] + public string DestinationRootDirectory { get; set; } + + [JsonProperty("SignRequestFiles")] + public List SignRequestFiles { get; set; } + + [JsonProperty("SigningInfo")] + public SigningInfo SigningInfo { get; set; } + + public SignBatch() + { + SignRequestFiles = new List(); + + SigningInfo = new SigningInfo(); + } + } + + public partial class SignRequestFile + { + [JsonProperty("CustomerCorrelationId")] + public string CustomerCorrelationId { get; set; } + + [JsonProperty("SourceLocation")] + public string SourceLocation { get; set; } + + [JsonProperty("SourceHash")] + public string SourceHash { get; set; } + + [JsonProperty("HashType")] + public object HashType { get; set; } + + [JsonProperty("SizeInBytes")] + public long SizeInBytes { get; set; } + + [JsonProperty("Name")] + public string Name { get; set; } + + [JsonProperty("DestinationLocation")] + public string DestinationLocation { get; set; } + } + + public partial class SigningInfo + { + [JsonProperty("Operations")] + public List Operations { get; set; } + + public SigningInfo() + { + Operations = new List(); + } + } + + public partial class Operation + { + [JsonProperty("KeyCode")] + public string KeyCode { get; set; } + + [JsonProperty("OperationCode")] + public string OperationCode { get; set; } + + [JsonProperty("Parameters")] + public Parameters Parameters { get; set; } + } + + public partial class Parameters + { + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Models/Esrp/SignResponse.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Models/Esrp/SignResponse.cs new file mode 100644 index 000000000000..e5c29ecc0642 --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Models/Esrp/SignResponse.cs @@ -0,0 +1,100 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Microsoft.Azure.Sdk.Build.Common.Models.Esrp.Sign +{ + using Newtonsoft.Json; + using Newtonsoft.Json.Converters; + using System; + using System.Collections.Generic; + using System.Globalization; + using System.IO; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + + public class SignResponse : EsrpServiceModelBase + { + [JsonProperty("Version")] + public string Version { get; set; } + + [JsonProperty("EsrpClientSessionGuid")] + public string EsrpClientSessionGuid { get; set; } + + [JsonProperty("SubmissionResponses")] + public List SubmissionResponses { get; set; } + + + + public SignResponse() + { + + } + + public void UpdateSignRequestWithDefaults() + { + + } + + //public SignResponse FromJson(string json) => JsonConvert.DeserializeObject(json, this.EsrpModelDeSerializerSetting); + + //public SignResponse FromJsonFile(string jsonFilePath) => FromJson(File.ReadAllText(jsonFilePath)); + + //public string ToJson() => JsonConvert.SerializeObject(this, this.EsrpModelSerializerSetting); + + } + + public partial class SubmissionResponse + { + [JsonProperty("FilesStatusDetail")] + public List FilesStatusDetail { get; set; } + + [JsonProperty("OperationId")] + public string OperationId { get; set; } + + [JsonProperty("CustomerCorrelationId")] + public string CustomerCorrelationId { get; set; } + + [JsonProperty("StatusCode")] + public string StatusCode { get; set; } + + [JsonProperty("ErrorInfo")] + public ErrorInfo ErrorInfo { get; set; } + + [JsonProperty("CertificateThumbprint")] + public object CertificateThumbprint { get; set; } + } + + public partial class ErrorInfo + { + [JsonProperty("code")] + public string Code { get; set; } + + [JsonProperty("details")] + public Details Details { get; set; } + + [JsonProperty("innerError")] + public ErrorInfo InnerError { get; set; } + } + + public partial class Details + { + [JsonProperty("clientId")] + public string ClientId { get; set; } + + [JsonProperty("keyCode")] + public string KeyCode { get; set; } + } + + public partial class FilesStatusDetail + { + [JsonProperty("SourceHash")] + public string SourceHash { get; set; } + + [JsonProperty("HashType")] + public string HashType { get; set; } + + [JsonProperty("DestinationHash")] + public string DestinationHash { get; set; } + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Models/SdkProjectMetaData.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Models/SdkProjectMetaData.cs new file mode 100644 index 000000000000..b6d68408e6f6 --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Models/SdkProjectMetaData.cs @@ -0,0 +1,360 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Microsoft.Azure.Sdk.Build.Common.Tasks.Models +{ + using Microsoft.Build.Construction; + using Microsoft.Build.Evaluation; + using Microsoft.Build.Framework; + using Microsoft.Azure.Sdk.Build.Common.Utilities; + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + + public class SdkProjectMetaData + { + public TargetFrameworkMoniker FxMoniker { get; set; } + + public string FxMonikerString { get; set; } + public string FullProjectPath { get; set; } + + public string TargetOutputFullPath { get; set; } + + public bool IsTargetFxSupported { get; set; } + + public SdkProjctType ProjectType { get; set; } + + public ITaskItem ProjectTaskItem { get; set; } + + public SdkProjectMetaData() { } + + public Project MsBuildProject { get; set; } + + public bool IsProjectDataPlane { get; set; } + + public bool IsFxFullDesktopVersion { get; set; } + + public bool IsFxNetCore { get; set; } + + public bool IsNonSdkProject { get; set; } + + public List ProjectImports { get; set; } + + public SdkProjectMetaData(ITaskItem project, Project msbuildProject, TargetFrameworkMoniker fxMoniker, string fxMonikerString, string fullProjectPath, string targetOutputPath, bool isTargetFxSupported, SdkProjctType projectType = SdkProjctType.Sdk) + { + ProjectTaskItem = project; + FxMoniker = fxMoniker; + FullProjectPath = fullProjectPath; + IsTargetFxSupported = isTargetFxSupported; + ProjectType = projectType; + TargetOutputFullPath = targetOutputPath; + FxMonikerString = fxMonikerString; + MsBuildProject = msbuildProject; + } + + public SdkProjectMetaData(ITaskItem project, + Project msbuildProject, TargetFrameworkMoniker fxMoniker, string fxMonikerString, + string fullProjectPath, string targetOutputPath, bool isTargetFxSupported, + SdkProjctType projectType, + bool isProjectDataPlaneProject, + bool isNonSdkProject = true) + { + ProjectTaskItem = project; + FxMoniker = fxMoniker; + FullProjectPath = fullProjectPath; + IsTargetFxSupported = isTargetFxSupported; + ProjectType = projectType; + TargetOutputFullPath = targetOutputPath; + FxMonikerString = fxMonikerString; + MsBuildProject = msbuildProject; + IsProjectDataPlane = isProjectDataPlaneProject; + IsFxFullDesktopVersion = IsExpectedFxCategory(fxMoniker, TargetFxCategory.FullDesktop); + IsFxNetCore = IsExpectedFxCategory(fxMoniker, TargetFxCategory.NetCore); + IsNonSdkProject = isNonSdkProject; + } + + public SdkProjectMetaData(string fullProjectPath, TargetFrameworkMoniker priorityFxVersion = TargetFrameworkMoniker.net452) + { + if(!string.IsNullOrEmpty(fullProjectPath)) + { + try + { + if (ProjectCollection.GlobalProjectCollection.GetLoadedProjects(fullProjectPath).Count != 0) + { + MsBuildProject = ProjectCollection.GlobalProjectCollection.GetLoadedProjects(fullProjectPath).FirstOrDefault(); + } + else + { + MsBuildProject = new Project(fullProjectPath); + } + } + catch(Exception ex) + { + + } + + if(MsBuildProject != null) + { + FxMoniker = GetTargetFramework(MsBuildProject, priorityFxVersion); + FxMonikerString = GetFxMonikerString(priorityFxVersion); + ProjectTaskItem = new Microsoft.Build.Utilities.TaskItem(fullProjectPath); + FullProjectPath = fullProjectPath; + TargetOutputFullPath = GetTargetFullPath(MsBuildProject, FxMonikerString); + ProjectType = GetProjectType(MsBuildProject); + IsTargetFxSupported = IsFxSupported(FxMonikerString); + IsProjectDataPlane = IsDataPlaneProject(MsBuildProject); + IsFxFullDesktopVersion = IsExpectedFxCategory(FxMoniker, TargetFxCategory.FullDesktop); + IsFxNetCore = IsExpectedFxCategory(FxMoniker, TargetFxCategory.NetCore); + ProjectImports = GetProjectImports(MsBuildProject); + } + } + } + + private List GetProjectImports(Project msbuildProj) + { + string rpProps = Constants.BuildStageConstant.PROPS_APITAG_FILE_NAME; + string multiApiProps = Constants.BuildStageConstant.PROPS_MULTIAPITAG_FILE_NAME; + //$([MSBuild]::GetPathOfFileAbove('AzSdk.RP.props')) + List importList = new List(); + ProjectRootElement rootElm = msbuildProj.Xml; + ICollection importElms = rootElm.Imports; + + foreach (ProjectImportElement imp in importElms) + { + if (imp.Project.Contains(rpProps)) + { + importList.Add(rpProps); + } + + if (imp.Project.Contains(multiApiProps)) + { + importList.Add(multiApiProps); + } + } + + return importList; + } + + private TargetFrameworkMoniker GetTargetFramework(Project msBuildProj, TargetFrameworkMoniker priorityFxVersion) + { + TargetFrameworkMoniker moniker = TargetFrameworkMoniker.UnSupported; + string targetFxList = msBuildProj.GetPropertyValue("TargetFrameworks"); + if (string.IsNullOrEmpty(targetFxList)) + { + targetFxList = msBuildProj.GetPropertyValue("TargetFramework"); + } + + var fxNames = targetFxList?.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)?.ToList(); + foreach (string fx in fxNames) + { + moniker = GetFxMoniker(fx); + if(moniker.Equals(priorityFxVersion)) + { + break; + } + } + + return moniker; + } + + private bool IsDataPlaneProject(Project msBuildProject) + { + bool isDataPlane = false; + if(msBuildProject.FullPath.ToLower().Contains("dataplane")) + { + isDataPlane = true; + string packageId = msBuildProject.GetPropertyValue("PackageId"); + if (packageId.ToLower().Contains("management")) + { + isDataPlane = false; + } + } + + return isDataPlane; + } + + private string GetTargetFullPath(Project sdkProj, string targetFxMoniker) + { + string projOutputPath = sdkProj.GetPropertyValue("OutputPath"); + string outputType = sdkProj.GetPropertyValue("OutputType"); + string asmName = sdkProj.GetPropertyValue("AssemblyName"); + string projDirPath = Path.GetDirectoryName(sdkProj.FullPath); + string fullTargetPath = string.Empty; + + if (outputType.Equals("Library", StringComparison.OrdinalIgnoreCase)) + { + fullTargetPath = Path.Combine(projDirPath, projOutputPath, targetFxMoniker, String.Concat(asmName, ".dll")); + } + + return fullTargetPath; + } + + public string GetFxMonikerString(TargetFrameworkMoniker fxMoniker) + { + string monikerString = string.Empty; + switch (fxMoniker) + { + case TargetFrameworkMoniker.net452: + monikerString = "net452"; + break; + + case TargetFrameworkMoniker.netcoreapp11: + monikerString = "netcoreapp1.1"; + break; + + case TargetFrameworkMoniker.netstandard14: + monikerString = "netstandard1.4"; + break; + + case TargetFrameworkMoniker.net46: + monikerString = "net46"; + break; + + case TargetFrameworkMoniker.net461: + monikerString = "net461"; + break; + } + + return monikerString; + } + + public bool IsExpectedFxCategory(TargetFrameworkMoniker targetFxMoniker, TargetFxCategory expectedFxCategory) + { + bool expectedFxCat = false; + switch (targetFxMoniker) + { + case TargetFrameworkMoniker.net452: + case TargetFrameworkMoniker.net46: + case TargetFrameworkMoniker.net461: + expectedFxCat = (expectedFxCategory == TargetFxCategory.FullDesktop); + break; + + case TargetFrameworkMoniker.netcoreapp11: + case TargetFrameworkMoniker.netstandard14: + expectedFxCat = (expectedFxCategory == TargetFxCategory.NetCore); + break; + } + + return expectedFxCat; + } + + public SdkProjctType GetProjectType(Project msbuildProj) + { + SdkProjctType pType = SdkProjctType.Sdk; + ICollection pkgs = msbuildProj.GetItemsIgnoringCondition("PackageReference"); + if (pkgs.Any()) + { + var testReference = pkgs.Where((p) => p.EvaluatedInclude.Equals("xunit", StringComparison.OrdinalIgnoreCase)); + if (testReference.Any()) + { + pType = SdkProjctType.Test; + } + else + { + pType = SdkProjctType.Sdk; + } + } + + return pType; + } + + private bool IsFxSupported(string fxMoniker) + { + string lcMoniker = fxMoniker.ToLower(); + bool fxSupported = false; + TargetFrameworkMoniker validMoniker = TargetFrameworkMoniker.UnSupported; + switch (lcMoniker) + { + case "net452": + validMoniker = TargetFrameworkMoniker.net452; + fxSupported = true; + break; + + case "netcoreapp1.1": + validMoniker = TargetFrameworkMoniker.netcoreapp11; + fxSupported = true; + break; + + case "netstandard1.4": + validMoniker = TargetFrameworkMoniker.netstandard14; + fxSupported = true; + break; + + case "net46": + validMoniker = TargetFrameworkMoniker.net46; + fxSupported = false; + break; + + case "net461": + validMoniker = TargetFrameworkMoniker.net461; + fxSupported = true; + break; + default: + validMoniker = TargetFrameworkMoniker.UnSupported; + fxSupported = false; + break; + } + + //targetFx = validMoniker; + return fxSupported; + } + + private TargetFrameworkMoniker GetFxMoniker(string fx) + { + string lcMoniker = fx.ToLower(); + TargetFrameworkMoniker validMoniker = TargetFrameworkMoniker.UnSupported; + switch (lcMoniker) + { + case "net452": + validMoniker = TargetFrameworkMoniker.net452; + break; + + case "netcoreapp1.1": + validMoniker = TargetFrameworkMoniker.netcoreapp11; + break; + + case "netstandard1.4": + validMoniker = TargetFrameworkMoniker.netstandard14; + break; + + case "net46": + validMoniker = TargetFrameworkMoniker.net46; + break; + + case "net461": + validMoniker = TargetFrameworkMoniker.net461; + break; + default: + validMoniker = TargetFrameworkMoniker.UnSupported; + break; + } + + return validMoniker; + } + + } + + public enum TargetFrameworkMoniker + { + net45, + net452, + net46, + net461, + netcoreapp11, + netstandard14, + UnSupported + } + + public enum TargetFxCategory + { + FullDesktop, + NetCore + } + + public enum SdkProjctType + { + Sdk, + Test + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Utilities/Constants.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Utilities/Constants.cs new file mode 100644 index 000000000000..eb5a93e29dd0 --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Build.Common/Utilities/Constants.cs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Microsoft.Azure.Sdk.Build.Common.Utilities +{ + /// + /// Constants used within the Build.Tasks library + /// + static class Constants + { + + /// + /// Constants, defaults used for Nuget Publish task + /// + public static class NugetDefaults + { + public const string NUGET_PATH = "nuget.exe"; + public const string NUGET_PUBLISH_URL = "https://www.nuget.org/api/v2/package/"; + public const string NUGET_SYMBOL_PUBLISH_URL = "https://nuget.smbsrc.net"; + public const int NUGET_TIMEOUT = 60; //Seconds + public const string DEFAULT_API_KEY = "1234"; + public const string SDK_NUGET_APIKEY_ENV = "NetSdkNugetApiKey"; + } + + /// + /// Constants used for various build stage tasks + /// + internal static class BuildStageConstant + { + public const string API_TAG_PROPERTYNAME = "AzureApiTag"; + public const string PROPS_APITAG_FILE_NAME = "AzSdk.RP.props"; + public const string PROPS_MULTIAPITAG_FILE_NAME = "AzSdk.MultiApi.RP.props"; + public const string APIMAPTYPENAMETOSEARCH = "SdkInfo"; + public const string PROPERTYNAMEPREFIX = "ApiInfo_"; + } + + internal static class FrameworkMonikerConstant + { + // Switch to Attributes on enums for description + public static string Net452 = "net452"; + public static string NetStd14 = "netstandard1.4"; + } + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/BaseTasks/NetSdkTask.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/BaseTasks/NetSdkTask.cs index 9571c3341cde..eeb028806325 100644 --- a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/BaseTasks/NetSdkTask.cs +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/BaseTasks/NetSdkTask.cs @@ -12,7 +12,7 @@ public abstract class NetSdkTask : Task, INetSdkTask { NetSdkTaskLogger _taskLogger; string _netSdkTaskName; - public bool DebugTrace { get; set; } + public bool DebugTraceEnabled { get; set; } public string BuildScope { get; set; } @@ -30,7 +30,7 @@ internal virtual NetSdkTaskLogger TaskLogger { if(_taskLogger == null) { - _taskLogger = new NetSdkTaskLogger(TaskInstance, DebugTrace); + _taskLogger = new NetSdkTaskLogger(TaskInstance, DebugTraceEnabled); } return _taskLogger; diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/BaseTasks/TaskData.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/BaseTasks/TaskData.cs index e13fb62af9f1..1c6c9e479cd1 100644 --- a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/BaseTasks/TaskData.cs +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/BaseTasks/TaskData.cs @@ -49,7 +49,9 @@ public static List FilterCategorizedProjects(ITaskItem[] fil IEnumerable distinctList = new List(); if (CategorizedProjects != null) { - var filtered = CategorizedProjects.Where((cat) => filterProjectOn.Any((fil) => fil.ItemSpec.Equals(cat.FullProjectPath, StringComparison.OrdinalIgnoreCase))); + //var filtered = CategorizedProjects.Where((cat) => filterProjectOn.Any((fil) => fil.ItemSpec.Equals(cat.FullProjectPath, StringComparison.OrdinalIgnoreCase))); + + List filtered = GetSdkProjects(filterProjectOn); if (filterSdkProjectsOnly == true) { @@ -66,5 +68,17 @@ public static List FilterCategorizedProjects(ITaskItem[] fil return distinctList?.ToList(); } + + public static List GetSdkProjects(ITaskItem[] sdkProjects) + { + List returnedList = new List(); + if (CategorizedProjects != null) + { + var filtered = CategorizedProjects.Where((cat) => sdkProjects.Any((fil) => fil.ItemSpec.Equals(cat.FullProjectPath, StringComparison.OrdinalIgnoreCase))); + returnedList = filtered.ToList(); + } + + return returnedList; + } } } diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/BuildStages/PostBuild/PreSignTask.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/BuildStages/PostBuild/PreSignTask.cs new file mode 100644 index 000000000000..e3d04d83b26b --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/BuildStages/PostBuild/PreSignTask.cs @@ -0,0 +1,334 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Microsoft.Azure.Sdk.Build.Tasks.BuildStages.PostBuild +{ + using Microsoft.Azure.Sdk.Build.Tasks.BaseTasks; + using Microsoft.Azure.Sdk.Build.Tasks.Models; + using Microsoft.Azure.Sdk.Build.Tasks.Models.Esrp.Sign; + using Microsoft.Build.Framework; + using Microsoft.WindowsAzure.Build.Tasks.Utilities; + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + + public class PreSignTask : NetSdkTask + { + protected override INetSdkTask TaskInstance { get => this; } + + public override string NetSdkTaskName => "PreSignTask"; + + public bool DebugTrace { get; set; } + + #region Input + + public string InSignBuildName { get; set; } + public ITaskItem[] InSdkProjects { get; set; } + + [Required] + public string InNugetPackageRootDir { get; set; } + /// + /// Space delimited extension list including . char + /// e.g. .nupkg .dll + /// + [Required] + public string InSearchExtensionToSearch { get; set; } + + /// + /// Root directory path where files will be searched for + /// provided space separated extension list + /// + [Required] + public string InSignedFilesRootDirPath { get; set; } + + /// + /// List of full file path that needs to be signed + /// + public string[] InFilesToSignWithFullPath { get; set; } + + /// + /// Root directory for creating manifest files needed for signing service + /// + //[Required] + public string InSignManifestDirPath { get; set; } + + /// + /// Possible values + /// 1) nuget + /// more types will be added + /// + [Required] + public string InSigningOperation { get; set; } + + #endregion + + #region output + [Output] + public string[] OutSignManifestFiles { get; set; } + #endregion + + + #region private internal fields + //List FinalFileListToBeSigned { get; set; } + + List SignFileListFromProjects { get; set; } + + List SignFileListFromFullPath { get; set; } + + List SignFileListFromRootDir { get; set; } + + #endregion + + + public PreSignTask() + { + DebugTraceEnabled = DebugTrace; + + SignFileListFromProjects = new List(); + SignFileListFromFullPath = new List(); + SignFileListFromRootDir = new List(); + } + + + public override bool Execute() + { + InitFileList(); + List manifestFiles = GenerateManifestFiles(); + if(manifestFiles.Any()) + { + OutSignManifestFiles = manifestFiles.ToArray(); + } + + return true; + } + + private List GenerateManifestFiles() + { + List manifestFileList = new List(); + + if(SignFileListFromProjects.Count > 0) + { + SignRequest projSignReq = CreateSignRequestModel(SignFileListFromProjects, @"bin\"); + if(projSignReq != null) + { + manifestFileList.Add(projSignReq.ToJsonFile(Path.Combine(InSignManifestDirPath, Constants.SigningConstants.SigningsProjectsManifestFileName))); + } + } + + if (SignFileListFromRootDir.Count > 0) + { + SignRequest projSignReq = CreateSignRequestModel(SignFileListFromRootDir, InSignedFilesRootDirPath); + if (projSignReq != null) + { + manifestFileList.Add(projSignReq.ToJsonFile(Path.Combine(InSignManifestDirPath, Constants.SigningConstants.SigningsRootDirFilesManifestFileName))); + } + } + + return manifestFileList; + //OutSignManifestFiles = manifestFileList.ToArray(); + } + + + + private void InitFileList() + { + #region From Projects + // Build File list from projects that got built + if(InSdkProjects != null) + { + if (InSdkProjects.Any()) + { + List filteredProjects = TaskData.GetSdkProjects(InSdkProjects); + + foreach (SdkProjectMetaData sdkProj in filteredProjects) + { + SignFileListFromProjects.Add(sdkProj.TargetOutputFullPath); + } + } + } + + #endregion + + #region FullPath File list + // Build file list from provided file list + + if (InFilesToSignWithFullPath != null) + { + if (InFilesToSignWithFullPath.Any()) + { + SignFileListFromFullPath.AddRange(InFilesToSignWithFullPath); + } + } + #endregion + + #region from root directory and searching providing file extensions + // Build file list from provided root directory and file extension + // this will include search for list of files with expected file extensions in the root directory + + if(string.IsNullOrEmpty(InSignedFilesRootDirPath)) + { + this.TaskLogger.LogDebugInfo("'SignedFilesRootDirPath' Provided directory path is empty"); + } + else + { + if(!Directory.Exists(InSignedFilesRootDirPath)) + { + this.TaskLogger.LogDebugInfo("Provided directory root '{0}' does not exists, files from the provided will be skipped", InSignedFilesRootDirPath); + } + else + { + char[] extSplitToken = new char[] { ' ' }; + string[] fileExt = InSearchExtensionToSearch.Split(extSplitToken, StringSplitOptions.RemoveEmptyEntries); + + List searchedFiles = new List(); + foreach (string extToSearch in fileExt) + { + string searchPattern = string.Concat("*", extToSearch); + var enumFiles = Directory.EnumerateFiles(InSignedFilesRootDirPath, searchPattern, SearchOption.AllDirectories); + if(enumFiles.Any()) + { + searchedFiles.AddRange(enumFiles.ToList()); + } + } + + if(searchedFiles != null) + { + if(searchedFiles.Any()) + { + SignFileListFromRootDir.AddRange(searchedFiles); + } + } + } + } + + #endregion + } + + private SignRequest CreateSignRequestModel(List fileList, string rootDirSplitToken) + { + if(Directory.Exists(rootDirSplitToken)) + { + DirectoryInfo dInfo = new DirectoryInfo(rootDirSplitToken); + + // We do this in order to get trailing directory separator character + rootDirSplitToken = Path.Combine(dInfo.Name, " ").Trim(); + } + + //TODO: guard against empty rootDirSplitToken + string[] pathSplitToken = new string[] { rootDirSplitToken }; + + Dictionary signBatchDictionary = new Dictionary(); + SignRequest signReq = null; + + foreach (string signFilePath in fileList) + { + string[] fileSplitPaths = signFilePath.Split(pathSplitToken, StringSplitOptions.RemoveEmptyEntries); + + if (fileSplitPaths != null) + { + if (fileSplitPaths.Length >= 2) + { + fileSplitPaths[0] = Path.Combine(fileSplitPaths[0], rootDirSplitToken); + if (!signBatchDictionary.ContainsKey(fileSplitPaths[0])) + { + SignBatch signBatch = new SignBatch(); + signBatch.SourceRootDirectory = fileSplitPaths[0]; + signBatch.DestinationRootDirectory = fileSplitPaths[0]; + + SignRequestFile srf = new SignRequestFile(); + srf.Name = Path.GetFileName(signFilePath); + srf.SourceLocation = fileSplitPaths[1]; + srf.DestinationLocation = fileSplitPaths[1]; + + signBatch.SignRequestFiles.Add(srf); + signBatchDictionary.Add(fileSplitPaths[0], signBatch); + + //TODO: Identify signingInfo from provided files, do not depend supplied property (InSigningOperation) + signBatch.SigningInfo = CreateSigningInfo(InSigningOperation); + } + else + { + if (signBatchDictionary.TryGetValue(fileSplitPaths[0], out SignBatch sb)) + { + SignRequestFile srf = new SignRequestFile(); + srf.Name = Path.GetFileName(signFilePath); + srf.SourceLocation = fileSplitPaths[1]; + srf.DestinationLocation = fileSplitPaths[1]; + sb.SignRequestFiles.Add(srf); + + signBatchDictionary[fileSplitPaths[0]] = sb; + } + } + } + } + } + + foreach (KeyValuePair sbKeyVal in signBatchDictionary) + { + if (signReq == null) + { + signReq = new SignRequest(InSignBuildName); + signReq.SignBatches.Add(sbKeyVal.Value); + } + else + { + signReq.SignBatches.Add(sbKeyVal.Value); + } + } + + return signReq; + } + + + private SigningInfo CreateSigningInfo(string signingOperationType) + { + SigningInfo signInfo = new SigningInfo(); + if(signingOperationType != null) + { + if (signingOperationType.Equals("nuget", StringComparison.OrdinalIgnoreCase)) + { + Operation signOp = new Operation(); + signOp.KeyCode = "CP-401405"; + signOp.OperationCode = "NuGetSign"; + signOp.ToolName = "sign"; + signOp.ToolVersion = "1.0"; + signOp.Parameters = new Parameters(); + + Operation signVerifyOp = new Operation(); + signVerifyOp.KeyCode = "CP-401405"; + signVerifyOp.OperationCode = "NuGetVerify"; + signVerifyOp.ToolName = "sign"; + signVerifyOp.ToolVersion = "1.0"; + signVerifyOp.Parameters = new Parameters(); + + signInfo.Operations.Add(signOp); + signInfo.Operations.Add(signVerifyOp); + } + } + + return signInfo; + } + + /* + {Microsoft.Azure.Sdk.Build.Tasks.Models.SdkProjectMetaData} + FullProjectPath: "D:\\myFork\\netSdkBuild\\src\\SDKs\\Compute\\Management.Compute\\Microsoft.Azure.Management.Compute.csproj" + FxMoniker: net452 + FxMonikerString: "net452" + IsFxFullDesktopVersion: true + IsFxNetCore: false + IsNonSdkProject: false + IsProjectDataPlane: false + IsTargetFxSupported: true + MsBuildProject: "D:\\myFork\\netSdkBuild\\src\\SDKs\\Compute\\Management.Compute\\Microsoft.Azure.Management.Compute.csproj" + EffectiveToolsVersion="15.0" #GlobalProperties=0 #Properties=288 #ItemTypes=4 #ItemDefinitions=0 #Items=64 #Targets=45 + ProjectImports: Count = 1 + ProjectTaskItem: {Microsoft.Build.Utilities.TaskItem} + ProjectType: Sdk + TargetOutputFullPath: "D:\\myFork\\netSdkBuild\\src\\SDKs\\Compute\\Management.Compute\\bin\\Debug\\net452\\Microsoft.Azure.Management.Compute.dll" + */ + + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/BuildStages/PostBuild/SignNugetTask.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/BuildStages/PostBuild/SignNugetTask.cs new file mode 100644 index 000000000000..eaa5ab9cdb6d --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/BuildStages/PostBuild/SignNugetTask.cs @@ -0,0 +1,304 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Microsoft.Azure.Sdk.Build.Tasks.BuildStages.PostBuild +{ + using Microsoft.Azure.Sdk.Build.ExecProcess; + using Microsoft.Azure.Sdk.Build.Tasks.BaseTasks; + using Microsoft.Azure.Sdk.Build.Tasks.Models.Esrp.Sign; + using Microsoft.Azure.Sdk.Build.Tasks.Utilities; + using Microsoft.Build.Framework; + using Microsoft.WindowsAzure.Build.Tasks.Utilities; + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + + public class SignNugetTask : NetSdkTask + { + + protected override INetSdkTask TaskInstance { get => this; } + + public override string NetSdkTaskName => "PreSignTask"; + + public bool DebugTrace { get; set; } + + #region Input + [Required] + public string InNugetPackageRootDir { get; set; } + /// + /// Space delimited extension list including . char + /// e.g. .nupkg .dll + /// + [Required] + public string InSearchExtensionToSearch { get; set; } + + /// + /// Root directory path where files will be searched for + /// provided space separated extension list + /// + [Required] + public string InSignedFilesRootDirPath { get; set; } + + /// + /// List of full file path that needs to be signed + /// + //public string[] InFilesToSignWithFullPath { get; set; } + + /// + /// Root directory for creating manifest files needed for signing service + /// + [Required] + public string InSignManifestDirPath { get; set; } + + [Required] + public string InSignBuildName { get; set; } + + [Required] + public string CiToolsRootDir { get; set; } + + /// + /// Possible values + /// 1) nuget + /// more types will be added + /// + [Required] + public string InSigningOperation { get; set; } + +#endregion + + #region output + [Output] + public string[] OutSignManifestFiles { get; set; } + #endregion + + + #region private internal fields + List SignFileListFromProjects { get; set; } + + List SignFileListFromFullPath { get; set; } + + List SignFileListFromRootDir { get; set; } + + #endregion + + public SignNugetTask() + { + DebugTraceEnabled = DebugTrace; + + SignFileListFromProjects = new List(); + SignFileListFromFullPath = new List(); + SignFileListFromRootDir = new List(); + } + + public override bool Execute() + { + List manifestList = GenerateManifestFiles(); + + if (manifestList.Count == 0) + { + TaskLogger.LogError("No manifest files were generated. Exiting Signing"); + } + + SignClientExec signClient = new SignClientExec(); + signClient.CiToolsRootDir = CiToolsRootDir; + signClient.SigningInputManifestFilePath = manifestList.First(); + + Check.FileExists(signClient.SigningInputManifestFilePath); + + string sf = signClient.SigningInputManifestFilePath; + string signOutputFilePath = Path.Combine(Path.GetDirectoryName(sf), String.Concat(Path.GetFileNameWithoutExtension(sf), "_output", ".json")); + signClient.SigningResultOutputFilePath = signOutputFilePath; + + TaskLogger.LogInfo("Submitting for nuget signing. This might take several minutes."); + int exitCode = signClient.ExecuteCommand(); + + if(exitCode != 0) + { + string signTaskOutput = signClient.AnalyzeExitCode(); + this.TaskLogger.LogInfo(signTaskOutput); + } + else + { + TaskLogger.LogInfo("Nuget signing completed successfully"); + } + + return true; + } + + #region Create Manifest + private void InitFileList() + { + + #region from root directory and searching providing file extensions + // Build file list from provided root directory and file extension + // this will include search for list of files with expected file extensions in the root directory + + if (string.IsNullOrEmpty(InSignedFilesRootDirPath)) + { + this.TaskLogger.LogDebugInfo("'SignedFilesRootDirPath' Provided directory path is empty"); + } + else + { + if (!Directory.Exists(InSignedFilesRootDirPath)) + { + this.TaskLogger.LogDebugInfo("Provided directory root '{0}' does not exists, files from the provided will be skipped", InSignedFilesRootDirPath); + } + else + { + char[] extSplitToken = new char[] { ' ' }; + string[] fileExt = InSearchExtensionToSearch.Split(extSplitToken, StringSplitOptions.RemoveEmptyEntries); + + List searchedFiles = new List(); + foreach (string extToSearch in fileExt) + { + string searchPattern = string.Concat("*", extToSearch); + var enumFiles = Directory.EnumerateFiles(InSignedFilesRootDirPath, searchPattern, SearchOption.AllDirectories); + if (enumFiles.Any()) + { + searchedFiles.AddRange(enumFiles.ToList()); + } + } + + if (searchedFiles != null) + { + if (searchedFiles.Any()) + { + SignFileListFromRootDir.AddRange(searchedFiles); + } + } + } + } + + #endregion + } + + private List GenerateManifestFiles() + { + InitFileList(); + + List manifestFileList = new List(); + + if (SignFileListFromRootDir.Count > 0) + { + SignRequest projSignReq = CreateSignRequestModel(SignFileListFromRootDir, InSignedFilesRootDirPath); + if (projSignReq != null) + { + manifestFileList.Add(projSignReq.ToJsonFile(Path.Combine(InSignManifestDirPath, Constants.SigningConstants.SigningsRootDirFilesManifestFileName))); + } + } + + + return manifestFileList; + } + + + private SignRequest CreateSignRequestModel(List fileList, string rootDirSplitToken) + { + if (Directory.Exists(rootDirSplitToken)) + { + DirectoryInfo dInfo = new DirectoryInfo(rootDirSplitToken); + + // We do this in order to get trailing directory separator character + rootDirSplitToken = Path.Combine(dInfo.Name, " ").Trim(); + } + + //TODO: guard against empty rootDirSplitToken + string[] pathSplitToken = new string[] { rootDirSplitToken }; + + Dictionary signBatchDictionary = new Dictionary(); + SignRequest signReq = null; + + foreach (string signFilePath in fileList) + { + TaskLogger.LogDebugInfo("Adding '{0}' to the signing manifest", signFilePath); + string[] fileSplitPaths = signFilePath.Split(pathSplitToken, StringSplitOptions.RemoveEmptyEntries); + + if (fileSplitPaths != null) + { + if (fileSplitPaths.Length >= 2) + { + fileSplitPaths[0] = Path.Combine(fileSplitPaths[0], rootDirSplitToken); + if (!signBatchDictionary.ContainsKey(fileSplitPaths[0])) + { + SignBatch signBatch = new SignBatch(); + signBatch.SourceRootDirectory = fileSplitPaths[0]; + signBatch.DestinationRootDirectory = fileSplitPaths[0]; + + SignRequestFile srf = new SignRequestFile(); + srf.Name = Path.GetFileName(signFilePath); + srf.SourceLocation = fileSplitPaths[1]; + srf.DestinationLocation = fileSplitPaths[1]; + + signBatch.SignRequestFiles.Add(srf); + signBatchDictionary.Add(fileSplitPaths[0], signBatch); + + //TODO: Identify signingInfo from provided files, do not depend supplied property (InSigningOperation) + signBatch.SigningInfo = CreateSigningInfo(InSigningOperation); + } + else + { + if (signBatchDictionary.TryGetValue(fileSplitPaths[0], out SignBatch sb)) + { + SignRequestFile srf = new SignRequestFile(); + srf.Name = Path.GetFileName(signFilePath); + srf.SourceLocation = fileSplitPaths[1]; + srf.DestinationLocation = fileSplitPaths[1]; + sb.SignRequestFiles.Add(srf); + + signBatchDictionary[fileSplitPaths[0]] = sb; + } + } + } + } + } + + foreach (KeyValuePair sbKeyVal in signBatchDictionary) + { + if (signReq == null) + { + signReq = new SignRequest(InSignBuildName); + signReq.SignBatches.Add(sbKeyVal.Value); + } + else + { + signReq.SignBatches.Add(sbKeyVal.Value); + } + } + + return signReq; + } + + + private SigningInfo CreateSigningInfo(string signingOperationType) + { + SigningInfo signInfo = new SigningInfo(); + if (signingOperationType != null) + { + if (signingOperationType.Equals("nuget", StringComparison.OrdinalIgnoreCase)) + { + Operation signOp = new Operation(); + signOp.KeyCode = "CP-401405"; + signOp.OperationCode = "NuGetSign"; + signOp.ToolName = "sign"; + signOp.ToolVersion = "1.0"; + signOp.Parameters = new Parameters(); + + Operation signVerifyOp = new Operation(); + signVerifyOp.KeyCode = "CP-401405"; + signVerifyOp.OperationCode = "NuGetVerify"; + signVerifyOp.ToolName = "sign"; + signVerifyOp.ToolVersion = "1.0"; + signVerifyOp.Parameters = new Parameters(); + + signInfo.Operations.Add(signOp); + signInfo.Operations.Add(signVerifyOp); + } + } + + return signInfo; + } + #endregion + + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/BuildStages/PostBuildTask.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/BuildStages/PostBuildTask.cs index e5294b532d97..c31c55d4da5c 100644 --- a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/BuildStages/PostBuildTask.cs +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/BuildStages/PostBuildTask.cs @@ -52,7 +52,7 @@ public class PostBuildTask : NetSdkTask public PostBuildTask() { - DebugTrace = EnableDebugTrace; + DebugTraceEnabled = EnableDebugTrace; } public override bool Execute() @@ -160,7 +160,7 @@ private IEnumerable> GetApiMapUsingReflection(stri } else { - sdkInfoTypes = sdkAsm.GetTypes().Where((t) => t.Name.Equals(FQTypeName, StringComparison.OrdinalIgnoreCase)); + sdkInfoTypes = sdkAsm.GetTypes().Where((t) => t.FullName.Equals(FQTypeName, StringComparison.OrdinalIgnoreCase)); } foreach(Type sdkInfo in sdkInfoTypes) diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/BuildStages/PreBuildTask.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/BuildStages/PreBuildTask.cs index ecac32101488..686759a9681f 100644 --- a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/BuildStages/PreBuildTask.cs +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/BuildStages/PreBuildTask.cs @@ -38,7 +38,7 @@ public class PreBuildTask : NetSdkTask public PreBuildTask() { - DebugTrace = EnableDebugTrace; + DebugTraceEnabled = EnableDebugTrace; } public override bool Execute() { diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/ExecProcess/NugetExec.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/ExecProcess/NugetExec.cs index d0344f4d230a..be2aa3a0fc39 100644 --- a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/ExecProcess/NugetExec.cs +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/ExecProcess/NugetExec.cs @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. -namespace Microsoft.WindowsAzure.Build.Tasks.ExecProcess +//namespace Microsoft.WindowsAzure.Build.Tasks.ExecProcess +namespace Microsoft.Azure.Sdk.Build.ExecProcess { using Microsoft.WindowsAzure.Build.Tasks.Utilities; using System; diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/ExecProcess/ShellExec.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/ExecProcess/ShellExec.cs index 5721d79c4179..4ee445f6dd64 100644 --- a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/ExecProcess/ShellExec.cs +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/ExecProcess/ShellExec.cs @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. -namespace Microsoft.WindowsAzure.Build.Tasks.ExecProcess +//namespace Microsoft.WindowsAzure.Build.Tasks.ExecProcess +namespace Microsoft.Azure.Sdk.Build.ExecProcess { using System; using System.ComponentModel; @@ -11,23 +12,54 @@ namespace Microsoft.WindowsAzure.Build.Tasks.ExecProcess public class ShellExec { #region CONST - const int DEFAULT_WAIT_TIMEOUT = 60000; // 60 seconds default timeout + const int DEFAULT_WAIT_TIMEOUT = 240000; // 60 seconds default timeout //const string COMMAND_ARGS = "push {0} -source {1} -ApiKey {2} -NonInteractive -Timeout {3}"; const int E_FAIL = -2147467259; const int ERROR_FILE_NOT_FOUND = 2; #endregion - - + #region Fields Process _shellProc; - + ProcessStartInfo _shellProcStartInfo; + string _shellProcCommandPath; + #endregion protected int LastExitCode { get; set; } protected Exception LastException { get; set; } + protected virtual string ShellProcessCommandPath + { + get => _shellProcCommandPath; + set => _shellProcCommandPath = value; + } + + protected virtual int DefaultTimeOut + { + get => DEFAULT_WAIT_TIMEOUT; + } + + public virtual ProcessStartInfo ShellProcessInfo + { + get + { + if (_shellProcStartInfo == null) + { + _shellProcStartInfo = new ProcessStartInfo(ShellProcessCommandPath); + _shellProcStartInfo.CreateNoWindow = true; + _shellProcStartInfo.UseShellExecute = false; + _shellProcStartInfo.RedirectStandardError = true; + _shellProcStartInfo.RedirectStandardInput = true; + _shellProcStartInfo.RedirectStandardOutput = true; + } + + return _shellProcStartInfo; + } + } + + /// /// /// @@ -36,25 +68,33 @@ public Process ShellProcess get { if (_shellProc == null) + { _shellProc = new Process(); - + _shellProc.StartInfo = ShellProcessInfo; + } + return _shellProc; } } protected ShellExec() { + _shellProcCommandPath = string.Empty; } public ShellExec(string commandPath): this() - { - ProcessStartInfo procInfo = new ProcessStartInfo(commandPath); - procInfo.CreateNoWindow = true; - procInfo.UseShellExecute = false; - procInfo.RedirectStandardError = true; - procInfo.RedirectStandardInput = true; - procInfo.RedirectStandardOutput = true; - ShellProcess.StartInfo = procInfo; + { + ShellProcessCommandPath = commandPath; + } + + protected virtual string BuildShellProcessArgs() + { + throw new NotImplementedException(); + } + + public virtual int ExecuteCommand() + { + return ExecuteCommand(BuildShellProcessArgs()); } public virtual int ExecuteCommand(string args) @@ -63,7 +103,7 @@ public virtual int ExecuteCommand(string args) { ShellProcess.StartInfo.Arguments = args; ShellProcess.Start(); - ShellProcess.WaitForExit(DEFAULT_WAIT_TIMEOUT); + ShellProcess.WaitForExit(DefaultTimeOut); LastExitCode = ShellProcess.ExitCode; //if (ShellProcess.HasExited == false) diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/ExecProcess/SignClientExec.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/ExecProcess/SignClientExec.cs new file mode 100644 index 000000000000..c2d8d850b6fd --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/ExecProcess/SignClientExec.cs @@ -0,0 +1,91 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Microsoft.Azure.Sdk.Build.ExecProcess +{ + using Microsoft.Azure.Sdk.Build.Tasks.Utilities; + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + + /// + /// TODO: Make exec base as Task + /// + public class SignClientExec : ShellExec + { + //ESRPClient sign ​-a c:/somefolder/auth.json, -c c:/somefolder/config.json -p c:/somefolder/policy.json -i c:/somefolder/input.json -o c:/somefolder/output.json + + private const int SignUtilityDefaultTimeOut = 360000; + + private string signClientExecName = "ESRPClient.exe"; + private string ciConfigDir; + + /// + /// Root direcotry for CI tools + /// + + public string CiToolsRootDir { get; set; } + + /// + /// Signing Client input file + /// + public string SigningInputManifestFilePath { get; set; } + + /// + /// + /// + public string SigningResultOutputFilePath { get; set; } + + /// + /// Defautl time for the shell process + /// + protected override int DefaultTimeOut => SignUtilityDefaultTimeOut; + + /// + /// Build commandline args string + /// + /// + protected override string BuildShellProcessArgs() + { + return string.Format("{0} -a {1} -c {2} -p {3} -i {4} -o {5}", "Sign", Path.Combine(ciConfigDir, "AdxSdkAuth.json"), + Path.Combine(ciConfigDir, "Config.json"), Path.Combine(ciConfigDir, "Policy.json"), SigningInputManifestFilePath, SigningResultOutputFilePath); + } + + + public SignClientExec() : base() { } + + public SignClientExec(string commandPath) : base(commandPath) { } + + + public override int ExecuteCommand() + { + VerifyRequiredProperties(); + + int exitCode = ExecuteCommand(BuildShellProcessArgs()); + //string output = this.AnalyzeExitCode(); + return exitCode; + } + + private void VerifyRequiredProperties() + { + //OnPremiseBuildTasks + Check.DirectoryExists(CiToolsRootDir); + var clientExes = Directory.EnumerateFiles(CiToolsRootDir, signClientExecName, SearchOption.AllDirectories); + Check.NotNull(clientExes, "SignUtility not found"); + if(clientExes.Any()) + { + this.ShellProcessCommandPath = clientExes.First(); + Check.FileExists(this.ShellProcessCommandPath); + } + + ciConfigDir = Path.Combine(CiToolsRootDir, @"tools\ESRPClient\configs"); + Check.DirectoryExists(ciConfigDir); + Check.FileExists(Path.Combine(ciConfigDir, "AdxSdkAuth.json")); + Check.FileExists(Path.Combine(ciConfigDir, "Config.json")); + Check.FileExists(Path.Combine(ciConfigDir, "Policy.json")); + } + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Microsoft.Azure.Sdk.Build.Tasks.csproj b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Microsoft.Azure.Sdk.Build.Tasks.csproj index e8cf4d44034d..9aa27d966659 100644 --- a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Microsoft.Azure.Sdk.Build.Tasks.csproj +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Microsoft.Azure.Sdk.Build.Tasks.csproj @@ -15,14 +15,17 @@ net46 $(TaskBinaryOutput) - + + + + + + - - - + \ No newline at end of file diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/EsrpServiceModelBase.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/EsrpServiceModelBase.cs new file mode 100644 index 000000000000..203a33d944b8 --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/EsrpServiceModelBase.cs @@ -0,0 +1,111 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Microsoft.Azure.Sdk.Build.Tasks.Models.Esrp +{ + using Newtonsoft.Json; + using Newtonsoft.Json.Converters; + using System; + using System.Collections.Generic; + using System.Globalization; + using System.IO; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + + public class EsrpServiceModelBase where T: class + { + private static JsonSerializerSettings _esrpModelSerializerSetting; + private static JsonSerializerSettings _esrpModelDeSerializerSetting; + + protected static JsonSerializerSettings EsrpModelSerializerSetting + { + get + { + if (_esrpModelSerializerSetting == null) + { + _esrpModelSerializerSetting = new JsonSerializerSettings + { + MetadataPropertyHandling = MetadataPropertyHandling.Ignore, + DateParseHandling = DateParseHandling.None, + Converters = { + new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } + }, + }; + } + + return _esrpModelSerializerSetting; + } + + set + { + _esrpModelSerializerSetting = value; + } + } + + protected static JsonSerializerSettings EsrpModelDeSerializerSetting + { + get + { + if (_esrpModelSerializerSetting == null) + { + _esrpModelSerializerSetting = new JsonSerializerSettings + { + MetadataPropertyHandling = MetadataPropertyHandling.Ignore, + DateParseHandling = DateParseHandling.None, + Converters = { + new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } + }, + }; + } + + return _esrpModelDeSerializerSetting; + } + + set + { + _esrpModelDeSerializerSetting = value; + } + } + + public EsrpServiceModelBase() + { + + } + public string ToJson() => JsonConvert.SerializeObject(this, EsrpModelSerializerSetting); + + public string ToJsonFile(string jsonFilePath) + { + if(File.Exists(jsonFilePath)) + { + File.Delete(jsonFilePath); + } + + string dirPath = Path.GetDirectoryName(jsonFilePath); + if(!Directory.Exists(dirPath)) + { + DirectoryInfo dirInfo = new DirectoryInfo(Path.GetDirectoryName(jsonFilePath)); + dirInfo.Create(); + } + + string jsonContents = this.ToJson(); + File.WriteAllText(jsonFilePath, jsonContents); + + if(!File.Exists(jsonFilePath)) + { + //Log error + } + + return jsonFilePath; + } + + + #region Static Methods + public static T FromJson(string json) => JsonConvert.DeserializeObject(json, EsrpModelDeSerializerSetting); + + public static T FromJsonFile(string jsonFilePath) => FromJson(File.ReadAllText(jsonFilePath)); + + + #endregion + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/ExtensionMethod.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/ExtensionMethod.cs new file mode 100644 index 000000000000..aa9f378c3bc7 --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/ExtensionMethod.cs @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Microsoft.Azure.Sdk.Build.Tasks.Models.Esrp +{ + using Microsoft.Azure.Sdk.Build.Tasks.Models.Esrp.Scan; + using Microsoft.Azure.Sdk.Build.Tasks.Models.Esrp.Sign; + using Microsoft.Azure.Sdk.Build.Tasks.Models.Esrp.SignClient; + using Newtonsoft.Json; + using Newtonsoft.Json.Converters; + using System.Globalization; + + public static class SerializeExtensions + { + #region Sign + public static string ToSignJson(this SignRequest self) => JsonConvert.SerializeObject(self, SerializerConfig); + #endregion + + + #region Scan + public static string ToScanJson(this ScanFileRequest self) => JsonConvert.SerializeObject(self, SerializerConfig); + #endregion + + #region SignClientCertAuthConfig + public static string ToSignClientCertAuthConfigJson(this SignClientCertAuthConfig self) => JsonConvert.SerializeObject(self, SerializerConfig); + #endregion + + #region SignClientConfig + public static string ToSignClientConfigJson(this SignClientConfig self) => JsonConvert.SerializeObject(self, SerializerConfig); + #endregion + + + #region SignClientPolicyConfig + public static string ToSignClientAuthConfigJson(this SignClientPolicyConfig self) => JsonConvert.SerializeObject(self, SerializerConfig); + #endregion + + + public static readonly JsonSerializerSettings SerializerConfig = new JsonSerializerSettings + { + MetadataPropertyHandling = MetadataPropertyHandling.Ignore, + DateParseHandling = DateParseHandling.None, + Converters = { + new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } + }, + }; + + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/Scan/ScanFileRequest.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/Scan/ScanFileRequest.cs new file mode 100644 index 000000000000..9d88d26e4454 --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/Scan/ScanFileRequest.cs @@ -0,0 +1,78 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Microsoft.Azure.Sdk.Build.Tasks.Models.Esrp.Scan +{ + using Newtonsoft.Json; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + + + public partial class ScanFileRequest : EsrpServiceModelBase + { + [JsonProperty("Version")] + public string Version { get; set; } + + [JsonProperty("ContextData")] + public ContextData ContextData { get; set; } + + [JsonProperty("DriEmail")] + public List DriEmail { get; set; } + + [JsonProperty("GroupId")] + public object GroupId { get; set; } + + [JsonProperty("CorrelationVector")] + public object CorrelationVector { get; set; } + + [JsonProperty("ScanBatches")] + public List ScanBatches { get; set; } + + + public ScanFileRequest() { } + + + } + + public partial class ContextData + { + [JsonProperty("mykey1")] + public string Mykey1 { get; set; } + + [JsonProperty("myKey2")] + public string MyKey2 { get; set; } + } + + public partial class ScanBatch + { + [JsonProperty("SourceLocationType")] + public string SourceLocationType { get; set; } + + [JsonProperty("SourceRootDirectory")] + public string SourceRootDirectory { get; set; } + + [JsonProperty("ScanRequestFiles")] + public List ScanRequestFiles { get; set; } + } + + public partial class ScanRequestFile + { + [JsonProperty("CustomerCorrelationId")] + public string CustomerCorrelationId { get; set; } + + [JsonProperty("SourceLocation")] + public string SourceLocation { get; set; } + + [JsonProperty("SizeInBytes")] + public long SizeInBytes { get; set; } + + [JsonProperty("HashType")] + public string HashType { get; set; } + + [JsonProperty("SourceHash")] + public string SourceHash { get; set; } + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/Scan/ScanFileResponse.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/Scan/ScanFileResponse.cs new file mode 100644 index 000000000000..8b1291710397 --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/Scan/ScanFileResponse.cs @@ -0,0 +1,68 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Microsoft.Azure.Sdk.Build.Tasks.Models.Esrp +{ + using Newtonsoft.Json; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + + public partial class ScanFileResponse : EsrpServiceModelBase + { + [JsonProperty("Version")] + public string Version { get; set; } + + [JsonProperty("EsrpClientSessionGuid")] + public string EsrpClientSessionGuid { get; set; } + + [JsonProperty("SubmissionResponses")] + public List SubmissionResponses { get; set; } + + public ScanFileResponse() { } + } + + public partial class SubmissionResponse + { + [JsonProperty("FileHash")] + public string FileHash { get; set; } + + [JsonProperty("FileHashType")] + public string FileHashType { get; set; } + + [JsonProperty("OperationId")] + public string OperationId { get; set; } + + [JsonProperty("CustomerCorrelationId")] + public string CustomerCorrelationId { get; set; } + + [JsonProperty("StatusCode", NullValueHandling = NullValueHandling.Ignore)] + public string StatusCode { get; set; } + + [JsonProperty("ErrorInfo")] + public ErrorInfo ErrorInfo { get; set; } + } + + public partial class ErrorInfo + { + [JsonProperty("code")] + public string Code { get; set; } + + [JsonProperty("details")] + public Details Details { get; set; } + + [JsonProperty("innerError")] + public ErrorInfo InnerError { get; set; } + } + + public partial class Details + { + [JsonProperty("clientId")] + public string ClientId { get; set; } + + [JsonProperty("keyCode")] + public string KeyCode { get; set; } + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/Sign/SignRequest.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/Sign/SignRequest.cs new file mode 100644 index 000000000000..0b51c3ae62ce --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/Sign/SignRequest.cs @@ -0,0 +1,211 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Microsoft.Azure.Sdk.Build.Tasks.Models.Esrp.Sign +{ + using Newtonsoft.Json; + using System.Collections.Generic; + + public class SignRequest : EsrpServiceModelBase + { + #region Properties + [JsonProperty("Version")] + public string Version { get; set; } + + [JsonProperty("ContextData")] + public ContextData ContextData { get; set; } + + [JsonProperty("DriEmail")] + public List DriEmail { get; set; } + + [JsonProperty("GroupId")] + public object GroupId { get; set; } + + [JsonProperty("CorrelationVector")] + public object CorrelationVector { get; set; } + + [JsonProperty("SignBatches")] + public List SignBatches { get; set; } + #endregion + + public SignRequest() + { + Version = "1.0.0"; + ContextData = new ContextData(); + SignBatches = new List(); + DriEmail = new List() { "abhishah@microsoft.com" }; + } + + public SignRequest(string signBuildName) : this() + { + ContextData.SignBuildName = signBuildName; + } + + + private SignRequest CreateSampleRequest() + { + SignRequest signReq = new SignRequest(); + + signReq.Version = "1.0.0"; + signReq.ContextData = new ContextData(""); + signReq.DriEmail = new List() { "abhishah@microsoft.com" }; + signReq.SignBatches = new List(); + + SignBatch sbatch = new SignBatch(); + sbatch.SourceLocationType = "UNC"; + sbatch.SourceRootDirectory = @"C:\signFiles\Input"; + sbatch.DestinationLocationType = "UNC"; + sbatch.DestinationRootDirectory = @"C:\signFiles\Output"; + + SignRequestFile srf = new SignRequestFile(); + srf.Name = "ClientRuntime.dll"; + srf.SourceLocation = @"InputFile\ClientRuntime.dll"; + srf.DestinationLocation = @"OutputFile\ClientRuntime.dll"; + srf.HashType = null; + srf.SizeInBytes = 0; + + sbatch.SignRequestFiles.Add(srf); + + Operation op = new Operation(); + op.KeyCode = "CodeSignTestCertSha2TestRoot"; + op.OperationCode = "Authenticode_SignTool6.2.9304_NPH"; + + sbatch.SigningInfo.Operations.Add(op); + + signReq.SignBatches.Add(sbatch); + + return signReq; + } + } + + public partial class ContextData + { + [JsonProperty("signbuildname")] + public string SignBuildName { get; set; } + + [JsonProperty("myKey2")] + public string MyKey2 { get; set; } + + public ContextData(string buildName) + { + SignBuildName = buildName; + } + + public ContextData() { } + } + + public partial class SignBatch + { + private string _sourceLocationType; + private string _destinationLocationType; + + const string DEFAULT_LOCATION_TYPE = "UNC"; + + + [JsonProperty("SourceLocationType")] + public string SourceLocationType + { + get + { + if(string.IsNullOrEmpty(_sourceLocationType)) + { + _sourceLocationType = DEFAULT_LOCATION_TYPE; + } + + return _sourceLocationType; + } + set { _sourceLocationType = value; } + } + + [JsonProperty("SourceRootDirectory")] + public string SourceRootDirectory { get; set; } + + [JsonProperty("DestinationLocationType")] + public string DestinationLocationType + { + get + { + if(string.IsNullOrEmpty(_destinationLocationType)) + { + _destinationLocationType = DEFAULT_LOCATION_TYPE; + } + + return _destinationLocationType; + } + set { _destinationLocationType = value; } + } + + [JsonProperty("DestinationRootDirectory")] + public string DestinationRootDirectory { get; set; } + + [JsonProperty("SignRequestFiles")] + public List SignRequestFiles { get; set; } + + [JsonProperty("SigningInfo")] + public SigningInfo SigningInfo { get; set; } + + public SignBatch() + { + SignRequestFiles = new List(); + + SigningInfo = new SigningInfo(); + } + } + + public partial class SignRequestFile + { + [JsonProperty("CustomerCorrelationId")] + public string CustomerCorrelationId { get; set; } + + [JsonProperty("SourceLocation")] + public string SourceLocation { get; set; } + + [JsonProperty("SourceHash")] + public string SourceHash { get; set; } + + [JsonProperty("HashType")] + public object HashType { get; set; } + + [JsonProperty("SizeInBytes")] + public long SizeInBytes { get; set; } + + [JsonProperty("Name")] + public string Name { get; set; } + + [JsonProperty("DestinationLocation")] + public string DestinationLocation { get; set; } + } + + public partial class SigningInfo + { + [JsonProperty("Operations")] + public List Operations { get; set; } + + public SigningInfo() + { + Operations = new List(); + } + } + + public partial class Operation + { + [JsonProperty("KeyCode")] + public string KeyCode { get; set; } + + [JsonProperty("OperationCode")] + public string OperationCode { get; set; } + + [JsonProperty("Parameters")] + public Parameters Parameters { get; set; } + + [JsonProperty("ToolName")] + public string ToolName { get; set; } + + [JsonProperty("ToolVersion")] + public string ToolVersion { get; set; } + } + + public partial class Parameters + { + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/Sign/SignResponse.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/Sign/SignResponse.cs new file mode 100644 index 000000000000..a1bbc4de08c9 --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/Sign/SignResponse.cs @@ -0,0 +1,100 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Microsoft.Azure.Sdk.Build.Tasks.Models.Esrp.Sign +{ + using Newtonsoft.Json; + using Newtonsoft.Json.Converters; + using System; + using System.Collections.Generic; + using System.Globalization; + using System.IO; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + + public class SignResponse : EsrpServiceModelBase + { + [JsonProperty("Version")] + public string Version { get; set; } + + [JsonProperty("EsrpClientSessionGuid")] + public string EsrpClientSessionGuid { get; set; } + + [JsonProperty("SubmissionResponses")] + public List SubmissionResponses { get; set; } + + + + public SignResponse() + { + + } + + public void UpdateSignRequestWithDefaults() + { + + } + + //public SignResponse FromJson(string json) => JsonConvert.DeserializeObject(json, this.EsrpModelDeSerializerSetting); + + //public SignResponse FromJsonFile(string jsonFilePath) => FromJson(File.ReadAllText(jsonFilePath)); + + //public string ToJson() => JsonConvert.SerializeObject(this, this.EsrpModelSerializerSetting); + + } + + public partial class SubmissionResponse + { + [JsonProperty("FilesStatusDetail")] + public List FilesStatusDetail { get; set; } + + [JsonProperty("OperationId")] + public string OperationId { get; set; } + + [JsonProperty("CustomerCorrelationId")] + public string CustomerCorrelationId { get; set; } + + [JsonProperty("StatusCode")] + public string StatusCode { get; set; } + + [JsonProperty("ErrorInfo")] + public ErrorInfo ErrorInfo { get; set; } + + [JsonProperty("CertificateThumbprint")] + public object CertificateThumbprint { get; set; } + } + + public partial class ErrorInfo + { + [JsonProperty("code")] + public string Code { get; set; } + + [JsonProperty("details")] + public Details Details { get; set; } + + [JsonProperty("innerError")] + public ErrorInfo InnerError { get; set; } + } + + public partial class Details + { + [JsonProperty("clientId")] + public string ClientId { get; set; } + + [JsonProperty("keyCode")] + public string KeyCode { get; set; } + } + + public partial class FilesStatusDetail + { + [JsonProperty("SourceHash")] + public string SourceHash { get; set; } + + [JsonProperty("HashType")] + public string HashType { get; set; } + + [JsonProperty("DestinationHash")] + public string DestinationHash { get; set; } + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/SignClient/SignClientCertAuthConfig.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/SignClient/SignClientCertAuthConfig.cs new file mode 100644 index 000000000000..3982d30b0c3f --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/SignClient/SignClientCertAuthConfig.cs @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Microsoft.Azure.Sdk.Build.Tasks.Models.Esrp.SignClient +{ + using Newtonsoft.Json; + public partial class SignClientCertAuthConfig : EsrpServiceModelBase + { + [JsonProperty("Version")] + public string Version { get; set; } + + [JsonProperty("AuthenticationType")] + public string AuthenticationType { get; set; } + + [JsonProperty("ClientId")] + public string ClientId { get; set; } + + [JsonProperty("AuthCert")] + public Cert AuthCert { get; set; } + + [JsonProperty("RequestSigningCert")] + public Cert RequestSigningCert { get; set; } + + public SignClientCertAuthConfig() + { + Version = "1.0.0"; + AuthenticationType = "AAD_CERT"; + ClientId = ""; + + AuthCert = new Cert(); + } + } + + public partial class Cert + { + [JsonProperty("SubjectName")] + public string SubjectName { get; set; } + + [JsonProperty("StoreLocation")] + public string StoreLocation { get; set; } + + [JsonProperty("StoreName")] + public string StoreName { get; set; } + + public Cert() + { + + } + + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/SignClient/SignClientConfig.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/SignClient/SignClientConfig.cs new file mode 100644 index 000000000000..829c60faac1a --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/SignClient/SignClientConfig.cs @@ -0,0 +1,53 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Microsoft.Azure.Sdk.Build.Tasks.Models.Esrp.SignClient +{ + using Newtonsoft.Json; + using System; + + public partial class SignClientConfig : EsrpServiceModelBase + { + [JsonProperty("Version")] + public string Version { get; set; } + + [JsonProperty("EsrpApiBaseUri")] + public string EsrpApiBaseUri { get; set; } + + [JsonProperty("EsrpSessionTimeoutInSec")] + public long EsrpSessionTimeoutInSec { get; set; } + + [JsonProperty("MinThreadPoolThreads")] + public long MinThreadPoolThreads { get; set; } + + [JsonProperty("MaxDegreeOfParallelism")] + public long MaxDegreeOfParallelism { get; set; } + + [JsonProperty("ExponentialFirstFastRetry")] + public bool ExponentialFirstFastRetry { get; set; } + + [JsonProperty("ExponentialRetryCount")] + public long ExponentialRetryCount { get; set; } + + [JsonProperty("ExponentialRetryMinBackOff")] + public DateTimeOffset ExponentialRetryMinBackOff { get; set; } + + [JsonProperty("ExponentialRetryMaxBackOff")] + public DateTimeOffset ExponentialRetryMaxBackOff { get; set; } + + [JsonProperty("ExponentialRetryDeltaBackOff")] + public DateTimeOffset ExponentialRetryDeltaBackOff { get; set; } + + [JsonProperty("AppDataFolder")] + public string AppDataFolder { get; set; } + + [JsonProperty("ExitOnFlaggedFile")] + public bool ExitOnFlaggedFile { get; set; } + + [JsonProperty("FlaggedFileClientWaitTimeout")] + public string FlaggedFileClientWaitTimeout { get; set; } + + [JsonProperty("ServicePointManagerDefaultConnectionLimit")] + public long ServicePointManagerDefaultConnectionLimit { get; set; } + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/SignClient/SignClientPolicyConfig.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/SignClient/SignClientPolicyConfig.cs new file mode 100644 index 000000000000..649b96387424 --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Models/Esrp/SignClient/SignClientPolicyConfig.cs @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Microsoft.Azure.Sdk.Build.Tasks.Models.Esrp.SignClient +{ + using Newtonsoft.Json; + public partial class SignClientPolicyConfig : EsrpServiceModelBase + { + [JsonProperty("Version")] + public string Version { get; set; } + + [JsonProperty("Intent")] + public string Intent { get; set; } + + [JsonProperty("ContentType")] + public string ContentType { get; set; } + + [JsonProperty("ContentOrigin")] + public string ContentOrigin { get; set; } + + [JsonProperty("ProductState")] + public string ProductState { get; set; } + + [JsonProperty("Audience")] + public string Audience { get; set; } + } +} \ No newline at end of file diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/PackageTasks/PrePackageTasks.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/PackageTasks/PrePackageTasks.cs index 29272de9ec97..86820b958460 100644 --- a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/PackageTasks/PrePackageTasks.cs +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/PackageTasks/PrePackageTasks.cs @@ -41,7 +41,7 @@ internal void Execute_AddTagInfoToPackage() addTagsTask.SdkProjectInfo = SdkProjectInfo; addTagsTask.BuildEngine = this.BuildEngine; addTagsTask.BuildScope = this.BuildScope; - addTagsTask.DebugTrace = this.DebugTrace; + addTagsTask.DebugTraceEnabled = this.DebugTraceEnabled; //addTagsTask.SdkMetaProjects = SdkMetaProjects; addTagsTask.Execute(); diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/PublishSDKNuget.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/PublishSDKNuget.cs index 1519cf6b8a80..2a426e10a945 100644 --- a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/PublishSDKNuget.cs +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/PublishSDKNuget.cs @@ -6,14 +6,16 @@ namespace Microsoft.WindowsAzure.Build.Tasks using System; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; - using Microsoft.WindowsAzure.Build.Tasks.ExecProcess; + //using Microsoft.WindowsAzure.Build.Tasks.ExecProcess; using Microsoft.WindowsAzure.Build.Tasks.Utilities; using System.IO; using System.Collections.Generic; using System.Linq; using System.Diagnostics; + using Microsoft.Azure.Sdk.Build.ExecProcess; + using Microsoft.Azure.Sdk.Build.Tasks.Utilities; - public class PublishSDKNuget : Task + public class PublishSDKNugetTask : Task { #region fields /// @@ -24,7 +26,7 @@ public class PublishSDKNuget : Task private string _apiKey; #endregion - public PublishSDKNuget() + public PublishSDKNugetTask() { _publishAllNugetsunderScope = false; _buildEngineInitialized = false; diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Utilities/Check.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Utilities/Check.cs index 1489e7330c6c..c05e0adde7a8 100644 --- a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Utilities/Check.cs +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Utilities/Check.cs @@ -1,10 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. -namespace Microsoft.WindowsAzure.Build.Tasks.Utilities +//namespace Microsoft.WindowsAzure.Build.Tasks.Utilities +namespace Microsoft.Azure.Sdk.Build.Tasks.Utilities { using System; + using System.Collections.Generic; using System.IO; + using System.Linq; /// /// Utility to check Null/Empty and throw appropriate exceptions @@ -67,5 +70,15 @@ public static void DirectoryExists(string dirPath) } } + public static void Empty(IEnumerable collection, bool expectedResult, string exceptionMessage = "Collection items do not match with expectedResult" ) + { + if (collection == null) throw new ArgumentNullException(exceptionMessage); + + if(collection.Any() == expectedResult) + { + throw new ArgumentException(exceptionMessage); + } + } + } } diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Utilities/Constants.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Utilities/Constants.cs index 0475d02a473a..d2bbcd8f8446 100644 --- a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Utilities/Constants.cs +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Utilities/Constants.cs @@ -40,5 +40,16 @@ internal static class FrameworkMonikerConstant public static string Net452 = "net452"; public static string NetStd14 = "netstandard1.4"; } + + internal static class SigningConstants + { + public const string SigningsProjectsManifestFileName = "AzSdkProject_SigningRequest.json"; + public const string SigningsFullFilePathManifestFileName = "FullFilePath_SigningRequest.json"; + public const string SigningsRootDirFilesManifestFileName = "RootDirFiles_SigningRequest.json"; + + public const string SignClientCertAuthConfigFileName = "SignClientCertAuthConfig.json"; + public const string SignClientConfigFileName = "SignClientConfig.json"; + public const string SignClientPolicyConfigFileName = "SignClientPolicyConfig.json"; + } } } diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Utilities/FileSystemUtility.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Utilities/FileSystemUtility.cs new file mode 100644 index 000000000000..d2bf98cc2c06 --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Utilities/FileSystemUtility.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace Microsoft.Azure.Sdk.Build.Tasks.Utilities +{ + class FileSystemUtility + { + + //internal string SplitDirPath(string split) + + /// + /// Given a directory path, traverses one directory + /// + /// + /// + internal string TraverseTowardsRoot(string directoryNameToken) + { + string srcRootDir = string.Empty; + string currDir = Directory.GetCurrentDirectory(); + + if (!Directory.Exists(currDir)) + { + currDir = Path.GetDirectoryName(this.GetType().GetTypeInfo().Assembly.Location); + } + + string dirRoot = Directory.GetDirectoryRoot(currDir); + + var buildProjFile = Directory.EnumerateFiles(currDir, "build.proj", SearchOption.TopDirectoryOnly); + + while (currDir != dirRoot) + { + if (buildProjFile.Any()) + { + srcRootDir = Path.GetDirectoryName(buildProjFile.First()); + break; + } + + currDir = Directory.GetParent(currDir).FullName; + buildProjFile = Directory.EnumerateFiles(currDir, "build.proj", SearchOption.TopDirectoryOnly); + } + + if (string.IsNullOrEmpty(srcRootDir)) + { + srcRootDir = @"C:\MyFork\vs17Dev"; + } + + return srcRootDir; + } + + + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Utilities/ProjectSearchUtility.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Utilities/ProjectSearchUtility.cs index 67f782eaff69..7948bf7566f8 100644 --- a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Utilities/ProjectSearchUtility.cs +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/SdkBuildTasks/Utilities/ProjectSearchUtility.cs @@ -3,6 +3,7 @@ namespace Microsoft.WindowsAzure.Build.Tasks.Utilities { + using Microsoft.Azure.Sdk.Build.Tasks.Utilities; using System; using System.Collections.Generic; using System.IO; diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/Build.Tasks.Tests.csproj b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/Build.Tasks.Tests.csproj index 8f44cb616a80..b0f897d9ff2b 100644 --- a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/Build.Tasks.Tests.csproj +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/Build.Tasks.Tests.csproj @@ -39,6 +39,22 @@ + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/BuildTestBase.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/BuildTestBase.cs index 97e9cf45b200..98d0a76173e2 100644 --- a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/BuildTestBase.cs +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/BuildTestBase.cs @@ -1,4 +1,5 @@ -using System; +using Microsoft.WindowsAzure.Build.Tasks; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -16,10 +17,26 @@ public class BuildTestBase public string RootDir { get; private set; } public string SourceRootDir { get; private set; } + public string BinariesRootDir { get; private set; } + + public string SignManifestDir { get; private set; } + + public string TestBinaryOutputDir { get; set; } + public string TestDataRuntimeDir { get; set; } + public BuildTestBase() { + string codeBasePath = Assembly.GetExecutingAssembly().CodeBase; + var uri = new UriBuilder(codeBasePath); + string path = Uri.UnescapeDataString(uri.Path); + path = Path.GetDirectoryName(path); + TestBinaryOutputDir = path; + TestDataRuntimeDir = Path.Combine(TestBinaryOutputDir, "TestData"); + RootDir = GetSourceRootDir(); SourceRootDir = Path.Combine(RootDir, "src"); + BinariesRootDir = Path.Combine(RootDir, "binaries"); + SignManifestDir = Path.Combine(BinariesRootDir, "signManifest"); } internal string GetSourceRootDir() @@ -34,10 +51,10 @@ internal string GetSourceRootDir() string dirRoot = Directory.GetDirectoryRoot(currDir); - var buildProjFile = Directory.EnumerateFiles(currDir, "build.proj", SearchOption.TopDirectoryOnly); - while (currDir != dirRoot) { + var buildProjFile = Directory.EnumerateFiles(currDir, "build.proj", SearchOption.TopDirectoryOnly); + if (buildProjFile.Any()) { srcRootDir = Path.GetDirectoryName(buildProjFile.First()); @@ -45,15 +62,27 @@ internal string GetSourceRootDir() } currDir = Directory.GetParent(currDir).FullName; - buildProjFile = Directory.EnumerateFiles(currDir, "build.proj", SearchOption.TopDirectoryOnly); - } - - if (string.IsNullOrEmpty(srcRootDir)) - { - srcRootDir = @"C:\MyFork\vs17Dev"; + //buildProjFile = Directory.EnumerateFiles(currDir, "build.proj", SearchOption.TopDirectoryOnly); } return srcRootDir; } + + internal string GetSourceDir() + { + return Path.Combine(GetSourceRootDir(), "src"); + } + + + + protected SDKCategorizeProjects GetCategorizedProjects(string scope) + { + SDKCategorizeProjects cproj = new SDKCategorizeProjects(); + cproj.SourceRootDirPath = GetSourceDir(); + cproj.BuildScope = scope; + cproj.Execute(); + + return cproj; + } } } diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/PublishNugetTests/PublishTests.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/PublishNugetTests/PublishTests.cs index 4664161b73c5..79b769b8390f 100644 --- a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/PublishNugetTests/PublishTests.cs +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/PublishNugetTests/PublishTests.cs @@ -1,8 +1,9 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. +using Microsoft.Azure.Sdk.Build.ExecProcess; using Microsoft.WindowsAzure.Build.Tasks; -using Microsoft.WindowsAzure.Build.Tasks.ExecProcess; +//using Microsoft.WindowsAzure.Build.Tasks.ExecProcess; using System; using System.Collections.Generic; using System.Diagnostics; @@ -67,7 +68,7 @@ public PublishTests() [Fact] public void PublishSingleNuget() { - PublishSDKNuget pubNug = new PublishSDKNuget(); + PublishSDKNugetTask pubNug = new PublishSDKNugetTask(); pubNug.PackageOutputPath = NugetPkgBuiltDir; pubNug.NugetPackageName = NUGET_PKG_NAME; pubNug.PublishNugetToPath = PublishToDir; @@ -85,7 +86,7 @@ public void PublishSingleNuget() [Fact] public void NonExistentPublishLocation() { - PublishSDKNuget pubNug = new PublishSDKNuget(); + PublishSDKNugetTask pubNug = new PublishSDKNugetTask(); pubNug.PackageOutputPath = NugetPkgBuiltDir; pubNug.NugetPackageName = NUGET_PKG_NAME; pubNug.PublishNugetToPath = "http://somelocation"; @@ -98,7 +99,7 @@ public void NonExistentPublishLocation() [Fact] public void SkipPublishingSymbols() { - PublishSDKNuget pubNug = new PublishSDKNuget(); + PublishSDKNugetTask pubNug = new PublishSDKNugetTask(); pubNug.PackageOutputPath = NugetPkgBuiltDir; pubNug.NugetPackageName = NUGET_PKG_NAME; pubNug.PublishNugetToPath = PublishToDir; @@ -129,7 +130,7 @@ public void DefaultPublishPaths() [Fact] public void PublishOnlySymbol() { - PublishSDKNuget pubNug = new PublishSDKNuget(); + PublishSDKNugetTask pubNug = new PublishSDKNugetTask(); pubNug.PackageOutputPath = NugetPkgBuiltDir; pubNug.NugetPackageName = NUGET_PKG_NAME; pubNug.PublishNugetToPath = "https://www.nuget.org/api/v2/package/"; @@ -141,7 +142,7 @@ public void PublishOnlySymbol() [Fact] public void PublishWithUnAuthenticatedKey() { - PublishSDKNuget pubNug = new PublishSDKNuget(); + PublishSDKNugetTask pubNug = new PublishSDKNugetTask(); pubNug.PackageOutputPath = NugetPkgBuiltDir; pubNug.NugetPackageName = NUGET_PKG_NAME; pubNug.PublishNugetToPath = "https://www.nuget.org/api/v2/package/"; @@ -164,7 +165,7 @@ public void PublishWithUnAuthenticatedKey() [Fact] public void IncorrectNugetExePath() { - PublishSDKNuget pubNug = new PublishSDKNuget(); + PublishSDKNugetTask pubNug = new PublishSDKNugetTask(); pubNug.PackageOutputPath = NugetPkgBuiltDir; pubNug.NugetPackageName = NUGET_PKG_NAME; pubNug.PublishNugetToPath = PublishToDir; @@ -176,7 +177,7 @@ public void IncorrectNugetExePath() [Fact] public void MissingNugetPackageName() { - PublishSDKNuget pubNug = new PublishSDKNuget(); + PublishSDKNugetTask pubNug = new PublishSDKNugetTask(); pubNug.PackageOutputPath = NugetPkgBuiltDir; pubNug.PublishNugetToPath = PublishToDir; pubNug.SkipSymbolPublishing = true; @@ -186,7 +187,7 @@ public void MissingNugetPackageName() [Fact] public void PublishAllNugetUnderScope() { - PublishSDKNuget pubNug = new PublishSDKNuget(); + PublishSDKNugetTask pubNug = new PublishSDKNugetTask(); pubNug.publishAllNugetsUnderScope = true; Assert.Throws(() => pubNug.Execute()); } @@ -194,14 +195,14 @@ public void PublishAllNugetUnderScope() [Fact] public void MissingRequiredProperties() { - PublishSDKNuget pubNug = new PublishSDKNuget(); + PublishSDKNugetTask pubNug = new PublishSDKNugetTask(); Assert.ThrowsAny(() => pubNug.Execute()); } [Fact] public void SkipPublishingCompletely() { - PublishSDKNuget pubNug = new PublishSDKNuget(); + PublishSDKNugetTask pubNug = new PublishSDKNugetTask(); pubNug.PackageOutputPath = NugetPkgBuiltDir; pubNug.NugetPackageName = NUGET_PKG_NAME; pubNug.PublishNugetToPath = PublishToDir; @@ -214,7 +215,7 @@ public void SkipPublishingCompletely() [Fact] public void GetInnerExceptionWhilePublishing() { - PublishSDKNuget pubNug = new PublishSDKNuget(); + PublishSDKNugetTask pubNug = new PublishSDKNugetTask(); pubNug.PackageOutputPath = NugetPkgBuiltDir; pubNug.NugetPackageName = NUGET_PKG_NAME; pubNug.PublishNugetToPath = PublishToDir; diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/SdkInfoTests.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/SdkInfoTests.cs index bacfccda6ace..cb9fdc4797d8 100644 --- a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/SdkInfoTests.cs +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/SdkInfoTests.cs @@ -28,7 +28,7 @@ public SdkInfoTests() [Fact] public void TagMultipleApiVersions() { - GetApiMap("SdkInfo_Compute"); + GetApiMap("ApiInfo_Compute"); VerifyNupkg(); } diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/Signing/NugetSigningTaskTest.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/Signing/NugetSigningTaskTest.cs new file mode 100644 index 000000000000..1caa7801dc06 --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/Signing/NugetSigningTaskTest.cs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Build.Tasks.Tests.Signing +{ + using Microsoft.Azure.Sdk.Build.ExecProcess; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + using Xunit; + + public class NugetSigningTaskTest + { + [Fact] + public void SignOneNuet() + { + SignClientExec signExec = new SignClientExec(); + signExec.CiToolsRootDir = @"D:\myFork\ci-signing\adxsdk"; + signExec.SigningInputManifestFilePath = @"D:\myFork\netSdkBuild\binaries\SignManifest\RootDirFiles_SigningRequest.json"; + signExec.SigningResultOutputFilePath = @"D:\myFork\netSdkBuild\binaries\SignManifest\SignServiceOutput.json"; + + int foo = signExec.ExecuteCommand(); + Assert.Equal(0, foo); + } + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/Signing/PreSignTaskTests.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/Signing/PreSignTaskTests.cs new file mode 100644 index 000000000000..4df78021eda8 --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/Signing/PreSignTaskTests.cs @@ -0,0 +1,90 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Build.Tasks.Tests.Signing +{ + using Microsoft.Azure.Sdk.Build.Tasks.BuildStages.PostBuild; + using Microsoft.Azure.Sdk.Build.Tasks.Models.Esrp.Sign; + using Microsoft.Build.Framework; + using Microsoft.WindowsAzure.Build.Tasks; + using System.IO; + using System.Linq; + using Xunit; + public class PreSignTaskTests : BuildTestBase + { + public PreSignTaskTests() { } + + [Fact] + public void PreSignOneProject() + { + PreSignTask pst = new PreSignTask(); + + SDKCategorizeProjects sdkProj = GetCategorizedProjects(@"SDKs\Compute"); + pst.InSdkProjects = sdkProj.net452SdkProjectsToBuild.Concat(sdkProj.netStd14SdkProjectsToBuild).ToArray(); + pst.InSignManifestDirPath = this.SignManifestDir; + pst.InSignBuildName = "TestSignBuildJob"; + + pst.Execute(); + Assert.Collection(pst.OutSignManifestFiles, (elem) => { }); + + SignRequest signReq = SignRequest.FromJsonFile(pst.OutSignManifestFiles[0]); + Assert.Collection(signReq.SignBatches, (elem) => { }); + Assert.Equal(pst.InSdkProjects.Count(), signReq.SignBatches[0].SignRequestFiles.Count); + } + + [Fact] + public void PreSignOnNugetPackage() + { + PreSignTask pst = new PreSignTask(); + //pst.InSignedFilesRootDirPath = Path.Combine(this.TestDataRuntimeDir, "PublishedNugets"); + pst.InSignedFilesRootDirPath = this.TestDataRuntimeDir; + pst.InSearchExtensionToSearch = ".nupkg"; + pst.InSignBuildName = "TestSignBuildJob"; + pst.InSignManifestDirPath = this.SignManifestDir; + pst.InSigningOperation = "nuget"; + + pst.Execute(); + Assert.Collection(pst.OutSignManifestFiles, (elem) => { }); + + SignRequest signReq = SignRequest.FromJsonFile(pst.OutSignManifestFiles[0]); + Assert.Collection(signReq.SignBatches, (elem) => { }); + Assert.Collection(signReq.SignBatches[0].SignRequestFiles, (col1Elm) => { }, (col2Elm) => { }); + + Assert.Collection(signReq.SignBatches[0].SigningInfo.Operations, (col1Elm) => { }, (col2Elm) => { }); + } + + /// + /// Trying to create manifest file from non-existant directory root + /// + [Fact(Skip = "Code Moved to SignNugetTask")] + public void PreSignTaskNonExistantDirectory() + { + PreSignTask pst = new PreSignTask(); + pst.InSignedFilesRootDirPath = Path.Combine(this.TestDataRuntimeDir, "Foo"); + + pst.InSearchExtensionToSearch = ".nupkg"; + pst.InSignBuildName = "TestSignBuildJob"; + pst.InSignManifestDirPath = this.SignManifestDir; + + pst.Execute(); + Assert.Empty(pst.OutSignManifestFiles); + } + + /// + /// Trying to create manifest file with non-existant file extensions + /// + [Fact(Skip = "Code Moved to SignNugetTask")] + public void PreSignTaskNoFilesToSign() + { + PreSignTask pst = new PreSignTask(); + pst.InSignedFilesRootDirPath = this.TestDataRuntimeDir; + pst.InSearchExtensionToSearch = ".foo"; + pst.InSignBuildName = "TestSignBuildJob"; + pst.InSignManifestDirPath = this.SignManifestDir; + + pst.Execute(); + Assert.Empty(pst.OutSignManifestFiles); + } + + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/SigningManifestTests/SignRequestTests.cs b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/SigningManifestTests/SignRequestTests.cs new file mode 100644 index 000000000000..b932daaee2ff --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/SigningManifestTests/SignRequestTests.cs @@ -0,0 +1,74 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Build.Tasks.Tests.SigningManifestTests +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + using Xunit; + using Microsoft.Azure.Sdk.Build.Tasks.Models.Esrp.Sign; + using System.IO; + + public class SignRequestTests : BuildTestBase + { + public SignRequestTests() { } + + [Fact] + public void SerializeSignRequest() + { + SignRequest sr = CreateSampleSignRequest(); + + string signJson = sr.ToJson(); + } + + private SignRequest CreateSampleSignRequest() + { + SignRequest signReq = new SignRequest(); + + signReq.Version = "1.0.0"; + signReq.ContextData = new ContextData(); + signReq.DriEmail = new List() { "someemail@someDomain.com" }; + signReq.SignBatches = new List(); + + SignBatch sbatch = new SignBatch(); + sbatch.SourceLocationType = "UNC"; + sbatch.SourceRootDirectory = @"C:\signFiles\Input"; + sbatch.DestinationLocationType = "UNC"; + sbatch.DestinationRootDirectory = @"C:\signFiles\Output"; + + SignRequestFile srf = new SignRequestFile(); + srf.Name = "ClientRuntime.dll"; + srf.SourceLocation = @"InputFile\ClientRuntime.dll"; + srf.DestinationLocation = @"OutputFile\ClientRuntime.dll"; + srf.HashType = null; + srf.SizeInBytes = 0; + + sbatch.SignRequestFiles.Add(srf); + + Operation op = new Operation(); + op.KeyCode = "CodeSignTestCertSha2TestRoot"; + op.OperationCode = "Authenticode_SignTool6.2.9304_NPH"; + + sbatch.SigningInfo.Operations.Add(op); + + signReq.SignBatches.Add(sbatch); + + return signReq; + + } + + + [Fact] + public void DeSerializeSignRequest() + { + string testSignRequestManifestFilePath = Path.Combine(TestDataRuntimeDir, "SigningManifests", "Sign", "SingleFileSignRequest.json"); + Assert.True(File.Exists(testSignRequestManifestFilePath)); + + SignRequest sr = SignRequest.FromJsonFile(testSignRequestManifestFilePath); + Assert.Equal("1.0.0", sr.Version); + } + } +} diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/TestData/SigningManifests/Scan/SubmitScan_Input.json b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/TestData/SigningManifests/Scan/SubmitScan_Input.json new file mode 100644 index 000000000000..e18880924cb8 --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/TestData/SigningManifests/Scan/SubmitScan_Input.json @@ -0,0 +1,52 @@ +{ + "Version": "1.0.0", + "ContextData": { + "mykey1": "myValue1", + "myKey2": "myValue2" + }, + "DriEmail": [ "test1@microsoft.com", "test2@microsoft.com" ], + "GroupId": null, + "CorrelationVector": null, + "ScanBatches": [ + { + "SourceLocationType": "unc", + "SourceRootDirectory": null, + "ScanRequestFiles": [ + { + "CustomerCorrelationId": "a8c3a8c8-ea1b-4a20-8fff-6fb7775e6bb1", + "SourceLocation": "c:\\temp\\ClientExe\\Input\\InputFile\\4-StaticBvt-notepad.exe", + "SizeInBytes": 252368, + "HashType": "Sha256", + "SourceHash": "KVSa/eJbSQuoPuHMoLP2HdbzxLXdWFojGK01Ym2O29g=" + }, + { + "CustomerCorrelationId": "b8c3a8c8-ea1b-4a20-8fff-6fb7775e6bb7", + "SourceLocation": "c:\\temp\\ClientExe\\Input\\InputFile\\322_aac_axecore.dll", + "SizeInBytes": 37064, + "HashType": "Sha256", + "SourceHash": "iHi0tWc3QlZPH5ZMShCpR9/7zuysDC8g7eXO7QdDWDI=" + } + ] + }, + { + "SourceLocationType": "unc", + "SourceRootDirectory": "c:\\temp\\ClientExe\\Input", + "ScanRequestFiles": [ + { + "CustomerCorrelationId": "a8c3a8c8-ea1b-hb20-8fff-6fb7775e6bb7", + "SourceLocation": "InputFile\\4-StaticBvt-notepad.exe", + "SizeInBytes": 252368, + "HashType": "Sha256", + "SourceHash": "KVSa/eJbSQuoPuHMoLP2HdbzxLXdWFojGK01Ym2O29g=" + }, + { + "CustomerCorrelationId": "a8c3a8c8-ea1b-hb20-8fff-6fb7775e6bb7", + "SourceLocation": "InputFile\\4-StaticBvt-notepad.exe", + "SizeInBytes": 252368, + "HashType": "Sha256", + "SourceHash": "KVSa/eJbSQuoPuHMoLP2HdbzxLXdWFojGK01Ym2O29g=" + } + ] + } + ] +} \ No newline at end of file diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/TestData/SigningManifests/Scan/SubmitScan_Output.json b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/TestData/SigningManifests/Scan/SubmitScan_Output.json new file mode 100644 index 000000000000..8119ca179139 --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/TestData/SigningManifests/Scan/SubmitScan_Output.json @@ -0,0 +1,32 @@ +{ + "Version": "1.0.0", + "EsrpClientSessionGuid": "f387751c-fde0-41dd-a63e-e366373651fa", + "SubmissionResponses": [ + { + "FileHash": "0A0B0B", + "FileHashType": "Sha256", + "OperationId": "a9b1fd4a-63d6-4db5-a84a-16492dcedc80", + "CustomerCorrelationId": "FileSubmittedId1", + "StatusCode": "Pass", + "ErrorInfo": null + }, + { + "FileHash": "0A0B0BAA", + "FileHashType": "Sha256", + "OperationId": "40145078-a717-44d9-9898-9f4512babfde", + "CustomerCorrelationId": "FileSubmittedId2", + "ErrorInfo": { + "code": "InvalidData", + "details": null, + "innerError": { + "code": "FailedToDecompress", + "details": { + "clientId": "ABS123", + "keyCode": "Xyz" + }, + "innerError": null + } + } + } + ] +} \ No newline at end of file diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/TestData/SigningManifests/Sign/SingleFileSignRequest.json b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/TestData/SigningManifests/Sign/SingleFileSignRequest.json new file mode 100644 index 000000000000..e48e2749373f --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/TestData/SigningManifests/Sign/SingleFileSignRequest.json @@ -0,0 +1,48 @@ +{ + "Version": "1.0.0", + + "ContextData": { + "mykey1": "myValue1", + "myKey2": "myValue2" + }, + "DriEmail": [ "test1@microsoft.com", "test2@microsoft.com" ], + "GroupId": null, + "CorrelationVector": null, + "SignBatches": [ + { + "SourceLocationType": "UNC", + "SourceRootDirectory": "c:\\temp\\ClientExe\\Input", + "DestinationLocationType": "UNC", + "DestinationRootDirectory": "c:\\temp\\ClientExe\\Output", + "SignRequestFiles": [ + { + "CustomerCorrelationId": "01A7F55F-6CDD-4123-B255-77E6F212CDAD", + "SourceLocation": "InputFile\\4-StaticBvt-notepad.exe", + "SourceHash": "", + "HashType": null, + "SizeInBytes": 0, + "Name": "4-StaticBvt-notepad.exe", + "DestinationLocation": "Signed1\\4-StaticBvt-notepad.exe" + } + ], + "SigningInfo": { + "Operations": [ + { + "KeyCode": "CP-401405", + "OperationCode": "NuGetSign", + "Parameters": {}, + "ToolName": "sign", + "ToolVersion": "1.0" + }, + { + "KeyCode": "CP-401405", + "OperationCode": "NuGetVerify", + "Parameters": {}, + "ToolName": "sign", + "ToolVersion": "1.0" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/TestData/SigningManifests/Sign/SingleFileSignResponseWithFailure.json b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/TestData/SigningManifests/Sign/SingleFileSignResponseWithFailure.json new file mode 100644 index 000000000000..7d9e7c0abc03 --- /dev/null +++ b/tools/BuildAssets/BuildTasks/Microsoft.Azure.Sdk.Build.Tasks/Tests/Build.Tasks.Tests/TestData/SigningManifests/Sign/SingleFileSignResponseWithFailure.json @@ -0,0 +1,45 @@ +{ + "Version": "1.0.0", + "EsrpClientSessionGuid": "f387751c-fde0-41dd-a63e-e366373651fa", + "SubmissionResponses": [ + { + "FilesStatusDetail": [ + { + "SourceHash": "0A0B0B", + "HashType": "Sha256", + "DestinationHash" : "0A0B0B" + } + ], + "OperationId": "a9b1fd4a-63d6-4db5-a84a-16492dcedc80", + "CustomerCorrelationId": "FileSubmittedId1", + "StatusCode": "Pass", + "ErrorInfo": null, + "CertificateThumbprint": null + }, + { + "FilesStatusDetail": [ + { + "SourceHash": "0A0B0BAA", + "HashType": "Sha256", + "DestinationHash": "0A0B0B" + } + ], + "OperationId": "5b96a9bb-10a0-4af9-af29-030f73707607", + "CustomerCorrelationId": "FileSubmittedId2", + "StatusCode": "FailDoNotRetry", + "ErrorInfo": { + "code": "InvalidKeyCode", + "details": null, + "innerError": { + "code": "NotAuthorizedToUseKeyCode", + "details": { + "clientId": "ABS123", + "keyCode": "Xyz" + }, + "innerError": null + } + }, + "CertificateThumbprint": null + } + ] +} \ No newline at end of file diff --git a/tools/BuildAssets/metaData/FilesToCopy.txt b/tools/BuildAssets/metaData/FilesToCopy.txt index bd25cccb9fb2..6f541d44906a 100644 --- a/tools/BuildAssets/metaData/FilesToCopy.txt +++ b/tools/BuildAssets/metaData/FilesToCopy.txt @@ -10,5 +10,6 @@ tasks/net46/Microsoft.Build.Framework.dll tasks/net46/Microsoft.Build.Tasks.Core.dll tasks/net46/Microsoft.Build.Utilities.Core.dll tasks/net46/Microsoft.Azure.Sdk.Build.Tasks.dll +tasks/net46/Microsoft.Azure.Sdk.Build.Common.dll tasks/net46/System.Threading.Thread.dll psModules/CodeGenerationModules/generateDotNetSdkCode.psm1 \ No newline at end of file diff --git a/tools/BuildAssets/targets/common.Build.props b/tools/BuildAssets/targets/common.Build.props index 87b52c91fba2..e5f1f9fa9324 100644 --- a/tools/BuildAssets/targets/common.Build.props +++ b/tools/BuildAssets/targets/common.Build.props @@ -20,6 +20,17 @@ false + + + + $(BinariesFolder)\signManifest + $(SignManifestRootDir)\signService + $(SignManifestRootDir)\signClientConfig + false + + + DesktopBuild + diff --git a/tools/BuildAssets/targets/common.targets b/tools/BuildAssets/targets/common.targets index 847d3515814f..d71c843e5804 100644 --- a/tools/BuildAssets/targets/common.targets +++ b/tools/BuildAssets/targets/common.targets @@ -40,12 +40,14 @@ $(RunTestProjectsDependsOn); RunSignTargets; - Package; + PackgNugetBootStrap; + $(RunTestProjectsDependsOn); RunSignTargets; - Package + PackgNugetBootStrap; + $(PackageNugetDependsOn); @@ -216,6 +218,10 @@ + + + + @@ -250,7 +256,7 @@ - + @@ -264,7 +270,7 @@ - + - + + + + + - + + WindowsSdkPath="$(WindowsSdkPath)" + Assembly="%(DelaySignedAssembliesToValidate.Identity)" + ExpectedTokenSignature="$(StrongNameToken)" + ExpectedDelaySigned="false" + ContinueOnError="false" + Condition="'$(CodeSign)' == 'true' and '@(DelaySignedAssembliesToValidate)' != ''"/> + + + + + + + + + + + + + + + diff --git a/tools/BuildAssets/tasks/common.tasks b/tools/BuildAssets/tasks/common.tasks index 74166a509d12..83116b4602a9 100644 --- a/tools/BuildAssets/tasks/common.tasks +++ b/tools/BuildAssets/tasks/common.tasks @@ -15,9 +15,11 @@ - + + + \ No newline at end of file diff --git a/tools/BuildAssets/tasks/net46/Microsoft.Azure.Build.BootstrapTasks.dll b/tools/BuildAssets/tasks/net46/Microsoft.Azure.Build.BootstrapTasks.dll index d96b5fc1e9f2..c328d5867c08 100644 Binary files a/tools/BuildAssets/tasks/net46/Microsoft.Azure.Build.BootstrapTasks.dll and b/tools/BuildAssets/tasks/net46/Microsoft.Azure.Build.BootstrapTasks.dll differ diff --git a/tools/BuildAssets/tasks/net46/Microsoft.Azure.Sdk.Build.Common.dll b/tools/BuildAssets/tasks/net46/Microsoft.Azure.Sdk.Build.Common.dll new file mode 100644 index 000000000000..ef2adc65793d Binary files /dev/null and b/tools/BuildAssets/tasks/net46/Microsoft.Azure.Sdk.Build.Common.dll differ diff --git a/tools/BuildAssets/tasks/net46/Microsoft.Azure.Sdk.Build.Common.runtimeconfig.dev.json b/tools/BuildAssets/tasks/net46/Microsoft.Azure.Sdk.Build.Common.runtimeconfig.dev.json new file mode 100644 index 000000000000..28129e6292e2 --- /dev/null +++ b/tools/BuildAssets/tasks/net46/Microsoft.Azure.Sdk.Build.Common.runtimeconfig.dev.json @@ -0,0 +1,7 @@ +{ + "runtimeOptions": { + "additionalProbingPaths": [ + "C:\\Users\\abhishah\\.nuget\\packages" + ] + } +} \ No newline at end of file diff --git a/tools/BuildAssets/tasks/net46/Microsoft.Azure.Sdk.Build.Common.runtimeconfig.json b/tools/BuildAssets/tasks/net46/Microsoft.Azure.Sdk.Build.Common.runtimeconfig.json new file mode 100644 index 000000000000..153e1cf4fac8 --- /dev/null +++ b/tools/BuildAssets/tasks/net46/Microsoft.Azure.Sdk.Build.Common.runtimeconfig.json @@ -0,0 +1,3 @@ +{ + "runtimeOptions": {} +} \ No newline at end of file diff --git a/tools/BuildAssets/tasks/net46/Microsoft.Azure.Sdk.Build.Tasks.dll b/tools/BuildAssets/tasks/net46/Microsoft.Azure.Sdk.Build.Tasks.dll index 87fd13d9a56f..df4cdb0a67e7 100644 Binary files a/tools/BuildAssets/tasks/net46/Microsoft.Azure.Sdk.Build.Tasks.dll and b/tools/BuildAssets/tasks/net46/Microsoft.Azure.Sdk.Build.Tasks.dll differ diff --git a/tools/BuildAssets/tasks/net46/Microsoft.Build.Framework.dll b/tools/BuildAssets/tasks/net46/Microsoft.Build.Framework.dll index 709e75a9faa7..2f51d7eed8ab 100644 Binary files a/tools/BuildAssets/tasks/net46/Microsoft.Build.Framework.dll and b/tools/BuildAssets/tasks/net46/Microsoft.Build.Framework.dll differ diff --git a/tools/BuildAssets/tasks/net46/Microsoft.Build.Tasks.Core.dll b/tools/BuildAssets/tasks/net46/Microsoft.Build.Tasks.Core.dll index a0e09d5d54e5..033d5c54b446 100644 Binary files a/tools/BuildAssets/tasks/net46/Microsoft.Build.Tasks.Core.dll and b/tools/BuildAssets/tasks/net46/Microsoft.Build.Tasks.Core.dll differ diff --git a/tools/BuildAssets/tasks/net46/Microsoft.Build.Utilities.Core.dll b/tools/BuildAssets/tasks/net46/Microsoft.Build.Utilities.Core.dll index e9fd61b50b43..6e5b66e4506a 100644 Binary files a/tools/BuildAssets/tasks/net46/Microsoft.Build.Utilities.Core.dll and b/tools/BuildAssets/tasks/net46/Microsoft.Build.Utilities.Core.dll differ diff --git a/tools/BuildAssets/tasks/net46/Microsoft.Build.dll b/tools/BuildAssets/tasks/net46/Microsoft.Build.dll index f0418158741b..864f36c570ed 100644 Binary files a/tools/BuildAssets/tasks/net46/Microsoft.Build.dll and b/tools/BuildAssets/tasks/net46/Microsoft.Build.dll differ diff --git a/tools/BuildAssets/tasks/net46/Newtonsoft.Json.dll b/tools/BuildAssets/tasks/net46/Newtonsoft.Json.dll new file mode 100644 index 000000000000..80699020cce0 Binary files /dev/null and b/tools/BuildAssets/tasks/net46/Newtonsoft.Json.dll differ