diff --git a/Assets/Plugins/Editor/Uplift/Common/StrictXmlSerializer.cs b/Assets/Plugins/Editor/Uplift/Common/StrictXmlSerializer.cs index d0d282ac..e09dea4f 100644 --- a/Assets/Plugins/Editor/Uplift/Common/StrictXmlSerializer.cs +++ b/Assets/Plugins/Editor/Uplift/Common/StrictXmlSerializer.cs @@ -42,12 +42,17 @@ public StrictXmlDeserializer() { this.serializer = new XmlSerializer(typeof(T)); } - public T Deserialize(FileStream fileStream) { + public T Deserialize(Stream stream) { return StrictDeserialize( - () => { return serializer.Deserialize(fileStream); } + () => { return serializer.Deserialize(stream); } ); } + public T Deserialize(string xmlString) + { + return Deserialize(new MemoryStream (Convert.FromBase64String(xmlString))); + } + private T StrictDeserialize(Func block) { errors = new List (); diff --git a/Assets/Plugins/Editor/Uplift/Common/UnityPackageOpener.cs b/Assets/Plugins/Editor/Uplift/Common/UnityPackageOpener.cs index 60d6a1b8..02e264f4 100644 --- a/Assets/Plugins/Editor/Uplift/Common/UnityPackageOpener.cs +++ b/Assets/Plugins/Editor/Uplift/Common/UnityPackageOpener.cs @@ -48,9 +48,7 @@ public void Extract(string archivePath) Path.GetDirectoryName(archivePath) ); } - - // From https://github.com/Unity-Technologies/dotpackage-assistant/blob/master/DotPackageAssistant.cs - + /// /// Extracts a package from archivePath, and unpacks it at destinationPath /// @@ -58,167 +56,177 @@ public void Extract(string archivePath, string destinationPath) { using (FileStream compressedFileStream = File.OpenRead(archivePath)) { - GZipStream gzipFileStream = new GZipStream(compressedFileStream, CompressionMode.Decompress); - BinaryReader reader = new BinaryReader(gzipFileStream); - int readBufferSize = 1024 * 1024 * 10; - int tarBlockSize = 512; - byte[] readBuffer = new byte[readBufferSize]; - Regex hashPattern = new Regex(@"^([a-f\d]{20,})\/"); + Extract(compressedFileStream, destinationPath); + } + } + + // From https://github.com/Unity-Technologies/dotpackage-assistant/blob/master/DotPackageAssistant.cs - byte[] rawAsset = null; - byte[] rawMeta = null; - string path = null; + /// + /// Extracts a package from the input stream, and unpacks it at destinationPath + /// + public void Extract(Stream stream, string destinationPath) + { + GZipStream gzipFileStream = new GZipStream(stream, CompressionMode.Decompress); + BinaryReader reader = new BinaryReader(gzipFileStream); + int readBufferSize = 1024 * 1024 * 10; + int tarBlockSize = 512; + byte[] readBuffer = new byte[readBufferSize]; + Regex hashPattern = new Regex(@"^([a-f\d]{20,})\/"); - while (true) + byte[] rawAsset = null; + byte[] rawMeta = null; + string path = null; + + while (true) + { + byte[] headerBuffer = reader.ReadBytes(tarBlockSize); //We want the header, but the header is padded to a blocksize + if (headerBuffer.All(x => x == 0)) { - byte[] headerBuffer = reader.ReadBytes(tarBlockSize); //We want the header, but the header is padded to a blocksize - if (headerBuffer.All(x => x == 0)) - { - //Reached end of stream - break; - } - GCHandle handle = GCHandle.Alloc(headerBuffer, GCHandleType.Pinned); - TarHeader header; - header = (TarHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(TarHeader)); - handle.Free(); + //Reached end of stream + break; + } + GCHandle handle = GCHandle.Alloc(headerBuffer, GCHandleType.Pinned); + TarHeader header; + header = (TarHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(TarHeader)); + handle.Free(); - string filename; + string filename; + unsafe + { + filename = Marshal.PtrToStringAnsi((IntPtr)header.filename, 100); + } + filename = filename.Trim(); + filename = filename.TrimEnd(new char[] { (char)0 }); + + string ustar; + unsafe + { + ustar = Marshal.PtrToStringAnsi((IntPtr)header.ustar, 6); + } + string prefix = string.Empty; + if (ustar.Equals("ustar")) + { unsafe { - filename = Marshal.PtrToStringAnsi((IntPtr)header.filename, 100); + prefix = Marshal.PtrToStringAnsi((IntPtr)header.prefix, 155); } - filename = filename.Trim(); - filename = filename.TrimEnd(new char[] { (char)0 }); + } + prefix = prefix.Trim(); + prefix = prefix.TrimEnd(new char[] { (char)0 }); - string ustar; - unsafe + string fullname = prefix + filename; + Match hashMatch = hashPattern.Match(fullname); + + bool extractPathName = false; + bool extractRawMeta = false; + bool extractRawAsset = false; + + if (hashMatch.Success) + { + if (fullname.EndsWith("/asset.meta")) { - ustar = Marshal.PtrToStringAnsi((IntPtr)header.ustar, 6); + extractRawMeta = true; } - string prefix = string.Empty; - if (ustar.Equals("ustar")) + if (fullname.EndsWith("/asset")) { - unsafe - { - prefix = Marshal.PtrToStringAnsi((IntPtr)header.prefix, 155); - } + extractRawAsset = true; } - prefix = prefix.Trim(); - prefix = prefix.TrimEnd(new char[] { (char)0 }); - - string fullname = prefix + filename; - Match hashMatch = hashPattern.Match(fullname); + if (fullname.EndsWith("/pathname")) + { + extractPathName = true; + } + } - bool extractPathName = false; - bool extractRawMeta = false; - bool extractRawAsset = false; + string rawFilesize; + unsafe + { + rawFilesize = Marshal.PtrToStringAnsi((IntPtr)header.filesize, 12); + } + string filesize = rawFilesize.Trim(); + filesize = filesize.TrimEnd(new char[] { (char)0 }); - if (hashMatch.Success) + //Convert the octal string to a decimal number + try + { + int filesizeInt = Convert.ToInt32(filesize, 8); + int toRead = filesizeInt; + int toWrite = filesizeInt; + int modulus = filesizeInt % tarBlockSize; + if (modulus > 0) + toRead += (tarBlockSize - modulus); //Read the file and assume it's also 512 byte padded + while (toRead > 0) { - if (fullname.EndsWith("/asset.meta")) + int readThisTime = Math.Min(readBufferSize, toRead); + int writeThisTime = Math.Min(readBufferSize, toWrite); + readBuffer = reader.ReadBytes(readThisTime); + if (extractPathName) { - extractRawMeta = true; + if (toRead > readThisTime) + throw new Exception("Assumed a pathname would fit in a single read!"); + string pathnameFileContents = Encoding.UTF8.GetString(readBuffer, 0, filesizeInt); + path = FormatPath(pathnameFileContents.Split(new char[] { '\n' })[0]); + Debug.Log(path); } - if (fullname.EndsWith("/asset")) + else if(extractRawMeta) { - extractRawAsset = true; + if(rawMeta == null) rawMeta = new byte[0]; + int rawLength = rawMeta.Length; + Array.Resize(ref rawMeta, rawLength + writeThisTime); + Array.Copy(readBuffer, 0, rawMeta, rawLength, writeThisTime); } - if (fullname.EndsWith("/pathname")) + else if(extractRawAsset) { - extractPathName = true; + if(rawAsset == null) rawAsset = new byte[0]; + int rawLength = rawAsset.Length; + Array.Resize(ref rawAsset, rawLength + writeThisTime); + Array.Copy(readBuffer, 0, rawAsset, rawLength, writeThisTime); } + toRead -= readThisTime; + toWrite -= writeThisTime; } - - string rawFilesize; - unsafe + } + catch (Exception ex) + { + Debug.Log(String.Format("Caught Exception converting octal string to int: {0}", ex.Message)); + foreach (byte fsChar in filesize) { - rawFilesize = Marshal.PtrToStringAnsi((IntPtr)header.filesize, 12); + Debug.Log(fsChar); } - string filesize = rawFilesize.Trim(); - filesize = filesize.TrimEnd(new char[] { (char)0 }); + throw; + } + + // Path has been read, write to file system + if(path != null) + { + string target = Path.Combine(destinationPath, path); + Uplift.Common.FileSystemUtil.EnsureParentExists(target); - //Convert the octal string to a decimal number - try + // Asset or not? (ie directory) + if(rawAsset == null) { - int filesizeInt = Convert.ToInt32(filesize, 8); - int toRead = filesizeInt; - int toWrite = filesizeInt; - int modulus = filesizeInt % tarBlockSize; - if (modulus > 0) - toRead += (tarBlockSize - modulus); //Read the file and assume it's also 512 byte padded - while (toRead > 0) - { - int readThisTime = Math.Min(readBufferSize, toRead); - int writeThisTime = Math.Min(readBufferSize, toWrite); - readBuffer = reader.ReadBytes(readThisTime); - if (extractPathName) - { - if (toRead > readThisTime) - throw new Exception("Assumed a pathname would fit in a single read!"); - string pathnameFileContents = Encoding.UTF8.GetString(readBuffer, 0, filesizeInt); - path = FormatPath(pathnameFileContents.Split(new char[] { '\n' })[0]); - Debug.Log(path); - } - else if(extractRawMeta) - { - if(rawMeta == null) rawMeta = new byte[0]; - int rawLength = rawMeta.Length; - Array.Resize(ref rawMeta, rawLength + writeThisTime); - Array.Copy(readBuffer, 0, rawMeta, rawLength, writeThisTime); - } - else if(extractRawAsset) - { - if(rawAsset == null) rawAsset = new byte[0]; - int rawLength = rawAsset.Length; - Array.Resize(ref rawAsset, rawLength + writeThisTime); - Array.Copy(readBuffer, 0, rawAsset, rawLength, writeThisTime); - } - toRead -= readThisTime; - toWrite -= writeThisTime; - } + Directory.CreateDirectory(target); } - catch (Exception ex) + else { - Debug.Log(String.Format("Caught Exception converting octal string to int: {0}", ex.Message)); - foreach (byte fsChar in filesize) + using(var tw = new StreamWriter(target, false, new UTF8Encoding(false))) { - Debug.Log(fsChar); + tw.BaseStream.Write(rawAsset, 0, rawAsset.Length); } - throw; + rawAsset = null; } - // Path has been read, write to file system - if(path != null) + // Create meta + if(rawMeta != null) { - string target = Path.Combine(destinationPath, path); - Uplift.Common.FileSystemUtil.EnsureParentExists(target); - - // Asset or not? (ie directory) - if(rawAsset == null) + using(var tw = new StreamWriter(target + ".meta", false, new UTF8Encoding(false))) { - Directory.CreateDirectory(target); + tw.BaseStream.Write(rawMeta, 0, rawMeta.Length); } - else - { - using(var tw = new StreamWriter(target, false, new UTF8Encoding(false))) - { - tw.BaseStream.Write(rawAsset, 0, rawAsset.Length); - } - rawAsset = null; - } - - // Create meta - if(rawMeta != null) - { - using(var tw = new StreamWriter(target + ".meta", false, new UTF8Encoding(false))) - { - tw.BaseStream.Write(rawMeta, 0, rawMeta.Length); - } - rawMeta = null; - } - - path = null; + rawMeta = null; } + + path = null; } } } diff --git a/Assets/Plugins/Editor/Uplift/Packages/PackageList.cs b/Assets/Plugins/Editor/Uplift/Packages/PackageList.cs index 1ad447b3..5c91e11a 100644 --- a/Assets/Plugins/Editor/Uplift/Packages/PackageList.cs +++ b/Assets/Plugins/Editor/Uplift/Packages/PackageList.cs @@ -80,16 +80,34 @@ public void RefreshPackages() public void LoadPackages(Repository repository) { - PackageRepo pr; - foreach (Upset package in repository.ListPackages()) + using(LogAggregator la = LogAggregator.InUnity( + "Packages successfully loaded from {0}", + "Packages successfully loaded from {0}, but warning were raised", + "Error(s) occured while loading packages from {0}", + repository.ToString() + )) { - pr = new PackageRepo + Upset[] packages; + try { - Package = package, - Repository = repository - }; - Packages.Add(pr); + packages = repository.ListPackages(); + } + catch(Exception e) + { + Debug.LogException(e); + return; + } + PackageRepo pr; + foreach (Upset package in packages) + { + pr = new PackageRepo + { + Package = package, + Repository = repository + }; + Packages.Add(pr); + } } } diff --git a/Assets/Plugins/Editor/Uplift/Schemas/Common_RepositoryTypes_Upbring_Upfile_UpfileOverride_Upset.cs b/Assets/Plugins/Editor/Uplift/Schemas/Common_RepositoryTypes_Upbring_Upfile_UpliftSettings_Upset.cs similarity index 81% rename from Assets/Plugins/Editor/Uplift/Schemas/Common_RepositoryTypes_Upbring_Upfile_UpfileOverride_Upset.cs rename to Assets/Plugins/Editor/Uplift/Schemas/Common_RepositoryTypes_Upbring_Upfile_UpliftSettings_Upset.cs index 28bf94b4..e35b594e 100644 --- a/Assets/Plugins/Editor/Uplift/Schemas/Common_RepositoryTypes_Upbring_Upfile_UpfileOverride_Upset.cs +++ b/Assets/Plugins/Editor/Uplift/Schemas/Common_RepositoryTypes_Upbring_Upfile_UpliftSettings_Upset.cs @@ -1,4 +1,4 @@ -// --- BEGIN LICENSE BLOCK --- +// --- BEGIN LICENSE BLOCK --- /* * Copyright (c) 2017-present WeWantToKnow AS * @@ -22,24 +22,25 @@ */ // --- END LICENSE BLOCK --- -// ------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Mono Runtime Version: 4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -// ------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +// +// Ce code a été généré par un outil. +// Version du runtime :2.0.50727.8825 +// +// Les modifications apportées à ce fichier peuvent provoquer un comportement incorrect et seront perdues si +// le code est régénéré. +// +//------------------------------------------------------------------------------ // -//This source code was auto-generated by MonoXSD -// +// This source code was auto-generated by xsd, Version=2.0.50727.3038. +// namespace Uplift.Schemas { + using System.Xml.Serialization; /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "0.0.0.0")] + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] @@ -61,7 +62,7 @@ public InstalledPackage[] InstalledPackage { } /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "0.0.0.0")] + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] @@ -110,7 +111,7 @@ public string Version { /// [System.Xml.Serialization.XmlIncludeAttribute(typeof(InstallSpecGUID))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(InstallSpecPath))] - [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "0.0.0.0")] + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] @@ -170,7 +171,7 @@ public string Value { } /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "0.0.0.0")] + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] [System.SerializableAttribute()] public enum InstallSpecType { @@ -200,7 +201,7 @@ public enum InstallSpecType { } /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "0.0.0.0")] + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] [System.SerializableAttribute()] public enum PlatformType { @@ -215,235 +216,215 @@ public enum PlatformType { } /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "0.0.0.0")] + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] - public partial class OverrideDestinationSpec { - - private InstallSpecType typeField; - - private string locationField; + public partial class InstallSpecGUID : InstallSpec { - /// - [System.Xml.Serialization.XmlAttributeAttribute()] - public InstallSpecType Type { - get { - return this.typeField; - } - set { - this.typeField = value; - } - } + private string guidField; /// [System.Xml.Serialization.XmlAttributeAttribute()] - public string Location { + public string Guid { get { - return this.locationField; + return this.guidField; } set { - this.locationField = value; + this.guidField = value; } } } /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "0.0.0.0")] + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] - public partial class SkipInstallSpec { + public partial class InstallSpecPath : InstallSpec { - private InstallSpecType typeField; + private string pathField; /// [System.Xml.Serialization.XmlAttributeAttribute()] - public InstallSpecType Type { + public string Path { get { - return this.typeField; + return this.pathField; } set { - this.typeField = value; + this.pathField = value; } } } /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "0.0.0.0")] + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] - public partial class DependencyDefinition { - - private SkipInstallSpec[] skipInstallField; - - private OverrideDestinationSpec[] overrideDestinationField; + [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)] + public partial class Upfile { - private string nameField; + private string unityVersionField; - private string versionField; + private Configuration configurationField; - private string repositoryField; + private Repository[] repositoriesField; - /// - [System.Xml.Serialization.XmlArrayItemAttribute("Skip", IsNullable=false)] - public SkipInstallSpec[] SkipInstall { - get { - return this.skipInstallField; - } - set { - this.skipInstallField = value; - } - } + private DependencyDefinition[] dependenciesField; /// - [System.Xml.Serialization.XmlArrayItemAttribute("Override", IsNullable=false)] - public OverrideDestinationSpec[] OverrideDestination { + public string UnityVersion { get { - return this.overrideDestinationField; + return this.unityVersionField; } set { - this.overrideDestinationField = value; + this.unityVersionField = value; } } /// - [System.Xml.Serialization.XmlAttributeAttribute()] - public string Name { + public Configuration Configuration { get { - return this.nameField; + return this.configurationField; } set { - this.nameField = value; + this.configurationField = value; } } /// - [System.Xml.Serialization.XmlAttributeAttribute()] - public string Version { + [System.Xml.Serialization.XmlArrayItemAttribute(typeof(FileRepository), IsNullable=false)] + [System.Xml.Serialization.XmlArrayItemAttribute(typeof(GitRepository), IsNullable=false)] + [System.Xml.Serialization.XmlArrayItemAttribute(typeof(GithubRepository), IsNullable=false)] + [System.Xml.Serialization.XmlArrayItemAttribute(typeof(WebRepository), IsNullable=false)] + public Repository[] Repositories { get { - return this.versionField; + return this.repositoriesField; } set { - this.versionField = value; + this.repositoriesField = value; } } /// - [System.Xml.Serialization.XmlAttributeAttribute()] - public string Repository { + [System.Xml.Serialization.XmlArrayItemAttribute("Package", IsNullable=false)] + public DependencyDefinition[] Dependencies { get { - return this.repositoryField; + return this.dependenciesField; } set { - this.repositoryField = value; + this.dependenciesField = value; } } } /// - [System.Xml.Serialization.XmlIncludeAttribute(typeof(FileRepository))] - [System.Xml.Serialization.XmlIncludeAttribute(typeof(GitRepository))] - [System.Xml.Serialization.XmlIncludeAttribute(typeof(WebRepository))] - [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "0.0.0.0")] + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] - public partial class Repository { + public partial class Configuration { - private string extractPathField; + private PathConfiguration repositoryPathField; - private string valueField; + private PathConfiguration docsPathField; + + private PathConfiguration examplesPathField; + + private PathConfiguration baseInstallPathField; + + private PathConfiguration mediaPathField; + + private PathConfiguration gizmoPathField; + + private PathConfiguration pluginPathField; + + private PathConfiguration editorPluginPathField; /// - [System.Xml.Serialization.XmlAttributeAttribute()] - public string ExtractPath { + public PathConfiguration RepositoryPath { get { - return this.extractPathField; + return this.repositoryPathField; } set { - this.extractPathField = value; + this.repositoryPathField = value; } } /// - [System.Xml.Serialization.XmlTextAttribute()] - public string Value { + public PathConfiguration DocsPath { get { - return this.valueField; + return this.docsPathField; } set { - this.valueField = value; + this.docsPathField = value; } } - } - - /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "0.0.0.0")] - [System.SerializableAttribute()] - [System.Diagnostics.DebuggerStepThroughAttribute()] - [System.ComponentModel.DesignerCategoryAttribute("code")] - public partial class FileRepository : Repository { - private string pathField; + /// + public PathConfiguration ExamplesPath { + get { + return this.examplesPathField; + } + set { + this.examplesPathField = value; + } + } /// - [System.Xml.Serialization.XmlAttributeAttribute()] - public string Path { + public PathConfiguration BaseInstallPath { get { - return this.pathField; + return this.baseInstallPathField; } set { - this.pathField = value; + this.baseInstallPathField = value; } } - } - - /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "0.0.0.0")] - [System.SerializableAttribute()] - [System.Diagnostics.DebuggerStepThroughAttribute()] - [System.ComponentModel.DesignerCategoryAttribute("code")] - public partial class GitRepository : Repository { - private string urlField; + /// + public PathConfiguration MediaPath { + get { + return this.mediaPathField; + } + set { + this.mediaPathField = value; + } + } /// - [System.Xml.Serialization.XmlAttributeAttribute(DataType="anyURI")] - public string Url { + public PathConfiguration GizmoPath { get { - return this.urlField; + return this.gizmoPathField; } set { - this.urlField = value; + this.gizmoPathField = value; } } - } - - /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "0.0.0.0")] - [System.SerializableAttribute()] - [System.Diagnostics.DebuggerStepThroughAttribute()] - [System.ComponentModel.DesignerCategoryAttribute("code")] - public partial class WebRepository : Repository { - private string urlField; + /// + public PathConfiguration PluginPath { + get { + return this.pluginPathField; + } + set { + this.pluginPathField = value; + } + } /// - [System.Xml.Serialization.XmlAttributeAttribute(DataType="anyURI")] - public string Url { + public PathConfiguration EditorPluginPath { get { - return this.urlField; + return this.editorPluginPathField; } set { - this.urlField = value; + this.editorPluginPathField = value; } } } /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "0.0.0.0")] + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] @@ -503,190 +484,271 @@ public string Value { } /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "0.0.0.0")] + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] - public partial class Configuration { - - private PathConfiguration repositoryPathField; - - private PathConfiguration docsPathField; - - private PathConfiguration examplesPathField; + public partial class FileRepository : Repository { - private PathConfiguration baseInstallPathField; + private string pathField; - private PathConfiguration mediaPathField; + /// + [System.Xml.Serialization.XmlAttributeAttribute()] + public string Path { + get { + return this.pathField; + } + set { + this.pathField = value; + } + } + } + + /// + [System.Xml.Serialization.XmlIncludeAttribute(typeof(FileRepository))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(GitRepository))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(GithubRepository))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(WebRepository))] + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] + [System.SerializableAttribute()] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + public partial class Repository { - private PathConfiguration gizmoPathField; + private string extractPathField; - private PathConfiguration pluginPathField; + /// + [System.Xml.Serialization.XmlAttributeAttribute()] + public string ExtractPath { + get { + return this.extractPathField; + } + set { + this.extractPathField = value; + } + } + } + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] + [System.SerializableAttribute()] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + public partial class GitRepository : Repository { - private PathConfiguration editorPluginPathField; + private string urlField; /// - public PathConfiguration RepositoryPath { + [System.Xml.Serialization.XmlAttributeAttribute(DataType="anyURI")] + public string Url { get { - return this.repositoryPathField; + return this.urlField; } set { - this.repositoryPathField = value; + this.urlField = value; } } + } + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] + [System.SerializableAttribute()] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + public partial class GithubRepository : Repository { + + private string[] tagListField; + + private string urlField; /// - public PathConfiguration DocsPath { + [System.Xml.Serialization.XmlArrayItemAttribute("Tag", IsNullable=false)] + public string[] TagList { get { - return this.docsPathField; + return this.tagListField; } set { - this.docsPathField = value; + this.tagListField = value; } } /// - public PathConfiguration ExamplesPath { + [System.Xml.Serialization.XmlAttributeAttribute(DataType="anyURI")] + public string Url { get { - return this.examplesPathField; + return this.urlField; } set { - this.examplesPathField = value; + this.urlField = value; } } + } + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] + [System.SerializableAttribute()] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + public partial class WebRepository : Repository { + + private string urlField; /// - public PathConfiguration BaseInstallPath { + [System.Xml.Serialization.XmlAttributeAttribute(DataType="anyURI")] + public string Url { get { - return this.baseInstallPathField; + return this.urlField; } set { - this.baseInstallPathField = value; + this.urlField = value; } } + } + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] + [System.SerializableAttribute()] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + public partial class DependencyDefinition { + + private SkipInstallSpec[] skipInstallField; + + private OverrideDestinationSpec[] overrideDestinationField; + + private string nameField; + + private string versionField; + + private string repositoryField; /// - public PathConfiguration MediaPath { + [System.Xml.Serialization.XmlArrayItemAttribute("Skip", IsNullable=false)] + public SkipInstallSpec[] SkipInstall { get { - return this.mediaPathField; + return this.skipInstallField; } set { - this.mediaPathField = value; + this.skipInstallField = value; } } /// - public PathConfiguration GizmoPath { + [System.Xml.Serialization.XmlArrayItemAttribute("Override", IsNullable=false)] + public OverrideDestinationSpec[] OverrideDestination { get { - return this.gizmoPathField; + return this.overrideDestinationField; } set { - this.gizmoPathField = value; + this.overrideDestinationField = value; } } /// - public PathConfiguration PluginPath { + [System.Xml.Serialization.XmlAttributeAttribute()] + public string Name { get { - return this.pluginPathField; + return this.nameField; } set { - this.pluginPathField = value; + this.nameField = value; } } /// - public PathConfiguration EditorPluginPath { + [System.Xml.Serialization.XmlAttributeAttribute()] + public string Version { get { - return this.editorPluginPathField; + return this.versionField; } set { - this.editorPluginPathField = value; + this.versionField = value; } } - } - - /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "0.0.0.0")] - [System.SerializableAttribute()] - [System.Diagnostics.DebuggerStepThroughAttribute()] - [System.ComponentModel.DesignerCategoryAttribute("code")] - public partial class InstallSpecGUID : InstallSpec { - - private string guidField; /// [System.Xml.Serialization.XmlAttributeAttribute()] - public string Guid { + public string Repository { get { - return this.guidField; + return this.repositoryField; } set { - this.guidField = value; + this.repositoryField = value; } } } /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "0.0.0.0")] + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] - public partial class InstallSpecPath : InstallSpec { + public partial class SkipInstallSpec { - private string pathField; + private InstallSpecType typeField; /// [System.Xml.Serialization.XmlAttributeAttribute()] - public string Path { + public InstallSpecType Type { get { - return this.pathField; + return this.typeField; } set { - this.pathField = value; + this.typeField = value; } } } /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "0.0.0.0")] + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] - [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)] - public partial class Upfile { - - private string unityVersionField; - - private Configuration configurationField; + public partial class OverrideDestinationSpec { - private Repository[] repositoriesField; + private InstallSpecType typeField; - private DependencyDefinition[] dependenciesField; + private string locationField; /// - public string UnityVersion { + [System.Xml.Serialization.XmlAttributeAttribute()] + public InstallSpecType Type { get { - return this.unityVersionField; + return this.typeField; } set { - this.unityVersionField = value; + this.typeField = value; } } /// - public Configuration Configuration { + [System.Xml.Serialization.XmlAttributeAttribute()] + public string Location { get { - return this.configurationField; + return this.locationField; } set { - this.configurationField = value; + this.locationField = value; } } + } + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] + [System.SerializableAttribute()] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)] + public partial class UpliftSettings { + + private Repository[] repositoriesField; + + private RepositoryToken[] authenticationMethodsField; /// [System.Xml.Serialization.XmlArrayItemAttribute(typeof(FileRepository), IsNullable=false)] [System.Xml.Serialization.XmlArrayItemAttribute(typeof(GitRepository), IsNullable=false)] + [System.Xml.Serialization.XmlArrayItemAttribute(typeof(GithubRepository), IsNullable=false)] [System.Xml.Serialization.XmlArrayItemAttribute(typeof(WebRepository), IsNullable=false)] public Repository[] Repositories { get { @@ -698,43 +760,75 @@ public Repository[] Repositories { } /// - [System.Xml.Serialization.XmlArrayItemAttribute("Package", IsNullable=false)] - public DependencyDefinition[] Dependencies { + [System.Xml.Serialization.XmlArrayItemAttribute(IsNullable=false)] + public RepositoryToken[] AuthenticationMethods { get { - return this.dependenciesField; + return this.authenticationMethodsField; } set { - this.dependenciesField = value; + this.authenticationMethodsField = value; } } } /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "0.0.0.0")] + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] - [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)] - public partial class UpfileOverride { + public partial class RepositoryToken : RepositoryAuthentication { - private Repository[] repositoriesField; + private string tokenField; /// - [System.Xml.Serialization.XmlArrayItemAttribute(typeof(FileRepository), IsNullable=false)] - [System.Xml.Serialization.XmlArrayItemAttribute(typeof(GitRepository), IsNullable=false)] - [System.Xml.Serialization.XmlArrayItemAttribute(typeof(WebRepository), IsNullable=false)] - public Repository[] Repositories { + [System.Xml.Serialization.XmlAttributeAttribute()] + public string Token { get { - return this.repositoriesField; + return this.tokenField; } set { - this.repositoriesField = value; + this.tokenField = value; + } + } + } + + /// + [System.Xml.Serialization.XmlIncludeAttribute(typeof(RepositoryToken))] + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] + [System.SerializableAttribute()] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + public abstract partial class RepositoryAuthentication { + + private string repositoryField; + + private string valueField; + + /// + [System.Xml.Serialization.XmlAttributeAttribute()] + public string Repository { + get { + return this.repositoryField; + } + set { + this.repositoryField = value; + } + } + + /// + [System.Xml.Serialization.XmlTextAttribute()] + public string Value { + get { + return this.valueField; + } + set { + this.valueField = value; } } } /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "0.0.0.0")] + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] diff --git a/Assets/Plugins/Editor/Uplift/Schemas/Common_RepositoryTypes_Upbring_Upfile_UpfileOverride_Upset.cs.meta b/Assets/Plugins/Editor/Uplift/Schemas/Common_RepositoryTypes_Upbring_Upfile_UpliftSettings_Upset.cs.meta similarity index 76% rename from Assets/Plugins/Editor/Uplift/Schemas/Common_RepositoryTypes_Upbring_Upfile_UpfileOverride_Upset.cs.meta rename to Assets/Plugins/Editor/Uplift/Schemas/Common_RepositoryTypes_Upbring_Upfile_UpliftSettings_Upset.cs.meta index 0f765427..8d697798 100644 --- a/Assets/Plugins/Editor/Uplift/Schemas/Common_RepositoryTypes_Upbring_Upfile_UpfileOverride_Upset.cs.meta +++ b/Assets/Plugins/Editor/Uplift/Schemas/Common_RepositoryTypes_Upbring_Upfile_UpliftSettings_Upset.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: f31c05a22425a4105acbdb8ac0e7787e -timeCreated: 1502376553 +guid: 5339aac872f92114eae5f79f9e64ef45 +timeCreated: 1511774104 licenseType: Free MonoImporter: serializedVersion: 2 diff --git a/Assets/Plugins/Editor/Uplift/Schemas/Extensions/Upfile.cs b/Assets/Plugins/Editor/Uplift/Schemas/Extensions/Upfile.cs index bf5e59d2..9b2b71ab 100644 --- a/Assets/Plugins/Editor/Uplift/Schemas/Extensions/Upfile.cs +++ b/Assets/Plugins/Editor/Uplift/Schemas/Extensions/Upfile.cs @@ -73,7 +73,7 @@ internal static void InitializeInstance() // --- CLASS DECLARATION --- public static readonly string upfilePath = "Upfile.xml"; - public static readonly string globalOverridePath = ".Upfile.xml"; + public string overridePath; public static bool CheckForUpfile() { @@ -128,7 +128,7 @@ public void SaveFile() // Set Repositories foreach(Repository repo in Repositories) - if(!GetOverrides(GetOverrideFilePath()).Any(extraRepo => + if(!GetRepositoryOverrides().Any(extraRepo => extraRepo is FileRepository && Uplift.Common.FileSystemUtil.MakePathOSFriendly((extraRepo as FileRepository).Path) == Uplift.Common.FileSystemUtil.MakePathOSFriendly((repo as FileRepository).Path) )) @@ -242,37 +242,12 @@ private void AddOrReplaceDependency(XmlDocument document, DependencyDefinition d public virtual void LoadOverrides() { - string overrideFilePath = GetOverrideFilePath(); - - try - { - LoadOverrides(overrideFilePath); - } - catch (Exception e) - { - throw new ApplicationException("Uplift: Could not load Upfile overrides from "+overrideFilePath, e); - } - } - - internal virtual string GetOverrideFilePath() - { - string homePath = (Environment.OSVersion.Platform == PlatformID.Unix || - Environment.OSVersion.Platform == PlatformID.MacOSX) - ? Environment.GetEnvironmentVariable("HOME") - : Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%"); - - return Path.Combine(homePath, globalOverridePath); - } - - internal virtual void LoadOverrides(string path) - { - Repository[] overrides = GetOverrides(path); - + Repository[] overrides = GetRepositoryOverrides(); if (Repositories == null) { Repositories = overrides; } - else if(overrides != null) + else if(overrides != null) { int repositoriesSize = Repositories.Length + overrides.Length; @@ -283,35 +258,23 @@ internal virtual void LoadOverrides(string path) Repositories = newRepositoryArray; } } - internal virtual Repository[] GetOverrides(string path) - { - // If we don't have override file, ignore - if (!File.Exists(path)) return null; - StrictXmlDeserializer deserializer = new StrictXmlDeserializer(); - - using (FileStream fs = new FileStream(path, FileMode.Open)) + internal Repository[] GetRepositoryOverrides() + { + Repository[] result = new Repository[0]; + try { - try - { - UpfileOverride upOverride = deserializer.Deserialize(fs); - - foreach (Repository repo in upOverride.Repositories) - { - if (repo is FileRepository) - (repo as FileRepository).Path = Uplift.Common.FileSystemUtil.MakePathOSFriendly((repo as FileRepository).Path); - } - - return upOverride.Repositories; - } - catch (InvalidOperationException) - { - Debug.LogError(string.Format("Global Override file at {0} is not well formed", path)); - return null; - } + result = string.IsNullOrEmpty(overridePath) ? + UpliftSettings.FromDefaultFile().Repositories : + UpliftSettings.FromFile(overridePath).Repositories; + } + catch (Exception e) + { + Debug.LogError("Could not load repositories overrides from .Uplift file\n" + e); } - } + return result; + } public string GetPackagesRootPath() { diff --git a/Assets/Plugins/Editor/Uplift/Schemas/Extensions/UpliftSettings.cs b/Assets/Plugins/Editor/Uplift/Schemas/Extensions/UpliftSettings.cs new file mode 100644 index 00000000..8e402f1b --- /dev/null +++ b/Assets/Plugins/Editor/Uplift/Schemas/Extensions/UpliftSettings.cs @@ -0,0 +1,93 @@ +// --- BEGIN LICENSE BLOCK --- +/* + * Copyright (c) 2017-present WeWantToKnow AS + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +// --- END LICENSE BLOCK --- + +using System; +using System.IO; +using System.Xml.Serialization; +using UnityEngine; +using Uplift.Common; +using FileSystemUtil = Uplift.Common.FileSystemUtil; + +namespace Uplift.Schemas +{ + public partial class UpliftSettings + { + public static readonly string folderName = ".uplift"; + public static readonly string defaultFileName = "settings.xml"; + + internal UpliftSettings() {} + + public static UpliftSettings FromDefaultFile() + { + string sourceDir = System.IO.Path.Combine(GetHomePath(), folderName); + string source = System.IO.Path.Combine(sourceDir, defaultFileName); + + return FromFile(source); + } + + public static UpliftSettings FromFile(string source) + { + UpliftSettings result = new UpliftSettings { Repositories = new Repository[0], AuthenticationMethods = new RepositoryToken[0] }; + + if(!File.Exists(source)) + { + Debug.Log("No local settings file detected at " + source); + return result; + } + + StrictXmlDeserializer deserializer = new StrictXmlDeserializer(); + + using (FileStream fs = new FileStream(source, FileMode.Open)) + { + try + { + result = deserializer.Deserialize(fs); + } + catch (InvalidOperationException) + { + Debug.LogError(string.Format("Global Override file at {0} is not well formed", source)); + return result; + } + + foreach (Repository repo in result.Repositories) + { + if (repo is FileRepository) + (repo as FileRepository).Path = FileSystemUtil.MakePathOSFriendly((repo as FileRepository).Path); + } + + return result; + } + } + + public static string GetHomePath() + { + return (Environment.OSVersion.Platform == PlatformID.Unix || + Environment.OSVersion.Platform == PlatformID.MacOSX) + ? Environment.GetEnvironmentVariable("HOME") + : Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%"); + } + + + } +} \ No newline at end of file diff --git a/Assets/Plugins/Editor/Uplift/Schemas/Extensions/UpliftSettings.cs.meta b/Assets/Plugins/Editor/Uplift/Schemas/Extensions/UpliftSettings.cs.meta new file mode 100644 index 00000000..05d0be09 --- /dev/null +++ b/Assets/Plugins/Editor/Uplift/Schemas/Extensions/UpliftSettings.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 9a9abfd729e23ce4dbb509e04d6ed67c +timeCreated: 1511774105 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/Editor/Uplift/Schemas/Repositories/GithubRepository.cs b/Assets/Plugins/Editor/Uplift/Schemas/Repositories/GithubRepository.cs new file mode 100644 index 00000000..74a24115 --- /dev/null +++ b/Assets/Plugins/Editor/Uplift/Schemas/Repositories/GithubRepository.cs @@ -0,0 +1,158 @@ +// --- BEGIN LICENSE BLOCK --- +/* + * Copyright (c) 2017-present WeWantToKnow AS + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +// --- END LICENSE BLOCK --- + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Threading; +using System.Linq; +using System.IO; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; +using Uplift.Common; +using Uplift.GitHubModule; +using System.Net; +using System.Security.Cryptography.X509Certificates; + +namespace Uplift.Schemas +{ + public partial class GithubRepository : Repository + { + private GitHubRelease[] releases; + + public override TemporaryDirectory DownloadPackage(Upset package) + { + string sourceName = Regex.Replace(package.MetaInformation.dirName, ".Upset.xml$", ".unitypackage", RegexOptions.IgnoreCase); + + releases = GetPackagesReleases(); + GitHubRelease release = releases.FirstOrDefault(rel => rel.assets.Any(asset => asset.name.Contains(sourceName))); + + if(release == null) + throw new ArgumentException(string.Format("Package {0} is not present in this repository", package.PackageName)); + + GitHubAsset packageAsset = release.assets.First(asset => asset.name.Contains(sourceName)); + TemporaryDirectory td = new TemporaryDirectory(); + using(StreamReader sr = new StreamReader(GitHub.GetAssetStream(packageAsset, GetToken()))) + { + UnityPackage unityPackage = new UnityPackage(); + unityPackage.Extract(sr.BaseStream, td.Path); + } + return td; + } + + public override Upset[] ListPackages() + { + releases = GetPackagesReleases(); + + GitHubAsset[] upsetAssets = releases + .SelectMany(rel => rel.assets.Where(asset => asset.name.EndsWith("Upset.xml"))) + .ToArray(); + + string progressBarTitle = "Parsing Upsets from GitHub repository"; + int index = 0; + + List upsetList = new List(); + EditorUtility.DisplayProgressBar(progressBarTitle, "Please wait a little bit while Uplift parses the Upset in the GitHub repository at " + urlField, 0f); + foreach(GitHubAsset asset in upsetAssets) + { + StrictXmlDeserializer deserializer = new StrictXmlDeserializer(); + + EditorUtility.DisplayProgressBar( + progressBarTitle, + "Parsing " + asset.name, + (float)(index++) / upsetAssets.Length + ); + + using(StreamReader sr = new StreamReader(GitHub.GetAssetStream(asset, GetToken()))) + { + Upset upset = deserializer.Deserialize(sr.BaseStream); + upset.MetaInformation.dirName = asset.name; + upsetList.Add(upset); + } + } + + EditorUtility.ClearProgressBar(); + return upsetList.ToArray(); + } + + private GitHubRelease[] GetPackagesReleases() + { + if(releases == null) + { + IEnumerator e = GitHub.LoadReleases(urlField, GetToken()); + do { Thread.Sleep(1000); } while (e.MoveNext()); + + GitHubRelease[] fetchedReleases = (GitHubRelease[]) e.Current; + + if (fetchedReleases == null) + throw new ApplicationException("This github repository does not have releases"); + + string[] tagArray = (tagListField == null || tagListField.Length == 0) ? + new string[] { "packages" } : + tagListField; + + releases = fetchedReleases.Where(rel => tagArray.Contains(rel.tag)).ToArray(); + + // Fail hard if no release could be found + if (releases.Length == 0) + throw new ApplicationException("This repository does not have a release correctly tagged"); + + // Logs missing tags if only some of them were found + if (releases.Length < tagArray.Length) + { + string missingTags = string.Join( + ", ", + tagArray.Where(tag => !releases.Any(rel => rel.tag == tag)).ToArray() + ); + + Debug.LogWarningFormat("Could not find a matching release for all of your tags (missing {0})", missingTags); + } + } + + return releases; + } + + private string GetToken() + { + UpliftSettings dotUplift = UpliftSettings.FromDefaultFile(); + if(dotUplift.AuthenticationMethods != null) + foreach(RepositoryAuthentication auth in dotUplift.AuthenticationMethods) + { + if(!(auth is RepositoryToken)) continue; + if(!(auth.Repository == urlField)) continue; + + return (auth as RepositoryToken).Token; + } + + Debug.LogWarning("Could not find authentication method for repository at " + urlField); + return null; + } + + public override string ToString() + { + return "GithubRepository: " + urlField; + } + } +} diff --git a/Assets/Plugins/Editor/Uplift/Schemas/Repositories/GithubRepository.cs.meta b/Assets/Plugins/Editor/Uplift/Schemas/Repositories/GithubRepository.cs.meta new file mode 100644 index 00000000..8e751e1e --- /dev/null +++ b/Assets/Plugins/Editor/Uplift/Schemas/Repositories/GithubRepository.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 84b62f3c29189fd4db839fac78188758 +timeCreated: 1511443550 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/Editor/Uplift/Schemas/RepositoryTypes.xsd b/Assets/Plugins/Editor/Uplift/Schemas/RepositoryTypes.xsd index 63501332..f6c2d9b3 100644 --- a/Assets/Plugins/Editor/Uplift/Schemas/RepositoryTypes.xsd +++ b/Assets/Plugins/Editor/Uplift/Schemas/RepositoryTypes.xsd @@ -6,38 +6,56 @@ - + - + + + + + + + + + + + - + - + - + - + - + - + + + + + + + + + diff --git a/Assets/Plugins/Editor/Uplift/Schemas/UpfileOverride.xsd b/Assets/Plugins/Editor/Uplift/Schemas/UpfileOverride.xsd deleted file mode 100644 index 2e8a2c01..00000000 --- a/Assets/Plugins/Editor/Uplift/Schemas/UpfileOverride.xsd +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - diff --git a/Assets/Plugins/Editor/Uplift/Schemas/UpliftSettings.xsd b/Assets/Plugins/Editor/Uplift/Schemas/UpliftSettings.xsd new file mode 100644 index 00000000..7def32e7 --- /dev/null +++ b/Assets/Plugins/Editor/Uplift/Schemas/UpliftSettings.xsd @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Assets/Plugins/Editor/Uplift/Schemas/UpfileOverride.xsd.meta b/Assets/Plugins/Editor/Uplift/Schemas/UpliftSettings.xsd.meta similarity index 64% rename from Assets/Plugins/Editor/Uplift/Schemas/UpfileOverride.xsd.meta rename to Assets/Plugins/Editor/Uplift/Schemas/UpliftSettings.xsd.meta index 9539f770..5e5d9c27 100644 --- a/Assets/Plugins/Editor/Uplift/Schemas/UpfileOverride.xsd.meta +++ b/Assets/Plugins/Editor/Uplift/Schemas/UpliftSettings.xsd.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 51d2d558af69e4d6f922b65714d5981b -timeCreated: 1502376553 +guid: e5bbfb085045cdc46bd5d2486d202994 +timeCreated: 1511774104 licenseType: Free DefaultImporter: userData: diff --git a/Assets/Plugins/Editor/Uplift/Testing/Helpers/UpfileExposer.cs b/Assets/Plugins/Editor/Uplift/Testing/Helpers/UpfileExposer.cs index 0c7bde4a..285c4196 100644 --- a/Assets/Plugins/Editor/Uplift/Testing/Helpers/UpfileExposer.cs +++ b/Assets/Plugins/Editor/Uplift/Testing/Helpers/UpfileExposer.cs @@ -82,11 +82,6 @@ internal static Upfile LoadTestXml(string path) return upfile; } } - - public override void LoadOverrides() - { - return; - } } } #endif diff --git a/Assets/Plugins/Editor/Uplift/Testing/UnitTesting/UpfileTest.cs b/Assets/Plugins/Editor/Uplift/Testing/UnitTesting/UpfileTest.cs index e079ab5a..8fc7c8d0 100644 --- a/Assets/Plugins/Editor/Uplift/Testing/UnitTesting/UpfileTest.cs +++ b/Assets/Plugins/Editor/Uplift/Testing/UnitTesting/UpfileTest.cs @@ -128,9 +128,10 @@ public void LoadXmlAbsent() public void LoadPresentOverrideTest() { string upfilePath = Helper.PathCombine ("TestData", "UpfileTest", "Upfile.xml"); - string upfileOverridePath = Helper.PathCombine ("TestData", "UpfileTest", "UpfileOverride.xml"); + string upfileOverridePath = Helper.PathCombine ("TestData", "UpfileTest", "UpliftSettings.xml"); Upfile upfile = Upfile.LoadXml(upfilePath); - upfile.LoadOverrides(upfileOverridePath); + upfile.overridePath = upfileOverridePath; + upfile.LoadOverrides(); Assert.IsTrue(upfile.Repositories.Any(repo => repo is FileRepository && string.Equals((repo as FileRepository).Path, Helper.PathCombine("Path","To","Some","Repository"))), "Original repository not found"); Assert.IsTrue(upfile.Repositories.Any(repo => repo is FileRepository && string.Equals((repo as FileRepository).Path, Helper.PathCombine("Path","To","Another","Repository"))), "Override repository not found"); @@ -140,9 +141,10 @@ public void LoadPresentOverrideTest() public void LoadAbsentOverrideTest() { string upfilePath = Helper.PathCombine ("TestData", "UpfileTest", "Upfile.xml"); - string upfileOverridePath = Helper.PathCombine ("TestData", "UpfileTest", "NoUpfileInIt", "UpfileOverride.xml"); + string upfileOverridePath = Helper.PathCombine ("TestData", "UpfileTest", "NoUpfileInIt", "UpliftSettings.xml"); Upfile upfile = Upfile.LoadXml(upfilePath); - upfile.LoadOverrides(upfileOverridePath); + upfile.overridePath = upfileOverridePath; + upfile.LoadOverrides(); Assert.IsTrue(upfile.Repositories.Any(repo => repo is FileRepository && string.Equals((repo as FileRepository).Path, Helper.PathCombine("Path","To","Some","Repository"))), "Original repository not found"); Assert.IsFalse(upfile.Repositories.Any(repo => repo is FileRepository && string.Equals((repo as FileRepository).Path, Helper.PathCombine("Path","To","Another","Repository"))), "Loaded absent file"); diff --git a/Assets/Plugins/Editor/Uplift/UpdateTool/Updater.cs b/Assets/Plugins/Editor/Uplift/UpdateTool/Updater.cs index 0405cbb1..619f67dd 100644 --- a/Assets/Plugins/Editor/Uplift/UpdateTool/Updater.cs +++ b/Assets/Plugins/Editor/Uplift/UpdateTool/Updater.cs @@ -46,151 +46,14 @@ public class Updater : MonoBehaviour private static readonly CultureInfo provider = CultureInfo.InvariantCulture; private static readonly string lastUpdateCheckKey = "UpliftLastUpdateCheck"; private static IEnumerator updateCoroutine; - private static readonly string[] githubCertificatesString = new string[] - { -// github.com -@"-----BEGIN CERTIFICATE----- -MIIHeTCCBmGgAwIBAgIQC/20CQrXteZAwwsWyVKaJzANBgkqhkiG9w0BAQsFADB1 -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVk -IFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE2MDMxMDAwMDAwMFoXDTE4MDUxNzEy -MDAwMFowgf0xHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYB -BAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQITCERlbGF3YXJlMRAwDgYDVQQF -Ewc1MTU3NTUwMSQwIgYDVQQJExs4OCBDb2xpbiBQIEtlbGx5LCBKciBTdHJlZXQx -DjAMBgNVBBETBTk0MTA3MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5p -YTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEVMBMGA1UEChMMR2l0SHViLCBJbmMu -MRMwEQYDVQQDEwpnaXRodWIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEA54hc8pZclxgcupjiA/F/OZGRwm/ZlucoQGTNTKmBEgNsrn/mxhngWmPw -bAvUaLP//T79Jc+1WXMpxMiz9PK6yZRRFuIo0d2bx423NA6hOL2RTtbnfs+y0PFS -/YTpQSelTuq+Fuwts5v6aAweNyMcYD0HBybkkdosFoDccBNzJ92Ac8I5EVDUc3Or -/4jSyZwzxu9kdmBlBzeHMvsqdH8SX9mNahXtXxRpwZnBiUjw36PgN+s9GLWGrafd -02T0ux9Yzd5ezkMxukqEAQ7AKIIijvaWPAJbK/52XLhIy2vpGNylyni/DQD18bBP -T+ZG1uv0QQP9LuY/joO+FKDOTler4wIDAQABo4IDejCCA3YwHwYDVR0jBBgwFoAU -PdNQpdagre7zSmAKZdMh1Pj41g8wHQYDVR0OBBYEFIhcSGcZzKB2WS0RecO+oqyH -IidbMCUGA1UdEQQeMByCCmdpdGh1Yi5jb22CDnd3dy5naXRodWIuY29tMA4GA1Ud -DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYDVR0f -BG4wbDA0oDKgMIYuaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItZXYtc2Vy -dmVyLWcxLmNybDA0oDKgMIYuaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTIt -ZXYtc2VydmVyLWcxLmNybDBLBgNVHSAERDBCMDcGCWCGSAGG/WwCATAqMCgGCCsG -AQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAcGBWeBDAEBMIGI -BggrBgEFBQcBAQR8MHowJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0 -LmNvbTBSBggrBgEFBQcwAoZGaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0Rp -Z2lDZXJ0U0hBMkV4dGVuZGVkVmFsaWRhdGlvblNlcnZlckNBLmNydDAMBgNVHRMB -Af8EAjAAMIIBfwYKKwYBBAHWeQIEAgSCAW8EggFrAWkAdgCkuQmQtBhYFIe7E6LM -Z3AKPDWYBPkb37jjd80OyA3cEAAAAVNhieoeAAAEAwBHMEUCIQCHHSEY/ROK2/sO -ljbKaNEcKWz6BxHJNPOtjSyuVnSn4QIgJ6RqvYbSX1vKLeX7vpnOfCAfS2Y8lB5R -NMwk6us2QiAAdgBo9pj4H2SCvjqM7rkoHUz8cVFdZ5PURNEKZ6y7T0/7xAAAAVNh -iennAAAEAwBHMEUCIQDZpd5S+3to8k7lcDeWBhiJASiYTk2rNAT26lVaM3xhWwIg -NUqrkIODZpRg+khhp8ag65B8mu0p4JUAmkRDbiYnRvYAdwBWFAaaL9fC7NP14b1E -sj7HRna5vJkRXMDvlJhV1onQ3QAAAVNhieqZAAAEAwBIMEYCIQDnm3WStlvE99GC -izSx+UGtGmQk2WTokoPgo1hfiv8zIAIhAPrYeXrBgseA9jUWWoB4IvmcZtshjXso -nT8MIG1u1zF8MA0GCSqGSIb3DQEBCwUAA4IBAQCLbNtkxuspqycq8h1EpbmAX0wM -5DoW7hM/FVdz4LJ3Kmftyk1yd8j/PSxRrAQN2Mr/frKeK8NE1cMji32mJbBqpWtK -/+wC+avPplBUbNpzP53cuTMF/QssxItPGNP5/OT9Aj1BxA/NofWZKh4ufV7cz3pY -RDS4BF+EEFQ4l5GY+yp4WJA/xSvYsTHWeWxRD1/nl62/Rd9FN2NkacRVozCxRVle -FrBHTFxqIP6kDnxiLElBrZngtY07ietaYZVLQN/ETyqLQftsf8TecwTklbjvm8NT -JqbaIVifYwqwNN+4lRxS3F5lNlA/il12IOgbRioLI62o8G0DaEUQgHNf8vSG ------END CERTIFICATE----- -", -// DigiCert High Assurance EV Root CA -@"-----BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j -ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 -LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug -RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm -+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW -PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM -xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB -Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 -hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg -EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA -FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec -nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z -eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF -hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 -Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe -vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep -+OkuE6N36B9K ------END CERTIFICATE----- -", -// DigiCert SHA2 Extended Validation Server CA -@"-----BEGIN CERTIFICATE----- -MIIEtjCCA56gAwIBAgIQDHmpRLCMEZUgkmFf4msdgzANBgkqhkiG9w0BAQsFADBs -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j -ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowdTEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 -LmRpZ2ljZXJ0LmNvbTE0MDIGA1UEAxMrRGlnaUNlcnQgU0hBMiBFeHRlbmRlZCBW -YWxpZGF0aW9uIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBANdTpARR+JmmFkhLZyeqk0nQOe0MsLAAh/FnKIaFjI5j2ryxQDji0/XspQUY -uD0+xZkXMuwYjPrxDKZkIYXLBxA0sFKIKx9om9KxjxKws9LniB8f7zh3VFNfgHk/ -LhqqqB5LKw2rt2O5Nbd9FLxZS99RStKh4gzikIKHaq7q12TWmFXo/a8aUGxUvBHy -/Urynbt/DvTVvo4WiRJV2MBxNO723C3sxIclho3YIeSwTQyJ3DkmF93215SF2AQh -cJ1vb/9cuhnhRctWVyh+HA1BV6q3uCe7seT6Ku8hI3UarS2bhjWMnHe1c63YlC3k -8wyd7sFOYn4XwHGeLN7x+RAoGTMCAwEAAaOCAUkwggFFMBIGA1UdEwEB/wQIMAYB -Af8CAQAwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF -BQcDAjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp -Z2ljZXJ0LmNvbTBLBgNVHR8ERDBCMECgPqA8hjpodHRwOi8vY3JsNC5kaWdpY2Vy -dC5jb20vRGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3JsMD0GA1UdIAQ2 -MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5j -b20vQ1BTMB0GA1UdDgQWBBQ901Cl1qCt7vNKYApl0yHU+PjWDzAfBgNVHSMEGDAW -gBSxPsNpA/i/RwHUmCYaCALvY2QrwzANBgkqhkiG9w0BAQsFAAOCAQEAnbbQkIbh -hgLtxaDwNBx0wY12zIYKqPBKikLWP8ipTa18CK3mtlC4ohpNiAexKSHc59rGPCHg -4xFJcKx6HQGkyhE6V6t9VypAdP3THYUYUN9XR3WhfVUgLkc3UHKMf4Ib0mKPLQNa -2sPIoc4sUqIAY+tzunHISScjl2SFnjgOrWNoPLpSgVh5oywM395t6zHyuqB8bPEs -1OG9d4Q3A84ytciagRpKkk47RpqF/oOi+Z6Mo8wNXrM9zwR4jxQUezKcxwCmXMS1 -oVWNWlZopCJwqjyBcdmdqEU79OX2olHdx3ti6G8MdOu42vi/hw15UJGQmxg7kVkn -8TUoE6smftX3eg== ------END CERTIFICATE----- -", -// Amazon S3 (provider for the release download) *.s3.amazonaws.com -@"-----BEGIN CERTIFICATE----- -MIIFWjCCBEKgAwIBAgIQBVG1kvpTzyBSuLcPJ1zBWTANBgkqhkiG9w0BAQsFADBk -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSMwIQYDVQQDExpEaWdpQ2VydCBCYWx0aW1vcmUgQ0Et -MiBHMjAeFw0xNzA5MjIwMDAwMDBaFw0xOTAxMDMxMjAwMDBaMGsxCzAJBgNVBAYT -AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdTZWF0dGxlMRgwFgYD -VQQKEw9BbWF6b24uY29tIEluYy4xGzAZBgNVBAMMEiouczMuYW1hem9uYXdzLmNv -bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKK5it42LH/8WFaEE7O9 -4XJMg48TengCM25C9O0dUaPGOnZ1+oGf7DNvdo/MGVoAW5hfPX9WqjY30KyuKiFv -8uAbyX+9Bzq8KMLjdvGxzYMqbSxeAPSBf1yMdCyDEc8gW+vh2uXO+x9QePgiOAoO -qujLzyS/p7pSWPUKUH8kpMgP99RPoD/lRNbPAFr3QeJr7D/x3xNTKBHCbpE4SxBH -QM02GCu2DSYQtgm3hfZmD79BB1Ej4U1vM0hgiOu9eFLwmycbnrnU8sa4DkvmUJlv -xiIP5PvNweawm/QeoH6Qk/zDF30nr+5Av9IUhE4uAhl1H2OMqPp79SfJ2wxtvmNt -3z0CAwEAAaOCAf8wggH7MB8GA1UdIwQYMBaAFMASsih0aEZn6XAldBoARVsGfVxE -MB0GA1UdDgQWBBSQFZo7H1VA7uODvdTP1I6idMLqyDAvBgNVHREEKDAmghIqLnMz -LmFtYXpvbmF3cy5jb22CEHMzLmFtYXpvbmF3cy5jb20wDgYDVR0PAQH/BAQDAgWg -MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjCBgQYDVR0fBHoweDA6oDig -NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QmFsdGltb3JlQ0Et -MkcyLmNybDA6oDigNoY0aHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0 -QmFsdGltb3JlQ0EtMkcyLmNybDBMBgNVHSAERTBDMDcGCWCGSAGG/WwBATAqMCgG -CCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAgGBmeBDAEC -AjB5BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2lj -ZXJ0LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29t -L0RpZ2lDZXJ0QmFsdGltb3JlQ0EtMkcyLmNydDAMBgNVHRMBAf8EAjAAMA0GCSqG -SIb3DQEBCwUAA4IBAQBydwnbmrwTTwhtCckZ9lDGoE+tdDFchjFG59dyzX1I4bHV -thVUwjEoc3VxngvmKb3cqLcHzXHNdoEdffRtw0IiEerPRsk7Nxh2p1HWR3cu/Hyp -kqGlObJADiw1DX4UDob735hevqcGN9M0rn9P/AbPK0HCn5uokLDmbeqe6u1YgdJL -m4skA/WsUsMCfsZY27RiZ+B162+laDD0oRiovOx5zKrzG/3yAFVutz2Bfud3QenU -3zt14ttnzFCcMlglW9oqffHMwQ1Smx/30ccDonoa1E02hnNmxeLyBwomPqd/ZYy6 -zSJW0aSi1DadkZsifpr65AwgSuN5uGEhQas0glsN ------END CERTIFICATE----- -" - }; - private static bool trustUnknown; public static void UpdateUplift(string url) { - trustUnknown = UpliftPreferences.TrustUnknownCertificates(); string unitypackageName = url.Split('/').Last(); DirectoryInfo assetsPath = new DirectoryInfo(Application.dataPath); string destination = Path.Combine(assetsPath.Parent.FullName, unitypackageName); - ServicePointManager.ServerCertificateValidationCallback = CertificateValidationCallback; + ServicePointManager.ServerCertificateValidationCallback = GitHub.CertificateValidationCallback; using (var client = new WebClient()) { client.DownloadFile(url, destination); @@ -255,49 +118,5 @@ private static IEnumerator CheckForUpdateRoutine() { DateTime.UtcNow.ToString(dateFormat, provider) ); } - - private static bool CertificateValidationCallback( - System.Object sender, - X509Certificate certificate, - X509Chain chain, - SslPolicyErrors sslPolicyErrors - ) - { - bool correct = true; - if(sslPolicyErrors == SslPolicyErrors.None) return true; - - X509Certificate[] githubCertificates = new X509Certificate[githubCertificatesString.Length]; - for(int i = 0; i < githubCertificatesString.Length; i++) - { - githubCertificates[i] = new X509Certificate(); - githubCertificates[i].Import(Encoding.ASCII.GetBytes(githubCertificatesString[i])); - } - - if(!(githubCertificates.Any(cert => cert.GetCertHashString() == certificate.GetCertHashString()) || trustUnknown)) - { - Debug.LogErrorFormat("The received certificate ({0}) is not known by Uplift. We cannot download the update package. You could update Uplift manually, or go to Preferences and set 'Trust unknown certificates' to true.", certificate.GetCertHashString()); - Debug.Log("Known certificates are:"); - foreach(X509Certificate cert in githubCertificates) - Debug.Log(" -- " + cert.GetCertHashString()); - return false; - } - - for (int i=0; i < chain.ChainStatus.Length; i++) { - if (chain.ChainStatus[i].Status == X509ChainStatusFlags.RevocationStatusUnknown) { - continue; - } - chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain; - chain.ChainPolicy.RevocationMode = X509RevocationMode.Online; - chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan (0, 1, 0); - chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags; - bool chainIsValid = chain.Build ((X509Certificate2)certificate); - if (!chainIsValid) { - correct = false; - break; - } - } - - return correct; - } } } diff --git a/Assets/Plugins/Editor/Uplift/Utils/GitHub.cs b/Assets/Plugins/Editor/Uplift/Utils/GitHub.cs index db799bd7..5d632573 100644 --- a/Assets/Plugins/Editor/Uplift/Utils/GitHub.cs +++ b/Assets/Plugins/Editor/Uplift/Utils/GitHub.cs @@ -25,7 +25,12 @@ using System; using System.Collections; using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Net; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; +using System.Text; using UnityEngine; using Uplift.Common; using Uplift.MiniJSON; @@ -34,16 +39,208 @@ namespace Uplift.GitHubModule { public class GitHub { - public static IEnumerator LoadReleases(string url) + private static readonly string[] githubCertificatesString = new string[] { - WWW www = new WWW (url); +// github.com +@"-----BEGIN CERTIFICATE----- +MIIHeTCCBmGgAwIBAgIQC/20CQrXteZAwwsWyVKaJzANBgkqhkiG9w0BAQsFADB1 +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVk +IFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE2MDMxMDAwMDAwMFoXDTE4MDUxNzEy +MDAwMFowgf0xHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYB +BAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQITCERlbGF3YXJlMRAwDgYDVQQF +Ewc1MTU3NTUwMSQwIgYDVQQJExs4OCBDb2xpbiBQIEtlbGx5LCBKciBTdHJlZXQx +DjAMBgNVBBETBTk0MTA3MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5p +YTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEVMBMGA1UEChMMR2l0SHViLCBJbmMu +MRMwEQYDVQQDEwpnaXRodWIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEA54hc8pZclxgcupjiA/F/OZGRwm/ZlucoQGTNTKmBEgNsrn/mxhngWmPw +bAvUaLP//T79Jc+1WXMpxMiz9PK6yZRRFuIo0d2bx423NA6hOL2RTtbnfs+y0PFS +/YTpQSelTuq+Fuwts5v6aAweNyMcYD0HBybkkdosFoDccBNzJ92Ac8I5EVDUc3Or +/4jSyZwzxu9kdmBlBzeHMvsqdH8SX9mNahXtXxRpwZnBiUjw36PgN+s9GLWGrafd +02T0ux9Yzd5ezkMxukqEAQ7AKIIijvaWPAJbK/52XLhIy2vpGNylyni/DQD18bBP +T+ZG1uv0QQP9LuY/joO+FKDOTler4wIDAQABo4IDejCCA3YwHwYDVR0jBBgwFoAU +PdNQpdagre7zSmAKZdMh1Pj41g8wHQYDVR0OBBYEFIhcSGcZzKB2WS0RecO+oqyH +IidbMCUGA1UdEQQeMByCCmdpdGh1Yi5jb22CDnd3dy5naXRodWIuY29tMA4GA1Ud +DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYDVR0f +BG4wbDA0oDKgMIYuaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItZXYtc2Vy +dmVyLWcxLmNybDA0oDKgMIYuaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTIt +ZXYtc2VydmVyLWcxLmNybDBLBgNVHSAERDBCMDcGCWCGSAGG/WwCATAqMCgGCCsG +AQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAcGBWeBDAEBMIGI +BggrBgEFBQcBAQR8MHowJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0 +LmNvbTBSBggrBgEFBQcwAoZGaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0Rp +Z2lDZXJ0U0hBMkV4dGVuZGVkVmFsaWRhdGlvblNlcnZlckNBLmNydDAMBgNVHRMB +Af8EAjAAMIIBfwYKKwYBBAHWeQIEAgSCAW8EggFrAWkAdgCkuQmQtBhYFIe7E6LM +Z3AKPDWYBPkb37jjd80OyA3cEAAAAVNhieoeAAAEAwBHMEUCIQCHHSEY/ROK2/sO +ljbKaNEcKWz6BxHJNPOtjSyuVnSn4QIgJ6RqvYbSX1vKLeX7vpnOfCAfS2Y8lB5R +NMwk6us2QiAAdgBo9pj4H2SCvjqM7rkoHUz8cVFdZ5PURNEKZ6y7T0/7xAAAAVNh +iennAAAEAwBHMEUCIQDZpd5S+3to8k7lcDeWBhiJASiYTk2rNAT26lVaM3xhWwIg +NUqrkIODZpRg+khhp8ag65B8mu0p4JUAmkRDbiYnRvYAdwBWFAaaL9fC7NP14b1E +sj7HRna5vJkRXMDvlJhV1onQ3QAAAVNhieqZAAAEAwBIMEYCIQDnm3WStlvE99GC +izSx+UGtGmQk2WTokoPgo1hfiv8zIAIhAPrYeXrBgseA9jUWWoB4IvmcZtshjXso +nT8MIG1u1zF8MA0GCSqGSIb3DQEBCwUAA4IBAQCLbNtkxuspqycq8h1EpbmAX0wM +5DoW7hM/FVdz4LJ3Kmftyk1yd8j/PSxRrAQN2Mr/frKeK8NE1cMji32mJbBqpWtK +/+wC+avPplBUbNpzP53cuTMF/QssxItPGNP5/OT9Aj1BxA/NofWZKh4ufV7cz3pY +RDS4BF+EEFQ4l5GY+yp4WJA/xSvYsTHWeWxRD1/nl62/Rd9FN2NkacRVozCxRVle +FrBHTFxqIP6kDnxiLElBrZngtY07ietaYZVLQN/ETyqLQftsf8TecwTklbjvm8NT +JqbaIVifYwqwNN+4lRxS3F5lNlA/il12IOgbRioLI62o8G0DaEUQgHNf8vSG +-----END CERTIFICATE----- +", +// api.github.com +@"-----BEGIN CERTIFICATE----- +MIIHTTCCBjWgAwIBAgIQDZ3d58+sYZrDhm+uNUWKlDANBgkqhkiG9w0BAQsFADBw +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNz +dXJhbmNlIFNlcnZlciBDQTAeFw0xNzAxMTgwMDAwMDBaFw0yMDA0MTcxMjAwMDBa +MGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T +YW4gRnJhbmNpc2NvMRUwEwYDVQQKEwxHaXRIdWIsIEluYy4xFTATBgNVBAMMDCou +Z2l0aHViLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKnAjzBJ +LbsS6AwMXR0ICPeRcHh+BWuvi7JVNqpplARfqbuGTlL6SEMVVOcKnVmsWWrsRtZ2 +FE6wFnT29Z9LpoC7BhO1mFyZ0DyXsCCuEIbmtC7K4qyHR5HMB0PNzRGI/pbMIYNH +1EFEbdOlLWuWpC6Lw3STy6k7k0v57ITmu+oUdKLlp66rnCy9bM3L1/6GwfjbG5q+ +fDK4PKa0H0aCuom85WcrFfPKj3AqXOe5aukASkNhfVoEDLLEIoF30zZvJQAEPi+o +AmZ4HeCnx2D0iWANO6BVprkjmpYIdNFofD1I7kRq3DcVqZoHwC0BxxWIKA3A/mvP +hqCZPhnSXd6J4GUCAwEAAaOCA+kwggPlMB8GA1UdIwQYMBaAFFFo/5CvAgd1PMzZ +ZWRiohK4WXI7MB0GA1UdDgQWBBTqYVKy/gpAgOUgijA3JKDqpmxqqjAjBgNVHREE +HDAaggwqLmdpdGh1Yi5jb22CCmdpdGh1Yi5jb20wDgYDVR0PAQH/BAQDAgWgMB0G +A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjB1BgNVHR8EbjBsMDSgMqAwhi5o +dHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1oYS1zZXJ2ZXItZzUuY3JsMDSg +MqAwhi5odHRwOi8vY3JsNC5kaWdpY2VydC5jb20vc2hhMi1oYS1zZXJ2ZXItZzUu +Y3JsMEwGA1UdIARFMEMwNwYJYIZIAYb9bAEBMCowKAYIKwYBBQUHAgEWHGh0dHBz +Oi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQICMIGDBggrBgEFBQcBAQR3 +MHUwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBNBggrBgEF +BQcwAoZBaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkhp +Z2hBc3N1cmFuY2VTZXJ2ZXJDQS5jcnQwDAYDVR0TAQH/BAIwADCCAfQGCisGAQQB +1nkCBAIEggHkBIIB4AHeAHUApLkJkLQYWBSHuxOizGdwCjw1mAT5G9+443fNDsgN +3BAAAAFZspw+SwAABAMARjBEAiAerA7v0bVTR1blKT6IzEFdNAbS9J2+sMIyN6Da +d8QGQgIgA94eKijn12cROhrzND6+thVW/PdImUzTEodCGFgaCPUAdgBWFAaaL9fC +7NP14b1Esj7HRna5vJkRXMDvlJhV1onQ3QAAAVmynD8cAAAEAwBHMEUCICSmaZLA +KILGLXy9tbDCRcqKx4KaXaOFICxUHLDavhvTAiEAiiXvucr1ZYHcoJ1ix+/UAyW4 +Sy1+SfIxV//PVuMumFcAdQDuS723dc5guuFCaR+r4Z5mow9+X7By2IMAxHuJeqj9 +ywAAAVmynEAuAAAEAwBGMEQCIHKrzA5IbzNEGMr2NmbmcJncuUTZHsHRJqU0eCZc +ian5AiBGGIX5adWUbjuFWiBb1ZnEkYsH81/ozbYGm5xY36IkxwB2ALvZ37wfinG1 +k5Qjl6qSe0c4V5UKq1LoGpCWZDaOHtGFAAABWbKcPl0AAAQDAEcwRQIhAJJMvQld +/c79AthFEj02qVdazf/Smjkb+ggN/DjrSB28AiAGEjSwxCj4r+PnUgzFtURbLofk +3iAvECLj9NZO2SZbdTANBgkqhkiG9w0BAQsFAAOCAQEAfIMvSUq9Z4EUniI976aO +kXTSPwa8GT+KFzlLpcyPmcU/x8ATptUsARnS96Yzx7BWtchprXsDWKdFLgmQ/YTT +dgUfy/Qyy7baJvCyLwBf4cJpsBdYaKxcige2dnAJjgVIvl8jEO4k+lD5BWgqQgRE +lDXj0SVVQQ1wd0MZTKWlDVbxmKsXzu5I0kWCG6/mfBcJc+6H+ABWc1YIK+pLP1jD +YcC8wj9fRkTCpZW/3lZ/Nt+snM1ujTRZ7RTBlRG2uJLpIX15JihSprEr3u39RHUp +HOODLNzVAw63zfJqCJvPtaCr+/KXKrqfjk9Z+e7Nmg+IxOf4M/Mxbox4KJvLlX8p +wQ== +-----END CERTIFICATE----- +", +// DigiCert High Assurance EV Root CA +@"-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- +", +// DigiCert SHA2 Extended Validation Server CA +@"-----BEGIN CERTIFICATE----- +MIIEtjCCA56gAwIBAgIQDHmpRLCMEZUgkmFf4msdgzANBgkqhkiG9w0BAQsFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowdTEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTE0MDIGA1UEAxMrRGlnaUNlcnQgU0hBMiBFeHRlbmRlZCBW +YWxpZGF0aW9uIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBANdTpARR+JmmFkhLZyeqk0nQOe0MsLAAh/FnKIaFjI5j2ryxQDji0/XspQUY +uD0+xZkXMuwYjPrxDKZkIYXLBxA0sFKIKx9om9KxjxKws9LniB8f7zh3VFNfgHk/ +LhqqqB5LKw2rt2O5Nbd9FLxZS99RStKh4gzikIKHaq7q12TWmFXo/a8aUGxUvBHy +/Urynbt/DvTVvo4WiRJV2MBxNO723C3sxIclho3YIeSwTQyJ3DkmF93215SF2AQh +cJ1vb/9cuhnhRctWVyh+HA1BV6q3uCe7seT6Ku8hI3UarS2bhjWMnHe1c63YlC3k +8wyd7sFOYn4XwHGeLN7x+RAoGTMCAwEAAaOCAUkwggFFMBIGA1UdEwEB/wQIMAYB +Af8CAQAwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF +BQcDAjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp +Z2ljZXJ0LmNvbTBLBgNVHR8ERDBCMECgPqA8hjpodHRwOi8vY3JsNC5kaWdpY2Vy +dC5jb20vRGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3JsMD0GA1UdIAQ2 +MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5j +b20vQ1BTMB0GA1UdDgQWBBQ901Cl1qCt7vNKYApl0yHU+PjWDzAfBgNVHSMEGDAW +gBSxPsNpA/i/RwHUmCYaCALvY2QrwzANBgkqhkiG9w0BAQsFAAOCAQEAnbbQkIbh +hgLtxaDwNBx0wY12zIYKqPBKikLWP8ipTa18CK3mtlC4ohpNiAexKSHc59rGPCHg +4xFJcKx6HQGkyhE6V6t9VypAdP3THYUYUN9XR3WhfVUgLkc3UHKMf4Ib0mKPLQNa +2sPIoc4sUqIAY+tzunHISScjl2SFnjgOrWNoPLpSgVh5oywM395t6zHyuqB8bPEs +1OG9d4Q3A84ytciagRpKkk47RpqF/oOi+Z6Mo8wNXrM9zwR4jxQUezKcxwCmXMS1 +oVWNWlZopCJwqjyBcdmdqEU79OX2olHdx3ti6G8MdOu42vi/hw15UJGQmxg7kVkn +8TUoE6smftX3eg== +-----END CERTIFICATE----- +", +// Amazon S3 (provider for the release download) *.s3.amazonaws.com +@"-----BEGIN CERTIFICATE----- +MIIFWjCCBEKgAwIBAgIQBVG1kvpTzyBSuLcPJ1zBWTANBgkqhkiG9w0BAQsFADBk +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSMwIQYDVQQDExpEaWdpQ2VydCBCYWx0aW1vcmUgQ0Et +MiBHMjAeFw0xNzA5MjIwMDAwMDBaFw0xOTAxMDMxMjAwMDBaMGsxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdTZWF0dGxlMRgwFgYD +VQQKEw9BbWF6b24uY29tIEluYy4xGzAZBgNVBAMMEiouczMuYW1hem9uYXdzLmNv +bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKK5it42LH/8WFaEE7O9 +4XJMg48TengCM25C9O0dUaPGOnZ1+oGf7DNvdo/MGVoAW5hfPX9WqjY30KyuKiFv +8uAbyX+9Bzq8KMLjdvGxzYMqbSxeAPSBf1yMdCyDEc8gW+vh2uXO+x9QePgiOAoO +qujLzyS/p7pSWPUKUH8kpMgP99RPoD/lRNbPAFr3QeJr7D/x3xNTKBHCbpE4SxBH +QM02GCu2DSYQtgm3hfZmD79BB1Ej4U1vM0hgiOu9eFLwmycbnrnU8sa4DkvmUJlv +xiIP5PvNweawm/QeoH6Qk/zDF30nr+5Av9IUhE4uAhl1H2OMqPp79SfJ2wxtvmNt +3z0CAwEAAaOCAf8wggH7MB8GA1UdIwQYMBaAFMASsih0aEZn6XAldBoARVsGfVxE +MB0GA1UdDgQWBBSQFZo7H1VA7uODvdTP1I6idMLqyDAvBgNVHREEKDAmghIqLnMz +LmFtYXpvbmF3cy5jb22CEHMzLmFtYXpvbmF3cy5jb20wDgYDVR0PAQH/BAQDAgWg +MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjCBgQYDVR0fBHoweDA6oDig +NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QmFsdGltb3JlQ0Et +MkcyLmNybDA6oDigNoY0aHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0 +QmFsdGltb3JlQ0EtMkcyLmNybDBMBgNVHSAERTBDMDcGCWCGSAGG/WwBATAqMCgG +CCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAgGBmeBDAEC +AjB5BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2lj +ZXJ0LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29t +L0RpZ2lDZXJ0QmFsdGltb3JlQ0EtMkcyLmNydDAMBgNVHRMBAf8EAjAAMA0GCSqG +SIb3DQEBCwUAA4IBAQBydwnbmrwTTwhtCckZ9lDGoE+tdDFchjFG59dyzX1I4bHV +thVUwjEoc3VxngvmKb3cqLcHzXHNdoEdffRtw0IiEerPRsk7Nxh2p1HWR3cu/Hyp +kqGlObJADiw1DX4UDob735hevqcGN9M0rn9P/AbPK0HCn5uokLDmbeqe6u1YgdJL +m4skA/WsUsMCfsZY27RiZ+B162+laDD0oRiovOx5zKrzG/3yAFVutz2Bfud3QenU +3zt14ttnzFCcMlglW9oqffHMwQ1Smx/30ccDonoa1E02hnNmxeLyBwomPqd/ZYy6 +zSJW0aSi1DadkZsifpr65AwgSuN5uGEhQas0glsN +-----END CERTIFICATE----- +" + }; + + + public static IEnumerator LoadReleases(string url, string authToken = null) + { + WWW www = string.IsNullOrEmpty(authToken) ? + new WWW (url) : + new WWW ( + url, + null, + new Dictionary + { + { "Authorization", "token " + authToken } + }); while (www.isDone == false) yield return null; yield return www; if(!string.IsNullOrEmpty(www.error)) { - Debug.Log(www.error); + Debug.LogError(www.error); + Debug.LogWarning(www.text); + + yield return null; } else { @@ -86,17 +283,108 @@ private static GitHubAsset[] ExtractAssets(Dictionary release) foreach (Dictionary asset in assets) { assetList.Add(new GitHubAsset { + apiURL = (string)asset["url"], htmlURL = (string)asset["browser_download_url"], - name = (string)asset["name"] + name = (string)asset["name"], + contentType = (string)asset["content_type"] }); } return assetList.ToArray(); } + + public static X509Certificate[] GetCertificates() + { + X509Certificate[] githubCertificates = new X509Certificate[githubCertificatesString.Length]; + for(int i = 0; i < githubCertificatesString.Length; i++) + { + githubCertificates[i] = new X509Certificate(); + githubCertificates[i].Import(Encoding.ASCII.GetBytes(githubCertificatesString[i])); + } + + return githubCertificates; + } + + public static bool CertificateValidationCallback( + System.Object sender, + X509Certificate certificate, + X509Chain chain, + SslPolicyErrors sslPolicyErrors + ) + { + bool correct = true; + if(sslPolicyErrors == SslPolicyErrors.None) return true; + + X509Certificate[] githubCertificates = GetCertificates(); + + if(!(githubCertificates.Any(cert => cert.GetCertHashString() == certificate.GetCertHashString()) || UpliftPreferences.TrustUnknownCertificates())) + { + Debug.LogErrorFormat("The received certificate ({0}) is not known by Uplift. We cannot download the update package. You could update Uplift manually, or go to Preferences and set 'Trust unknown certificates' to true.", certificate.GetCertHashString()); + Debug.Log("Known certificates are:"); + foreach(X509Certificate cert in githubCertificates) + Debug.Log(" -- " + cert.GetCertHashString()); + return false; + } + + for (int i=0; i < chain.ChainStatus.Length; i++) { + if (chain.ChainStatus[i].Status == X509ChainStatusFlags.RevocationStatusUnknown) { + continue; + } + chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain; + chain.ChainPolicy.RevocationMode = X509RevocationMode.Online; + chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan (0, 1, 0); + chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags; + bool chainIsValid = chain.Build ((X509Certificate2)certificate); + if (!chainIsValid) { + correct = false; + break; + } + } + + return correct; + } + + public static Stream GetAssetStream(GitHubAsset asset) + { + return GetAssetStream(asset, ""); + } + public static Stream GetAssetStream(GitHubAsset asset, string token) + { + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(asset.apiURL); + request.Method = "GET"; + if(!string.IsNullOrEmpty(token)) + request.Headers["Authorization"] = "token " + token; + request.Accept = "application/octet-stream"; + request.UserAgent = "Uplift GithubRepository/1.0 - https://github.com/DragonBox/uplift"; + request.AllowAutoRedirect = false; + + ServicePointManager.ServerCertificateValidationCallback = GitHub.CertificateValidationCallback; + Uri address; + HttpStatusCode responseStatus; + using(HttpWebResponse response = (HttpWebResponse)request.GetResponse()) + { + responseStatus = response.StatusCode; + if((int)response.StatusCode < 300 || (int)response.StatusCode > 399) + throw new ApplicationException("Request should be redirected"); + address = new Uri(response.GetResponseHeader("Location")); + } + + request = (HttpWebRequest)WebRequest.Create(address); + request.Method = "GET"; + request.UserAgent = "Uplift GithubRepository/1.0 - https://github.com/DragonBox/uplift"; + HttpWebResponse finalResponse = (HttpWebResponse)request.GetResponse(); + responseStatus = finalResponse.StatusCode; + if((int)finalResponse.StatusCode >= 200 && (int)finalResponse.StatusCode <= 299) + { + return finalResponse.GetResponseStream(); + } + + throw new ApplicationException("Could not get asset at " + asset.apiURL); + } } // Based on https://developer.github.com/v3/repos/releases/ - public struct GitHubRelease + public class GitHubRelease { public string tag; public string body; @@ -104,9 +392,11 @@ public struct GitHubRelease public GitHubAsset[] assets; } - public struct GitHubAsset + public class GitHubAsset { public string htmlURL; + public string apiURL; public string name; + public string contentType; } } diff --git a/TestData/UpfileTest/UpfileOverride.xml b/TestData/UpfileTest/UpliftSettings.xml similarity index 72% rename from TestData/UpfileTest/UpfileOverride.xml rename to TestData/UpfileTest/UpliftSettings.xml index f5e309f0..e274ed07 100644 --- a/TestData/UpfileTest/UpfileOverride.xml +++ b/TestData/UpfileTest/UpliftSettings.xml @@ -1,5 +1,5 @@ - + - +